refactored atoms
This commit is contained in:
parent
85d3c3ce79
commit
0dd42a7039
|
@ -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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue