Search code examples
c++cgtkgdk

Gtk: send focus to a toplevel window without losing the first toplevel window


Here is the situation:

1) I have two toplevel windows, A and B

2) A is in front of B

How can I send to keyboard focus to the window B while keeping the window A in front of B ?


Solution

  • I'm assuming you control both windows, and this is on an X11 system like Linux. If not, it's much more challenging. I've done things like this within a single app, and here are some recollections.

    You've probably figured out you can't just use gtk_widget_grab_focus() to do it. That only works for determining which widget within a window has focus when the window itself has focus.

    It's X11 that determines which window gets a keyboard event, based on the window hierarchy, info from the window manager, etc. However, you can monkey around with that via GDK to get the result you want.

    You'll have to learn about GDK event propagation, and probably read some of the GDK sources. But I believe that, generally, what you'll need to do is this:

    1. Use gdk_event_handler_set() to install your own event handler. You'll need to do this after GTK+ is initialized, and chain to gtk_main_do_event().
    2. When you get a keyboard event (GdkEventKey), look at the X event structure. If it has the XID for window A, replace that with the XID for window B, and pass it on to GTK+. You might need to duplicate the event, and not modify the original one.

    If the windows belong to different apps, you can look at gdk_event_send_client_message(), but I've never used it.