my Gtk3 app https://horizon-eda.org/ consists of multiple processes that need to raise each other’s windows on user request.
This of course requires some special care to not run into focus stealing prevention measures.
On X11, passing the event’s timestamp across the process boundary to gtk_window_present_with_time worked well.
On wayland however, things work differently. xdg_activation_v1_activate requires a token to be created with a recent-enough serial.
So far I haven’t found a way to get such a serial by other means than listening to the mouse and keyboard events from wayland directly. See wip · horizon-eda/horizon@1ac4fbb · GitHub for a proof-of-concept implementation. Someone please tell me that there’s a better way to do this.
The annoying thing is that Gtk can do what I need, it’s just not part of any public API as far as I can tell:
_gdk_wayland_seat_get_last_implicit_grab_serial would provide the right serial for the current seat.
I see, then what you can do is use the xdg-activation protocol as is. Do this:
In response to a focus or input event use xdg_activation_v1.get_activation_token() to create a new token
Set the serial and surface that was the recipient to the above focus/input event on the token (xdg_activation_token_v1.set_serial and xdg_activation_token_v1.set_surface.
Commit the token (xdg_activation_token_v1.commit)
Wait for the xdg_activation_token_v1.done event which carries the exported token string
Pass this string to the application process you want to activate via whatever way you prefer
In the process you want to activate the window do this:
Receive the token from the last step above
Call xdg_activation_v1.activate with said token string and the surface you want to activate
This should activate (i.e. raise / bring to focus) the surface in the second process.
Looking a bit at gtk3, I think you can achieve this by using gdk_display_get_app_launch_context() then get said token from the last step above via g_app_launch_context_get_startup_notify_id().
And in the other process, achieve the last step via gdk_window_set_startup_id().