git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitebee8be4216b6e14f501729d2deeb8fb6f893873
parentae7b2952ef
authorIsaac Freund <[email protected]>
date2026-02-13 10:28
Xwayland: send configure on renderFinish() as well

This ensures that Xwayland windows are always provided with the most
up-to-date position possible.

 river/Window.zig         | 5 +++++
 river/XwaylandWindow.zig | 7 +++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/river/Window.zig b/river/Window.zig
index 2deeae6..340952e 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -847,6 +847,11 @@ pub fn renderFinish(window: *Window) void {
     window.tree.node.setPosition(window.box.x, window.box.y);
     window.popup_tree.node.setPosition(window.box.x, window.box.y);
 
+    switch (window.impl) {
+        .xwayland => |*xwindow| _ = xwindow.configure(),
+        .toplevel, .destroying => {},
+    }
+
     window.applySurfaceClip(&clip, &content_clip);
     inline for (.{ &window.decorations_above, &window.decorations_below }) |decorations| {
         var it = decorations.iterator(.forward);
diff --git a/river/XwaylandWindow.zig b/river/XwaylandWindow.zig
index 98a931f..adea211 100644
--- a/river/XwaylandWindow.zig
+++ b/river/XwaylandWindow.zig
@@ -99,8 +99,11 @@ pub fn configure(xwindow: *XwaylandWindow) bool {
     const width = scheduled.width orelse xwindow.xsurface.width;
     const height = scheduled.height orelse xwindow.xsurface.height;
 
-    // Yes it's technically wrong to send rendering_requested state
-    // here, but we don't care about frame perfection for X11 windows.
+    // Unlike native Wayland windows, we need to tell X11 windows about their
+    // position. However, river does not necessarily know the new position
+    // until after a rendering sequence is completed. Therefore, configure()
+    // is called both on manageFinish() and renderFinish() for Xwayland windows.
+    // Frame perfection is not achievable for Xwayland windows in any case.
     if (window.rendering_requested.x != xwindow.xsurface.x or
         window.rendering_requested.y != xwindow.xsurface.y or
         width != xwindow.xsurface.width or