Search code examples
gtk3gtk#

GTK3: How can I disable default widget activation?


Here's a sample GTK# program that listens for key presses and prints them.

using Gtk;
using Application = Gtk.Application;

Application.Init();

Window win = new Window("Title");
win.DeleteEvent += (_, eventArgs) => Application.Quit();
win.KeyPressEvent += (_, eventArgs) =>
{
    Console.WriteLine($"Key down {eventArgs.Event.Key}");
};
win.KeyReleaseEvent += (_, eventArgs) =>
{
    Console.WriteLine($"Key up   {eventArgs.Event.Key}");
};

win.Show();

Application.Run();

I would expect to see Enter key presses, but I don't. Instead, they are mapped to activate the window's default widget. Can I disable this functionality so that Enter key presses are also caught by the key listener?


Solution

  • GTK comes with a set of default keybinds, maintained by a GtkBindingSet (C name). In C, one would essentially do:

    GtkBindingSet* binding_set = gtk_binding_set_by_class(GTK_TYPE_WINDOW);
    // For each keybinding that needs removal...
    gtk_binding_entry_remove(binding_set, /* GdkKey */ key, /*GdkModifierType*/ modifiers);
    

    I wrote C# bindings for both functions, then used them to delete the following keybinds:

    • Space
    • KP_space
    • Return
    • ISO_Enter
    • KP_Enter
    • Ctrl+Shift+I
    • Ctrl+Shift+D
    • Arrow keys (and keypad arrows), with Ctrl and without
    • Tab (and KP_tab), with Ctrl, Shift, or Ctrl+Shift

    These are all of GTK's default keybindings. There's probably a more robust way to do this, but I didn't bother.