使用Gnome库(GDK)获取键盘修饰符状态仅获取初始状态
我试图通过gnome GDK或GTK库来获取当前的键盘修饰符状态,目的是实现显示该状态的可访问性gnome shell扩展。
我知道如何使用xlib获得状态,但是gnome gjs没有完全绑定。
下面的代码只获得初始状态。 它不会更新状态。
/* * compiling: gcc `pkg-config --cflags gdk-3.0` -o gdk_mod gdk_mod.c `pkg-config --libs gdk-3.0` */ #include int main (int argc, char **argv) { gdk_init(&argc, &argv); GdkDisplay * disp; disp = gdk_display_open(NULL); if (disp!=NULL) g_printf("display connected!\n"); GdkKeymap * kmap; kmap = gdk_keymap_get_for_display(disp); guint state; state = gdk_keymap_get_modifier_state(kmap); g_printf("mod state: %x\n", state); while (1) { g_usleep(1000000); //kmap = gdk_keymap_get_for_display(disp); state = gdk_keymap_get_modifier_state(kmap); g_printf("mod state: %x\n", state); } }
这里有CAPS锁定的示例输出然后处于非活动状态但没有变化:
$ ./gdk_mod display found! mod state: 2 mod state: 2 mod state: 2 mod state: 2 mod state: 2 ^C
目前正在使用Kubuntu 15.04。
我的代码出了什么问题?
您将需要运行GTK +事件循环才能实现此function。 事件循环是GLib 主循环的一部分 。 当您调用gtk_main()
,将运行此主循环。 我不知道它是否对事件进行了轮询或是否有事件被推送到它,但它不会像你想要的那样在运行时询问键盘状态。
设置GDK的最简单方法是使用gtk_init()
和gtk_main()
通过GTK +完成。 你可以自己使用GDK,但我不知道怎么做。 你好像已经弄明白了,哪个有效。
而不是调用只阻止程序的g_usleep()
,你可以将定期超时挂钩到主循环中。 这是通过g_timeout_add()
。 传递给g_timeout_add()
的函数返回一个布尔值,该值决定是否应该停止计时器,因此您不必担心重新调度函数,因为GLib会为您执行此操作。
-
事实上,正如andlabs在评论中所说,我需要一个事件循环。 他建议使用GTK
gtk_init()
&gtk_main()
完美无缺。/* * compiling: gcc `pkg-config --cflags gtk+-3.0` -o gtk_xkbmod3 gtk_xkbmod3.c `pkg-config --libs gtk+-3.0` */ #include
static void update(GdkKeymap * kmap) { guint state; state = gdk_keymap_get_modifier_state(kmap); g_printf("%i\n", state); } int main (int argc, char **argv) { gtk_init(&argc, &argv); GdkKeymap * kmap; kmap = gdk_keymap_get_default(); g_timeout_add_seconds(1, (GSourceFunc) update, kmap); gtk_main(); } -
我也可以使用GDK和GLib GMainLoop。
/* * compiling: gcc `pkg-config --cflags gdk-3.0` -o gdk_xkbmod4 gdk_xkbmod4.c `pkg-config --libs gdk-3.0` */ #include
GMainLoop *mainloop; static void update(GdkKeymap * kmap) { guint state; state = gdk_keymap_get_modifier_state(kmap); g_printf("%i\n", state); } int main (int argc, char **argv) { gdk_init(&argc, &argv); GdkKeymap * kmap; kmap = gdk_keymap_get_default(); g_timeout_add_seconds(1, (GSourceFunc) update, kmap); mainloop = g_main_loop_new(g_main_context_default(), FALSE); g_main_loop_run(mainloop); }
参考文献:
- Xfce Foundation类:主事件循环
- GTK +论坛:GDK + GLib主循环