From 18bddbc9870a8b86b30f55ca0c1ffe1a0f880fee Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 17 Oct 2024 16:08:54 +0200 Subject: [PATCH] seat: keep track of serials that are allowed to steal keyboard focus --- src/client.rs | 2 ++ src/ifs/wl_seat.rs | 12 ++++++++++++ src/ifs/wl_seat/event_handling.rs | 6 +++++- src/ifs/wl_seat/tablet/tool.rs | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/client.rs b/src/client.rs index 70a7f586..71fdeb5c 100644 --- a/src/client.rs +++ b/src/client.rs @@ -175,6 +175,7 @@ impl Clients { slf, )), wire_scale: Default::default(), + focus_stealing_serial: Default::default(), }); track!(data, data); let display = Rc::new(WlDisplay::new(&data)); @@ -286,6 +287,7 @@ pub struct Client { pub activation_tokens: RefCell>, pub commit_timelines: Rc, pub wire_scale: Cell>, + pub focus_stealing_serial: Cell>, } pub const NUM_CACHED_SERIAL_RANGES: usize = 64; diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 409f8ea8..b4598f8f 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -1041,6 +1041,18 @@ impl WlSeatGlobal { ei_seat.regions_changed(); }); } + + #[expect(dead_code)] + pub fn handle_focus_request(self: &Rc, client: &Client, node: Rc, serial: u64) { + let Some(max_serial) = client.focus_stealing_serial.get() else { + return; + }; + let serial = serial.min(max_serial); + if serial <= self.keyboard_node_serial.get() { + return; + } + self.focus_node_with_serial(node, serial); + } } impl CursorUserOwner for WlSeatGlobal { diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index ea638a37..0a8ded1d 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -1150,7 +1150,10 @@ impl WlSeatGlobal { ) { let (state, pressed) = match state { KeyState::Released => (wl_pointer::RELEASED, false), - KeyState::Pressed => (wl_pointer::PRESSED, true), + KeyState::Pressed => { + surface.client.focus_stealing_serial.set(Some(serial)); + (wl_pointer::PRESSED, true) + } }; let time = (time_usec / 1000) as u32; self.surface_pointer_event(Version::ALL, surface, |p| { @@ -1372,6 +1375,7 @@ impl WlSeatGlobal { y: Fixed, ) { let serial = surface.client.next_serial(); + surface.client.focus_stealing_serial.set(Some(serial)); let time = (time_usec / 1000) as _; self.surface_touch_event(Version::ALL, surface, |t| { t.send_down(serial, time, surface.id, id, x, y) diff --git a/src/ifs/wl_seat/tablet/tool.rs b/src/ifs/wl_seat/tablet/tool.rs index c8346781..fcda9cbf 100644 --- a/src/ifs/wl_seat/tablet/tool.rs +++ b/src/ifs/wl_seat/tablet/tool.rs @@ -211,6 +211,7 @@ impl TabletTool { tool.send_frame(time); }); if state == ToolButtonState::Pressed { + n.client.focus_stealing_serial.set(Some(serial.get())); if let Some(node) = n.get_focus_node(self.tablet.seat.id) { self.tablet.seat.focus_node_with_serial(node, serial.get()); } @@ -259,6 +260,7 @@ impl TabletTool { }); if let Some(changes) = changes { if changes.down == Some(true) { + n.client.focus_stealing_serial.set(Some(serial.get())); if let Some(node) = n.get_focus_node(self.tablet.seat.id) { self.tablet.seat.focus_node_with_serial(node, serial.get()); }