Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
protocol: add "done" event to input management objects
build.zig | 6 +++---
protocol/river-input-management-v1.xml | 14 ++++++++++++--
protocol/river-libinput-config-v1.xml | 14 ++++++++++++--
protocol/river-xkb-config-v1.xml | 16 +++++++++++++---
river/InputDevice.zig | 3 +++
river/InputManager.zig | 2 +-
river/LibinputConfig.zig | 2 +-
river/LibinputDevice.zig | 34 ++++++++++++++++++++++++++++++++++
river/XkbConfig.zig | 2 +-
river/XkbKeyboard.zig | 10 ++++++++++
10 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/build.zig b/build.zig
index 39e179a..428ccc1 100644
--- a/build.zig
+++ b/build.zig
@@ -126,9 +126,9 @@ pub fn build(b: *Build) !void {
scanner.generate("river_window_manager_v1", 4);
scanner.generate("river_xkb_bindings_v1", 3);
scanner.generate("river_layer_shell_v1", 1);
- scanner.generate("river_input_manager_v1", 1);
- scanner.generate("river_libinput_config_v1", 1);
- scanner.generate("river_xkb_config_v1", 1);
+ scanner.generate("river_input_manager_v1", 2);
+ scanner.generate("river_libinput_config_v1", 2);
+ scanner.generate("river_xkb_config_v1", 2);
scanner.generate("zwlr_output_power_manager_v1", 1);
scanner.generate("zwlr_layer_shell_v1", 4);
diff --git a/protocol/river-input-management-v1.xml b/protocol/river-input-management-v1.xml
index 81f707c..e0f5498 100644
--- a/protocol/river-input-management-v1.xml
+++ b/protocol/river-input-management-v1.xml
@@ -32,7 +32,7 @@
document are to be interpreted as described in IETF RFC 2119.
</description>
- <interface name="river_input_manager_v1" version="1">
+ <interface name="river_input_manager_v1" version="2">
<description summary="input manager global interface">
Input manager global interface.
</description>
@@ -110,7 +110,7 @@
</event>
</interface>
- <interface name="river_input_device_v1" version="1">
+ <interface name="river_input_device_v1" version="2">
<description summary="an input device">
An input device represents a physical keyboard, mouse, touchscreen, or
drawing tablet tool. It is assigned to exactly one seat at a time.
@@ -230,5 +230,15 @@
<arg name="width" type="int"/>
<arg name="height" type="int"/>
</request>
+
+ <event name="done" since="2">
+ <description summary="all information has been sent">
+ This event is sent after all information about the input device has
+ been sent.
+
+ This allows changes to one or more river_input_device_v1 properties to
+ be seen as atomic, even if they happen via multiple events.
+ </description>
+ </event>
</interface>
</protocol>
diff --git a/protocol/river-libinput-config-v1.xml b/protocol/river-libinput-config-v1.xml
index 5e38b08..d98a2c4 100644
--- a/protocol/river-libinput-config-v1.xml
+++ b/protocol/river-libinput-config-v1.xml
@@ -47,7 +47,7 @@
document are to be interpreted as described in IETF RFC 2119.
</description>
- <interface name="river_libinput_config_v1" version="1">
+ <interface name="river_libinput_config_v1" version="2">
<description summary="libinput config global interface">
Global interface for configuring libinput devices. This global should
only be advertised if river_input_manager_v1 is advertised as well.
@@ -115,7 +115,7 @@
</request>
</interface>
- <interface name="river_libinput_device_v1" version="1">
+ <interface name="river_libinput_device_v1" version="2">
<description summary="a libinput device">
In general, *_support events will be sent exactly once directly after the
river_libinput_device_v1 is created. *_default events will be sent after
@@ -828,6 +828,16 @@
<arg name="result" type="new_id" interface="river_libinput_result_v1"/>
<arg name="angle" type="uint"/>
</request>
+
+ <event name="done" since="2">
+ <description summary="all information has been sent">
+ This event is sent after all information about the libinput device has
+ been sent.
+
+ This allows changes to one or more river_libinput_device_v1 properties
+ to be seen as atomic, even if they happen via multiple events.
+ </description>
+ </event>
</interface>
<interface name="river_libinput_accel_config_v1" version="1">
diff --git a/protocol/river-xkb-config-v1.xml b/protocol/river-xkb-config-v1.xml
index 2e3b8dd..f73ec67 100644
--- a/protocol/river-xkb-config-v1.xml
+++ b/protocol/river-xkb-config-v1.xml
@@ -33,7 +33,7 @@
document are to be interpreted as described in IETF RFC 2119.
</description>
- <interface name="river_xkb_config_v1" version="1">
+ <interface name="river_xkb_config_v1" version="2">
<description summary="xkb config global interface">
Global interface for configuring xkb devices.
@@ -107,7 +107,7 @@
</event>
</interface>
- <interface name="river_xkb_keymap_v1" version="1">
+ <interface name="river_xkb_keymap_v1" version="2">
<description summary="xkbcommon keymap">
This object is the result of attempting to create an xkbcommon keymap.
</description>
@@ -137,7 +137,7 @@
</event>
</interface>
- <interface name="river_xkb_keyboard_v1" version="1">
+ <interface name="river_xkb_keyboard_v1" version="2">
<description summary="xkbcommon keyboard device">
This object represent a physical keyboard which has its configuration and
state managed by xkbcommon.
@@ -273,5 +273,15 @@
again whenever the numlock state changes.
</description>
</event>
+
+ <event name="done" since="2">
+ <description summary="all information has been sent">
+ This event is sent after all information about the keyboard has been
+ sent.
+
+ This allows changes to one or more river_xkb_keyboard_v1 properties to
+ be seen as atomic, even if they happen via multiple events.
+ </description>
+ </event>
</interface>
</protocol>
diff --git a/river/InputDevice.zig b/river/InputDevice.zig
index 060e595..63e68bd 100644
--- a/river/InputDevice.zig
+++ b/river/InputDevice.zig
@@ -120,6 +120,9 @@ pub fn createObject(device: *InputDevice, im_v1: *river.InputManagerV1) void {
object.setHandler(*InputDevice, handleRequest, handleDestroy, device);
object.sendType(device_type);
object.sendName(device.wlr_device.name orelse "");
+ if (object.getVersion() >= 2) {
+ object.sendDone();
+ }
}
pub fn deinit(device: *InputDevice) void {
diff --git a/river/InputManager.zig b/river/InputManager.zig
index b5bb9e3..960b36e 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -51,7 +51,7 @@ new_text_input: wl.Listener(*wlr.TextInputV3) = .init(handleNewTextInput),
pub fn init(input_manager: *InputManager) !void {
input_manager.* = .{
- .global = try wl.Global.create(server.wl_server, river.InputManagerV1, 1, *InputManager, input_manager, bind),
+ .global = try wl.Global.create(server.wl_server, river.InputManagerV1, 2, *InputManager, input_manager, bind),
// These are automatically freed when the display is destroyed
.idle_notifier = try wlr.IdleNotifierV1.create(server.wl_server),
.relative_pointer_manager = try wlr.RelativePointerManagerV1.create(server.wl_server),
diff --git a/river/LibinputConfig.zig b/river/LibinputConfig.zig
index fb20a22..4759fc8 100644
--- a/river/LibinputConfig.zig
+++ b/river/LibinputConfig.zig
@@ -24,7 +24,7 @@ server_destroy: wl.Listener(*wl.Server) = .init(handleServerDestroy),
pub fn init(config: *LibinputConfig) !void {
config.* = .{
- .global = try wl.Global.create(server.wl_server, river.LibinputConfigV1, 1, *LibinputConfig, config, bind),
+ .global = try wl.Global.create(server.wl_server, river.LibinputConfigV1, 2, *LibinputConfig, config, bind),
.objects = undefined,
.devices = undefined,
};
diff --git a/river/LibinputDevice.zig b/river/LibinputDevice.zig
index 183d7ee..507368f 100644
--- a/river/LibinputDevice.zig
+++ b/river/LibinputDevice.zig
@@ -168,6 +168,9 @@ pub fn createObject(device: *LibinputDevice, config_v1: *river.LibinputConfigV1)
object.sendRotationDefault(c.libinput_device_config_rotation_get_default_angle(device.libinput));
object.sendRotationCurrent(c.libinput_device_config_rotation_get_angle(device.libinput));
}
+ if (object.getVersion() >= 2) {
+ object.sendDone();
+ }
}
pub fn deinit(device: *LibinputDevice) void {
@@ -200,6 +203,7 @@ fn handleRequest(
request: river.LibinputDeviceV1.Request,
device: *LibinputDevice,
) void {
+ var send_done = false;
switch (request) {
.destroy => object.destroy(),
.set_send_events => |args| {
@@ -209,6 +213,7 @@ fn handleRequest(
const current = c.libinput_device_config_send_events_get_mode(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendSendEventsCurrent(@bitCast(current));
+ send_done = true;
}
},
.set_tap => |args| {
@@ -225,6 +230,7 @@ fn handleRequest(
const current = c.libinput_device_config_tap_get_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendTapCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_tap_button_map => |args| {
@@ -241,6 +247,7 @@ fn handleRequest(
const current = c.libinput_device_config_tap_get_button_map(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendTapButtonMapCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_drag => |args| {
@@ -257,6 +264,7 @@ fn handleRequest(
const current = c.libinput_device_config_tap_get_drag_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendDragCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_drag_lock => |args| {
@@ -274,6 +282,7 @@ fn handleRequest(
const current = c.libinput_device_config_tap_get_drag_lock_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendDragLockCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_three_finger_drag => |args| {
@@ -291,6 +300,7 @@ fn handleRequest(
const current = c.libinput_device_config_3fg_drag_get_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendThreeFingerDragCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_calibration_matrix => |args| {
@@ -308,6 +318,7 @@ fn handleRequest(
_ = c.libinput_device_config_calibration_get_matrix(device.libinput, ¤t);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendCalibrationMatrixCurrent(&array);
+ send_done = true;
}
},
.set_accel_profile => |args| {
@@ -326,6 +337,7 @@ fn handleRequest(
const current = c.libinput_device_config_accel_get_profile(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendAccelProfileCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_accel_speed => |args| {
@@ -342,6 +354,7 @@ fn handleRequest(
var array: wl.Array = .{ .size = bytes.len, .alloc = bytes.len, .data = bytes.ptr };
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendAccelSpeedCurrent(&array);
+ send_done = true;
}
},
.apply_accel_config => |args| {
@@ -356,6 +369,7 @@ fn handleRequest(
const current = c.libinput_device_config_accel_get_profile(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendAccelProfileCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_natural_scroll => |args| {
@@ -372,6 +386,7 @@ fn handleRequest(
const current = c.libinput_device_config_scroll_get_natural_scroll_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendNaturalScrollCurrent(if (current != 0) .enabled else .disabled);
+ send_done = true;
}
},
.set_left_handed => |args| {
@@ -388,6 +403,7 @@ fn handleRequest(
const current = c.libinput_device_config_left_handed_get(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendLeftHandedCurrent(if (current != 0) .enabled else .disabled);
+ send_done = true;
}
},
.set_click_method => |args| {
@@ -405,6 +421,7 @@ fn handleRequest(
const current = c.libinput_device_config_click_get_method(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendClickMethodCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_clickfinger_button_map => |args| {
@@ -421,6 +438,7 @@ fn handleRequest(
const current = c.libinput_device_config_click_get_clickfinger_button_map(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendClickfingerButtonMapCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_middle_emulation => |args| {
@@ -437,6 +455,7 @@ fn handleRequest(
const current = c.libinput_device_config_middle_emulation_get_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendMiddleEmulationCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_scroll_method => |args| {
@@ -455,6 +474,7 @@ fn handleRequest(
const current = c.libinput_device_config_scroll_get_method(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendScrollMethodCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_scroll_button => |args| {
@@ -464,6 +484,7 @@ fn handleRequest(
const current = c.libinput_device_config_scroll_get_button(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendScrollButtonCurrent(current);
+ send_done = true;
}
},
.set_scroll_button_lock => |args| {
@@ -480,6 +501,7 @@ fn handleRequest(
const current = c.libinput_device_config_scroll_get_button_lock(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendScrollButtonLockCurrent(@enumFromInt(current));
+ send_done = true;
}
},
.set_dwt => |args| {
@@ -496,6 +518,7 @@ fn handleRequest(
const current = c.libinput_device_config_dwt_get_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendDwtCurrent(if (current != 0) .enabled else .disabled);
+ send_done = true;
}
},
.set_dwtp => |args| {
@@ -512,6 +535,7 @@ fn handleRequest(
const current = c.libinput_device_config_dwtp_get_enabled(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendDwtpCurrent(if (current != 0) .enabled else .disabled);
+ send_done = true;
}
},
.set_rotation => |args| {
@@ -521,9 +545,19 @@ fn handleRequest(
const current = c.libinput_device_config_rotation_get_angle(device.libinput);
var it = device.objects.iterator(.forward);
while (it.next()) |o| o.sendRotationCurrent(current);
+ send_done = true;
}
},
}
+
+ if (send_done) {
+ var it = device.objects.iterator(.forward);
+ while (it.next()) |o| {
+ if (o.getVersion() >= 2) {
+ o.sendDone();
+ }
+ }
+ }
}
const Result = struct {
diff --git a/river/XkbConfig.zig b/river/XkbConfig.zig
index 159604e..2107a84 100644
--- a/river/XkbConfig.zig
+++ b/river/XkbConfig.zig
@@ -36,7 +36,7 @@ pub fn init(config: *XkbConfig) !void {
defer default_keymap.unref();
config.* = .{
- .global = try wl.Global.create(server.wl_server, river.XkbConfigV1, 1, *XkbConfig, config, bind),
+ .global = try wl.Global.create(server.wl_server, river.XkbConfigV1, 2, *XkbConfig, config, bind),
.context = context.ref(),
.default_keymap = default_keymap.ref(),
.objects = undefined,
diff --git a/river/XkbKeyboard.zig b/river/XkbKeyboard.zig
index 0921bc6..2fff5d6 100644
--- a/river/XkbKeyboard.zig
+++ b/river/XkbKeyboard.zig
@@ -83,6 +83,9 @@ pub fn createObject(xkb_keyboard: *XkbKeyboard, config_v1: *river.XkbConfigV1) v
object.sendNumlockDisabled();
}
}
+ if (object.getVersion() >= 2) {
+ object.sendDone();
+ }
}
pub fn deinit(xkb_keyboard: *XkbKeyboard) void {
@@ -179,11 +182,13 @@ pub fn sendState(
const sent = &xkb_keyboard.sent;
var it = xkb_keyboard.objects.iterator(.forward);
while (it.next()) |object| {
+ var send_done = false;
if (sent.layout_index != layout_index or
(sent.layout_name == null) != (layout_name == null) or
(layout_name != null and mem.orderZ(u8, layout_name.?, sent.layout_name.?) != .eq))
{
object.sendLayout(layout_index, layout_name);
+ send_done = true;
}
if (sent.capslock != capslock) {
if (capslock) {
@@ -191,6 +196,7 @@ pub fn sendState(
} else {
object.sendCapslockDisabled();
}
+ send_done = true;
}
if (sent.numlock != numlock) {
if (numlock) {
@@ -198,6 +204,10 @@ pub fn sendState(
} else {
object.sendNumlockDisabled();
}
+ send_done = true;
+ }
+ if (send_done and object.getVersion() >= 2) {
+ object.sendDone();
}
}
sent.layout_index = layout_index;