ewmh root window properties
This commit is contained in:
parent
36add615d9
commit
48a8fca18f
8 changed files with 867 additions and 256 deletions
|
@ -4,14 +4,12 @@ version = "0.1.0"
|
|||
authors = [ "Armin Friedl <dev@friedl.net>" ]
|
||||
description = "Rust implementation of xcb-wm - icccm and ewmh extensions for xcb"
|
||||
readme = "README.md"
|
||||
keyworks = ["icccm", "ewmh", "xcb-wm", "xcb", "window", "xlib", "x11"]
|
||||
keywords = ["icccm", "ewmh", "xcb-wm", "xcb", "window", "xlib", "x11"]
|
||||
license = "MIT"
|
||||
edition = "2018"
|
||||
repository = "https://git.friedl.net/incubator/rust-xcb-wm"
|
||||
homepage = "https://git.friedl.net/incubator/rust-xcb-wm"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
xcb = "1"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
const ATOM_NAMES: [&'static str; 82] = [
|
||||
const ATOM_NAMES: [&str; 82] = [
|
||||
"_NET_SUPPORTED",
|
||||
"_NET_CLIENT_LIST",
|
||||
"_NET_CLIENT_LIST_STACKING",
|
||||
|
@ -85,6 +85,7 @@ const ATOM_NAMES: [&'static str; 82] = [
|
|||
"_NET_WM_ACTION_BELOW"
|
||||
];
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub struct Atoms {
|
||||
// TODO _NET_WM_CM_Sn atoms
|
||||
pub _NET_SUPPORTED: xcb::x::Atom,
|
||||
|
|
163
src/ewmh/ewmh.rs
163
src/ewmh/ewmh.rs
|
@ -1,5 +1,3 @@
|
|||
use xcb::x::{Atom, GetPropertyReply};
|
||||
|
||||
use crate::ewmh::proto_traits::{EwmhCookie, EwmhRequest};
|
||||
|
||||
use super::atoms::Atoms;
|
||||
|
@ -9,6 +7,7 @@ pub struct Connection<'a> {
|
|||
pub atoms: Atoms,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<'a> Connection<'a> {
|
||||
pub fn connect(xcb_con: &'a xcb::Connection) -> Connection<'a> {
|
||||
Connection {
|
||||
|
@ -37,7 +36,7 @@ impl<'a> Connection<'a> {
|
|||
self.con.send_request(&request)
|
||||
}
|
||||
|
||||
fn send_request<R: EwmhRequest>(&self, request: R) -> R::Cookie {
|
||||
fn send_request<R: EwmhRequest<'a>>(&self, request: R) -> R::Cookie {
|
||||
request.send_request(self)
|
||||
}
|
||||
|
||||
|
@ -53,12 +52,12 @@ mod tests {
|
|||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetSupportedRequest {};
|
||||
let request = crate::ewmh::proto::GetSupported::new();
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
|
||||
for atom in reply.value {
|
||||
for atom in reply.atoms {
|
||||
let cookie = xcb_con.send_request(&xcb::x::GetAtomName { atom: atom });
|
||||
|
||||
println!("{}", xcb_con.wait_for_reply(cookie).unwrap().name());
|
||||
|
@ -70,7 +69,7 @@ mod tests {
|
|||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetClientListRequest {};
|
||||
let request = crate::ewmh::proto::GetClientList::new();
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
|
@ -81,7 +80,29 @@ mod tests {
|
|||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetNumberOfDesktopsRequest {};
|
||||
let request = crate::ewmh::proto::GetNumberOfDesktops::new();
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_number_of_desktops() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::SetNumberOfDesktops::new(4);
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = xcb_con.check_request(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn number_of_desktops2() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNumberOfDesktops::new();
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
|
@ -92,18 +113,51 @@ mod tests {
|
|||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetDesktopGeometryRequest {};
|
||||
let request = crate::ewmh::proto::GetNumberOfDesktops {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_desktop_geometry() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::SetDesktopGeometry::new(1024, 800);
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = xcb_con.check_request(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desktop_viewport() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetDesktopViewportRequest {};
|
||||
let request = crate::ewmh::proto::GetDesktopViewport {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_desktop_viewport() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::SetDesktopViewport::new(200, 200);
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = xcb_con.check_request(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desktop_viewport2() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetDesktopViewport {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
|
@ -114,7 +168,7 @@ mod tests {
|
|||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetCurrentDesktopRequest {};
|
||||
let request = crate::ewmh::proto::GetCurrentDesktop {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
|
@ -125,9 +179,96 @@ mod tests {
|
|||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetNetDesktopNamesRequest {};
|
||||
let request = crate::ewmh::proto::GetDesktopNames {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_active_window() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetClientList {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
|
||||
let request = crate::ewmh::proto::SetActiveWindow::new(
|
||||
&ewmh_con,
|
||||
reply.clients.last().unwrap().to_owned(),
|
||||
1,
|
||||
xcb::x::CURRENT_TIME,
|
||||
Option::None,
|
||||
);
|
||||
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
xcb_con.check_request(cookie).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workarea() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetWorkarea {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn supporting_wm_check() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetSupportingWmCheck {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_roots() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetVirtualRoots {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desktop_layout() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetDesktopLayout {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn showing_desktop() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::GetShowingDesktop {};
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = ewmh_con.wait_for_reply(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_showing_desktop() {
|
||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||
let ewmh_con = crate::ewmh::ewmh::Connection::connect(&xcb_con);
|
||||
|
||||
let request = crate::ewmh::proto::SetShowingDesktop::new(&ewmh_con, true);
|
||||
let cookie = ewmh_con.send_request(request);
|
||||
let reply = xcb_con.check_request(cookie);
|
||||
println!("{:?}", reply);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
mod ewmh;
|
||||
mod atoms;
|
||||
mod proto_traits;
|
||||
mod proto;
|
||||
mod proto_traits;
|
|
@ -1,228 +0,0 @@
|
|||
use crate::ewmh::ewmh::Connection;
|
||||
use crate::ewmh::proto_traits::{EwmhCookie, EwmhCookieUnchecked, EwmhRequest, EwmhRequestData};
|
||||
use crate::{request, root_request};
|
||||
|
||||
root_request! {
|
||||
GetNetSupportedRequest,
|
||||
_NET_SUPPORTED,
|
||||
ATOM_ATOM,
|
||||
GetNetSupportedCookie,
|
||||
GetNetSupportedCookieUnchecked,
|
||||
GetNetSupportedReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetSupportedReply {
|
||||
pub value: Vec<xcb::x::Atom>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetSupportedReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetSupportedReply {
|
||||
value: reply.value().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetClientListRequest,
|
||||
_NET_CLIENT_LIST,
|
||||
ATOM_WINDOW,
|
||||
GetNetClientListCookie,
|
||||
GetNetClientListCookieUnchecked,
|
||||
GetNetClientListReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetClientListReply {
|
||||
pub value: Vec<xcb::x::Window>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetClientListReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetClientListReply {
|
||||
value: reply.value().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetClientListStackingRequest,
|
||||
_NET_CLIENT_LIST_STACKING,
|
||||
ATOM_WINDOW,
|
||||
GetNetClientListStackingCookie,
|
||||
GetNetClientListStackingCookieUnchecked,
|
||||
GetNetClientListStackingReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetClientListStackingReply {
|
||||
pub value: Vec<xcb::x::Window>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetClientListStackingReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetClientListStackingReply {
|
||||
value: reply.value().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetNumberOfDesktopsRequest,
|
||||
_NET_NUMBER_OF_DESKTOPS,
|
||||
ATOM_CARDINAL,
|
||||
GetNetNumberOfDesktopsCookie,
|
||||
GetNetNumberOfDesktopsCookieUnchecked,
|
||||
GetNetNumberOfDesktopsReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetNumberOfDesktopsReply {
|
||||
pub value: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetNumberOfDesktopsReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetNumberOfDesktopsReply {
|
||||
value: reply.value::<u32>()[0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetDesktopGeometryRequest,
|
||||
_NET_DESKTOP_GEOMETRY,
|
||||
ATOM_CARDINAL,
|
||||
GetNetDesktopGeometryCookie,
|
||||
GetNetDesktopGeometryCookieUnchecked,
|
||||
GetNetDesktopGeometryReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetDesktopGeometryReply {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetDesktopGeometryReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetDesktopGeometryReply {
|
||||
width: reply.value::<u32>()[0],
|
||||
height: reply.value::<u32>()[1],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetDesktopViewportRequest,
|
||||
_NET_DESKTOP_VIEWPORT,
|
||||
ATOM_CARDINAL,
|
||||
GetNetDesktopViewportCookie,
|
||||
GetNetDesktopViewportCookieUnchecked,
|
||||
GetNetDesktopViewportReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetDesktopViewportReply {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetDesktopViewportReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetDesktopViewportReply {
|
||||
x: reply.value::<u32>()[0],
|
||||
y: reply.value::<u32>()[1],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetCurrentDesktopRequest,
|
||||
_NET_CURRENT_DESKTOP,
|
||||
ATOM_CARDINAL,
|
||||
GetNetCurrentDesktopCookie,
|
||||
GetNetCurrentDesktopCookieUnchecked,
|
||||
GetNetCurrentDesktopReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetCurrentDesktopReply {
|
||||
pub desktop: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetCurrentDesktopReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetCurrentDesktopReply {
|
||||
desktop: reply.value::<u32>()[0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
request! {
|
||||
GetNetDesktopNamesRequest,
|
||||
GetNetDesktopNamesCookie,
|
||||
GetNetDesktopNamesCookieUnchecked,
|
||||
GetNetDesktopNamesReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetDesktopNamesReply {
|
||||
pub value: Vec<String>,
|
||||
}
|
||||
|
||||
impl EwmhRequestData for GetNetDesktopNamesRequest {
|
||||
fn get_request_data(&self, con: &Connection) -> xcb::x::GetProperty {
|
||||
xcb::x::GetProperty {
|
||||
delete: false,
|
||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||
property: con.atoms._NET_DESKTOP_NAMES,
|
||||
r#type: con.atoms.UTF8_STRING,
|
||||
long_offset: 0,
|
||||
long_length: u32::MAX,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetDesktopNamesReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
let mut vals = vec![];
|
||||
let mut buf = vec![];
|
||||
|
||||
for b in reply.value::<u8>() {
|
||||
if *b != 0x00 {
|
||||
buf.push(*b)
|
||||
} else if !buf.is_empty() {
|
||||
vals.push(String::from_utf8(buf.clone()).unwrap());
|
||||
buf.clear();
|
||||
} else {
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
GetNetDesktopNamesReply { value: vals }
|
||||
}
|
||||
}
|
||||
|
||||
root_request! {
|
||||
GetNetActiveWindowRequest,
|
||||
_NET_ACTIVE_WINDOW,
|
||||
ATOM_WINDOW,
|
||||
GetNetActiveWindowCookie,
|
||||
GetNetActiveWindowCookieUnchecked,
|
||||
GetNetActiveWindowReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNetActiveWindowReply {
|
||||
pub value: xcb::x::Window,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNetActiveWindowReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNetActiveWindowReply {
|
||||
value: reply.value::<xcb::x::Window>()[0],
|
||||
}
|
||||
}
|
||||
}
|
4
src/ewmh/proto/mod.rs
Normal file
4
src/ewmh/proto/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
#[allow(unused)]
|
||||
mod root_props;
|
||||
|
||||
pub use root_props::*;
|
606
src/ewmh/proto/root_props.rs
Normal file
606
src/ewmh/proto/root_props.rs
Normal file
|
@ -0,0 +1,606 @@
|
|||
//! Root Window Properties (and Related Messages)
|
||||
//!
|
||||
//! see: https://specifications.freedesktop.org/wm-spec/1.5/ar01s03.html#idm45539547193552
|
||||
|
||||
use xcb::{Xid, XidNew};
|
||||
|
||||
use crate::ewmh::ewmh::Connection;
|
||||
use crate::ewmh::proto_traits::{EwmhCookie, EwmhCookieUnchecked, EwmhRequest, EwmhRequestData};
|
||||
|
||||
// _NET_SUPPORTED, ATOM[]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetSupported,
|
||||
_NET_SUPPORTED,
|
||||
ATOM_ATOM,
|
||||
GetSupportedCookie,
|
||||
GetSupportedCookieUnchecked,
|
||||
GetSupportedReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetSupportedReply {
|
||||
pub atoms: Vec<xcb::x::Atom>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetSupportedReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetSupportedReply {
|
||||
atoms: reply.value().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_CLIENT_LIST, WINDOW[]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetClientList,
|
||||
_NET_CLIENT_LIST,
|
||||
ATOM_WINDOW,
|
||||
GetClientListCookie,
|
||||
GetClientListCookieUnchecked,
|
||||
GetClientListReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetClientListReply {
|
||||
pub clients: Vec<xcb::x::Window>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetClientListReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetClientListReply {
|
||||
clients: reply.value().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_CLIENT_LIST_STACKING, WINDOW[]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetClientListStacking,
|
||||
_NET_CLIENT_LIST_STACKING,
|
||||
ATOM_WINDOW,
|
||||
GetClientListStackingCookie,
|
||||
GetClientListStackingCookieUnchecked,
|
||||
GetClientListStackingReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetClientListStackingReply {
|
||||
pub clients: Vec<xcb::x::Window>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetClientListStackingReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetClientListStackingReply {
|
||||
clients: reply.value().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_NUMBER_OF_DESKTOPS, CARDINAL/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetNumberOfDesktops,
|
||||
_NET_NUMBER_OF_DESKTOPS,
|
||||
ATOM_CARDINAL,
|
||||
GetNumberOfDesktopsCookie,
|
||||
GetNumberOfDesktopsCookieUnchecked,
|
||||
GetNumberOfDesktopsReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetNumberOfDesktopsReply {
|
||||
pub desktops: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetNumberOfDesktopsReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetNumberOfDesktopsReply {
|
||||
desktops: reply.value::<u32>()[0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetNumberOfDesktops {
|
||||
data: [u32; 1],
|
||||
}
|
||||
|
||||
impl SetNumberOfDesktops {
|
||||
pub fn new(desktops: u32) -> SetNumberOfDesktops {
|
||||
SetNumberOfDesktops { data: [desktops] }
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_set_root_request! {
|
||||
SetNumberOfDesktops,
|
||||
_NET_NUMBER_OF_DESKTOPS,
|
||||
ATOM_CARDINAL
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// _NET_DESKTOP_GEOMETRY width, height, CARDINAL[2]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetDesktopGeometry,
|
||||
_NET_DESKTOP_GEOMETRY,
|
||||
ATOM_CARDINAL,
|
||||
GetDesktopGeometryCookie,
|
||||
GetDesktopGeometryCookieUnchecked,
|
||||
GetDesktopGeometryReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetDesktopGeometryReply {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetDesktopGeometryReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetDesktopGeometryReply {
|
||||
width: reply.value::<u32>()[0],
|
||||
height: reply.value::<u32>()[0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetDesktopGeometry {
|
||||
data: [u32; 2],
|
||||
}
|
||||
|
||||
impl SetDesktopGeometry {
|
||||
pub fn new(width: u32, height: u32) -> SetDesktopGeometry {
|
||||
SetDesktopGeometry {
|
||||
data: [width, height],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_set_root_request! {
|
||||
SetDesktopGeometry,
|
||||
_NET_DESKTOP_GEOMETRY,
|
||||
ATOM_CARDINAL
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// _NET_DESTKOP_VIEWPORT x, y, CARDINAL[][2]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetDesktopViewport,
|
||||
_NET_DESKTOP_VIEWPORT,
|
||||
ATOM_CARDINAL,
|
||||
GetDesktopViewportCookie,
|
||||
GetDesktopViewportCookieUnchecked,
|
||||
GetDesktopViewportReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetDesktopViewportReply {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetDesktopViewportReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetDesktopViewportReply {
|
||||
x: reply.value::<u32>()[0],
|
||||
y: reply.value::<u32>()[1],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetDesktopViewport {
|
||||
data: [u32; 2],
|
||||
}
|
||||
|
||||
impl SetDesktopViewport {
|
||||
pub fn new(x: u32, y: u32) -> SetDesktopViewport {
|
||||
SetDesktopViewport { data: [x, y] }
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_set_root_request! {
|
||||
SetDesktopViewport,
|
||||
_NET_DESKTOP_VIEWPORT,
|
||||
ATOM_CARDINAL
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// _NET_CURRENT_DESKTOP desktop, CARDINAL/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetCurrentDesktop,
|
||||
_NET_CURRENT_DESKTOP,
|
||||
ATOM_CARDINAL,
|
||||
GetCurrentDesktopCookie,
|
||||
GetCurrentDesktopCookieUnchecked,
|
||||
GetCurrentDesktopReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetCurrentDesktopReply {
|
||||
pub desktop: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetCurrentDesktopReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetCurrentDesktopReply {
|
||||
desktop: reply.value::<u32>()[0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetCurrentDesktop {
|
||||
data: [u32; 2],
|
||||
}
|
||||
|
||||
impl SetCurrentDesktop {
|
||||
pub fn new(new_index: u32, timestamp: u32) -> SetCurrentDesktop {
|
||||
SetCurrentDesktop {
|
||||
data: [new_index, timestamp],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_set_root_request! {
|
||||
SetCurrentDesktop,
|
||||
_NET_CURRENT_DESKTOP,
|
||||
ATOM_CARDINAL
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// _NET_DESKTOP_NAMES desktop, UTF8_STRING[]
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetDesktopNames,
|
||||
_NET_DESKTOP_NAMES,
|
||||
UTF8_STRING,
|
||||
GetDesktopNamesCookie,
|
||||
GetDesktopNamesCookieUnchecked,
|
||||
GetDesktopNamesReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetDesktopNamesReply {
|
||||
pub desktop_names: Vec<String>,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetDesktopNamesReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
let mut vals = vec![];
|
||||
let mut buf = vec![];
|
||||
|
||||
for b in reply.value::<u8>() {
|
||||
if *b != 0x00 {
|
||||
buf.push(*b)
|
||||
} else if !buf.is_empty() {
|
||||
vals.push(String::from_utf8(buf.clone()).unwrap());
|
||||
buf.clear();
|
||||
} else {
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
|
||||
GetDesktopNamesReply {
|
||||
desktop_names: vals,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetDesktopNames {
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl SetDesktopNames {
|
||||
pub fn new(new_names: Vec<&str>) -> SetDesktopNames {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
|
||||
// flatten `new_names` into a continuous array of bytes
|
||||
for name in new_names {
|
||||
let mut bname = name.as_bytes().to_owned();
|
||||
bname.push(0b00);
|
||||
data.extend(bname)
|
||||
}
|
||||
|
||||
SetDesktopNames { data }
|
||||
}
|
||||
}
|
||||
|
||||
ewmh_set_root_request! {
|
||||
SetDesktopNames,
|
||||
_NET_DESKTOP_NAMES,
|
||||
UTF8_STRING
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// _NET_ACTIVE_WINDOW, WINDOW/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetActiveWindow,
|
||||
_NET_ACTIVE_WINDOW,
|
||||
ATOM_WINDOW,
|
||||
GetActiveWindowCookie,
|
||||
GetActiveWindowCookieUnchecked,
|
||||
GetActiveWindowReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetActiveWindowReply {
|
||||
pub value: xcb::x::Window,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetActiveWindowReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetActiveWindowReply {
|
||||
value: reply.value::<xcb::x::Window>()[0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetActiveWindow {
|
||||
client_message: xcb::x::ClientMessageEvent,
|
||||
}
|
||||
|
||||
impl SetActiveWindow {
|
||||
pub fn new(
|
||||
connection: &Connection,
|
||||
window: xcb::x::Window,
|
||||
source_indication: u32,
|
||||
timestamp: u32,
|
||||
requestor_window: Option<xcb::x::Window>,
|
||||
) -> SetActiveWindow {
|
||||
let data = [
|
||||
source_indication,
|
||||
timestamp,
|
||||
requestor_window.map_or(0, |w| w.resource_id()),
|
||||
0x00,
|
||||
0x00,
|
||||
];
|
||||
|
||||
let client_message = xcb::x::ClientMessageEvent::new(
|
||||
window,
|
||||
connection.atoms._NET_ACTIVE_WINDOW,
|
||||
xcb::x::ClientMessageData::Data32(data),
|
||||
);
|
||||
|
||||
SetActiveWindow { client_message }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> EwmhRequest<'a> for SetActiveWindow {
|
||||
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 SetActiveWindow {
|
||||
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_WORKAREA, x, y, width, height, CARDINAL[][4]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetWorkarea,
|
||||
_NET_WORKAREA,
|
||||
ATOM_CARDINAL,
|
||||
GetWorkareaCookie,
|
||||
GetWorkareaCookieUnchecked,
|
||||
GetWorkareaReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetWorkareaReply {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetWorkareaReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetWorkareaReply {
|
||||
x: reply.value::<u32>()[0],
|
||||
y: reply.value::<u32>()[1],
|
||||
width: reply.value::<u32>()[2],
|
||||
height: reply.value::<u32>()[3],
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_SUPPORTING_WM_CHECK, WINDOW/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetSupportingWmCheck,
|
||||
_NET_SUPPORTING_WM_CHECK,
|
||||
ATOM_WINDOW,
|
||||
GetSupportingWmCheckCookie,
|
||||
GetSupportingWmCheckCookieUnchecked,
|
||||
GetSupportingWmCheckReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetSupportingWmCheckReply {
|
||||
pub window: xcb::x::Window,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetSupportingWmCheckReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetSupportingWmCheckReply {
|
||||
window: unsafe { xcb::x::Window::new(reply.value::<u32>()[0]) },
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_VIRTUAL_ROOTS, WINDOW/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetVirtualRoots,
|
||||
_NET_VIRTUAL_ROOTS,
|
||||
ATOM_WINDOW,
|
||||
GetVirtualRootsCookie,
|
||||
GetVirtualRootsCookieUnchecked,
|
||||
GetVirtualRootsReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetVirtualRootsReply {
|
||||
pub window: xcb::x::Window,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetVirtualRootsReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetVirtualRootsReply {
|
||||
window: unsafe { xcb::x::Window::new(reply.value::<u32>()[0]) },
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_DESKTOP_LAYOUT, orientation, columns, rows, starting_corner, CARDINAL[4]/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetDesktopLayout,
|
||||
_NET_DESKTOP_LAYOUT,
|
||||
ATOM_CARDINAL,
|
||||
GetDesktopLayoutCookie,
|
||||
GetDesktopLayoutCookieUnchecked,
|
||||
GetDesktopLayoutReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetDesktopLayoutReply {
|
||||
orientation: u32,
|
||||
columns: u32,
|
||||
rows: u32,
|
||||
starting_corner: u32,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetDesktopLayoutReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetDesktopLayoutReply {
|
||||
orientation: reply.value::<u32>()[0],
|
||||
columns: reply.value::<u32>()[1],
|
||||
rows: reply.value::<u32>()[2],
|
||||
starting_corner: reply.value::<u32>()[3],
|
||||
}
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// _NET_SHOWING_DESKTOP desktop, CARDINAL/32
|
||||
// {{{
|
||||
ewmh_get_root_request! {
|
||||
GetShowingDesktop,
|
||||
_NET_SHOWING_DESKTOP,
|
||||
ATOM_CARDINAL,
|
||||
GetShowingDesktopCookie,
|
||||
GetShowingDesktopCookieUnchecked,
|
||||
GetShowingDesktopReply
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GetShowingDesktopReply {
|
||||
showing_desktop: bool,
|
||||
}
|
||||
|
||||
impl From<xcb::x::GetPropertyReply> for GetShowingDesktopReply {
|
||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||
GetShowingDesktopReply {
|
||||
showing_desktop: match reply.value::<u32>()[0] {
|
||||
0 => false,
|
||||
1 => true,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SetShowingDesktop {
|
||||
client_message: xcb::x::ClientMessageEvent,
|
||||
}
|
||||
|
||||
impl SetShowingDesktop {
|
||||
pub fn new(connection: &Connection, show_desktop: bool) -> SetShowingDesktop {
|
||||
let data = match show_desktop {
|
||||
false => 0 as u32,
|
||||
true => 1 as u32,
|
||||
};
|
||||
|
||||
let client_message = xcb::x::ClientMessageEvent::new(
|
||||
connection.con.get_setup().roots().next().unwrap().root(),
|
||||
connection.atoms._NET_SHOWING_DESKTOP,
|
||||
xcb::x::ClientMessageData::Data32([data, 0x00, 0x00, 0x00, 0x00]),
|
||||
);
|
||||
|
||||
SetShowingDesktop { client_message }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> EwmhRequest<'a> for SetShowingDesktop {
|
||||
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 SetShowingDesktop {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
|
@ -1,6 +1,8 @@
|
|||
#![macro_use]
|
||||
|
||||
use crate::ewmh::ewmh::Connection;
|
||||
|
||||
pub(crate) trait EwmhRequest: EwmhRequestData {
|
||||
pub(crate) trait EwmhRequest<'a>: EwmhRequestData<'a> {
|
||||
type Cookie;
|
||||
type CookieUnchecked;
|
||||
|
||||
|
@ -8,8 +10,9 @@ pub(crate) trait EwmhRequest: EwmhRequestData {
|
|||
fn send_request_unchecked(&self, con: &Connection) -> Self::CookieUnchecked;
|
||||
}
|
||||
|
||||
pub(crate) trait EwmhRequestData {
|
||||
fn get_request_data(&self, con: &Connection) -> xcb::x::GetProperty;
|
||||
pub(crate) trait EwmhRequestData<'a> {
|
||||
type Request: xcb::Request;
|
||||
fn get_request_data(&'a self, con: &Connection) -> Self::Request;
|
||||
}
|
||||
|
||||
pub(crate) trait EwmhCookie {
|
||||
|
@ -22,10 +25,10 @@ pub(crate) trait EwmhCookieUnchecked {
|
|||
fn reply(self, con: &Connection) -> Option<Self::Reply>;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! request {
|
||||
macro_rules! ewmh_get_request {
|
||||
($req: ident, $cookie: ident, $cookie_unchecked: ident, $reply: ident) => {
|
||||
pub struct $req {}
|
||||
|
||||
pub struct $cookie {
|
||||
cookie: xcb::x::GetPropertyCookie,
|
||||
}
|
||||
|
@ -33,7 +36,13 @@ macro_rules! request {
|
|||
cookie: xcb::x::GetPropertyCookieUnchecked,
|
||||
}
|
||||
|
||||
impl EwmhRequest for $req {
|
||||
impl $req {
|
||||
pub fn new() -> $req {
|
||||
$req {}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> EwmhRequest<'a> for $req {
|
||||
type Cookie = $cookie;
|
||||
type CookieUnchecked = $cookie_unchecked;
|
||||
|
||||
|
@ -72,13 +81,33 @@ macro_rules! request {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! root_request {
|
||||
($req: ident, $prop: ident, $type: ident, $cookie: ident, $cookie_unchecked: ident, $reply: ident) => {
|
||||
request! {$req, $cookie, $cookie_unchecked, $reply}
|
||||
macro_rules! ewmh_get_root_request {
|
||||
($req: ident, $prop: ident, UTF8_STRING, $cookie: ident, $cookie_unchecked: ident, $reply: ident) => {
|
||||
ewmh_get_request! {$req, $cookie, $cookie_unchecked, $reply}
|
||||
|
||||
impl EwmhRequestData for $req {
|
||||
fn get_request_data(&self, con: &Connection) -> xcb::x::GetProperty {
|
||||
impl<'a> EwmhRequestData<'a> for $req {
|
||||
type Request = xcb::x::GetProperty;
|
||||
|
||||
fn get_request_data(&'a self, con: &Connection) -> Self::Request {
|
||||
xcb::x::GetProperty {
|
||||
delete: false,
|
||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||
property: con.atoms.$prop,
|
||||
r#type: con.atoms.UTF8_STRING,
|
||||
long_offset: 0,
|
||||
long_length: u32::MAX,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($req: ident, $prop: ident, $type: ident, $cookie: ident, $cookie_unchecked: ident, $reply: ident) => {
|
||||
ewmh_get_request! {$req, $cookie, $cookie_unchecked, $reply}
|
||||
|
||||
impl<'a> EwmhRequestData<'a> for $req {
|
||||
type Request = xcb::x::GetProperty;
|
||||
|
||||
fn get_request_data(&'a self, con: &Connection) -> Self::Request {
|
||||
xcb::x::GetProperty {
|
||||
delete: false,
|
||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||
|
@ -91,3 +120,63 @@ macro_rules! root_request {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! ewmh_set_root_request {
|
||||
($req: ident, $prop: ident, UTF8_STRING) => {
|
||||
impl<'a> EwmhRequest<'a> for $req {
|
||||
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 $req {
|
||||
type Request = xcb::x::ChangeProperty<'a, u8>;
|
||||
|
||||
fn get_request_data(&'a self, con: &Connection) -> Self::Request {
|
||||
xcb::x::ChangeProperty {
|
||||
mode: xcb::x::PropMode::Replace,
|
||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||
property: con.atoms.$prop,
|
||||
r#type: con.atoms.UTF8_STRING,
|
||||
data: self.data.as_slice(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($req: ident, $prop: ident, $type: ident) => {
|
||||
impl<'a> EwmhRequest<'a> for $req {
|
||||
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 $req {
|
||||
type Request = xcb::x::ChangeProperty<'a, u32>;
|
||||
|
||||
fn get_request_data(&'a self, con: &Connection) -> Self::Request {
|
||||
xcb::x::ChangeProperty {
|
||||
mode: xcb::x::PropMode::Replace,
|
||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||
property: con.atoms.$prop,
|
||||
r#type: xcb::x::$type,
|
||||
data: &self.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue