From 0dd42a7039623ddc17294f9eba425c502630713a Mon Sep 17 00:00:00 2001 From: Janis Date: Sat, 7 May 2022 16:34:44 +0200 Subject: [PATCH] refactored atoms --- src/backends/xlib/mod.rs | 151 +++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 85 deletions(-) diff --git a/src/backends/xlib/mod.rs b/src/backends/xlib/mod.rs index 29067d6..90967fb 100644 --- a/src/backends/xlib/mod.rs +++ b/src/backends/xlib/mod.rs @@ -1,5 +1,6 @@ use log::{debug, error, warn}; use num_traits::Zero; +<<<<<<< HEAD use std::{ffi::CString, mem::MaybeUninit, ptr::NonNull, rc::Rc}; use std::{ffi::CString, rc::Rc}; >>>>>>> variant B @@ -9,6 +10,13 @@ use std::{ffi::CString, mem::MaybeUninit, ptr::NonNull, rc::Rc}; use thiserror::Error; 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::{ keycodes::KeyOrButton, xlib::keysym::mouse_button_to_xbutton, @@ -16,12 +24,12 @@ use crate::backends::{ use self::{ connection::XLibConnection, - ewmh::EWMHAtoms, + ewmh::{EWMHAtom, EWMHAtoms}, keysym::{ keysym_to_virtual_keycode, virtual_keycode_to_keysym, xev_to_mouse_button, XKeySym, }, - wmh::ICCCMAtoms, + wmh::{ICCCMAtom, ICCCMAtoms}, }; use super::{ @@ -109,15 +117,12 @@ impl From for XlibError { } 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 x11::xlib::{Atom, XA_ATOM}; + use x11::xlib::Atom; - use super::{ - connection::{PropMode, XLibConnection}, - Display, - }; + use super::{connection::XLibConnection, Display}; #[derive(Debug, PartialEq, Eq, EnumIter, EnumCount, Clone, Copy)] pub enum ICCCMAtom { @@ -310,7 +315,7 @@ pub mod ewmh { ] .to_vec(); - con.borrow().change_property_long( + con.borrow().change_root_property_long( self[EWMHAtom::NetSupported], XA_ATOM, PropMode::Replace, @@ -464,7 +469,10 @@ pub mod ewmh { } 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}; @@ -530,7 +538,33 @@ pub mod connection { self.screen } - pub fn change_property_byte>( + pub fn get_text_property( + &self, + window: Window, + atom: Atom, + ) -> Option { + unsafe { + let mut text_prop = + std::mem::MaybeUninit::::zeroed() + .assume_init(); + + if xlib::XGetTextProperty( + self.dpy(), + window, + &mut text_prop, + atom, + ) == 0 + { + return None; + } + + CString::from_raw(text_prop.value.cast::()) + .into_string() + .ok() + } + } + + pub fn change_root_property_byte>( &self, atom: Atom, atom_type: Atom, @@ -551,7 +585,7 @@ pub mod connection { } } - pub fn change_property_long>( + pub fn change_root_property_long>( &self, atom: Atom, atom_type: Atom, @@ -593,7 +627,7 @@ impl Display { pub struct XLib { connection: Rc, //atoms: XLibAtoms, - icccm_atoms: ICCCMAtoms, + atoms: ICCCMAtoms, ewmh_atoms: EWMHAtoms, keybinds: Vec, active_border_color: Option, @@ -607,8 +641,7 @@ impl XLib { Self { connection: con.clone(), - icccm_atoms: ICCCMAtoms::from_connection(con.clone()) - .expect("atoms"), + atoms: ICCCMAtoms::from_connection(con.clone()).expect("atoms"), ewmh_atoms: EWMHAtoms::from_connection(con.clone()) .expect("ewmh atoms"), keybinds: Vec::new(), @@ -645,7 +678,7 @@ impl XLib { xlib::XSync(self.dpy(), 0); } - #[deprecated = "use `self.connection.dpy()` instead"] + //#[deprecated = "use `self.connection.dpy()` instead"] fn dpy(&self) -> *mut xlib::Display { self.connection.dpy() } @@ -754,14 +787,14 @@ impl XLib { let ev = unsafe { &event.property }; match ev.atom { - atom if atom == self.atoms.net_wm_window_type => { + atom if atom == self.ewmh_atoms[EWMHAtom::NetWmWindowType] => { if self .get_atom_property( ev.window, - self.atoms.net_wm_state, + ewmh_atoms[EWMHAtom::NetWmState], ) .map(|atom| { - *atom == self.atoms.net_wm_state_fullscreen + *atom == self.ewmh_atoms[EWMHAtom::NetWmStateFullscreen] }) .unwrap_or(false) { @@ -783,11 +816,11 @@ impl XLib { let ev = unsafe { &event.client_message }; 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(); - 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 - == self.atoms.net_wm_state_fullscreen + == self.ewmh_atoms[EWMHAtom::NetWmStateFullscreen] { debug!("fullscreen event"); Some(XLibWindowEvent::FullscreenEvent( @@ -906,7 +939,7 @@ impl XLib { send_event: 0, window, format: 32, - message_type: self.atoms.wm_protocols, + message_type: self.atoms[ICCCMAtom::WmProtocols], data, }, }; @@ -1233,7 +1266,7 @@ impl WindowServerBackend for XLib { xlib::XChangeProperty( self.dpy(), self.connection.root(), - self.atoms.wm_active_window, + self.atoms[ICCCMAtom::WmActiveWindow], xlib::XA_WINDOW, 32, 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) { @@ -1272,7 +1305,7 @@ impl WindowServerBackend for XLib { xlib::XDeleteProperty( self.dpy(), 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) { - if !self.send_protocol(window, self.atoms.wm_delete_window) { + if !self.send_protocol(window, self.atoms[ICCCMAtom::WmDeleteWindow]) { unsafe { xlib::XKillClient(self.dpy(), window); } @@ -1456,64 +1489,12 @@ impl WindowServerBackend for XLib { } fn get_window_name(&self, window: Self::Window) -> Option { - todo!() - } -} - -#[allow(dead_code)] -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 { - let name = CString::new(atom).ok()?; - match unsafe { XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) } - { - 0 => None, - atom => Some(atom), - } + self.connection + .get_text_property(window, self.ewmh_atoms[EWMHAtom::NetWmName]) + .or_else(|| { + self.connection + .get_text_property(window, self.atoms[ICCCMAtom::WmName]) + }) } }