keybind grabbing in xlib backend

This commit is contained in:
Janis 2021-11-27 22:14:09 +01:00
parent 696559d0af
commit 72129ba61e
3 changed files with 131 additions and 7 deletions

View file

@ -1,5 +1,11 @@
#![allow(dead_code)]
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
pub enum KeyOrButton {
Key(VirtualKeyCode),
Button(MouseButton),
}
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
pub enum MouseButton {
Left,

View file

@ -281,8 +281,8 @@ impl<Window> FullscreenEvent<Window> {
#[derive(Debug, Clone)]
pub struct KeyBind {
key: VirtualKeyCode,
modifiers: ModifierState,
pub key: VirtualKeyCode,
pub modifiers: ModifierState,
}
impl KeyBind {
@ -300,6 +300,6 @@ impl KeyBind {
}
pub struct MouseBind {
button: MouseButton,
modifiers: ModifierState,
pub button: MouseButton,
pub modifiers: ModifierState,
}

View file

@ -8,7 +8,10 @@ use x11::xlib::{
self, Atom, KeyPress, KeyRelease, Window, XEvent, XInternAtom, XKeyEvent,
};
use crate::backends::window_event::ModifierKey;
use crate::backends::{
keycodes::KeyOrButton, window_event::ModifierKey,
xlib::keysym::mouse_button_to_xbutton,
};
use self::keysym::{virtual_keycode_to_keysym, xev_to_mouse_button, XKeySym};
@ -391,6 +394,88 @@ impl XLib {
}
}
fn get_numlock_mask(&self) -> Option<u32> {
unsafe {
let modmap = xlib::XGetModifierMapping(self.dpy());
let max_keypermod = (*modmap).max_keypermod;
for i in 0..8 {
for j in 0..max_keypermod {
if *(*modmap)
.modifiermap
.offset((i * max_keypermod + j) as isize)
== xlib::XKeysymToKeycode(
self.dpy(),
x11::keysym::XK_Num_Lock as u64,
)
{
return Some(1 << i);
}
}
}
}
None
}
fn grab_key_or_button(
&self,
window: xlib::Window,
key: KeyOrButton,
modifiers: ModifierState,
) {
let modmask = modifiers.as_modmask(self);
let numlock_mask = self
.get_numlock_mask()
.expect("failed to query numlock mask.");
let modifiers = vec![
0,
xlib::LockMask,
numlock_mask,
xlib::LockMask | numlock_mask,
];
let keycode = match key {
KeyOrButton::Key(key) => self.vk_to_keycode(key),
KeyOrButton::Button(button) => mouse_button_to_xbutton(button),
};
for modifier in modifiers.iter() {
match key {
KeyOrButton::Key(_) => unsafe {
xlib::XGrabKey(
self.dpy(),
keycode,
modmask | modifier,
window,
1,
xlib::GrabModeAsync,
xlib::GrabModeAsync,
);
},
KeyOrButton::Button(_) => unsafe {
xlib::XGrabButton(
self.dpy(),
keycode as u32,
modmask | modifier,
window,
1,
(xlib::ButtonPressMask
| xlib::ButtonReleaseMask
| xlib::PointerMotionMask)
as u32,
xlib::GrabModeAsync,
xlib::GrabModeAsync,
0,
0,
);
},
}
}
}
fn vk_to_keycode(&self, vk: VirtualKeyCode) -> i32 {
unsafe {
xlib::XKeysymToKeycode(
@ -406,6 +491,31 @@ impl XLib {
XKeySym::new(keysym as u32)
}
fn modifier_state_to_modmask(&self) {}
}
trait ModifierStateExt {
fn as_modmask(&self, xlib: &XLib) -> u32;
}
impl ModifierStateExt for ModifierState {
fn as_modmask(&self, xlib: &XLib) -> u32 {
let bits = self.bits();
let mut mask = 0;
let numlock_mask = xlib
.get_numlock_mask()
.expect("failed to query numlock mask");
mask &= xlib::ShiftMask & !u32::from(self.contains(Self::SHIFT));
mask &= xlib::LockMask & !u32::from(self.contains(Self::SHIFT_LOCK));
mask &= xlib::ControlMask & !u32::from(self.contains(Self::CONTROL));
mask &= xlib::Mod1Mask & !u32::from(self.contains(Self::ALT));
mask &= xlib::Mod4Mask & !u32::from(self.contains(Self::SUPER));
mask &= numlock_mask & !u32::from(self.contains(Self::NUM_LOCK));
mask
}
}
impl WindowServerBackend for XLib {
@ -438,7 +548,11 @@ impl WindowServerBackend for XLib {
keybind: super::window_event::KeyBind,
window: Option<Self::Window>,
) {
todo!()
self.grab_key_or_button(
window.unwrap_or(self.root),
KeyOrButton::Key(keybind.key),
keybind.modifiers,
);
}
fn remove_keybind(
@ -454,7 +568,11 @@ impl WindowServerBackend for XLib {
keybind: super::window_event::MouseBind,
window: Option<Self::Window>,
) {
todo!()
self.grab_key_or_button(
window.unwrap_or(self.root),
KeyOrButton::Button(keybind.button),
keybind.modifiers,
);
}
fn remove_mousebind(