Compare commits
No commits in common. "ae89404de3110957b11797f4778d7ff8eb6c5ade" and "364d621b72874ccccd0c76207c24e83a8e083a32" have entirely different histories.
ae89404de3
...
364d621b72
21
Cargo.toml
21
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "wm"
|
name = "wm"
|
||||||
version = "0.3.0"
|
version = "0.2.1"
|
||||||
authors = ["noonebtw <noonebtw@gmail.com>"]
|
authors = ["noonebtw <noonebtw@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
@ -11,17 +11,16 @@ path = "src/main.rs"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
x11 = {version = "2.19", features = ["xlib", "xft"] }
|
x11 = {version = "2.18.2", features = ["xlib", "xft"] }
|
||||||
log = "0.4"
|
log = "0.4.13"
|
||||||
simple_logger = "2.0"
|
simple_logger = "1.11.0"
|
||||||
dirs = "3.0.0"
|
dirs = "3.0.2"
|
||||||
log4rs = "1.0"
|
log4rs = "1.0.0"
|
||||||
indexmap = "1.0"
|
indexmap = "1.6.2"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0.30"
|
||||||
bitflags = "1.3"
|
bitflags = "1.3.2"
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2.14"
|
||||||
strum = {version = "0.24.0", features = ["derive"]}
|
strum = {version = "0.24.0", features = ["derive"]}
|
||||||
bytemuck = "1.0"
|
|
||||||
|
|
|
@ -18,11 +18,4 @@ pub mod structs {
|
||||||
Dock,
|
Dock,
|
||||||
Desktop,
|
Desktop,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
|
||||||
pub enum Cursor {
|
|
||||||
Normal,
|
|
||||||
Resize,
|
|
||||||
Move,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use super::{
|
use super::keycodes::{KeyOrButton, MouseButton, VirtualKeyCode};
|
||||||
keycodes::{KeyOrButton, MouseButton, VirtualKeyCode},
|
|
||||||
structs::WindowType,
|
|
||||||
};
|
|
||||||
use crate::util::{Point, Size};
|
use crate::util::{Point, Size};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub enum WindowEvent<Window> {
|
pub enum WindowEvent<Window> {
|
||||||
KeyEvent(KeyEvent<Window>),
|
KeyEvent(KeyEvent<Window>),
|
||||||
ButtonEvent(ButtonEvent<Window>),
|
ButtonEvent(ButtonEvent<Window>),
|
||||||
|
@ -21,7 +18,6 @@ pub enum WindowEvent<Window> {
|
||||||
ConfigureEvent(ConfigureEvent<Window>),
|
ConfigureEvent(ConfigureEvent<Window>),
|
||||||
FullscreenEvent(FullscreenEvent<Window>), //1 { window: Window, event: 1 },
|
FullscreenEvent(FullscreenEvent<Window>), //1 { window: Window, event: 1 },
|
||||||
WindowNameEvent(WindowNameEvent<Window>),
|
WindowNameEvent(WindowNameEvent<Window>),
|
||||||
WindowTypeChangedEvent(WindowTypeChangedEvent<Window>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
|
@ -111,7 +107,7 @@ impl Into<u8> for ModifierKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct KeyEvent<Window> {
|
pub struct KeyEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub state: KeyState,
|
pub state: KeyState,
|
||||||
|
@ -135,7 +131,7 @@ impl<Window> KeyEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct ButtonEvent<Window> {
|
pub struct ButtonEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub state: KeyState,
|
pub state: KeyState,
|
||||||
|
@ -162,7 +158,7 @@ impl<Window> ButtonEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct MotionEvent<Window> {
|
pub struct MotionEvent<Window> {
|
||||||
pub position: Point<i32>,
|
pub position: Point<i32>,
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
|
@ -174,22 +170,22 @@ impl<Window> MotionEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct MapEvent<Window> {
|
pub struct MapEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct UnmapEvent<Window> {
|
pub struct UnmapEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct EnterEvent<Window> {
|
pub struct EnterEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct DestroyEvent<Window> {
|
pub struct DestroyEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
}
|
}
|
||||||
|
@ -200,7 +196,7 @@ impl<Window> DestroyEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct CreateEvent<Window> {
|
pub struct CreateEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub position: Point<i32>,
|
pub position: Point<i32>,
|
||||||
|
@ -217,7 +213,7 @@ impl<Window> CreateEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct ConfigureEvent<Window> {
|
pub struct ConfigureEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub position: Point<i32>,
|
pub position: Point<i32>,
|
||||||
|
@ -234,7 +230,7 @@ impl<Window> ConfigureEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub enum FullscreenState {
|
pub enum FullscreenState {
|
||||||
On,
|
On,
|
||||||
Off,
|
Off,
|
||||||
|
@ -250,7 +246,7 @@ impl From<bool> for FullscreenState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct FullscreenEvent<Window> {
|
pub struct FullscreenEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub state: FullscreenState,
|
pub state: FullscreenState,
|
||||||
|
@ -262,7 +258,7 @@ impl<Window> FullscreenEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct WindowNameEvent<Window> {
|
pub struct WindowNameEvent<Window> {
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -274,21 +270,6 @@ impl<Window> WindowNameEvent<Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct WindowTypeChangedEvent<Window> {
|
|
||||||
pub window: Window,
|
|
||||||
pub window_type: WindowType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Window> WindowTypeChangedEvent<Window> {
|
|
||||||
pub fn new(window: Window, window_type: WindowType) -> Self {
|
|
||||||
Self {
|
|
||||||
window,
|
|
||||||
window_type,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct KeyBind {
|
pub struct KeyBind {
|
||||||
pub key: VirtualKeyCode,
|
pub key: VirtualKeyCode,
|
||||||
|
|
|
@ -4,15 +4,14 @@ use std::{convert::TryFrom, ptr::NonNull, rc::Rc};
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use x11::xlib::{self, Atom, Success, Window, XEvent, XKeyEvent, XA_WINDOW};
|
use x11::xlib::{self, Atom, Success, XEvent, XKeyEvent};
|
||||||
|
|
||||||
use crate::backends::{
|
use crate::backends::{
|
||||||
keycodes::KeyOrButton, xlib::keysym::mouse_button_to_xbutton,
|
keycodes::KeyOrButton, xlib::keysym::mouse_button_to_xbutton,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
connection::{PropMode, XLibConnection},
|
connection::XLibConnection,
|
||||||
cursors::Cursors,
|
|
||||||
ewmh::{EWMHAtom, EWMHAtoms},
|
ewmh::{EWMHAtom, EWMHAtoms},
|
||||||
keysym::{
|
keysym::{
|
||||||
keysym_to_virtual_keycode, virtual_keycode_to_keysym,
|
keysym_to_virtual_keycode, virtual_keycode_to_keysym,
|
||||||
|
@ -28,7 +27,6 @@ use super::{
|
||||||
ButtonEvent, ConfigureEvent, DestroyEvent, EnterEvent, FullscreenEvent,
|
ButtonEvent, ConfigureEvent, DestroyEvent, EnterEvent, FullscreenEvent,
|
||||||
FullscreenState, KeyEvent, KeyOrMouseBind, KeyState, MapEvent,
|
FullscreenState, KeyEvent, KeyOrMouseBind, KeyState, MapEvent,
|
||||||
ModifierState, MotionEvent, UnmapEvent, WindowEvent, WindowNameEvent,
|
ModifierState, MotionEvent, UnmapEvent, WindowEvent, WindowNameEvent,
|
||||||
WindowTypeChangedEvent,
|
|
||||||
},
|
},
|
||||||
WindowServerBackend,
|
WindowServerBackend,
|
||||||
};
|
};
|
||||||
|
@ -37,7 +35,7 @@ use crate::util::{Point, Size};
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod keysym;
|
pub mod keysym;
|
||||||
|
|
||||||
pub type XLibWindowEvent = WindowEvent<Window>;
|
pub type XLibWindowEvent = WindowEvent<xlib::Window>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Display(Rc<NonNull<x11::xlib::Display>>);
|
pub struct Display(Rc<NonNull<x11::xlib::Display>>);
|
||||||
|
@ -124,7 +122,6 @@ pub mod wmh {
|
||||||
WmTakeFocus,
|
WmTakeFocus,
|
||||||
WmState,
|
WmState,
|
||||||
WmTransientFor,
|
WmTransientFor,
|
||||||
Utf8String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -188,7 +185,6 @@ pub mod wmh {
|
||||||
ICCCMAtom::WmTakeFocus => "WM_TAKE_FOCUS",
|
ICCCMAtom::WmTakeFocus => "WM_TAKE_FOCUS",
|
||||||
ICCCMAtom::WmState => "WM_STATE",
|
ICCCMAtom::WmState => "WM_STATE",
|
||||||
ICCCMAtom::WmTransientFor => "WM_TRANSIENT_FOR",
|
ICCCMAtom::WmTransientFor => "WM_TRANSIENT_FOR",
|
||||||
ICCCMAtom::Utf8String => "UTF8_STRING",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,14 +472,12 @@ pub mod ewmh {
|
||||||
pub mod connection {
|
pub mod connection {
|
||||||
use std::{
|
use std::{
|
||||||
ffi::CString,
|
ffi::CString,
|
||||||
mem::size_of,
|
|
||||||
os::raw::{c_char, c_long},
|
os::raw::{c_char, c_long},
|
||||||
};
|
};
|
||||||
|
|
||||||
use bytemuck::from_bytes;
|
|
||||||
use x11::xlib::{self, Atom, Window};
|
use x11::xlib::{self, Atom, Window};
|
||||||
|
|
||||||
use super::{xpointer::XPointer, Display};
|
use super::Display;
|
||||||
|
|
||||||
pub struct XLibConnection {
|
pub struct XLibConnection {
|
||||||
display: Display,
|
display: Display,
|
||||||
|
@ -545,61 +539,6 @@ pub mod connection {
|
||||||
self.screen
|
self.screen
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_window_property(
|
|
||||||
&self,
|
|
||||||
window: Window,
|
|
||||||
atom: Atom,
|
|
||||||
atom_type: Atom,
|
|
||||||
) -> Option<Vec<u8>> {
|
|
||||||
let mut format_returned = 0;
|
|
||||||
let mut items_returned = 0;
|
|
||||||
let mut bytes_after_return = 0;
|
|
||||||
let mut type_returned = 0;
|
|
||||||
|
|
||||||
let (ptr, success) =
|
|
||||||
XPointer::<u8>::build_with_result(|ptr| unsafe {
|
|
||||||
xlib::XGetWindowProperty(
|
|
||||||
self.dpy(),
|
|
||||||
window,
|
|
||||||
atom,
|
|
||||||
0,
|
|
||||||
4096 / 4,
|
|
||||||
0,
|
|
||||||
atom_type,
|
|
||||||
&mut type_returned,
|
|
||||||
&mut format_returned,
|
|
||||||
&mut items_returned,
|
|
||||||
&mut bytes_after_return,
|
|
||||||
ptr as *mut _ as *mut _,
|
|
||||||
) == i32::from(xlib::Success)
|
|
||||||
});
|
|
||||||
|
|
||||||
success.then(|| ptr).flatten().map(|ptr| {
|
|
||||||
unsafe {
|
|
||||||
std::slice::from_raw_parts(
|
|
||||||
ptr.as_ptr(),
|
|
||||||
items_returned as usize * format_returned as usize,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.to_vec()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_property_long(
|
|
||||||
&self,
|
|
||||||
window: Window,
|
|
||||||
atom: Atom,
|
|
||||||
atom_type: Atom,
|
|
||||||
) -> Option<Vec<c_long>> {
|
|
||||||
self.get_window_property(window, atom, atom_type)
|
|
||||||
.map(|bytes| {
|
|
||||||
bytes
|
|
||||||
.chunks(size_of::<c_long>())
|
|
||||||
.map(|bytes| *from_bytes::<c_long>(bytes))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_text_property(
|
pub fn get_text_property(
|
||||||
&self,
|
&self,
|
||||||
window: Window,
|
window: Window,
|
||||||
|
@ -626,59 +565,20 @@ pub mod connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_property(&self, window: Window, atom: Atom) {
|
|
||||||
unsafe {
|
|
||||||
xlib::XDeleteProperty(self.dpy(), window, atom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_property_byte<T: AsRef<[u8]>>(
|
|
||||||
&self,
|
|
||||||
window: Window,
|
|
||||||
atom: Atom,
|
|
||||||
atom_type: Atom,
|
|
||||||
mode: PropMode,
|
|
||||||
data: T,
|
|
||||||
) {
|
|
||||||
unsafe {
|
|
||||||
xlib::XChangeProperty(
|
|
||||||
self.dpy(),
|
|
||||||
window,
|
|
||||||
atom,
|
|
||||||
atom_type,
|
|
||||||
8,
|
|
||||||
mode.into(),
|
|
||||||
data.as_ref().as_ptr().cast::<u8>(),
|
|
||||||
data.as_ref().len() as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_root_property_byte<T: AsRef<[u8]>>(
|
pub fn change_root_property_byte<T: AsRef<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
atom: Atom,
|
atom: Atom,
|
||||||
atom_type: Atom,
|
atom_type: Atom,
|
||||||
mode: PropMode,
|
mode: PropMode,
|
||||||
data: T,
|
data: T,
|
||||||
) {
|
|
||||||
self.change_property_byte(self.root, atom, atom_type, mode, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_property_long<T: AsRef<[c_long]>>(
|
|
||||||
&self,
|
|
||||||
window: Window,
|
|
||||||
atom: Atom,
|
|
||||||
atom_type: Atom,
|
|
||||||
mode: PropMode,
|
|
||||||
data: T,
|
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
xlib::XChangeProperty(
|
xlib::XChangeProperty(
|
||||||
self.dpy(),
|
self.dpy(),
|
||||||
window,
|
self.root,
|
||||||
atom,
|
atom,
|
||||||
atom_type,
|
atom_type,
|
||||||
32,
|
8,
|
||||||
mode.into(),
|
mode.into(),
|
||||||
data.as_ref().as_ptr().cast::<u8>(),
|
data.as_ref().as_ptr().cast::<u8>(),
|
||||||
data.as_ref().len() as i32,
|
data.as_ref().len() as i32,
|
||||||
|
@ -693,7 +593,18 @@ pub mod connection {
|
||||||
mode: PropMode,
|
mode: PropMode,
|
||||||
data: T,
|
data: T,
|
||||||
) {
|
) {
|
||||||
self.change_property_long(self.root, atom, atom_type, mode, data)
|
unsafe {
|
||||||
|
xlib::XChangeProperty(
|
||||||
|
self.dpy(),
|
||||||
|
self.root,
|
||||||
|
atom,
|
||||||
|
atom_type,
|
||||||
|
32,
|
||||||
|
mode.into(),
|
||||||
|
data.as_ref().as_ptr().cast::<u8>(),
|
||||||
|
data.as_ref().len() as i32,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,77 +625,14 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod cursors {
|
|
||||||
use std::{borrow::Borrow, ops::Index};
|
|
||||||
|
|
||||||
use x11::xlib::{Cursor as XCursor, XCreateFontCursor, XFreeCursor};
|
|
||||||
|
|
||||||
use crate::backends::structs::Cursor;
|
|
||||||
|
|
||||||
use super::connection::XLibConnection;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
|
||||||
pub struct Cursors {
|
|
||||||
normal: XCursor,
|
|
||||||
resize: XCursor,
|
|
||||||
grab: XCursor,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Cursors {
|
|
||||||
const LEFT_PTR: u32 = 68;
|
|
||||||
const SIZING: u32 = 120;
|
|
||||||
const FLEUR: u32 = 52;
|
|
||||||
|
|
||||||
pub fn from_connection<C: Borrow<XLibConnection>>(con: C) -> Self {
|
|
||||||
unsafe {
|
|
||||||
Self {
|
|
||||||
normal: XCreateFontCursor(
|
|
||||||
con.borrow().dpy(),
|
|
||||||
Self::LEFT_PTR,
|
|
||||||
),
|
|
||||||
resize: XCreateFontCursor(con.borrow().dpy(), Self::SIZING),
|
|
||||||
grab: XCreateFontCursor(con.borrow().dpy(), Self::FLEUR),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn free<C: Borrow<XLibConnection>>(&self, con: C) {
|
|
||||||
unsafe {
|
|
||||||
XFreeCursor(con.borrow().dpy(), self.normal);
|
|
||||||
XFreeCursor(con.borrow().dpy(), self.resize);
|
|
||||||
XFreeCursor(con.borrow().dpy(), self.grab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Index<Cursor> for Cursors {
|
|
||||||
type Output = XCursor;
|
|
||||||
|
|
||||||
fn index(&self, index: Cursor) -> &Self::Output {
|
|
||||||
match index {
|
|
||||||
Cursor::Normal => &self.normal,
|
|
||||||
Cursor::Resize => &self.resize,
|
|
||||||
Cursor::Move => &self.grab,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct XLib {
|
pub struct XLib {
|
||||||
connection: Rc<XLibConnection>,
|
connection: Rc<XLibConnection>,
|
||||||
|
//atoms: XLibAtoms,
|
||||||
atoms: ICCCMAtoms,
|
atoms: ICCCMAtoms,
|
||||||
ewmh_atoms: EWMHAtoms,
|
ewmh_atoms: EWMHAtoms,
|
||||||
keybinds: Vec<KeyOrMouseBind>,
|
keybinds: Vec<KeyOrMouseBind>,
|
||||||
active_border_color: Option<color::XftColor>,
|
active_border_color: Option<color::XftColor>,
|
||||||
inactive_border_color: Option<color::XftColor>,
|
inactive_border_color: Option<color::XftColor>,
|
||||||
wm_window: Window,
|
|
||||||
cursors: Cursors,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for XLib {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { self.cursors.free(self.connection.clone()) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XLib {
|
impl XLib {
|
||||||
|
@ -800,20 +648,6 @@ impl XLib {
|
||||||
keybinds: Vec::new(),
|
keybinds: Vec::new(),
|
||||||
active_border_color: None,
|
active_border_color: None,
|
||||||
inactive_border_color: None,
|
inactive_border_color: None,
|
||||||
cursors: Cursors::from_connection(con.clone()),
|
|
||||||
wm_window: unsafe {
|
|
||||||
xlib::XCreateSimpleWindow(
|
|
||||||
con.dpy(),
|
|
||||||
con.root(),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,34 +680,6 @@ impl XLib {
|
||||||
xlib::XSync(self.dpy(), 0);
|
xlib::XSync(self.dpy(), 0);
|
||||||
|
|
||||||
self.ewmh_atoms.set_supported_atoms(self.connection.clone());
|
self.ewmh_atoms.set_supported_atoms(self.connection.clone());
|
||||||
self.connection.delete_property(
|
|
||||||
self.connection.root(),
|
|
||||||
self.ewmh_atoms[EWMHAtom::NetClientList],
|
|
||||||
);
|
|
||||||
|
|
||||||
self.connection.change_property_long(
|
|
||||||
self.wm_window,
|
|
||||||
self.ewmh_atoms[EWMHAtom::NetSupportingWmCheck],
|
|
||||||
XA_WINDOW,
|
|
||||||
PropMode::Replace,
|
|
||||||
&[self.wm_window as i64],
|
|
||||||
);
|
|
||||||
|
|
||||||
self.connection.change_property_long(
|
|
||||||
self.connection.root(),
|
|
||||||
self.ewmh_atoms[EWMHAtom::NetSupportingWmCheck],
|
|
||||||
XA_WINDOW,
|
|
||||||
PropMode::Replace,
|
|
||||||
&[self.wm_window as i64],
|
|
||||||
);
|
|
||||||
|
|
||||||
self.connection.change_property_byte(
|
|
||||||
self.wm_window,
|
|
||||||
self.ewmh_atoms[EWMHAtom::NetWmName],
|
|
||||||
self.atoms[ICCCMAtom::Utf8String],
|
|
||||||
PropMode::Replace,
|
|
||||||
"nirgendwm".as_bytes(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[deprecated = "use `self.connection.dpy()` instead"]
|
//#[deprecated = "use `self.connection.dpy()` instead"]
|
||||||
|
@ -997,12 +803,28 @@ impl XLib {
|
||||||
atom if atom
|
atom if atom
|
||||||
== self.ewmh_atoms[EWMHAtom::NetWmWindowType] =>
|
== self.ewmh_atoms[EWMHAtom::NetWmWindowType] =>
|
||||||
{
|
{
|
||||||
Some(XLibWindowEvent::WindowTypeChangedEvent(
|
if self
|
||||||
WindowTypeChangedEvent::new(
|
.get_atom_property(
|
||||||
ev.window,
|
ev.window,
|
||||||
self.get_window_type(ev.window),
|
self.ewmh_atoms[EWMHAtom::NetWmState],
|
||||||
),
|
)
|
||||||
))
|
.map(|atom| {
|
||||||
|
*atom
|
||||||
|
== self.ewmh_atoms
|
||||||
|
[EWMHAtom::NetWmStateFullscreen]
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
debug!("fullscreen event");
|
||||||
|
Some(XLibWindowEvent::FullscreenEvent(
|
||||||
|
FullscreenEvent::new(
|
||||||
|
ev.window,
|
||||||
|
FullscreenState::On,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +872,7 @@ impl XLib {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn get_window_attributes(
|
fn get_window_attributes(
|
||||||
&self,
|
&self,
|
||||||
window: Window,
|
window: xlib::Window,
|
||||||
) -> Option<xlib::XWindowAttributes> {
|
) -> Option<xlib::XWindowAttributes> {
|
||||||
let mut wa = unsafe {
|
let mut wa = unsafe {
|
||||||
std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed()
|
std::mem::MaybeUninit::<xlib::XWindowAttributes>::zeroed()
|
||||||
|
@ -1068,7 +890,7 @@ impl XLib {
|
||||||
|
|
||||||
fn get_atom_property(
|
fn get_atom_property(
|
||||||
&self,
|
&self,
|
||||||
window: Window,
|
window: xlib::Window,
|
||||||
atom: xlib::Atom,
|
atom: xlib::Atom,
|
||||||
) -> Option<xpointer::XPointer<xlib::Atom>> {
|
) -> Option<xpointer::XPointer<xlib::Atom>> {
|
||||||
let mut di = 0;
|
let mut di = 0;
|
||||||
|
@ -1097,7 +919,11 @@ impl XLib {
|
||||||
success.then(|| atom_out).flatten()
|
success.then(|| atom_out).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_protocol(&self, window: Window, proto: xlib::Atom) -> bool {
|
fn check_for_protocol(
|
||||||
|
&self,
|
||||||
|
window: xlib::Window,
|
||||||
|
proto: xlib::Atom,
|
||||||
|
) -> bool {
|
||||||
let mut protos: *mut xlib::Atom = std::ptr::null_mut();
|
let mut protos: *mut xlib::Atom = std::ptr::null_mut();
|
||||||
let mut num_protos: i32 = 0;
|
let mut num_protos: i32 = 0;
|
||||||
|
|
||||||
|
@ -1120,7 +946,7 @@ impl XLib {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_protocol(&self, window: Window, proto: Atom) -> bool {
|
fn send_protocol(&self, window: xlib::Window, proto: Atom) -> bool {
|
||||||
if self.check_for_protocol(window, proto) {
|
if self.check_for_protocol(window, 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);
|
||||||
|
@ -1206,7 +1032,11 @@ impl XLib {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grab_key_or_button(&self, binding: &KeyOrMouseBind, window: Window) {
|
fn grab_key_or_button(
|
||||||
|
&self,
|
||||||
|
binding: &KeyOrMouseBind,
|
||||||
|
window: xlib::Window,
|
||||||
|
) {
|
||||||
let modmask = binding.modifiers.as_modmask(self);
|
let modmask = binding.modifiers.as_modmask(self);
|
||||||
|
|
||||||
let numlock_mask = self
|
let numlock_mask = self
|
||||||
|
@ -1260,7 +1090,11 @@ impl XLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn ungrab_key_or_button(&self, binding: &KeyOrMouseBind, window: Window) {
|
fn ungrab_key_or_button(
|
||||||
|
&self,
|
||||||
|
binding: &KeyOrMouseBind,
|
||||||
|
window: xlib::Window,
|
||||||
|
) {
|
||||||
let modmask = binding.modifiers.as_modmask(self);
|
let modmask = binding.modifiers.as_modmask(self);
|
||||||
|
|
||||||
let numlock_mask = self
|
let numlock_mask = self
|
||||||
|
@ -1301,7 +1135,7 @@ impl XLib {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grab_global_keybinds(&self, window: Window) {
|
fn grab_global_keybinds(&self, window: xlib::Window) {
|
||||||
for binding in self.keybinds.iter() {
|
for binding in self.keybinds.iter() {
|
||||||
self.grab_key_or_button(binding, window);
|
self.grab_key_or_button(binding, window);
|
||||||
}
|
}
|
||||||
|
@ -1363,7 +1197,7 @@ impl ModifierStateExt for ModifierState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowServerBackend for XLib {
|
impl WindowServerBackend for XLib {
|
||||||
type Window = Window;
|
type Window = xlib::Window;
|
||||||
|
|
||||||
fn build() -> Self {
|
fn build() -> Self {
|
||||||
let xlib = Self::new();
|
let xlib = Self::new();
|
||||||
|
@ -1377,7 +1211,6 @@ impl WindowServerBackend for XLib {
|
||||||
let ev = self.xevent_to_window_event(ev);
|
let ev = self.xevent_to_window_event(ev);
|
||||||
|
|
||||||
if let Some(ev) = ev {
|
if let Some(ev) = ev {
|
||||||
self.handle_event(ev.clone());
|
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1403,34 +1236,14 @@ impl WindowServerBackend for XLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.grab_global_keybinds(event.window);
|
self.grab_global_keybinds(event.window);
|
||||||
|
|
||||||
// add window to client list
|
|
||||||
self.connection.change_root_property_long(
|
|
||||||
self.ewmh_atoms[EWMHAtom::NetClientList],
|
|
||||||
XA_WINDOW,
|
|
||||||
PropMode::Append,
|
|
||||||
&[event.window as i64],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
WindowEvent::DestroyEvent(event) => {
|
WindowEvent::ConfigureEvent(event) => {
|
||||||
self.connection
|
self.configure_window(
|
||||||
.get_property_long(
|
event.window,
|
||||||
self.connection.root(),
|
Some(event.size),
|
||||||
self.ewmh_atoms[EWMHAtom::NetClientList],
|
Some(event.position),
|
||||||
XA_WINDOW,
|
None,
|
||||||
)
|
);
|
||||||
.map(|mut clients| {
|
|
||||||
clients
|
|
||||||
.retain(|&window| window as Window != event.window);
|
|
||||||
|
|
||||||
self.connection.change_property_long(
|
|
||||||
self.connection.root(),
|
|
||||||
self.ewmh_atoms[EWMHAtom::NetClientList],
|
|
||||||
XA_WINDOW,
|
|
||||||
PropMode::Replace,
|
|
||||||
&clients,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1799,10 +1612,6 @@ pub mod xpointer {
|
||||||
let result = cb(&mut ptr);
|
let result = cb(&mut ptr);
|
||||||
(NonNull::new(ptr as *mut T).map(|ptr| Self(ptr)), result)
|
(NonNull::new(ptr as *mut T).map(|ptr| Self(ptr)), result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *const T {
|
|
||||||
self.0.as_ptr() as *const _
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AsRef<T> for XPointer<T> {
|
impl<T> AsRef<T> for XPointer<T> {
|
||||||
|
|
|
@ -606,20 +606,6 @@ impl ClientState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_window_type<K>(&mut self, key: &K, window_type: WindowType)
|
|
||||||
where
|
|
||||||
K: ClientKey,
|
|
||||||
{
|
|
||||||
if let Some(client) = self.get_mut(key).into_option() {
|
|
||||||
client.window_type = window_type;
|
|
||||||
|
|
||||||
match window_type {
|
|
||||||
WindowType::Normal => self.set_floating(key),
|
|
||||||
_ => self.set_tiled(key),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_from_virtual_screens<K>(&mut self, key: &K)
|
fn remove_from_virtual_screens<K>(&mut self, key: &K)
|
||||||
where
|
where
|
||||||
K: ClientKey,
|
K: ClientKey,
|
||||||
|
|
60
src/state.rs
60
src/state.rs
|
@ -6,7 +6,7 @@ use x11::xlib::{self, Window};
|
||||||
|
|
||||||
use crate::backends::structs::WindowType;
|
use crate::backends::structs::WindowType;
|
||||||
use crate::backends::window_event::{
|
use crate::backends::window_event::{
|
||||||
FullscreenEvent, FullscreenState, WindowNameEvent, WindowTypeChangedEvent,
|
FullscreenEvent, FullscreenState, WindowNameEvent,
|
||||||
};
|
};
|
||||||
use crate::util::{Point, Size};
|
use crate::util::{Point, Size};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -306,6 +306,13 @@ where
|
||||||
&self.config.inactive_window_border_color,
|
&self.config.inactive_window_border_color,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// add all already existing windows to the WM
|
||||||
|
if let Some(windows) = self.backend.all_windows() {
|
||||||
|
windows
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|window| self.new_client(window));
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,6 +431,8 @@ where
|
||||||
self.button_event(&event);
|
self.button_event(&event);
|
||||||
}
|
}
|
||||||
WindowEvent::MapRequestEvent(MapEvent { window }) => {
|
WindowEvent::MapRequestEvent(MapEvent { window }) => {
|
||||||
|
self.backend.handle_event(event);
|
||||||
|
|
||||||
if !self.clients.contains(&window) {
|
if !self.clients.contains(&window) {
|
||||||
self.new_client(window);
|
self.new_client(window);
|
||||||
}
|
}
|
||||||
|
@ -439,27 +448,28 @@ where
|
||||||
self.do_move_resize_window(&event);
|
self.do_move_resize_window(&event);
|
||||||
}
|
}
|
||||||
WindowEvent::ConfigureEvent(ConfigureEvent {
|
WindowEvent::ConfigureEvent(ConfigureEvent {
|
||||||
window,
|
window, ..
|
||||||
size,
|
}) => {
|
||||||
position,
|
match self.clients.get(&window) {
|
||||||
..
|
ClientEntry::Tiled(client)
|
||||||
}) => match self.clients.get(&window) {
|
| ClientEntry::Floating(client) => {
|
||||||
ClientEntry::Tiled(client)
|
self.backend.configure_window(
|
||||||
| ClientEntry::Floating(client) => {
|
window,
|
||||||
self.backend.configure_window(
|
Some(client.size),
|
||||||
window,
|
Some(client.position),
|
||||||
Some(client.size),
|
None,
|
||||||
Some(client.position),
|
)
|
||||||
None,
|
}
|
||||||
)
|
ClientEntry::Vacant => self.backend.handle_event(event),
|
||||||
}
|
}
|
||||||
ClientEntry::Vacant => self.backend.configure_window(
|
// TODO
|
||||||
window,
|
// match self.clients.get(&event.window).into_option() {
|
||||||
Some(size),
|
// Some(client) => self
|
||||||
Some(position),
|
// .xlib
|
||||||
None,
|
// .configure_client(client, self.clients.get_border()),
|
||||||
),
|
// None => self.xlib.configure_window(event),
|
||||||
},
|
// }
|
||||||
|
}
|
||||||
WindowEvent::FullscreenEvent(FullscreenEvent {
|
WindowEvent::FullscreenEvent(FullscreenEvent {
|
||||||
window,
|
window,
|
||||||
state,
|
state,
|
||||||
|
@ -496,14 +506,6 @@ where
|
||||||
WindowEvent::WindowNameEvent(WindowNameEvent { .. }) => {
|
WindowEvent::WindowNameEvent(WindowNameEvent { .. }) => {
|
||||||
info!("{:#?}", event);
|
info!("{:#?}", event);
|
||||||
}
|
}
|
||||||
WindowEvent::WindowTypeChangedEvent(
|
|
||||||
WindowTypeChangedEvent {
|
|
||||||
window,
|
|
||||||
window_type,
|
|
||||||
},
|
|
||||||
) => {
|
|
||||||
self.clients.update_window_type(&window, window_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// i dont think i actually have to handle destroy notify events.
|
// i dont think i actually have to handle destroy notify events.
|
||||||
// every window should be unmapped regardless
|
// every window should be unmapped regardless
|
||||||
|
|
Loading…
Reference in a new issue