diff --git a/.builds/alpine.yml b/.builds/alpine.yml index 30356d9..ae040fc 100644 --- a/.builds/alpine.yml +++ b/.builds/alpine.yml @@ -28,7 +28,7 @@ sources: tasks: - install_deps: | cd wlroots - git checkout 0.19.0 + git checkout 0.20.0 meson setup build --auto-features=enabled -Drenderers=gles2 \ -Dcolor-management=disabled -Dlibliftoff=disabled \ -Dexamples=false -Dwerror=false -Db_ndebug=false \ diff --git a/.builds/archlinux.yml b/.builds/archlinux.yml index bf7db0a..be19c56 100644 --- a/.builds/archlinux.yml +++ b/.builds/archlinux.yml @@ -25,7 +25,7 @@ sources: tasks: - install_deps: | cd wlroots - git checkout 0.19.0 + git checkout 0.20.0 meson setup build --auto-features=enabled -Drenderers=gles2 \ -Dcolor-management=disabled -Dlibliftoff=disabled \ -Dexamples=false -Dwerror=false -Db_ndebug=false \ diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index 8450545..3191571 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -31,7 +31,7 @@ sources: tasks: - install_deps: | cd wlroots - git checkout 0.19.0 + git checkout 0.20.0 meson setup build --auto-features=enabled -Drenderers=gles2 \ -Dallocators=gbm \ -Dcolor-management=disabled -Dlibliftoff=disabled \ diff --git a/README.md b/README.md index 3df5af3..0f84f01 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ distribution. - [zig](https://ziglang.org/download/) 0.15 - wayland - wayland-protocols -- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.19 +- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.20 - xkbcommon - libevdev - pixman diff --git a/build.zig b/build.zig index bdbd49c..641e0a7 100644 --- a/build.zig +++ b/build.zig @@ -98,6 +98,7 @@ pub fn build(b: *Build) !void { scanner.addCustomProtocol(b.path("protocol/river-layout-v3.xml")); scanner.addCustomProtocol(b.path("protocol/wlr-layer-shell-unstable-v1.xml")); scanner.addCustomProtocol(b.path("protocol/wlr-output-power-management-unstable-v1.xml")); + scanner.addCustomProtocol(b.path("protocol/virtual-keyboard-unstable-v1.xml")); // Some of these versions may be out of date with what wlroots implements. // This is not a problem in practice though as long as river successfully compiles. @@ -126,6 +127,7 @@ pub fn build(b: *Build) !void { scanner.generate("zwlr_layer_shell_v1", 4); scanner.generate("zwlr_output_power_manager_v1", 1); + scanner.generate("zwp_virtual_keyboard_manager_v1", 1); const wayland = b.createModule(.{ .root_source_file = scanner.result }); @@ -141,7 +143,7 @@ pub fn build(b: *Build) !void { // exposed to the wlroots module for @cImport() to work. This seems to be // the best way to do so with the current std.Build API. wlroots.resolved_target = target; - wlroots.linkSystemLibrary("wlroots-0.19", .{}); + wlroots.linkSystemLibrary("wlroots-0.20", .{}); const flags = b.createModule(.{ .root_source_file = b.path("common/flags.zig") }); const globber = b.createModule(.{ .root_source_file = b.path("common/globber.zig") }); @@ -162,7 +164,7 @@ pub fn build(b: *Build) !void { river.linkSystemLibrary("libevdev"); river.linkSystemLibrary("libinput"); river.linkSystemLibrary("wayland-server"); - river.linkSystemLibrary("wlroots-0.19"); + river.linkSystemLibrary("wlroots-0.20"); river.linkSystemLibrary("xkbcommon"); river.linkSystemLibrary("pixman-1"); diff --git a/build.zig.zon b/build.zig.zon index da4fdfa..963987c 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -17,8 +17,8 @@ .hash = "wayland-0.4.0-lQa1khbMAQAsLS2eBR7M5lofyEGPIbu2iFDmoz8lPC27", }, .wlroots = .{ - .url = "https://codeberg.org/ifreund/zig-wlroots/archive/v0.19.3.tar.gz", - .hash = "wlroots-0.19.3-jmOlcuL_AwBHhLCwpFsXbTizE3q9BugFmGX-XIxqcPMc", + .url = "git+https://codeberg.org/ifreund/zig-wlroots?ref=master#6ffee8b21d24e0e4aadcf204f65ebe7ad3c3bacf", + .hash = "wlroots-0.20.0-dev-jmOlclseBABjKSxVH4TVkN4Fm-moidbybTStGsujJU_m", }, .xkbcommon = .{ .url = "https://codeberg.org/ifreund/zig-xkbcommon/archive/v0.3.0.tar.gz", diff --git a/protocol/virtual-keyboard-unstable-v1.xml b/protocol/virtual-keyboard-unstable-v1.xml new file mode 100644 index 0000000..5095c91 --- /dev/null +++ b/protocol/virtual-keyboard-unstable-v1.xml @@ -0,0 +1,113 @@ + + + + Copyright © 2008-2011 Kristian Høgsberg + Copyright © 2010-2013 Intel Corporation + Copyright © 2012-2013 Collabora, Ltd. + Copyright © 2018 Purism SPC + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + The virtual keyboard provides an application with requests which emulate + the behaviour of a physical keyboard. + + This interface can be used by clients on its own to provide raw input + events, or it can accompany the input method protocol. + + + + + Provide a file descriptor to the compositor which can be + memory-mapped to provide a keyboard mapping description. + + Format carries a value from the keymap_format enumeration. + + + + + + + + + + + + + A key was pressed or released. + The time argument is a timestamp with millisecond granularity, with an + undefined base. All requests regarding a single object must share the + same clock. + + Keymap must be set before issuing this request. + + State carries a value from the key_state enumeration. + + + + + + + + + Notifies the compositor that the modifier and/or group state has + changed, and it should update state. + + The client should use wl_keyboard.modifiers event to synchronize its + internal state with seat state. + + Keymap must be set before issuing this request. + + + + + + + + + + + + + + + A virtual keyboard manager allows an application to provide keyboard + input events as if they came from a physical keyboard. + + + + + + + + + Creates a new virtual keyboard associated to a seat. + + If the compositor enables a keyboard to perform arbitrary actions, it + should present an error when an untrusted client requests a new + keyboard. + + + + + + diff --git a/river/Cursor.zig b/river/Cursor.zig index 2e29e2d..0d5c472 100644 --- a/river/Cursor.zig +++ b/river/Cursor.zig @@ -307,10 +307,7 @@ pub fn setTheme(cursor: *Cursor, theme: ?[*:0]const u8, _size: ?u32) !void { const wlr_xcursor = xcursor_manager.getXcursor("default", 1).?; const image = wlr_xcursor.images[0]; xwayland.setCursor( - image.buffer, - image.width * 4, - image.width, - image.height, + image.getBuffer(), @intCast(image.hotspot_x), @intCast(image.hotspot_y), ); diff --git a/river/InputManager.zig b/river/InputManager.zig index 0a744d4..96df752 100644 --- a/river/InputManager.zig +++ b/river/InputManager.zig @@ -104,8 +104,8 @@ pub fn init(input_manager: *InputManager) !void { input_manager.virtual_pointer_manager.events.new_virtual_pointer.add(&input_manager.new_virtual_pointer); input_manager.virtual_keyboard_manager.events.new_virtual_keyboard.add(&input_manager.new_virtual_keyboard); input_manager.pointer_constraints.events.new_constraint.add(&input_manager.new_constraint); - input_manager.input_method_manager.events.input_method.add(&input_manager.new_input_method); - input_manager.text_input_manager.events.text_input.add(&input_manager.new_text_input); + input_manager.input_method_manager.events.new_input_method.add(&input_manager.new_input_method); + input_manager.text_input_manager.events.new_text_input.add(&input_manager.new_text_input); } pub fn deinit(input_manager: *InputManager) void { diff --git a/river/InputRelay.zig b/river/InputRelay.zig index 69d655d..87e8f4c 100644 --- a/river/InputRelay.zig +++ b/river/InputRelay.zig @@ -46,12 +46,10 @@ 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), +input_method_commit: wl.Listener(void) = .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_destroy: wl.Listener(void) = .init(handleInputMethodDestroy), input_method_new_popup: wl.Listener(*wlr.InputPopupSurfaceV2) = wl.Listener(*wlr.InputPopupSurfaceV2).init(handleInputMethodNewPopup), @@ -89,12 +87,9 @@ pub fn newInputMethod(relay: *InputRelay, input_method: *wlr.InputMethodV2) void } } -fn handleInputMethodCommit( - listener: *wl.Listener(*wlr.InputMethodV2), - input_method: *wlr.InputMethodV2, -) void { +fn handleInputMethodCommit(listener: *wl.Listener(void)) void { const relay: *InputRelay = @fieldParentPtr("input_method_commit", listener); - assert(input_method == relay.input_method); + const input_method = relay.input_method.?; if (!input_method.client_active) return; const text_input = relay.text_input orelse return; @@ -123,12 +118,8 @@ fn handleInputMethodCommit( text_input.wlr_text_input.sendDone(); } -fn handleInputMethodDestroy( - listener: *wl.Listener(*wlr.InputMethodV2), - input_method: *wlr.InputMethodV2, -) void { +fn handleInputMethodDestroy(listener: *wl.Listener(void)) void { const relay: *InputRelay = @fieldParentPtr("input_method_destroy", listener); - assert(input_method == relay.input_method); relay.input_method_commit.link.remove(); relay.grab_keyboard.link.remove(); diff --git a/river/TextInput.zig b/river/TextInput.zig index e296cb4..f9d601f 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(void) = .init(handleEnable), +commit: wl.Listener(void) = .init(handleCommit), +disable: wl.Listener(void) = .init(handleDisable), +destroy: wl.Listener(void) = .init(handleDestroy), pub fn create(wlr_text_input: *wlr.TextInputV3) !void { const seat: *Seat = @ptrCast(@alignCast(wlr_text_input.seat.data)); @@ -62,7 +58,7 @@ pub fn create(wlr_text_input: *wlr.TextInputV3) !void { wlr_text_input.events.destroy.add(&text_input.destroy); } -fn handleEnable(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void { +fn handleEnable(listener: *wl.Listener(void)) void { const text_input: *TextInput = @fieldParentPtr("enable", listener); const seat: *Seat = @ptrCast(@alignCast(text_input.wlr_text_input.seat.data)); @@ -89,7 +85,7 @@ fn handleEnable(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) v } } -fn handleCommit(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void { +fn handleCommit(listener: *wl.Listener(void)) void { const text_input: *TextInput = @fieldParentPtr("commit", listener); const seat: *Seat = @ptrCast(@alignCast(text_input.wlr_text_input.seat.data)); @@ -103,7 +99,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) v } } -fn handleDisable(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void { +fn handleDisable(listener: *wl.Listener(void)) void { const text_input: *TextInput = @fieldParentPtr("disable", listener); const seat: *Seat = @ptrCast(@alignCast(text_input.wlr_text_input.seat.data)); @@ -112,7 +108,7 @@ fn handleDisable(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) } } -fn handleDestroy(listener: *wl.Listener(*wlr.TextInputV3), _: *wlr.TextInputV3) void { +fn handleDestroy(listener: *wl.Listener(void)) void { const text_input: *TextInput = @fieldParentPtr("destroy", listener); const seat: *Seat = @ptrCast(@alignCast(text_input.wlr_text_input.seat.data));