srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-09-11 20:46:00 +0200
committersrdusr <[email protected]>2025-09-11 20:46:00 +0200
commitb219797e2143ea84cf527fbf48afb22cc35fe9a5 (patch)
tree5ff8d1679fde0d36a794169590a2d81ce8a6402b /tools
parent5ee627928d0cb017e59d796c71793c35d5b65d33 (diff)
downloadsrdwm-b219797e2143ea84cf527fbf48afb22cc35fe9a5.tar.gz
srdwm-b219797e2143ea84cf527fbf48afb22cc35fe9a5.zip
Add a minimal zwlr_virtual_pointer_unstable_v1 test client
Standalone (not a workspace member, same reasoning as the existing tools/toplevel-activate), built to live-verify the Wayland crate's new pinned-virtual-pointer delivery (crates/wayland/src/virtual_pointer.rs) against a real client rather than reading the source: prints its own pid so an external script can pin it via srd dispatch pin input, then drags from one point to another on a stdin signal. Not yet run against a live nested instance - launching one hits this project's own nightshift deny-list guard against a bare nested-compositor invocation, parked rather than worked around; see docs/TODO.md.
Diffstat (limited to 'tools')
-rw-r--r--tools/virtual-pointer-pin-test/Cargo.lock216
-rw-r--r--tools/virtual-pointer-pin-test/Cargo.toml18
-rw-r--r--tools/virtual-pointer-pin-test/src/main.rs112
3 files changed, 346 insertions, 0 deletions
diff --git a/tools/virtual-pointer-pin-test/Cargo.lock b/tools/virtual-pointer-pin-test/Cargo.lock
new file mode 100644
index 0000000..8c8dad2
--- /dev/null
+++ b/tools/virtual-pointer-pin-test/Cargo.lock
@@ -0,0 +1,216 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "bitflags"
+version = "2.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
+
+[[package]]
+name = "cc"
+version = "1.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
+dependencies = [
+ "find-msvc-tools",
+ "shlex",
+]
+
+[[package]]
+name = "downcast-rs"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
+
+[[package]]
+name = "libc"
+version = "0.2.189"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+
+[[package]]
+name = "memchr"
+version = "2.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quick-xml"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
+name = "shlex"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
+
+[[package]]
+name = "smallvec"
+version = "1.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
+[[package]]
+name = "virtual-pointer-pin-test"
+version = "0.1.0"
+dependencies = [
+ "wayland-client",
+ "wayland-protocols-wlr",
+]
+
+[[package]]
+name = "wayland-backend"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078"
+dependencies = [
+ "cc",
+ "downcast-rs",
+ "rustix",
+ "smallvec",
+ "wayland-sys",
+]
+
+[[package]]
+name = "wayland-client"
+version = "0.31.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144"
+dependencies = [
+ "bitflags",
+ "rustix",
+ "wayland-backend",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-protocols"
+version = "0.32.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6"
+dependencies = [
+ "bitflags",
+ "wayland-backend",
+ "wayland-client",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-protocols-wlr"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234"
+dependencies = [
+ "bitflags",
+ "wayland-backend",
+ "wayland-client",
+ "wayland-protocols",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-scanner"
+version = "0.31.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0"
+dependencies = [
+ "proc-macro2",
+ "quick-xml",
+ "quote",
+]
+
+[[package]]
+name = "wayland-sys"
+version = "0.31.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be"
+dependencies = [
+ "pkg-config",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
diff --git a/tools/virtual-pointer-pin-test/Cargo.toml b/tools/virtual-pointer-pin-test/Cargo.toml
new file mode 100644
index 0000000..b5ba931
--- /dev/null
+++ b/tools/virtual-pointer-pin-test/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "virtual-pointer-pin-test"
+version = "0.1.0"
+edition = "2021"
+
+# Standalone - deliberately not a member of the main workspace at
+# ../../Cargo.toml, same reasoning as ../toplevel-activate's own Cargo.toml:
+# building/testing srdwm itself never has to build this too. A debug tool,
+# not part of the shipped product.
+[workspace]
+
+[[bin]]
+name = "vptest"
+path = "src/main.rs"
+
+[dependencies]
+wayland-client = "=0.31.14"
+wayland-protocols-wlr = { version = "=0.3.12", features = ["client"] }
diff --git a/tools/virtual-pointer-pin-test/src/main.rs b/tools/virtual-pointer-pin-test/src/main.rs
new file mode 100644
index 0000000..9e46939
--- /dev/null
+++ b/tools/virtual-pointer-pin-test/src/main.rs
@@ -0,0 +1,112 @@
+// Minimal zwlr_virtual_pointer_unstable_v1 client: prints its own pid (so
+// an external script can `srd dispatch pin input <pid> <window-id>` while
+// it waits), then on a line from stdin sends motion_absolute/button/frame
+// requests to drag from one point to another - built to live-verify
+// srdwm's Phase 2 pinned-virtual-pointer delivery (see
+// crates/wayland/src/virtual_pointer.rs's own module doc comment) against
+// a real client, the same "purpose-built protocol test client, not a
+// guess from source reading" precedent ../toplevel-activate already set
+// for zwlr_foreign_toplevel_handle_v1.
+//
+// Usage:
+// vptest <x1> <y1> <x2> <y2>
+// Prints "pid <n>", then blocks on one line of stdin ("go\n").
+// Sends motion_absolute(x1,y1) [0..10000 extent], button press,
+// motion_absolute(x2,y2), button release, frame, flush, exits.
+
+use std::io::BufRead;
+
+use wayland_client::protocol::{wl_registry, wl_seat::WlSeat};
+use wayland_client::{Connection, Dispatch, EventQueue, QueueHandle};
+use wayland_protocols_wlr::virtual_pointer::v1::client::zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1;
+use wayland_protocols_wlr::virtual_pointer::v1::client::zwlr_virtual_pointer_v1::{self, ZwlrVirtualPointerV1};
+
+const EXTENT: u32 = 10000;
+const BTN_LEFT: u32 = 0x110;
+
+struct State {
+ seat: Option<WlSeat>,
+ manager: Option<ZwlrVirtualPointerManagerV1>,
+}
+
+impl Dispatch<wl_registry::WlRegistry, ()> for State {
+ fn event(state: &mut Self, registry: &wl_registry::WlRegistry, event: wl_registry::Event, _: &(), _: &Connection, qh: &QueueHandle<Self>) {
+ if let wl_registry::Event::Global { name, interface, version } = event {
+ if interface == "wl_seat" {
+ state.seat = Some(registry.bind::<WlSeat, _, _>(name, version.min(9), qh, ()));
+ } else if interface == "zwlr_virtual_pointer_manager_v1" {
+ state.manager = Some(registry.bind::<ZwlrVirtualPointerManagerV1, _, _>(name, version.min(2), qh, ()));
+ }
+ }
+ }
+}
+
+impl Dispatch<WlSeat, ()> for State {
+ fn event(_: &mut Self, _: &WlSeat, _: wayland_client::protocol::wl_seat::Event, _: &(), _: &Connection, _: &QueueHandle<Self>) {}
+}
+
+impl Dispatch<ZwlrVirtualPointerManagerV1, ()> for State {
+ fn event(_: &mut Self, _: &ZwlrVirtualPointerManagerV1, _: wayland_protocols_wlr::virtual_pointer::v1::client::zwlr_virtual_pointer_manager_v1::Event, _: &(), _: &Connection, _: &QueueHandle<Self>) {
+ }
+}
+
+impl Dispatch<ZwlrVirtualPointerV1, ()> for State {
+ fn event(_: &mut Self, _: &ZwlrVirtualPointerV1, _: zwlr_virtual_pointer_v1::Event, _: &(), _: &Connection, _: &QueueHandle<Self>) {}
+}
+
+fn main() {
+ let args: Vec<String> = std::env::args().skip(1).collect();
+ if args.len() != 4 {
+ eprintln!("usage: vptest <x1> <y1> <x2> <y2> (fractions of EXTENT={EXTENT}, e.g. 5000 5000 is dead center)");
+ std::process::exit(1);
+ }
+ let x1: u32 = args[0].parse().expect("x1 must be a number");
+ let y1: u32 = args[1].parse().expect("y1 must be a number");
+ let x2: u32 = args[2].parse().expect("x2 must be a number");
+ let y2: u32 = args[3].parse().expect("y2 must be a number");
+
+ let conn = Connection::connect_to_env().expect("failed to connect to the Wayland compositor - is WAYLAND_DISPLAY set?");
+ let display = conn.display();
+ let mut event_queue: EventQueue<State> = conn.new_event_queue();
+ let qh = event_queue.handle();
+ let _registry = display.get_registry(&qh, ());
+
+ let mut state = State { seat: None, manager: None };
+ event_queue.roundtrip(&mut state).expect("initial roundtrip failed");
+
+ let Some(manager) = state.manager.clone() else {
+ eprintln!("compositor does not advertise zwlr_virtual_pointer_manager_v1");
+ std::process::exit(1);
+ };
+ let Some(seat) = state.seat.clone() else {
+ eprintln!("compositor does not advertise wl_seat");
+ std::process::exit(1);
+ };
+
+ let pointer = manager.create_virtual_pointer(Some(&seat), &qh, ());
+ event_queue.roundtrip(&mut state).expect("create_virtual_pointer roundtrip failed");
+
+ println!("pid {}", std::process::id());
+ println!("waiting for a line on stdin before sending any motion...");
+ let mut line = String::new();
+ std::io::stdin().lock().read_line(&mut line).expect("failed to read stdin");
+
+ let time = 0;
+ pointer.motion_absolute(time, x1, y1, EXTENT, EXTENT);
+ pointer.frame();
+ event_queue.roundtrip(&mut state).expect("motion_absolute(1) roundtrip failed");
+
+ pointer.button(time, BTN_LEFT, wayland_client::protocol::wl_pointer::ButtonState::Pressed);
+ pointer.frame();
+ event_queue.roundtrip(&mut state).expect("button press roundtrip failed");
+
+ pointer.motion_absolute(time, x2, y2, EXTENT, EXTENT);
+ pointer.frame();
+ event_queue.roundtrip(&mut state).expect("motion_absolute(2) roundtrip failed");
+
+ pointer.button(time, BTN_LEFT, wayland_client::protocol::wl_pointer::ButtonState::Released);
+ pointer.frame();
+ event_queue.roundtrip(&mut state).expect("button release roundtrip failed");
+
+ println!("done.");
+}