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

commit1b6d6598951b155ed29112eba6c3d988293e3504
parent8acf947bbe
authorIsaac Freund <[email protected]>
date2022-01-12 14:50
XdgPopup: fix unconstrain from box coords

We currently don't properly handle xdg surface geometry of the parent,
which causes popups to render partially off-screen in some cases.

GTK4 clients such as easyeffects seem to trigger this issue reliably.

 river/XdgPopup.zig | 42 ++++++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig
index 864d69d..95e504b 100644
--- a/river/XdgPopup.zig
+++ b/river/XdgPopup.zig
@@ -54,25 +54,31 @@ pub fn create(wlr_xdg_popup: *wlr.XdgPopup, parent: Parent) void {
     assert(wlr_xdg_popup.base.data == 0);
     wlr_xdg_popup.base.data = @ptrToInt(xdg_popup);
 
-    const parent_box = switch (parent) {
-        .xdg_toplevel => |xdg_toplevel| &xdg_toplevel.view.pending.box,
-        .layer_surface => |layer_surface| &layer_surface.box,
+    switch (parent) {
+        .xdg_toplevel => |xdg_toplevel| {
+            const output_dimensions = xdg_toplevel.view.output.getEffectiveResolution();
+            // The output box relative to the parent of the xdg_popup
+            var box = wlr.Box{
+                .x = xdg_toplevel.view.surface_box.x - xdg_toplevel.view.pending.box.x,
+                .y = xdg_toplevel.view.surface_box.y - xdg_toplevel.view.pending.box.y,
+                .width = @intCast(c_int, output_dimensions.width),
+                .height = @intCast(c_int, output_dimensions.height),
+            };
+            wlr_xdg_popup.unconstrainFromBox(&box);
+        },
+        .layer_surface => |layer_surface| {
+            const output_dimensions = layer_surface.output.getEffectiveResolution();
+            // The output box relative to the parent of the xdg_popup
+            var box = wlr.Box{
+                .x = layer_surface.box.x,
+                .y = layer_surface.box.y,
+                .width = @intCast(c_int, output_dimensions.width),
+                .height = @intCast(c_int, output_dimensions.height),
+            };
+            wlr_xdg_popup.unconstrainFromBox(&box);
+        },
         .drag_icon => unreachable,
-    };
-    const output_dimensions = switch (parent) {
-        .xdg_toplevel => |xdg_toplevel| xdg_toplevel.view.output.getEffectiveResolution(),
-        .layer_surface => |layer_surface| layer_surface.output.getEffectiveResolution(),
-        .drag_icon => unreachable,
-    };
-
-    // The output box relative to the parent of the xdg_popup
-    var box = wlr.Box{
-        .x = -parent_box.x,
-        .y = -parent_box.y,
-        .width = @intCast(c_int, output_dimensions.width),
-        .height = @intCast(c_int, output_dimensions.height),
-    };
-    wlr_xdg_popup.unconstrainFromBox(&box);
+    }
 
     wlr_xdg_popup.base.events.destroy.add(&xdg_popup.surface_destroy);
     wlr_xdg_popup.base.events.map.add(&xdg_popup.map);