On X11, replay modifiers consumed by XIM
This commit is contained in:
parent
010787a430
commit
7e28d7615e
4 changed files with 170 additions and 16 deletions
|
|
@ -1,6 +1,12 @@
|
|||
// Welcome to the util module, where we try to keep you from shooting yourself in the foot.
|
||||
// *results may vary
|
||||
|
||||
use std::{
|
||||
mem::{self, MaybeUninit},
|
||||
ops::BitAnd,
|
||||
os::raw::*,
|
||||
};
|
||||
|
||||
mod client_msg;
|
||||
mod cursor;
|
||||
mod geometry;
|
||||
|
|
@ -12,13 +18,10 @@ pub(crate) mod memory;
|
|||
mod randr;
|
||||
mod window_property;
|
||||
mod wm;
|
||||
mod xmodmap;
|
||||
|
||||
pub use self::{cursor::*, geometry::*, hint::*, input::*, window_property::*, wm::*};
|
||||
|
||||
use std::{
|
||||
mem::{self, MaybeUninit},
|
||||
ops::BitAnd,
|
||||
os::raw::*,
|
||||
pub use self::{
|
||||
cursor::*, geometry::*, hint::*, input::*, window_property::*, wm::*, xmodmap::ModifierKeymap,
|
||||
};
|
||||
|
||||
use super::{atoms::*, ffi, VoidCookie, X11Error, XConnection, XError};
|
||||
|
|
|
|||
56
src/platform_impl/linux/x11/util/xmodmap.rs
Normal file
56
src/platform_impl/linux/x11/util/xmodmap.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
use std::collections::HashSet;
|
||||
use std::slice;
|
||||
|
||||
use x11_dl::xlib::{KeyCode as XKeyCode, XModifierKeymap};
|
||||
|
||||
// Offsets within XModifierKeymap to each set of keycodes.
|
||||
// We are only interested in Shift, Control, Alt, and Logo.
|
||||
//
|
||||
// There are 8 sets total. The order of keycode sets is:
|
||||
// Shift, Lock, Control, Mod1 (Alt), Mod2, Mod3, Mod4 (Logo), Mod5
|
||||
//
|
||||
// https://tronche.com/gui/x/xlib/input/XSetModifierMapping.html
|
||||
const NUM_MODS: usize = 8;
|
||||
|
||||
/// Track which keys are modifiers, so we can properly replay them when they were filtered.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ModifierKeymap {
|
||||
// Maps keycodes to modifiers
|
||||
modifers: HashSet<XKeyCode>,
|
||||
}
|
||||
|
||||
impl ModifierKeymap {
|
||||
pub fn new() -> ModifierKeymap {
|
||||
ModifierKeymap::default()
|
||||
}
|
||||
|
||||
pub fn is_modifier(&self, keycode: XKeyCode) -> bool {
|
||||
self.modifers.contains(&keycode)
|
||||
}
|
||||
|
||||
pub fn reload_from_x_connection(&mut self, xconn: &super::XConnection) {
|
||||
unsafe {
|
||||
let keymap = (xconn.xlib.XGetModifierMapping)(xconn.display);
|
||||
|
||||
if keymap.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.reset_from_x_keymap(&*keymap);
|
||||
|
||||
(xconn.xlib.XFreeModifiermap)(keymap);
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_from_x_keymap(&mut self, keymap: &XModifierKeymap) {
|
||||
let keys_per_mod = keymap.max_keypermod as usize;
|
||||
|
||||
let keys = unsafe {
|
||||
slice::from_raw_parts(keymap.modifiermap as *const _, keys_per_mod * NUM_MODS)
|
||||
};
|
||||
self.modifers.clear();
|
||||
for key in keys {
|
||||
self.modifers.insert(*key);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue