3

我正在尝试通过 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 <gdk/gdk.h>

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。

我的代码有什么问题?

4

2 回答 2

2
  • 事实上,正如 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 <gtk/gtk.h>
    
    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 <gdk/gdk.h>
    
    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);    
    }
    

参考:

于 2015-08-07T21:57:49.887 回答
2

您将需要运行 GTK+ 事件循环才能使其工作。事件循环是 GLib主循环的一部分。当您调用 时gtk_main(),将运行此主循环。我不知道它是轮询事件还是将事件推送给它,但它不会像您尝试做的那样即时询问键盘状态。

设置 GDK 的最简单方法是通过 GTK+ 使用gtk_init()and来完成gtk_main()。您可以单独使用GDK,但我不知道如何。您似乎已经弄清楚了,这很有效。

g_usleep()您可以将定期超时挂接到主循环中,而不是调用只会阻塞您的程序。这是用g_timeout_add(). 您传递给的函数g_timeout_add()返回一个布尔值,该值决定是否应该停止计时器,因此您不必担心重新安排您的函数,因为 GLib 会为您执行此操作。

于 2015-08-08T00:15:14.473 回答