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))>, focus: Option<(Resource<WlSurface>, (f64, f64))>,
location: (f64, f64), location: (f64, f64),
grab: GrabStatus, grab: GrabStatus,
pressed_buttons: Vec<u32>,
} }
impl PointerInternal { impl PointerInternal {
@ -29,6 +30,7 @@ impl PointerInternal {
focus: None, focus: None,
location: (0.0, 0.0), location: (0.0, 0.0),
grab: GrabStatus::None, grab: GrabStatus::None,
pressed_buttons: Vec::new(),
} }
} }
@ -146,7 +148,16 @@ impl PointerHandle {
/// This will internally send the appropriate button event to the client /// This will internally send the appropriate button event to the client
/// objects matching with the currently focused surface. /// objects matching with the currently focused surface.
pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) { 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); grab.button(&mut handle, button, state, serial, time);
}); });
} }
@ -229,6 +240,14 @@ impl<'a> PointerInnerHandle<'a> {
self.inner.location 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 /// Notify that the pointer moved
/// ///
/// You provide the new location of the pointer, in the form of: /// You provide the new location of the pointer, in the form of:
@ -542,7 +561,6 @@ impl PointerGrab for DefaultGrab {
handle.set_grab( handle.set_grab(
serial, serial,
ClickGrab { ClickGrab {
buttons: vec![button],
current_focus, current_focus,
pending_focus: None, pending_focus: None,
}, },
@ -559,7 +577,6 @@ impl PointerGrab for DefaultGrab {
// In case the user maintains several simultaneous clicks, release // In case the user maintains several simultaneous clicks, release
// the grab once all are released. // the grab once all are released.
struct ClickGrab { struct ClickGrab {
buttons: Vec<u32>,
current_focus: Option<(Resource<WlSurface>, (f64, f64))>, current_focus: Option<(Resource<WlSurface>, (f64, f64))>,
pending_focus: Option<(Resource<WlSurface>, (f64, f64))>, pending_focus: Option<(Resource<WlSurface>, (f64, f64))>,
} }
@ -585,12 +602,8 @@ impl PointerGrab for ClickGrab {
serial: u32, serial: u32,
time: 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); 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 // no more buttons are pressed, release the grab
handle.unset_grab(); handle.unset_grab();
// restore the focus // restore the focus