api: refactor ActiveEventLoop into trait

This should help with further extensions because the backend event
loops are used directly now.
This commit is contained in:
Kirill Chibisov 2024-08-06 21:02:53 +03:00 committed by GitHub
parent f5304815a1
commit f07153b8e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 1058 additions and 1071 deletions

View file

@ -25,13 +25,11 @@ use crate::event::{
DeviceEvent, ElementState, Event, Ime, InnerSizeWriter, MouseButton, MouseScrollDelta,
RawKeyEvent, Touch, TouchPhase, WindowEvent,
};
use crate::event_loop::ActiveEventLoop as RootAEL;
use crate::keyboard::ModifiersState;
use crate::platform_impl::common::xkb::{self, XkbState};
use crate::platform_impl::platform::common::xkb::Context;
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventReceiver, ImeRequest};
use crate::platform_impl::platform::x11::ActiveEventLoop;
use crate::platform_impl::platform::ActiveEventLoop as PlatformActiveEventLoop;
use crate::platform_impl::x11::atoms::*;
use crate::platform_impl::x11::util::cookie::GenericEventCookie;
use crate::platform_impl::x11::{
@ -53,7 +51,7 @@ pub struct EventProcessor {
pub devices: RefCell<HashMap<DeviceId, Device>>,
pub xi2ext: ExtensionInformation,
pub xkbext: ExtensionInformation,
pub target: RootAEL,
pub target: ActiveEventLoop,
pub xkb_context: Context,
// Number of touch events currently in progress
pub num_touch: u32,
@ -75,18 +73,17 @@ pub struct EventProcessor {
impl EventProcessor {
pub(crate) fn process_event<F>(&mut self, xev: &mut XEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
self.process_xevent(xev, &mut callback);
let window_target = Self::window_target_mut(&mut self.target);
// Handle IME requests.
while let Ok(request) = self.ime_receiver.try_recv() {
let ime = match window_target.ime.as_mut() {
let ime = match self.target.ime.as_mut() {
Some(ime) => ime,
None => continue,
};
let ime = ime.get_mut();
match request {
ImeRequest::Position(window_id, x, y) => {
@ -131,9 +128,8 @@ impl EventProcessor {
/// along with an extra copy of the KeyRelease events. This also prevents backspace and
/// arrow keys from being detected twice.
fn filter_event(&mut self, xev: &mut XEvent) -> bool {
let wt = Self::window_target(&self.target);
unsafe {
(wt.xconn.xlib.XFilterEvent)(xev, {
(self.target.xconn.xlib.XFilterEvent)(xev, {
let xev: &XAnyEvent = xev.as_ref();
xev.window
}) == xlib::True
@ -142,7 +138,7 @@ impl EventProcessor {
fn process_xevent<F>(&mut self, xev: &mut XEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let event_type = xev.get_type();
@ -184,9 +180,8 @@ impl EventProcessor {
self.xinput_key_input(xev.as_mut(), state, &mut callback);
},
xlib::GenericEvent => {
let wt = Self::window_target(&self.target);
let xev: GenericEventCookie =
match GenericEventCookie::from_event(wt.xconn.clone(), *xev) {
match GenericEventCookie::from_event(self.target.xconn.clone(), *xev) {
Some(xev) if xev.extension() == self.xi2ext.major_opcode => xev,
_ => return,
};
@ -298,14 +293,10 @@ impl EventProcessor {
}
pub fn poll(&self) -> bool {
let window_target = Self::window_target(&self.target);
let result = unsafe { (window_target.xconn.xlib.XPending)(window_target.xconn.display) };
result != 0
unsafe { (self.target.xconn.xlib.XPending)(self.target.xconn.display) != 0 }
}
pub unsafe fn poll_one_event(&mut self, event_ptr: *mut XEvent) -> bool {
let window_target = Self::window_target(&self.target);
// This function is used to poll and remove a single event
// from the Xlib event queue in a non-blocking, atomic way.
// XCheckIfEvent is non-blocking and removes events from queue.
@ -321,22 +312,19 @@ impl EventProcessor {
1
}
let result = unsafe {
(window_target.xconn.xlib.XCheckIfEvent)(
window_target.xconn.display,
unsafe {
(self.target.xconn.xlib.XCheckIfEvent)(
self.target.xconn.display,
event_ptr,
Some(predicate),
std::ptr::null_mut(),
)
};
result != 0
) != 0
}
}
pub fn init_device(&self, device: xinput::DeviceId) {
let window_target = Self::window_target(&self.target);
let mut devices = self.devices.borrow_mut();
if let Some(info) = DeviceInfo::get(&window_target.xconn, device as _) {
if let Some(info) = DeviceInfo::get(&self.target.xconn, device as _) {
for info in info.iter() {
devices.insert(DeviceId(info.deviceid as _), Device::new(info));
}
@ -349,8 +337,8 @@ impl EventProcessor {
{
let mut deleted = false;
let window_id = WindowId(window_id as _);
let window_target = Self::window_target(&self.target);
let result = window_target
let result = self
.target
.windows
.borrow()
.get(&window_id)
@ -363,53 +351,33 @@ impl EventProcessor {
if deleted {
// Garbage collection
window_target.windows.borrow_mut().remove(&window_id);
self.target.windows.borrow_mut().remove(&window_id);
}
result
}
// NOTE: we avoid `self` to not borrow the entire `self` as not mut.
/// Get the platform window target.
pub fn window_target(window_target: &RootAEL) -> &ActiveEventLoop {
match &window_target.p {
PlatformActiveEventLoop::X(target) => target,
#[cfg(wayland_platform)]
_ => unreachable!(),
}
}
/// Get the platform window target.
pub fn window_target_mut(window_target: &mut RootAEL) -> &mut ActiveEventLoop {
match &mut window_target.p {
PlatformActiveEventLoop::X(target) => target,
#[cfg(wayland_platform)]
_ => unreachable!(),
}
}
fn client_message<F>(&mut self, xev: &XClientMessageEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let atoms = wt.xconn.atoms();
let atoms = self.target.xconn.atoms();
let window = xev.window as xproto::Window;
let window_id = mkwid(window);
if xev.data.get_long(0) as xproto::Atom == wt.wm_delete_window {
if xev.data.get_long(0) as xproto::Atom == self.target.wm_delete_window {
let event = Event::WindowEvent { window_id, event: WindowEvent::CloseRequested };
callback(&self.target, event);
return;
}
if xev.data.get_long(0) as xproto::Atom == wt.net_wm_ping {
if xev.data.get_long(0) as xproto::Atom == self.target.net_wm_ping {
let client_msg = xproto::ClientMessageEvent {
response_type: xproto::CLIENT_MESSAGE_EVENT,
format: xev.format as _,
sequence: xev.serial as _,
window: wt.root,
window: self.target.root,
type_: xev.message_type as _,
data: xproto::ClientMessageData::from({
let [a, b, c, d, e]: [c_long; 5] = xev.data.as_longs().try_into().unwrap();
@ -417,11 +385,12 @@ impl EventProcessor {
}),
};
wt.xconn
self.target
.xconn
.xcb_connection()
.send_event(
false,
wt.root,
self.target.root,
xproto::EventMask::SUBSTRUCTURE_NOTIFY
| xproto::EventMask::SUBSTRUCTURE_REDIRECT,
client_msg.serialize(),
@ -430,7 +399,7 @@ impl EventProcessor {
return;
}
if xev.data.get_long(0) as xproto::Atom == wt.net_wm_sync_request {
if xev.data.get_long(0) as xproto::Atom == self.target.net_wm_sync_request {
let sync_counter_id = match self
.with_window(xev.window as xproto::Window, |window| window.sync_counter_id())
{
@ -448,10 +417,12 @@ impl EventProcessor {
bytemuck::cast::<u32, i32>((xev.data.get_long(3) & 0xffffffff) as u32),
);
wt.xconn
self.target
.xconn
.xcb_connection()
.sync_set_counter(sync_counter_id, Int64 { lo, hi })
.expect_then_ignore_error("Failed to set XSync counter.");
return;
}
@ -526,7 +497,7 @@ impl EventProcessor {
};
// Log this timestamp.
wt.xconn.set_timestamp(time);
self.target.xconn.set_timestamp(time);
// This results in the `SelectionNotify` event below
unsafe {
@ -580,16 +551,15 @@ impl EventProcessor {
fn selection_notify<F>(&mut self, xev: &XSelectionEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let atoms = wt.xconn.atoms();
let atoms = self.target.xconn.atoms();
let window = xev.requestor as xproto::Window;
let window_id = mkwid(window);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
if xev.property != atoms[XdndSelection] as c_ulong {
return;
@ -614,10 +584,8 @@ impl EventProcessor {
fn configure_notify<F>(&self, xev: &XConfigureEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let xwindow = xev.window as xproto::Window;
let window_id = mkwid(xwindow);
@ -672,7 +640,8 @@ impl EventProcessor {
// We need to convert client area position to window position.
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 =
self.target.xconn.get_frame_extents_heuristic(xwindow, self.target.root);
shared_state_lock.frame_extents = Some(frame_extents.clone());
frame_extents
});
@ -703,7 +672,8 @@ impl EventProcessor {
let last_scale_factor = shared_state_lock.last_monitor.scale_factor;
let new_scale_factor = {
let window_rect = util::AaRect::new(new_outer_position, new_inner_size);
let monitor = wt
let monitor = self
.target
.xconn
.get_monitor_for_window(Some(window_rect))
.expect("Failed to find monitor for window");
@ -798,9 +768,7 @@ impl EventProcessor {
/// really have much impact, since on the WMs affected (xmonad, dwm, etc.) the only
/// effect is that we waste some time trying to query unsupported properties.
fn reparent_notify(&self, xev: &XReparentEvent) {
let wt = Self::window_target(&self.target);
wt.xconn.update_cached_wm_info(wt.root);
self.target.xconn.update_cached_wm_info(self.target.root);
self.with_window(xev.window as xproto::Window, |window| {
window.invalidate_cached_frame_extents();
@ -809,7 +777,7 @@ impl EventProcessor {
fn map_notify<F>(&self, xev: &XMapEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let window = xev.window as xproto::Window;
let window_id = mkwid(window);
@ -827,20 +795,18 @@ impl EventProcessor {
fn destroy_notify<F>(&self, xev: &XDestroyWindowEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let window = xev.window as xproto::Window;
let window_id = mkwid(window);
// In the event that the window's been destroyed without being dropped first, we
// cleanup again here.
wt.windows.borrow_mut().remove(&WindowId(window as _));
self.target.windows.borrow_mut().remove(&WindowId(window as _));
// Since all XIM stuff needs to happen from the same thread, we destroy the input
// context here instead of when dropping the window.
if let Some(ime) = wt.ime.as_ref() {
if let Some(ime) = self.target.ime.as_ref() {
ime.borrow_mut()
.remove_context(window as XWindow)
.expect("Failed to destroy input context");
@ -851,10 +817,9 @@ impl EventProcessor {
fn property_notify<F>(&mut self, xev: &XPropertyEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let atoms = wt.x_connection().atoms();
let atoms = self.target.x_connection().atoms();
let atom = xev.atom as xproto::Atom;
if atom == xproto::Atom::from(xproto::AtomEnum::RESOURCE_MANAGER)
@ -866,7 +831,7 @@ impl EventProcessor {
fn visibility_notify<F>(&self, xev: &XVisibilityEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let xwindow = xev.window as xproto::Window;
@ -883,7 +848,7 @@ impl EventProcessor {
fn expose<F>(&self, xev: &XExposeEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
// Multiple Expose events may be received for subareas of a window.
// We issue `RedrawRequested` only for the last event of such a series.
@ -899,12 +864,10 @@ impl EventProcessor {
fn xinput_key_input<F>(&mut self, xev: &mut XKeyEvent, state: ElementState, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let window = match self.active_window {
Some(window) => window,
@ -989,12 +952,10 @@ impl EventProcessor {
return;
}
let wt = Self::window_target(&self.target);
if let Some(ic) =
wt.ime.as_ref().and_then(|ime| ime.borrow().get_context(window as XWindow))
self.target.ime.as_ref().and_then(|ime| ime.borrow().get_context(window as XWindow))
{
let written = wt.xconn.lookup_utf8(ic, xev);
let written = self.target.xconn.lookup_utf8(ic, xev);
if !written.is_empty() {
let event = Event::WindowEvent {
window_id,
@ -1017,15 +978,14 @@ impl EventProcessor {
state: u16,
mut callback: F,
) where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let keymap = match self.xkb_context.keymap_mut() {
Some(keymap) => keymap,
None => return,
};
let wt = Self::window_target(&self.target);
let xcb = wt.xconn.xcb_connection().get_raw_xcb_connection();
let xcb = self.target.xconn.xcb_connection().get_raw_xcb_connection();
// Use synthetic state since we're replaying the modifier. The user modifier state
// will be restored later.
@ -1046,14 +1006,13 @@ impl EventProcessor {
fn xinput2_button_input<F>(&self, event: &XIDeviceEvent, state: ElementState, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let window_id = mkwid(event.event as xproto::Window);
let device_id = mkdid(event.deviceid as xinput::DeviceId);
// Set the timestamp.
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
// Deliver multi-touch events instead of emulated mouse events.
if (event.flags & xinput2::XIPointerEmulated) != 0 {
@ -1099,12 +1058,10 @@ impl EventProcessor {
fn xinput2_mouse_motion<F>(&self, event: &XIDeviceEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
let device_id = mkdid(event.deviceid as xinput::DeviceId);
let window = event.event as xproto::Window;
@ -1174,18 +1131,16 @@ impl EventProcessor {
fn xinput2_mouse_enter<F>(&self, event: &XIEnterEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
let window = event.event as xproto::Window;
let window_id = mkwid(window);
let device_id = mkdid(event.deviceid as xinput::DeviceId);
if let Some(all_info) = DeviceInfo::get(&wt.xconn, super::ALL_DEVICES.into()) {
if let Some(all_info) = DeviceInfo::get(&self.target.xconn, super::ALL_DEVICES.into()) {
let mut devices = self.devices.borrow_mut();
for device_info in all_info.iter() {
// The second expression is need for resetting to work correctly on i3, and
@ -1219,13 +1174,12 @@ impl EventProcessor {
fn xinput2_mouse_left<F>(&self, event: &XILeaveEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let window = event.event as xproto::Window;
// Set the timestamp.
wt.xconn.set_timestamp(event.time as xproto::Timestamp);
self.target.xconn.set_timestamp(event.time as xproto::Timestamp);
// Leave, FocusIn, and FocusOut can be received by a window that's already
// been destroyed, which the user presumably doesn't want to deal with.
@ -1242,15 +1196,14 @@ impl EventProcessor {
fn xinput2_focused<F>(&mut self, xev: &XIFocusInEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let window = xev.event as xproto::Window;
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
if let Some(ime) = wt.ime.as_ref() {
if let Some(ime) = self.target.ime.as_ref() {
ime.borrow_mut().focus(xev.event).expect("Failed to focus input context");
}
@ -1260,7 +1213,7 @@ impl EventProcessor {
self.active_window = Some(window);
wt.update_listen_device_events(true);
self.target.update_listen_device_events(true);
let window_id = mkwid(window);
let position = PhysicalPosition::new(xev.event_x, xev.event_y);
@ -1301,26 +1254,25 @@ impl EventProcessor {
fn xinput2_unfocused<F>(&mut self, xev: &XIFocusOutEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let window = xev.event as xproto::Window;
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
if !self.window_exists(window) {
return;
}
if let Some(ime) = wt.ime.as_ref() {
if let Some(ime) = self.target.ime.as_ref() {
ime.borrow_mut().unfocus(xev.event).expect("Failed to unfocus input context");
}
if self.active_window.take() == Some(window) {
let window_id = mkwid(window);
wt.update_listen_device_events(false);
self.target.update_listen_device_events(false);
// Clear the modifiers when unfocusing the window.
if let Some(xkb_state) = self.xkb_context.state_mut() {
@ -1353,12 +1305,10 @@ impl EventProcessor {
fn xinput2_touch<F>(&mut self, xev: &XIDeviceEvent, phase: TouchPhase, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let window = xev.event as xproto::Window;
if self.window_exists(window) {
@ -1395,12 +1345,10 @@ impl EventProcessor {
fn xinput2_raw_button_input<F>(&self, xev: &XIRawEvent, state: ElementState, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
if xev.flags & xinput2::XIPointerEmulated == 0 {
let event = Event::DeviceEvent {
@ -1413,12 +1361,10 @@ impl EventProcessor {
fn xinput2_raw_mouse_motion<F>(&self, xev: &XIRawEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let did = mkdid(xev.deviceid as xinput::DeviceId);
@ -1467,12 +1413,10 @@ impl EventProcessor {
fn xinput2_raw_key_input<F>(&mut self, xev: &XIRawEvent, state: ElementState, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let device_id = mkdid(xev.sourceid as xinput::DeviceId);
let keycode = xev.detail as u32;
@ -1488,10 +1432,8 @@ impl EventProcessor {
}
fn xinput2_hierarchy_changed(&mut self, xev: &XIHierarchyEvent) {
let wt = Self::window_target(&self.target);
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let infos = unsafe { slice::from_raw_parts(xev.info, xev.num_info as usize) };
for info in infos {
if 0 != info.flags & (xinput2::XISlaveAdded | xinput2::XIMasterAdded) {
@ -1505,15 +1447,14 @@ impl EventProcessor {
fn xkb_event<F>(&mut self, xev: &XkbAnyEvent, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
match xev.xkb_type {
xlib::XkbNewKeyboardNotify => {
let xev = unsafe { &*(xev as *const _ as *const xlib::XkbNewKeyboardNotifyEvent) };
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
let keycodes_changed_flag = 0x1;
let geometry_changed_flag = 0x1 << 1;
@ -1524,9 +1465,9 @@ impl EventProcessor {
if xev.device == self.xkb_context.core_keyboard_id
&& (keycodes_changed || geometry_changed)
{
let xcb = wt.xconn.xcb_connection().get_raw_xcb_connection();
let xcb = self.target.xconn.xcb_connection().get_raw_xcb_connection();
self.xkb_context.set_keymap_from_x11(xcb);
self.xmodmap.reload_from_x_connection(&wt.xconn);
self.xmodmap.reload_from_x_connection(&self.target.xconn);
let window_id = match self.active_window.map(super::mkwid) {
Some(window_id) => window_id,
@ -1540,9 +1481,9 @@ impl EventProcessor {
}
},
xlib::XkbMapNotify => {
let xcb = wt.xconn.xcb_connection().get_raw_xcb_connection();
let xcb = self.target.xconn.xcb_connection().get_raw_xcb_connection();
self.xkb_context.set_keymap_from_x11(xcb);
self.xmodmap.reload_from_x_connection(&wt.xconn);
self.xmodmap.reload_from_x_connection(&self.target.xconn);
let window_id = match self.active_window.map(super::mkwid) {
Some(window_id) => window_id,
None => return,
@ -1557,7 +1498,7 @@ impl EventProcessor {
let xev = unsafe { &*(xev as *const _ as *const xlib::XkbStateNotifyEvent) };
// Set the timestamp.
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
self.target.xconn.set_timestamp(xev.time as xproto::Timestamp);
if let Some(state) = self.xkb_context.state_mut() {
state.update_modifiers(
@ -1589,7 +1530,7 @@ impl EventProcessor {
force: bool,
mut callback: F,
) where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
if let Some(state) = self.xkb_context.state_mut() {
state.update_modifiers(
@ -1615,10 +1556,8 @@ impl EventProcessor {
fn update_mods_from_query<F>(&mut self, window_id: crate::window::WindowId, mut callback: F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
let xkb_state = match self.xkb_context.state_mut() {
Some(xkb_state) => xkb_state,
None => return,
@ -1626,8 +1565,11 @@ impl EventProcessor {
unsafe {
let mut state: XkbStateRec = std::mem::zeroed();
if (wt.xconn.xlib.XkbGetState)(wt.xconn.display, XkbId::USE_CORE_KBD.into(), &mut state)
== xlib::True
if (self.target.xconn.xlib.XkbGetState)(
self.target.xconn.display,
XkbId::USE_CORE_KBD.into(),
&mut state,
) == xlib::True
{
xkb_state.update_modifiers(
state.base_mods as u32,
@ -1650,7 +1592,7 @@ impl EventProcessor {
state: u16,
mut callback: F,
) where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let xkb_mask = self.xkb_mod_mask_from_core(state);
let xkb_state = match self.xkb_context.state_mut() {
@ -1723,7 +1665,7 @@ impl EventProcessor {
///
/// The event won't be sent when the `modifiers` match the previously `sent` modifiers value,
/// unless `force` is passed. The `force` should be passed when the active window changes.
fn send_modifiers<F: FnMut(&RootAEL, Event)>(
fn send_modifiers<F: FnMut(&ActiveEventLoop, Event)>(
&self,
window_id: crate::window::WindowId,
modifiers: ModifiersState,
@ -1742,19 +1684,18 @@ impl EventProcessor {
}
fn handle_pressed_keys<F>(
target: &RootAEL,
target: &ActiveEventLoop,
window_id: crate::window::WindowId,
state: ElementState,
xkb_context: &mut Context,
callback: &mut F,
) where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD);
// Update modifiers state and emit key events based on which keys are currently pressed.
let window_target = Self::window_target(target);
let xcb = window_target.xconn.xcb_connection().get_raw_xcb_connection();
let xcb = target.xconn.xcb_connection().get_raw_xcb_connection();
let keymap = match xkb_context.keymap_mut() {
Some(keymap) => keymap,
@ -1771,9 +1712,7 @@ impl EventProcessor {
None => return,
};
for keycode in
window_target.xconn.query_keymap().into_iter().filter(|k| *k >= KEYCODE_OFFSET)
{
for keycode in target.xconn.query_keymap().into_iter().filter(|k| *k >= KEYCODE_OFFSET) {
let event = key_processor.process_key_event(keycode as u32, state, false);
let event = Event::WindowEvent {
window_id,
@ -1785,21 +1724,20 @@ impl EventProcessor {
fn process_dpi_change<F>(&self, callback: &mut F)
where
F: FnMut(&RootAEL, Event),
F: FnMut(&ActiveEventLoop, Event),
{
let wt = Self::window_target(&self.target);
wt.xconn.reload_database().expect("failed to reload Xft database");
self.target.xconn.reload_database().expect("failed to reload Xft database");
// In the future, it would be quite easy to emit monitor hotplug events.
let prev_list = {
let prev_list = wt.xconn.invalidate_cached_monitor_list();
let prev_list = self.target.xconn.invalidate_cached_monitor_list();
match prev_list {
Some(prev_list) => prev_list,
None => return,
}
};
let new_list = wt.xconn.available_monitors().expect("Failed to get monitor list");
let new_list = self.target.xconn.available_monitors().expect("Failed to get monitor list");
for new_monitor in new_list {
// Previous list may be empty, in case of disconnecting and
// reconnecting the only one monitor. We still need to emit events in
@ -1809,7 +1747,7 @@ impl EventProcessor {
.find(|prev_monitor| prev_monitor.name == new_monitor.name)
.map(|prev_monitor| prev_monitor.scale_factor);
if Some(new_monitor.scale_factor) != maybe_prev_scale_factor {
for window in wt.windows.borrow().iter().filter_map(|(_, w)| w.upgrade()) {
for window in self.target.windows.borrow().iter().filter_map(|(_, w)| w.upgrade()) {
window.refresh_dpi_for_monitor(&new_monitor, maybe_prev_scale_factor, |event| {
callback(&self.target, event);
})