keybind grabbing in xlib backend
This commit is contained in:
parent
696559d0af
commit
72129ba61e
|
@ -1,5 +1,11 @@
|
||||||
#![allow(dead_code)]
|
#![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)]
|
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum MouseButton {
|
pub enum MouseButton {
|
||||||
Left,
|
Left,
|
||||||
|
|
|
@ -281,8 +281,8 @@ impl<Window> FullscreenEvent<Window> {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct KeyBind {
|
pub struct KeyBind {
|
||||||
key: VirtualKeyCode,
|
pub key: VirtualKeyCode,
|
||||||
modifiers: ModifierState,
|
pub modifiers: ModifierState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyBind {
|
impl KeyBind {
|
||||||
|
@ -300,6 +300,6 @@ impl KeyBind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MouseBind {
|
pub struct MouseBind {
|
||||||
button: MouseButton,
|
pub button: MouseButton,
|
||||||
modifiers: ModifierState,
|
pub modifiers: ModifierState,
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,10 @@ use x11::xlib::{
|
||||||
self, Atom, KeyPress, KeyRelease, Window, XEvent, XInternAtom, XKeyEvent,
|
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};
|
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 {
|
fn vk_to_keycode(&self, vk: VirtualKeyCode) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
xlib::XKeysymToKeycode(
|
xlib::XKeysymToKeycode(
|
||||||
|
@ -406,6 +491,31 @@ impl XLib {
|
||||||
|
|
||||||
XKeySym::new(keysym as u32)
|
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 {
|
impl WindowServerBackend for XLib {
|
||||||
|
@ -438,7 +548,11 @@ impl WindowServerBackend for XLib {
|
||||||
keybind: super::window_event::KeyBind,
|
keybind: super::window_event::KeyBind,
|
||||||
window: Option<Self::Window>,
|
window: Option<Self::Window>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
self.grab_key_or_button(
|
||||||
|
window.unwrap_or(self.root),
|
||||||
|
KeyOrButton::Key(keybind.key),
|
||||||
|
keybind.modifiers,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_keybind(
|
fn remove_keybind(
|
||||||
|
@ -454,7 +568,11 @@ impl WindowServerBackend for XLib {
|
||||||
keybind: super::window_event::MouseBind,
|
keybind: super::window_event::MouseBind,
|
||||||
window: Option<Self::Window>,
|
window: Option<Self::Window>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
self.grab_key_or_button(
|
||||||
|
window.unwrap_or(self.root),
|
||||||
|
KeyOrButton::Button(keybind.button),
|
||||||
|
keybind.modifiers,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_mousebind(
|
fn remove_mousebind(
|
||||||
|
|
Loading…
Reference in a new issue