CloseWindow and RequestFrameExtents properties

This commit is contained in:
Armin Friedl 2022-05-14 21:07:11 +02:00
parent 48a8fca18f
commit eb7785a74a
4 changed files with 181 additions and 10 deletions

View file

@ -82,7 +82,7 @@ const ATOM_NAMES: [&str; 82] = [
"_NET_WM_ACTION_CHANGE_DESKTOP", "_NET_WM_ACTION_CHANGE_DESKTOP",
"_NET_WM_ACTION_CLOSE", "_NET_WM_ACTION_CLOSE",
"_NET_WM_ACTION_ABOVE", "_NET_WM_ACTION_ABOVE",
"_NET_WM_ACTION_BELOW" "_NET_WM_ACTION_BELOW",
]; ];
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -169,10 +169,9 @@ pub struct Atoms {
pub _NET_WM_ACTION_CHANGE_DESKTOP: xcb::x::Atom, pub _NET_WM_ACTION_CHANGE_DESKTOP: xcb::x::Atom,
pub _NET_WM_ACTION_CLOSE: xcb::x::Atom, pub _NET_WM_ACTION_CLOSE: xcb::x::Atom,
pub _NET_WM_ACTION_ABOVE: xcb::x::Atom, pub _NET_WM_ACTION_ABOVE: xcb::x::Atom,
pub _NET_WM_ACTION_BELOW: xcb::x::Atom pub _NET_WM_ACTION_BELOW: xcb::x::Atom,
} }
impl Atoms { impl Atoms {
pub(crate) fn intern(con: &xcb::Connection) -> Atoms { pub(crate) fn intern(con: &xcb::Connection) -> Atoms {
let mut cookies: HashMap<&'static str, xcb::x::InternAtomCookie> = HashMap::new(); let mut cookies: HashMap<&'static str, xcb::x::InternAtomCookie> = HashMap::new();
@ -186,7 +185,8 @@ impl Atoms {
cookies.insert(atom, con.send_request(&intern_atom)); cookies.insert(atom, con.send_request(&intern_atom));
} }
let interned_atoms: HashMap<&'static str, xcb::x::Atom> = cookies.into_iter() let interned_atoms: HashMap<&'static str, xcb::x::Atom> = cookies
.into_iter()
.map(|(atom_name, cookie)| (atom_name, con.wait_for_reply(cookie).unwrap())) .map(|(atom_name, cookie)| (atom_name, con.wait_for_reply(cookie).unwrap()))
.map(|(atom_name, reply)| (atom_name, reply.atom())) .map(|(atom_name, reply)| (atom_name, reply.atom()))
.collect(); .collect();
@ -247,10 +247,14 @@ impl Atoms {
_NET_WM_WINDOW_TYPE_UTILITY: atoms.remove("_NET_WM_WINDOW_TYPE_UTILITY").unwrap(), _NET_WM_WINDOW_TYPE_UTILITY: atoms.remove("_NET_WM_WINDOW_TYPE_UTILITY").unwrap(),
_NET_WM_WINDOW_TYPE_SPLASH: atoms.remove("_NET_WM_WINDOW_TYPE_SPLASH").unwrap(), _NET_WM_WINDOW_TYPE_SPLASH: atoms.remove("_NET_WM_WINDOW_TYPE_SPLASH").unwrap(),
_NET_WM_WINDOW_TYPE_DIALOG: atoms.remove("_NET_WM_WINDOW_TYPE_DIALOG").unwrap(), _NET_WM_WINDOW_TYPE_DIALOG: atoms.remove("_NET_WM_WINDOW_TYPE_DIALOG").unwrap(),
_NET_WM_WINDOW_TYPE_DROPDOWN_MENU: atoms.remove("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU").unwrap(), _NET_WM_WINDOW_TYPE_DROPDOWN_MENU: atoms
.remove("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU")
.unwrap(),
_NET_WM_WINDOW_TYPE_POPUP_MENU: atoms.remove("_NET_WM_WINDOW_TYPE_POPUP_MENU").unwrap(), _NET_WM_WINDOW_TYPE_POPUP_MENU: atoms.remove("_NET_WM_WINDOW_TYPE_POPUP_MENU").unwrap(),
_NET_WM_WINDOW_TYPE_TOOLTIP: atoms.remove("_NET_WM_WINDOW_TYPE_TOOLTIP").unwrap(), _NET_WM_WINDOW_TYPE_TOOLTIP: atoms.remove("_NET_WM_WINDOW_TYPE_TOOLTIP").unwrap(),
_NET_WM_WINDOW_TYPE_NOTIFICATION: atoms.remove("_NET_WM_WINDOW_TYPE_NOTIFICATION").unwrap(), _NET_WM_WINDOW_TYPE_NOTIFICATION: atoms
.remove("_NET_WM_WINDOW_TYPE_NOTIFICATION")
.unwrap(),
_NET_WM_WINDOW_TYPE_COMBO: atoms.remove("_NET_WM_WINDOW_TYPE_COMBO").unwrap(), _NET_WM_WINDOW_TYPE_COMBO: atoms.remove("_NET_WM_WINDOW_TYPE_COMBO").unwrap(),
_NET_WM_WINDOW_TYPE_DND: atoms.remove("_NET_WM_WINDOW_TYPE_DND").unwrap(), _NET_WM_WINDOW_TYPE_DND: atoms.remove("_NET_WM_WINDOW_TYPE_DND").unwrap(),
_NET_WM_WINDOW_TYPE_NORMAL: atoms.remove("_NET_WM_WINDOW_TYPE_NORMAL").unwrap(), _NET_WM_WINDOW_TYPE_NORMAL: atoms.remove("_NET_WM_WINDOW_TYPE_NORMAL").unwrap(),
@ -265,7 +269,9 @@ impl Atoms {
_NET_WM_STATE_FULLSCREEN: atoms.remove("_NET_WM_STATE_FULLSCREEN").unwrap(), _NET_WM_STATE_FULLSCREEN: atoms.remove("_NET_WM_STATE_FULLSCREEN").unwrap(),
_NET_WM_STATE_ABOVE: atoms.remove("_NET_WM_STATE_ABOVE").unwrap(), _NET_WM_STATE_ABOVE: atoms.remove("_NET_WM_STATE_ABOVE").unwrap(),
_NET_WM_STATE_BELOW: atoms.remove("_NET_WM_STATE_BELOW").unwrap(), _NET_WM_STATE_BELOW: atoms.remove("_NET_WM_STATE_BELOW").unwrap(),
_NET_WM_STATE_DEMANDS_ATTENTION: atoms.remove("_NET_WM_STATE_DEMANDS_ATTENTION").unwrap(), _NET_WM_STATE_DEMANDS_ATTENTION: atoms
.remove("_NET_WM_STATE_DEMANDS_ATTENTION")
.unwrap(),
_NET_WM_ACTION_MOVE: atoms.remove("_NET_WM_ACTION_MOVE").unwrap(), _NET_WM_ACTION_MOVE: atoms.remove("_NET_WM_ACTION_MOVE").unwrap(),
_NET_WM_ACTION_RESIZE: atoms.remove("_NET_WM_ACTION_RESIZE").unwrap(), _NET_WM_ACTION_RESIZE: atoms.remove("_NET_WM_ACTION_RESIZE").unwrap(),
_NET_WM_ACTION_MINIMIZE: atoms.remove("_NET_WM_ACTION_MINIMIZE").unwrap(), _NET_WM_ACTION_MINIMIZE: atoms.remove("_NET_WM_ACTION_MINIMIZE").unwrap(),

View file

@ -271,4 +271,37 @@ mod tests {
let reply = xcb_con.check_request(cookie); let reply = xcb_con.check_request(cookie);
println!("{:?}", reply); println!("{:?}", reply);
} }
#[test]
fn close_window() {
use xcb::XidNew;
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
let window = unsafe { xcb::x::Window::new(20979719) };
let request =
crate::ewmh::proto::CloseWindow::new(&ewmh_con, window, 0, xcb::x::CURRENT_TIME);
let cookie = ewmh_con.send_request(request);
let reply = xcb_con.check_request(cookie);
println!("{:?}", reply);
}
#[test]
fn request_frame_extents() {
use xcb::XidNew;
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
let window = unsafe { xcb::x::Window::new(20979719) };
let request = crate::ewmh::proto::RequestFrameExtents::new(&ewmh_con, window);
let cookie = ewmh_con.send_request(request);
let reply = xcb_con.check_request(cookie);
println!("{:?}", reply);
}
} }

View file

@ -1,4 +1,6 @@
mod ewmh; #[macro_use]
mod atoms;
mod proto_traits; mod proto_traits;
mod atoms;
mod ewmh;
mod proto; mod proto;

View file

@ -604,3 +604,133 @@ impl<'a> EwmhRequestData<'a> for SetShowingDesktop {
} }
// }}} // }}}
// _NET_CLOSE_WINDOW
// {{{
pub struct CloseWindow {
client_message: xcb::x::ClientMessageEvent,
}
impl CloseWindow {
pub fn new(
connection: &Connection,
window: xcb::x::Window,
source_indication: u32,
timestamp: u32,
) -> CloseWindow {
let data = [timestamp, source_indication, 0x00, 0x00, 0x00];
let client_message = xcb::x::ClientMessageEvent::new(
window,
connection.atoms._NET_CLOSE_WINDOW,
xcb::x::ClientMessageData::Data32(data),
);
CloseWindow { client_message }
}
}
impl<'a> EwmhRequest<'a> for CloseWindow {
type Cookie = xcb::VoidCookieChecked;
type CookieUnchecked = xcb::VoidCookie;
fn send_request(&self, con: &Connection) -> Self::Cookie {
con.con.send_request_checked(&self.get_request_data(con))
}
fn send_request_unchecked(&self, con: &Connection) -> Self::CookieUnchecked {
con.con.send_request(&self.get_request_data(con))
}
}
impl<'a> EwmhRequestData<'a> for CloseWindow {
type Request = xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent>;
fn get_request_data(
&'a self,
con: &Connection,
) -> xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent> {
xcb::x::SendEvent {
propagate: false,
destination: xcb::x::SendEventDest::Window(
con.con.get_setup().roots().next().unwrap().root(),
),
event_mask: xcb::x::EventMask::SUBSTRUCTURE_NOTIFY
| xcb::x::EventMask::SUBSTRUCTURE_REDIRECT,
event: &self.client_message,
}
}
}
// }}}
// _NET_MOVERESIZE_WINDOW
// {{{
// TODO
// }}}
// _NET_WM_MOVERESIZE
// {{{
// TODO
// }}}
// _NET_RESTACK_WINDOW
// {{{
// TODO
// }}}
// _NET_REQUEST_FRAME_EXTENTS
// {{{
pub struct RequestFrameExtents {
client_message: xcb::x::ClientMessageEvent,
}
impl RequestFrameExtents {
pub fn new(connection: &Connection, window: xcb::x::Window) -> RequestFrameExtents {
let client_message = xcb::x::ClientMessageEvent::new(
window,
connection.atoms._NET_REQUEST_FRAME_EXTENTS,
xcb::x::ClientMessageData::Data32([0x0, 0x0, 0x0, 0x0, 0x0]),
);
RequestFrameExtents { client_message }
}
}
impl<'a> EwmhRequest<'a> for RequestFrameExtents {
type Cookie = xcb::VoidCookieChecked;
type CookieUnchecked = xcb::VoidCookie;
fn send_request(&self, con: &Connection) -> Self::Cookie {
con.con.send_request_checked(&self.get_request_data(con))
}
fn send_request_unchecked(&self, con: &Connection) -> Self::CookieUnchecked {
con.con.send_request(&self.get_request_data(con))
}
}
impl<'a> EwmhRequestData<'a> for RequestFrameExtents {
type Request = xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent>;
fn get_request_data(
&'a self,
con: &Connection,
) -> xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent> {
xcb::x::SendEvent {
propagate: false,
destination: xcb::x::SendEventDest::Window(
con.con.get_setup().roots().next().unwrap().root(),
),
event_mask: xcb::x::EventMask::SUBSTRUCTURE_NOTIFY
| xcb::x::EventMask::SUBSTRUCTURE_REDIRECT,
event: &self.client_message,
}
}
}
// }}}