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

commit27218cab2198903672240b0c61fd2c51ececf1e2
parentb9b6062389
authorIsaac Freund <[email protected]>
date2025-07-02 10:12
river: leverage decl literals

 river/Cursor.zig                   | 70 ++++++++++++++------------------------
 river/DragIcon.zig                 |  2 +-
 river/IdleInhibitManager.zig       |  3 +-
 river/IdleInhibitor.zig            |  2 +-
 river/InputDevice.zig              |  2 +-
 river/InputManager.zig             | 17 ++++-----
 river/InputPopup.zig               |  8 ++---
 river/InputRelay.zig               | 17 ++++-----
 river/Keyboard.zig                 |  4 +--
 river/LockManager.zig              |  9 +++--
 river/LockSurface.zig              |  4 +--
 river/Output.zig                   |  8 ++---
 river/OutputManager.zig            | 14 +++-----
 river/PointerConstraint.zig        |  6 ++--
 river/SceneNodeData.zig            |  2 +-
 river/Seat.zig                     | 13 +++----
 river/Server.zig                   | 16 ++++-----
 river/Switch.zig                   |  2 +-
 river/TabletTool.zig               |  5 ++-
 river/TextInput.zig                | 12 +++----
 river/WindowManager.zig            |  2 +-
 river/XdgDecoration.zig            |  6 ++--
 river/XdgPopup.zig                 |  8 ++---
 river/XdgToplevel.zig              | 25 ++++++--------
 river/XwaylandOverrideRedirect.zig | 17 +++++----
 river/XwaylandWindow.zig           | 26 +++++++-------
 26 files changed, 123 insertions(+), 177 deletions(-)

diff --git a/river/Cursor.zig b/river/Cursor.zig
index 2c83441..654c383 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -107,50 +107,32 @@ constraint: ?*PointerConstraint = null,
 /// This information is necessary for proper touch dnd support if there are multiple touch points.
 touch_points: std.AutoHashMapUnmanaged(i32, LayoutPoint) = .{},
 
-request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) =
-    wl.Listener(*wlr.Seat.event.RequestSetCursor).init(handleRequestSetCursor),
-
-motion_relative: wl.Listener(*wlr.Pointer.event.Motion) =
-    wl.Listener(*wlr.Pointer.event.Motion).init(queueMotionRelative),
-motion_absolute: wl.Listener(*wlr.Pointer.event.MotionAbsolute) =
-    wl.Listener(*wlr.Pointer.event.MotionAbsolute).init(queueMotionAbsolute),
-button: wl.Listener(*wlr.Pointer.event.Button) =
-    wl.Listener(*wlr.Pointer.event.Button).init(queueButton),
-axis: wl.Listener(*wlr.Pointer.event.Axis) = wl.Listener(*wlr.Pointer.event.Axis).init(queueAxis),
-frame: wl.Listener(*wlr.Cursor) = wl.Listener(*wlr.Cursor).init(queueFrame),
-
-swipe_begin: wl.Listener(*wlr.Pointer.event.SwipeBegin) =
-    wl.Listener(*wlr.Pointer.event.SwipeBegin).init(queueSwipeBegin),
-swipe_update: wl.Listener(*wlr.Pointer.event.SwipeUpdate) =
-    wl.Listener(*wlr.Pointer.event.SwipeUpdate).init(queueSwipeUpdate),
-swipe_end: wl.Listener(*wlr.Pointer.event.SwipeEnd) =
-    wl.Listener(*wlr.Pointer.event.SwipeEnd).init(queueSwipeEnd),
-
-pinch_begin: wl.Listener(*wlr.Pointer.event.PinchBegin) =
-    wl.Listener(*wlr.Pointer.event.PinchBegin).init(queuePinchBegin),
-pinch_update: wl.Listener(*wlr.Pointer.event.PinchUpdate) =
-    wl.Listener(*wlr.Pointer.event.PinchUpdate).init(queuePinchUpdate),
-pinch_end: wl.Listener(*wlr.Pointer.event.PinchEnd) =
-    wl.Listener(*wlr.Pointer.event.PinchEnd).init(queuePinchEnd),
-
-touch_down: wl.Listener(*wlr.Touch.event.Down) =
-    wl.Listener(*wlr.Touch.event.Down).init(handleTouchDown),
-touch_motion: wl.Listener(*wlr.Touch.event.Motion) =
-    wl.Listener(*wlr.Touch.event.Motion).init(handleTouchMotion),
-touch_up: wl.Listener(*wlr.Touch.event.Up) =
-    wl.Listener(*wlr.Touch.event.Up).init(handleTouchUp),
-touch_cancel: wl.Listener(*wlr.Touch.event.Cancel) =
-    wl.Listener(*wlr.Touch.event.Cancel).init(handleTouchCancel),
-touch_frame: wl.Listener(void) = wl.Listener(void).init(handleTouchFrame),
-
-tablet_tool_axis: wl.Listener(*wlr.Tablet.event.Axis) =
-    wl.Listener(*wlr.Tablet.event.Axis).init(handleTabletToolAxis),
-tablet_tool_proximity: wl.Listener(*wlr.Tablet.event.Proximity) =
-    wl.Listener(*wlr.Tablet.event.Proximity).init(handleTabletToolProximity),
-tablet_tool_tip: wl.Listener(*wlr.Tablet.event.Tip) =
-    wl.Listener(*wlr.Tablet.event.Tip).init(handleTabletToolTip),
-tablet_tool_button: wl.Listener(*wlr.Tablet.event.Button) =
-    wl.Listener(*wlr.Tablet.event.Button).init(handleTabletToolButton),
+request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = .init(handleRequestSetCursor),
+
+motion_relative: wl.Listener(*wlr.Pointer.event.Motion) = .init(queueMotionRelative),
+motion_absolute: wl.Listener(*wlr.Pointer.event.MotionAbsolute) = .init(queueMotionAbsolute),
+button: wl.Listener(*wlr.Pointer.event.Button) = .init(queueButton),
+axis: wl.Listener(*wlr.Pointer.event.Axis) = .init(queueAxis),
+frame: wl.Listener(*wlr.Cursor) = .init(queueFrame),
+
+swipe_begin: wl.Listener(*wlr.Pointer.event.SwipeBegin) = .init(queueSwipeBegin),
+swipe_update: wl.Listener(*wlr.Pointer.event.SwipeUpdate) = .init(queueSwipeUpdate),
+swipe_end: wl.Listener(*wlr.Pointer.event.SwipeEnd) = .init(queueSwipeEnd),
+
+pinch_begin: wl.Listener(*wlr.Pointer.event.PinchBegin) = .init(queuePinchBegin),
+pinch_update: wl.Listener(*wlr.Pointer.event.PinchUpdate) = .init(queuePinchUpdate),
+pinch_end: wl.Listener(*wlr.Pointer.event.PinchEnd) = .init(queuePinchEnd),
+
+touch_down: wl.Listener(*wlr.Touch.event.Down) = .init(handleTouchDown),
+touch_motion: wl.Listener(*wlr.Touch.event.Motion) = .init(handleTouchMotion),
+touch_up: wl.Listener(*wlr.Touch.event.Up) = .init(handleTouchUp),
+touch_cancel: wl.Listener(*wlr.Touch.event.Cancel) = .init(handleTouchCancel),
+touch_frame: wl.Listener(void) = .init(handleTouchFrame),
+
+tablet_tool_axis: wl.Listener(*wlr.Tablet.event.Axis) = .init(handleTabletToolAxis),
+tablet_tool_proximity: wl.Listener(*wlr.Tablet.event.Proximity) = .init(handleTabletToolProximity),
+tablet_tool_tip: wl.Listener(*wlr.Tablet.event.Tip) = .init(handleTabletToolTip),
+tablet_tool_button: wl.Listener(*wlr.Tablet.event.Button) = .init(handleTabletToolButton),
 
 pub fn init(cursor: *Cursor, seat: *Seat) !void {
     const wlr_cursor = try wlr.Cursor.create();
diff --git a/river/DragIcon.zig b/river/DragIcon.zig
index 99b6d56..2ff1152 100644
--- a/river/DragIcon.zig
+++ b/river/DragIcon.zig
@@ -29,7 +29,7 @@ const SceneNodeData = @import("SceneNodeData.zig");
 wlr_drag_icon: *wlr.Drag.Icon,
 scene_drag_icon: *wlr.SceneTree,
 
-destroy: wl.Listener(*wlr.Drag.Icon) = wl.Listener(*wlr.Drag.Icon).init(handleDestroy),
+destroy: wl.Listener(*wlr.Drag.Icon) = .init(handleDestroy),
 
 pub fn create(wlr_drag_icon: *wlr.Drag.Icon, cursor: *Cursor) error{OutOfMemory}!void {
     const scene_drag_icon = try server.scene.drag_icons.createSceneDragIcon(wlr_drag_icon);
diff --git a/river/IdleInhibitManager.zig b/river/IdleInhibitManager.zig
index 01d796d..44785cc 100644
--- a/river/IdleInhibitManager.zig
+++ b/river/IdleInhibitManager.zig
@@ -28,8 +28,7 @@ const SceneNodeData = @import("SceneNodeData.zig");
 const Window = @import("Window.zig");
 
 wlr_manager: *wlr.IdleInhibitManagerV1,
-new_idle_inhibitor: wl.Listener(*wlr.IdleInhibitorV1) =
-    wl.Listener(*wlr.IdleInhibitorV1).init(handleNewIdleInhibitor),
+new_idle_inhibitor: wl.Listener(*wlr.IdleInhibitorV1) = .init(handleNewIdleInhibitor),
 inhibitors: std.DoublyLinkedList(IdleInhibitor) = .{},
 
 pub fn init(inhibit_manager: *IdleInhibitManager) !void {
diff --git a/river/IdleInhibitor.zig b/river/IdleInhibitor.zig
index 2b45786..9e2ccc5 100644
--- a/river/IdleInhibitor.zig
+++ b/river/IdleInhibitor.zig
@@ -28,7 +28,7 @@ const IdleInhibitManager = @import("IdleInhibitManager.zig");
 inhibit_manager: *IdleInhibitManager,
 wlr_inhibitor: *wlr.IdleInhibitorV1,
 
-destroy: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleDestroy),
+destroy: wl.Listener(*wlr.Surface) = .init(handleDestroy),
 
 pub fn init(
     inhibitor: *IdleInhibitor,
diff --git a/river/InputDevice.zig b/river/InputDevice.zig
index fd8bde9..b0a106e 100644
--- a/river/InputDevice.zig
+++ b/river/InputDevice.zig
@@ -38,7 +38,7 @@ const log = std.log.scoped(.input);
 seat: *Seat,
 wlr_device: *wlr.InputDevice,
 
-destroy: wl.Listener(*wlr.InputDevice) = wl.Listener(*wlr.InputDevice).init(handleDestroy),
+destroy: wl.Listener(*wlr.InputDevice) = .init(handleDestroy),
 
 /// Careful: The identifier is not unique! A physical input device may have
 /// multiple logical input devices with the exact same vendor id, product id
diff --git a/river/InputManager.zig b/river/InputManager.zig
index 313f101..bae8b77 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -41,7 +41,7 @@ const default_seat_name = "default";
 
 const log = std.log.scoped(.input);
 
-new_input: wl.Listener(*wlr.InputDevice) = wl.Listener(*wlr.InputDevice).init(handleNewInput),
+new_input: wl.Listener(*wlr.InputDevice) = .init(handleNewInput),
 
 idle_notifier: *wlr.IdleNotifierV1,
 relative_pointer_manager: *wlr.RelativePointerManagerV1,
@@ -60,16 +60,11 @@ configs: std.ArrayList(InputConfig),
 devices: wl.list.Head(InputDevice, .link),
 seats: wl.list.Head(Seat, .link),
 
-new_virtual_pointer: wl.Listener(*wlr.VirtualPointerManagerV1.event.NewPointer) =
-    wl.Listener(*wlr.VirtualPointerManagerV1.event.NewPointer).init(handleNewVirtualPointer),
-new_virtual_keyboard: wl.Listener(*wlr.VirtualKeyboardV1) =
-    wl.Listener(*wlr.VirtualKeyboardV1).init(handleNewVirtualKeyboard),
-new_constraint: wl.Listener(*wlr.PointerConstraintV1) =
-    wl.Listener(*wlr.PointerConstraintV1).init(handleNewConstraint),
-new_input_method: wl.Listener(*wlr.InputMethodV2) =
-    wl.Listener(*wlr.InputMethodV2).init(handleNewInputMethod),
-new_text_input: wl.Listener(*wlr.TextInputV3) =
-    wl.Listener(*wlr.TextInputV3).init(handleNewTextInput),
+new_virtual_pointer: wl.Listener(*wlr.VirtualPointerManagerV1.event.NewPointer) = .init(handleNewVirtualPointer),
+new_virtual_keyboard: wl.Listener(*wlr.VirtualKeyboardV1) = .init(handleNewVirtualKeyboard),
+new_constraint: wl.Listener(*wlr.PointerConstraintV1) = .init(handleNewConstraint),
+new_input_method: wl.Listener(*wlr.InputMethodV2) = .init(handleNewInputMethod),
+new_text_input: wl.Listener(*wlr.TextInputV3) = .init(handleNewTextInput),
 
 pub fn init(input_manager: *InputManager) !void {
     input_manager.* = .{
diff --git a/river/InputPopup.zig b/river/InputPopup.zig
index 7c6c576..0d7a775 100644
--- a/river/InputPopup.zig
+++ b/river/InputPopup.zig
@@ -34,10 +34,10 @@ input_relay: *InputRelay,
 wlr_popup: *wlr.InputPopupSurfaceV2,
 surface_tree: *wlr.SceneTree,
 
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
-map: wl.Listener(void) = wl.Listener(void).init(handleMap),
-unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
-commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
+destroy: wl.Listener(void) = .init(handleDestroy),
+map: wl.Listener(void) = .init(handleMap),
+unmap: wl.Listener(void) = .init(handleUnmap),
+commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
 
 pub fn create(wlr_popup: *wlr.InputPopupSurfaceV2, input_relay: *InputRelay) !void {
     const input_popup = try util.gpa.create(InputPopup);
diff --git a/river/InputRelay.zig b/river/InputRelay.zig
index ca21f69..38976f3 100644
--- a/river/InputRelay.zig
+++ b/river/InputRelay.zig
@@ -46,17 +46,12 @@ input_popups: wl.list.Head(InputPopup, .link),
 /// Always null if there is no input method.
 text_input: ?*TextInput = null,
 
-input_method_commit: wl.Listener(*wlr.InputMethodV2) =
-    wl.Listener(*wlr.InputMethodV2).init(handleInputMethodCommit),
-grab_keyboard: wl.Listener(*wlr.InputMethodV2.KeyboardGrab) =
-    wl.Listener(*wlr.InputMethodV2.KeyboardGrab).init(handleInputMethodGrabKeyboard),
-input_method_destroy: wl.Listener(*wlr.InputMethodV2) =
-    wl.Listener(*wlr.InputMethodV2).init(handleInputMethodDestroy),
-input_method_new_popup: wl.Listener(*wlr.InputPopupSurfaceV2) =
-    wl.Listener(*wlr.InputPopupSurfaceV2).init(handleInputMethodNewPopup),
-
-grab_keyboard_destroy: wl.Listener(*wlr.InputMethodV2.KeyboardGrab) =
-    wl.Listener(*wlr.InputMethodV2.KeyboardGrab).init(handleInputMethodGrabKeyboardDestroy),
+input_method_commit: wl.Listener(*wlr.InputMethodV2) = .init(handleInputMethodCommit),
+grab_keyboard: wl.Listener(*wlr.InputMethodV2.KeyboardGrab) = .init(handleInputMethodGrabKeyboard),
+input_method_destroy: wl.Listener(*wlr.InputMethodV2) = .init(handleInputMethodDestroy),
+input_method_new_popup: wl.Listener(*wlr.InputPopupSurfaceV2) = .init(handleInputMethodNewPopup),
+
+grab_keyboard_destroy: wl.Listener(*wlr.InputMethodV2.KeyboardGrab) = .init(handleInputMethodGrabKeyboardDestroy),
 
 pub fn init(relay: *InputRelay) void {
     relay.* = .{ .text_inputs = undefined, .input_popups = undefined };
diff --git a/river/Keyboard.zig b/river/Keyboard.zig
index d70715d..8a54cac 100644
--- a/river/Keyboard.zig
+++ b/river/Keyboard.zig
@@ -93,8 +93,8 @@ device: InputDevice,
 /// Pressed keys along with where their press event has been sent
 pressed: Pressed = .{},
 
-key: wl.Listener(*wlr.Keyboard.event.Key) = wl.Listener(*wlr.Keyboard.event.Key).init(queueKey),
-modifiers: wl.Listener(*wlr.Keyboard) = wl.Listener(*wlr.Keyboard).init(queueModifiers),
+key: wl.Listener(*wlr.Keyboard.event.Key) = .init(queueKey),
+modifiers: wl.Listener(*wlr.Keyboard) = .init(queueModifiers),
 
 pub fn init(keyboard: *Keyboard, seat: *Seat, wlr_device: *wlr.InputDevice) !void {
     keyboard.* = .{
diff --git a/river/LockManager.zig b/river/LockManager.zig
index 184d836..f777b14 100644
--- a/river/LockManager.zig
+++ b/river/LockManager.zig
@@ -56,11 +56,10 @@ lock: ?*wlr.SessionLockV1 = null,
 /// been blanked.
 lock_surfaces_timer: *wl.EventSource,
 
-new_lock: wl.Listener(*wlr.SessionLockV1) = wl.Listener(*wlr.SessionLockV1).init(handleLock),
-unlock: wl.Listener(void) = wl.Listener(void).init(handleUnlock),
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
-new_surface: wl.Listener(*wlr.SessionLockSurfaceV1) =
-    wl.Listener(*wlr.SessionLockSurfaceV1).init(handleSurface),
+new_lock: wl.Listener(*wlr.SessionLockV1) = .init(handleLock),
+unlock: wl.Listener(void) = .init(handleUnlock),
+destroy: wl.Listener(void) = .init(handleDestroy),
+new_surface: wl.Listener(*wlr.SessionLockSurfaceV1) = .init(handleSurface),
 
 pub fn init(manager: *LockManager) !void {
     const event_loop = server.wl_server.getEventLoop();
diff --git a/river/LockSurface.zig b/river/LockSurface.zig
index 3192ff7..716c774 100644
--- a/river/LockSurface.zig
+++ b/river/LockSurface.zig
@@ -33,8 +33,8 @@ lock: *wlr.SessionLockV1,
 
 idle_update_focus: ?*wl.EventSource = null,
 
-map: wl.Listener(void) = wl.Listener(void).init(handleMap),
-surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
+map: wl.Listener(void) = .init(handleMap),
+surface_destroy: wl.Listener(void) = .init(handleDestroy),
 
 pub fn create(wlr_lock_surface: *wlr.SessionLockSurfaceV1, lock: *wlr.SessionLockV1) error{OutOfMemory}!void {
     const lock_surface = try util.gpa.create(LockSurface);
diff --git a/river/Output.zig b/river/Output.zig
index a146405..52f5b50 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -170,10 +170,10 @@ link_sent: wl.list.Link,
 /// State applied to the wlr_output and rendered.
 current: State,
 
-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),
-present: wl.Listener(*wlr.Output.event.Present) = wl.Listener(*wlr.Output.event.Present).init(handlePresent),
+destroy: wl.Listener(*wlr.Output) = .init(handleDestroy),
+request_state: wl.Listener(*wlr.Output.event.RequestState) = .init(handleRequestState),
+frame: wl.Listener(*wlr.Output) = .init(handleFrame),
+present: wl.Listener(*wlr.Output.event.Present) = .init(handlePresent),
 
 pub fn create(wlr_output: *wlr.Output) !void {
     const output = try util.gpa.create(Output);
diff --git a/river/OutputManager.zig b/river/OutputManager.zig
index e8429fe..f9f37e6 100644
--- a/river/OutputManager.zig
+++ b/river/OutputManager.zig
@@ -36,7 +36,7 @@ const XwaylandOverrideRedirect = @import("XwaylandOverrideRedirect.zig");
 
 const log = std.log.scoped(.output);
 
-new_output: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleNewOutput),
+new_output: wl.Listener(*wlr.Output) = .init(handleNewOutput),
 
 output_layout: *wlr.OutputLayout,
 
@@ -44,18 +44,14 @@ presentation: *wlr.Presentation,
 xdg_output_manager: *wlr.XdgOutputManagerV1,
 
 wlr_output_manager: *wlr.OutputManagerV1,
-manager_apply: wl.Listener(*wlr.OutputConfigurationV1) =
-    wl.Listener(*wlr.OutputConfigurationV1).init(handleManagerApply),
-manager_test: wl.Listener(*wlr.OutputConfigurationV1) =
-    wl.Listener(*wlr.OutputConfigurationV1).init(handleManagerTest),
+manager_apply: wl.Listener(*wlr.OutputConfigurationV1) = .init(handleManagerApply),
+manager_test: wl.Listener(*wlr.OutputConfigurationV1) = .init(handleManagerTest),
 
 power_manager: *wlr.OutputPowerManagerV1,
-power_manager_set_mode: wl.Listener(*wlr.OutputPowerManagerV1.event.SetMode) =
-    wl.Listener(*wlr.OutputPowerManagerV1.event.SetMode).init(handlePowerManagerSetMode),
+power_manager_set_mode: wl.Listener(*wlr.OutputPowerManagerV1.event.SetMode) = .init(handlePowerManagerSetMode),
 
 gamma_control_manager: *wlr.GammaControlManagerV1,
-gamma_control_set_gamma: wl.Listener(*wlr.GammaControlManagerV1.event.SetGamma) =
-    wl.Listener(*wlr.GammaControlManagerV1.event.SetGamma).init(handleSetGamma),
+gamma_control_set_gamma: wl.Listener(*wlr.GammaControlManagerV1.event.SetGamma) = .init(handleSetGamma),
 
 /// All Outputs that have a corresponding wlr_output.
 outputs: wl.list.Head(Output, .link),
diff --git a/river/PointerConstraint.zig b/river/PointerConstraint.zig
index f460afd..b9890b4 100644
--- a/river/PointerConstraint.zig
+++ b/river/PointerConstraint.zig
@@ -41,10 +41,10 @@ state: union(enum) {
     },
 } = .inactive,
 
-destroy: wl.Listener(*wlr.PointerConstraintV1) = wl.Listener(*wlr.PointerConstraintV1).init(handleDestroy),
-commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
+destroy: wl.Listener(*wlr.PointerConstraintV1) = .init(handleDestroy),
+commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
 
-node_destroy: wl.Listener(void) = wl.Listener(void).init(handleNodeDestroy),
+node_destroy: wl.Listener(void) = .init(handleNodeDestroy),
 
 pub fn create(wlr_constraint: *wlr.PointerConstraintV1) error{OutOfMemory}!void {
     const seat: *Seat = @ptrFromInt(wlr_constraint.seat.data);
diff --git a/river/SceneNodeData.zig b/river/SceneNodeData.zig
index aae8273..2cabad8 100644
--- a/river/SceneNodeData.zig
+++ b/river/SceneNodeData.zig
@@ -37,7 +37,7 @@ pub const Data = union(enum) {
 
 node: *wlr.SceneNode,
 data: Data,
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
+destroy: wl.Listener(void) = .init(handleDestroy),
 
 pub fn attach(node: *wlr.SceneNode, data: Data) error{OutOfMemory}!void {
     const scene_node_data = try util.gpa.create(SceneNodeData);
diff --git a/river/Seat.zig b/river/Seat.zig
index f185429..61b4883 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -170,14 +170,11 @@ drag: enum {
     touch,
 } = .none,
 
-request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) =
-    wl.Listener(*wlr.Seat.event.RequestSetSelection).init(handleRequestSetSelection),
-request_start_drag: wl.Listener(*wlr.Seat.event.RequestStartDrag) =
-    wl.Listener(*wlr.Seat.event.RequestStartDrag).init(handleRequestStartDrag),
-start_drag: wl.Listener(*wlr.Drag) = wl.Listener(*wlr.Drag).init(handleStartDrag),
-drag_destroy: wl.Listener(*wlr.Drag) = wl.Listener(*wlr.Drag).init(handleDragDestroy),
-request_set_primary_selection: wl.Listener(*wlr.Seat.event.RequestSetPrimarySelection) =
-    wl.Listener(*wlr.Seat.event.RequestSetPrimarySelection).init(handleRequestSetPrimarySelection),
+request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = .init(handleRequestSetSelection),
+request_start_drag: wl.Listener(*wlr.Seat.event.RequestStartDrag) = .init(handleRequestStartDrag),
+start_drag: wl.Listener(*wlr.Drag) = .init(handleStartDrag),
+drag_destroy: wl.Listener(*wlr.Drag) = .init(handleDragDestroy),
+request_set_primary_selection: wl.Listener(*wlr.Seat.event.RequestSetPrimarySelection) = .init(handleRequestSetPrimarySelection),
 
 pub fn create(name: [*:0]const u8) !void {
     const seat = try util.gpa.create(Seat);
diff --git a/river/Server.zig b/river/Server.zig
index eee2557..ce3d95a 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -91,16 +91,12 @@ wm: WindowManager,
 
 xwayland: if (build_options.xwayland) ?*wlr.Xwayland else void = if (build_options.xwayland) null,
 new_xsurface: if (build_options.xwayland) wl.Listener(*wlr.XwaylandSurface) else void =
-    if (build_options.xwayland) wl.Listener(*wlr.XwaylandSurface).init(handleNewXwaylandSurface),
-
-new_xdg_toplevel: wl.Listener(*wlr.XdgToplevel) =
-    wl.Listener(*wlr.XdgToplevel).init(handleNewXdgToplevel),
-new_toplevel_decoration: wl.Listener(*wlr.XdgToplevelDecorationV1) =
-    wl.Listener(*wlr.XdgToplevelDecorationV1).init(handleNewToplevelDecoration),
-request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) =
-    wl.Listener(*wlr.XdgActivationV1.event.RequestActivate).init(handleRequestActivate),
-request_set_cursor_shape: wl.Listener(*wlr.CursorShapeManagerV1.event.RequestSetShape) =
-    wl.Listener(*wlr.CursorShapeManagerV1.event.RequestSetShape).init(handleRequestSetCursorShape),
+    if (build_options.xwayland) .init(handleNewXwaylandSurface),
+
+new_xdg_toplevel: wl.Listener(*wlr.XdgToplevel) = .init(handleNewXdgToplevel),
+new_toplevel_decoration: wl.Listener(*wlr.XdgToplevelDecorationV1) = .init(handleNewToplevelDecoration),
+request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) = .init(handleRequestActivate),
+request_set_cursor_shape: wl.Listener(*wlr.CursorShapeManagerV1.event.RequestSetShape) = .init(handleRequestSetCursorShape),
 
 pub fn init(server: *Server, runtime_xwayland: bool) !void {
     // We intentionally don't try to prevent memory leaks on error in this function
diff --git a/river/Switch.zig b/river/Switch.zig
index 6d1268e..a441345 100644
--- a/river/Switch.zig
+++ b/river/Switch.zig
@@ -50,7 +50,7 @@ pub const TabletState = enum {
 
 device: InputDevice,
 
-toggle: wl.Listener(*wlr.Switch.event.Toggle) = wl.Listener(*wlr.Switch.event.Toggle).init(handleToggle),
+toggle: wl.Listener(*wlr.Switch.event.Toggle) = .init(handleToggle),
 
 pub fn init(switch_device: *Switch, seat: *Seat, wlr_device: *wlr.InputDevice) !void {
     switch_device.* = .{
diff --git a/river/TabletTool.zig b/river/TabletTool.zig
index cea658e..dadac7b 100644
--- a/river/TabletTool.zig
+++ b/river/TabletTool.zig
@@ -54,9 +54,8 @@ mode: Mode = .passthrough,
 tilt_x: f64 = 0,
 tilt_y: f64 = 0,
 
-destroy: wl.Listener(*wlr.TabletTool) = wl.Listener(*wlr.TabletTool).init(handleDestroy),
-set_cursor: wl.Listener(*wlr.TabletV2TabletTool.event.SetCursor) =
-    wl.Listener(*wlr.TabletV2TabletTool.event.SetCursor).init(handleSetCursor),
+destroy: wl.Listener(*wlr.TabletTool) = .init(handleDestroy),
+set_cursor: wl.Listener(*wlr.TabletV2TabletTool.event.SetCursor) = .init(handleSetCursor),
 
 pub fn get(wlr_seat: *wlr.Seat, wlr_tool: *wlr.TabletTool) error{OutOfMemory}!*TabletTool {
     if (@as(?*TabletTool, @ptrFromInt(wlr_tool.data))) |tool| {
diff --git a/river/TextInput.zig b/river/TextInput.zig
index 9070768..f831d78 100644
--- a/river/TextInput.zig
+++ b/river/TextInput.zig
@@ -33,14 +33,10 @@ link: wl.list.Link,
 
 wlr_text_input: *wlr.TextInputV3,
 
-enable: wl.Listener(*wlr.TextInputV3) =
-    wl.Listener(*wlr.TextInputV3).init(handleEnable),
-commit: wl.Listener(*wlr.TextInputV3) =
-    wl.Listener(*wlr.TextInputV3).init(handleCommit),
-disable: wl.Listener(*wlr.TextInputV3) =
-    wl.Listener(*wlr.TextInputV3).init(handleDisable),
-destroy: wl.Listener(*wlr.TextInputV3) =
-    wl.Listener(*wlr.TextInputV3).init(handleDestroy),
+enable: wl.Listener(*wlr.TextInputV3) = .init(handleEnable),
+commit: wl.Listener(*wlr.TextInputV3) = .init(handleCommit),
+disable: wl.Listener(*wlr.TextInputV3) = .init(handleDisable),
+destroy: wl.Listener(*wlr.TextInputV3) = .init(handleDestroy),
 
 pub fn create(wlr_text_input: *wlr.TextInputV3) !void {
     const seat: *Seat = @ptrFromInt(wlr_text_input.seat.data);
diff --git a/river/WindowManager.zig b/river/WindowManager.zig
index 97af9cc..08195ab 100644
--- a/river/WindowManager.zig
+++ b/river/WindowManager.zig
@@ -35,7 +35,7 @@ const WmNode = @import("WmNode.zig");
 const log = std.log.scoped(.wm);
 
 global: *wl.Global,
-server_destroy: wl.Listener(*wl.Server) = wl.Listener(*wl.Server).init(handleServerDestroy),
+server_destroy: wl.Listener(*wl.Server) = .init(handleServerDestroy),
 
 /// The protocol object of the active window manager, if any.
 object: ?*river.WindowManagerV1 = null,
diff --git a/river/XdgDecoration.zig b/river/XdgDecoration.zig
index 558bd10..71d6230 100644
--- a/river/XdgDecoration.zig
+++ b/river/XdgDecoration.zig
@@ -28,10 +28,8 @@ const XdgToplevel = @import("XdgToplevel.zig");
 
 wlr_decoration: *wlr.XdgToplevelDecorationV1,
 
-destroy: wl.Listener(*wlr.XdgToplevelDecorationV1) =
-    wl.Listener(*wlr.XdgToplevelDecorationV1).init(handleDestroy),
-request_mode: wl.Listener(*wlr.XdgToplevelDecorationV1) =
-    wl.Listener(*wlr.XdgToplevelDecorationV1).init(handleRequestMode),
+destroy: wl.Listener(*wlr.XdgToplevelDecorationV1) = wl.Listener(*wlr.XdgToplevelDecorationV1).init(handleDestroy),
+request_mode: wl.Listener(*wlr.XdgToplevelDecorationV1) = wl.Listener(*wlr.XdgToplevelDecorationV1).init(handleRequestMode),
 
 pub fn init(wlr_decoration: *wlr.XdgToplevelDecorationV1) void {
     const toplevel: *XdgToplevel = @ptrFromInt(wlr_decoration.toplevel.base.data);
diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig
index 29019fe..833cd41 100644
--- a/river/XdgPopup.zig
+++ b/river/XdgPopup.zig
@@ -34,10 +34,10 @@ root: *wlr.SceneTree,
 
 tree: *wlr.SceneTree,
 
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
-commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
-new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
-reposition: wl.Listener(void) = wl.Listener(void).init(handleReposition),
+destroy: wl.Listener(void) = .init(handleDestroy),
+commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
+new_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewPopup),
+reposition: wl.Listener(void) = .init(handleReposition),
 
 // TODO check if popup is set_reactive and reposition on parent movement.
 pub fn create(
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 8553993..f9f0e10 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -59,20 +59,17 @@ configure_state: union(enum) {
 } = .idle,
 
 // Listeners that are always active over the window's lifetime
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
-ack_configure: wl.Listener(*wlr.XdgSurface.Configure) =
-    wl.Listener(*wlr.XdgSurface.Configure).init(handleAckConfigure),
-map: wl.Listener(void) = wl.Listener(void).init(handleMap),
-unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
-commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
-new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
-request_fullscreen: wl.Listener(void) = wl.Listener(void).init(handleRequestFullscreen),
-request_move: wl.Listener(*wlr.XdgToplevel.event.Move) =
-    wl.Listener(*wlr.XdgToplevel.event.Move).init(handleRequestMove),
-request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) =
-    wl.Listener(*wlr.XdgToplevel.event.Resize).init(handleRequestResize),
-set_title: wl.Listener(void) = wl.Listener(void).init(handleSetTitle),
-set_app_id: wl.Listener(void) = wl.Listener(void).init(handleSetAppId),
+destroy: wl.Listener(void) = .init(handleDestroy),
+ack_configure: wl.Listener(*wlr.XdgSurface.Configure) = .init(handleAckConfigure),
+map: wl.Listener(void) = .init(handleMap),
+unmap: wl.Listener(void) = .init(handleUnmap),
+commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
+new_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewPopup),
+request_fullscreen: wl.Listener(void) = .init(handleRequestFullscreen),
+request_move: wl.Listener(*wlr.XdgToplevel.event.Move) = .init(handleRequestMove),
+request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = .init(handleRequestResize),
+set_title: wl.Listener(void) = .init(handleSetTitle),
+set_app_id: wl.Listener(void) = .init(handleSetAppId),
 
 pub fn create(wlr_toplevel: *wlr.XdgToplevel) error{OutOfMemory}!void {
     log.debug("new xdg_toplevel", .{});
diff --git a/river/XwaylandOverrideRedirect.zig b/river/XwaylandOverrideRedirect.zig
index 70ec3b1..e5554dc 100644
--- a/river/XwaylandOverrideRedirect.zig
+++ b/river/XwaylandOverrideRedirect.zig
@@ -35,19 +35,18 @@ xsurface: *wlr.XwaylandSurface,
 surface_tree: ?*wlr.SceneTree = null,
 
 // Active over entire lifetime
-request_configure: wl.Listener(*wlr.XwaylandSurface.event.Configure) =
-    wl.Listener(*wlr.XwaylandSurface.event.Configure).init(handleRequestConfigure),
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
-set_override_redirect: wl.Listener(void) = wl.Listener(void).init(handleSetOverrideRedirect),
-associate: wl.Listener(void) = wl.Listener(void).init(handleAssociate),
-dissociate: wl.Listener(void) = wl.Listener(void).init(handleDissociate),
+request_configure: wl.Listener(*wlr.XwaylandSurface.event.Configure) = .init(handleRequestConfigure),
+destroy: wl.Listener(void) = .init(handleDestroy),
+set_override_redirect: wl.Listener(void) = .init(handleSetOverrideRedirect),
+associate: wl.Listener(void) = .init(handleAssociate),
+dissociate: wl.Listener(void) = .init(handleDissociate),
 
 // Active while the xsurface is associated with a wlr_surface
-map: wl.Listener(void) = wl.Listener(void).init(handleMap),
-unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
+map: wl.Listener(void) = .init(handleMap),
+unmap: wl.Listener(void) = .init(handleUnmap),
 
 // Active while mapped
-set_geometry: wl.Listener(void) = wl.Listener(void).init(handleSetGeometry),
+set_geometry: wl.Listener(void) = .init(handleSetGeometry),
 
 pub fn create(xsurface: *wlr.XwaylandSurface) error{OutOfMemory}!void {
     log.debug("new xwayland override redirect: title='{?s}', class='{?s}'", .{
diff --git a/river/XwaylandWindow.zig b/river/XwaylandWindow.zig
index 7f46a17..cc3cd65 100644
--- a/river/XwaylandWindow.zig
+++ b/river/XwaylandWindow.zig
@@ -40,22 +40,20 @@ xsurface: *wlr.XwaylandSurface,
 surface_tree: ?*wlr.SceneTree = null,
 
 // Active over entire lifetime
-destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
-request_configure: wl.Listener(*wlr.XwaylandSurface.event.Configure) =
-    wl.Listener(*wlr.XwaylandSurface.event.Configure).init(handleRequestConfigure),
-set_override_redirect: wl.Listener(void) = wl.Listener(void).init(handleSetOverrideRedirect),
-associate: wl.Listener(void) = wl.Listener(void).init(handleAssociate),
-dissociate: wl.Listener(void) = wl.Listener(void).init(handleDissociate),
-set_title: wl.Listener(void) = wl.Listener(void).init(handleSetTitle),
-set_class: wl.Listener(void) = wl.Listener(void).init(handleSetClass),
-set_decorations: wl.Listener(void) = wl.Listener(void).init(handleSetDecorations),
-request_fullscreen: wl.Listener(void) = wl.Listener(void).init(handleRequestFullscreen),
-request_minimize: wl.Listener(*wlr.XwaylandSurface.event.Minimize) =
-    wl.Listener(*wlr.XwaylandSurface.event.Minimize).init(handleRequestMinimize),
+destroy: wl.Listener(void) = .init(handleDestroy),
+request_configure: wl.Listener(*wlr.XwaylandSurface.event.Configure) = .init(handleRequestConfigure),
+set_override_redirect: wl.Listener(void) = .init(handleSetOverrideRedirect),
+associate: wl.Listener(void) = .init(handleAssociate),
+dissociate: wl.Listener(void) = .init(handleDissociate),
+set_title: wl.Listener(void) = .init(handleSetTitle),
+set_class: wl.Listener(void) = .init(handleSetClass),
+set_decorations: wl.Listener(void) = .init(handleSetDecorations),
+request_fullscreen: wl.Listener(void) = .init(handleRequestFullscreen),
+request_minimize: wl.Listener(*wlr.XwaylandSurface.event.Minimize) = .init(handleRequestMinimize),
 
 // Active while the xsurfaceis associated with a wlr_surface
-map: wl.Listener(void) = wl.Listener(void).init(handleMap),
-unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap),
+map: wl.Listener(void) = .init(handleMap),
+unmap: wl.Listener(void) = .init(handleUnmap),
 
 pub fn create(xsurface: *wlr.XwaylandSurface) error{OutOfMemory}!void {
     log.debug("new xwayland window: title='{?s}', class='{?s}'", .{