Xdg Activation (Wayland/X11)

On wayland, windows are cannot gain focus by default due to focus stealing prevention*, and are instead expected to transfer focus between windows with activation tokens, which are. A similar system is also used on x11, and used for things like cursor loading indicators, it’s less important than on wayland but winit mostly abstracts support for both.

  • Because support for it is still poor, most compositors operate on a less strict mode by default that focuses newly spawned windows even if they are not activated. See this Gnome blog post for more detail.

We can roughly list the things that an application needs to do to fully support it:

  1. When an application is created (N/A in daemon mode), get a token from the application that spawned it (the standard is reading the XDG_ACTIVATION_TOKEN env var or DESKTOP_STARTUP_ID on x11) and activate the window
  2. When a window is created or focused while the application has focused, the focused window needs to create an activation token, and the new window needs to activate with it
  3. Activate a window (that is either new or already open) from external interactions: portals, notifications, system tray, etc.
  4. Create a token for external applications to take focus, most common one being spawning a new process that creates a window

I’m not sure how much iced should do, and how much is the responsibility of applications.
It’s unreasonable to do 3 and 4 automatically, 3 it requires interaction with platform specific code such as ashpd (which already handle it itself using given a rwh) and 4 is again outside the scope of iced e.g. std::process. This feels obvious but it’s worth mentioning because in other frameworks such as gtk and qt these are within the scope.

So either way we need to have a platform specific field for window creation to supply an activation token, and a platform specific window action (I don’t think there’s precedence for this) to set and request a token.
I think we should automate 1, it’s applies to almost every application and is very straight forward. I’m less sure about 2, it’s also very common and iced has the required information so it would be nice to support, it requires keeping track of the last focused window which doesn’t seem too bad (it also requires “the serial of the event that requested the token”, winit takes care of that remembering the serial of the last input event).

winit provides WindowAttributesExtStartupNotify::with_activation_token and WindowExtStartupNotify::request_activation_token methods to set and request an activation token and EventLoopExtStartupNotify::read_token_from_env and startup_notify::reset_activation_token_env helpers that read XDG_ACTIVATION_TOKEN (or DESKTOP_STARTUP_ID on x11)