Format everything and add rustfmt to travis (#951)
* Format everything and add rustfmt to travis * Remove extern crate winit from examples and add force_multiline_blocks * Format the code properly * Fix inconsistent period in PULL_REQUEST_TEMPLATE.md * Only run rustfmt on nightly * Travis fixings
This commit is contained in:
parent
b1b5aefc4b
commit
e2c84725de
109 changed files with 4787 additions and 3679 deletions
|
|
@ -1,20 +1,18 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
use std::{cell::RefCell, collections::HashMap, ptr, rc::Rc, slice};
|
||||
|
||||
use libc::{c_int, c_uint, c_ulong, c_char, c_long};
|
||||
use libc::{c_char, c_int, c_long, c_uint, c_ulong};
|
||||
|
||||
use super::{
|
||||
mkdid, mkwid, get_xtarget, DeviceId, WindowId, Device, ImeReceiver, XExtension,
|
||||
monitor, ffi, UnownedWindow, ScrollOrientation, GenericEventCookie,
|
||||
events, util, DndState, Dnd, DeviceInfo
|
||||
events, ffi, get_xtarget, mkdid, mkwid, monitor, util, Device, DeviceId, DeviceInfo, Dnd,
|
||||
DndState, GenericEventCookie, ImeReceiver, ScrollOrientation, UnownedWindow, WindowId,
|
||||
XExtension,
|
||||
};
|
||||
|
||||
use crate::event_loop::EventLoopWindowTarget as RootELW;
|
||||
use crate::event::{DeviceEvent, Event, KeyboardInput, ModifiersState, WindowEvent};
|
||||
use crate::dpi::{LogicalPosition,LogicalSize};
|
||||
use crate::{
|
||||
dpi::{LogicalPosition, LogicalSize},
|
||||
event::{DeviceEvent, Event, KeyboardInput, ModifiersState, WindowEvent},
|
||||
event_loop::EventLoopWindowTarget as RootELW,
|
||||
};
|
||||
|
||||
pub(super) struct EventProcessor<T: 'static> {
|
||||
pub(super) dnd: Dnd,
|
||||
|
|
@ -22,7 +20,7 @@ pub(super) struct EventProcessor<T: 'static> {
|
|||
pub(super) randr_event_offset: c_int,
|
||||
pub(super) devices: RefCell<HashMap<DeviceId, Device>>,
|
||||
pub(super) xi2ext: XExtension,
|
||||
pub(super) target: Rc<RootELW<T>>
|
||||
pub(super) target: Rc<RootELW<T>>,
|
||||
}
|
||||
|
||||
impl<T: 'static> EventProcessor<T> {
|
||||
|
|
@ -37,12 +35,14 @@ impl<T: 'static> EventProcessor<T> {
|
|||
}
|
||||
|
||||
fn with_window<F, Ret>(&self, window_id: ffi::Window, callback: F) -> Option<Ret>
|
||||
where F: Fn(&UnownedWindow) -> Ret
|
||||
where
|
||||
F: Fn(&UnownedWindow) -> Ret,
|
||||
{
|
||||
let mut deleted = false;
|
||||
let window_id = WindowId(window_id);
|
||||
let wt = get_xtarget(&self.target);
|
||||
let result = wt.windows
|
||||
let result = wt
|
||||
.windows
|
||||
.borrow()
|
||||
.get(&window_id)
|
||||
.and_then(|window| {
|
||||
|
|
@ -62,7 +62,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
self.with_window(window_id, |_| ()).is_some()
|
||||
}
|
||||
|
||||
pub(super) unsafe fn poll_one_event(&mut self, event_ptr : *mut ffi::XEvent) -> bool {
|
||||
pub(super) unsafe fn poll_one_event(&mut self, event_ptr: *mut ffi::XEvent) -> bool {
|
||||
let wt = get_xtarget(&self.target);
|
||||
// This function is used to poll and remove a single event
|
||||
// from the Xlib event queue in a non-blocking, atomic way.
|
||||
|
|
@ -73,7 +73,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
unsafe extern "C" fn predicate(
|
||||
_display: *mut ffi::Display,
|
||||
_event: *mut ffi::XEvent,
|
||||
_arg : *mut c_char) -> c_int {
|
||||
_arg: *mut c_char,
|
||||
) -> c_int {
|
||||
// This predicate always returns "true" (1) to accept all events
|
||||
1
|
||||
}
|
||||
|
|
@ -82,32 +83,42 @@ impl<T: 'static> EventProcessor<T> {
|
|||
wt.xconn.display,
|
||||
event_ptr,
|
||||
Some(predicate),
|
||||
std::ptr::null_mut());
|
||||
std::ptr::null_mut(),
|
||||
);
|
||||
|
||||
result != 0
|
||||
}
|
||||
|
||||
pub(super) fn process_event<F>(&mut self, xev: &mut ffi::XEvent, mut callback: F)
|
||||
where F: FnMut(Event<T>)
|
||||
where
|
||||
F: FnMut(Event<T>),
|
||||
{
|
||||
let wt = get_xtarget(&self.target);
|
||||
// XFilterEvent tells us when an event has been discarded by the input method.
|
||||
// Specifically, this involves all of the KeyPress events in compose/pre-edit sequences,
|
||||
// along with an extra copy of the KeyRelease events. This also prevents backspace and
|
||||
// arrow keys from being detected twice.
|
||||
if ffi::True == unsafe { (wt.xconn.xlib.XFilterEvent)(
|
||||
xev,
|
||||
{ let xev: &ffi::XAnyEvent = xev.as_ref(); xev.window }
|
||||
) } {
|
||||
if ffi::True
|
||||
== unsafe {
|
||||
(wt.xconn.xlib.XFilterEvent)(xev, {
|
||||
let xev: &ffi::XAnyEvent = xev.as_ref();
|
||||
xev.window
|
||||
})
|
||||
}
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let event_type = xev.get_type();
|
||||
match event_type {
|
||||
ffi::MappingNotify => {
|
||||
unsafe { (wt.xconn.xlib.XRefreshKeyboardMapping)(xev.as_mut()); }
|
||||
wt.xconn.check_errors().expect("Failed to call XRefreshKeyboardMapping");
|
||||
}
|
||||
unsafe {
|
||||
(wt.xconn.xlib.XRefreshKeyboardMapping)(xev.as_mut());
|
||||
}
|
||||
wt.xconn
|
||||
.check_errors()
|
||||
.expect("Failed to call XRefreshKeyboardMapping");
|
||||
},
|
||||
|
||||
ffi::ClientMessage => {
|
||||
let client_msg: &ffi::XClientMessageEvent = xev.as_ref();
|
||||
|
|
@ -116,7 +127,10 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let window_id = mkwid(window);
|
||||
|
||||
if client_msg.data.get_long(0) as ffi::Atom == wt.wm_delete_window {
|
||||
callback(Event::WindowEvent { window_id, event: WindowEvent::CloseRequested });
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::CloseRequested,
|
||||
});
|
||||
} else if client_msg.message_type == self.dnd.atoms.enter {
|
||||
let source_window = client_msg.data.get_long(0) as c_ulong;
|
||||
let flags = client_msg.data.get_long(1);
|
||||
|
|
@ -127,10 +141,11 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let type_list = vec![
|
||||
client_msg.data.get_long(2) as c_ulong,
|
||||
client_msg.data.get_long(3) as c_ulong,
|
||||
client_msg.data.get_long(4) as c_ulong
|
||||
client_msg.data.get_long(4) as c_ulong,
|
||||
];
|
||||
self.dnd.type_list = Some(type_list);
|
||||
} else if let Ok(more_types) = unsafe { self.dnd.get_type_list(source_window) } {
|
||||
} else if let Ok(more_types) = unsafe { self.dnd.get_type_list(source_window) }
|
||||
{
|
||||
self.dnd.type_list = Some(more_types);
|
||||
}
|
||||
} else if client_msg.message_type == self.dnd.atoms.position {
|
||||
|
|
@ -178,18 +193,21 @@ impl<T: 'static> EventProcessor<T> {
|
|||
// This results in the `SelectionNotify` event below
|
||||
self.dnd.convert_selection(window, time);
|
||||
}
|
||||
self.dnd.send_status(window, source_window, DndState::Accepted)
|
||||
self.dnd
|
||||
.send_status(window, source_window, DndState::Accepted)
|
||||
.expect("Failed to send `XdndStatus` message.");
|
||||
}
|
||||
} else {
|
||||
unsafe {
|
||||
self.dnd.send_status(window, source_window, DndState::Rejected)
|
||||
self.dnd
|
||||
.send_status(window, source_window, DndState::Rejected)
|
||||
.expect("Failed to send `XdndStatus` message.");
|
||||
}
|
||||
self.dnd.reset();
|
||||
}
|
||||
} else if client_msg.message_type == self.dnd.atoms.drop {
|
||||
let (source_window, state) = if let Some(source_window) = self.dnd.source_window {
|
||||
let (source_window, state) = if let Some(source_window) = self.dnd.source_window
|
||||
{
|
||||
if let Some(Ok(ref path_list)) = self.dnd.result {
|
||||
for path in path_list {
|
||||
callback(Event::WindowEvent {
|
||||
|
|
@ -206,7 +224,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
(source_window, DndState::Rejected)
|
||||
};
|
||||
unsafe {
|
||||
self.dnd.send_finished(window, source_window, state)
|
||||
self.dnd
|
||||
.send_finished(window, source_window, state)
|
||||
.expect("Failed to send `XdndFinished` message.");
|
||||
}
|
||||
self.dnd.reset();
|
||||
|
|
@ -217,7 +236,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
event: WindowEvent::HoveredFileCancelled,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::SelectionNotify => {
|
||||
let xsel: &ffi::XSelectionEvent = xev.as_ref();
|
||||
|
|
@ -244,7 +263,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
|
||||
self.dnd.result = result;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::ConfigureNotify => {
|
||||
#[derive(Debug, Default)]
|
||||
|
|
@ -274,15 +293,22 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let mut shared_state_lock = window.shared_state.lock();
|
||||
|
||||
let (mut resized, moved) = {
|
||||
let resized = util::maybe_change(&mut shared_state_lock.size, new_inner_size);
|
||||
let resized =
|
||||
util::maybe_change(&mut shared_state_lock.size, new_inner_size);
|
||||
let moved = if is_synthetic {
|
||||
util::maybe_change(&mut shared_state_lock.inner_position, new_inner_position)
|
||||
util::maybe_change(
|
||||
&mut shared_state_lock.inner_position,
|
||||
new_inner_position,
|
||||
)
|
||||
} else {
|
||||
// Detect when frame extents change.
|
||||
// Since this isn't synthetic, as per the notes above, this position is relative to the
|
||||
// parent window.
|
||||
let rel_parent = new_inner_position;
|
||||
if util::maybe_change(&mut shared_state_lock.inner_position_rel_parent, rel_parent) {
|
||||
if util::maybe_change(
|
||||
&mut shared_state_lock.inner_position_rel_parent,
|
||||
rel_parent,
|
||||
) {
|
||||
// This ensures we process the next `Moved`.
|
||||
shared_state_lock.inner_position = None;
|
||||
// Extra insurance against stale frame extents.
|
||||
|
|
@ -297,18 +323,22 @@ impl<T: 'static> EventProcessor<T> {
|
|||
|
||||
let new_outer_position = if moved || shared_state_lock.position.is_none() {
|
||||
// We need to convert client area position to window position.
|
||||
let frame_extents = shared_state_lock.frame_extents
|
||||
let frame_extents = shared_state_lock
|
||||
.frame_extents
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| {
|
||||
let frame_extents = wt.xconn.get_frame_extents_heuristic(xwindow, wt.root);
|
||||
let frame_extents =
|
||||
wt.xconn.get_frame_extents_heuristic(xwindow, wt.root);
|
||||
shared_state_lock.frame_extents = Some(frame_extents.clone());
|
||||
frame_extents
|
||||
});
|
||||
let outer = frame_extents.inner_pos_to_outer(new_inner_position.0, new_inner_position.1);
|
||||
let outer = frame_extents
|
||||
.inner_pos_to_outer(new_inner_position.0, new_inner_position.1);
|
||||
shared_state_lock.position = Some(outer);
|
||||
if moved {
|
||||
let logical_position = LogicalPosition::from_physical(outer, monitor.hidpi_factor);
|
||||
let logical_position =
|
||||
LogicalPosition::from_physical(outer, monitor.hidpi_factor);
|
||||
events.moved = Some(WindowEvent::Moved(logical_position));
|
||||
}
|
||||
outer
|
||||
|
|
@ -319,12 +349,13 @@ impl<T: 'static> EventProcessor<T> {
|
|||
if is_synthetic {
|
||||
// If we don't use the existing adjusted value when available, then the user can screw up the
|
||||
// resizing by dragging across monitors *without* dropping the window.
|
||||
let (width, height) = shared_state_lock.dpi_adjusted
|
||||
let (width, height) = shared_state_lock
|
||||
.dpi_adjusted
|
||||
.unwrap_or_else(|| (xev.width as f64, xev.height as f64));
|
||||
let last_hidpi_factor = shared_state_lock.guessed_dpi
|
||||
.take()
|
||||
.unwrap_or_else(|| {
|
||||
shared_state_lock.last_monitor
|
||||
let last_hidpi_factor =
|
||||
shared_state_lock.guessed_dpi.take().unwrap_or_else(|| {
|
||||
shared_state_lock
|
||||
.last_monitor
|
||||
.as_ref()
|
||||
.map(|last_monitor| last_monitor.hidpi_factor)
|
||||
.unwrap_or(1.0)
|
||||
|
|
@ -337,7 +368,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
new_hidpi_factor
|
||||
};
|
||||
if last_hidpi_factor != new_hidpi_factor {
|
||||
events.dpi_changed = Some(WindowEvent::HiDpiFactorChanged(new_hidpi_factor));
|
||||
events.dpi_changed =
|
||||
Some(WindowEvent::HiDpiFactorChanged(new_hidpi_factor));
|
||||
let (new_width, new_height, flusher) = window.adjust_for_dpi(
|
||||
last_hidpi_factor,
|
||||
new_hidpi_factor,
|
||||
|
|
@ -357,7 +389,10 @@ impl<T: 'static> EventProcessor<T> {
|
|||
// WMs constrain the window size, making the resize fail. This would cause an endless stream of
|
||||
// XResizeWindow requests, making Xorg, the winit client, and the WM consume 100% of CPU.
|
||||
if let Some(adjusted_size) = shared_state_lock.dpi_adjusted {
|
||||
let rounded_size = (adjusted_size.0.round() as u32, adjusted_size.1.round() as u32);
|
||||
let rounded_size = (
|
||||
adjusted_size.0.round() as u32,
|
||||
adjusted_size.1.round() as u32,
|
||||
);
|
||||
if new_inner_size == rounded_size || !util::wm_name_is_one_of(&["Xfwm4"]) {
|
||||
// When this finally happens, the event will not be synthetic.
|
||||
shared_state_lock.dpi_adjusted = None;
|
||||
|
|
@ -374,7 +409,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
}
|
||||
|
||||
if resized {
|
||||
let logical_size = LogicalSize::from_physical(new_inner_size, monitor.hidpi_factor);
|
||||
let logical_size =
|
||||
LogicalSize::from_physical(new_inner_size, monitor.hidpi_factor);
|
||||
events.resized = Some(WindowEvent::Resized(logical_size));
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +429,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
callback(Event::WindowEvent { window_id, event });
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::ReparentNotify => {
|
||||
let xev: &ffi::XReparentEvent = xev.as_ref();
|
||||
|
|
@ -408,7 +444,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
self.with_window(xev.window, |window| {
|
||||
window.invalidate_cached_frame_extents();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
ffi::DestroyNotify => {
|
||||
let xev: &ffi::XDestroyWindowEvent = xev.as_ref();
|
||||
|
|
@ -427,8 +463,11 @@ impl<T: 'static> EventProcessor<T> {
|
|||
.remove_context(window)
|
||||
.expect("Failed to destroy input context");
|
||||
|
||||
callback(Event::WindowEvent { window_id, event: WindowEvent::Destroyed });
|
||||
}
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::Destroyed,
|
||||
});
|
||||
},
|
||||
|
||||
ffi::Expose => {
|
||||
let xev: &ffi::XExposeEvent = xev.as_ref();
|
||||
|
|
@ -436,8 +475,11 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let window = xev.window;
|
||||
let window_id = mkwid(window);
|
||||
|
||||
callback(Event::WindowEvent { window_id, event: WindowEvent::RedrawRequested });
|
||||
}
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::RedrawRequested,
|
||||
});
|
||||
},
|
||||
|
||||
ffi::KeyPress | ffi::KeyRelease => {
|
||||
use crate::event::ElementState::{Pressed, Released};
|
||||
|
|
@ -493,7 +535,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
virtual_keycode,
|
||||
modifiers,
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -512,20 +554,29 @@ impl<T: 'static> EventProcessor<T> {
|
|||
callback(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::GenericEvent => {
|
||||
let guard = if let Some(e) = GenericEventCookie::from_event(&wt.xconn, *xev) { e } else { return };
|
||||
let guard = if let Some(e) = GenericEventCookie::from_event(&wt.xconn, *xev) {
|
||||
e
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let xev = &guard.cookie;
|
||||
if self.xi2ext.opcode != xev.extension {
|
||||
return;
|
||||
}
|
||||
|
||||
use crate::event::WindowEvent::{Focused, CursorEntered, MouseInput, CursorLeft, CursorMoved, MouseWheel, AxisMotion};
|
||||
use crate::event::ElementState::{Pressed, Released};
|
||||
use crate::event::MouseButton::{Left, Right, Middle, Other};
|
||||
use crate::event::MouseScrollDelta::LineDelta;
|
||||
use crate::event::{Touch, TouchPhase};
|
||||
use crate::event::{
|
||||
ElementState::{Pressed, Released},
|
||||
MouseButton::{Left, Middle, Other, Right},
|
||||
MouseScrollDelta::LineDelta,
|
||||
Touch, TouchPhase,
|
||||
WindowEvent::{
|
||||
AxisMotion, CursorEntered, CursorLeft, CursorMoved, Focused, MouseInput,
|
||||
MouseWheel,
|
||||
},
|
||||
};
|
||||
|
||||
match xev.evtype {
|
||||
ffi::XI_ButtonPress | ffi::XI_ButtonRelease => {
|
||||
|
|
@ -545,66 +596,76 @@ impl<T: 'static> EventProcessor<T> {
|
|||
Released
|
||||
};
|
||||
match xev.detail as u32 {
|
||||
ffi::Button1 => callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Left,
|
||||
modifiers,
|
||||
},
|
||||
}),
|
||||
ffi::Button2 => callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Middle,
|
||||
modifiers,
|
||||
},
|
||||
}),
|
||||
ffi::Button3 => callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Right,
|
||||
modifiers,
|
||||
},
|
||||
}),
|
||||
ffi::Button1 => {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Left,
|
||||
modifiers,
|
||||
},
|
||||
})
|
||||
},
|
||||
ffi::Button2 => {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Middle,
|
||||
modifiers,
|
||||
},
|
||||
})
|
||||
},
|
||||
ffi::Button3 => {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Right,
|
||||
modifiers,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
// 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
|
||||
// turn) as axis motion, so we don't otherwise special-case these button presses.
|
||||
4 | 5 | 6 | 7 => if xev.flags & ffi::XIPointerEmulated == 0 {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseWheel {
|
||||
device_id,
|
||||
delta: match xev.detail {
|
||||
4 => LineDelta(0.0, 1.0),
|
||||
5 => LineDelta(0.0, -1.0),
|
||||
6 => LineDelta(-1.0, 0.0),
|
||||
7 => LineDelta(1.0, 0.0),
|
||||
_ => unreachable!(),
|
||||
4 | 5 | 6 | 7 => {
|
||||
if xev.flags & ffi::XIPointerEmulated == 0 {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseWheel {
|
||||
device_id,
|
||||
delta: match xev.detail {
|
||||
4 => LineDelta(0.0, 1.0),
|
||||
5 => LineDelta(0.0, -1.0),
|
||||
6 => LineDelta(-1.0, 0.0),
|
||||
7 => LineDelta(1.0, 0.0),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
phase: TouchPhase::Moved,
|
||||
modifiers,
|
||||
},
|
||||
phase: TouchPhase::Moved,
|
||||
modifiers,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
x => callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Other(x as u8),
|
||||
modifiers,
|
||||
},
|
||||
}),
|
||||
x => {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button: Other(x as u8),
|
||||
modifiers,
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
ffi::XI_Motion => {
|
||||
let xev: &ffi::XIDeviceEvent = unsafe { &*(xev.data as *const _) };
|
||||
let device_id = mkdid(xev.deviceid);
|
||||
|
|
@ -618,9 +679,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
util::maybe_change(&mut shared_state_lock.cursor_pos, new_cursor_pos)
|
||||
});
|
||||
if cursor_moved == Some(true) {
|
||||
let dpi_factor = self.with_window(xev.event, |window| {
|
||||
window.hidpi_factor()
|
||||
});
|
||||
let dpi_factor =
|
||||
self.with_window(xev.event, |window| window.hidpi_factor());
|
||||
if let Some(dpi_factor) = dpi_factor {
|
||||
let position = LogicalPosition::from_physical(
|
||||
(xev.event_x as f64, xev.event_y as f64),
|
||||
|
|
@ -644,7 +704,12 @@ impl<T: 'static> EventProcessor<T> {
|
|||
// More gymnastics, for self.devices
|
||||
let mut events = Vec::new();
|
||||
{
|
||||
let mask = unsafe { slice::from_raw_parts(xev.valuators.mask, xev.valuators.mask_len as usize) };
|
||||
let mask = unsafe {
|
||||
slice::from_raw_parts(
|
||||
xev.valuators.mask,
|
||||
xev.valuators.mask_len as usize,
|
||||
)
|
||||
};
|
||||
let mut devices = self.devices.borrow_mut();
|
||||
let physical_device = match devices.get_mut(&DeviceId(xev.sourceid)) {
|
||||
Some(device) => device,
|
||||
|
|
@ -652,10 +717,14 @@ impl<T: 'static> EventProcessor<T> {
|
|||
};
|
||||
|
||||
let mut value = xev.valuators.values;
|
||||
for i in 0..xev.valuators.mask_len*8 {
|
||||
for i in 0..xev.valuators.mask_len * 8 {
|
||||
if ffi::XIMaskIsSet(mask, i) {
|
||||
let x = unsafe { *value };
|
||||
if let Some(&mut (_, ref mut info)) = physical_device.scroll_axes.iter_mut().find(|&&mut (axis, _)| axis == i) {
|
||||
if let Some(&mut (_, ref mut info)) = physical_device
|
||||
.scroll_axes
|
||||
.iter_mut()
|
||||
.find(|&&mut (axis, _)| axis == i)
|
||||
{
|
||||
let delta = (x - info.position) / info.increment;
|
||||
info.position = x;
|
||||
events.push(Event::WindowEvent {
|
||||
|
|
@ -663,9 +732,13 @@ impl<T: 'static> EventProcessor<T> {
|
|||
event: MouseWheel {
|
||||
device_id,
|
||||
delta: match info.orientation {
|
||||
ScrollOrientation::Horizontal => LineDelta(delta as f32, 0.0),
|
||||
ScrollOrientation::Horizontal => {
|
||||
LineDelta(delta as f32, 0.0)
|
||||
},
|
||||
// X11 vertical scroll coordinates are opposite to winit's
|
||||
ScrollOrientation::Vertical => LineDelta(0.0, -delta as f32),
|
||||
ScrollOrientation::Vertical => {
|
||||
LineDelta(0.0, -delta as f32)
|
||||
},
|
||||
},
|
||||
phase: TouchPhase::Moved,
|
||||
modifiers,
|
||||
|
|
@ -688,7 +761,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
for event in events {
|
||||
callback(event);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::XI_Enter => {
|
||||
let xev: &ffi::XIEnterEvent = unsafe { &*(xev.data as *const _) };
|
||||
|
|
@ -704,7 +777,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
// presumably some other WMs. On those, `XI_Enter` doesn't include
|
||||
// the physical device ID, so both `sourceid` and `deviceid` are
|
||||
// the virtual device.
|
||||
|| device_info.attachment == xev.sourceid {
|
||||
|| device_info.attachment == xev.sourceid
|
||||
{
|
||||
let device_id = DeviceId(device_info.deviceid);
|
||||
if let Some(device) = devices.get_mut(&device_id) {
|
||||
device.reset_scroll_position(device_info);
|
||||
|
|
@ -717,9 +791,9 @@ impl<T: 'static> EventProcessor<T> {
|
|||
event: CursorEntered { device_id },
|
||||
});
|
||||
|
||||
if let Some(dpi_factor) = self.with_window(xev.event, |window| {
|
||||
window.hidpi_factor()
|
||||
}) {
|
||||
if let Some(dpi_factor) =
|
||||
self.with_window(xev.event, |window| window.hidpi_factor())
|
||||
{
|
||||
let position = LogicalPosition::from_physical(
|
||||
(xev.event_x as f64, xev.event_y as f64),
|
||||
dpi_factor,
|
||||
|
|
@ -732,7 +806,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
// This needs to only be done after confirming the window still exists,
|
||||
// since otherwise we risk getting a `BadWindow` error if the window was
|
||||
// dropped with queued events.
|
||||
let modifiers = wt.xconn
|
||||
let modifiers = wt
|
||||
.xconn
|
||||
.query_pointer(xev.event, xev.deviceid)
|
||||
.expect("Failed to query pointer device")
|
||||
.get_modifier_state();
|
||||
|
|
@ -746,7 +821,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
ffi::XI_Leave => {
|
||||
let xev: &ffi::XILeaveEvent = unsafe { &*(xev.data as *const _) };
|
||||
|
||||
|
|
@ -756,19 +831,20 @@ impl<T: 'static> EventProcessor<T> {
|
|||
if !window_closed {
|
||||
callback(Event::WindowEvent {
|
||||
window_id: mkwid(xev.event),
|
||||
event: CursorLeft { device_id: mkdid(xev.deviceid) },
|
||||
event: CursorLeft {
|
||||
device_id: mkdid(xev.deviceid),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
ffi::XI_FocusIn => {
|
||||
let xev: &ffi::XIFocusInEvent = unsafe { &*(xev.data as *const _) };
|
||||
|
||||
let dpi_factor = match self.with_window(xev.event, |window| {
|
||||
window.hidpi_factor()
|
||||
}) {
|
||||
Some(dpi_factor) => dpi_factor,
|
||||
None => return,
|
||||
};
|
||||
let dpi_factor =
|
||||
match self.with_window(xev.event, |window| window.hidpi_factor()) {
|
||||
Some(dpi_factor) => dpi_factor,
|
||||
None => return,
|
||||
};
|
||||
let window_id = mkwid(xev.event);
|
||||
|
||||
wt.ime
|
||||
|
|
@ -776,11 +852,15 @@ impl<T: 'static> EventProcessor<T> {
|
|||
.focus(xev.event)
|
||||
.expect("Failed to focus input context");
|
||||
|
||||
callback(Event::WindowEvent { window_id, event: Focused(true) });
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: Focused(true),
|
||||
});
|
||||
|
||||
// The deviceid for this event is for a keyboard instead of a pointer,
|
||||
// so we have to do a little extra work.
|
||||
let pointer_id = self.devices
|
||||
let pointer_id = self
|
||||
.devices
|
||||
.borrow()
|
||||
.get(&DeviceId(xev.deviceid))
|
||||
.map(|device| device.attachment)
|
||||
|
|
@ -796,12 +876,14 @@ impl<T: 'static> EventProcessor<T> {
|
|||
device_id: mkdid(pointer_id),
|
||||
position,
|
||||
modifiers: ModifiersState::from(xev.mods),
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
ffi::XI_FocusOut => {
|
||||
let xev: &ffi::XIFocusOutEvent = unsafe { &*(xev.data as *const _) };
|
||||
if !self.window_exists(xev.event) { return; }
|
||||
if !self.window_exists(xev.event) {
|
||||
return;
|
||||
}
|
||||
wt.ime
|
||||
.borrow_mut()
|
||||
.unfocus(xev.event)
|
||||
|
|
@ -810,7 +892,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
window_id: mkwid(xev.event),
|
||||
event: Focused(false),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
ffi::XI_TouchBegin | ffi::XI_TouchUpdate | ffi::XI_TouchEnd => {
|
||||
let xev: &ffi::XIDeviceEvent = unsafe { &*(xev.data as *const _) };
|
||||
|
|
@ -819,11 +901,10 @@ impl<T: 'static> EventProcessor<T> {
|
|||
ffi::XI_TouchBegin => TouchPhase::Started,
|
||||
ffi::XI_TouchUpdate => TouchPhase::Moved,
|
||||
ffi::XI_TouchEnd => TouchPhase::Ended,
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let dpi_factor = self.with_window(xev.event, |window| {
|
||||
window.hidpi_factor()
|
||||
});
|
||||
let dpi_factor =
|
||||
self.with_window(xev.event, |window| window.hidpi_factor());
|
||||
if let Some(dpi_factor) = dpi_factor {
|
||||
let location = LogicalPosition::from_physical(
|
||||
(xev.event_x as f64, xev.event_y as f64),
|
||||
|
|
@ -839,31 +920,39 @@ impl<T: 'static> EventProcessor<T> {
|
|||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::XI_RawButtonPress | ffi::XI_RawButtonRelease => {
|
||||
let xev: &ffi::XIRawEvent = unsafe { &*(xev.data as *const _) };
|
||||
if xev.flags & ffi::XIPointerEmulated == 0 {
|
||||
callback(Event::DeviceEvent { device_id: mkdid(xev.deviceid), event: DeviceEvent::Button {
|
||||
button: xev.detail as u32,
|
||||
state: match xev.evtype {
|
||||
ffi::XI_RawButtonPress => Pressed,
|
||||
ffi::XI_RawButtonRelease => Released,
|
||||
_ => unreachable!(),
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: mkdid(xev.deviceid),
|
||||
event: DeviceEvent::Button {
|
||||
button: xev.detail as u32,
|
||||
state: match xev.evtype {
|
||||
ffi::XI_RawButtonPress => Pressed,
|
||||
ffi::XI_RawButtonRelease => Released,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
},
|
||||
}});
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::XI_RawMotion => {
|
||||
let xev: &ffi::XIRawEvent = unsafe { &*(xev.data as *const _) };
|
||||
let did = mkdid(xev.deviceid);
|
||||
|
||||
let mask = unsafe { slice::from_raw_parts(xev.valuators.mask, xev.valuators.mask_len as usize) };
|
||||
let mask = unsafe {
|
||||
slice::from_raw_parts(
|
||||
xev.valuators.mask,
|
||||
xev.valuators.mask_len as usize,
|
||||
)
|
||||
};
|
||||
let mut value = xev.raw_values;
|
||||
let mut mouse_delta = (0.0, 0.0);
|
||||
let mut scroll_delta = (0.0, 0.0);
|
||||
for i in 0..xev.valuators.mask_len*8 {
|
||||
for i in 0..xev.valuators.mask_len * 8 {
|
||||
if ffi::XIMaskIsSet(mask, i) {
|
||||
let x = unsafe { *value };
|
||||
// We assume that every XInput2 device with analog axes is a pointing device emitting
|
||||
|
|
@ -875,24 +964,31 @@ impl<T: 'static> EventProcessor<T> {
|
|||
3 => scroll_delta.1 = x as f32,
|
||||
_ => {},
|
||||
}
|
||||
callback(Event::DeviceEvent { device_id: did, event: DeviceEvent::Motion {
|
||||
axis: i as u32,
|
||||
value: x,
|
||||
}});
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: did,
|
||||
event: DeviceEvent::Motion {
|
||||
axis: i as u32,
|
||||
value: x,
|
||||
},
|
||||
});
|
||||
value = unsafe { value.offset(1) };
|
||||
}
|
||||
}
|
||||
if mouse_delta != (0.0, 0.0) {
|
||||
callback(Event::DeviceEvent { device_id: did, event: DeviceEvent::MouseMotion {
|
||||
delta: mouse_delta,
|
||||
}});
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: did,
|
||||
event: DeviceEvent::MouseMotion { delta: mouse_delta },
|
||||
});
|
||||
}
|
||||
if scroll_delta != (0.0, 0.0) {
|
||||
callback(Event::DeviceEvent { device_id: did, event: DeviceEvent::MouseWheel {
|
||||
delta: LineDelta(scroll_delta.0, scroll_delta.1),
|
||||
}});
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: did,
|
||||
event: DeviceEvent::MouseWheel {
|
||||
delta: LineDelta(scroll_delta.0, scroll_delta.1),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ffi::XI_RawKeyPress | ffi::XI_RawKeyRelease => {
|
||||
let xev: &ffi::XIRawEvent = unsafe { &*(xev.data as *const _) };
|
||||
|
|
@ -905,7 +1001,9 @@ impl<T: 'static> EventProcessor<T> {
|
|||
|
||||
let device_id = xev.sourceid;
|
||||
let keycode = xev.detail;
|
||||
if keycode < 8 { return; }
|
||||
if keycode < 8 {
|
||||
return;
|
||||
}
|
||||
let scancode = (keycode - 8) as u32;
|
||||
|
||||
let keysym = unsafe {
|
||||
|
|
@ -915,7 +1013,9 @@ impl<T: 'static> EventProcessor<T> {
|
|||
0,
|
||||
)
|
||||
};
|
||||
wt.xconn.check_errors().expect("Failed to lookup raw keysym");
|
||||
wt.xconn
|
||||
.check_errors()
|
||||
.expect("Failed to lookup raw keysym");
|
||||
|
||||
let virtual_keycode = events::keysym_to_element(keysym as c_uint);
|
||||
|
||||
|
|
@ -933,23 +1033,32 @@ impl<T: 'static> EventProcessor<T> {
|
|||
modifiers: ModifiersState::default(),
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
ffi::XI_HierarchyChanged => {
|
||||
let xev: &ffi::XIHierarchyEvent = unsafe { &*(xev.data as *const _) };
|
||||
for info in unsafe { slice::from_raw_parts(xev.info, xev.num_info as usize) } {
|
||||
for info in
|
||||
unsafe { slice::from_raw_parts(xev.info, xev.num_info as usize) }
|
||||
{
|
||||
if 0 != info.flags & (ffi::XISlaveAdded | ffi::XIMasterAdded) {
|
||||
self.init_device(info.deviceid);
|
||||
callback(Event::DeviceEvent { device_id: mkdid(info.deviceid), event: DeviceEvent::Added });
|
||||
} else if 0 != info.flags & (ffi::XISlaveRemoved | ffi::XIMasterRemoved) {
|
||||
callback(Event::DeviceEvent { device_id: mkdid(info.deviceid), event: DeviceEvent::Removed });
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: mkdid(info.deviceid),
|
||||
event: DeviceEvent::Added,
|
||||
});
|
||||
} else if 0 != info.flags & (ffi::XISlaveRemoved | ffi::XIMasterRemoved)
|
||||
{
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: mkdid(info.deviceid),
|
||||
event: DeviceEvent::Removed,
|
||||
});
|
||||
let mut devices = self.devices.borrow_mut();
|
||||
devices.remove(&DeviceId(info.deviceid));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
|
|
@ -972,10 +1081,11 @@ impl<T: 'static> EventProcessor<T> {
|
|||
callback(Event::WindowEvent {
|
||||
window_id: mkwid(window_id.0),
|
||||
event: WindowEvent::HiDpiFactorChanged(
|
||||
new_monitor.hidpi_factor
|
||||
new_monitor.hidpi_factor,
|
||||
),
|
||||
});
|
||||
let (width, height) = window.inner_size_physical();
|
||||
let (width, height) =
|
||||
window.inner_size_physical();
|
||||
let (_, _, flusher) = window.adjust_for_dpi(
|
||||
prev_monitor.hidpi_factor,
|
||||
new_monitor.hidpi_factor,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue