Added modifier support to mouse events (#328)
This commit is contained in:
parent
d92666c188
commit
011720848a
7 changed files with 116 additions and 33 deletions
|
|
@ -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
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue