gpui_linux: Clear X11 urgency hint when the window becomes active (#61619)

# Objective

On X11, GPUI raises the ICCCM `WM_HINTS` urgency flag to ask for
attention, but
it never clears it. The window stays urgent for the rest of its life.

`request_attention` was the only thing touching the bit. There was no
code
anywhere to clear it.

Docks and taskbars latch on the rising edge, so they show the attention
state
once and then sit there with a permanent urgent indicator, no further
notifications.

## Solution

Clear the flag when the window becomes active.

The read/modify/write moves out of `request_attention` into a helper,
`set_wm_hints_urgency(xcb, x_window, urgent)`. The raise and clear sites
are on
different self types (`X11Window` vs `X11WindowStatePtr`), so it takes
the
connection and window id.

The clear goes in `set_wm_properties`, where `state.active` gets set
from
`_NET_WM_STATE_FOCUSED`. That's the same field `request_attention`
already checks
in its `if self.is_active() { return; }` guard.

Two implementation notes:

* The clear is edge triggered (`state.active && !was_active`).
`set_wm_properties` recomputes everything on every `_NET_WM_STATE`
change, so a
level triggered check would do a blocking `WmHints::get` round trip on
every
maximize, fullscreen, hide and workspace switch while focused. Edge
triggering
is safe here because `request_attention` early returns when active, so
urgency
only ever gets raised while inactive, and the false to true transition
always
  follows a raise.
* Clearing reads the hints first and skips the write if the bit isn't
set.
Otherwise focusing a window that never asked for attention would create
a
  `WM_HINTS` property just to say "not urgent".

The raise path behaves exactly as before. The skip can't fire when
`urgent` is
true, so repeat raises still write every time.

Focusing clears the flag even if a second thread is still waiting.
That's already
how it works, since `request_attention` early returns when the window is
active.

## Testing

Tested on X11, Cinnamon with Muffin.

On an unpatched build the window had `_NET_WM_STATE_FOCUSED` and the
urgency bit
set at the same time.

    W=$(xdotool search --class "dev.zed.Zed" | head -1)
    xprop -id $W WM_HINTS
    xprop -spy -id $W WM_HINTS

1. Fresh window says `WM_HINTS: not found`, and still does after
focusing it.
2. With focus on another window, the urgency bit shows up when attention
is
requested. `request_attention` early returns when active, so the window
has to
   be unfocused for this to fire.
3. Focusing Zed clears the bit.
4. Repeating 2 and 3 re-arms it every cycle, not just once.
5. No `WM_HINTS` writes during normal use (resize, maximize, workspace
switch).

No automated test. It's an X11 round trip on a real window and there's
no X11
test harness in the tree.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (none added)
- [x] The content adheres to Zed's UI standards (no UI change)
- [x] Tests cover the new/changed behavior (see Testing)
- [x] Performance impact has been considered and is acceptable

Note this was manually tested, there wasn't a good way to test it
through the current harness.

---

Release Notes:

- Fixed the X11 urgency hint never being cleared, which left Zed showing
a permanent attention indicator in taskbars and docks after the first
notification
4d1935b8d0Josh Ellithorpe committed on 8/20/2026, 8:52:37 AM· committed by GitHubparentcef06d3
1 file changedLine totals unavailable