CloseWindow and RequestFrameExtents properties
This commit is contained in:
parent
48a8fca18f
commit
eb7785a74a
4 changed files with 181 additions and 10 deletions
|
@ -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(),
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
mod ewmh;
|
#[macro_use]
|
||||||
mod atoms;
|
|
||||||
mod proto_traits;
|
mod proto_traits;
|
||||||
|
|
||||||
|
mod atoms;
|
||||||
|
mod ewmh;
|
||||||
mod proto;
|
mod proto;
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
Loading…
Reference in a new issue