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

commitac62676b03addec2538608a711edc95d87728d24
parentc13bca08b0
authorIsaac Freund <[email protected]>
date2025-12-27 22:25
protocol: add river_window_v1.unreliable_pid

 protocol/river-window-management-v1.xml | 16 ++++++++++++++++
 river/Window.zig                        | 17 +++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/protocol/river-window-management-v1.xml b/protocol/river-window-management-v1.xml
index ea621aa..525373d 100644
--- a/protocol/river-window-management-v1.xml
+++ b/protocol/river-window-management-v1.xml
@@ -966,6 +966,22 @@
       <arg name="width" type="int"/>
       <arg name="height" type="int"/>
     </request>
+
+    <event name="unreliable_pid" since="2">
+      <description summary="unreliable PID of the window's creator">
+        This event gives an unreliable PID of the process that created the
+        window. Obtaining this information is inherently racy due to PID reuse.
+        Therefore, this PID must not be used for anything security sensitive.
+
+        Note also that a single process may create multiple windows, so there is
+        not necessarily a 1-to-1 mapping from PID to window. Multiple windows
+        may have the same PID.
+
+        This event is sent once when the river_window_v1 is created and never
+        sent again.
+      </description>
+      <arg name="unreliable_pid" type="int"/>
+    </event>
   </interface>
 
   <interface name="river_decoration_v1" version="2">
diff --git a/river/Window.zig b/river/Window.zig
index 190fce2..8d5609e 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -383,6 +383,12 @@ pub fn manageStart(window: *Window) void {
             };
             errdefer comptime unreachable;
 
+            if (new) {
+                if (window_v1.getVersion() >= 2) {
+                    window_v1.sendUnreliablePid(window.unreliablePid());
+                }
+            }
+
             const scheduled = &window.wm_scheduled;
             const sent = &window.wm_sent;
 
@@ -940,6 +946,17 @@ pub fn getParent(window: *Window) ?*Window {
     }
 }
 
+pub fn unreliablePid(window: *Window) i32 {
+    switch (window.impl) {
+        .toplevel => |toplevel| {
+            const client = toplevel.wlr_toplevel.base.surface.resource.getClient();
+            return client.getCredentials().pid;
+        },
+        .xwayland => |xwindow| return xwindow.xsurface.pid,
+        .destroying => unreachable,
+    }
+}
+
 /// Return the current title of the window if any.
 pub fn getTitle(window: Window) ?[*:0]const u8 {
     return switch (window.impl) {