Generating Gdk/Gtk keyboard events programmatically

I need to generate keyboard events for my app running on a Raspberry Pi with no keyboard attached. The user has requested a grid of buttons with numbers, etc on one the side of the app. In years gone by (Gtk 3.20) this code used to work:

keyval = Gdk.unicode_to_keyval(5)
event = Gdk.EventKey()
event.window = self.edit_widget.get_window()
event.type = Gdk.EventType.KEY_PRESS
event.send_event = True
event.time = Gdk.CURRENT_TIME
event.keyval = keyval
event.put()

But in Gtk 3.24, I get a lot of this error message:

Gdk-WARNING **: 09:43:49.136: Event with type 8 not holding a GdkDevice. It is most likely synthesized outside Gdk/GTK+

Gdk-WARNING **: 09:43:49.136: Event with type 8 not holding a GdkDevice. It is most likely synthesized outside Gdk/GTK+

Gdk-WARNING **: 09:43:49.136: Event with type 8 not holding a GdkDevice. It is most likely synthesized outside Gdk/GTK+

The original places I found this code was:

https://mail.gnome.org/archives/gtk-app-devel-list/2004-July/msg00016.html

You may try:

keyval = Gdk.unicode_to_keyval(5)
event = Gdk.EventKey()
event.window = self.edit_widget.get_window()
event.type = Gdk.EventType.KEY_PRESS
event.send_event = True
event.time = Gdk.CURRENT_TIME
event.keyval = keyval

display = Gdk.Display.get_default()
seat = display.get_default_seat()
keyboard = seat.get_keyboard()
event.set_device(keyboard);

event.put()

Note that Gdk.Seat is a relatively new type introduced in GTK 3.20. If you need to support older GTK releases, then you should use Gdk.DeviceManager to get the virtual keyboard device.

1 Like

Same error. Maybe I should come up with a small program so it can be tested on different computers/distros.

Do you mean the warning above actually is preventing the event from taking place? This post python 3.x - Remove focus from TextEntry - Stack Overflow is dealing with a similar scenario and it works for me but not the OP. I’m on Ubuntu 22.04 LTS, using latest version of Gtk3.

I tried using Gdk.EventKey() at first and couldn’t get it to work. I tried to use it again just now with the code below, it works but it kept spitting that same warning. Meanwhile, using Gdk.Event() works with no warning for me. Also, I just found out I can comment out all these attributes and the event still works for me, but I’m leaving them in for clarity.

Here’s how I synthesized the event:

display = Gdk.Display().get_default()
seat = display.get_default_seat()
keyboard = seat.get_keyboard()
keymap = Gdk.Keymap().get_for_display(display)
key = keymap.get_entries_for_keyval(Gdk.KEY_Tab)

event = Gdk.Event().new(Gdk.EventType.KEY_PRESS)
event.hardware_keycode = key[1][0].keycode
event.window = notebook.get_window()
event.set_device(keyboard)

# event.time = Gdk.CURRENT_TIME
# event.send_event = True
# event.keyval = Gdk.KEY_Tab
# event.type = Gdk.EventType.KEY_PRESS
# event.length = 0
# event.is_modifier = 0
# event.state = 0
# event.string = ""
# event.group = key[1][0].group
1 Like