Игнорировать курсор клавиатуры в GTK3 C - PullRequest
0 голосов
/ 04 апреля 2020

Используя GTK3 в C, у меня есть интерфейс с кнопками. Я хочу, чтобы пользователь с мышью мог нажимать кнопку ИЛИ использовать одну кнопку на клавиатуре, чтобы сделать то же самое.

MWE (модифицировано из примера GTK3 Hello World):

/*
 * Ignore keyboard cursor in GTK3 C
 */

#include <gtk/gtk.h>

void thing() {
    printf("did a thing\n");
}

void otherthing() {
    printf("did something different\n");
}

static gboolean key_event(GtkWidget *widget, GdkEventKey *event) {
    gchar* val = gdk_keyval_name (event->keyval);

    if (strcmp(val, "Left") == 0) {
        thing();
    }
    return 0;
}

static void activate (GtkApplication *app, gpointer user_data) {
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *button2;
    GtkWidget *button_box;

    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Window");
    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);

    button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_container_add (GTK_CONTAINER (window), button_box);

    button = gtk_button_new_with_label ("Do the thing");
    button2 = gtk_button_new_with_label ("xxx");
    g_signal_connect(window, "key-release-event", G_CALLBACK(key_event), NULL);
    g_signal_connect (button, "clicked", G_CALLBACK (thing), window);
    g_signal_connect (button2, "clicked", G_CALLBACK (otherthing), window);
    gtk_container_add (GTK_CONTAINER (button_box), button2);
    gtk_container_add (GTK_CONTAINER (button_box), button);

    gtk_widget_show_all (window);
}

int main (int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

В этой программе пользователь может нажать клавишу со стрелкой влево, чтобы выполнить thing. Пользователь также может нажать на кнопку gui, чтобы выполнить thing. Однако нажатие определенных клавиш клавиатуры, таких как пробел или ввод, будет «щелкать» по кнопке gui, чтобы выполнить thing.

Как запретить клавиатуре «щелкать» по кнопке, на которой находится курсор клавиатуры включено в этом случае?

1 Ответ

0 голосов
/ 14 апреля 2020

Hake Button Hack

Я взломал обходной путь в своем коде, используя бесполезную кнопку. Я не буду отмечать этот ответ как решенный, поскольку он очень небрежный, но он выполняет свою работу до тех пор, пока не станет доступно что-то лучшее.

Описание

Этот хак добавляет еще одну кнопку без назначенных функций. Используя gtk_widget_grab_focus, мы заставляем эту бесполезную «фальшивую кнопку» удерживать фокус клавиатуры. Мы повторяем эту команду каждый раз, когда нажимается кнопка.

Проблемы

Захват фокуса назад на фальшивую кнопку происходит медленно. Пользователь может выполнить быструю последовательность команд (в случае MWE, нажав Влево и Пробел , чтобы ошибочно выполнить функцию otherthing).

MWE

/*
 * Ignore keyboard cursor in GTK3 C
 */

#include <gtk/gtk.h>

GtkWidget *fakebutton;

void thing() {
    printf("did a thing\n");
}

void otherthing() {
    printf("did something different\n");
}

static gboolean key_event(GtkWidget *widget, GdkEventKey *event) {
    gchar* val = gdk_keyval_name (event->keyval);

    if (strcmp(val, "Left") == 0) {
        thing();
        gtk_widget_grab_focus(fakebutton);
    } else {
        gtk_widget_grab_focus(fakebutton);
    }
    return 0;
}

static void activate (GtkApplication *app, gpointer user_data) {
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *button2;
    GtkWidget *button_box;

    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Window");
    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);

    button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_container_add (GTK_CONTAINER (window), button_box);

    button = gtk_button_new_with_label ("Do the thing");
    button2 = gtk_button_new_with_label ("xxx");
    fakebutton = gtk_button_new();
    g_signal_connect(window, "key-release-event", G_CALLBACK(key_event), NULL);
    g_signal_connect (button, "clicked", G_CALLBACK (thing), window);
    g_signal_connect (button2, "clicked", G_CALLBACK (otherthing), window);
    gtk_container_add (GTK_CONTAINER (button_box), button2);
    gtk_container_add (GTK_CONTAINER (button_box), fakebutton);
    gtk_container_add (GTK_CONTAINER (button_box), button);


    gtk_widget_show_all (window);
}

int main (int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}
...