From 3e28358668d0db6dffad145bc3591416943f4787 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Tue, 20 Nov 2018 23:27:12 +0100 Subject: [PATCH] seat: track pressed buttons for the grab --- src/wayland/seat/pointer.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/wayland/seat/pointer.rs b/src/wayland/seat/pointer.rs index ff9f6dc..c8a6951 100644 --- a/src/wayland/seat/pointer.rs +++ b/src/wayland/seat/pointer.rs @@ -20,6 +20,7 @@ struct PointerInternal { focus: Option<(Resource, (f64, f64))>, location: (f64, f64), grab: GrabStatus, + pressed_buttons: Vec, } impl PointerInternal { @@ -29,6 +30,7 @@ impl PointerInternal { focus: None, location: (0.0, 0.0), grab: GrabStatus::None, + pressed_buttons: Vec::new(), } } @@ -146,7 +148,16 @@ impl PointerHandle { /// This will internally send the appropriate button event to the client /// objects matching with the currently focused surface. pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) { - self.inner.lock().unwrap().with_grab(|mut handle, grab| { + let mut inner = self.inner.lock().unwrap(); + match state { + ButtonState::Pressed => { + inner.pressed_buttons.push(button); + } + ButtonState::Released => { + inner.pressed_buttons.retain(|b| *b != button); + } + } + inner.with_grab(|mut handle, grab| { grab.button(&mut handle, button, state, serial, time); }); } @@ -229,6 +240,14 @@ impl<'a> PointerInnerHandle<'a> { self.inner.location } + /// A list of the currently physically pressed buttons + /// + /// This still includes buttons that your grab have intercepted and not sent + /// to the client. + pub fn current_pressed(&self) -> &[u32] { + &self.inner.pressed_buttons + } + /// Notify that the pointer moved /// /// You provide the new location of the pointer, in the form of: @@ -542,7 +561,6 @@ impl PointerGrab for DefaultGrab { handle.set_grab( serial, ClickGrab { - buttons: vec![button], current_focus, pending_focus: None, }, @@ -559,7 +577,6 @@ impl PointerGrab for DefaultGrab { // In case the user maintains several simultaneous clicks, release // the grab once all are released. struct ClickGrab { - buttons: Vec, current_focus: Option<(Resource, (f64, f64))>, pending_focus: Option<(Resource, (f64, f64))>, } @@ -585,12 +602,8 @@ impl PointerGrab for ClickGrab { serial: u32, time: u32, ) { - match state { - ButtonState::Pressed => self.buttons.push(button), - ButtonState::Released => self.buttons.retain(|b| *b != button), - } handle.button(button, state, serial, time); - if self.buttons.is_empty() { + if handle.current_pressed().len() == 0 { // no more buttons are pressed, release the grab handle.unset_grab(); // restore the focus