3

その状態を示すアクセシビリティgnomeシェル拡張を実装することを目的として、gnome GDKまたはGTKライブラリを介して現在のキーボード修飾子の状態を取得しようとしています。

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

これを機能させるには、GTK+ イベント ループを実行する必要があります。イベント ループは、GLib のメイン ループの一部です。を呼び出すとgtk_main()、このメイン ループが実行されます。イベントをポーリングするのか、イベントをプッシュするのかはわかりませんが、あなたがしようとしていたように、その場でキーボードの状態を尋ねることはありません。

GDK を設定する最も簡単な方法は、 と を使用して GTK+ 経由で行うことgtk_init()ですgtk_main()。GDK は単独で使用できますが、その方法はわかりません。あなたはそれを理解したようで、うまくいきました。

また、プログラムをブロックするだけの を呼び出す代わりにg_usleep()、定期的なタイムアウトをメイン ループにフックすることができます。これは で行われg_timeout_add()ます。に渡す関数はg_timeout_add()、タイマーを停止するかどうかを決定するブール値を返すため、関数の再スケジュールについて心配する必要はありません。GLib が自動的に実行します。

于 2015-08-08T00:15:14.473 に答える
2
  • 確かに、andlabs がコメントで述べたように、イベント ループが必要です。gtk_init()GTK &を使用するという彼の提案は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();
    
    }
    
  • GLib GMainLoop で GDK を使用することもできます。

    /*
     * 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 に答える