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