Linux下C语言system函数结合鼠标滚动切换光标主题异常问题
问题描述
我编写了以下C语言代码,期望通过监听鼠标滚动事件,在向上滚动(value=120)时调用system()函数切换GNOME光标主题为Spotlight,向下滚动(value=-120)时切换回Adwaita。单独运行system命令对应的代码可正常生效,但结合鼠标滚动触发时却无法正常运行。
#include <linux/input-event-codes.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <linux/input.h> #define MOUSEFILE "/dev/input/event9" //#define TOUCHPAD "/dev/input/event0" void createSpot(){ system("gsettings set org.gnome.desktop.interface cursor-theme Spotlight"); } void offSpot(){ system("gsettings set org.gnome.desktop.interface cursor-theme Adwaita"); } int main() { int fd; struct input_event ie; if((fd = open(MOUSEFILE, O_RDONLY)) == -1) { perror("opening device"); exit(EXIT_FAILURE); } while(read(fd, &ie, sizeof(struct input_event))) { if(ie.value==120){ createSpot(); } if(ie.value==-120){ offSpot(); } printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n", ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value); } return 0; }
解决办法
1. 环境变量缺失
gsettings依赖GNOME会话的环境变量(比如DBUS_SESSION_BUS_ADDRESS)才能和桌面进程通信,而直接读取/dev/input的程序如果在非桌面上下文运行(比如用root启动、环境变量未继承),就会失效。
- 直接在当前桌面的终端中运行编译后的程序,确保继承完整的桌面环境变量。
- 如果必须用root权限运行,手动传递关键环境变量:
sudo DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS ./your_compiled_program
2. 滚动事件重复触发
鼠标滚动会生成多个连续的input_event,短时间内多次调用gsettings可能导致配置切换冲突,添加防抖机制:
#include <time.h> time_t last_switch = 0; #define DEBOUNCE_INTERVAL 1 // 间隔1秒才允许再次执行切换 void createSpot(){ time_t now = time(NULL); if (now - last_switch < DEBOUNCE_INTERVAL) return; last_switch = now; system("gsettings set org.gnome.desktop.interface cursor-theme Spotlight"); } void offSpot(){ time_t now = time(NULL); if (now - last_switch < DEBOUNCE_INTERVAL) return; last_switch = now; system("gsettings set org.gnome.desktop.interface cursor-theme Adwaita"); }
3. 设备节点或权限问题
- 确认
/dev/input/event9是正确的鼠标设备:执行cat /proc/bus/input/devices,找到鼠标对应的eventX节点并替换。 - 普通用户可能没有读取输入设备的权限,将用户加入
input组:
注销后重新登录生效。sudo usermod -aG input $USER
内容的提问来源于stack exchange,提问作者No pen At lab
相关产品推荐
相关产品推荐

