Получение состояния модификаторов клавиатуры с помощью Gnome libs (GDK) извлекает только начальное состояние
Я пытаюсь получить текущее состояние модификаторов клавиатуры через библиотеку gnome GDK или GTK, чтобы реализовать расширение оболочки доступности gnome, которое показывает это состояние.
Я знаю, как получить их состояние с помощью 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.
Что не так с моим кодом?
2 ответа
Вам нужно будет запустить цикл событий GTK+, чтобы это работало. Цикл событий является частью основного цикла GLib. Когда вы звоните gtk_main()
этот основной цикл запускается. Я не знаю, опрашивает ли он события или ему выдвигаются события, но он не будет запрашивать состояние клавиатуры на лету, как вы пытались это сделать.
Самый простой способ настроить GDK - это сделать через GTK+, используя gtk_init()
а также gtk_main()
, Вы можете использовать GDK самостоятельно, но я не знаю как. Вы, казалось, поняли это, который работает.
И вместо того, чтобы звонить g_usleep()
, который просто блокирует вашу программу, вы можете подключить периодический таймаут в основной цикл. Это сделано с g_timeout_add()
, Функция, которую вы передаете g_timeout_add()
возвращает логическое значение, которое решает, должен ли таймер быть остановлен или нет, поэтому вам не нужно беспокоиться о перепланировании вашей функции, поскольку GLib сделает это за вас.
Действительно, мне нужен цикл обработки событий, как сказал andlabs в своем комментарии. Его предложение использовать GTK
gtk_init()
>k_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); }
Рекомендации: