Added modifier support to mouse events (#328)

This commit is contained in:
Bryan Gilbert 2017-12-26 16:46:28 -05:00 committed by Pierre Krieger
parent d92666c188
commit 011720848a
7 changed files with 116 additions and 33 deletions

View file

@ -1,6 +1,7 @@
use std::sync::{Arc, Mutex};
use {WindowEvent as Event, ElementState, MouseButton, MouseScrollDelta, TouchPhase};
use events::ModifiersState;
use super::{WindowId, DeviceId};
use super::event_loop::EventsLoopSink;
@ -50,6 +51,8 @@ pub fn pointer_implementation() -> wl_pointer::Implementation<PointerIData> {
Event::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
position: (x, y),
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
);
@ -73,7 +76,9 @@ pub fn pointer_implementation() -> wl_pointer::Implementation<PointerIData> {
idata.sink.lock().unwrap().send_event(
Event::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
position: (x, y)
position: (x, y),
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid
);
@ -97,6 +102,8 @@ pub fn pointer_implementation() -> wl_pointer::Implementation<PointerIData> {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
state: state,
button: button,
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid
);
@ -117,6 +124,8 @@ pub fn pointer_implementation() -> wl_pointer::Implementation<PointerIData> {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
delta: MouseScrollDelta::PixelDelta(x as f32, y as f32),
phase: TouchPhase::Moved,
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid
);
@ -145,6 +154,8 @@ pub fn pointer_implementation() -> wl_pointer::Implementation<PointerIData> {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
delta: MouseScrollDelta::LineDelta(x as f32, y as f32),
phase: idata.axis_state,
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid
);
@ -154,6 +165,8 @@ pub fn pointer_implementation() -> wl_pointer::Implementation<PointerIData> {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
delta: MouseScrollDelta::PixelDelta(x as f32, y as f32),
phase: idata.axis_state,
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid
);

View file

@ -471,6 +471,8 @@ impl EventsLoop {
match xev.evtype {
ffi::XI_ButtonPress | ffi::XI_ButtonRelease => {
use events::ModifiersState;
let xev: &ffi::XIDeviceEvent = unsafe { &*(xev.data as *const _) };
let wid = mkwid(xev.event);
let did = mkdid(xev.deviceid);
@ -478,6 +480,18 @@ impl EventsLoop {
// Deliver multi-touch events instead of emulated mouse events.
return;
}
let ev_mods = {
// Translate x mod state to mods
let state = xev.mods.effective as u32;
ModifiersState {
alt: state & ffi::Mod1Mask != 0,
shift: state & ffi::ShiftMask != 0,
ctrl: state & ffi::ControlMask != 0,
logo: state & ffi::Mod4Mask != 0,
}
};
let state = if xev.evtype == ffi::XI_ButtonPress {
Pressed
} else {
@ -485,11 +499,11 @@ impl EventsLoop {
};
match xev.detail as u32 {
ffi::Button1 => callback(Event::WindowEvent { window_id: wid, event:
MouseInput { device_id: did, state: state, button: Left } }),
MouseInput { device_id: did, state: state, button: Left, modifiers: ev_mods } }),
ffi::Button2 => callback(Event::WindowEvent { window_id: wid, event:
MouseInput { device_id: did, state: state, button: Middle } }),
MouseInput { device_id: did, state: state, button: Middle, modifiers: ev_mods} }),
ffi::Button3 => callback(Event::WindowEvent { window_id: wid, event:
MouseInput { device_id: did, state: state, button: Right } }),
MouseInput { device_id: did, state: state, button: Right, modifiers: ev_mods } }),
// Suppress emulated scroll wheel clicks, since we handle the real motion events for those.
// In practice, even clicky scroll wheels appear to be reported by evdev (and XInput2 in
@ -505,18 +519,33 @@ impl EventsLoop {
_ => unreachable!()
},
phase: TouchPhase::Moved,
modifiers: ev_mods,
}});
},
x => callback(Event::WindowEvent { window_id: wid, event: MouseInput { device_id: did, state: state, button: Other(x as u8) } })
x => callback(Event::WindowEvent { window_id: wid,
event: MouseInput { device_id: did, state: state, button: Other(x as u8), modifiers: ev_mods } })
}
}
ffi::XI_Motion => {
use events::ModifiersState;
let xev: &ffi::XIDeviceEvent = unsafe { &*(xev.data as *const _) };
let did = mkdid(xev.deviceid);
let wid = mkwid(xev.event);
let new_cursor_pos = (xev.event_x, xev.event_y);
let ev_mods = {
// Translate x event state to mods
let state = xev.mods.effective as u32;
ModifiersState {
alt: state & ffi::Mod1Mask != 0,
shift: state & ffi::ShiftMask != 0,
ctrl: state & ffi::ControlMask != 0,
logo: state & ffi::Mod4Mask != 0,
}
};
// Gymnastics to ensure self.windows isn't locked when we invoke callback
if {
let mut windows = self.windows.lock().unwrap();
@ -528,7 +557,8 @@ impl EventsLoop {
} {
callback(Event::WindowEvent { window_id: wid, event: CursorMoved {
device_id: did,
position: new_cursor_pos
position: new_cursor_pos,
modifiers: ev_mods,
}});
}
@ -554,6 +584,7 @@ impl EventsLoop {
ScrollOrientation::Vertical => LineDelta(0.0, -delta as f32),
},
phase: TouchPhase::Moved,
modifiers: ev_mods,
}});
} else {
events.push(Event::WindowEvent { window_id: wid, event: AxisMotion {
@ -572,8 +603,20 @@ impl EventsLoop {
}
ffi::XI_Enter => {
use events::ModifiersState;
let xev: &ffi::XIEnterEvent = unsafe { &*(xev.data as *const _) };
let ev_mods = {
// Translate x event state to mods
let state = xev.mods.effective as u32;
ModifiersState {
alt: state & ffi::Mod1Mask != 0,
shift: state & ffi::ShiftMask != 0,
ctrl: state & ffi::ControlMask != 0,
logo: state & ffi::Mod4Mask != 0,
}
};
let mut devices = self.devices.lock().unwrap();
let physical_device = devices.get_mut(&DeviceId(xev.sourceid)).unwrap();
for info in DeviceInfo::get(&self.display, ffi::XIAllDevices).iter() {
@ -586,7 +629,8 @@ impl EventsLoop {
let new_cursor_pos = (xev.event_x, xev.event_y);
callback(Event::WindowEvent { window_id: wid, event: CursorMoved {
device_id: mkdid(xev.deviceid),
position: new_cursor_pos
position: new_cursor_pos,
modifiers: ev_mods,
}})
}
ffi::XI_Leave => {
@ -594,7 +638,20 @@ impl EventsLoop {
callback(Event::WindowEvent { window_id: mkwid(xev.event), event: CursorLeft { device_id: mkdid(xev.deviceid) } })
}
ffi::XI_FocusIn => {
use events::ModifiersState;
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
let ev_mods = {
// Translate x event state to mods
let state = xev.mods.effective as u32;
ModifiersState {
alt: state & ffi::Mod1Mask != 0,
shift: state & ffi::ShiftMask != 0,
ctrl: state & ffi::ControlMask != 0,
logo: state & ffi::Mod4Mask != 0,
}
};
unsafe {
let mut windows = self.windows.lock().unwrap();
let window_data = windows.get_mut(&WindowId(xev.event)).unwrap();
@ -605,7 +662,8 @@ impl EventsLoop {
let new_cursor_pos = (xev.event_x, xev.event_y);
callback(Event::WindowEvent { window_id: wid, event: CursorMoved {
device_id: mkdid(xev.deviceid),
position: new_cursor_pos
position: new_cursor_pos,
modifiers: ev_mods,
}})
}
ffi::XI_FocusOut => {