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

commit48f9f813e3577001494a0d2bdfa95c5a8872603d
parentcc5f05ec92
authorBonicgamer <[email protected]>
date2020-10-22 13:22
xwayland: make behavior more like xdg toplevels

- float fixed size xwayland windows by default
- align configure handling with that of xdg toplevel views

 river/View.zig         | 12 ++++++++++++
 river/XdgToplevel.zig  | 11 ++---------
 river/XwaylandView.zig | 28 +++++++++++++++++++++++-----
 3 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/river/View.zig b/river/View.zig
index 2e312f7..7ba48f0 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -242,6 +242,18 @@ pub fn saveBuffers(self: *Self) void {
     self.forEachSurface(saveBuffersIterator, &self.saved_buffers);
 }
 
+pub fn notifyConfiguredOrApplyPending(self: *Self) void {
+    self.pending_serial = null;
+    if (self.shouldTrackConfigure())
+        self.output.root.notifyConfigured()
+    else {
+        const self_tags_changed = self.pending.tags != self.current.tags;
+        self.current = self.pending;
+        self.commitOpacityTransition();
+        if (self_tags_changed) self.output.sendViewTags();
+    }
+}
+
 fn saveBuffersIterator(
     wlr_surface: ?*c.wlr_surface,
     surface_x: c_int,
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index ede27de..47fdd16 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -195,6 +195,7 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
 
     if (wlr_xdg_toplevel.parent != null or has_fixed_size) {
         // If the toplevel has a parent or has a fixed size make it float
+        view.current.float = true;
         view.pending.float = true;
         view.pending.box = view.float_box;
     } else {
@@ -259,15 +260,7 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
             // If this commit is in response to our configure and the
             // transaction code is tracking this configure, notify it.
             // Otherwise, apply the pending state immediately.
-            view.pending_serial = null;
-            if (view.shouldTrackConfigure())
-                view.output.root.notifyConfigured()
-            else {
-                const view_tags_changed = view.pending.tags != view.current.tags;
-                view.current = view.pending;
-                view.commitOpacityTransition();
-                if (view_tags_changed) view.output.sendViewTags();
-            }
+            view.notifyConfiguredOrApplyPending();
         } else {
             // If the client has not yet acked our configure, we need to send a
             // frame done event so that it commits another buffer. These
diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig
index 2959624..909cfe3 100644
--- a/river/XwaylandView.zig
+++ b/river/XwaylandView.zig
@@ -165,6 +165,28 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     view.float_box.y = std.math.max(0, @divTrunc(@intCast(i32, view.output.usable_box.height) -
         @intCast(i32, view.float_box.height), 2));
 
+    const size_hints = self.wlr_xwayland_surface.size_hints;
+    const has_fixed_size = size_hints.*.min_width != 0 and size_hints.*.min_height != 0 and
+        (size_hints.*.min_width == size_hints.*.max_width or size_hints.*.min_height == size_hints.*.max_height);
+    const app_id: [*:0]const u8 = if (self.wlr_xwayland_surface.class) |id| id else "NULL";
+
+    if (self.wlr_xwayland_surface.parent != null or has_fixed_size) {
+        // If the toplevel has a parent or has a fixed size make it float
+        view.current.float = true;
+        view.pending.float = true;
+        view.pending.box = view.float_box;
+    } else {
+        // Make views with app_ids listed in the float filter float
+        for (root.server.config.float_filter.items) |filter_app_id| {
+            if (std.mem.eql(u8, std.mem.span(app_id), std.mem.span(filter_app_id))) {
+                view.current.float = true;
+                view.pending.float = true;
+                view.pending.box = view.float_box;
+                break;
+            }
+        }
+    }
+
     view.map();
 }
 
@@ -195,10 +217,6 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     if (view.pending_serial != null) {
         // If the view is part of the layout, notify the transaction code. If
         // the view is floating or fullscreen apply the pending state immediately.
-        view.pending_serial = null;
-        if (!view.pending.float and !view.pending.fullscreen)
-            view.output.root.notifyConfigured()
-        else
-            view.current = view.pending;
+        view.notifyConfiguredOrApplyPending();
     }
 }