On Thu Feb 19 15:42:17 2026 +0000, Gabriel Ivăncescu wrote:
I forgot to mention it happens with just spawning winecfg, simplest testcase possible. It doesn't receive focus. According to ICCCM, the WM does not unilaterally activate a client window on map without the client's participation when WM_TAKE_FOCUS or similar semantics apply. And _NET_ACTIVE_WINDOW (which is what is needed) is not assumed explicitly and has to be sent manually, but that never happens since we return early. `WM_TAKE_FOCUS` reply is delayed when there's a `WM_STATE` change pending. We expect to receive the `WM_STATE` PropertyNotify before we can decide whether to accept or not focus, because it's otherwise possible to have multiple `WM_STATE` changes pending in sequence (either for one window that gets mapped/minimized/mapped in short sequence, or because another window is being mapped at the same time), and we need that sequence to complete before we decide which one wins the focus race or we may trigger more race conditions.
This is not delayed wrt. the _NET_ACTIVE_WINDOW requests, so changing the pending_state.active_window or its serial isn't going to make any difference there. The issue might be that the WM sends `WM_TAKE_FOCUS` first, before actually changing the `WM_STATE` property, and doesn't send more `WM_TAKE_FOCUS` requests after that? Note that `handle_wm_state_notify` also tries to explicitly activate the window again for cases like this, so it's unclear why this doesn't work for you. Fwiw window activation works fine with every WM I have tried, Mutter, Kwin, Openbox, Fvwm.
But the point is that the pending_state should be set when we actually have a pending operation on it, not a no-op. I don't understand what sense does it make to have the pending state set to something that we haven't actually requested (and thus isn't pending)???
Sure, it's a bit weird, but that is meant to work with the GetWindowStateUpdates side or things, to delay changes that would make Win32 active window match the X11 one, if we have just requested explicit window activation, or if we're about to map a window. In the latter case ActivateWindow is called before the WindowPosChanged call that will trigger the mapping of the window, this is a bit unfortunate and could perhaps be changed to make it less awkward but it's a bit delicate to get it right. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10133#note_129967