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:
Osspial 2019-06-21 11:33:15 -04:00 committed by GitHub
parent b1b5aefc4b
commit e2c84725de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
109 changed files with 4787 additions and 3679 deletions

View file

@ -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,