From 5a1d3e46563f5e8695875db3824eba1cfca77827 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sat, 30 Dec 2023 01:10:38 +0400 Subject: [PATCH] On X11, update keymap on XkbMapNotify This is required to handle xmodmap. Fixes #3338. --- CHANGELOG.md | 1 + src/platform_impl/linux/x11/event_processor.rs | 15 +++++++++++++++ src/platform_impl/linux/x11/mod.rs | 4 +++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ac1a442..6b9ec750 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Unreleased` header. # Unreleased +- On X11, keymap not updated from xmodmap. - On X11, reduce the amount of time spent fetching screen resources. - On Windows, macOS, X11, Wayland and Web, implement setting images as cursors. See the `custom_cursors.rs` example. - **Breaking:** Remove `Window::set_cursor_icon` diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index ad031b28..2cf597f9 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -1282,6 +1282,21 @@ impl EventProcessor { unsafe { self.kb_state.init_with_x11_keymap() }; } } + ffi::XkbMapNotify => { + let prev_mods = self.kb_state.mods_state(); + unsafe { self.kb_state.init_with_x11_keymap() }; + let new_mods = self.kb_state.mods_state(); + if prev_mods != new_mods { + if let Some(window) = self.active_window { + callback(Event::WindowEvent { + window_id: mkwid(window), + event: WindowEvent::ModifiersChanged( + Into::::into(new_mods).into(), + ), + }); + } + } + } ffi::XkbStateNotify => { let xev = unsafe { &*(xev as *const _ as *const ffi::XkbStateNotifyEvent) }; diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 0efef5ad..7d6743d8 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -365,7 +365,9 @@ impl EventLoop { .xconn .select_xkb_events( 0x100, // Use the "core keyboard device" - xkb::EventType::NEW_KEYBOARD_NOTIFY | xkb::EventType::STATE_NOTIFY, + xkb::EventType::NEW_KEYBOARD_NOTIFY + | xkb::EventType::MAP_NOTIFY + | xkb::EventType::STATE_NOTIFY, ) .unwrap();