seat: track pressed buttons for the grab

This commit is contained in:
Victor Berger 2018-11-20 23:27:12 +01:00
parent 0434cbb90d
commit 3e28358668
1 changed files with 21 additions and 8 deletions

View File

@ -20,6 +20,7 @@ struct PointerInternal {
focus: Option<(Resource<WlSurface>, (f64, f64))>,
location: (f64, f64),
grab: GrabStatus,
pressed_buttons: Vec<u32>,
}
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<u32>,
current_focus: Option<(Resource<WlSurface>, (f64, f64))>,
pending_focus: Option<(Resource<WlSurface>, (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