changed rustfmt to max 80 chars per line, added better ways to switch virtual screens
This commit is contained in:
		
							parent
							
								
									ef63004242
								
							
						
					
					
						commit
						5b37a86a58
					
				|  | @ -1,2 +1,3 @@ | |||
| imports_granularity = "Crate" | ||||
| wrap_comments = true | ||||
| wrap_comments = true | ||||
| max_width = 80 | ||||
|  | @ -32,7 +32,11 @@ mod client { | |||
|     } | ||||
| 
 | ||||
|     impl Client { | ||||
|         pub fn new(window: Window, size: (i32, i32), position: (i32, i32)) -> Self { | ||||
|         pub fn new( | ||||
|             window: Window, | ||||
|             size: (i32, i32), | ||||
|             position: (i32, i32), | ||||
|         ) -> Self { | ||||
|             Self { | ||||
|                 window, | ||||
|                 size, | ||||
|  | @ -41,7 +45,11 @@ mod client { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         pub fn new_transient(window: Window, size: (i32, i32), transient: Window) -> Self { | ||||
|         pub fn new_transient( | ||||
|             window: Window, | ||||
|             size: (i32, i32), | ||||
|             transient: Window, | ||||
|         ) -> Self { | ||||
|             Self { | ||||
|                 window, | ||||
|                 size, | ||||
|  | @ -300,13 +308,17 @@ impl ClientState { | |||
|     pub fn insert(&mut self, mut client: Client) -> Option<&Client> { | ||||
|         let key = client.key(); | ||||
| 
 | ||||
|         if client.is_transient() && self.contains(&client.transient_for.unwrap()) { | ||||
|         if client.is_transient() | ||||
|             && self.contains(&client.transient_for.unwrap()) | ||||
|         { | ||||
|             let transient = self.get(&client.transient_for.unwrap()).unwrap(); | ||||
| 
 | ||||
|             client.position = { | ||||
|                 ( | ||||
|                     transient.position.0 + (transient.size.0 - client.size.0) / 2, | ||||
|                     transient.position.1 + (transient.size.1 - client.size.1) / 2, | ||||
|                     transient.position.0 | ||||
|                         + (transient.size.0 - client.size.0) / 2, | ||||
|                     transient.position.1 | ||||
|                         + (transient.size.1 - client.size.1) / 2, | ||||
|                 ) | ||||
|             }; | ||||
| 
 | ||||
|  | @ -347,7 +359,8 @@ impl ClientState { | |||
|     { | ||||
|         let key = key.key(); | ||||
| 
 | ||||
|         self.clients.contains_key(&key) || self.floating_clients.contains_key(&key) | ||||
|         self.clients.contains_key(&key) | ||||
|             || self.floating_clients.contains_key(&key) | ||||
|     } | ||||
| 
 | ||||
|     pub fn iter_floating(&self) -> impl Iterator<Item = (&u64, &Client)> { | ||||
|  | @ -378,6 +391,18 @@ impl ClientState { | |||
|             .filter(move |&(k, _)| self.current_vs().contains(k)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn iter_master_stack(&self) -> impl Iterator<Item = (&u64, &Client)> { | ||||
|         self.clients | ||||
|             .iter() | ||||
|             .filter(move |&(k, _)| self.current_vs().is_in_master(k)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn iter_aux_stack(&self) -> impl Iterator<Item = (&u64, &Client)> { | ||||
|         self.clients | ||||
|             .iter() | ||||
|             .filter(move |&(k, _)| self.current_vs().is_in_aux(k)) | ||||
|     } | ||||
| 
 | ||||
|     /// Returns reference to the current `VirtualScreen`.
 | ||||
|     fn current_vs(&self) -> &VirtualScreen { | ||||
|         // there is always at least one (1) virtual screen.
 | ||||
|  | @ -510,31 +535,39 @@ impl ClientState { | |||
|     where | ||||
|         K: ClientKey, | ||||
|     { | ||||
|         self.virtual_screens | ||||
|             .iter() | ||||
|             .find_map(|vs| if vs.contains(key) { Some(vs) } else { None }) | ||||
|         self.virtual_screens.iter().find_map(|vs| { | ||||
|             if vs.contains(key) { | ||||
|                 Some(vs) | ||||
|             } else { | ||||
|                 None | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn get_mut_virtualscreen_for_client<K>(&mut self, key: &K) -> Option<&mut VirtualScreen> | ||||
|     fn get_mut_virtualscreen_for_client<K>( | ||||
|         &mut self, | ||||
|         key: &K, | ||||
|     ) -> Option<&mut VirtualScreen> | ||||
|     where | ||||
|         K: ClientKey, | ||||
|     { | ||||
|         self.virtual_screens.iter_mut().find_map( | ||||
|             |vs| { | ||||
|                 if vs.contains(key) { | ||||
|                     Some(vs) | ||||
|                 } else { | ||||
|                     None | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         self.virtual_screens.iter_mut().find_map(|vs| { | ||||
|             if vs.contains(key) { | ||||
|                 Some(vs) | ||||
|             } else { | ||||
|                 None | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|     focuses client `key` if it contains `key` and returns a reference to the  newly and the previously | ||||
|     focused clients if any. | ||||
|     */ | ||||
|     pub fn focus_client<K>(&mut self, key: &K) -> (ClientEntry<&Client>, ClientEntry<&Client>) | ||||
|     pub fn focus_client<K>( | ||||
|         &mut self, | ||||
|         key: &K, | ||||
|     ) -> (ClientEntry<&Client>, ClientEntry<&Client>) | ||||
|     where | ||||
|         K: ClientKey, | ||||
|     { | ||||
|  | @ -613,7 +646,12 @@ impl ClientState { | |||
|     screen width and screen height. | ||||
|     Optionally adds a gap between windows `gap.unwrap_or(0)` pixels wide. | ||||
|     */ | ||||
|     pub fn arrange_virtual_screen(&mut self, width: i32, height: i32, gap: Option<i32>) { | ||||
|     pub fn arrange_virtual_screen( | ||||
|         &mut self, | ||||
|         width: i32, | ||||
|         height: i32, | ||||
|         gap: Option<i32>, | ||||
|     ) { | ||||
|         let gap = gap.unwrap_or(0); | ||||
| 
 | ||||
|         // should be fine to unwrap since we will always have at least 1 virtual screen
 | ||||
|  | @ -687,6 +725,20 @@ impl VirtualScreen { | |||
|         self.master.contains(&key.key()) || self.aux.contains(&key.key()) | ||||
|     } | ||||
| 
 | ||||
|     fn is_in_master<K>(&self, key: &K) -> bool | ||||
|     where | ||||
|         K: ClientKey, | ||||
|     { | ||||
|         self.master.contains(&key.key()) | ||||
|     } | ||||
| 
 | ||||
|     fn is_in_aux<K>(&self, key: &K) -> bool | ||||
|     where | ||||
|         K: ClientKey, | ||||
|     { | ||||
|         self.aux.contains(&key.key()) | ||||
|     } | ||||
| 
 | ||||
|     fn insert<K>(&mut self, key: &K) | ||||
|     where | ||||
|         K: ClientKey, | ||||
|  | @ -716,7 +768,8 @@ impl VirtualScreen { | |||
|                 self.aux.extend(self.master.drain(index..=index)); | ||||
|             } | ||||
|             None => { | ||||
|                 let index = self.aux.iter().position(|&k| k == key.key()).unwrap(); | ||||
|                 let index = | ||||
|                     self.aux.iter().position(|&k| k == key.key()).unwrap(); | ||||
|                 self.master.extend(self.aux.drain(index..=index)); | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ use log4rs::{ | |||
|     encode::pattern::PatternEncoder, | ||||
|     Config, | ||||
| }; | ||||
| use state::WMConfig; | ||||
| 
 | ||||
| mod clients; | ||||
| mod state; | ||||
|  | @ -44,7 +45,7 @@ fn main() { | |||
| 
 | ||||
|     log_prologue(); | ||||
| 
 | ||||
|     state::WindowManager::new().init().run(); | ||||
|     state::WindowManager::new(WMConfig::default()).init().run(); | ||||
| } | ||||
| 
 | ||||
| fn log_prologue() { | ||||
|  |  | |||
							
								
								
									
										167
									
								
								src/state.rs
									
									
									
									
									
								
							
							
						
						
									
										167
									
								
								src/state.rs
									
									
									
									
									
								
							|  | @ -2,10 +2,14 @@ use std::rc::Rc; | |||
| 
 | ||||
| use log::{error, info}; | ||||
| 
 | ||||
| use x11::xlib::{self, ShiftMask, Window, XButtonEvent, XEvent, XKeyEvent, XMotionEvent}; | ||||
| use x11::xlib::{ | ||||
|     self, Mod4Mask, ShiftMask, Window, XButtonEvent, XEvent, XKeyEvent, | ||||
|     XMotionEvent, | ||||
| }; | ||||
| use xlib::{ | ||||
|     ButtonPressMask, ButtonReleaseMask, Mod1Mask, PointerMotionMask, XConfigureRequestEvent, | ||||
|     XCrossingEvent, XDestroyWindowEvent, XMapRequestEvent, XUnmapEvent, | ||||
|     ButtonPressMask, ButtonReleaseMask, PointerMotionMask, | ||||
|     XConfigureRequestEvent, XCrossingEvent, XDestroyWindowEvent, | ||||
|     XMapRequestEvent, XUnmapEvent, | ||||
| }; | ||||
| 
 | ||||
| use crate::{ | ||||
|  | @ -14,15 +18,28 @@ use crate::{ | |||
|     xlib::XLib, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
| Contains static config data for the window manager, the sort of stuff you might want to | ||||
| be able to configure in a config file. | ||||
| */ | ||||
| pub struct WMConfig { | ||||
|     num_virtualscreens: usize, | ||||
|     mod_key: u32, | ||||
|     gap: Option<i32>, | ||||
| } | ||||
| 
 | ||||
| pub struct WindowManager { | ||||
|     clients: ClientState, | ||||
|     move_window: Option<MoveWindow>, | ||||
|     resize_window: Option<MoveWindow>, | ||||
|     keybinds: Vec<KeyBinding>, | ||||
|     xlib: XLib, | ||||
| 
 | ||||
|     last_rotation: Option<Direction>, | ||||
|     config: WMConfig, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum Direction { | ||||
|     Left, | ||||
|     Right, | ||||
|  | @ -40,8 +57,9 @@ struct KeyBinding { | |||
| } | ||||
| 
 | ||||
| impl WindowManager { | ||||
|     pub fn new() -> Self { | ||||
|         let clients = ClientState::with_virtualscreens(3); | ||||
|     pub fn new(config: WMConfig) -> Self { | ||||
|         let clients = | ||||
|             ClientState::with_virtualscreens(config.num_virtualscreens); | ||||
|         let xlib = XLib::new(); | ||||
| 
 | ||||
|         Self { | ||||
|  | @ -50,28 +68,30 @@ impl WindowManager { | |||
|             resize_window: None, | ||||
|             keybinds: Vec::new(), | ||||
|             xlib, | ||||
|             last_rotation: None, | ||||
|             config, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn init(mut self) -> Self { | ||||
|         self.xlib.add_global_keybind(KeyOrButton::button( | ||||
|             1, | ||||
|             Mod1Mask, | ||||
|             self.config.mod_key, | ||||
|             ButtonPressMask | ButtonReleaseMask | PointerMotionMask, | ||||
|         )); | ||||
|         self.xlib.add_global_keybind(KeyOrButton::button( | ||||
|             2, | ||||
|             Mod1Mask, | ||||
|             self.config.mod_key, | ||||
|             ButtonPressMask | ButtonReleaseMask | PointerMotionMask, | ||||
|         )); | ||||
|         self.xlib.add_global_keybind(KeyOrButton::button( | ||||
|             3, | ||||
|             Mod1Mask, | ||||
|             self.config.mod_key, | ||||
|             ButtonPressMask | ButtonReleaseMask | PointerMotionMask, | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("P", Mod1Mask), | ||||
|             self.xlib.make_key("P", self.config.mod_key), | ||||
|             |wm, _| { | ||||
|                 wm.spawn( | ||||
|                     "dmenu_run", | ||||
|  | @ -94,37 +114,63 @@ impl WindowManager { | |||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("M", Mod1Mask), | ||||
|             self.xlib.make_key("M", self.config.mod_key), | ||||
|             Self::handle_switch_stack, | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("Q", Mod1Mask), | ||||
|             self.xlib.make_key("Q", self.config.mod_key), | ||||
|             Self::kill_client, | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("Q", Mod1Mask | ShiftMask), | ||||
|             self.xlib.make_key("Q", self.config.mod_key | ShiftMask), | ||||
|             |wm, _| wm.quit(), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("T", Mod1Mask), | ||||
|             self.xlib.make_key("T", self.config.mod_key), | ||||
|             |wm, _| wm.spawn("alacritty", &[]), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("Return", Mod1Mask | ShiftMask), | ||||
|             self.xlib | ||||
|                 .make_key("Return", self.config.mod_key | ShiftMask), | ||||
|             |wm, _| wm.spawn("alacritty", &[]), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("Left", Mod1Mask), | ||||
|             self.xlib.make_key("Left", self.config.mod_key), | ||||
|             |wm, _| wm.rotate_virtual_screen(Direction::Left), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("Right", Mod1Mask), | ||||
|             self.xlib.make_key("Right", self.config.mod_key), | ||||
|             |wm, _| wm.rotate_virtual_screen(Direction::Right), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("Tab", self.config.mod_key), | ||||
|             |wm, _| wm.rotate_virtual_screen_back(), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("J", self.config.mod_key), | ||||
|             |wm, _| wm.focus_master_stack(), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("K", self.config.mod_key), | ||||
|             |wm, _| wm.focus_aux_stack(), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("J", self.config.mod_key | ShiftMask), | ||||
|             |wm, _| wm.rotate_virtual_screen(Direction::Left), | ||||
|         )); | ||||
| 
 | ||||
|         self.add_keybind(KeyBinding::new( | ||||
|             self.xlib.make_key("K", self.config.mod_key | ShiftMask), | ||||
|             |wm, _| wm.rotate_virtual_screen(Direction::Right), | ||||
|         )); | ||||
| 
 | ||||
|  | @ -192,7 +238,9 @@ impl WindowManager { | |||
|             let event: &XButtonEvent = event.as_ref(); | ||||
|             let clean_mask = self.xlib.get_clean_mask(); | ||||
| 
 | ||||
|             if event.button == 2 && event.state & clean_mask == Mod1Mask & clean_mask { | ||||
|             if event.button == 2 | ||||
|                 && event.state & clean_mask == self.config.mod_key & clean_mask | ||||
|             { | ||||
|                 if self.clients.contains(&event.subwindow) { | ||||
|                     info!("toggleing floating for {:?}", event.subwindow); | ||||
| 
 | ||||
|  | @ -221,7 +269,8 @@ impl WindowManager { | |||
| 
 | ||||
|                 if self.move_window.is_none() | ||||
|                     && event.button == 1 | ||||
|                     && event.state & clean_mask == Mod1Mask & clean_mask | ||||
|                     && event.state & clean_mask | ||||
|                         == self.config.mod_key & clean_mask | ||||
|                     && self.clients.contains(&event.subwindow) | ||||
|                 { | ||||
|                     // if client is tiled, set to floating
 | ||||
|  | @ -257,7 +306,9 @@ impl WindowManager { | |||
| 
 | ||||
|                     move_window.cached_cursor_position = (event.x, event.y); | ||||
| 
 | ||||
|                     if let Some(client) = self.clients.get_mut(&move_window.key).into_option() { | ||||
|                     if let Some(client) = | ||||
|                         self.clients.get_mut(&move_window.key).into_option() | ||||
|                     { | ||||
|                         let position = &mut client.position; | ||||
|                         position.0 += x; | ||||
|                         position.1 += y; | ||||
|  | @ -279,7 +330,8 @@ impl WindowManager { | |||
| 
 | ||||
|                 if self.resize_window.is_none() | ||||
|                     && event.button == 3 | ||||
|                     && event.state & clean_mask == Mod1Mask & clean_mask | ||||
|                     && event.state & clean_mask | ||||
|                         == self.config.mod_key & clean_mask | ||||
|                     && self.clients.contains(&event.subwindow) | ||||
|                 { | ||||
|                     // if client is tiled, set to floating
 | ||||
|  | @ -329,7 +381,9 @@ impl WindowManager { | |||
| 
 | ||||
|                     resize_window.cached_cursor_position = (event.x, event.y); | ||||
| 
 | ||||
|                     if let Some(client) = self.clients.get_mut(&resize_window.key).into_option() { | ||||
|                     if let Some(client) = | ||||
|                         self.clients.get_mut(&resize_window.key).into_option() | ||||
|                     { | ||||
|                         let size = &mut client.size; | ||||
| 
 | ||||
|                         size.0 = std::cmp::max(1, size.0 + x); | ||||
|  | @ -343,9 +397,17 @@ impl WindowManager { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn rotate_virtual_screen_back(&mut self) { | ||||
|         if let Some(dir) = self.last_rotation { | ||||
|             self.rotate_virtual_screen(!dir); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn rotate_virtual_screen(&mut self, dir: Direction) { | ||||
|         info!("rotateing VS: {:?}", dir); | ||||
| 
 | ||||
|         self.last_rotation = Some(dir); | ||||
| 
 | ||||
|         match dir { | ||||
|             Direction::Left => self.clients.rotate_left(), | ||||
|             Direction::Right => self.clients.rotate_right(), | ||||
|  | @ -354,13 +416,40 @@ impl WindowManager { | |||
|         self.arrange_clients(); | ||||
| 
 | ||||
|         // focus first client in all visible clients
 | ||||
|         let to_focus = self.clients.iter_visible().next().map(|(k, _)| k).cloned(); | ||||
|         let to_focus = | ||||
|             self.clients.iter_visible().next().map(|(k, _)| k).cloned(); | ||||
| 
 | ||||
|         if let Some(key) = to_focus { | ||||
|             self.focus_client(&key); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn focus_master_stack(&mut self) { | ||||
|         let k = self | ||||
|             .clients | ||||
|             .iter_master_stack() | ||||
|             .map(|(k, _)| k) | ||||
|             .next() | ||||
|             .cloned(); | ||||
| 
 | ||||
|         if let Some(k) = k { | ||||
|             self.focus_client(&k); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn focus_aux_stack(&mut self) { | ||||
|         let k = self | ||||
|             .clients | ||||
|             .iter_aux_stack() | ||||
|             .map(|(k, _)| k) | ||||
|             .next() | ||||
|             .cloned(); | ||||
| 
 | ||||
|         if let Some(k) = k { | ||||
|             self.focus_client(&k); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn hide_hidden_clients(&self) { | ||||
|         self.clients | ||||
|             .iter_hidden() | ||||
|  | @ -379,14 +468,15 @@ impl WindowManager { | |||
| 
 | ||||
|     fn arrange_clients(&mut self) { | ||||
|         let (width, height) = self.xlib.dimensions(); | ||||
|         self.clients.arrange_virtual_screen(width, height, Some(2)); | ||||
| 
 | ||||
|         self.hide_hidden_clients(); | ||||
|         self.clients | ||||
|             .arrange_virtual_screen(width, height, self.config.gap); | ||||
| 
 | ||||
|         self.clients | ||||
|             .iter_visible() | ||||
|             .for_each(|(_, c)| self.xlib.move_resize_client(c)); | ||||
| 
 | ||||
|         self.hide_hidden_clients(); | ||||
| 
 | ||||
|         self.raise_floating_clients(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -410,7 +500,9 @@ impl WindowManager { | |||
| 
 | ||||
|     fn new_client(&mut self, window: Window) { | ||||
|         info!("new client: {:?}", window); | ||||
|         let client = if let Some(transient_window) = self.xlib.get_transient_for_window(window) { | ||||
|         let client = if let Some(transient_window) = | ||||
|             self.xlib.get_transient_for_window(window) | ||||
|         { | ||||
|             Client::new_transient( | ||||
|                 window, | ||||
|                 self.xlib.get_window_size(window).unwrap_or((100, 100)), | ||||
|  | @ -502,3 +594,24 @@ impl KeyBinding { | |||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Default for WMConfig { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             num_virtualscreens: 5, | ||||
|             mod_key: Mod4Mask, | ||||
|             gap: Some(2), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl std::ops::Not for Direction { | ||||
|     type Output = Self; | ||||
| 
 | ||||
|     fn not(self) -> Self::Output { | ||||
|         match self { | ||||
|             Direction::Left => Direction::Right, | ||||
|             Direction::Right => Direction::Left, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										115
									
								
								src/xlib.rs
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								src/xlib.rs
									
									
									
									
									
								
							|  | @ -3,12 +3,14 @@ use std::ptr::{null, null_mut}; | |||
| use std::{ffi::CString, rc::Rc}; | ||||
| 
 | ||||
| use x11::xlib::{ | ||||
|     self, Atom, ButtonPressMask, ButtonReleaseMask, CWEventMask, ControlMask, CurrentTime, | ||||
|     EnterWindowMask, FocusChangeMask, LockMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask, | ||||
|     PointerMotionMask, PropertyChangeMask, ShiftMask, StructureNotifyMask, SubstructureNotifyMask, | ||||
|     SubstructureRedirectMask, Window, XCloseDisplay, XConfigureRequestEvent, XDefaultScreen, | ||||
|     XEvent, XGetTransientForHint, XGrabPointer, XInternAtom, XKillClient, XMapWindow, XOpenDisplay, | ||||
|     XRaiseWindow, XRootWindow, XSetErrorHandler, XSync, XUngrabPointer, XWarpPointer, | ||||
|     self, Atom, ButtonPressMask, ButtonReleaseMask, CWEventMask, ControlMask, | ||||
|     CurrentTime, EnterWindowMask, FocusChangeMask, LockMask, Mod1Mask, | ||||
|     Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask, PointerMotionMask, | ||||
|     PropertyChangeMask, ShiftMask, StructureNotifyMask, SubstructureNotifyMask, | ||||
|     SubstructureRedirectMask, Window, XCloseDisplay, XConfigureRequestEvent, | ||||
|     XDefaultScreen, XEvent, XGetTransientForHint, XGrabPointer, XInternAtom, | ||||
|     XKillClient, XMapWindow, XOpenDisplay, XRaiseWindow, XRootWindow, | ||||
|     XSetErrorHandler, XSync, XUngrabPointer, XWarpPointer, | ||||
| }; | ||||
| use xlib::GrabModeAsync; | ||||
| 
 | ||||
|  | @ -76,7 +78,8 @@ impl XLib { | |||
|     pub fn init(&mut self) { | ||||
|         unsafe { | ||||
|             let mut window_attributes = | ||||
|                 std::mem::MaybeUninit::<xlib::XSetWindowAttributes>::zeroed().assume_init(); | ||||
|                 std::mem::MaybeUninit::<xlib::XSetWindowAttributes>::zeroed() | ||||
|                     .assume_init(); | ||||
| 
 | ||||
|             window_attributes.event_mask = SubstructureRedirectMask | ||||
|                 | StructureNotifyMask | ||||
|  | @ -92,7 +95,11 @@ impl XLib { | |||
|                 &mut window_attributes, | ||||
|             ); | ||||
| 
 | ||||
|             xlib::XSelectInput(self.dpy(), self.root, window_attributes.event_mask); | ||||
|             xlib::XSelectInput( | ||||
|                 self.dpy(), | ||||
|                 self.root, | ||||
|                 window_attributes.event_mask, | ||||
|             ); | ||||
| 
 | ||||
|             XSetErrorHandler(Some(xlib_error_handler)); | ||||
|         } | ||||
|  | @ -123,9 +130,12 @@ impl XLib { | |||
| 
 | ||||
|     pub fn squash_event(&self, event_type: i32) -> XEvent { | ||||
|         unsafe { | ||||
|             let mut event = std::mem::MaybeUninit::<xlib::XEvent>::zeroed().assume_init(); | ||||
|             let mut event = | ||||
|                 std::mem::MaybeUninit::<xlib::XEvent>::zeroed().assume_init(); | ||||
| 
 | ||||
|             while xlib::XCheckTypedEvent(self.dpy(), event_type, &mut event) != 0 {} | ||||
|             while xlib::XCheckTypedEvent(self.dpy(), event_type, &mut event) | ||||
|                 != 0 | ||||
|             {} | ||||
| 
 | ||||
|             event | ||||
|         } | ||||
|  | @ -133,7 +143,8 @@ impl XLib { | |||
| 
 | ||||
|     pub fn next_event(&self) -> XEvent { | ||||
|         unsafe { | ||||
|             let mut event = std::mem::MaybeUninit::<xlib::XEvent>::zeroed().assume_init(); | ||||
|             let mut event = | ||||
|                 std::mem::MaybeUninit::<xlib::XEvent>::zeroed().assume_init(); | ||||
|             xlib::XNextEvent(self.dpy(), &mut event); | ||||
| 
 | ||||
|             event | ||||
|  | @ -142,7 +153,8 @@ impl XLib { | |||
| 
 | ||||
|     pub fn grab_key_or_button(&self, window: Window, key: &KeyOrButton) { | ||||
|         let numlock_mask = self.get_numlock_mask(); | ||||
|         let modifiers = vec![0, LockMask, numlock_mask, LockMask | numlock_mask]; | ||||
|         let modifiers = | ||||
|             vec![0, LockMask, numlock_mask, LockMask | numlock_mask]; | ||||
| 
 | ||||
|         for modifier in modifiers.iter() { | ||||
|             match key { | ||||
|  | @ -215,7 +227,11 @@ impl XLib { | |||
|                 xlib::CurrentTime, | ||||
|             ); | ||||
| 
 | ||||
|             xlib::XDeleteProperty(self.dpy(), self.root, self.atoms.active_window); | ||||
|             xlib::XDeleteProperty( | ||||
|                 self.dpy(), | ||||
|                 self.root, | ||||
|                 self.atoms.active_window, | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -237,7 +253,8 @@ impl XLib { | |||
|                 xlib::XConfigureWindow( | ||||
|                     self.dpy(), | ||||
|                     client.window, | ||||
|                     (xlib::CWY | xlib::CWX | xlib::CWHeight | xlib::CWWidth) as u32, | ||||
|                     (xlib::CWY | xlib::CWX | xlib::CWHeight | xlib::CWWidth) | ||||
|                         as u32, | ||||
|                     &mut windowchanges, | ||||
|                 ); | ||||
| 
 | ||||
|  | @ -338,10 +355,14 @@ impl XLib { | |||
|     } | ||||
| 
 | ||||
|     pub fn get_window_size(&self, window: Window) -> Option<(i32, i32)> { | ||||
|         let mut wa = | ||||
|             unsafe { std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed().assume_init() }; | ||||
|         let mut wa = unsafe { | ||||
|             std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed() | ||||
|                 .assume_init() | ||||
|         }; | ||||
| 
 | ||||
|         if unsafe { xlib::XGetWindowAttributes(self.dpy(), window, &mut wa) != 0 } { | ||||
|         if unsafe { | ||||
|             xlib::XGetWindowAttributes(self.dpy(), window, &mut wa) != 0 | ||||
|         } { | ||||
|             Some((wa.width, wa.height)) | ||||
|         } else { | ||||
|             None | ||||
|  | @ -351,7 +372,9 @@ impl XLib { | |||
|     pub fn get_transient_for_window(&self, window: Window) -> Option<Window> { | ||||
|         let mut transient_for: Window = 0; | ||||
| 
 | ||||
|         if unsafe { XGetTransientForHint(self.dpy(), window, &mut transient_for) != 0 } { | ||||
|         if unsafe { | ||||
|             XGetTransientForHint(self.dpy(), window, &mut transient_for) != 0 | ||||
|         } { | ||||
|             Some(transient_for) | ||||
|         } else { | ||||
|             None | ||||
|  | @ -370,7 +393,12 @@ impl XLib { | |||
|         }; | ||||
| 
 | ||||
|         unsafe { | ||||
|             xlib::XConfigureWindow(self.dpy(), event.window, event.value_mask as u32, &mut wc); | ||||
|             xlib::XConfigureWindow( | ||||
|                 self.dpy(), | ||||
|                 event.window, | ||||
|                 event.value_mask as u32, | ||||
|                 &mut wc, | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -409,7 +437,10 @@ impl XLib { | |||
|             xlib::XSelectInput( | ||||
|                 self.dpy(), | ||||
|                 window, | ||||
|                 EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask, | ||||
|                 EnterWindowMask | ||||
|                     | FocusChangeMask | ||||
|                     | PropertyChangeMask | ||||
|                     | StructureNotifyMask, | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|  | @ -445,7 +476,8 @@ impl XLib { | |||
|                 self.dpy(), | ||||
|                 self.root, | ||||
|                 0, | ||||
|                 (ButtonPressMask | ButtonReleaseMask | PointerMotionMask) as u32, | ||||
|                 (ButtonPressMask | ButtonReleaseMask | PointerMotionMask) | ||||
|                     as u32, | ||||
|                 GrabModeAsync, | ||||
|                 GrabModeAsync, | ||||
|                 0, | ||||
|  | @ -463,7 +495,17 @@ impl XLib { | |||
| 
 | ||||
|     pub fn move_cursor(&self, window: Window, position: (i32, i32)) { | ||||
|         unsafe { | ||||
|             XWarpPointer(self.dpy(), 0, window, 0, 0, 0, 0, position.0, position.1); | ||||
|             XWarpPointer( | ||||
|                 self.dpy(), | ||||
|                 0, | ||||
|                 window, | ||||
|                 0, | ||||
|                 0, | ||||
|                 0, | ||||
|                 0, | ||||
|                 position.0, | ||||
|                 position.1, | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -472,7 +514,13 @@ impl XLib { | |||
|         let mut num_protos: i32 = 0; | ||||
| 
 | ||||
|         unsafe { | ||||
|             if xlib::XGetWMProtocols(self.dpy(), client.window, &mut protos, &mut num_protos) != 0 { | ||||
|             if xlib::XGetWMProtocols( | ||||
|                 self.dpy(), | ||||
|                 client.window, | ||||
|                 &mut protos, | ||||
|                 &mut num_protos, | ||||
|             ) != 0 | ||||
|             { | ||||
|                 for i in 0..num_protos { | ||||
|                     if *protos.offset(i as isize) == proto { | ||||
|                         return true; | ||||
|  | @ -503,7 +551,13 @@ impl XLib { | |||
|             }; | ||||
| 
 | ||||
|             unsafe { | ||||
|                 xlib::XSendEvent(self.dpy(), client.window, 0, xlib::NoEventMask, &mut event); | ||||
|                 xlib::XSendEvent( | ||||
|                     self.dpy(), | ||||
|                     client.window, | ||||
|                     0, | ||||
|                     xlib::NoEventMask, | ||||
|                     &mut event, | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             true | ||||
|  | @ -543,7 +597,10 @@ impl XLib { | |||
|                     if *(*modmap) | ||||
|                         .modifiermap | ||||
|                         .offset((i * max_keypermod + j) as isize) | ||||
|                         == xlib::XKeysymToKeycode(self.dpy(), x11::keysym::XK_Num_Lock as u64) | ||||
|                         == xlib::XKeysymToKeycode( | ||||
|                             self.dpy(), | ||||
|                             x11::keysym::XK_Num_Lock as u64, | ||||
|                         ) | ||||
|                     { | ||||
|                         return 1 << i; | ||||
|                     } | ||||
|  | @ -556,7 +613,13 @@ impl XLib { | |||
| 
 | ||||
|     pub fn get_clean_mask(&self) -> u32 { | ||||
|         !(self.get_numlock_mask() | LockMask) | ||||
|             & (ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) | ||||
|             & (ShiftMask | ||||
|                 | ControlMask | ||||
|                 | Mod1Mask | ||||
|                 | Mod2Mask | ||||
|                 | Mod3Mask | ||||
|                 | Mod4Mask | ||||
|                 | Mod5Mask) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue