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

commit0acedfeac3fd8f355a905219a84c9115bacfd0a3
parentc48d171faa
authorIsaac Freund <[email protected]>
date2024-06-28 10:02
river: remove river-status-unstable-v1

 CONTRIBUTING.md                       |   4 +-
 build.zig                             |   2 -
 protocol/river-status-unstable-v1.xml | 148 -----------------------------
 river/Layout.zig                      |   2 -
 river/Output.zig                      |   6 --
 river/OutputStatus.zig                | 172 ----------------------------------
 river/Root.zig                        |   5 -
 river/Seat.zig                        |  23 -----
 river/SeatStatus.zig                  |  80 ----------------
 river/Server.zig                      |   5 -
 river/StatusManager.zig               | 112 ----------------------
 river/View.zig                        |  10 --
 12 files changed, 2 insertions(+), 567 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1c5d6d8..324ef6d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -16,13 +16,13 @@ change, followed by a brief summary.
 For example:
 
 ```
-build: scan river-status protocol
+build: add -Dxwayland option
 ```
 
 or
 
 ```
-river-status: send view_tags on view map/unmap
+Keyboard: fix redundant leave/enter on creation
 ```
 
 In addition to the summary, feel free to add any other details you want preceded
diff --git a/build.zig b/build.zig
index 93dafd3..8cb11f8 100644
--- a/build.zig
+++ b/build.zig
@@ -100,7 +100,6 @@ pub fn build(b: *Build) !void {
     scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml");
 
     scanner.addCustomProtocol("protocol/river-control-unstable-v1.xml");
-    scanner.addCustomProtocol("protocol/river-status-unstable-v1.xml");
     scanner.addCustomProtocol("protocol/river-layout-v3.xml");
     scanner.addCustomProtocol("protocol/wlr-layer-shell-unstable-v1.xml");
     scanner.addCustomProtocol("protocol/wlr-output-power-management-unstable-v1.xml");
@@ -126,7 +125,6 @@ pub fn build(b: *Build) !void {
     scanner.generate("wp_cursor_shape_manager_v1", 1);
 
     scanner.generate("zriver_control_v1", 1);
-    scanner.generate("zriver_status_manager_v1", 4);
     scanner.generate("river_layout_manager_v3", 2);
 
     scanner.generate("zwlr_layer_shell_v1", 4);
diff --git a/protocol/river-status-unstable-v1.xml b/protocol/river-status-unstable-v1.xml
deleted file mode 100644
index e9629dd..0000000
--- a/protocol/river-status-unstable-v1.xml
+++ /dev/null
@@ -1,148 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="river_status_unstable_v1">
-  <copyright>
-    Copyright 2020 The River Developers
-
-    Permission to use, copy, modify, and/or distribute this software for any
-    purpose with or without fee is hereby granted, provided that the above
-    copyright notice and this permission notice appear in all copies.
-
-    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-  </copyright>
-
-  <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.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the river_status_manager object">
-        This request indicates that the client will not use the
-        river_status_manager object any more. Objects that have been created
-        through this instance are not affected.
-      </description>
-    </request>
-
-    <request name="get_river_output_status">
-      <description summary="create an output status object">
-        This creates a new river_output_status object for the given wl_output.
-      </description>
-      <arg name="id" type="new_id" interface="zriver_output_status_v1"/>
-      <arg name="output" type="object" interface="wl_output"/>
-    </request>
-
-    <request name="get_river_seat_status">
-      <description summary="create a seat status object">
-        This creates a new river_seat_status object for the given wl_seat.
-      </description>
-      <arg name="id" type="new_id" interface="zriver_seat_status_v1"/>
-      <arg name="seat" type="object" interface="wl_seat"/>
-    </request>
-  </interface>
-
-  <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.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the river_output_status object">
-        This request indicates that the client will not use the
-        river_output_status object any more.
-      </description>
-    </request>
-
-    <event name="focused_tags">
-      <description summary="focused tags of the output">
-        Sent once binding the interface and again whenever the tag focus of
-        the output changes.
-      </description>
-      <arg name="tags" type="uint" summary="32-bit bitfield"/>
-    </event>
-
-    <event name="view_tags">
-      <description summary="tag state of an output's views">
-        Sent once on binding the interface and again whenever the tag state
-        of the output changes.
-      </description>
-      <arg name="tags" type="array" summary="array of 32-bit bitfields"/>
-    </event>
-
-    <event name="urgent_tags" since="2">
-      <description summary="tags of the output with an urgent view">
-        Sent once on binding the interface and again whenever the set of
-        tags with at least one urgent view changes.
-      </description>
-      <arg name="tags" type="uint" summary="32-bit bitfield"/>
-    </event>
-
-    <event name="layout_name" since="4">
-      <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="4">
-      <description summary="name of the layout">
-        Sent when the current layout name has been removed without a new one
-        being set, for example when the active layout generator disconnects.
-      </description>
-    </event>
-  </interface>
-
-  <interface name="zriver_seat_status_v1" version="3">
-    <description summary="track seat focus">
-      This interface allows clients to receive information about the current
-      focus of a seat. Note that (un)focused_output events will only be sent
-      if the client has bound the relevant wl_output globals.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the river_seat_status object">
-        This request indicates that the client will not use the
-        river_seat_status object any more.
-      </description>
-    </request>
-
-    <event name="focused_output">
-      <description summary="the seat focused an output">
-        Sent on binding the interface and again whenever an output gains focus.
-      </description>
-      <arg name="output" type="object" interface="wl_output"/>
-    </event>
-
-    <event name="unfocused_output">
-      <description summary="the seat unfocused an output">
-        Sent whenever an output loses focus.
-      </description>
-      <arg name="output" type="object" interface="wl_output"/>
-    </event>
-
-    <event name="focused_view">
-      <description summary="information on the focused view">
-        Sent once on binding the interface and again whenever the focused
-        view or a property thereof changes. The title may be an empty string
-        if no view is focused or the focused view did not set a title.
-      </description>
-      <arg name="title" type="string" summary="title of the focused view"/>
-    </event>
-
-    <event name="mode" since="3">
-      <description summary="the active mode changed">
-        Sent once on binding the interface and again whenever a new mode
-        is entered (e.g. with riverctl enter-mode foobar).
-      </description>
-      <arg name="name" type="string" summary="name of the mode"/>
-    </event>
-  </interface>
-</protocol>
diff --git a/river/Layout.zig b/river/Layout.zig
index 858cd08..6bd107f 100644
--- a/river/Layout.zig
+++ b/river/Layout.zig
@@ -169,7 +169,6 @@ fn handleRequest(layout_v3: *river.LayoutV3, request: river.LayoutV3.Request, la
                 };
                 if (layout.output.layout_name) |name| util.gpa.free(name);
                 layout.output.layout_name = owned;
-                layout.output.status.sendLayoutName(layout.output);
             }
         },
     }
@@ -201,7 +200,6 @@ pub fn destroy(layout: *Layout) void {
         if (layout.output.layout_name) |name| {
             util.gpa.free(name);
             layout.output.layout_name = null;
-            layout.output.status.sendLayoutNameClear(layout.output);
         }
     }
 
diff --git a/river/Output.zig b/river/Output.zig
index e449f3f..d391314 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -34,7 +34,6 @@ const LayerSurface = @import("LayerSurface.zig");
 const Layout = @import("Layout.zig");
 const LayoutDemand = @import("LayoutDemand.zig");
 const LockSurface = @import("LockSurface.zig");
-const OutputStatus = @import("OutputStatus.zig");
 const SceneNodeData = @import("SceneNodeData.zig");
 const View = @import("View.zig");
 const Config = @import("Config.zig");
@@ -192,8 +191,6 @@ layout_name: ?[:0]const u8 = null,
 /// affect already floating views.
 layout: ?*Layout = null,
 
-status: OutputStatus,
-
 destroy: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleDestroy),
 request_state: wl.Listener(*wlr.Output.event.RequestState) = wl.Listener(*wlr.Output.event.RequestState).init(handleRequestState),
 frame: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleFrame),
@@ -293,7 +290,6 @@ pub fn create(wlr_output: *wlr.Output) !void {
             .width = width,
             .height = height,
         },
-        .status = undefined,
     };
     wlr_output.data = @intFromPtr(output);
 
@@ -302,8 +298,6 @@ pub fn create(wlr_output: *wlr.Output) !void {
     output.inflight.focus_stack.init();
     output.inflight.wm_stack.init();
 
-    output.status.init();
-
     _ = try output.layers.fullscreen.createSceneRect(width, height, &[_]f32{ 0, 0, 0, 1.0 });
     output.layers.fullscreen.node.setEnabled(false);
 
diff --git a/river/OutputStatus.zig b/river/OutputStatus.zig
deleted file mode 100644
index 7e05cf8..0000000
--- a/river/OutputStatus.zig
+++ /dev/null
@@ -1,172 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2020 The River Developers
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-const OutputStatus = @This();
-
-const std = @import("std");
-const assert = std.debug.assert;
-
-const wayland = @import("wayland");
-const wl = wayland.server.wl;
-const zriver = wayland.server.zriver;
-
-const util = @import("util.zig");
-
-const Output = @import("Output.zig");
-const View = @import("View.zig");
-
-const log = std.log.scoped(.river_status);
-
-resources: wl.list.Head(zriver.OutputStatusV1, null),
-view_tags: std.ArrayListUnmanaged(u32) = .{},
-focused_tags: u32 = 0,
-urgent_tags: u32 = 0,
-
-pub fn init(status: *OutputStatus) void {
-    status.* = .{
-        .resources = undefined,
-    };
-    status.resources.init();
-}
-
-pub fn add(status: *OutputStatus, resource: *zriver.OutputStatusV1, output: *Output) void {
-    resource.setHandler(?*anyopaque, handleRequest, handleDestroy, null);
-
-    var wl_array: wl.Array = .{
-        .size = status.view_tags.items.len * @sizeOf(u32),
-        .alloc = status.view_tags.items.len * @sizeOf(u32),
-        .data = status.view_tags.items.ptr,
-    };
-    resource.sendViewTags(&wl_array);
-    resource.sendFocusedTags(status.focused_tags);
-    if (resource.getVersion() >= 2) resource.sendUrgentTags(status.urgent_tags);
-    if (resource.getVersion() >= 4) {
-        if (output.layout_name) |name| resource.sendLayoutName(name);
-    }
-
-    status.resources.append(resource);
-}
-
-pub fn deinit(status: *OutputStatus) void {
-    {
-        var it = status.resources.safeIterator(.forward);
-        while (it.next()) |resource| {
-            resource.setHandler(?*anyopaque, handleRequest, null, null);
-            resource.getLink().remove();
-        }
-    }
-    status.view_tags.deinit(util.gpa);
-}
-
-fn handleRequest(resource: *zriver.OutputStatusV1, request: zriver.OutputStatusV1.Request, _: ?*anyopaque) void {
-    switch (request) {
-        .destroy => resource.destroy(),
-    }
-}
-
-fn handleDestroy(resource: *zriver.OutputStatusV1, _: ?*anyopaque) void {
-    resource.getLink().remove();
-}
-
-pub fn handleTransactionCommit(status: *OutputStatus, output: *Output) void {
-    status.sendViewTags(output);
-    status.sendFocusedTags(output);
-    status.sendUrgentTags(output);
-}
-
-fn sendViewTags(status: *OutputStatus, output: *Output) void {
-    var dirty: bool = false;
-    {
-        var it = output.inflight.wm_stack.iterator(.forward);
-        var i: usize = 0;
-        while (it.next()) |view| : (i += 1) {
-            assert(view.inflight.tags == view.current.tags);
-            if (status.view_tags.items.len <= i) {
-                dirty = true;
-                _ = status.view_tags.addOne(util.gpa) catch {
-                    log.err("out of memory", .{});
-                    return;
-                };
-            } else if (view.inflight.tags != status.view_tags.items[i]) {
-                dirty = true;
-            }
-            status.view_tags.items[i] = view.inflight.tags;
-        }
-
-        if (i != status.view_tags.items.len) {
-            assert(i < status.view_tags.items.len);
-            status.view_tags.items.len = i;
-            dirty = true;
-        }
-    }
-
-    if (dirty) {
-        var wl_array: wl.Array = .{
-            .size = status.view_tags.items.len * @sizeOf(u32),
-            .alloc = status.view_tags.items.len * @sizeOf(u32),
-            .data = status.view_tags.items.ptr,
-        };
-        var it = status.resources.iterator(.forward);
-        while (it.next()) |resource| resource.sendViewTags(&wl_array);
-    }
-}
-
-fn sendFocusedTags(status: *OutputStatus, output: *Output) void {
-    assert(output.inflight.tags == output.current.tags);
-    if (status.focused_tags != output.inflight.tags) {
-        status.focused_tags = output.inflight.tags;
-
-        var it = status.resources.iterator(.forward);
-        while (it.next()) |resource| resource.sendFocusedTags(status.focused_tags);
-    }
-}
-
-fn sendUrgentTags(status: *OutputStatus, output: *Output) void {
-    var urgent_tags: u32 = 0;
-    {
-        var it = output.inflight.wm_stack.iterator(.forward);
-        while (it.next()) |view| {
-            if (view.current.urgent) urgent_tags |= view.current.tags;
-        }
-    }
-
-    if (status.urgent_tags != urgent_tags) {
-        status.urgent_tags = urgent_tags;
-
-        var it = status.resources.iterator(.forward);
-        while (it.next()) |resource| {
-            if (resource.getVersion() >= 2) resource.sendUrgentTags(urgent_tags);
-        }
-    }
-}
-
-pub fn sendLayoutName(status: *OutputStatus, output: *Output) void {
-    assert(output.layout_name != null);
-
-    var it = status.resources.iterator(.forward);
-    while (it.next()) |resource| {
-        if (resource.getVersion() >= 4) resource.sendLayoutName(output.layout_name.?);
-    }
-}
-
-pub fn sendLayoutNameClear(status: *OutputStatus, output: *Output) void {
-    assert(output.layout_name == null);
-
-    var it = status.resources.iterator(.forward);
-    while (it.next()) |resource| {
-        if (resource.getVersion() >= 4) resource.sendLayoutNameClear();
-    }
-}
diff --git a/river/Root.zig b/river/Root.zig
index 08d5cc7..4f9c5ff 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -338,9 +338,6 @@ pub fn deactivateOutput(root: *Root, output: *Output) void {
         }
     }
 
-    output.status.deinit();
-    output.status.init();
-
     if (output.inflight.layout_demand) |layout_demand| {
         layout_demand.deinit();
         output.inflight.layout_demand = null;
@@ -712,8 +709,6 @@ fn commitTransaction(root: *Root) void {
             output.current.fullscreen = output.inflight.fullscreen;
             output.layers.fullscreen.node.setEnabled(output.current.fullscreen != null);
         }
-
-        output.status.handleTransactionCommit(output);
     }
 
     {
diff --git a/river/Seat.zig b/river/Seat.zig
index bb8e827..257c72d 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -39,7 +39,6 @@ const LockSurface = @import("LockSurface.zig");
 const Mapping = @import("Mapping.zig");
 const Output = @import("Output.zig");
 const PointerConstraint = @import("PointerConstraint.zig");
-const SeatStatus = @import("SeatStatus.zig");
 const Switch = @import("Switch.zig");
 const Tablet = @import("Tablet.zig");
 const View = @import("View.zig");
@@ -91,9 +90,6 @@ focused_output: ?*Output = null,
 
 focused: FocusTarget = .none,
 
-/// List of status tracking objects relaying changes to this seat to clients.
-status_trackers: std.SinglyLinkedList(SeatStatus) = .{},
-
 /// The currently in progress drag operation type.
 drag: enum {
     none,
@@ -293,10 +289,6 @@ pub fn setFocusRaw(seat: *Seat, new_focus: FocusTarget) void {
     // Depending on configuration and cursor position, changing keyboard focus
     // may cause the cursor to be warped.
     seat.cursor.may_need_warp = true;
-
-    // Inform any clients tracking status of the change
-    var it = seat.status_trackers.first;
-    while (it) |node| : (it = node.next) node.data.sendFocusedView();
 }
 
 /// Send keyboard enter/leave events and handle pointer constraints
@@ -333,18 +325,8 @@ fn keyboardNotifyEnter(seat: *Seat, wlr_surface: *wlr.Surface) void {
 pub fn focusOutput(seat: *Seat, output: ?*Output) void {
     if (seat.focused_output == output) return;
 
-    if (seat.focused_output) |old| {
-        var it = seat.status_trackers.first;
-        while (it) |node| : (it = node.next) node.data.sendOutput(old, .unfocused);
-    }
-
     seat.focused_output = output;
 
-    if (seat.focused_output) |new| {
-        var it = seat.status_trackers.first;
-        while (it) |node| : (it = node.next) node.data.sendOutput(new, .focused);
-    }
-
     // Depending on configuration and cursor position, changing output focus
     // may cause the cursor to be warped.
     seat.cursor.may_need_warp = true;
@@ -356,11 +338,6 @@ pub fn handleActivity(seat: Seat) void {
 
 pub fn enterMode(seat: *Seat, mode_id: u32) void {
     seat.mode_id = mode_id;
-
-    var it = seat.status_trackers.first;
-    while (it) |node| : (it = node.next) {
-        node.data.sendMode(server.config.modes.items[mode_id].name);
-    }
 }
 
 /// Handle any user-defined mapping for passed keycode, modifiers and keyboard state
diff --git a/river/SeatStatus.zig b/river/SeatStatus.zig
deleted file mode 100644
index 0c8b3eb..0000000
--- a/river/SeatStatus.zig
+++ /dev/null
@@ -1,80 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2020 The River Developers
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-const SeatStatus = @This();
-
-const std = @import("std");
-const wayland = @import("wayland");
-const wl = wayland.server.wl;
-const zriver = wayland.server.zriver;
-
-const server = &@import("main.zig").server;
-const util = @import("util.zig");
-
-const Seat = @import("Seat.zig");
-const Output = @import("Output.zig");
-const View = @import("View.zig");
-
-seat: *Seat,
-seat_status_v1: *zriver.SeatStatusV1,
-
-pub fn init(seat_status: *SeatStatus, seat: *Seat, seat_status_v1: *zriver.SeatStatusV1) void {
-    seat_status.* = .{ .seat = seat, .seat_status_v1 = seat_status_v1 };
-
-    seat_status_v1.setHandler(*SeatStatus, handleRequest, handleDestroy, seat_status);
-
-    // Send all info once on bind
-    seat_status.sendMode(server.config.modes.items[seat.mode_id].name);
-    if (seat.focused_output) |output| seat_status.sendOutput(output, .focused);
-    seat_status.sendFocusedView();
-}
-
-fn handleRequest(seat_status_v1: *zriver.SeatStatusV1, request: zriver.SeatStatusV1.Request, _: *SeatStatus) void {
-    switch (request) {
-        .destroy => seat_status_v1.destroy(),
-    }
-}
-
-fn handleDestroy(_: *zriver.SeatStatusV1, seat_status: *SeatStatus) void {
-    const node: *std.SinglyLinkedList(SeatStatus).Node = @fieldParentPtr("data", seat_status);
-    seat_status.seat.status_trackers.remove(node);
-    util.gpa.destroy(node);
-}
-
-pub fn sendOutput(seat_status: SeatStatus, output: *Output, state: enum { focused, unfocused }) void {
-    const client = seat_status.seat_status_v1.getClient();
-    var it = output.wlr_output.resources.iterator(.forward);
-    while (it.next()) |wl_output| {
-        if (wl_output.getClient() == client) switch (state) {
-            .focused => seat_status.seat_status_v1.sendFocusedOutput(wl_output),
-            .unfocused => seat_status.seat_status_v1.sendUnfocusedOutput(wl_output),
-        };
-    }
-}
-
-pub fn sendFocusedView(seat_status: SeatStatus) void {
-    const title: [*:0]const u8 = if (seat_status.seat.focused == .view)
-        seat_status.seat.focused.view.getTitle() orelse ""
-    else
-        "";
-    seat_status.seat_status_v1.sendFocusedView(title);
-}
-
-pub fn sendMode(seat_status: SeatStatus, mode: [*:0]const u8) void {
-    if (seat_status.seat_status_v1.getVersion() >= 3) {
-        seat_status.seat_status_v1.sendMode(mode);
-    }
-}
diff --git a/river/Server.zig b/river/Server.zig
index bb50dab..6a25d34 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -37,7 +37,6 @@ const Output = @import("Output.zig");
 const Root = @import("Root.zig");
 const Seat = @import("Seat.zig");
 const SceneNodeData = @import("SceneNodeData.zig");
-const StatusManager = @import("StatusManager.zig");
 const TabletTool = @import("TabletTool.zig");
 const XdgDecoration = @import("XdgDecoration.zig");
 const XdgToplevel = @import("XdgToplevel.zig");
@@ -88,7 +87,6 @@ input_manager: InputManager,
 root: Root,
 config: Config,
 control: Control,
-status_manager: StatusManager,
 layout_manager: LayoutManager,
 idle_inhibit_manager: IdleInhibitManager,
 lock_manager: LockManager,
@@ -162,7 +160,6 @@ pub fn init(server: *Server, runtime_xwayland: bool) !void {
         .root = undefined,
         .input_manager = undefined,
         .control = undefined,
-        .status_manager = undefined,
         .layout_manager = undefined,
         .idle_inhibit_manager = undefined,
         .lock_manager = undefined,
@@ -186,7 +183,6 @@ pub fn init(server: *Server, runtime_xwayland: bool) !void {
     try server.root.init();
     try server.input_manager.init();
     try server.control.init();
-    try server.status_manager.init();
     try server.layout_manager.init();
     try server.idle_inhibit_manager.init();
     try server.lock_manager.init();
@@ -325,7 +321,6 @@ fn blocklist(server: *Server, global: *const wl.Global) bool {
         global == server.data_control_manager.global or
         global == server.layout_manager.global or
         global == server.control.global or
-        global == server.status_manager.global or
         global == server.root.output_manager.global or
         global == server.root.power_manager.global or
         global == server.root.gamma_control_manager.global or
diff --git a/river/StatusManager.zig b/river/StatusManager.zig
deleted file mode 100644
index 4464431..0000000
--- a/river/StatusManager.zig
+++ /dev/null
@@ -1,112 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2020 The River Developers
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, version 3.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-const StatusManager = @This();
-
-const std = @import("std");
-const wlr = @import("wlroots");
-const wayland = @import("wayland");
-const wl = wayland.server.wl;
-const zriver = wayland.server.zriver;
-
-const server = &@import("main.zig").server;
-const util = @import("util.zig");
-
-const Output = @import("Output.zig");
-const OutputStatus = @import("OutputStatus.zig");
-const Seat = @import("Seat.zig");
-const SeatStatus = @import("SeatStatus.zig");
-const Server = @import("Server.zig");
-
-const log = std.log.scoped(.river_status);
-
-global: *wl.Global,
-
-server_destroy: wl.Listener(*wl.Server) = wl.Listener(*wl.Server).init(handleServerDestroy),
-
-pub fn init(status_manager: *StatusManager) !void {
-    status_manager.* = .{
-        .global = try wl.Global.create(server.wl_server, zriver.StatusManagerV1, 4, ?*anyopaque, null, bind),
-    };
-
-    server.wl_server.addDestroyListener(&status_manager.server_destroy);
-}
-
-fn handleServerDestroy(listener: *wl.Listener(*wl.Server), _: *wl.Server) void {
-    const status_manager: *StatusManager = @fieldParentPtr("server_destroy", listener);
-    status_manager.global.destroy();
-}
-
-fn bind(client: *wl.Client, _: ?*anyopaque, version: u32, id: u32) void {
-    const status_manager_v1 = zriver.StatusManagerV1.create(client, version, id) catch {
-        client.postNoMemory();
-        log.err("out of memory", .{});
-        return;
-    };
-    status_manager_v1.setHandler(?*anyopaque, handleRequest, null, null);
-}
-
-fn handleRequest(
-    status_manager_v1: *zriver.StatusManagerV1,
-    request: zriver.StatusManagerV1.Request,
-    _: ?*anyopaque,
-) void {
-    switch (request) {
-        .destroy => status_manager_v1.destroy(),
-        .get_river_output_status => |req| {
-            // ignore if the output is inert
-            const wlr_output = wlr.Output.fromWlOutput(req.output) orelse return;
-            const output: *Output = @ptrFromInt(wlr_output.data);
-
-            const resource = zriver.OutputStatusV1.create(
-                status_manager_v1.getClient(),
-                status_manager_v1.getVersion(),
-                req.id,
-            ) catch {
-                status_manager_v1.getClient().postNoMemory();
-                log.err("out of memory", .{});
-                return;
-            };
-
-            output.status.add(resource, output);
-        },
-        .get_river_seat_status => |req| {
-            // ignore if the seat is inert
-            const wlr_seat = wlr.Seat.Client.fromWlSeat(req.seat) orelse return;
-            const seat: *Seat = @ptrFromInt(wlr_seat.seat.data);
-
-            const node = util.gpa.create(std.SinglyLinkedList(SeatStatus).Node) catch {
-                status_manager_v1.getClient().postNoMemory();
-                log.err("out of memory", .{});
-                return;
-            };
-
-            const seat_status = zriver.SeatStatusV1.create(
-                status_manager_v1.getClient(),
-                status_manager_v1.getVersion(),
-                req.id,
-            ) catch {
-                status_manager_v1.getClient().postNoMemory();
-                util.gpa.destroy(node);
-                log.err("out of memory", .{});
-                return;
-            };
-
-            node.data.init(seat, seat_status);
-            seat.status_trackers.prepend(node);
-        },
-    }
-}
diff --git a/river/View.zig b/river/View.zig
index bb02da0..e6654c2 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -722,16 +722,6 @@ pub fn notifyTitle(view: *const View) void {
     if (view.foreign_toplevel_handle.wlr_handle) |wlr_handle| {
         if (view.getTitle()) |title| wlr_handle.setTitle(title);
     }
-    // Send title to all status listeners attached to a seat which focuses this view
-    var seat_it = server.input_manager.seats.first;
-    while (seat_it) |seat_node| : (seat_it = seat_node.next) {
-        if (seat_node.data.focused == .view and seat_node.data.focused.view == view) {
-            var client_it = seat_node.data.status_trackers.first;
-            while (client_it) |client_node| : (client_it = client_node.next) {
-                client_node.data.sendFocusedView();
-            }
-        }
-    }
 }
 
 pub fn notifyAppId(view: View) void {