From 69b1c1870e7eb2bbbc159d0b3a3ea85bd7ca192f Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 1 Feb 2020 18:25:50 +0300 Subject: [PATCH 1/9] anvil.window_map: add Kind::equals --- anvil/src/window_map.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/anvil/src/window_map.rs b/anvil/src/window_map.rs index b15a37c..3a553c0 100644 --- a/anvil/src/window_map.rs +++ b/anvil/src/window_map.rs @@ -33,6 +33,15 @@ where Kind::Wl(ref t) => t.get_surface(), } } + + /// Do this handle and the other one actually refer to the same toplevel surface? + pub fn equals(&self, other: &Self) -> bool { + match (self, other) { + (Kind::Xdg(a), Kind::Xdg(b)) => a.equals(b), + (Kind::Wl(a), Kind::Wl(b)) => a.equals(b), + _ => false, + } + } } struct Window { From a51e421c1922f58a85e364112085c3bf4fcefb42 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 1 Feb 2020 18:30:01 +0300 Subject: [PATCH 2/9] anvil.window_map: add WindowMap::location --- anvil/src/window_map.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/anvil/src/window_map.rs b/anvil/src/window_map.rs index 3a553c0..0021063 100644 --- a/anvil/src/window_map.rs +++ b/anvil/src/window_map.rs @@ -234,4 +234,12 @@ where pub fn clear(&mut self) { self.windows.clear(); } + + /// Returns the location of the toplevel, if it exists. + pub fn location(&self, toplevel: &Kind) -> Option<(i32, i32)> { + self.windows + .iter() + .find(|w| w.toplevel.equals(toplevel)) + .map(|w| w.location) + } } From 0ea4ec9abe7140e6e496c3275c68cc1802e828b7 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 1 Feb 2020 18:30:13 +0300 Subject: [PATCH 3/9] anvil.window_map: add WindowMap::set_location --- anvil/src/window_map.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/anvil/src/window_map.rs b/anvil/src/window_map.rs index 0021063..5d59831 100644 --- a/anvil/src/window_map.rs +++ b/anvil/src/window_map.rs @@ -242,4 +242,12 @@ where .find(|w| w.toplevel.equals(toplevel)) .map(|w| w.location) } + + /// Sets the location of the toplevel, if it exists. + pub fn set_location(&mut self, toplevel: &Kind, location: (i32, i32)) { + if let Some(w) = self.windows.iter_mut().find(|w| w.toplevel.equals(toplevel)) { + w.location = location; + w.self_update(self.ctoken, &self.get_size); + } + } } From ba1396ca8cae671869de1aaad4fe43a5162abb44 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 1 Feb 2020 18:31:13 +0300 Subject: [PATCH 4/9] seat: add PointerHandle::current_location --- src/wayland/seat/pointer.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wayland/seat/pointer.rs b/src/wayland/seat/pointer.rs index 24aad26..e674b4a 100644 --- a/src/wayland/seat/pointer.rs +++ b/src/wayland/seat/pointer.rs @@ -219,6 +219,11 @@ impl PointerHandle { grab.axis(&mut handle, details); }); } + + /// Access the current location of this pointer in the global space + pub fn current_location(&self) -> (f64, f64) { + self.inner.borrow().location + } } /// A trait to implement a pointer grab From 24af494cbfbcd48de78d343e1b17946cf143869c Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 1 Feb 2020 18:42:08 +0300 Subject: [PATCH 5/9] anvil.shell: implement the Move request --- anvil/src/shell.rs | 125 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 17 deletions(-) diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index 21ddb8e..cfd4957 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -8,14 +8,14 @@ use rand; use smithay::{ reexports::wayland_server::{ - protocol::{wl_buffer, wl_shell_surface, wl_surface}, + protocol::{wl_buffer, wl_pointer::ButtonState, wl_shell_surface, wl_surface}, Display, }, utils::Rectangle, wayland::{ compositor::{compositor_init, CompositorToken, RegionAttributes, SurfaceAttributes, SurfaceEvent}, data_device::DnDIconRole, - seat::CursorImageRole, + seat::{AxisFrame, CursorImageRole, PointerGrab, PointerInnerHandle, Seat}, shell::{ legacy::{ wl_shell_init, ShellRequest, ShellState as WlShellState, ShellSurfaceKind, ShellSurfaceRole, @@ -25,6 +25,7 @@ use smithay::{ XdgSurfaceRole, }, }, + SERIAL_COUNTER as SCOUNTER, }, }; @@ -45,6 +46,52 @@ pub type MyWindowMap = WindowMap< pub type MyCompositorToken = CompositorToken; +struct MoveSurfaceGrab { + window_map: Rc>, + toplevel: SurfaceKind, + initial_pointer_location: (f64, f64), + initial_window_location: (i32, i32), +} + +impl PointerGrab for MoveSurfaceGrab { + fn motion( + &mut self, + _handle: &mut PointerInnerHandle<'_>, + location: (f64, f64), + _focus: Option<(wl_surface::WlSurface, (f64, f64))>, + _serial: u32, + _time: u32, + ) { + let dx = location.0 - self.initial_pointer_location.0; + let dy = location.1 - self.initial_pointer_location.1; + let new_window_x = (self.initial_window_location.0 as f64 + dx) as i32; + let new_window_y = (self.initial_window_location.1 as f64 + dy) as i32; + + self.window_map + .borrow_mut() + .set_location(&self.toplevel, (new_window_x, new_window_y)); + } + + fn button( + &mut self, + handle: &mut PointerInnerHandle<'_>, + button: u32, + state: ButtonState, + serial: u32, + time: u32, + ) { + handle.button(button, state, serial, time); + if handle.current_pressed().is_empty() { + // No more buttons are pressed, release the grab. + handle.unset_grab(serial, time); + } + } + + fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) { + handle.axis(details) + } +} + pub fn init_shell( display: &mut Display, log: ::slog::Logger, @@ -100,6 +147,27 @@ pub fn init_shell( position: (10, 10), serial: 42, }), + XdgRequest::Move { + surface, + seat, + serial, + } => { + let seat = Seat::from_resource(&seat).unwrap(); + // TODO: touch move. + let pointer = seat.get_pointer().unwrap(); + + let toplevel = SurfaceKind::Xdg(surface); + let initial_window_location = xdg_window_map.borrow().location(&toplevel).unwrap(); + + let grab = MoveSurfaceGrab { + window_map: xdg_window_map.clone(), + toplevel, + initial_pointer_location: pointer.current_location(), + initial_window_location, + }; + + pointer.set_grab(grab, serial); + } _ => (), }, log.clone(), @@ -111,21 +179,44 @@ pub fn init_shell( display, compositor_token, move |req: ShellRequest<_>| { - if let ShellRequest::SetKind { - surface, - kind: ShellSurfaceKind::Toplevel, - } = req - { - // place the window at a random location in the [0;800]x[0;800] square - use rand::distributions::{Distribution, Uniform}; - let range = Uniform::new(0, 800); - let mut rng = rand::thread_rng(); - let x = range.sample(&mut rng); - let y = range.sample(&mut rng); - surface.send_configure((0, 0), wl_shell_surface::Resize::None); - shell_window_map - .borrow_mut() - .insert(SurfaceKind::Wl(surface), (x, y)); + match req { + ShellRequest::SetKind { + surface, + kind: ShellSurfaceKind::Toplevel, + } => { + // place the window at a random location in the [0;800]x[0;800] square + use rand::distributions::{Distribution, Uniform}; + let range = Uniform::new(0, 800); + let mut rng = rand::thread_rng(); + let x = range.sample(&mut rng); + let y = range.sample(&mut rng); + surface.send_configure((0, 0), wl_shell_surface::Resize::None); + shell_window_map + .borrow_mut() + .insert(SurfaceKind::Wl(surface), (x, y)); + } + ShellRequest::Move { + surface, + seat, + serial, + } => { + let seat = Seat::from_resource(&seat).unwrap(); + // TODO: touch move. + let pointer = seat.get_pointer().unwrap(); + + let toplevel = SurfaceKind::Wl(surface); + let initial_window_location = shell_window_map.borrow().location(&toplevel).unwrap(); + + let grab = MoveSurfaceGrab { + window_map: shell_window_map.clone(), + toplevel, + initial_pointer_location: pointer.current_location(), + initial_window_location, + }; + + pointer.set_grab(grab, serial); + } + _ => (), } }, log.clone(), From 03392bf7d19dce60ea6da8416c013d81bb7e2c89 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 2 Feb 2020 18:05:49 +0300 Subject: [PATCH 6/9] seat: add GrabStartData to PointerGrab Stores the data about the event that started the grab. Will be useful for things like move and resize requests. --- anvil/src/shell.rs | 20 +++++++---- src/wayland/data_device/dnd_grab.rs | 9 ++++- src/wayland/data_device/mod.rs | 20 ++++++++--- src/wayland/data_device/server_dnd_grab.rs | 9 ++++- src/wayland/seat/mod.rs | 3 +- src/wayland/seat/pointer.rs | 41 +++++++++++++++++++--- 6 files changed, 85 insertions(+), 17 deletions(-) diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index cfd4957..81b85b5 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -15,7 +15,7 @@ use smithay::{ wayland::{ compositor::{compositor_init, CompositorToken, RegionAttributes, SurfaceAttributes, SurfaceEvent}, data_device::DnDIconRole, - seat::{AxisFrame, CursorImageRole, PointerGrab, PointerInnerHandle, Seat}, + seat::{AxisFrame, CursorImageRole, GrabStartData, PointerGrab, PointerInnerHandle, Seat}, shell::{ legacy::{ wl_shell_init, ShellRequest, ShellState as WlShellState, ShellSurfaceKind, ShellSurfaceRole, @@ -47,9 +47,9 @@ pub type MyWindowMap = WindowMap< pub type MyCompositorToken = CompositorToken; struct MoveSurfaceGrab { + start_data: GrabStartData, window_map: Rc>, toplevel: SurfaceKind, - initial_pointer_location: (f64, f64), initial_window_location: (i32, i32), } @@ -62,8 +62,8 @@ impl PointerGrab for MoveSurfaceGrab { _serial: u32, _time: u32, ) { - let dx = location.0 - self.initial_pointer_location.0; - let dy = location.1 - self.initial_pointer_location.1; + let dx = location.0 - self.start_data.location.0; + let dy = location.1 - self.start_data.location.1; let new_window_x = (self.initial_window_location.0 as f64 + dx) as i32; let new_window_y = (self.initial_window_location.1 as f64 + dy) as i32; @@ -90,6 +90,10 @@ impl PointerGrab for MoveSurfaceGrab { fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) { handle.axis(details) } + + fn start_data(&self) -> &GrabStartData { + &self.start_data + } } pub fn init_shell( @@ -156,13 +160,15 @@ pub fn init_shell( // TODO: touch move. let pointer = seat.get_pointer().unwrap(); + let start_data = pointer.grab_start_data().unwrap(); + let toplevel = SurfaceKind::Xdg(surface); let initial_window_location = xdg_window_map.borrow().location(&toplevel).unwrap(); let grab = MoveSurfaceGrab { + start_data, window_map: xdg_window_map.clone(), toplevel, - initial_pointer_location: pointer.current_location(), initial_window_location, }; @@ -204,13 +210,15 @@ pub fn init_shell( // TODO: touch move. let pointer = seat.get_pointer().unwrap(); + let start_data = pointer.grab_start_data().unwrap(); + let toplevel = SurfaceKind::Wl(surface); let initial_window_location = shell_window_map.borrow().location(&toplevel).unwrap(); let grab = MoveSurfaceGrab { + start_data, window_map: shell_window_map.clone(), toplevel, - initial_pointer_location: pointer.current_location(), initial_window_location, }; diff --git a/src/wayland/data_device/dnd_grab.rs b/src/wayland/data_device/dnd_grab.rs index f97fd62..7b9c1cd 100644 --- a/src/wayland/data_device/dnd_grab.rs +++ b/src/wayland/data_device/dnd_grab.rs @@ -8,12 +8,13 @@ use wayland_server::{ use crate::wayland::{ compositor::{roles::Role, CompositorToken}, - seat::{AxisFrame, PointerGrab, PointerInnerHandle, Seat}, + seat::{AxisFrame, GrabStartData, PointerGrab, PointerInnerHandle, Seat}, }; use super::{with_source_metadata, DataDeviceData, DnDIconRole, SeatData}; pub(crate) struct DnDGrab { + start_data: GrabStartData, data_source: Option, current_focus: Option, pending_offers: Vec, @@ -27,6 +28,7 @@ pub(crate) struct DnDGrab { impl + 'static> DnDGrab { pub(crate) fn new( + start_data: GrabStartData, source: Option, origin: wl_surface::WlSurface, seat: Seat, @@ -35,6 +37,7 @@ impl + 'static> DnDGrab { callback: Rc>, ) -> DnDGrab { DnDGrab { + start_data, data_source: source, current_focus: None, pending_offers: Vec::with_capacity(1), @@ -222,6 +225,10 @@ impl + 'static> PointerGrab for DnDGrab { // we just forward the axis events as is handle.axis(details); } + + fn start_data(&self) -> &GrabStartData { + &self.start_data + } } struct OfferData { diff --git a/src/wayland/data_device/mod.rs b/src/wayland/data_device/mod.rs index 74ae600..96996b3 100644 --- a/src/wayland/data_device/mod.rs +++ b/src/wayland/data_device/mod.rs @@ -69,7 +69,7 @@ use wayland_server::{ use crate::wayland::{ compositor::{roles::Role, CompositorToken}, - seat::Seat, + seat::{GrabStartData, Seat}, }; mod data_source; @@ -354,8 +354,13 @@ pub fn set_data_device_selection(seat: &Seat, mime_types: Vec) { /// You'll receive events generated by the interaction of clients with your /// drag'n'drop in the provided callback. See [`ServerDndEvent`] for details about /// which events can be generated and what response is expected from you to them. -pub fn start_dnd(seat: &Seat, serial: u32, metadata: SourceMetadata, callback: C) -where +pub fn start_dnd( + seat: &Seat, + serial: u32, + start_data: GrabStartData, + metadata: SourceMetadata, + callback: C, +) where C: FnMut(ServerDndEvent) + 'static, { // TODO: same question as in set_data_device_focus @@ -366,7 +371,12 @@ where }); if let Some(pointer) = seat.get_pointer() { pointer.set_grab( - server_dnd_grab::ServerDnDGrab::new(metadata, seat.clone(), Rc::new(RefCell::new(callback))), + server_dnd_grab::ServerDnDGrab::new( + start_data, + metadata, + seat.clone(), + Rc::new(RefCell::new(callback)), + ), serial, ); return; @@ -466,8 +476,10 @@ where source: source.clone(), icon: icon.clone(), }); + let start_data = pointer.grab_start_data().unwrap(); pointer.set_grab( dnd_grab::DnDGrab::new( + start_data, source, origin, seat.clone(), diff --git a/src/wayland/data_device/server_dnd_grab.rs b/src/wayland/data_device/server_dnd_grab.rs index ab79fe4..a2ce916 100644 --- a/src/wayland/data_device/server_dnd_grab.rs +++ b/src/wayland/data_device/server_dnd_grab.rs @@ -7,7 +7,7 @@ use wayland_server::{ NewResource, }; -use crate::wayland::seat::{AxisFrame, PointerGrab, PointerInnerHandle, Seat}; +use crate::wayland::seat::{AxisFrame, GrabStartData, PointerGrab, PointerInnerHandle, Seat}; use super::{DataDeviceData, SeatData}; @@ -37,6 +37,7 @@ pub enum ServerDndEvent { } pub(crate) struct ServerDnDGrab { + start_data: GrabStartData, metadata: super::SourceMetadata, current_focus: Option, pending_offers: Vec, @@ -47,11 +48,13 @@ pub(crate) struct ServerDnDGrab { impl ServerDnDGrab { pub(crate) fn new( + start_data: GrabStartData, metadata: super::SourceMetadata, seat: Seat, callback: Rc>, ) -> ServerDnDGrab { ServerDnDGrab { + start_data, metadata, current_focus: None, pending_offers: Vec::with_capacity(1), @@ -212,6 +215,10 @@ where // we just forward the axis events as is handle.axis(details); } + + fn start_data(&self) -> &GrabStartData { + &self.start_data + } } struct OfferData { diff --git a/src/wayland/seat/mod.rs b/src/wayland/seat/mod.rs index fe58900..11f4b49 100644 --- a/src/wayland/seat/mod.rs +++ b/src/wayland/seat/mod.rs @@ -49,7 +49,8 @@ mod pointer; pub use self::{ keyboard::{keysyms, Error as KeyboardError, KeyboardHandle, Keysym, ModifiersState, XkbConfig}, pointer::{ - AxisFrame, CursorImageRole, CursorImageStatus, PointerGrab, PointerHandle, PointerInnerHandle, + AxisFrame, CursorImageRole, CursorImageStatus, GrabStartData, PointerGrab, PointerHandle, + PointerInnerHandle, }, }; diff --git a/src/wayland/seat/pointer.rs b/src/wayland/seat/pointer.rs index e674b4a..5d6a2b4 100644 --- a/src/wayland/seat/pointer.rs +++ b/src/wayland/seat/pointer.rs @@ -166,6 +166,15 @@ impl PointerHandle { } } + /// Returns the start data for the grab, if any. + pub fn grab_start_data(&self) -> Option { + let guard = self.inner.borrow(); + match &guard.grab { + GrabStatus::Active(_, g) => Some(g.start_data().clone()), + _ => None, + } + } + /// Notify that the pointer moved /// /// You provide the new location of the pointer, in the form of: @@ -226,6 +235,19 @@ impl PointerHandle { } } +/// Data about the event that started the grab. +#[derive(Clone)] +pub struct GrabStartData { + /// The focused surface and its location, if any, at the start of the grab. + /// + /// The location coordinates are in the global compositor space. + pub focus: Option<(WlSurface, (f64, f64))>, + /// The button that initiated the grab. + pub button: u32, + /// The location of the click that initiated the grab, in the global compositor space. + pub location: (f64, f64), +} + /// A trait to implement a pointer grab /// /// In some context, it is necessary to temporarily change the behavior of the pointer. This is @@ -262,6 +284,8 @@ pub trait PointerGrab { ); /// An axis scroll was reported fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame); + /// The data about the event that started the grab. + fn start_data(&self) -> &GrabStartData; } /// This inner handle is accessed from inside a pointer grab logic, and directly @@ -631,11 +655,14 @@ impl PointerGrab for DefaultGrab { time: u32, ) { handle.button(button, state, serial, time); - let current_focus = handle.current_focus().cloned(); handle.set_grab( serial, ClickGrab { - current_focus, + start_data: GrabStartData { + focus: handle.current_focus().cloned(), + button, + location: handle.current_location(), + }, pending_focus: None, }, ); @@ -643,6 +670,9 @@ impl PointerGrab for DefaultGrab { fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) { handle.axis(details); } + fn start_data(&self) -> &GrabStartData { + unreachable!() + } } // A click grab, basic grab started when an user clicks a surface @@ -651,7 +681,7 @@ impl PointerGrab for DefaultGrab { // In case the user maintains several simultaneous clicks, release // the grab once all are released. struct ClickGrab { - current_focus: Option<(WlSurface, (f64, f64))>, + start_data: GrabStartData, pending_focus: Option<(WlSurface, (f64, f64))>, } @@ -666,7 +696,7 @@ impl PointerGrab for ClickGrab { ) { // buffer the future focus, but maintain the current one self.pending_focus = focus; - handle.motion(location, self.current_focus.clone(), serial, time); + handle.motion(location, self.start_data.focus.clone(), serial, time); } fn button( &mut self, @@ -685,4 +715,7 @@ impl PointerGrab for ClickGrab { fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame) { handle.axis(details); } + fn start_data(&self) -> &GrabStartData { + &self.start_data + } } From d8495d81f227c6f741697d7f1bb7eedf4f659e86 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 2 Feb 2020 18:07:43 +0300 Subject: [PATCH 7/9] anvil.shell: check that there's a grab before Move If there's no click grab then the request is invalid. --- anvil/src/shell.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index 81b85b5..e69b400 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -160,6 +160,11 @@ pub fn init_shell( // TODO: touch move. let pointer = seat.get_pointer().unwrap(); + // Check that this surface has a click grab. + if !pointer.has_grab(serial) { + return; + } + let start_data = pointer.grab_start_data().unwrap(); let toplevel = SurfaceKind::Xdg(surface); @@ -210,6 +215,11 @@ pub fn init_shell( // TODO: touch move. let pointer = seat.get_pointer().unwrap(); + // Check that this surface has a click grab. + if !pointer.has_grab(serial) { + return; + } + let start_data = pointer.grab_start_data().unwrap(); let toplevel = SurfaceKind::Wl(surface); From 32613f3cd6b3059bd78fe00264f8ee437f00ad8c Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 2 Feb 2020 18:09:21 +0300 Subject: [PATCH 8/9] anvil.shell: check that grab is correct in Move Check that the grab had a focus and it was the same client as this surface. --- anvil/src/shell.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index e69b400..b9fa6a3 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -167,6 +167,19 @@ pub fn init_shell( let start_data = pointer.grab_start_data().unwrap(); + // If the focus was for a different surface, ignore the request. + if start_data.focus.is_none() + || !start_data + .focus + .as_ref() + .unwrap() + .0 + .as_ref() + .same_client_as(surface.get_surface().unwrap().as_ref()) + { + return; + } + let toplevel = SurfaceKind::Xdg(surface); let initial_window_location = xdg_window_map.borrow().location(&toplevel).unwrap(); @@ -222,6 +235,19 @@ pub fn init_shell( let start_data = pointer.grab_start_data().unwrap(); + // If the focus was for a different surface, ignore the request. + if start_data.focus.is_none() + || !start_data + .focus + .as_ref() + .unwrap() + .0 + .as_ref() + .same_client_as(surface.get_surface().unwrap().as_ref()) + { + return; + } + let toplevel = SurfaceKind::Wl(surface); let initial_window_location = shell_window_map.borrow().location(&toplevel).unwrap(); From fab0b7a05fe33a5f7b307ecfb721d8111c813d64 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Mon, 3 Feb 2020 07:33:16 +0300 Subject: [PATCH 9/9] seat: remove ClickGrab.pending_focus It was unused. --- src/wayland/seat/pointer.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/wayland/seat/pointer.rs b/src/wayland/seat/pointer.rs index 5d6a2b4..f86dc3a 100644 --- a/src/wayland/seat/pointer.rs +++ b/src/wayland/seat/pointer.rs @@ -663,7 +663,6 @@ impl PointerGrab for DefaultGrab { button, location: handle.current_location(), }, - pending_focus: None, }, ); } @@ -682,7 +681,6 @@ impl PointerGrab for DefaultGrab { // the grab once all are released. struct ClickGrab { start_data: GrabStartData, - pending_focus: Option<(WlSurface, (f64, f64))>, } impl PointerGrab for ClickGrab { @@ -690,12 +688,10 @@ impl PointerGrab for ClickGrab { &mut self, handle: &mut PointerInnerHandle<'_>, location: (f64, f64), - focus: Option<(WlSurface, (f64, f64))>, + _focus: Option<(WlSurface, (f64, f64))>, serial: u32, time: u32, ) { - // buffer the future focus, but maintain the current one - self.pending_focus = focus; handle.motion(location, self.start_data.focus.clone(), serial, time); } fn button(