使用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主循环