fixed keybinds in backend trait/impl

This commit is contained in:
Janis 2021-11-28 16:44:33 +01:00
parent 964d6fe748
commit d3f630549e
4 changed files with 231 additions and 114 deletions

View file

@ -1,6 +1,6 @@
use super::{
window_event,
window_event::{KeyBind, MouseBind, Point},
window_event::{KeyOrMouseBind, Point},
};
pub trait WindowServerBackend {
@ -13,23 +13,9 @@ pub trait WindowServerBackend {
fn handle_event(&mut self, event: window_event::WindowEvent<Self::Window>);
/// adds a keybind to the specified `window`, or globally if `window` is `None`.
fn add_keybind(&mut self, keybind: KeyBind, window: Option<Self::Window>);
fn remove_keybind(
&mut self,
keybind: KeyBind,
window: Option<Self::Window>,
);
fn add_mousebind(
&mut self,
keybind: MouseBind,
window: Option<Self::Window>,
);
fn remove_mousebind(
&mut self,
keybind: MouseBind,
window: Option<Self::Window>,
);
/// add global keybind
fn add_keybind(&mut self, keybind: KeyOrMouseBind);
fn remove_keybind(&mut self, keybind: &KeyOrMouseBind);
fn focus_window(&self, window: Self::Window);
fn unfocus_window(&self, window: Self::Window);

View file

@ -1,6 +1,6 @@
#![allow(dead_code)]
use super::keycodes::{MouseButton, VirtualKeyCode};
use super::keycodes::{KeyOrButton, MouseButton, VirtualKeyCode};
use bitflags::bitflags;
#[derive(Debug)]
@ -279,7 +279,7 @@ impl<Window> FullscreenEvent<Window> {
}
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct KeyBind {
pub key: VirtualKeyCode,
pub modifiers: ModifierState,
@ -299,7 +299,78 @@ impl KeyBind {
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct MouseBind {
pub button: MouseButton,
pub modifiers: ModifierState,
}
impl MouseBind {
pub fn new(button: MouseButton) -> Self {
Self {
button,
modifiers: ModifierState::empty(),
}
}
pub fn with_mod(mut self, modifier_key: ModifierKey) -> Self {
self.modifiers.set_mod(modifier_key);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct KeyOrMouseBind {
pub key: KeyOrButton,
pub modifiers: ModifierState,
}
impl KeyOrMouseBind {
pub fn new(key: KeyOrButton) -> Self {
Self {
key,
modifiers: ModifierState::empty(),
}
}
pub fn with_mod(mut self, modifier_key: ModifierKey) -> Self {
self.modifiers.set_mod(modifier_key);
self
}
}
impl From<&KeyBind> for KeyOrMouseBind {
fn from(keybind: &KeyBind) -> Self {
Self {
key: KeyOrButton::Key(keybind.key),
modifiers: keybind.modifiers,
}
}
}
impl From<KeyBind> for KeyOrMouseBind {
fn from(keybind: KeyBind) -> Self {
Self {
key: KeyOrButton::Key(keybind.key),
modifiers: keybind.modifiers,
}
}
}
impl From<&MouseBind> for KeyOrMouseBind {
fn from(mousebind: &MouseBind) -> Self {
Self {
key: KeyOrButton::Button(mousebind.button),
modifiers: mousebind.modifiers,
}
}
}
impl From<MouseBind> for KeyOrMouseBind {
fn from(mousebind: MouseBind) -> Self {
Self {
key: KeyOrButton::Button(mousebind.button),
modifiers: mousebind.modifiers,
}
}
}

View file

@ -18,8 +18,8 @@ use self::keysym::{virtual_keycode_to_keysym, xev_to_mouse_button, XKeySym};
use super::{
keycodes::VirtualKeyCode,
window_event::{
ButtonEvent, ConfigureEvent, DestroyEvent, EnterEvent, KeyState,
MapEvent, ModifierState, Point, UnmapEvent, WindowEvent,
ButtonEvent, ConfigureEvent, DestroyEvent, EnterEvent, KeyOrMouseBind,
KeyState, MapEvent, ModifierState, Point, UnmapEvent, WindowEvent,
},
WindowServerBackend,
};
@ -139,7 +139,7 @@ pub struct XLib {
root: Window,
screen: i32,
atoms: XLibAtoms,
keybinds: Vec<()>,
keybinds: Vec<KeyOrMouseBind>,
}
impl Drop for XLib {
@ -420,11 +420,10 @@ impl XLib {
fn grab_key_or_button(
&self,
binding: &KeyOrMouseBind,
window: xlib::Window,
key: KeyOrButton,
modifiers: ModifierState,
) {
let modmask = modifiers.as_modmask(self);
let modmask = binding.modifiers.as_modmask(self);
let numlock_mask = self
.get_numlock_mask()
@ -437,13 +436,13 @@ impl XLib {
xlib::LockMask | numlock_mask,
];
let keycode = match key {
let keycode = match binding.key {
KeyOrButton::Key(key) => self.vk_to_keycode(key),
KeyOrButton::Button(button) => mouse_button_to_xbutton(button),
};
for modifier in modifiers.iter() {
match key {
match binding.key {
KeyOrButton::Key(_) => unsafe {
xlib::XGrabKey(
self.dpy(),
@ -476,6 +475,57 @@ impl XLib {
}
}
fn ungrab_key_or_button(
&self,
binding: &KeyOrMouseBind,
window: xlib::Window,
) {
let modmask = binding.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 binding.key {
KeyOrButton::Key(key) => self.vk_to_keycode(key),
KeyOrButton::Button(button) => mouse_button_to_xbutton(button),
};
for modifier in modifiers.iter() {
match binding.key {
KeyOrButton::Key(_) => unsafe {
xlib::XUngrabKey(
self.dpy(),
keycode,
modmask | modifier,
window,
);
},
KeyOrButton::Button(_) => unsafe {
xlib::XUngrabButton(
self.dpy(),
keycode as u32,
modmask | modifier,
window,
);
},
}
}
}
fn grab_global_keybinds(&self, window: xlib::Window) {
for binding in self.keybinds.iter() {
self.grab_key_or_button(binding, window);
}
}
fn vk_to_keycode(&self, vk: VirtualKeyCode) -> i32 {
unsafe {
xlib::XKeysymToKeycode(
@ -538,47 +588,44 @@ impl WindowServerBackend for XLib {
&mut self,
event: super::window_event::WindowEvent<Self::Window>,
) {
todo!()
match event {
WindowEvent::MapRequestEvent(event) => {
unsafe {
xlib::XMapWindow(self.dpy(), event.window);
xlib::XSelectInput(
self.dpy(),
event.window,
xlib::EnterWindowMask
| xlib::FocusChangeMask
| xlib::PropertyChangeMask
| xlib::StructureNotifyMask,
);
}
self.grab_global_keybinds(event.window);
}
WindowEvent::ConfigureEvent(event) => {
self.configure_window(
event.window,
Some(event.size),
Some(event.position),
);
}
_ => {}
}
}
fn add_keybind(
&mut self,
keybind: super::window_event::KeyBind,
window: Option<Self::Window>,
) {
self.grab_key_or_button(
window.unwrap_or(self.root),
KeyOrButton::Key(keybind.key),
keybind.modifiers,
);
fn add_keybind(&mut self, keybind: super::window_event::KeyOrMouseBind) {
self.grab_key_or_button(&keybind, self.root);
self.keybinds.push(keybind);
}
fn remove_keybind(
&mut self,
keybind: super::window_event::KeyBind,
window: Option<Self::Window>,
keybind: &super::window_event::KeyOrMouseBind,
) {
todo!()
}
fn add_mousebind(
&mut self,
keybind: super::window_event::MouseBind,
window: Option<Self::Window>,
) {
self.grab_key_or_button(
window.unwrap_or(self.root),
KeyOrButton::Button(keybind.button),
keybind.modifiers,
);
}
fn remove_mousebind(
&mut self,
keybind: super::window_event::MouseBind,
window: Option<Self::Window>,
) {
todo!()
self.keybinds.retain(|kb| kb != keybind);
}
fn focus_window(&self, window: Self::Window) {

View file

@ -2,7 +2,7 @@ use std::{cell::RefCell, rc::Rc};
use log::{error, info};
use x11::xlib::{self, Window, XEvent, XMotionEvent};
use x11::xlib::{self, Window, XEvent};
use xlib::{
XConfigureRequestEvent, XCrossingEvent, XDestroyWindowEvent,
XMapRequestEvent, XUnmapEvent,
@ -12,8 +12,9 @@ use crate::{
backends::{
keycodes::{MouseButton, VirtualKeyCode},
window_event::{
ButtonEvent, KeyBind, KeyEvent, KeyState, ModifierKey,
ModifierState, Point, WindowEvent,
ButtonEvent, ConfigureEvent, KeyBind, KeyEvent, KeyState, MapEvent,
ModifierKey, ModifierState, MotionEvent, MouseBind, Point,
WindowEvent,
},
xlib::XLib,
WindowServerBackend,
@ -119,22 +120,21 @@ where
}
fn init(mut self) -> Self {
// TODO: fix keybinds for moving windows and stuff
// self.xlib.add_global_keybind(KeyOrButton::button(
// 1,
// self.config.mod_key,
// ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
// ));
// self.xlib.add_global_keybind(KeyOrButton::button(
// 2,
// self.config.mod_key,
// ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
// ));
// self.xlib.add_global_keybind(KeyOrButton::button(
// 3,
// self.config.mod_key,
// ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
// ));
self.backend.add_keybind(
MouseBind::new(MouseButton::Left)
.with_mod(self.config.mod_key)
.into(),
);
self.backend.add_keybind(
MouseBind::new(MouseButton::Middle)
.with_mod(self.config.mod_key)
.into(),
);
self.backend.add_keybind(
MouseBind::new(MouseButton::Right)
.with_mod(self.config.mod_key)
.into(),
);
self.add_keybind(KeyBinding::new(
KeyBind::new(VirtualKeyCode::P).with_mod(self.config.mod_key),
@ -256,7 +256,7 @@ where
}
fn add_keybind(&mut self, keybind: KeyBinding<B>) {
//self.xlib.add_global_keybind(keybind.key);
self.backend.add_keybind((&keybind.key).into());
self.keybinds.borrow_mut().push(keybind);
}
@ -361,23 +361,47 @@ where
let event = self.backend.next_event();
match event {
WindowEvent::KeyEvent(event @ KeyEvent { window, .. }) => {
WindowEvent::KeyEvent(event) => {
self.handle_keybinds(&event);
}
WindowEvent::ButtonEvent(
event @ ButtonEvent { window, .. },
) => {
WindowEvent::ButtonEvent(event) => {
self.button_event(&event);
}
// xlib::MapRequest => self.map_request(&event),
// xlib::UnmapNotify => self.unmap_notify(&event),
// xlib::ConfigureRequest => self.configure_request(&event),
// xlib::EnterNotify => self.enter_notify(&event),
WindowEvent::MapRequestEvent(MapEvent { window }) => {
if !self.clients.contains(&window) {
self.new_client(window);
}
self.backend.handle_event(event);
}
WindowEvent::UnmapEvent(event) => {
self.clients.remove(&event.window);
self.arrange_clients();
}
WindowEvent::EnterEvent(event) => {
self.focus_client(&event.window, false);
}
WindowEvent::MotionEvent(event) => {
self.do_move_resize_window(&event);
}
WindowEvent::ConfigureEvent(ConfigureEvent {
window, ..
}) => {
if !self.clients.contains(&window) {
self.backend.handle_event(event);
}
// TODO
// match self.clients.get(&event.window).into_option() {
// Some(client) => self
// .xlib
// .configure_client(client, self.clients.get_border()),
// None => self.xlib.configure_window(event),
// }
}
// i dont think i actually have to handle destroy notify events.
// every window should be unmapped regardless
// xlib::DestroyNotify => self.destroy_notify(&event),
// xlib::ButtonPress => self.button_press(event.as_ref()),
// xlib::ButtonRelease => self.button_release(event.as_ref()),
// xlib::MotionNotify => self.motion_notify(event.as_ref()),
// xlib::KeyPress => self.handle_keybinds(event.as_ref()),
_ => {}
}
}
@ -397,6 +421,7 @@ where
// TODO: change this somehow cuz I'm not a big fan of this "hardcoded" keybind stuff
fn handle_keybinds(&mut self, event: &KeyEvent<B::Window>) {
// I'm not sure if this has to be a Rc<RefCell>> or if it would be better as a Cell<>
let keybinds = self.keybinds.clone();
for kb in keybinds.borrow().iter() {
@ -406,17 +431,6 @@ where
kb.call(self, event);
}
}
//let clean_mask = self.xlib.get_clean_mask();
// TODO: Fix this
// for kb in self.keybinds.clone().into_iter() {
// if let KeyOrButton::Key(keycode, modmask) = kb.key {
// if keycode as u32 == event.keycode
// && modmask & clean_mask == event.state & clean_mask
// {
// (kb.closure)(self, event);
// }
// }
// }
}
fn handle_switch_stack(&mut self) {
@ -629,11 +643,13 @@ where
Client::new_default(window)
};
// TODO
//self.xlib
//.configure_client(&client, self.clients.get_border());
self.clients.insert(client).unwrap();
self.arrange_clients();
// TODO
//self.xlib.map_window(window);
self.focus_client(&window, true);
@ -666,6 +682,7 @@ where
fn configure_request(&mut self, event: &XEvent) {
let event: &XConfigureRequestEvent = event.as_ref();
// TODO
// match self.clients.get(&event.window).into_option() {
// Some(client) => self
// .xlib
@ -741,12 +758,12 @@ where
}
}
fn do_move_resize_window(&mut self, event: &XMotionEvent) {
fn do_move_resize_window(&mut self, event: &MotionEvent<B::Window>) {
match &self.move_resize_window {
MoveResizeInfo::Move(info) => {
let (x, y) = (
event.x - info.starting_cursor_pos.x,
event.y - info.starting_cursor_pos.y,
event.position.x - info.starting_cursor_pos.x,
event.position.y - info.starting_cursor_pos.y,
);
if let Some(client) =
@ -762,8 +779,8 @@ where
}
MoveResizeInfo::Resize(info) => {
let (x, y) = (
event.x - info.starting_cursor_pos.x,
event.y - info.starting_cursor_pos.y,
event.position.x - info.starting_cursor_pos.x,
event.position.y - info.starting_cursor_pos.y,
);
if let Some(client) =
@ -817,10 +834,6 @@ where
}
}
fn motion_notify(&mut self, event: &XMotionEvent) {
self.do_move_resize_window(event);
}
pub fn spawn(&self, command: &str, args: &[&str]) {
info!("spawn: {:?} {:?}", command, args.join(" "));
match std::process::Command::new(command).args(args).spawn() {