changed rustfmt to actually work hopefully (70 char limit)

also more abstraction stuff
This commit is contained in:
NoOneBtw 2021-05-15 02:48:23 +02:00
parent 98459d620c
commit 1b2e2d848c
14 changed files with 2134 additions and 198 deletions

View file

@ -1,2 +1,2 @@
#wrap_comments = true wrap_comments = true
max_width = 80 max_width = 70

209
src/backends/keycodes.rs Normal file
View file

@ -0,0 +1,209 @@
#![allow(dead_code)]
#[derive(
Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy,
)]
pub enum MouseButton {
Left,
Middle,
Right,
ScrollUp,
ScrollDown,
ScrollLeft,
ScrollRight,
Forward,
Backward,
}
/// from winit
#[derive(
Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy,
)]
#[repr(u32)]
pub enum VirtualKeyCode {
Key1,
Key2,
Key3,
Key4,
Key5,
Key6,
Key7,
Key8,
Key9,
Key0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
/// The Escape key, next to F1.
Escape,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
/// Print Screen/SysRq.
Snapshot,
/// Scroll Lock.
Scroll,
/// Pause/Break key, next to Scroll lock.
Pause,
/// `Insert`, next to Backspace.
Insert,
Home,
Delete,
End,
PageDown,
PageUp,
Left,
Up,
Right,
Down,
/// The Backspace key, right over Enter.
// TODO: rename
Back,
/// The Enter key.
Return,
/// The space bar.
Space,
/// The "Compose" key on Linux.
Compose,
Caret,
Numlock,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
NumpadAdd,
NumpadDivide,
NumpadDecimal,
NumpadComma,
NumpadEnter,
NumpadEquals,
NumpadMultiply,
NumpadSubtract,
AbntC1,
AbntC2,
Apostrophe,
Apps,
Asterisk,
At,
Ax,
Backslash,
Calculator,
Capital,
Colon,
Comma,
Convert,
Equals,
Grave,
Kana,
Kanji,
LAlt,
LBracket,
LControl,
LShift,
LWin,
Mail,
MediaSelect,
MediaStop,
Minus,
Mute,
MyComputer,
// also called "Next"
NavigateForward,
// also called "Prior"
NavigateBackward,
NextTrack,
NoConvert,
OEM102,
Period,
PlayPause,
Plus,
Power,
PrevTrack,
RAlt,
RBracket,
RControl,
RShift,
RWin,
Semicolon,
Slash,
Sleep,
Stop,
Sysrq,
Tab,
Underline,
Unlabeled,
VolumeDown,
VolumeUp,
Wake,
WebBack,
WebFavorites,
WebForward,
WebHome,
WebRefresh,
WebSearch,
WebStop,
Yen,
Copy,
Paste,
Cut,
}

View file

@ -1,3 +1,5 @@
mod keycodes;
mod window_event;
mod xcb; mod xcb;
mod xlib; mod xlib;

View file

@ -0,0 +1,220 @@
#![allow(dead_code)]
use x11::xlib::Window;
use super::keycodes::{MouseButton, VirtualKeyCode};
#[derive(Debug)]
pub enum WindowEvent {
KeyEvent {
window: Window,
event: KeyEvent,
},
ButtonEvent {
window: Window,
event: ButtonEvent,
},
MotionEvent {
window: Window,
event: MotionEvent,
},
MapEvent {
window: Window,
event: MapEvent,
},
UnmapEvent {
window: Window,
event: UnmapEvent,
},
CreateEvent {
window: Window,
event: CreateEvent,
},
DestroyEvent {
window: Window,
event: DestroyEvent,
},
EnterEvent {
window: Window,
event: EnterEvent,
},
ConfigureEvent {
window: Window,
event: ConfigureEvent,
},
//1 { window: Window, event: 1 },
}
#[derive(Debug)]
pub enum KeyState {
Pressed,
Released,
}
#[derive(
Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy,
)]
#[repr(u8)]
pub enum ModifierKey {
Shift,
ShiftLock,
Control,
Alt,
AltGr,
/// Windows key on most keyboards
Super,
NumLock,
}
#[derive(Default, Debug, Clone)]
pub struct ModifierState {
modifiers: std::collections::HashSet<ModifierKey>,
}
impl ModifierState {
pub fn new() -> Self {
Self::default()
}
pub fn set_modifier(&mut self, modifier: ModifierKey) {
self.modifiers.insert(modifier);
}
pub fn unset_modifier(&mut self, modifier: ModifierKey) {
self.modifiers.remove(&modifier);
}
pub fn get_modifier(&mut self, modifier: ModifierKey) -> bool {
self.modifiers.contains(&modifier)
}
}
#[derive(Debug)]
pub struct KeyEvent {
state: KeyState,
keycode: VirtualKeyCode,
modifierstate: ModifierState,
}
impl KeyEvent {
pub fn new(
state: KeyState,
keycode: VirtualKeyCode,
modifierstate: ModifierState,
) -> Self {
Self {
state,
keycode,
modifierstate,
}
}
}
#[derive(Debug)]
pub struct ButtonEvent {
state: KeyState,
keycode: MouseButton,
modifierstate: ModifierState,
}
impl ButtonEvent {
pub fn new(
state: KeyState,
keycode: MouseButton,
modifierstate: ModifierState,
) -> Self {
Self {
state,
keycode,
modifierstate,
}
}
}
#[derive(Debug)]
pub struct MotionEvent {
position: [i32; 2],
}
impl MotionEvent {
pub fn new(position: [i32; 2]) -> Self {
Self { position }
}
}
#[derive(Debug)]
pub struct MapEvent {
window: Window,
}
impl MapEvent {
pub fn new(window: Window) -> Self {
Self { window }
}
}
#[derive(Debug)]
pub struct UnmapEvent {
window: Window,
}
impl UnmapEvent {
pub fn new(window: Window) -> Self {
Self { window }
}
}
#[derive(Debug)]
pub struct EnterEvent {}
#[derive(Debug)]
pub struct DestroyEvent {
window: Window,
}
impl DestroyEvent {
pub fn new(window: Window) -> Self {
Self { window }
}
}
#[derive(Debug)]
pub struct CreateEvent {
window: Window,
position: [i32; 2],
size: [i32; 2],
}
impl CreateEvent {
pub fn new(
window: Window,
position: [i32; 2],
size: [i32; 2],
) -> Self {
Self {
window,
position,
size,
}
}
}
#[derive(Debug)]
pub struct ConfigureEvent {
window: Window,
position: [i32; 2],
size: [i32; 2],
}
impl ConfigureEvent {
pub fn new(
window: Window,
position: [i32; 2],
size: [i32; 2],
) -> Self {
Self {
window,
position,
size,
}
}
}

View file

@ -12,8 +12,8 @@ use x11rb::{
errors::ReplyError, errors::ReplyError,
errors::ReplyOrIdError, errors::ReplyOrIdError,
protocol::xproto::{ protocol::xproto::{
Atom, ChangeWindowAttributesAux, ConnectionExt, EventMask, Screen, Atom, ChangeWindowAttributesAux, ConnectionExt, EventMask,
Setup, Screen, Setup,
}, },
}; };
@ -41,12 +41,37 @@ mod tests {
.enumerate() .enumerate()
{ {
println!( println!(
"keycode: {:#x?}\tkeysyms: {:0x?}", "keycode: {:#?}\tkeysyms: {:0x?}",
xcb.setup().min_keycode as usize + i, xcb.setup().min_keycode as usize + i,
keysyms keysyms
); );
} }
} }
#[test]
fn modifier_masks() {
let xcb = create_backend().unwrap();
let mapping = xcb
.connection
.get_modifier_mapping()
.unwrap()
.reply()
.unwrap();
for (modifier_index, keycodes) in mapping
.keycodes
.chunks(mapping.keycodes_per_modifier() as usize)
.enumerate()
{
println!(
"Mod: {}[{:#x?}] keycodes: {:?}",
modifier_index,
1 << modifier_index,
keycodes
);
}
}
} }
#[repr(u8)] #[repr(u8)]
@ -205,24 +230,29 @@ impl Atoms {
where where
C: Connection, C: Connection,
{ {
let wm_protocols = connection.intern_atom(false, b"WM_PROTOCOLS")?; let wm_protocols =
connection.intern_atom(false, b"WM_PROTOCOLS")?;
let wm_state = connection.intern_atom(false, b"WM_STATE")?; let wm_state = connection.intern_atom(false, b"WM_STATE")?;
let wm_delete_window = let wm_delete_window =
connection.intern_atom(false, b"WM_DELETE_WINDOW")?; connection.intern_atom(false, b"WM_DELETE_WINDOW")?;
let wm_take_focus = connection.intern_atom(false, b"WM_TAKE_FOCUS")?; let wm_take_focus =
let net_supported = connection.intern_atom(false, b"_NET_SUPPORTED")?; connection.intern_atom(false, b"WM_TAKE_FOCUS")?;
let net_supported =
connection.intern_atom(false, b"_NET_SUPPORTED")?;
let net_active_window = let net_active_window =
connection.intern_atom(false, b"_NET_ACTIVE_WINDOW")?; connection.intern_atom(false, b"_NET_ACTIVE_WINDOW")?;
let net_client_list = let net_client_list =
connection.intern_atom(false, b"_NET_CLIENT_LIST")?; connection.intern_atom(false, b"_NET_CLIENT_LIST")?;
let net_wm_name = connection.intern_atom(false, b"_NET_WM_NAME")?; let net_wm_name =
let net_wm_state = connection.intern_atom(false, b"_NET_WM_STATE")?; connection.intern_atom(false, b"_NET_WM_NAME")?;
let net_wm_state_fullscreen = let net_wm_state =
connection.intern_atom(false, b"_NET_WM_STATE_FULLSCREEN")?; connection.intern_atom(false, b"_NET_WM_STATE")?;
let net_wm_state_fullscreen = connection
.intern_atom(false, b"_NET_WM_STATE_FULLSCREEN")?;
let net_wm_window_type = let net_wm_window_type =
connection.intern_atom(false, b"_NET_WM_WINDOW_TYPE")?; connection.intern_atom(false, b"_NET_WM_WINDOW_TYPE")?;
let net_wm_window_type_dialog = let net_wm_window_type_dialog = connection
connection.intern_atom(false, b"_NET_WM_WINDOW_TYPE_DIALOG")?; .intern_atom(false, b"_NET_WM_WINDOW_TYPE_DIALOG")?;
Ok(Self { Ok(Self {
wm_protocols: wm_protocols.reply()?.atom, wm_protocols: wm_protocols.reply()?.atom,
@ -234,9 +264,13 @@ impl Atoms {
net_client_list: net_client_list.reply()?.atom, net_client_list: net_client_list.reply()?.atom,
net_wm_name: net_wm_name.reply()?.atom, net_wm_name: net_wm_name.reply()?.atom,
net_wm_state: net_wm_state.reply()?.atom, net_wm_state: net_wm_state.reply()?.atom,
net_wm_state_fullscreen: net_wm_state_fullscreen.reply()?.atom, net_wm_state_fullscreen: net_wm_state_fullscreen
.reply()?
.atom,
net_wm_window_type: net_wm_window_type.reply()?.atom, net_wm_window_type: net_wm_window_type.reply()?.atom,
net_wm_window_type_dialog: net_wm_window_type_dialog.reply()?.atom, net_wm_window_type_dialog: net_wm_window_type_dialog
.reply()?
.atom,
}) })
} }
} }
@ -250,9 +284,10 @@ where
atoms: Atoms, atoms: Atoms,
} }
pub fn create_backend( pub fn create_backend() -> Result<
) -> Result<X11Backend<impl Connection + Send + Sync>, Box<dyn std::error::Error>> X11Backend<impl Connection + Send + Sync>,
{ Box<dyn std::error::Error>,
> {
let (connection, screen) = connect(None)?; let (connection, screen) = connect(None)?;
Ok(X11Backend::new(Arc::new(connection), screen)?) Ok(X11Backend::new(Arc::new(connection), screen)?)
@ -338,10 +373,14 @@ where
} }
} }
pub fn request_substructure_events(&self) -> Result<(), ReplyError> { pub fn request_substructure_events(
let attributes = ChangeWindowAttributesAux::default().event_mask( &self,
EventMask::SUBSTRUCTURE_REDIRECT | EventMask::SUBSTRUCTURE_NOTIFY, ) -> Result<(), ReplyError> {
); let attributes = ChangeWindowAttributesAux::default()
.event_mask(
EventMask::SUBSTRUCTURE_REDIRECT
| EventMask::SUBSTRUCTURE_NOTIFY,
);
match self match self
.connection .connection

View file

@ -1,34 +0,0 @@
use std::ptr::null;
use x11::xlib::{Window, XRootWindow};
// xlib backend
pub struct XLib {
display: *mut x11::xlib::Display,
screen: i32,
}
impl Drop for XLib {
fn drop(&mut self) {
unsafe {
x11::xlib::XCloseDisplay(self.display);
}
}
}
impl XLib {
pub fn new() -> Self {
let (display, screen) = unsafe {
let display = x11::xlib::XOpenDisplay(null());
let screen = x11::xlib::XDefaultScreen(display);
(display, screen)
};
Self { display, screen }
}
fn root_window(&self) -> Window {
unsafe { XRootWindow(self.display, self.screen) }
}
}

1028
src/backends/xlib/keysym.rs Normal file

File diff suppressed because it is too large Load diff

250
src/backends/xlib/mod.rs Normal file
View file

@ -0,0 +1,250 @@
#![allow(non_upper_case_globals)]
pub mod keysym;
use std::ptr::null;
use x11::xlib::{
ButtonPress, ButtonRelease, ConfigureRequest, CreateNotify,
DestroyNotify, EnterNotify, KeyPress, KeyRelease, MapRequest,
MotionNotify, UnmapNotify, Window, XAnyEvent, XButtonEvent,
XConfigureRequestEvent, XCreateWindowEvent, XDestroyWindowEvent,
XEvent, XKeyEvent, XLookupKeysym, XMapRequestEvent, XMotionEvent,
XNextEvent, XRootWindow, XUnmapEvent,
};
use crate::backends::window_event::{
ButtonEvent, KeyEvent, KeyState, ModifierKey,
};
use self::keysym::{keysym_to_virtual_keycode, xev_to_mouse_button};
use super::window_event::{
ConfigureEvent, CreateEvent, DestroyEvent, MapEvent,
ModifierState, MotionEvent, UnmapEvent, WindowEvent,
};
// xlib backend
pub struct XLib {
display: *mut x11::xlib::Display,
modifier_state: ModifierState,
screen: i32,
}
impl Drop for XLib {
fn drop(&mut self) {
unsafe {
x11::xlib::XCloseDisplay(self.display);
}
}
}
impl XLib {
pub fn new() -> Self {
let (display, screen) = unsafe {
let display = x11::xlib::XOpenDisplay(null());
let screen = x11::xlib::XDefaultScreen(display);
(display, screen)
};
Self {
display,
screen,
modifier_state: Default::default(),
}
}
fn root_window(&self) -> Window {
unsafe { XRootWindow(self.display, self.screen) }
}
fn update_modifier_state(
&mut self,
keyevent: &x11::xlib::XKeyEvent,
) {
//keyevent.keycode
let keysym = self.keyev_to_keysym(keyevent);
use x11::keysym::*;
let modifier = match keysym as u32 {
XK_Shift_L | XK_Shift_R => Some(ModifierKey::Shift),
XK_Control_L | XK_Control_R => Some(ModifierKey::Control),
XK_Alt_L | XK_Alt_R => Some(ModifierKey::Alt),
XK_ISO_Level3_Shift => Some(ModifierKey::AltGr),
XK_Caps_Lock => Some(ModifierKey::ShiftLock),
XK_Num_Lock => Some(ModifierKey::NumLock),
XK_Win_L | XK_Win_R => Some(ModifierKey::Super),
XK_Super_L | XK_Super_R => Some(ModifierKey::Super),
_ => None,
};
if let Some(modifier) = modifier {
match keyevent.type_ {
KeyPress => {
self.modifier_state.set_modifier(modifier)
}
KeyRelease => {
self.modifier_state.set_modifier(modifier)
}
_ => unreachable!(
"keyyevent != (KeyPress | KeyRelease)"
),
}
}
}
fn keyev_to_keysym(&self, keyev: &XKeyEvent) -> u32 {
unsafe {
XLookupKeysym(keyev as *const _ as *mut _, 0) as u32
}
}
pub fn next_event(&self) -> XEvent {
unsafe {
let mut event = std::mem::MaybeUninit::zeroed();
XNextEvent(self.display, event.as_mut_ptr());
event.assume_init()
}
}
fn next_window_event(&mut self) -> WindowEvent {
loop {
let event = self.next_event();
match event.get_type() {
KeyPress | KeyRelease => {
let key_ev: &XKeyEvent = event.as_ref();
self.update_modifier_state(key_ev);
let keycode = keysym_to_virtual_keycode(
self.keyev_to_keysym(event.as_ref()),
);
if let Some(keycode) = keycode {
return WindowEvent::KeyEvent {
window: key_ev.subwindow,
event: KeyEvent::new(
match event.get_type() {
KeyPress => KeyState::Pressed,
KeyRelease => KeyState::Released,
_ => unreachable!(),
},
keycode,
self.modifier_state.clone(),
),
};
}
}
ButtonPress | ButtonRelease => {
let button_ev: &XButtonEvent = event.as_ref();
let button = xev_to_mouse_button(button_ev);
if let Some(button) = button {
return WindowEvent::ButtonEvent {
window: button_ev.subwindow,
event: ButtonEvent::new(
match event.get_type() {
ButtonPress => KeyState::Pressed,
ButtonRelease => {
KeyState::Released
}
_ => unreachable!(),
},
button,
self.modifier_state.clone(),
),
};
}
}
MotionNotify => {
let motion_ev: &XMotionEvent = event.as_ref();
return WindowEvent::MotionEvent {
window: motion_ev.subwindow,
event: MotionEvent::new([
motion_ev.x_root,
motion_ev.y_root,
]),
};
}
MapRequest => {
// MapEvent
let map_ev: &XMapRequestEvent = event.as_ref();
return WindowEvent::MapEvent {
window: map_ev.window,
event: MapEvent::new(map_ev.window),
};
}
UnmapNotify => {
// UnmapEvent
let unmap_ev: &XUnmapEvent = event.as_ref();
return WindowEvent::UnmapEvent {
window: unmap_ev.window,
event: UnmapEvent::new(unmap_ev.window),
};
}
CreateNotify => {
// CreateEvent
let create_ev: &XCreateWindowEvent =
event.as_ref();
return WindowEvent::CreateEvent {
window: create_ev.window,
event: CreateEvent::new(
create_ev.window,
[create_ev.x, create_ev.y],
[create_ev.width, create_ev.height],
),
};
}
DestroyNotify => {
// DestroyEvent
let destroy_ev: &XDestroyWindowEvent =
event.as_ref();
return WindowEvent::DestroyEvent {
window: destroy_ev.window,
event: DestroyEvent::new(destroy_ev.window),
};
}
ConfigureRequest => {
// ConfigureEvent
let configure_ev: &XConfigureRequestEvent =
event.as_ref();
return WindowEvent::ConfigureEvent {
window: configure_ev.window,
event: ConfigureEvent::new(
configure_ev.window,
[configure_ev.x, configure_ev.y],
[configure_ev.width, configure_ev.height],
),
};
}
_ => {}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
//#[test]
// fn window_events() {
// let mut xlib = XLib::new();
// loop {
// if let Some(event) =
// xlib.xevent_to_window_event(xlib.next_event())
// {
// println!("{:#?}", event);
// }
// }
// }
}

View file

@ -185,7 +185,9 @@ where
.map(move |&i| &self.workspaces[i]) .map(move |&i| &self.workspaces[i])
} }
fn get_current_mut(&mut self) -> impl Iterator<Item = &mut Workspace<T>> { fn get_current_mut(
&mut self,
) -> impl Iterator<Item = &mut Workspace<T>> {
let current_indices = &self.current_indices; let current_indices = &self.current_indices;
self.workspaces self.workspaces
@ -217,7 +219,9 @@ where
.flat_map(|w| w.aux.iter()) .flat_map(|w| w.aux.iter())
} }
fn iter_mut_current_master(&mut self) -> impl Iterator<Item = &mut T> { fn iter_mut_current_master(
&mut self,
) -> impl Iterator<Item = &mut T> {
let current_indices = &self.current_indices; let current_indices = &self.current_indices;
self.workspaces self.workspaces
@ -228,7 +232,9 @@ where
.flat_map(|w| w.master.iter_mut()) .flat_map(|w| w.master.iter_mut())
} }
fn iter_mut_current_aux(&mut self) -> impl Iterator<Item = &mut T> { fn iter_mut_current_aux(
&mut self,
) -> impl Iterator<Item = &mut T> {
let current_indices = &self.current_indices; let current_indices = &self.current_indices;
self.workspaces self.workspaces
@ -243,7 +249,9 @@ where
self.workspaces.iter() self.workspaces.iter()
} }
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Workspace<T>> { fn iter_mut(
&mut self,
) -> impl Iterator<Item = &mut Workspace<T>> {
self.workspaces.iter_mut() self.workspaces.iter_mut()
} }
@ -270,13 +278,18 @@ where
where where
Vec<usize>: From<I>, Vec<usize>: From<I>,
{ {
self.previous_indices = self.previous_indices = Some(std::mem::replace(
Some(std::mem::replace(&mut self.current_indices, idx.into())); &mut self.current_indices,
idx.into(),
));
} }
fn select_previous_workspaces(&mut self) { fn select_previous_workspaces(&mut self) {
if let Some(previous_indices) = &mut self.previous_indices { if let Some(previous_indices) = &mut self.previous_indices {
std::mem::swap(previous_indices, &mut self.current_indices); std::mem::swap(
previous_indices,
&mut self.current_indices,
);
} }
} }
@ -394,7 +407,8 @@ where
(dimensions.0 - gap * 2, dimensions.1 - gap * 2) (dimensions.0 - gap * 2, dimensions.1 - gap * 2)
}; };
let len_master = self.workspaces.iter_current_master().count(); let len_master =
self.workspaces.iter_current_master().count();
let len_aux = self.workspaces.iter_current_aux().count(); let len_aux = self.workspaces.iter_current_aux().count();
let width_master = match len_aux { let width_master = match len_aux {
@ -412,18 +426,23 @@ where
n => height / n as i32, n => height / n as i32,
}; };
for (i, id) in self.workspaces.iter_mut_current_master().enumerate() { for (i, id) in
self.workspaces.iter_mut_current_master().enumerate()
{
let size = ( let size = (
width_master - gap * 2 - border * 2, width_master - gap * 2 - border * 2,
height_master - gap * 2 - border * 2, height_master - gap * 2 - border * 2,
); );
let position = (gap * 2, height_master * i as i32 + gap * 2); let position =
(gap * 2, height_master * i as i32 + gap * 2);
if let Some(client) = if let Some(client) =
Option::<&mut Client<T>>::from(self.store.get_mut(id)) Option::<&mut Client<T>>::from(self.store.get_mut(id))
{ {
if *client.position() != position || *client.size() != size { if *client.position() != position
|| *client.size() != size
{
*client.position_mut() = position; *client.position_mut() = position;
*client.size_mut() = size; *client.size_mut() = size;
@ -432,19 +451,25 @@ where
} }
} }
for (i, id) in self.workspaces.iter_mut_current_aux().enumerate() { for (i, id) in
self.workspaces.iter_mut_current_aux().enumerate()
{
let size = ( let size = (
width_aux - gap * 2 - border * 2, width_aux - gap * 2 - border * 2,
height_aux - gap * 2 - border * 2, height_aux - gap * 2 - border * 2,
); );
let position = let position = (
(width_master + gap * 2, height_aux * i as i32 + gap * 2); width_master + gap * 2,
height_aux * i as i32 + gap * 2,
);
if let Some(client) = if let Some(client) =
Option::<&mut Client<T>>::from(self.store.get_mut(id)) Option::<&mut Client<T>>::from(self.store.get_mut(id))
{ {
if *client.position() != position || *client.size() != size { if *client.position() != position
|| *client.size() != size
{
*client.position_mut() = position; *client.position_mut() = position;
*client.size_mut() = size; *client.size_mut() = size;

View file

@ -217,7 +217,8 @@ impl ClientState {
if client.is_transient() if client.is_transient()
&& self.contains(&client.transient_for.unwrap()) && self.contains(&client.transient_for.unwrap())
{ {
let transient = self.get(&client.transient_for.unwrap()).unwrap(); let transient =
self.get(&client.transient_for.unwrap()).unwrap();
client.position = { client.position = {
( (
@ -271,7 +272,9 @@ impl ClientState {
|| self.floating_clients.contains_key(&key) || self.floating_clients.contains_key(&key)
} }
pub fn iter_floating(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_floating(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.floating_clients.iter() self.floating_clients.iter()
} }
@ -283,32 +286,44 @@ impl ClientState {
.filter(move |&(k, _)| self.is_client_visible(k)) .filter(move |&(k, _)| self.is_client_visible(k))
} }
fn iter_all_clients(&self) -> impl Iterator<Item = (&u64, &Client)> { fn iter_all_clients(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.floating_clients.iter().chain(self.clients.iter()) self.floating_clients.iter().chain(self.clients.iter())
} }
pub fn iter_hidden(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_hidden(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.iter_all_clients() self.iter_all_clients()
.filter(move |&(k, _)| !self.is_client_visible(k)) .filter(move |&(k, _)| !self.is_client_visible(k))
} }
pub fn iter_transient(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_transient(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.iter_floating().filter(|&(_, c)| c.is_transient()) self.iter_floating().filter(|&(_, c)| c.is_transient())
} }
pub fn iter_visible(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_visible(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.iter_all_clients() self.iter_all_clients()
.filter(move |&(k, _)| self.is_client_visible(k)) .filter(move |&(k, _)| self.is_client_visible(k))
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn iter_current_screen(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_current_screen(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.clients.iter().filter(move |&(k, _)| { self.clients.iter().filter(move |&(k, _)| {
self.virtual_screens.get_current().contains(k) self.virtual_screens.get_current().contains(k)
}) })
} }
pub fn iter_master_stack(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_master_stack(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.virtual_screens self.virtual_screens
.get_current() .get_current()
.master .master
@ -316,7 +331,9 @@ impl ClientState {
.map(move |k| (k, self.get(k).unwrap())) .map(move |k| (k, self.get(k).unwrap()))
} }
pub fn iter_aux_stack(&self) -> impl Iterator<Item = (&u64, &Client)> { pub fn iter_aux_stack(
&self,
) -> impl Iterator<Item = (&u64, &Client)> {
self.virtual_screens self.virtual_screens
.get_current() .get_current()
.aux .aux
@ -441,12 +458,15 @@ impl ClientState {
// transient clients cannot be tiled // transient clients cannot be tiled
match floating_client.is_transient() { match floating_client.is_transient() {
true => { true => {
self.floating_clients.insert(key, floating_client); self.floating_clients
.insert(key, floating_client);
} }
false => { false => {
self.clients.insert(key, floating_client); self.clients.insert(key, floating_client);
self.virtual_screens.get_mut_current().insert(&key); self.virtual_screens
.get_mut_current()
.insert(&key);
} }
} }
} }
@ -464,7 +484,9 @@ impl ClientState {
K: ClientKey, K: ClientKey,
{ {
if self.contains(key) { if self.contains(key) {
if let Some(vs) = self.get_mut_virtualscreen_for_client(key) { if let Some(vs) =
self.get_mut_virtualscreen_for_client(key)
{
vs.remove(key); vs.remove(key);
// we removed a client so the layout changed, rearrange // we removed a client so the layout changed, rearrange
@ -473,7 +495,10 @@ impl ClientState {
} }
} }
fn get_virtualscreen_for_client<K>(&self, key: &K) -> Option<&VirtualScreen> fn get_virtualscreen_for_client<K>(
&self,
key: &K,
) -> Option<&VirtualScreen>
where where
K: ClientKey, K: ClientKey,
{ {
@ -502,7 +527,10 @@ impl ClientState {
}) })
} }
pub fn get_stack_for_client<K>(&self, key: &K) -> Option<&Vec<u64>> pub fn get_stack_for_client<K>(
&self,
key: &K,
) -> Option<&Vec<u64>>
where where
K: ClientKey, K: ClientKey,
{ {
@ -637,7 +665,8 @@ impl ClientState {
self.master_size / 2.0 self.master_size / 2.0
}; };
let master_width = (effective_width as f32 * master_size) as i32; let master_width =
(effective_width as f32 * master_size) as i32;
let aux_width = effective_width - master_width; let aux_width = effective_width - master_width;
(master_width, aux_width) (master_width, aux_width)
@ -665,7 +694,8 @@ impl ClientState {
master_height - gap * 2 - self.border_size * 2, master_height - gap * 2 - self.border_size * 2,
); );
let position = (gap * 2, master_height * i as i32 + gap * 2); let position =
(gap * 2, master_height * i as i32 + gap * 2);
if let Some(client) = self.clients.get_mut(key) { if let Some(client) = self.clients.get_mut(key) {
*client = Client { *client = Client {
@ -683,8 +713,10 @@ impl ClientState {
aux_height - gap * 2 - self.border_size * 2, aux_height - gap * 2 - self.border_size * 2,
); );
let position = let position = (
(master_width + gap * 2, aux_height * i as i32 + gap * 2); master_width + gap * 2,
aux_height * i as i32 + gap * 2,
);
if let Some(client) = self.clients.get_mut(key) { if let Some(client) = self.clients.get_mut(key) {
*client = Client { *client = Client {
@ -720,7 +752,8 @@ impl VirtualScreen {
where where
K: ClientKey, K: ClientKey,
{ {
self.master.contains(&key.key()) || self.aux.contains(&key.key()) self.master.contains(&key.key())
|| self.aux.contains(&key.key())
} }
fn is_in_master<K>(&self, key: &K) -> bool fn is_in_master<K>(&self, key: &K) -> bool
@ -766,8 +799,11 @@ impl VirtualScreen {
self.aux.extend(self.master.drain(index..=index)); self.aux.extend(self.master.drain(index..=index));
} }
None => { None => {
let index = let index = self
self.aux.iter().position(|&k| k == key.key()).unwrap(); .aux
.iter()
.position(|&k| k == key.key())
.unwrap();
self.master.extend(self.aux.drain(index..=index)); self.master.extend(self.aux.drain(index..=index));
} }
} }
@ -814,7 +850,9 @@ impl VirtualScreenStore {
self.screens.iter() self.screens.iter()
} }
fn iter_mut(&mut self) -> impl Iterator<Item = &mut VirtualScreen> { fn iter_mut(
&mut self,
) -> impl Iterator<Item = &mut VirtualScreen> {
self.screens.iter_mut() self.screens.iter_mut()
} }
@ -861,7 +899,9 @@ impl<T> Into<Option<T>> for ClientEntry<T> {
fn into(self) -> Option<T> { fn into(self) -> Option<T> {
match self { match self {
Self::Vacant => None, Self::Vacant => None,
Self::Tiled(client) | Self::Floating(client) => Some(client), Self::Tiled(client) | Self::Floating(client) => {
Some(client)
}
} }
} }
} }

View file

@ -47,7 +47,10 @@ impl<T> PartialOrd for Client<T>
where where
T: PartialOrd, T: PartialOrd,
{ {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { fn partial_cmp(
&self,
other: &Self,
) -> Option<std::cmp::Ordering> {
self.window_id.partial_cmp(&other.window_id) self.window_id.partial_cmp(&other.window_id)
} }
} }
@ -229,7 +232,10 @@ where
Self::default() Self::default()
} }
pub fn insert(&mut self, entry: Entry<Client<T>>) -> Entry<&Client<T>> { pub fn insert(
&mut self,
entry: Entry<Client<T>>,
) -> Entry<&Client<T>> {
if let Some(key) = if let Some(key) =
Option::<&Client<T>>::from(&entry).map(|c| c.window_id()) Option::<&Client<T>>::from(&entry).map(|c| c.window_id())
{ {
@ -258,11 +264,16 @@ where
pub fn remove(&mut self, key: &T) -> Entry<Client<T>> { pub fn remove(&mut self, key: &T) -> Entry<Client<T>> {
if let Some(client) = self.tiled_clients.remove(key) { if let Some(client) = self.tiled_clients.remove(key) {
Entry::Tiled(client) Entry::Tiled(client)
} else if let Some(client) = self.floating_clients.remove(key) { } else if let Some(client) = self.floating_clients.remove(key)
{
Entry::Floating(client) Entry::Floating(client)
} else if let Some(client) = self.transient_clients.remove(key) { } else if let Some(client) =
self.transient_clients.remove(key)
{
Entry::Transient(client) Entry::Transient(client)
} else if let Some(client) = self.fullscreen_clients.remove(key) { } else if let Some(client) =
self.fullscreen_clients.remove(key)
{
Entry::Fullscreen(client) Entry::Fullscreen(client)
} else { } else {
Entry::Vacant Entry::Vacant
@ -276,7 +287,8 @@ where
Entry::Floating(client) Entry::Floating(client)
} else if let Some(client) = self.transient_clients.get(key) { } else if let Some(client) = self.transient_clients.get(key) {
Entry::Transient(client) Entry::Transient(client)
} else if let Some(client) = self.fullscreen_clients.get(key) { } else if let Some(client) = self.fullscreen_clients.get(key)
{
Entry::Fullscreen(client) Entry::Fullscreen(client)
} else { } else {
Entry::Vacant Entry::Vacant
@ -286,11 +298,17 @@ where
pub fn get_mut(&mut self, key: &T) -> Entry<&mut Client<T>> { pub fn get_mut(&mut self, key: &T) -> Entry<&mut Client<T>> {
if let Some(client) = self.tiled_clients.get_mut(key) { if let Some(client) = self.tiled_clients.get_mut(key) {
Entry::Tiled(client) Entry::Tiled(client)
} else if let Some(client) = self.floating_clients.get_mut(key) { } else if let Some(client) =
self.floating_clients.get_mut(key)
{
Entry::Floating(client) Entry::Floating(client)
} else if let Some(client) = self.transient_clients.get_mut(key) { } else if let Some(client) =
self.transient_clients.get_mut(key)
{
Entry::Transient(client) Entry::Transient(client)
} else if let Some(client) = self.fullscreen_clients.get_mut(key) { } else if let Some(client) =
self.fullscreen_clients.get_mut(key)
{
Entry::Fullscreen(client) Entry::Fullscreen(client)
} else { } else {
Entry::Vacant Entry::Vacant
@ -304,7 +322,9 @@ where
|| self.fullscreen_clients.contains_key(key) || self.fullscreen_clients.contains_key(key)
} }
pub fn iter_tiled(&self) -> impl Iterator<Item = (&T, &Client<T>)> { pub fn iter_tiled(
&self,
) -> impl Iterator<Item = (&T, &Client<T>)> {
self.tiled_clients.iter() self.tiled_clients.iter()
} }
@ -314,7 +334,9 @@ where
self.tiled_clients.iter_mut() self.tiled_clients.iter_mut()
} }
pub fn iter_floating(&self) -> impl Iterator<Item = (&T, &Client<T>)> { pub fn iter_floating(
&self,
) -> impl Iterator<Item = (&T, &Client<T>)> {
self.floating_clients.iter() self.floating_clients.iter()
} }
@ -324,7 +346,9 @@ where
self.floating_clients.iter_mut() self.floating_clients.iter_mut()
} }
pub fn iter_transient(&self) -> impl Iterator<Item = (&T, &Client<T>)> { pub fn iter_transient(
&self,
) -> impl Iterator<Item = (&T, &Client<T>)> {
self.transient_clients.iter() self.transient_clients.iter()
} }
@ -334,7 +358,9 @@ where
self.transient_clients.iter_mut() self.transient_clients.iter_mut()
} }
pub fn iter_fullscreen(&self) -> impl Iterator<Item = (&T, &Client<T>)> { pub fn iter_fullscreen(
&self,
) -> impl Iterator<Item = (&T, &Client<T>)> {
self.fullscreen_clients.iter() self.fullscreen_clients.iter()
} }
@ -372,7 +398,10 @@ mod tests {
Entry::Tiled(client.clone()), Entry::Tiled(client.clone()),
client_store.remove(&client.borrow()) client_store.remove(&client.borrow())
); );
assert_eq!(Entry::Vacant, client_store.remove(&client.borrow())); assert_eq!(
Entry::Vacant,
client_store.remove(&client.borrow())
);
assert_eq!(Entry::Vacant, client_store.remove(&1)); assert_eq!(Entry::Vacant, client_store.remove(&1));
assert!(client_store.contains(&client2.borrow())); assert!(client_store.contains(&client2.borrow()));

View file

@ -23,9 +23,11 @@ fn init_logger() {
"{d(%Y-%m-%d %H:%M:%S %Z)(utc)} │ {({M}::{f}:{L}):>25} │ {h({l:>5})} │ {m}{n}", "{d(%Y-%m-%d %H:%M:%S %Z)(utc)} │ {({M}::{f}:{L}):>25} │ {h({l:>5})} │ {m}{n}",
)); ));
let stdout = ConsoleAppender::builder().encoder(encoder.clone()).build(); let stdout =
ConsoleAppender::builder().encoder(encoder.clone()).build();
let home = dirs::home_dir().expect("Failed to get $HOME env var."); let home =
dirs::home_dir().expect("Failed to get $HOME env var.");
let _logfile = FileAppender::builder() let _logfile = FileAppender::builder()
.encoder(encoder) .encoder(encoder)
@ -33,7 +35,9 @@ fn init_logger() {
.unwrap(); .unwrap();
let config = Config::builder() let config = Config::builder()
.appender(Appender::builder().build("stdout", Box::new(stdout))) .appender(
Appender::builder().build("stdout", Box::new(stdout)),
)
//.appender(Appender::builder().build("logfile", Box::new(logfile))) //.appender(Appender::builder().build("logfile", Box::new(logfile)))
.build( .build(
Root::builder() Root::builder()

View file

@ -151,7 +151,9 @@ impl WindowManager {
.get_focused() .get_focused()
.into_option() .into_option()
.map(|c| c.key()) .map(|c| c.key())
.and_then(|k| Some(wm.clients.toggle_floating(&k))); .and_then(|k| {
Some(wm.clients.toggle_floating(&k))
});
wm.arrange_clients(); wm.arrange_clients();
}, },
@ -224,15 +226,24 @@ impl WindowManager {
} }
fn add_vs_switch_keybinds(&mut self) { fn add_vs_switch_keybinds(&mut self) {
fn rotate_west<const N: usize>(wm: &mut WindowManager, _: &XKeyEvent) { fn rotate_west<const N: usize>(
wm: &mut WindowManager,
_: &XKeyEvent,
) {
wm.rotate_virtual_screen(Direction::West(N)); wm.rotate_virtual_screen(Direction::West(N));
} }
fn rotate_east<const N: usize>(wm: &mut WindowManager, _: &XKeyEvent) { fn rotate_east<const N: usize>(
wm: &mut WindowManager,
_: &XKeyEvent,
) {
wm.rotate_virtual_screen(Direction::East(N)); wm.rotate_virtual_screen(Direction::East(N));
} }
fn goto_nth<const N: usize>(wm: &mut WindowManager, _: &XKeyEvent) { fn goto_nth<const N: usize>(
wm: &mut WindowManager,
_: &XKeyEvent,
) {
wm.go_to_nth_virtual_screen(N) wm.go_to_nth_virtual_screen(N)
} }
@ -333,13 +344,23 @@ impl WindowManager {
match event.get_type() { match event.get_type() {
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 => {
xlib::ButtonRelease => self.button_release(event.as_ref()), self.button_press(event.as_ref())
xlib::MotionNotify => self.motion_notify(event.as_ref()), }
xlib::KeyPress => self.handle_keybinds(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())
}
_ => {} _ => {}
} }
} }
@ -354,7 +375,8 @@ impl WindowManager {
} }
fn kill_client(&mut self, _event: &XKeyEvent) { fn kill_client(&mut self, _event: &XKeyEvent) {
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);
} }
} }
@ -365,7 +387,8 @@ impl WindowManager {
for kb in self.keybinds.clone().into_iter() { for kb in self.keybinds.clone().into_iter() {
if let KeyOrButton::Key(keycode, modmask) = kb.key { if let KeyOrButton::Key(keycode, modmask) = kb.key {
if keycode as u32 == event.keycode if keycode as u32 == event.keycode
&& modmask & clean_mask == event.state & clean_mask && modmask & clean_mask
== event.state & clean_mask
{ {
(kb.closure)(self, event); (kb.closure)(self, event);
} }
@ -409,8 +432,12 @@ impl WindowManager {
fn focus_any(&mut self) { fn focus_any(&mut self) {
// focus first client in all visible clients // focus first client in all visible clients
let to_focus = let to_focus = self
self.clients.iter_visible().next().map(|(k, _)| k).cloned(); .clients
.iter_visible()
.next()
.map(|(k, _)| k)
.cloned();
if let Some(key) = to_focus { if let Some(key) = to_focus {
self.focus_client(&key, false); self.focus_client(&key, false);
@ -418,7 +445,8 @@ impl WindowManager {
} }
fn focus_master_stack(&mut self) { fn focus_master_stack(&mut self) {
let focused = self.clients.get_focused().into_option().map(|c| c.key()); let focused =
self.clients.get_focused().into_option().map(|c| c.key());
let k = self let k = self
.clients .clients
@ -436,7 +464,8 @@ impl WindowManager {
} }
fn focus_aux_stack(&mut self) { fn focus_aux_stack(&mut self) {
let focused = self.clients.get_focused().into_option().map(|c| c.key()); let focused =
self.clients.get_focused().into_option().map(|c| c.key());
let k = self let k = self
.clients .clients
@ -454,12 +483,12 @@ impl WindowManager {
} }
fn focus_up(&mut self) { fn focus_up(&mut self) {
let focused = self.clients.get_focused().into_option().map(|c| c.key()); let focused =
self.clients.get_focused().into_option().map(|c| c.key());
let k = focused.and_then(|focused| { let k = focused.and_then(|focused| {
self.clients self.clients.get_stack_for_client(&focused).and_then(
.get_stack_for_client(&focused) |stack| {
.and_then(|stack| {
stack stack
.iter() .iter()
.rev() .rev()
@ -467,7 +496,8 @@ impl WindowManager {
.skip(1) .skip(1)
.next() .next()
.cloned() .cloned()
}) },
)
}); });
if let Some(k) = k { if let Some(k) = k {
@ -476,19 +506,20 @@ impl WindowManager {
} }
fn focus_down(&mut self) { fn focus_down(&mut self) {
let focused = self.clients.get_focused().into_option().map(|c| c.key()); let focused =
self.clients.get_focused().into_option().map(|c| c.key());
let k = focused.and_then(|focused| { let k = focused.and_then(|focused| {
self.clients self.clients.get_stack_for_client(&focused).and_then(
.get_stack_for_client(&focused) |stack| {
.and_then(|stack| {
stack stack
.iter() .iter()
.skip_while(|&&k| k != focused) .skip_while(|&&k| k != focused)
.skip(1) .skip(1)
.next() .next()
.cloned() .cloned()
}) },
)
}); });
if let Some(k) = k { if let Some(k) = k {
@ -573,7 +604,9 @@ impl WindowManager {
{ {
Client::new_transient( Client::new_transient(
window, window,
self.xlib.get_window_size(window).unwrap_or((100, 100)), self.xlib
.get_window_size(window)
.unwrap_or((100, 100)),
transient_window, transient_window,
) )
} else { } else {
@ -632,7 +665,10 @@ impl WindowManager {
} }
/// ensure event.subwindow refers to a valid client. /// ensure event.subwindow refers to a valid client.
fn start_move_resize_window(&mut self, event: &XButtonPressedEvent) { fn start_move_resize_window(
&mut self,
event: &XButtonPressedEvent,
) {
let window = event.subwindow; let window = event.subwindow;
match event.button { match event.button {
@ -641,15 +677,16 @@ impl WindowManager {
self.arrange_clients(); self.arrange_clients();
} }
self.move_resize_window = MoveResizeInfo::Move(MoveInfoInner { self.move_resize_window =
window, MoveResizeInfo::Move(MoveInfoInner {
starting_cursor_pos: (event.x, event.y), window,
starting_window_pos: self starting_cursor_pos: (event.x, event.y),
.clients starting_window_pos: self
.get(&window) .clients
.unwrap() .get(&window)
.position, .unwrap()
}); .position,
});
} }
3 => { 3 => {
if self.clients.set_floating(&window) { if self.clients.set_floating(&window) {
@ -679,7 +716,10 @@ impl WindowManager {
} }
} }
fn end_move_resize_window(&mut self, event: &XButtonReleasedEvent) { fn end_move_resize_window(
&mut self,
event: &XButtonReleasedEvent,
) {
if event.button == 1 || event.button == 3 { if event.button == 1 || event.button == 3 {
self.move_resize_window = MoveResizeInfo::None; self.move_resize_window = MoveResizeInfo::None;
} }
@ -718,8 +758,14 @@ impl WindowManager {
{ {
let size = &mut client.size; let size = &mut client.size;
size.0 = std::cmp::max(1, info.starting_window_size.0 + x); size.0 = std::cmp::max(
size.1 = std::cmp::max(1, info.starting_window_size.1 + y); 1,
info.starting_window_size.0 + x,
);
size.1 = std::cmp::max(
1,
info.starting_window_size.1 + y,
);
self.xlib.resize_client(client); self.xlib.resize_client(client);
} }
@ -734,10 +780,12 @@ impl WindowManager {
match event.button { match event.button {
1 | 3 => match self.move_resize_window { 1 | 3 => match self.move_resize_window {
MoveResizeInfo::None MoveResizeInfo::None
if self if self.xlib.are_masks_equal(
.xlib event.state,
.are_masks_equal(event.state, self.config.mod_key) self.config.mod_key,
&& self.clients.contains(&event.subwindow) => ) && self
.clients
.contains(&event.subwindow) =>
{ {
self.start_move_resize_window(event) self.start_move_resize_window(event)
} }

View file

@ -4,14 +4,16 @@ use std::{ffi::CString, rc::Rc};
use x11::xlib::{ use x11::xlib::{
self, AnyButton, AnyKey, AnyModifier, Atom, ButtonPressMask, self, AnyButton, AnyKey, AnyModifier, Atom, ButtonPressMask,
ButtonReleaseMask, CWEventMask, ControlMask, CurrentTime, EnterWindowMask, ButtonReleaseMask, CWEventMask, ControlMask, CurrentTime,
FocusChangeMask, LockMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, EnterWindowMask, FocusChangeMask, LockMask, Mod1Mask, Mod2Mask,
Mod5Mask, PointerMotionMask, PropertyChangeMask, ShiftMask, Mod3Mask, Mod4Mask, Mod5Mask, PointerMotionMask,
StructureNotifyMask, SubstructureNotifyMask, SubstructureRedirectMask, PropertyChangeMask, ShiftMask, StructureNotifyMask,
Window, XCloseDisplay, XConfigureRequestEvent, XDefaultScreen, XEvent, SubstructureNotifyMask, SubstructureRedirectMask, Window,
XGetTransientForHint, XGrabPointer, XInternAtom, XKillClient, XMapWindow, XCloseDisplay, XConfigureRequestEvent, XDefaultScreen, XEvent,
XOpenDisplay, XRaiseWindow, XRootWindow, XSetErrorHandler, XSync, XGetTransientForHint, XGrabPointer, XInternAtom, XKillClient,
XUngrabButton, XUngrabKey, XUngrabPointer, XWarpPointer, XWindowAttributes, XMapWindow, XOpenDisplay, XRaiseWindow, XRootWindow,
XSetErrorHandler, XSync, XUngrabButton, XUngrabKey,
XUngrabPointer, XWarpPointer, XWindowAttributes,
}; };
use xlib::GrabModeAsync; use xlib::GrabModeAsync;
@ -45,7 +47,11 @@ impl KeyOrButton {
pub fn key(keycode: i32, modmask: u32) -> Self { pub fn key(keycode: i32, modmask: u32) -> Self {
Self::Key(keycode, modmask) Self::Key(keycode, modmask)
} }
pub fn button(button: u32, modmask: u32, buttonmask: i64) -> Self { pub fn button(
button: u32,
modmask: u32,
buttonmask: i64,
) -> Self {
Self::Button(button, modmask, buttonmask as u64) Self::Button(button, modmask, buttonmask as u64)
} }
} }
@ -78,9 +84,10 @@ impl XLib {
pub fn init(&mut self) { pub fn init(&mut self) {
unsafe { unsafe {
let mut window_attributes = let mut window_attributes = std::mem::MaybeUninit::<
std::mem::MaybeUninit::<xlib::XSetWindowAttributes>::zeroed() xlib::XSetWindowAttributes,
.assume_init(); >::zeroed()
.assume_init();
window_attributes.event_mask = SubstructureRedirectMask window_attributes.event_mask = SubstructureRedirectMask
| StructureNotifyMask | StructureNotifyMask
@ -117,7 +124,12 @@ impl XLib {
#[allow(dead_code)] #[allow(dead_code)]
fn ungrab_global_keybings(&self, window: Window) { fn ungrab_global_keybings(&self, window: Window) {
unsafe { unsafe {
XUngrabButton(self.dpy(), AnyButton as u32, AnyModifier, window); XUngrabButton(
self.dpy(),
AnyButton as u32,
AnyModifier,
window,
);
XUngrabKey(self.dpy(), AnyKey, AnyModifier, window); XUngrabKey(self.dpy(), AnyKey, AnyModifier, window);
} }
} }
@ -143,10 +155,14 @@ impl XLib {
pub fn squash_event(&self, event_type: i32) -> XEvent { pub fn squash_event(&self, event_type: i32) -> XEvent {
unsafe { unsafe {
let mut event = let mut event =
std::mem::MaybeUninit::<xlib::XEvent>::zeroed().assume_init(); std::mem::MaybeUninit::<xlib::XEvent>::zeroed()
.assume_init();
while xlib::XCheckTypedEvent(self.dpy(), event_type, &mut event) while xlib::XCheckTypedEvent(
!= 0 self.dpy(),
event_type,
&mut event,
) != 0
{} {}
event event
@ -156,14 +172,19 @@ impl XLib {
pub fn next_event(&self) -> XEvent { pub fn next_event(&self) -> XEvent {
unsafe { unsafe {
let mut event = let mut event =
std::mem::MaybeUninit::<xlib::XEvent>::zeroed().assume_init(); std::mem::MaybeUninit::<xlib::XEvent>::zeroed()
.assume_init();
xlib::XNextEvent(self.dpy(), &mut event); xlib::XNextEvent(self.dpy(), &mut event);
event event
} }
} }
pub fn grab_key_or_button(&self, window: Window, key: &KeyOrButton) { pub fn grab_key_or_button(
&self,
window: Window,
key: &KeyOrButton,
) {
let numlock_mask = self.get_numlock_mask(); let numlock_mask = self.get_numlock_mask();
let modifiers = let modifiers =
vec![0, LockMask, numlock_mask, LockMask | numlock_mask]; vec![0, LockMask, numlock_mask, LockMask | numlock_mask];
@ -212,7 +233,8 @@ impl XLib {
xlib::CurrentTime, xlib::CurrentTime,
); );
let screen = xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref(); let screen =
xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref();
if let Some(screen) = screen { if let Some(screen) = screen {
xlib::XSetWindowBorder( xlib::XSetWindowBorder(
@ -248,7 +270,8 @@ impl XLib {
xlib::CurrentTime, xlib::CurrentTime,
); );
let screen = xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref(); let screen =
xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref();
if let Some(screen) = screen { if let Some(screen) = screen {
xlib::XSetWindowBorder( xlib::XSetWindowBorder(
@ -284,8 +307,10 @@ impl XLib {
xlib::XConfigureWindow( xlib::XConfigureWindow(
self.dpy(), self.dpy(),
client.window, client.window,
(xlib::CWY | xlib::CWX | xlib::CWHeight | xlib::CWWidth) (xlib::CWY
as u32, | xlib::CWX
| xlib::CWHeight
| xlib::CWWidth) as u32,
&mut windowchanges, &mut windowchanges,
); );
@ -376,14 +401,18 @@ impl XLib {
} }
} }
pub fn get_window_size(&self, window: Window) -> Option<(i32, i32)> { pub fn get_window_size(
&self,
window: Window,
) -> Option<(i32, i32)> {
let mut wa = unsafe { let mut wa = unsafe {
std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed() std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed()
.assume_init() .assume_init()
}; };
if unsafe { if unsafe {
xlib::XGetWindowAttributes(self.dpy(), window, &mut wa) != 0 xlib::XGetWindowAttributes(self.dpy(), window, &mut wa)
!= 0
} { } {
Some((wa.width, wa.height)) Some((wa.width, wa.height))
} else { } else {
@ -401,7 +430,8 @@ impl XLib {
}; };
if unsafe { if unsafe {
xlib::XGetWindowAttributes(self.dpy(), window, &mut wa) != 0 xlib::XGetWindowAttributes(self.dpy(), window, &mut wa)
!= 0
} { } {
Some(wa) Some(wa)
} else { } else {
@ -409,11 +439,18 @@ impl XLib {
} }
} }
pub fn get_transient_for_window(&self, window: Window) -> Option<Window> { pub fn get_transient_for_window(
&self,
window: Window,
) -> Option<Window> {
let mut transient_for: Window = 0; let mut transient_for: Window = 0;
if unsafe { if unsafe {
XGetTransientForHint(self.dpy(), window, &mut transient_for) != 0 XGetTransientForHint(
self.dpy(),
window,
&mut transient_for,
) != 0
} { } {
Some(transient_for) Some(transient_for)
} else { } else {
@ -515,13 +552,21 @@ impl XLib {
pub fn dimensions(&self) -> (i32, i32) { pub fn dimensions(&self) -> (i32, i32) {
unsafe { unsafe {
let mut wa = let mut wa = std::mem::MaybeUninit::<
std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed() xlib::XWindowAttributes,
.assume_init(); >::zeroed()
.assume_init();
xlib::XGetWindowAttributes(self.dpy(), self.root, &mut wa); xlib::XGetWindowAttributes(
self.dpy(),
self.root,
&mut wa,
);
info!("Root window dimensions: {}, {}", wa.width, wa.height); info!(
"Root window dimensions: {}, {}",
wa.width, wa.height
);
(wa.width, wa.height) (wa.width, wa.height)
} }
@ -547,8 +592,9 @@ impl XLib {
self.dpy(), self.dpy(),
self.root, self.root,
0, 0,
(ButtonPressMask | ButtonReleaseMask | PointerMotionMask) (ButtonPressMask
as u32, | ButtonReleaseMask
| PointerMotionMask) as u32,
GrabModeAsync, GrabModeAsync,
GrabModeAsync, GrabModeAsync,
0, 0,
@ -564,7 +610,11 @@ impl XLib {
} }
} }
pub fn move_cursor(&self, window: Option<Window>, position: (i32, i32)) { pub fn move_cursor(
&self,
window: Option<Window>,
position: (i32, i32),
) {
unsafe { unsafe {
XWarpPointer( XWarpPointer(
self.dpy(), self.dpy(),
@ -580,7 +630,11 @@ impl XLib {
} }
} }
fn check_for_protocol(&self, client: &Client, proto: xlib::Atom) -> bool { fn check_for_protocol(
&self,
client: &Client,
proto: xlib::Atom,
) -> bool {
let mut protos: *mut xlib::Atom = null_mut(); let mut protos: *mut xlib::Atom = null_mut();
let mut num_protos: i32 = 0; let mut num_protos: i32 = 0;
@ -603,7 +657,11 @@ impl XLib {
return false; return false;
} }
fn send_protocol(&self, client: &Client, proto: xlib::Atom) -> bool { fn send_protocol(
&self,
client: &Client,
proto: xlib::Atom,
) -> bool {
if self.check_for_protocol(client, proto) { if self.check_for_protocol(client, proto) {
let mut data = xlib::ClientMessageData::default(); let mut data = xlib::ClientMessageData::default();
data.set_long(0, proto as i64); data.set_long(0, proto as i64);
@ -723,19 +781,37 @@ impl Atoms {
Self { Self {
protocols: { protocols: {
let name = CString::new("WM_PROTOCOLS").unwrap(); let name = CString::new("WM_PROTOCOLS").unwrap();
XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) XInternAtom(
display.get(),
name.as_c_str().as_ptr(),
0,
)
}, },
delete_window: { delete_window: {
let name = CString::new("WM_DELETE_WINDOW").unwrap(); let name =
XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) CString::new("WM_DELETE_WINDOW").unwrap();
XInternAtom(
display.get(),
name.as_c_str().as_ptr(),
0,
)
}, },
active_window: { active_window: {
let name = CString::new("WM_ACTIVE_WINDOW").unwrap(); let name =
XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) CString::new("WM_ACTIVE_WINDOW").unwrap();
XInternAtom(
display.get(),
name.as_c_str().as_ptr(),
0,
)
}, },
take_focus: { take_focus: {
let name = CString::new("WM_TAKE_FOCUS").unwrap(); let name = CString::new("WM_TAKE_FOCUS").unwrap();
XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) XInternAtom(
display.get(),
name.as_c_str().as_ptr(),
0,
)
}, },
} }
} }