zed/crates/gpui_linux
mTvare f4178619ac
gpui_linux: Drain buffered X11 events after foreground work (#62081)
# Objective

Closes #52429
Closes #56735
Closes #62495
Closes #62878

Reverts #13071

This PR fixes Zed windows sometimes remaining blank when first opened on
X11.

The issue remained very inconsistent across WMs and conditions to
reproduce and was finally consistently reproducable on my dwm build with
no compositor and on i3 with no compositor after removing the workaround
earlier added, which made it occur in i3 but not on my dwm build because
it was more aggressive with it's EWMH policy. It happened only on
opening a newer repo not opened the last time.

While running foreground work, a synchronous X11 request can read events
from the socket and place them in x11rb's internal event queue, calloop
monitors the underlying socket rather than this internal queue, so if
the socket is empty when the foreground work finishes, these events may
remain unprocessed until unrelated X11 activity occurs.

window is mapped -> events are buffered by x11rb
-> X11 socket is no longer readable
-> calloop does not wake
-> MapNotify is not processed
-> refresh loop does not start
-> window remains blank


This explains why the problem was inconsistent and differed between
window managers. Later focus, scrolling (on any window), exposure, or
other X11 activity could make the connection readable again and
incidentally process the older events.

My earlier PR #61162 fixed the related case where an already processed
`Expose` event could wait indefinitely for a stopped refresh loop. It
did not fix this initial-window case because the relevant events had not
reached Zed's event handler yet, which was again not perfectly
reproducable and lead me to assume was fixed.

## Solution

Process any X11 events buffered by x11rb after each foreground runnable
completes:

foreground work completes
-> buffered X11 events are processed
-> MapNotify starts the refresh loop
-> initial window contents are displayed

This also removes the unconditional
[`SetInputFocus`](https://tronche.com/gui/x/xlib/input/XSetInputFocus.html)
added in #13071. That call frequently masked the issue by generating
additional X11 activity, but also bypassed the window manager's focus
policy despite Zed already sending the standard `_NET_ACTIVE_WINDOW`
request.

With the event queue handled correctly, Zed no longer needs to force
focus to make the initial frame appear.

## Testing

Repeatedly opened fresh and existing workspaces under dwm while another
application retained focus with a new-project being opened everytime (at
least not the previous one).

Before this change, fresh windows could remain blank until later X11
activity occurred. After this change, they render immediately without
focusing, scrolling, resizing, or switching workspaces.

Also verified that window activation is left to the window manager
through `_NET_ACTIVE_WINDOW`.

## Self-Review Checklist:

* [x] I've reviewed my own diff for quality, security, and reliability
* [x] Unsafe blocks (if any) have justifying comments
* [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
* [ ] Tests cover the new/changed behavior
* [x] Performance impact has been considered and is acceptable

Release Notes:

* Fixed Zed windows sometimes remaining blank when first opened on X11
* Fixed Zed overriding window-manager focus policies when activating
windows
2026-08-20 15:01:09 +00:00
..
src gpui_linux: Drain buffered X11 events after foreground work (#62081) 2026-08-20 15:01:09 +00:00
Cargo.toml Switch from cargo-machete to cargo-shear (#62643) 2026-08-20 10:08:48 +00:00
LICENSE-APACHE