diff --git a/src/backends/window_event.rs b/src/backends/window_event.rs index 4f21875..89a7867 100644 --- a/src/backends/window_event.rs +++ b/src/backends/window_event.rs @@ -18,7 +18,7 @@ pub enum WindowEvent { FullscreenEvent(FullscreenEvent), //1 { window: Window, event: 1 }, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum KeyState { Pressed, Released, @@ -55,7 +55,7 @@ impl From<[ModifierKey; N]> for ModifierState { fn from(slice: [ModifierKey; N]) -> Self { let mut state = ModifierState::empty(); for ele in slice { - state.set_mod(ele); + state.insert_mod(ele); } state @@ -69,32 +69,31 @@ impl ModifierState { } pub fn with_mod(mut self, modifier: ModifierKey) -> Self { - self.set_mod(modifier); + self.insert_mod(modifier); self } pub fn unset_mod(&mut self, modifier: ModifierKey) { - match modifier { - ModifierKey::Shift => self.remove(Self::SHIFT), - ModifierKey::ShiftLock => self.remove(Self::SHIFT_LOCK), - ModifierKey::Control => self.remove(Self::CONTROL), - ModifierKey::Alt => self.remove(Self::ALT), - ModifierKey::AltGr => self.remove(Self::ALT_GR), - ModifierKey::Super => self.remove(Self::SUPER), - ModifierKey::NumLock => self.remove(Self::NUM_LOCK), - } + self.set_mod(modifier, false); } - pub fn set_mod(&mut self, modifier: ModifierKey) { - match modifier { - ModifierKey::Shift => self.insert(Self::SHIFT), - ModifierKey::ShiftLock => self.insert(Self::SHIFT_LOCK), - ModifierKey::Control => self.insert(Self::CONTROL), - ModifierKey::Alt => self.insert(Self::ALT), - ModifierKey::AltGr => self.insert(Self::ALT_GR), - ModifierKey::Super => self.insert(Self::SUPER), - ModifierKey::NumLock => self.insert(Self::NUM_LOCK), - } + pub fn set_mod(&mut self, modifier: ModifierKey, state: bool) { + self.set( + match modifier { + ModifierKey::Shift => Self::SHIFT, + ModifierKey::ShiftLock => Self::SHIFT_LOCK, + ModifierKey::Control => Self::CONTROL, + ModifierKey::Alt => Self::ALT, + ModifierKey::AltGr => Self::ALT_GR, + ModifierKey::Super => Self::SUPER, + ModifierKey::NumLock => Self::NUM_LOCK, + }, + state, + ); + } + + pub fn insert_mod(&mut self, modifier: ModifierKey) { + self.set_mod(modifier, true); } } @@ -294,7 +293,7 @@ impl KeyBind { } pub fn with_mod(mut self, modifier_key: ModifierKey) -> Self { - self.modifiers.set_mod(modifier_key); + self.modifiers.insert_mod(modifier_key); self } } @@ -314,7 +313,7 @@ impl MouseBind { } pub fn with_mod(mut self, modifier_key: ModifierKey) -> Self { - self.modifiers.set_mod(modifier_key); + self.modifiers.insert_mod(modifier_key); self } } @@ -334,7 +333,7 @@ impl KeyOrMouseBind { } pub fn with_mod(mut self, modifier_key: ModifierKey) -> Self { - self.modifiers.set_mod(modifier_key); + self.modifiers.insert_mod(modifier_key); self } } diff --git a/src/backends/xlib/mod.rs b/src/backends/xlib/mod.rs index dbab7ef..0ce1446 100644 --- a/src/backends/xlib/mod.rs +++ b/src/backends/xlib/mod.rs @@ -1,5 +1,5 @@ #![allow(unused_variables, dead_code)] -use log::{error, warn}; +use log::{debug, error, warn}; use std::{ffi::CString, rc::Rc}; use thiserror::Error; @@ -13,13 +13,17 @@ use crate::backends::{ xlib::keysym::mouse_button_to_xbutton, }; -use self::keysym::{virtual_keycode_to_keysym, xev_to_mouse_button, XKeySym}; +use self::keysym::{ + keysym_to_virtual_keycode, virtual_keycode_to_keysym, xev_to_mouse_button, + XKeySym, +}; use super::{ keycodes::VirtualKeyCode, window_event::{ - ButtonEvent, ConfigureEvent, DestroyEvent, EnterEvent, KeyOrMouseBind, - KeyState, MapEvent, ModifierState, Point, UnmapEvent, WindowEvent, + ButtonEvent, ConfigureEvent, DestroyEvent, EnterEvent, KeyEvent, + KeyOrMouseBind, KeyState, MapEvent, ModifierState, MotionEvent, Point, + UnmapEvent, WindowEvent, }, WindowServerBackend, }; @@ -152,7 +156,7 @@ impl XLib { fn new() -> Self { let (display, screen, root) = { let display = unsafe { xlib::XOpenDisplay(std::ptr::null()) }; - assert_eq!(display, std::ptr::null_mut()); + assert_ne!(display, std::ptr::null_mut()); let screen = unsafe { xlib::XDefaultScreen(display) }; let root = unsafe { xlib::XRootWindow(display, screen) }; @@ -215,14 +219,14 @@ impl XLib { event.assume_init() }; - match event.get_type() { - xlib::KeyPress | xlib::KeyRelease => { - self.update_modifier_state(AsRef::::as_ref( - &event, - )); - } - _ => {} - } + // match event.get_type() { + // xlib::KeyPress | xlib::KeyRelease => { + // self.update_modifier_state(AsRef::::as_ref( + // &event, + // )); + // } + // _ => {} + // } event } @@ -261,27 +265,51 @@ impl XLib { window: ev.window, })) } + xlib::MotionNotify => { + let ev = unsafe { &event.motion }; + Some(XLibWindowEvent::MotionEvent(MotionEvent { + position: (ev.x, ev.y).into(), + window: ev.window, + })) + } // both ButtonPress and ButtonRelease use the XButtonEvent structure, aliased as either // XButtonReleasedEvent or XButtonPressedEvent xlib::ButtonPress | xlib::ButtonRelease => { let ev = unsafe { &event.button }; let keycode = xev_to_mouse_button(ev).unwrap(); - let state = if ev.state as i32 == xlib::ButtonPress { + let state = if ev.type_ == xlib::ButtonPress { KeyState::Pressed } else { KeyState::Released }; - let modifierstate = ModifierState::empty(); - Some(XLibWindowEvent::ButtonEvent(ButtonEvent::new( ev.subwindow, state, keycode, (ev.x, ev.y).into(), - modifierstate, + ModifierState::from_modmask(ev.state), ))) } + xlib::KeyPress | xlib::KeyRelease => { + let ev = unsafe { &event.key }; + let keycode = + keysym_to_virtual_keycode(self.keyev_to_keysym(ev).get()); + let state = if ev.type_ == xlib::KeyPress { + KeyState::Pressed + } else { + KeyState::Released + }; + + keycode.map(|keycode| { + XLibWindowEvent::KeyEvent(KeyEvent::new( + ev.subwindow, + state, + keycode, + ModifierState::from_modmask(ev.state), + )) + }) + } _ => None, } } @@ -387,7 +415,7 @@ impl XLib { if let Some(modifier) = modifier { match keyevent.type_ { - KeyPress => self.modifier_state.set_mod(modifier), + KeyPress => self.modifier_state.insert_mod(modifier), KeyRelease => self.modifier_state.unset_mod(modifier), _ => unreachable!("keyyevent != (KeyPress | KeyRelease)"), } @@ -545,6 +573,7 @@ impl XLib { trait ModifierStateExt { fn as_modmask(&self, xlib: &XLib) -> u32; + fn from_modmask(modmask: u32) -> Self; } impl ModifierStateExt for ModifierState { @@ -555,15 +584,30 @@ impl ModifierStateExt for ModifierState { .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 |= 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::Mod2Mask * u32::from(self.contains(Self::NUM_LOCK)); + //mask |= xlib::Mod3Mask * u32::from(self.contains(Self::ALT_GR)); + mask |= xlib::Mod4Mask * u32::from(self.contains(Self::SUPER)); + //mask |= numlock_mask * u32::from(self.contains(Self::NUM_LOCK)); mask } + + fn from_modmask(modmask: u32) -> Self { + let mut state = Self::empty(); + state.set(Self::SHIFT, (modmask & xlib::ShiftMask) != 0); + //state.set(Self::SHIFT_LOCK, (modmask & xlib::LockMask) != 0); + state.set(Self::CONTROL, (modmask & xlib::ControlMask) != 0); + state.set(Self::ALT, (modmask & xlib::Mod1Mask) != 0); + //state.set(Self::NUM_LOCK, (modmask & xlib::Mod2Mask) != 0); + state.set(Self::ALT_GR, (modmask & xlib::Mod3Mask) != 0); + state.set(Self::SUPER, (modmask & xlib::Mod4Mask) != 0); + + state + } } impl WindowServerBackend for XLib { @@ -576,12 +620,14 @@ impl WindowServerBackend for XLib { } fn next_event(&mut self) -> super::window_event::WindowEvent { - std::iter::from_fn(|| { + loop { let ev = self.next_xevent(); - self.xevent_to_window_event(ev) - }) - .next() - .unwrap() + let ev = self.xevent_to_window_event(ev); + + if let Some(ev) = ev { + return ev; + } + } } fn handle_event( @@ -700,7 +746,6 @@ impl WindowServerBackend for XLib { xlib::XKillClient(self.dpy(), window); } } - todo!() } fn get_parent_window(&self, window: Self::Window) -> Option { diff --git a/src/state.rs b/src/state.rs index cdacae0..be63222 100644 --- a/src/state.rs +++ b/src/state.rs @@ -58,12 +58,14 @@ enum MoveResizeInfo { None, } +#[derive(Debug)] struct MoveInfoInner { window: Window, starting_cursor_pos: Point, starting_window_pos: Point, } +#[derive(Debug)] struct ResizeInfoInner { window: Window, starting_cursor_pos: Point, @@ -160,12 +162,12 @@ where )); self.add_keybind(KeyBinding::new( - KeyBind::new(VirtualKeyCode::Snapshot), + KeyBind::new(VirtualKeyCode::Print), |wm, _| wm.spawn("screenshot.sh", &[]), )); self.add_keybind(KeyBinding::new( - KeyBind::new(VirtualKeyCode::Snapshot).with_mod(ModifierKey::Shift), + KeyBind::new(VirtualKeyCode::Print).with_mod(ModifierKey::Shift), |wm, _| wm.spawn("screenshot.sh", &["-edit"]), )); @@ -250,8 +252,6 @@ where self.add_vs_switch_keybinds(); - //self.xlib.init(); - self } @@ -421,14 +421,16 @@ where // TODO: change this somehow cuz I'm not a big fan of this "hardcoded" keybind stuff fn handle_keybinds(&mut self, event: &KeyEvent) { - // I'm not sure if this has to be a Rc> or if it would be better as a Cell<> - let keybinds = self.keybinds.clone(); + if event.state == KeyState::Released { + // I'm not sure if this has to be a Rc> or if it would be better as a Cell<> + let keybinds = self.keybinds.clone(); - for kb in keybinds.borrow().iter() { - if kb.key.key == event.keycode - && kb.key.modifiers == event.modifierstate - { - kb.call(self, event); + for kb in keybinds.borrow().iter() { + if kb.key.key == event.keycode + && kb.key.modifiers == event.modifierstate + { + kb.call(self, event); + } } } } @@ -761,6 +763,8 @@ where fn do_move_resize_window(&mut self, event: &MotionEvent) { match &self.move_resize_window { MoveResizeInfo::Move(info) => { + info!("do_move: {:#?}", info); + let (x, y) = ( event.position.x - info.starting_cursor_pos.x, event.position.y - info.starting_cursor_pos.y, @@ -778,6 +782,8 @@ where } } MoveResizeInfo::Resize(info) => { + info!("do_resize: {:#?}", info); + let (x, y) = ( event.position.x - info.starting_cursor_pos.x, event.position.y - info.starting_cursor_pos.y,