From b47f245250e700e41f4051ad527d99cafe9a4888 Mon Sep 17 00:00:00 2001
From: Janis <janis@nirgendwo.xyz>
Date: Sun, 28 Nov 2021 19:11:16 +0100
Subject: [PATCH] seems to work now :^)

---
 src/backends/window_event.rs |  49 ++++++++--------
 src/backends/xlib/mod.rs     | 105 +++++++++++++++++++++++++----------
 src/state.rs                 |  28 ++++++----
 3 files changed, 116 insertions(+), 66 deletions(-)

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<Window> {
     FullscreenEvent(FullscreenEvent<Window>), //1 { window: Window, event: 1 },
 }
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
 pub enum KeyState {
     Pressed,
     Released,
@@ -55,7 +55,7 @@ impl<const N: usize> 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::<xlib::XKeyEvent>::as_ref(
-                    &event,
-                ));
-            }
-            _ => {}
-        }
+        // match event.get_type() {
+        //     xlib::KeyPress | xlib::KeyRelease => {
+        //         self.update_modifier_state(AsRef::<xlib::XKeyEvent>::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<Self::Window> {
-        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<Self::Window> {
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<i32>,
     starting_window_pos: Point<i32>,
 }
 
+#[derive(Debug)]
 struct ResizeInfoInner {
     window: Window,
     starting_cursor_pos: Point<i32>,
@@ -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<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();
+        if event.state == KeyState::Released {
+            // 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() {
-            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<B::Window>) {
         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,