cargo check throws no error

This commit is contained in:
Janis 2021-11-24 18:40:55 +01:00
parent 6c3999caab
commit bea2ad6688
7 changed files with 357 additions and 205 deletions

View file

@ -17,16 +17,16 @@ pub enum MouseButton {
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)] #[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
#[repr(u32)] #[repr(u32)]
pub enum VirtualKeyCode { pub enum VirtualKeyCode {
Key1, One,
Key2, Two,
Key3, Three,
Key4, Four,
Key5, Five,
Key6, Six,
Key7, Seven,
Key8, Eight,
Key9, Nine,
Key0, Zero,
A, A,
B, B,
C, C,

View file

@ -7,6 +7,8 @@ pub mod xlib;
pub trait WindowServerBackend { pub trait WindowServerBackend {
type Window; type Window;
fn new() -> Self;
fn next_event(&self) -> window_event::WindowEvent<Self::Window>; fn next_event(&self) -> window_event::WindowEvent<Self::Window>;
fn add_keybind(&mut self, keybind: KeyBind, window: Option<Self::Window>); fn add_keybind(&mut self, keybind: KeyBind, window: Option<Self::Window>);
fn remove_keybind( fn remove_keybind(
@ -22,9 +24,12 @@ pub trait WindowServerBackend {
); );
fn focus_window(&self, window: Self::Window); fn focus_window(&self, window: Self::Window);
fn unfocus_window(&self, window: Self::Window); fn unfocus_window(&self, window: Self::Window);
fn move_window(&self, window: Self::Window, pos: i32); fn move_window(&self, window: Self::Window, new_pos: (i32, i32));
fn resize_window(&self, window: Self::Window, pos: i32); fn resize_window(&self, window: Self::Window, new_size: (i32, i32));
fn raise_window(&self, window: Self::Window);
fn get_parent_window(&self, window: Self::Window) -> Option<Self::Window>;
fn hide_window(&self, window: Self::Window); fn hide_window(&self, window: Self::Window);
fn screen_size(&self) -> (i32, i32); fn screen_size(&self) -> (i32, i32);
fn kill_window(&self, window: Self::Window); fn kill_window(&self, window: Self::Window);
fn get_window_size(&self, window: Self::Window) -> Option<(i32, i32)>;
} }

View file

@ -37,7 +37,13 @@ pub enum ModifierKey {
NumLock, NumLock,
} }
#[derive(Default, Debug, Clone)] impl Into<u8> for ModifierKey {
fn into(self) -> u8 {
self as u8
}
}
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct ModifierState { pub struct ModifierState {
modifiers: std::collections::HashSet<ModifierKey>, modifiers: std::collections::HashSet<ModifierKey>,
} }
@ -47,6 +53,11 @@ impl ModifierState {
Self::default() Self::default()
} }
pub fn with_mod(mut self, modifier: ModifierKey) -> Self {
self.set_modifier(modifier);
self
}
pub fn set_modifier(&mut self, modifier: ModifierKey) { pub fn set_modifier(&mut self, modifier: ModifierKey) {
self.modifiers.insert(modifier); self.modifiers.insert(modifier);
} }
@ -58,6 +69,79 @@ impl ModifierState {
pub fn get_modifier(&mut self, modifier: ModifierKey) -> bool { pub fn get_modifier(&mut self, modifier: ModifierKey) -> bool {
self.modifiers.contains(&modifier) self.modifiers.contains(&modifier)
} }
pub fn all() -> Self {
[
ModifierKey::Alt,
ModifierKey::Shift,
ModifierKey::AltGr,
ModifierKey::Super,
ModifierKey::Control,
ModifierKey::NumLock,
ModifierKey::ShiftLock,
]
.into()
}
pub fn ignore_mask() -> Self {
[
ModifierKey::Alt,
ModifierKey::AltGr,
ModifierKey::Shift,
ModifierKey::Super,
ModifierKey::Control,
]
.into()
}
pub fn eq_ignore_lock(&self, other: &Self) -> bool {
let mask = &Self::ignore_mask();
self & mask == other & mask
}
}
impl<const N: usize> From<[ModifierKey; N]> for ModifierState {
fn from(slice: [ModifierKey; N]) -> Self {
Self {
modifiers: std::collections::HashSet::from(slice),
}
}
}
impl From<std::collections::HashSet<ModifierKey>> for ModifierState {
fn from(set: std::collections::HashSet<ModifierKey>) -> Self {
Self { modifiers: set }
}
}
impl std::ops::BitXor for &ModifierState {
type Output = ModifierState;
fn bitxor(self, rhs: Self) -> Self::Output {
Self::Output {
modifiers: self.modifiers.bitxor(&rhs.modifiers),
}
}
}
impl std::ops::BitOr for &ModifierState {
type Output = ModifierState;
fn bitor(self, rhs: Self) -> Self::Output {
Self::Output {
modifiers: self.modifiers.bitor(&rhs.modifiers),
}
}
}
impl std::ops::BitAnd for &ModifierState {
type Output = ModifierState;
fn bitand(self, rhs: Self) -> Self::Output {
Self::Output {
modifiers: self.modifiers.bitand(&rhs.modifiers),
}
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -195,11 +279,26 @@ impl<Window> FullscreenEvent<Window> {
} }
} }
#[derive(Debug, Clone)]
pub struct KeyBind { pub struct KeyBind {
key: VirtualKeyCode, key: VirtualKeyCode,
modifiers: ModifierState, modifiers: ModifierState,
} }
impl KeyBind {
pub fn new(key: VirtualKeyCode) -> Self {
Self {
key,
modifiers: Default::default(),
}
}
pub fn with_mod(mut self, modifier_key: ModifierKey) -> Self {
self.modifiers.set_modifier(modifier_key);
self
}
}
pub struct MouseBind { pub struct MouseBind {
button: MouseButton, button: MouseButton,
modifiers: ModifierState, modifiers: ModifierState,

View file

@ -1,7 +1,10 @@
#![allow(unreachable_patterns)] #![allow(unreachable_patterns)]
use std::{borrow::Borrow, ops::Deref}; use std::{borrow::Borrow, ops::Deref};
use crate::backends::keycodes::{MouseButton, VirtualKeyCode}; use crate::backends::{
keycodes::{MouseButton, VirtualKeyCode},
window_event::ModifierState,
};
pub fn xev_to_mouse_button( pub fn xev_to_mouse_button(
button: &x11::xlib::XButtonEvent, button: &x11::xlib::XButtonEvent,
@ -68,6 +71,10 @@ impl From<VirtualKeyCode> for XKeysym {
} }
} }
pub fn xlib_state_to_modifier_state(state: u32) -> ModifierState {
todo!()
}
/// from winit /// from winit
pub fn keysym_to_virtual_keycode(keysym: u32) -> Option<VirtualKeyCode> { pub fn keysym_to_virtual_keycode(keysym: u32) -> Option<VirtualKeyCode> {
Some(match keysym { Some(match keysym {
@ -256,16 +263,16 @@ pub fn keysym_to_virtual_keycode(keysym: u32) -> Option<VirtualKeyCode> {
x11::keysym::XK_minus => VirtualKeyCode::Minus, x11::keysym::XK_minus => VirtualKeyCode::Minus,
x11::keysym::XK_period => VirtualKeyCode::Period, x11::keysym::XK_period => VirtualKeyCode::Period,
x11::keysym::XK_slash => VirtualKeyCode::Slash, x11::keysym::XK_slash => VirtualKeyCode::Slash,
x11::keysym::XK_0 => VirtualKeyCode::Key0, x11::keysym::XK_0 => VirtualKeyCode::Zero,
x11::keysym::XK_1 => VirtualKeyCode::Key1, x11::keysym::XK_1 => VirtualKeyCode::One,
x11::keysym::XK_2 => VirtualKeyCode::Key2, x11::keysym::XK_2 => VirtualKeyCode::Two,
x11::keysym::XK_3 => VirtualKeyCode::Key3, x11::keysym::XK_3 => VirtualKeyCode::Three,
x11::keysym::XK_4 => VirtualKeyCode::Key4, x11::keysym::XK_4 => VirtualKeyCode::Four,
x11::keysym::XK_5 => VirtualKeyCode::Key5, x11::keysym::XK_5 => VirtualKeyCode::Five,
x11::keysym::XK_6 => VirtualKeyCode::Key6, x11::keysym::XK_6 => VirtualKeyCode::Six,
x11::keysym::XK_7 => VirtualKeyCode::Key7, x11::keysym::XK_7 => VirtualKeyCode::Seven,
x11::keysym::XK_8 => VirtualKeyCode::Key8, x11::keysym::XK_8 => VirtualKeyCode::Eight,
x11::keysym::XK_9 => VirtualKeyCode::Key9, x11::keysym::XK_9 => VirtualKeyCode::Nine,
x11::keysym::XK_colon => VirtualKeyCode::Colon, x11::keysym::XK_colon => VirtualKeyCode::Colon,
x11::keysym::XK_semicolon => VirtualKeyCode::Semicolon, x11::keysym::XK_semicolon => VirtualKeyCode::Semicolon,
//x11::keysym::XK_less => VirtualKeyCode::Less, //x11::keysym::XK_less => VirtualKeyCode::Less,
@ -1261,16 +1268,16 @@ pub fn virtual_keycode_to_keysym(keycode: VirtualKeyCode) -> Option<u32> {
VirtualKeyCode::Minus => x11::keysym::XK_minus, VirtualKeyCode::Minus => x11::keysym::XK_minus,
VirtualKeyCode::Period => x11::keysym::XK_period, VirtualKeyCode::Period => x11::keysym::XK_period,
VirtualKeyCode::Slash => x11::keysym::XK_slash, VirtualKeyCode::Slash => x11::keysym::XK_slash,
VirtualKeyCode::Key0 => x11::keysym::XK_0, VirtualKeyCode::Zero => x11::keysym::XK_0,
VirtualKeyCode::Key1 => x11::keysym::XK_1, VirtualKeyCode::One => x11::keysym::XK_1,
VirtualKeyCode::Key2 => x11::keysym::XK_2, VirtualKeyCode::Two => x11::keysym::XK_2,
VirtualKeyCode::Key3 => x11::keysym::XK_3, VirtualKeyCode::Three => x11::keysym::XK_3,
VirtualKeyCode::Key4 => x11::keysym::XK_4, VirtualKeyCode::Four => x11::keysym::XK_4,
VirtualKeyCode::Key5 => x11::keysym::XK_5, VirtualKeyCode::Five => x11::keysym::XK_5,
VirtualKeyCode::Key6 => x11::keysym::XK_6, VirtualKeyCode::Six => x11::keysym::XK_6,
VirtualKeyCode::Key7 => x11::keysym::XK_7, VirtualKeyCode::Seven => x11::keysym::XK_7,
VirtualKeyCode::Key8 => x11::keysym::XK_8, VirtualKeyCode::Eight => x11::keysym::XK_8,
VirtualKeyCode::Key9 => x11::keysym::XK_9, VirtualKeyCode::Nine => x11::keysym::XK_9,
VirtualKeyCode::Colon => x11::keysym::XK_colon, VirtualKeyCode::Colon => x11::keysym::XK_colon,
VirtualKeyCode::Semicolon => x11::keysym::XK_semicolon, VirtualKeyCode::Semicolon => x11::keysym::XK_semicolon,
//VirtualKeyCode::Less => x11::keysym::XK_less, //VirtualKeyCode::Less => x11::keysym::XK_less,

View file

@ -252,11 +252,11 @@ impl WindowServerBackend for XLib {
todo!() todo!()
} }
fn move_window(&self, window: Self::Window, pos: i32) { fn move_window(&self, window: Self::Window, new_pos: (i32, i32)) {
todo!() todo!()
} }
fn resize_window(&self, window: Self::Window, pos: i32) { fn resize_window(&self, window: Self::Window, new_pos: (i32, i32)) {
todo!() todo!()
} }
@ -271,6 +271,22 @@ impl WindowServerBackend for XLib {
fn kill_window(&self, window: Self::Window) { fn kill_window(&self, window: Self::Window) {
todo!() todo!()
} }
fn raise_window(&self, window: Self::Window) {
todo!()
}
fn get_parent_window(&self, window: Self::Window) -> Option<Self::Window> {
todo!()
}
fn get_window_size(&self, window: Self::Window) -> Option<(i32, i32)> {
todo!()
}
fn new() -> Self {
todo!()
}
} }
struct XLibAtoms { struct XLibAtoms {

View file

@ -1,3 +1,5 @@
#![allow(dead_code, unused_variables)]
use log::{debug, error, info, trace, warn}; use log::{debug, error, info, trace, warn};
use log4rs::{ use log4rs::{
append::{console::ConsoleAppender, file::FileAppender}, append::{console::ConsoleAppender, file::FileAppender},
@ -67,7 +69,8 @@ fn main() {
log_prologue(); log_prologue();
state::WindowManager::new(WMConfig::default()).run(); state::WindowManager::<backends::xlib::XLib>::new(WMConfig::default())
.run();
} }
fn log_prologue() { fn log_prologue() {

View file

@ -3,19 +3,24 @@ use std::rc::Rc;
use log::{error, info}; use log::{error, info};
use x11::xlib::{ use x11::xlib::{
self, Mod4Mask, ShiftMask, Window, XButtonPressedEvent, self, Window, XButtonPressedEvent, XButtonReleasedEvent, XEvent, XKeyEvent,
XButtonReleasedEvent, XEvent, XKeyEvent, XMotionEvent, XMotionEvent,
}; };
use xlib::{ use xlib::{
ButtonPressMask, ButtonReleaseMask, PointerMotionMask,
XConfigureRequestEvent, XCrossingEvent, XDestroyWindowEvent, XConfigureRequestEvent, XCrossingEvent, XDestroyWindowEvent,
XMapRequestEvent, XUnmapEvent, XMapRequestEvent, XUnmapEvent,
}; };
use crate::{ use crate::{
clients::{Client, ClientEntry, ClientKey, ClientState}, backends::{
xlib::KeyOrButton, keycodes::{MouseButton, VirtualKeyCode},
window_event::{
ButtonEvent, KeyBind, KeyEvent, ModifierKey, ModifierState,
},
xlib::XLib, xlib::XLib,
WindowServerBackend,
},
clients::{Client, ClientEntry, ClientKey, ClientState},
}; };
/** /**
@ -24,15 +29,18 @@ be able to configure in a config file.
*/ */
pub struct WMConfig { pub struct WMConfig {
num_virtualscreens: usize, num_virtualscreens: usize,
mod_key: u32, mod_key: ModifierKey,
gap: Option<i32>, gap: Option<i32>,
} }
pub struct WindowManager { pub struct WindowManager<B = XLib>
where
B: WindowServerBackend,
{
clients: ClientState, clients: ClientState,
move_resize_window: MoveResizeInfo, move_resize_window: MoveResizeInfo,
keybinds: Vec<KeyBinding>, keybinds: Vec<KeyBinding<B>>,
xlib: XLib, backend: B,
config: WMConfig, config: WMConfig,
} }
@ -64,50 +72,71 @@ struct ResizeInfoInner {
} }
#[derive(Clone)] #[derive(Clone)]
struct KeyBinding { struct KeyBinding<B: WindowServerBackend> {
key: KeyOrButton, key: KeyBind,
closure: Rc<dyn Fn(&mut WindowManager, &XKeyEvent)>, closure: Rc<dyn Fn(&mut WindowManager<B>, &KeyEvent<B::Window>)>,
} }
impl WindowManager { impl<B: WindowServerBackend> KeyBinding<B> {
pub fn new<F>(key: KeyBind, cb: F) -> Self
where
F: Fn(&mut WindowManager<B>, &KeyEvent<B::Window>),
F: 'static,
{
Self {
key,
closure: Rc::new(cb),
}
}
pub fn call(&self, wm: &mut WindowManager<B>, ev: &KeyEvent<B::Window>) {
(self.closure)(wm, ev);
}
}
impl<B> WindowManager<B>
where
B: WindowServerBackend<Window = xlib::Window>,
{
pub fn new(config: WMConfig) -> Self { pub fn new(config: WMConfig) -> Self {
let xlib = XLib::new(); let backend = B::new();
let clients = ClientState::new() let clients = ClientState::new()
.with_virtualscreens(config.num_virtualscreens) .with_virtualscreens(config.num_virtualscreens)
.with_gap(config.gap.unwrap_or(1)) .with_gap(config.gap.unwrap_or(1))
.with_border(1) .with_border(1)
.with_screen_size(xlib.dimensions()); .with_screen_size(backend.screen_size());
Self { Self {
clients, clients,
move_resize_window: MoveResizeInfo::None, move_resize_window: MoveResizeInfo::None,
keybinds: Vec::new(), keybinds: Vec::new(),
xlib, backend,
config, config,
} }
.init() .init()
} }
fn init(mut self) -> Self { fn init(mut self) -> Self {
self.xlib.add_global_keybind(KeyOrButton::button( // TODO: fix keybinds for moving windows and stuff
1, // self.xlib.add_global_keybind(KeyOrButton::button(
self.config.mod_key, // 1,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // self.config.mod_key,
)); // ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
self.xlib.add_global_keybind(KeyOrButton::button( // ));
2, // self.xlib.add_global_keybind(KeyOrButton::button(
self.config.mod_key, // 2,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // self.config.mod_key,
)); // ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
self.xlib.add_global_keybind(KeyOrButton::button( // ));
3, // self.xlib.add_global_keybind(KeyOrButton::button(
self.config.mod_key, // 3,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // self.config.mod_key,
)); // ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
// ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("P", self.config.mod_key), KeyBind::new(VirtualKeyCode::P).with_mod(self.config.mod_key),
|wm, _| { |wm, _| {
wm.spawn( wm.spawn(
"dmenu_run", "dmenu_run",
@ -130,22 +159,22 @@ impl WindowManager {
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Print", 0), KeyBind::new(VirtualKeyCode::Snapshot),
|wm, _| wm.spawn("screenshot.sh", &[]), |wm, _| wm.spawn("screenshot.sh", &[]),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Print", ShiftMask), KeyBind::new(VirtualKeyCode::Snapshot).with_mod(ModifierKey::Shift),
|wm, _| wm.spawn("screenshot.sh", &["-edit"]), |wm, _| wm.spawn("screenshot.sh", &["-edit"]),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("M", self.config.mod_key), KeyBind::new(VirtualKeyCode::M).with_mod(self.config.mod_key),
Self::handle_switch_stack, |wm, _| wm.handle_switch_stack(),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("F", self.config.mod_key), KeyBind::new(VirtualKeyCode::F).with_mod(self.config.mod_key),
|wm, _| { |wm, _| {
wm.clients wm.clients
.get_focused() .get_focused()
@ -158,45 +187,50 @@ impl WindowManager {
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Q", self.config.mod_key), KeyBind::new(VirtualKeyCode::Q).with_mod(self.config.mod_key),
Self::kill_client, |wm, _| wm.kill_client(),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Q", self.config.mod_key | ShiftMask), KeyBind::new(VirtualKeyCode::Q)
.with_mod(self.config.mod_key)
.with_mod(ModifierKey::Shift),
|wm, _| wm.quit(), |wm, _| wm.quit(),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib KeyBind::new(VirtualKeyCode::Return)
.make_key("Return", self.config.mod_key | ShiftMask), .with_mod(self.config.mod_key)
.with_mod(ModifierKey::Shift),
|wm, _| wm.spawn("alacritty", &[]), |wm, _| wm.spawn("alacritty", &[]),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("J", self.config.mod_key), KeyBind::new(VirtualKeyCode::J).with_mod(self.config.mod_key),
|wm, _| wm.move_focus(Direction::south()), |wm, _| wm.move_focus(Direction::south()),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("K", self.config.mod_key), KeyBind::new(VirtualKeyCode::K).with_mod(self.config.mod_key),
|wm, _| wm.move_focus(Direction::north()), |wm, _| wm.move_focus(Direction::north()),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("H", self.config.mod_key), KeyBind::new(VirtualKeyCode::H).with_mod(self.config.mod_key),
|wm, _| wm.move_focus(Direction::west()), |wm, _| wm.move_focus(Direction::west()),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("L", self.config.mod_key), KeyBind::new(VirtualKeyCode::L).with_mod(self.config.mod_key),
|wm, _| wm.move_focus(Direction::east()), |wm, _| wm.move_focus(Direction::east()),
)); ));
// resize master stack // resize master stack
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("K", self.config.mod_key | ShiftMask), KeyBind::new(VirtualKeyCode::K)
.with_mod(self.config.mod_key)
.with_mod(ModifierKey::Shift),
|wm, _| { |wm, _| {
wm.clients.change_master_size(0.1); wm.clients.change_master_size(0.1);
wm.arrange_clients(); wm.arrange_clients();
@ -204,7 +238,9 @@ impl WindowManager {
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("J", self.config.mod_key | ShiftMask), KeyBind::new(VirtualKeyCode::J)
.with_mod(self.config.mod_key)
.with_mod(ModifierKey::Shift),
|wm, _| { |wm, _| {
wm.clients.change_master_size(-0.1); wm.clients.change_master_size(-0.1);
wm.arrange_clients(); wm.arrange_clients();
@ -213,53 +249,45 @@ impl WindowManager {
self.add_vs_switch_keybinds(); self.add_vs_switch_keybinds();
self.xlib.init(); //self.xlib.init();
self self
} }
fn add_keybind(&mut self, keybind: KeyBinding) { fn add_keybind(&mut self, keybind: KeyBinding<B>) {
self.xlib.add_global_keybind(keybind.key); //self.xlib.add_global_keybind(keybind.key);
self.keybinds.push(keybind); self.keybinds.push(keybind);
} }
fn add_vs_switch_keybinds(&mut self) { fn add_vs_switch_keybinds(&mut self) {
fn rotate_west<const N: usize>(wm: &mut WindowManager, _: &XKeyEvent) {
wm.rotate_virtual_screen(Direction::West(N));
}
fn rotate_east<const N: usize>(wm: &mut WindowManager, _: &XKeyEvent) {
wm.rotate_virtual_screen(Direction::East(N));
}
fn goto_nth<const N: usize>(wm: &mut WindowManager, _: &XKeyEvent) {
wm.go_to_nth_virtual_screen(N)
}
// Old keybinds // Old keybinds
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Left", self.config.mod_key), KeyBind::new(VirtualKeyCode::Left).with_mod(self.config.mod_key),
rotate_west::<1>, |wm, _| wm.rotate_virtual_screen(Direction::West(1)),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("H", self.config.mod_key | ShiftMask), KeyBind::new(VirtualKeyCode::H)
rotate_west::<1>, .with_mod(self.config.mod_key)
.with_mod(ModifierKey::Shift),
|wm, _| wm.rotate_virtual_screen(Direction::West(1)),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Right", self.config.mod_key), KeyBind::new(VirtualKeyCode::Right).with_mod(self.config.mod_key),
rotate_east::<1>, |wm, _| wm.rotate_virtual_screen(Direction::East(1)),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("L", self.config.mod_key | ShiftMask), KeyBind::new(VirtualKeyCode::L)
rotate_east::<1>, .with_mod(self.config.mod_key)
.with_mod(ModifierKey::Shift),
|wm, _| wm.rotate_virtual_screen(Direction::East(1)),
)); ));
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("Tab", self.config.mod_key), KeyBind::new(VirtualKeyCode::Tab).with_mod(self.config.mod_key),
|wm, _| wm.rotate_virtual_screen_back(), |wm, _| wm.rotate_virtual_screen_back(),
)); ));
@ -267,79 +295,80 @@ impl WindowManager {
// Press Mod + `1` to move go to the `1`th virtual screen // Press Mod + `1` to move go to the `1`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("1", self.config.mod_key), KeyBind::new(VirtualKeyCode::One).with_mod(self.config.mod_key),
goto_nth::<1>, |wm, _| wm.go_to_nth_virtual_screen(1),
)); ));
// Press Mod + `2` to move go to the `2`th virtual screen // Press Mod + `2` to move go to the `2`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("2", self.config.mod_key), KeyBind::new(VirtualKeyCode::Two).with_mod(self.config.mod_key),
goto_nth::<2>, |wm, _| wm.go_to_nth_virtual_screen(2),
)); ));
// Press Mod + `3` to move go to the `3`th virtual screen // Press Mod + `3` to move go to the `3`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("3", self.config.mod_key), KeyBind::new(VirtualKeyCode::Three).with_mod(self.config.mod_key),
goto_nth::<3>, |wm, _| wm.go_to_nth_virtual_screen(3),
)); ));
// Press Mod + `4` to move go to the `4`th virtual screen // Press Mod + `4` to move go to the `4`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("4", self.config.mod_key), KeyBind::new(VirtualKeyCode::Four).with_mod(self.config.mod_key),
goto_nth::<4>, |wm, _| wm.go_to_nth_virtual_screen(4),
)); ));
// Press Mod + `5` to move go to the `5`th virtual screen // Press Mod + `5` to move go to the `5`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("5", self.config.mod_key), KeyBind::new(VirtualKeyCode::Five).with_mod(self.config.mod_key),
goto_nth::<5>, |wm, _| wm.go_to_nth_virtual_screen(5),
)); ));
// Press Mod + `6` to move go to the `6`th virtual screen // Press Mod + `6` to move go to the `6`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("6", self.config.mod_key), KeyBind::new(VirtualKeyCode::Six).with_mod(self.config.mod_key),
goto_nth::<6>, |wm, _| wm.go_to_nth_virtual_screen(6),
)); ));
// Press Mod + `7` to move go to the `7`th virtual screen // Press Mod + `7` to move go to the `7`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("7", self.config.mod_key), KeyBind::new(VirtualKeyCode::Seven).with_mod(self.config.mod_key),
goto_nth::<7>, |wm, _| wm.go_to_nth_virtual_screen(7),
)); ));
// Press Mod + `8` to move go to the `8`th virtual screen // Press Mod + `8` to move go to the `8`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("8", self.config.mod_key), KeyBind::new(VirtualKeyCode::Eight).with_mod(self.config.mod_key),
goto_nth::<8>, |wm, _| wm.go_to_nth_virtual_screen(8),
)); ));
// Press Mod + `9` to move go to the `9`th virtual screen // Press Mod + `9` to move go to the `9`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("9", self.config.mod_key), KeyBind::new(VirtualKeyCode::Nine).with_mod(self.config.mod_key),
goto_nth::<9>, |wm, _| wm.go_to_nth_virtual_screen(9),
)); ));
// Press Mod + `0` to move go to the `0`th virtual screen // Press Mod + `0` to move go to the `0`th virtual screen
self.add_keybind(KeyBinding::new( self.add_keybind(KeyBinding::new(
self.xlib.make_key("0", self.config.mod_key), KeyBind::new(VirtualKeyCode::Zero).with_mod(self.config.mod_key),
goto_nth::<10>, |wm, _| wm.go_to_nth_virtual_screen(10),
)); ));
} }
#[allow(unused_mut)]
pub fn run(mut self) -> ! { pub fn run(mut self) -> ! {
loop { loop {
let event = self.xlib.next_event(); let event = self.backend.next_event();
match event.get_type() { match event {
xlib::MapRequest => self.map_request(&event), // xlib::MapRequest => self.map_request(&event),
xlib::UnmapNotify => self.unmap_notify(&event), // xlib::UnmapNotify => self.unmap_notify(&event),
xlib::ConfigureRequest => self.configure_request(&event), // xlib::ConfigureRequest => self.configure_request(&event),
xlib::EnterNotify => self.enter_notify(&event), // xlib::EnterNotify => self.enter_notify(&event),
xlib::DestroyNotify => self.destroy_notify(&event), // xlib::DestroyNotify => self.destroy_notify(&event),
xlib::ButtonPress => self.button_press(event.as_ref()), // xlib::ButtonPress => self.button_press(event.as_ref()),
xlib::ButtonRelease => self.button_release(event.as_ref()), // xlib::ButtonRelease => self.button_release(event.as_ref()),
xlib::MotionNotify => self.motion_notify(event.as_ref()), // xlib::MotionNotify => self.motion_notify(event.as_ref()),
xlib::KeyPress => self.handle_keybinds(event.as_ref()), // xlib::KeyPress => self.handle_keybinds(event.as_ref()),
_ => {} _ => {}
} }
} }
@ -351,27 +380,28 @@ impl WindowManager {
std::process::exit(0); std::process::exit(0);
} }
fn kill_client(&mut self, _event: &XKeyEvent) { fn kill_client(&mut self) {
if let Some(client) = self.clients.get_focused().into_option() { if let Some(client) = self.clients.get_focused().into_option() {
self.xlib.kill_client(client); //self.xlib.kill_client(client);
} }
} }
// TODO: change this somehow cuz I'm not a big fan of this "hardcoded" keybind stuff // TODO: change this somehow cuz I'm not a big fan of this "hardcoded" keybind stuff
fn handle_keybinds(&mut self, event: &XKeyEvent) { fn handle_keybinds(&mut self, event: &XKeyEvent) {
let clean_mask = self.xlib.get_clean_mask(); //let clean_mask = self.xlib.get_clean_mask();
for kb in self.keybinds.clone().into_iter() { // TODO: Fix this
if let KeyOrButton::Key(keycode, modmask) = kb.key { // for kb in self.keybinds.clone().into_iter() {
if keycode as u32 == event.keycode // if let KeyOrButton::Key(keycode, modmask) = kb.key {
&& modmask & clean_mask == event.state & clean_mask // if keycode as u32 == event.keycode
{ // && modmask & clean_mask == event.state & clean_mask
(kb.closure)(self, event); // {
} // (kb.closure)(self, event);
} // }
} // }
// }
} }
fn handle_switch_stack(&mut self, _event: &XKeyEvent) { fn handle_switch_stack(&mut self) {
if let Some(client) = if let Some(client) =
self.clients.get_focused().into_option().map(|c| c.key()) self.clients.get_focused().into_option().map(|c| c.key())
{ {
@ -506,22 +536,23 @@ impl WindowManager {
fn hide_hidden_clients(&self) { fn hide_hidden_clients(&self) {
self.clients self.clients
.iter_hidden() .iter_hidden()
.for_each(|(_, c)| self.xlib.hide_client(c)); .for_each(|(_, c)| self.backend.hide_window(c.window));
} }
fn raise_floating_clients(&self) { fn raise_floating_clients(&self) {
self.clients self.clients
.iter_floating() .iter_floating()
.for_each(|(_, c)| self.xlib.raise_client(c)); .for_each(|(_, c)| self.backend.raise_window(c.window));
self.clients self.clients
.iter_transient() .iter_transient()
.for_each(|(_, c)| self.xlib.raise_client(c)); .for_each(|(_, c)| self.backend.raise_window(c.window));
} }
fn arrange_clients(&mut self) { fn arrange_clients(&mut self) {
self.clients.iter_visible().for_each(|(_, c)| { self.clients.iter_visible().for_each(|(_, c)| {
self.xlib.move_resize_client(c); self.backend.move_window(c.window, c.position);
self.backend.resize_window(c.window, c.size);
//self.xlib.expose_client(c); //self.xlib.expose_client(c);
}); });
@ -546,19 +577,19 @@ impl WindowManager {
let (new, old) = self.clients.focus_client(key); let (new, old) = self.clients.focus_client(key);
if let Some(old) = old.into_option() { if let Some(old) = old.into_option() {
self.xlib.unfocus_client(old); self.backend.unfocus_window(old.window);
} }
match new { match new {
ClientEntry::Floating(new) => { ClientEntry::Floating(new) => {
self.xlib.focus_client(new); self.backend.focus_window(new.window);
if try_raise { if try_raise {
self.xlib.raise_client(new); self.backend.raise_window(new.window);
} }
} }
ClientEntry::Tiled(new) => { ClientEntry::Tiled(new) => {
self.xlib.focus_client(new); self.backend.focus_window(new.window);
} }
_ => {} _ => {}
} }
@ -567,23 +598,23 @@ impl WindowManager {
fn new_client(&mut self, window: Window) { fn new_client(&mut self, window: Window) {
info!("new client: {:?}", window); info!("new client: {:?}", window);
let client = if let Some(transient_window) = let client = if let Some(transient_window) =
self.xlib.get_transient_for_window(window) self.backend.get_parent_window(window)
{ {
Client::new_transient( Client::new_transient(
window, window,
self.xlib.get_window_size(window).unwrap_or((100, 100)), self.backend.get_window_size(window).unwrap_or((100, 100)),
transient_window, transient_window,
) )
} else { } else {
Client::new_default(window) Client::new_default(window)
}; };
self.xlib //self.xlib
.configure_client(&client, self.clients.get_border()); //.configure_client(&client, self.clients.get_border());
self.clients.insert(client).unwrap(); self.clients.insert(client).unwrap();
self.arrange_clients(); self.arrange_clients();
self.xlib.map_window(window); //self.xlib.map_window(window);
self.focus_client(&window, true); self.focus_client(&window, true);
} }
@ -615,12 +646,12 @@ impl WindowManager {
fn configure_request(&mut self, event: &XEvent) { fn configure_request(&mut self, event: &XEvent) {
let event: &XConfigureRequestEvent = event.as_ref(); let event: &XConfigureRequestEvent = event.as_ref();
match self.clients.get(&event.window).into_option() { // match self.clients.get(&event.window).into_option() {
Some(client) => self // Some(client) => self
.xlib // .xlib
.configure_client(client, self.clients.get_border()), // .configure_client(client, self.clients.get_border()),
None => self.xlib.configure_window(event), // None => self.xlib.configure_window(event),
} // }
} }
fn enter_notify(&mut self, event: &XEvent) { fn enter_notify(&mut self, event: &XEvent) {
@ -663,8 +694,9 @@ impl WindowManager {
) )
}; };
self.xlib.move_cursor(None, corner_pos); // TODO fix backend cursor api
self.xlib.grab_cursor(); //self.xlib.move_cursor(None, corner_pos);
//self.xlib.grab_cursor();
self.move_resize_window = self.move_resize_window =
MoveResizeInfo::Resize(ResizeInfoInner { MoveResizeInfo::Resize(ResizeInfoInner {
@ -682,7 +714,8 @@ impl WindowManager {
self.move_resize_window = MoveResizeInfo::None; self.move_resize_window = MoveResizeInfo::None;
} }
if event.button == 3 { if event.button == 3 {
self.xlib.release_cursor(); // TODO fix backend cursor api
//self.xlib.release_cursor();
} }
} }
@ -702,7 +735,7 @@ impl WindowManager {
position.0 = info.starting_window_pos.0 + x; position.0 = info.starting_window_pos.0 + x;
position.1 = info.starting_window_pos.1 + y; position.1 = info.starting_window_pos.1 + y;
self.xlib.move_client(client); self.backend.move_window(client.window, client.position);
} }
} }
MoveResizeInfo::Resize(info) => { MoveResizeInfo::Resize(info) => {
@ -719,30 +752,31 @@ impl WindowManager {
size.0 = std::cmp::max(1, info.starting_window_size.0 + x); size.0 = std::cmp::max(1, info.starting_window_size.0 + x);
size.1 = std::cmp::max(1, info.starting_window_size.1 + y); size.1 = std::cmp::max(1, info.starting_window_size.1 + y);
self.xlib.resize_client(client); self.backend.resize_window(client.window, client.size);
} }
} }
_ => {} _ => {}
} }
} }
fn button_press(&mut self, event: &XButtonPressedEvent) { fn button_press(&mut self, event: &ButtonEvent<B::Window>) {
self.focus_client(&event.subwindow, true); self.focus_client(&event.window, true);
match event.button { match event.keycode {
1 | 3 => match self.move_resize_window { MouseButton::Left | MouseButton::Right => {
match self.move_resize_window {
MoveResizeInfo::None MoveResizeInfo::None
if self if ModifierState::from([self.config.mod_key])
.xlib .eq_ignore_lock(&event.modifierstate)
.are_masks_equal(event.state, self.config.mod_key) && self.clients.contains(&event.window) =>
&& self.clients.contains(&event.subwindow) =>
{ {
self.start_move_resize_window(event) //self.start_move_resize_window(event)
} }
_ => {} _ => {}
}, }
2 => { }
self.clients.toggle_floating(&event.subwindow); MouseButton::Middle => {
self.clients.toggle_floating(&event.window);
self.arrange_clients(); self.arrange_clients();
} }
_ => {} _ => {}
@ -773,23 +807,11 @@ impl WindowManager {
} }
} }
impl KeyBinding {
fn new<F>(key: KeyOrButton, closure: F) -> Self
where
F: Fn(&mut WindowManager, &XKeyEvent) + 'static,
{
Self {
key,
closure: Rc::new(closure),
}
}
}
impl Default for WMConfig { impl Default for WMConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
num_virtualscreens: 10, num_virtualscreens: 10,
mod_key: Mod4Mask, mod_key: ModifierKey::Super,
gap: Some(2), gap: Some(2),
} }
} }