refactored atoms

This commit is contained in:
Janis 2022-05-07 16:34:44 +02:00 committed by Gitea
parent 85d3c3ce79
commit 0dd42a7039

View file

@ -1,5 +1,6 @@
use log::{debug, error, warn}; use log::{debug, error, warn};
use num_traits::Zero; use num_traits::Zero;
<<<<<<< HEAD
use std::{ffi::CString, mem::MaybeUninit, ptr::NonNull, rc::Rc}; use std::{ffi::CString, mem::MaybeUninit, ptr::NonNull, rc::Rc};
use std::{ffi::CString, rc::Rc}; use std::{ffi::CString, rc::Rc};
>>>>>>> variant B >>>>>>> variant B
@ -9,6 +10,13 @@ use std::{ffi::CString, mem::MaybeUninit, ptr::NonNull, rc::Rc};
use thiserror::Error; use thiserror::Error;
use x11::xlib::{self, Atom, Success, Window, XEvent, XInternAtom, XKeyEvent}; use x11::xlib::{self, Atom, Success, Window, XEvent, XInternAtom, XKeyEvent};
=======
use std::{mem::MaybeUninit, ptr::NonNull, rc::Rc};
use thiserror::Error;
use x11::xlib::{self, Atom, XEvent, XKeyEvent};
>>>>>>> ab99fdd (refactored atoms)
use crate::backends::{ use crate::backends::{
keycodes::KeyOrButton, xlib::keysym::mouse_button_to_xbutton, keycodes::KeyOrButton, xlib::keysym::mouse_button_to_xbutton,
@ -16,12 +24,12 @@ use crate::backends::{
use self::{ use self::{
connection::XLibConnection, connection::XLibConnection,
ewmh::EWMHAtoms, ewmh::{EWMHAtom, EWMHAtoms},
keysym::{ keysym::{
keysym_to_virtual_keycode, virtual_keycode_to_keysym, keysym_to_virtual_keycode, virtual_keycode_to_keysym,
xev_to_mouse_button, XKeySym, xev_to_mouse_button, XKeySym,
}, },
wmh::ICCCMAtoms, wmh::{ICCCMAtom, ICCCMAtoms},
}; };
use super::{ use super::{
@ -109,15 +117,12 @@ impl From<u8> for XlibError {
} }
pub mod wmh { pub mod wmh {
use std::{borrow::Borrow, ffi::CString, ops::Index, os::raw::c_long}; use std::{borrow::Borrow, ffi::CString, ops::Index};
use strum::{EnumCount, EnumIter}; use strum::{EnumCount, EnumIter};
use x11::xlib::{Atom, XA_ATOM}; use x11::xlib::Atom;
use super::{ use super::{connection::XLibConnection, Display};
connection::{PropMode, XLibConnection},
Display,
};
#[derive(Debug, PartialEq, Eq, EnumIter, EnumCount, Clone, Copy)] #[derive(Debug, PartialEq, Eq, EnumIter, EnumCount, Clone, Copy)]
pub enum ICCCMAtom { pub enum ICCCMAtom {
@ -310,7 +315,7 @@ pub mod ewmh {
] ]
.to_vec(); .to_vec();
con.borrow().change_property_long( con.borrow().change_root_property_long(
self[EWMHAtom::NetSupported], self[EWMHAtom::NetSupported],
XA_ATOM, XA_ATOM,
PropMode::Replace, PropMode::Replace,
@ -464,7 +469,10 @@ pub mod ewmh {
} }
pub mod connection { pub mod connection {
use std::os::raw::c_long; use std::{
ffi::CString,
os::raw::{c_char, c_long},
};
use x11::xlib::{self, Atom, Window}; use x11::xlib::{self, Atom, Window};
@ -530,7 +538,33 @@ pub mod connection {
self.screen self.screen
} }
pub fn change_property_byte<T: AsRef<[u8]>>( pub fn get_text_property(
&self,
window: Window,
atom: Atom,
) -> Option<String> {
unsafe {
let mut text_prop =
std::mem::MaybeUninit::<xlib::XTextProperty>::zeroed()
.assume_init();
if xlib::XGetTextProperty(
self.dpy(),
window,
&mut text_prop,
atom,
) == 0
{
return None;
}
CString::from_raw(text_prop.value.cast::<c_char>())
.into_string()
.ok()
}
}
pub fn change_root_property_byte<T: AsRef<[u8]>>(
&self, &self,
atom: Atom, atom: Atom,
atom_type: Atom, atom_type: Atom,
@ -551,7 +585,7 @@ pub mod connection {
} }
} }
pub fn change_property_long<T: AsRef<[c_long]>>( pub fn change_root_property_long<T: AsRef<[c_long]>>(
&self, &self,
atom: Atom, atom: Atom,
atom_type: Atom, atom_type: Atom,
@ -593,7 +627,7 @@ impl Display {
pub struct XLib { pub struct XLib {
connection: Rc<XLibConnection>, connection: Rc<XLibConnection>,
//atoms: XLibAtoms, //atoms: XLibAtoms,
icccm_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>,
@ -607,8 +641,7 @@ impl XLib {
Self { Self {
connection: con.clone(), connection: con.clone(),
icccm_atoms: ICCCMAtoms::from_connection(con.clone()) atoms: ICCCMAtoms::from_connection(con.clone()).expect("atoms"),
.expect("atoms"),
ewmh_atoms: EWMHAtoms::from_connection(con.clone()) ewmh_atoms: EWMHAtoms::from_connection(con.clone())
.expect("ewmh atoms"), .expect("ewmh atoms"),
keybinds: Vec::new(), keybinds: Vec::new(),
@ -645,7 +678,7 @@ impl XLib {
xlib::XSync(self.dpy(), 0); xlib::XSync(self.dpy(), 0);
} }
#[deprecated = "use `self.connection.dpy()` instead"] //#[deprecated = "use `self.connection.dpy()` instead"]
fn dpy(&self) -> *mut xlib::Display { fn dpy(&self) -> *mut xlib::Display {
self.connection.dpy() self.connection.dpy()
} }
@ -754,14 +787,14 @@ impl XLib {
let ev = unsafe { &event.property }; let ev = unsafe { &event.property };
match ev.atom { match ev.atom {
atom if atom == self.atoms.net_wm_window_type => { atom if atom == self.ewmh_atoms[EWMHAtom::NetWmWindowType] => {
if self if self
.get_atom_property( .get_atom_property(
ev.window, ev.window,
self.atoms.net_wm_state, ewmh_atoms[EWMHAtom::NetWmState],
) )
.map(|atom| { .map(|atom| {
*atom == self.atoms.net_wm_state_fullscreen *atom == self.ewmh_atoms[EWMHAtom::NetWmStateFullscreen]
}) })
.unwrap_or(false) .unwrap_or(false)
{ {
@ -783,11 +816,11 @@ impl XLib {
let ev = unsafe { &event.client_message }; let ev = unsafe { &event.client_message };
match ev.message_type { match ev.message_type {
message_type if message_type == self.atoms.net_wm_state => { message_type if message_type == self.ewmh_atoms[EWMHAtom::NetWmState] => {
let data = ev.data.as_longs(); let data = ev.data.as_longs();
if data[1] as u64 == self.atoms.net_wm_state_fullscreen if data[1] as u64 == self.ewmh_atoms[EWMHAtom::NetWmStateFullScreen]
|| data[2] as u64 || data[2] as u64
== self.atoms.net_wm_state_fullscreen == self.ewmh_atoms[EWMHAtom::NetWmStateFullscreen]
{ {
debug!("fullscreen event"); debug!("fullscreen event");
Some(XLibWindowEvent::FullscreenEvent( Some(XLibWindowEvent::FullscreenEvent(
@ -906,7 +939,7 @@ impl XLib {
send_event: 0, send_event: 0,
window, window,
format: 32, format: 32,
message_type: self.atoms.wm_protocols, message_type: self.atoms[ICCCMAtom::WmProtocols],
data, data,
}, },
}; };
@ -1233,7 +1266,7 @@ impl WindowServerBackend for XLib {
xlib::XChangeProperty( xlib::XChangeProperty(
self.dpy(), self.dpy(),
self.connection.root(), self.connection.root(),
self.atoms.wm_active_window, self.atoms[ICCCMAtom::WmActiveWindow],
xlib::XA_WINDOW, xlib::XA_WINDOW,
32, 32,
xlib::PropModeReplace, xlib::PropModeReplace,
@ -1242,7 +1275,7 @@ impl WindowServerBackend for XLib {
); );
} }
self.send_protocol(window, self.atoms.wm_take_focus); self.send_protocol(window, self.atoms[ICCCMAtom::WmTakeFocus]);
} }
fn unfocus_window(&self, window: Self::Window) { fn unfocus_window(&self, window: Self::Window) {
@ -1272,7 +1305,7 @@ impl WindowServerBackend for XLib {
xlib::XDeleteProperty( xlib::XDeleteProperty(
self.dpy(), self.dpy(),
self.connection.root(), self.connection.root(),
self.atoms.wm_active_window, self.atoms[ICCCMAtom::WmActiveWindow],
); );
} }
} }
@ -1289,7 +1322,7 @@ impl WindowServerBackend for XLib {
} }
fn kill_window(&self, window: Self::Window) { fn kill_window(&self, window: Self::Window) {
if !self.send_protocol(window, self.atoms.wm_delete_window) { if !self.send_protocol(window, self.atoms[ICCCMAtom::WmDeleteWindow]) {
unsafe { unsafe {
xlib::XKillClient(self.dpy(), window); xlib::XKillClient(self.dpy(), window);
} }
@ -1456,64 +1489,12 @@ impl WindowServerBackend for XLib {
} }
fn get_window_name(&self, window: Self::Window) -> Option<String> { fn get_window_name(&self, window: Self::Window) -> Option<String> {
todo!() self.connection
} .get_text_property(window, self.ewmh_atoms[EWMHAtom::NetWmName])
} .or_else(|| {
self.connection
#[allow(dead_code)] .get_text_property(window, self.atoms[ICCCMAtom::WmName])
struct XLibAtoms { })
wm_protocols: Atom,
wm_delete_window: Atom,
wm_active_window: Atom,
wm_take_focus: Atom,
net_supported: Atom,
net_active_window: Atom,
net_client_list: Atom,
net_wm_name: Atom,
net_wm_state: Atom,
net_wm_state_fullscreen: Atom,
net_wm_window_type: Atom,
net_wm_window_type_dialog: Atom,
}
impl XLibAtoms {
fn init(display: Display) -> Self {
Self {
wm_protocols: Self::get_atom(&display, "WM_PROTOCOLS").unwrap(),
wm_delete_window: Self::get_atom(&display, "WM_DELETE_WINDOW")
.unwrap(),
wm_active_window: Self::get_atom(&display, "WM_ACTIVE_WINDOW")
.unwrap(),
wm_take_focus: Self::get_atom(&display, "WM_TAKE_FOCUS").unwrap(),
net_supported: Self::get_atom(&display, "_NET_SUPPORTED").unwrap(),
net_active_window: Self::get_atom(&display, "_NET_ACTIVE_WINDOW")
.unwrap(),
net_client_list: Self::get_atom(&display, "_NET_CLIENT_LIST")
.unwrap(),
net_wm_name: Self::get_atom(&display, "_NET_WM_NAME").unwrap(),
net_wm_state: Self::get_atom(&display, "_NET_WM_STATE").unwrap(),
net_wm_state_fullscreen: Self::get_atom(
&display,
"_NET_WM_STATE_FULLSCREEN",
)
.unwrap(),
net_wm_window_type: Self::get_atom(&display, "_NET_WM_WINDOW_TYPE")
.unwrap(),
net_wm_window_type_dialog: Self::get_atom(
&display,
"_NET_WM_WINDOW_TYPE_DIALOG",
)
.unwrap(),
}
}
fn get_atom(display: &Display, atom: &str) -> Option<Atom> {
let name = CString::new(atom).ok()?;
match unsafe { XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) }
{
0 => None,
atom => Some(atom),
}
} }
} }