fix(x11): correct XDBE swap presentation on Xwayland (font thickening + frame repeat)#2369
fix(x11): correct XDBE swap presentation on Xwayland (font thickening + frame repeat)#2369tmineno wants to merge 4 commits into
Conversation
XdbeBackground is supposed to reset the back buffer to the window background after each swap, but some drivers (notably under Xwayland and certain NVIDIA setups) ignore it. The back buffer then keeps the previous frame, so antialiased glyphs blend onto themselves and fonts appear to thicken — most visibly when other windows overlap conky and trigger extra redraws. Clear the back buffer explicitly with XFillRectangle after the swap, mirroring the XPMDB path.
✅ Deploy Preview for conkyweb canceled.
|
A swap left in the X output buffer is flushed lazily (on the next request that forces a flush). Under Xwayland the compositor can then coalesce/reorder it with later requests and momentarily re-present the previous frame -- a visible "frame repeat", e.g. a clock's seconds briefly bouncing back (40 -> 39 -> 40) right at the boundary. XSync after the swap blocks until the server has processed it, yielding a clean, ordered present. A plain XFlush only queues the request and is not enough (verified: XFlush still bounces, XSync does not).
|
How does XPMDB work for you? I'm asking because XPMDB path is much closer to how Wayland side works and also how most GUI toolkits handled double buffering on X11 (not relying on Xdbe ext - even though now it's always provided). I was hoping to remove one or the other and make it so that X11 just uses Cairo if it's included the same way Wayland does (pipeline unification), after Cairo rendering backend is up-to-speed of course. |
The XPMDB present had two Xwayland-specific issues that together caused an intermittent whole-window blank flicker (background-only for a frame, even when idle): 1. The XCopyArea was flushed with XFlush, which only queues the request, so the compositor could pick it up mid-update. XSync after the copy blocks until the server has processed it, giving a clean, ordered present -- the same fix already applied to the XDBE path. 2. The XCopyArea inherited the GC's dirty-region clip and so refreshed only the changed area, whereas XdbeSwapBuffers always presents the whole window. Under Xwayland the window's backing buffer does not reliably persist the previous frame between presents, so a partial copy leaves the rest blank. Drop the clip before the copy so the full window is always presented; the XPMDB path redraws the full text rect every frame, so clearing the whole back buffer afterward stays safe.
|
@Caellian Tested it — built with
XPMDB's copy-to-window model maps better onto the Wayland/Cairo path, so +1 on consolidating there. I've added both fixes to the XPMDB path in this PR. |
|
Correction to "solid": longer soak shows a rare residual blank-frame flicker, and it's on the XDBE path too (the shipped build with both fixes) — so not XPMDB-specific. Whole-window present and |
|
Here's a patch for Mutter that adds If you go with it, match the version you already have on your system and apply the patch on top. It might yield better or worse results depending on how extensively you're using conky (cairo backend is not complete). |
Two related fixes for XDBE double-buffering under Xwayland (and drivers where
XdbeBackgroundis unreliable). Found while running conky as an X11 client on GNOME/Mutter + NVIDIA.1. Back buffer not cleared -> fonts thicken (
ec9bc11)In the XDBE path
clear_text()is a no-op and the back buffer is only ever reset via theXdbeBackgroundswap action. Some drivers don't honor it (notably under Xwayland and certain NVIDIA setups); the back buffer then keeps the previous frame, so antialiased glyphs blend on top of themselves and fonts appear to thicken over time -- most visibly when other windows overlap conky and trigger extra redraws.Fix: clear the back buffer explicitly with
XFillRectangleafter the swap, mirroring the existing XPMDB path.2. Deferred swap -> momentary frame repeat (
b3e0409)The swap was left in the X output buffer and flushed lazily. Under Xwayland the compositor can coalesce/reorder it with later requests and momentarily re-present the previous frame -- a visible "frame repeat" (e.g. a clock's seconds bouncing back, 40 -> 39 -> 40, at the boundary).
Fix:
XSyncafter the swap so the server processes it before conky proceeds, giving a clean, ordered present. A plainXFlushonly queues the request and is not enough (verified empirically: XFlush still bounces, XSync does not).Blast radius
double_buffer = trueon XDBE builds only. XPMDB builds, Wayland output, anddouble_buffer = falseare unchanged.XdbeBackgroundalready works, the explicit clear is a redundant reset (identical output).Testing
Verified on Xwayland + Mutter (GNOME) + NVIDIA with an ARGB (semi-transparent)
own_window_colouranddouble_buffer = true: no font thickening on overlap, no frame-repeat at the second boundary.