Skip to content

kawa: support xdg-activation-v1 - #18

Merged
DeedleFake merged 5 commits into
layer-shellfrom
xdg-activation
Oct 1, 2026
Merged

DeedleFake merged 5 commits into
layer-shellfrom
xdg-activation

Conversation

@DeedleFake

@DeedleFake DeedleFake commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Why

A window launched from a terminal never gets focus today, and only windows opened through New are focused when they map. Rather than focus every new window, which would let any client steal focus, this adds xdg-activation-v1: a window gets focus only when it presents a token tied to recent input on the surface the user was using. It uses the bindings from DeedleFake/wlr#13, which is merged, and the last commit bumps wlr to master at fb0cc1b.

Scope

  • Kawa now creates the xdg_activation_v1 global. A request is granted only if wlroots tied the token to a real input serial (the token has a seat) and the token's surface had the keyboard when the token was made, or still has it. A token with no surface is refused, as in sway, because a bare serial can't be tied to what the user was doing. A granted request focuses and raises the window, or unhides it if it is hidden.
  • A request can arrive before the window maps, which is the usual order for a program started with a token, or after it. A granted request for an unmapped window is remembered and applied on map. New keeps its existing focusing.
  • A refused request leaves focus alone and marks the window as wanting attention. It gets a red border (even with client-side decorations), and its hidden-menu entry turns red. Both clear when the window gets focus.
  • Programs started from New get XDG_ACTIVATION_TOKEN and DESKTOP_STARTUP_ID from a token kawa creates and trusts.

Tradeoffs

The policy is stricter than labwc, which only checks for a seat. It also requires keyboard focus, where wlroots accepts pointer focus too. So a click-made token from a window under the pointer but without the keyboard only gets attention. Tokens that wlroots rejects at commit time, such as one with serial 0 that GTK sends for self-activation, never reach kawa, so they can't mark attention either. weston-terminal and foot's spawn-terminal don't pass tokens on, so programs started from them still don't get focus, which is the intended behavior.

Blast Radius

Only windows that ask for activation are affected. Existing focus, New, menus and layer shell behave as before.

Verification

go build ./... and go vet ./... pass on every commit. On a nested Xvfb session I checked these cases:

  • A test client that makes a token from a click and starts a child gets that child focused, whether it activates before or after mapping.
  • A second gtk4-demo started with a token takes focus. One started from the terminal without a token does not.
  • An already-running window and a hidden window are raised or unhidden by a valid token.
  • A delayed self-activation without a serial, a stale serial with only pointer focus, and foot's urgent bell all leave focus where it was and show attention.
  • New's child carries the token, and a client using it gets focus.

The core verify-kawa flow and a layer-shell smoke run with swaybg, waybar and fuzzel still pass.

Create the xdg_activation_v1 global and grant focus only for a token
that wlroots tied to a real input serial and whose surface had the
keyboard when the token was made or still has it. Tokens without a
surface are refused. A refused request marks the window as wanting
attention instead of moving focus. Requests can arrive before the
window maps, so an allowed one is remembered and applied on map.
Draw a window that was refused activation with the selection color
border, even if it draws its own decorations, and draw its hidden menu
entry in that color. Both clear when the window gets focus.
Export XDG_ACTIVATION_TOKEN and DESKTOP_STARTUP_ID from a token that
kawa creates and trusts, so that a program that supports either can
take focus when it opens its window.
@DeedleFake
DeedleFake merged commit 9ddeeda into master Oct 1, 2026
2 checks passed
@DeedleFake
DeedleFake deleted the xdg-activation branch October 1, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant