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

commit846ed96b4e4a6acf0d2eff0031eb5163035bcfb1
parentce9c83addd
authorLeon Henrik Plickat <[email protected]>
date2022-08-14 17:16
river-status: expose current layout name

 protocol/river-status-unstable-v1.xml | 19 +++++++++++++++++--
 river/Layout.zig                      | 12 ++++++++++++
 river/Output.zig                      | 15 +++++++++++++++
 river/OutputStatus.zig                | 16 ++++++++++++++++
 4 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/protocol/river-status-unstable-v1.xml b/protocol/river-status-unstable-v1.xml
index 6a74256..f6bc091 100644
--- a/protocol/river-status-unstable-v1.xml
+++ b/protocol/river-status-unstable-v1.xml
@@ -16,7 +16,7 @@
     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   </copyright>
 
-  <interface name="zriver_status_manager_v1" version="3">
+  <interface name="zriver_status_manager_v1" version="4">
     <description summary="manage river status objects">
       A global factory for objects that receive status information specific
       to river. It could be used to implement, for example, a status bar.
@@ -47,7 +47,7 @@
     </request>
   </interface>
 
-  <interface name="zriver_output_status_v1" version="2">
+  <interface name="zriver_output_status_v1" version="4">
     <description summary="track output tags and focus">
       This interface allows clients to receive information about the current
       windowing state of an output.
@@ -83,6 +83,21 @@
       </description>
       <arg name="tags" type="uint" summary="32-bit bitfield"/>
     </event>
+
+    <event name="layout_name" since="3">
+      <description summary="name of the layout">
+        Sent once on binding the interface should a layout name exist and again
+        whenever the name changes.
+      </description>
+      <arg name="name" type="string" summary="layout name"/>
+    </event>
+
+    <event name="layout_name_clear" since="3">
+      <description summary="name of the layout">
+        Sent when the current layout name has been removed without a new one
+        being set, for example whent the active layout generator disconnects.
+      </description>
+    </event>
   </interface>
 
   <interface name="zriver_seat_status_v1" version="3">
diff --git a/river/Layout.zig b/river/Layout.zig
index 1dfc136..35b726f 100644
--- a/river/Layout.zig
+++ b/river/Layout.zig
@@ -161,6 +161,12 @@ fn handleRequest(layout: *river.LayoutV3, request: river.LayoutV3.Request, self:
                 // Therefore, simply ignore requests with old/wrong serials.
                 if (layout_demand.serial == req.serial) layout_demand.apply(self);
             }
+
+            if (self.output.layout_name) |name| {
+                util.gpa.free(name);
+            }
+            self.output.layout_name = util.gpa.dupeZ(u8, mem.span(req.layout_name)) catch null;
+            self.output.sendLayoutName();
         },
     }
 }
@@ -187,6 +193,12 @@ pub fn destroy(self: *Self) void {
             self.output.layout_demand = null;
             server.root.notifyLayoutDemandDone();
         }
+
+        if (self.output.layout_name) |name| {
+            util.gpa.free(name);
+            self.output.layout_name = null;
+            self.output.sendLayoutNameClear();
+        }
     }
 
     self.layout.setHandler(?*anyopaque, handleRequestInert, null, null);
diff --git a/river/Output.zig b/river/Output.zig
index 59edff7..3cb6879 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -88,6 +88,9 @@ layouts: std.TailQueue(Layout) = .{},
 /// Call handleLayoutNamespaceChange() after setting this.
 layout_namespace: ?[]const u8 = null,
 
+/// The last set layout name.
+layout_name: ?[:0]const u8 = null,
+
 /// Bitmask that whitelists tags for newly spawned views
 spawn_tagmask: u32 = math.maxInt(u32),
 
@@ -180,6 +183,18 @@ pub fn sendUrgentTags(self: Self) void {
     while (it) |node| : (it = node.next) node.data.sendUrgentTags(urgent_tags);
 }
 
+pub fn sendLayoutName(self: Self) void {
+    std.debug.assert(self.layout_name != null);
+    var it = self.status_trackers.first;
+    while (it) |node| : (it = node.next) node.data.sendLayoutName(self.layout_name.?);
+}
+
+pub fn sendLayoutNameClear(self: Self) void {
+    std.debug.assert(self.layout_name == null);
+    var it = self.status_trackers.first;
+    while (it) |node| : (it = node.next) node.data.sendLayoutNameClear();
+}
+
 pub fn arrangeFilter(view: *View, filter_tags: u32) bool {
     return view.surface != null and !view.pending.float and !view.pending.fullscreen and
         view.pending.tags & filter_tags != 0;
diff --git a/river/OutputStatus.zig b/river/OutputStatus.zig
index baf4d01..fc5b67e 100644
--- a/river/OutputStatus.zig
+++ b/river/OutputStatus.zig
@@ -47,6 +47,10 @@ pub fn init(self: *Self, output: *Output, output_status: *zriver.OutputStatusV1)
         if (node.view.current.urgent) urgent_tags |= node.view.current.tags;
     }
     self.sendUrgentTags(urgent_tags);
+
+    if (output.layout_name) |name| {
+        self.sendLayoutName(name);
+    }
 }
 
 pub fn destroy(self: *Self) void {
@@ -94,3 +98,15 @@ pub fn sendUrgentTags(self: Self, tags: u32) void {
         self.output_status.sendUrgentTags(tags);
     }
 }
+
+pub fn sendLayoutName(self: Self, name: [:0]const u8) void {
+    if (self.output_status.getVersion() >= 4) {
+        self.output_status.sendLayoutName(name);
+    }
+}
+
+pub fn sendLayoutNameClear(self: Self) void {
+    if (self.output_status.getVersion() >= 4) {
+        self.output_status.sendLayoutNameClear();
+    }
+}