fixed keybinds in backend trait/impl
This commit is contained in:
parent
964d6fe748
commit
d3f630549e
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
117
src/state.rs
117
src/state.rs
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue