Skip to content

fix(xwm): Defer X11 focus release between same-client transitions#2029

Open
mayakwd wants to merge 1 commit intoSmithay:masterfrom
mayakwd:fix/x11-same-client-focus-transitions
Open

fix(xwm): Defer X11 focus release between same-client transitions#2029
mayakwd wants to merge 1 commit intoSmithay:masterfrom
mayakwd:fix/x11-same-client-focus-transitions

Conversation

@mayakwd
Copy link
Copy Markdown

@mayakwd mayakwd commented May 9, 2026

Description

X11Wm set _NET_ACTIVE_WINDOW = NONE for any FocusOut event on a tracked top-level window, ignoring detail field. It breaks X11 clients like Unity Editor.

Mechanism of the flaw:

  • the client gets focus at the top level and...
  • almost instantly switches focus to its sub-window.
  • X-server generates FocusOut(detail=inferior) for the top-level window.
  • code without fix just set _NET_ACTIVE_WINDOW to none, and...
  • there is no one to receive FocusIn.

But that's not the whole issue. X11Surface also synchronously calls set_input_focus(NONE, NONE), producing the intermediate state "focus is nowhere".

Fixes:

Works not only for cosmic-comp but also for other compositors based on Smithay, all of which suffer the same issue.

Symptoms

Symptoms are exactly as described in pop-os/cosmic-comp#2006:

  • Open a project in Unity
  • It's smooth and nice
  • Press Play, and experience a framerate dropped to 10 frames per second (Unity turns on throttling when losing focus, to not waste resources).
  • More than that, the keyboard and mouse are unresponsive inside Game view
  • Alt+tab and back - helps to return focus, but framerate is still down.

And many other related to input-unresponsiveness and sluggish experience, which cannot always be resolved by clicking other panels/alt-tabbing.

Diagnostics

Instrumentation wired into Smithay showed that:

  02:06:02.408  X11Surface::enter                          WINDOW=29360433 MODEL=LocallyActive
  02:06:02.412  xwm Event::FocusIn   WINDOW=29360433 detail=NONLINEAR tracked=true
  02:06:02.412  xwm: _NET_ACTIVE_WINDOW = window           WINDOW=29360433 
  02:06:02.462  xwm Event::FocusOut  WINDOW=29360433 detail=INFERIOR tracked=true
  02:06:02.462  xwm: _NET_ACTIVE_WINDOW = NONE             WINDOW=29360433   <-- issue

Meaning that Unity switched focus from the top level to a sub-window, but _NET_ACTIVE_WINDOW became none.

How the fix works

  • FocusOut now doesn't touch _NET_ACTIVE_WINDOW
  • Losing focus now deferred to the next event loop, leaving a space to cancel focus leaving for X11Wm.

What I've checked

  • Checked locally with cosmic-comp (no code was changed in cosmic-comp, only path to local version of smithay)
  • Unity Editor is no longer throttling
  • Switching between X11<->Wayland apps works as expected
  • No regression issues found

Checklist

The synchronous `set_input_focus(NONE, NONE)` in `X11Surface::leave`
breaks focus transitions between same-client windows. Defer the
focus-out decision to the next event-loop iteration so it can be
cancelled out.
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