Implement new macros, restructure in sub-modules
This commit is contained in:
parent
fe183b4c4b
commit
bee554c057
7 changed files with 324 additions and 222 deletions
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
// TODO use xcb::atom_struct!{} for this?
|
||||||
const ATOM_NAMES: [&str; 82] = [
|
const ATOM_NAMES: [&str; 82] = [
|
||||||
"_NET_SUPPORTED",
|
"_NET_SUPPORTED",
|
||||||
"_NET_CLIENT_LIST",
|
"_NET_CLIENT_LIST",
|
||||||
|
|
|
@ -78,7 +78,7 @@ mod tests {
|
||||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||||
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
||||||
|
|
||||||
let request = crate::ewmh::GetSupported;
|
let request = crate::ewmh::proto::GetSupported;
|
||||||
let cookie = ewmh_con.send_request(&request);
|
let cookie = ewmh_con.send_request(&request);
|
||||||
let reply = ewmh_con.wait_for_reply(cookie);
|
let reply = ewmh_con.wait_for_reply(cookie);
|
||||||
println!("{:?}", reply);
|
println!("{:?}", reply);
|
||||||
|
@ -205,7 +205,7 @@ mod tests {
|
||||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||||
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
||||||
|
|
||||||
let request = crate::ewmh::GetDesktopNames {};
|
let request = crate::ewmh::proto::GetDesktopNames {};
|
||||||
let cookie = ewmh_con.send_request(&request);
|
let cookie = ewmh_con.send_request(&request);
|
||||||
let reply = ewmh_con.wait_for_reply(cookie);
|
let reply = ewmh_con.wait_for_reply(cookie);
|
||||||
println!("{:?}", reply);
|
println!("{:?}", reply);
|
||||||
|
@ -216,7 +216,7 @@ mod tests {
|
||||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||||
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
||||||
|
|
||||||
let request = crate::ewmh::SetDesktopNames::new(vec!["X", "Y", "Z"]);
|
let request = crate::ewmh::proto::SetDesktopNames::new(vec!["A", "B", "Z"]);
|
||||||
let cookie = ewmh_con.send_request_checked(&request);
|
let cookie = ewmh_con.send_request_checked(&request);
|
||||||
let reply = xcb_con.check_request(cookie);
|
let reply = xcb_con.check_request(cookie);
|
||||||
println!("{:?}", reply);
|
println!("{:?}", reply);
|
||||||
|
@ -303,7 +303,7 @@ mod tests {
|
||||||
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
let xcb_con = xcb::Connection::connect(Option::None).unwrap().0;
|
||||||
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
let ewmh_con = crate::ewmh::Connection::connect(&xcb_con);
|
||||||
|
|
||||||
let request = crate::ewmh::SetShowingDesktop::new(&ewmh_con, true);
|
let request = crate::ewmh::proto::SetShowingDesktop::new(&ewmh_con, true);
|
||||||
let cookie = ewmh_con.send_request_checked(&request);
|
let cookie = ewmh_con.send_request_checked(&request);
|
||||||
let reply = xcb_con.check_request(cookie);
|
let reply = xcb_con.check_request(cookie);
|
||||||
println!("{:?}", reply);
|
println!("{:?}", reply);
|
||||||
|
|
|
@ -3,11 +3,8 @@ mod traits;
|
||||||
|
|
||||||
mod atoms;
|
mod atoms;
|
||||||
mod connection;
|
mod connection;
|
||||||
mod proto;
|
|
||||||
|
|
||||||
pub use atoms::Atoms;
|
pub use atoms::Atoms;
|
||||||
pub use connection::Connection;
|
pub use connection::Connection;
|
||||||
|
|
||||||
pub use proto::net_desktop_names::*;
|
pub mod proto;
|
||||||
pub use proto::net_showing_desktop::*;
|
|
||||||
pub use proto::net_supported::*;
|
|
||||||
|
|
237
src/ewmh/proto/macros.rs
Normal file
237
src/ewmh/proto/macros.rs
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
macro_rules! _get_property_base {
|
||||||
|
($reply:ident, $cookie:ident, $cookie_unchecked:ident) => {
|
||||||
|
impl EwmhCookie for $cookie {
|
||||||
|
type XcbCookie = xcb::x::GetPropertyCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EwmhPropertyCookieChecked for $cookie {
|
||||||
|
type Reply = $reply;
|
||||||
|
|
||||||
|
fn inner(self) -> xcb::x::GetPropertyCookie {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EwmhPropertyCookieUnchecked for $cookie_unchecked {
|
||||||
|
type Reply = $reply;
|
||||||
|
|
||||||
|
fn inner(self) -> xcb::x::GetPropertyCookieUnchecked {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! _get_property_request {
|
||||||
|
(root_window, $property:ident, UTF8_STRING) => {
|
||||||
|
fn xcb_request(&self, con: &Connection) -> xcb::x::GetProperty {
|
||||||
|
xcb::x::GetProperty {
|
||||||
|
delete: false,
|
||||||
|
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: con.atoms.UTF8_STRING,
|
||||||
|
long_offset: 0,
|
||||||
|
long_length: u32::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(root_window, $property:ident, $xtype:ident) => {
|
||||||
|
fn xcb_request(&self, con: &Connection) -> xcb::x::GetProperty {
|
||||||
|
xcb::x::GetProperty {
|
||||||
|
delete: false,
|
||||||
|
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: xcb::x::$xtype,
|
||||||
|
long_offset: 0,
|
||||||
|
long_length: u32::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($window:ident, $property:ident, UTF8_STRING) => {
|
||||||
|
fn xcb_request(&self, con: &Connection) -> xcb::x::GetProperty {
|
||||||
|
xcb::x::GetProperty {
|
||||||
|
delete: false,
|
||||||
|
window: $window,
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: con.atoms.UTF8_STRING,
|
||||||
|
long_offset: 0,
|
||||||
|
long_length: u32::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($window:ident, $property:ident, $xtype:ident) => {
|
||||||
|
fn xcb_request(&self, con: &Connection) -> xcb::x::GetProperty {
|
||||||
|
xcb::x::GetProperty {
|
||||||
|
delete: false,
|
||||||
|
window: $window,
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: xcb::x::$xtype,
|
||||||
|
long_offset: 0,
|
||||||
|
long_length: u32::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! ewmh_get_property {
|
||||||
|
(request=$request:ident{
|
||||||
|
window: $window:ident,
|
||||||
|
property: $property:ident,
|
||||||
|
xtype: $xtype: ident
|
||||||
|
},
|
||||||
|
reply=$reply:ident,
|
||||||
|
cookie=$cookie:ident,
|
||||||
|
cookie_unchecked=$cookie_unchecked:ident) => {
|
||||||
|
impl<'a> EwmhRequest<'a> for $request {
|
||||||
|
type XcbRequest = xcb::x::GetProperty;
|
||||||
|
type EwmhCookie = $cookie;
|
||||||
|
|
||||||
|
_get_property_request! {$window, $property, $xtype}
|
||||||
|
|
||||||
|
fn convert_cookie(&'a self, xcb_cookie: xcb::x::GetPropertyCookie) -> Self::EwmhCookie {
|
||||||
|
$cookie(xcb_cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EwmhPropertyRequestUnchecked for $request {
|
||||||
|
type EwmhCookie = $cookie_unchecked;
|
||||||
|
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn convert_cookie(&self,xcb_cookie: xcb::x::GetPropertyCookieUnchecked,) -> Self::EwmhCookie {
|
||||||
|
$cookie_unchecked(xcb_cookie)
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_property_request! {$window, $property, $xtype}
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_property_base! {$reply, $cookie, $cookie_unchecked}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! _set_property_base {
|
||||||
|
(root_window, $property:ident, UTF8_STRING) => {
|
||||||
|
fn xcb_request(&'a self, con: &Connection) -> xcb::x::ChangeProperty<'a, u8> {
|
||||||
|
xcb::x::ChangeProperty {
|
||||||
|
mode: xcb::x::PropMode::Replace,
|
||||||
|
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: con.atoms.UTF8_STRING,
|
||||||
|
data: &self.data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(root_window, $property:ident, $xtype:ident) => {
|
||||||
|
fn xcb_request(&'a self, con: &Connection) -> xcb::x::ChangeProperty<'a, u8> {
|
||||||
|
xcb::x::ChangeProperty {
|
||||||
|
mode: xcb::x::PropMode::Replace,
|
||||||
|
window: con.con.get_setup().roots().next().unwrap().root(),
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: xcb::x::$xtype,
|
||||||
|
data: &self.data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($window:ident, $property:ident, UTF8_STRING) => {
|
||||||
|
fn xcb_request(&'a self, con: &Connection) -> xcb::x::ChangeProperty<'a, u8> {
|
||||||
|
xcb::x::ChangeProperty {
|
||||||
|
mode: xcb::x::PropMode::Replace,
|
||||||
|
window: $window,
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: con.atoms.UTF8_STRING,
|
||||||
|
data: &self.data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($window:ident, $property:ident, $xtype:ident) => {
|
||||||
|
fn xcb_request(&'a self, con: &Connection) -> xcb::x::ChangeProperty<'a, u8> {
|
||||||
|
xcb::x::ChangeProperty {
|
||||||
|
mode: xcb::x::PropMode::Replace,
|
||||||
|
window: $window,
|
||||||
|
property: con.atoms.$property,
|
||||||
|
r#type: xcb::x::$xtype,
|
||||||
|
data: &self.data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! ewmh_set_property {
|
||||||
|
(request=$request:ident{
|
||||||
|
window: $window:ident,
|
||||||
|
property: $property:ident,
|
||||||
|
xtype: $xtype: ident
|
||||||
|
}) => {
|
||||||
|
impl<'a> EwmhRequest<'a> for $request {
|
||||||
|
// TODO fixing to u8 is probably not flexible enough
|
||||||
|
type XcbRequest = xcb::x::ChangeProperty<'a, u8>;
|
||||||
|
type EwmhCookie = xcb::VoidCookie;
|
||||||
|
|
||||||
|
_set_property_base! {$window, $property, $xtype}
|
||||||
|
|
||||||
|
fn convert_cookie(&'a self, xcb_cookie: xcb::VoidCookie) -> Self::EwmhCookie {
|
||||||
|
xcb_cookie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EwmhVoidRequestChecked<'a> for $request {
|
||||||
|
type XcbRequest = xcb::x::ChangeProperty<'a, u8>;
|
||||||
|
|
||||||
|
_set_property_base! {$window, $property, $xtype}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! _client_message_base {
|
||||||
|
(root_window) => {
|
||||||
|
fn xcb_request(&'a self, con: &Connection) -> Self::XcbRequest {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($destination: ident) => {
|
||||||
|
fn xcb_request(&'a self, con: &Connection) -> Self::XcbRequest {
|
||||||
|
xcb::x::SendEvent {
|
||||||
|
propagate: false,
|
||||||
|
destination: xcb::x::SendEventDest::Window($destination),
|
||||||
|
event_mask: xcb::x::EventMask::SUBSTRUCTURE_NOTIFY
|
||||||
|
| xcb::x::EventMask::SUBSTRUCTURE_REDIRECT,
|
||||||
|
event: &self.client_message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! ewmh_client_message {
|
||||||
|
(request=$request:ident{destination: $destination:ident}) => {
|
||||||
|
impl<'a> EwmhRequest<'a> for $request {
|
||||||
|
type XcbRequest = xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent>;
|
||||||
|
type EwmhCookie = xcb::VoidCookie;
|
||||||
|
|
||||||
|
_client_message_base! {$destination}
|
||||||
|
|
||||||
|
fn convert_cookie(&'a self, xcb_cookie: xcb::VoidCookie) -> Self::EwmhCookie {
|
||||||
|
xcb_cookie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EwmhVoidRequestChecked<'a> for $request {
|
||||||
|
type XcbRequest = xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent>;
|
||||||
|
_client_message_base! {$destination}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,24 @@
|
||||||
|
//! Request and response definitions for the ewmh protocol
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//! ```
|
||||||
|
//! let connection = xcb_wm::ewmh::Connection();
|
||||||
|
//! let request = xcb_wm::ewmh::proto::GetSupported;
|
||||||
|
//! let cookie = connection.send_request(request);
|
||||||
|
//! let response = connection.wait_for_reply(cookie);
|
||||||
|
//! ```
|
||||||
|
|
||||||
// mod application_props;
|
// mod application_props;
|
||||||
// #[allow(unused)]
|
// #[allow(unused)]
|
||||||
// mod root_props;
|
// mod root_props;
|
||||||
//
|
//
|
||||||
// pub use application_props::*;
|
// pub use application_props::*;
|
||||||
// pub use root_props::*;
|
// pub use root_props::*;
|
||||||
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
|
|
||||||
mod test_props;
|
mod test_props;
|
||||||
pub(crate) use test_props::*;
|
|
||||||
|
pub use test_props::net_desktop_names::*;
|
||||||
|
pub use test_props::net_showing_desktop::*;
|
||||||
|
pub use test_props::net_supported::*;
|
||||||
|
|
|
@ -1,3 +1,34 @@
|
||||||
|
fn x_buffer_to_strings(xbuf: &[u8]) -> Vec<String> {
|
||||||
|
let mut vals = vec![];
|
||||||
|
let mut buf = vec![];
|
||||||
|
|
||||||
|
for b in xbuf {
|
||||||
|
if *b != 0x00 {
|
||||||
|
buf.push(*b)
|
||||||
|
} else if !buf.is_empty() {
|
||||||
|
vals.push(String::from_utf8(buf.clone()).unwrap());
|
||||||
|
buf.clear();
|
||||||
|
} else {
|
||||||
|
buf.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vals
|
||||||
|
}
|
||||||
|
|
||||||
|
fn strings_to_x_buffer(strings: Vec<&str>) -> Vec<u8> {
|
||||||
|
let mut data = vec![];
|
||||||
|
|
||||||
|
// flatten `strings` into a continuous, NULL separated, array of bytes
|
||||||
|
for s in strings {
|
||||||
|
let mut bs = s.as_bytes().to_owned();
|
||||||
|
bs.push(0b00);
|
||||||
|
data.extend(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
data
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) mod net_supported {
|
pub(crate) mod net_supported {
|
||||||
use crate::ewmh::traits::*;
|
use crate::ewmh::traits::*;
|
||||||
use crate::ewmh::Connection;
|
use crate::ewmh::Connection;
|
||||||
|
@ -13,68 +44,6 @@ pub(crate) mod net_supported {
|
||||||
pub atoms: Vec<xcb::x::Atom>,
|
pub atoms: Vec<xcb::x::Atom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EwmhRequest<'a> for GetSupported {
|
|
||||||
type XcbRequest = xcb::x::GetProperty;
|
|
||||||
type EwmhCookie = GetSupportedCookie;
|
|
||||||
|
|
||||||
fn xcb_request(&self, con: &Connection) -> Self::XcbRequest {
|
|
||||||
xcb::x::GetProperty {
|
|
||||||
delete: false,
|
|
||||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
|
||||||
property: con.atoms._NET_SUPPORTED,
|
|
||||||
r#type: xcb::x::ATOM_ATOM,
|
|
||||||
long_offset: 0,
|
|
||||||
long_length: u32::MAX,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_cookie(&'a self, xcb_cookie: xcb::x::GetPropertyCookie) -> Self::EwmhCookie {
|
|
||||||
GetSupportedCookie(xcb_cookie)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhPropertyRequestUnchecked for GetSupported {
|
|
||||||
type EwmhCookie = GetSupportedCookieUnchecked;
|
|
||||||
|
|
||||||
fn convert_cookie(
|
|
||||||
&self,
|
|
||||||
xcb_cookie: xcb::x::GetPropertyCookieUnchecked,
|
|
||||||
) -> Self::EwmhCookie {
|
|
||||||
GetSupportedCookieUnchecked(xcb_cookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn xcb_request(&self, con: &Connection) -> xcb::x::GetProperty {
|
|
||||||
xcb::x::GetProperty {
|
|
||||||
delete: false,
|
|
||||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
|
||||||
property: con.atoms._NET_SUPPORTED,
|
|
||||||
r#type: xcb::x::ATOM_ATOM,
|
|
||||||
long_offset: 0,
|
|
||||||
long_length: u32::MAX,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhCookie for GetSupportedCookie {
|
|
||||||
type XcbCookie = xcb::x::GetPropertyCookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhPropertyCookieChecked for GetSupportedCookie {
|
|
||||||
type Reply = GetSupportedReply;
|
|
||||||
|
|
||||||
fn inner(self) -> xcb::x::GetPropertyCookie {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhPropertyCookieUnchecked for GetSupportedCookieUnchecked {
|
|
||||||
type Reply = GetSupportedReply;
|
|
||||||
|
|
||||||
fn inner(self) -> xcb::x::GetPropertyCookieUnchecked {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<xcb::x::GetPropertyReply> for GetSupportedReply {
|
impl From<xcb::x::GetPropertyReply> for GetSupportedReply {
|
||||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
||||||
GetSupportedReply {
|
GetSupportedReply {
|
||||||
|
@ -82,9 +51,21 @@ pub(crate) mod net_supported {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ewmh_get_property! {
|
||||||
|
request=GetSupported{
|
||||||
|
window: root_window,
|
||||||
|
property: _NET_SUPPORTED,
|
||||||
|
xtype: ATOM_ATOM
|
||||||
|
},
|
||||||
|
reply=GetSupportedReply,
|
||||||
|
cookie=GetSupportedCookie,
|
||||||
|
cookie_unchecked=GetSupportedCookieUnchecked
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod net_desktop_names {
|
pub(crate) mod net_desktop_names {
|
||||||
|
use crate::ewmh::proto::test_props::{strings_to_x_buffer, x_buffer_to_strings};
|
||||||
use crate::ewmh::traits::*;
|
use crate::ewmh::traits::*;
|
||||||
use crate::ewmh::Connection;
|
use crate::ewmh::Connection;
|
||||||
|
|
||||||
|
@ -99,139 +80,42 @@ pub(crate) mod net_desktop_names {
|
||||||
pub desktop_names: Vec<String>,
|
pub desktop_names: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EwmhRequest<'a> for GetDesktopNames {
|
|
||||||
type XcbRequest = xcb::x::GetProperty;
|
|
||||||
type EwmhCookie = GetDesktopNamesCookie;
|
|
||||||
|
|
||||||
fn xcb_request(&self, con: &Connection) -> Self::XcbRequest {
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_cookie(&'a self, xcb_cookie: xcb::x::GetPropertyCookie) -> Self::EwmhCookie {
|
|
||||||
GetDesktopNamesCookie(xcb_cookie)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhPropertyRequestUnchecked for GetDesktopNames {
|
|
||||||
type EwmhCookie = GetDesktopNamesCookieUnchecked;
|
|
||||||
|
|
||||||
fn convert_cookie(
|
|
||||||
&self,
|
|
||||||
xcb_cookie: xcb::x::GetPropertyCookieUnchecked,
|
|
||||||
) -> Self::EwmhCookie {
|
|
||||||
GetDesktopNamesCookieUnchecked(xcb_cookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn xcb_request(&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 EwmhCookie for GetDesktopNamesCookie {
|
|
||||||
type XcbCookie = xcb::x::GetPropertyCookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhPropertyCookieChecked for GetDesktopNamesCookie {
|
|
||||||
type Reply = GetDesktopNamesReply;
|
|
||||||
|
|
||||||
fn inner(self) -> xcb::x::GetPropertyCookie {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EwmhPropertyCookieUnchecked for GetDesktopNamesCookieUnchecked {
|
|
||||||
type Reply = GetDesktopNamesReply;
|
|
||||||
|
|
||||||
fn inner(self) -> xcb::x::GetPropertyCookieUnchecked {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<xcb::x::GetPropertyReply> for GetDesktopNamesReply {
|
impl From<xcb::x::GetPropertyReply> for GetDesktopNamesReply {
|
||||||
fn from(reply: xcb::x::GetPropertyReply) -> Self {
|
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 {
|
GetDesktopNamesReply {
|
||||||
desktop_names: vals,
|
desktop_names: x_buffer_to_strings(reply.value::<u8>()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ewmh_get_property! {
|
||||||
|
request=GetDesktopNames{
|
||||||
|
window: root_window,
|
||||||
|
property: _NET_DESKTOP_NAMES,
|
||||||
|
xtype: UTF8_STRING
|
||||||
|
},
|
||||||
|
reply=GetDesktopNamesReply,
|
||||||
|
cookie=GetDesktopNamesCookie,
|
||||||
|
cookie_unchecked=GetDesktopNamesCookieUnchecked
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SetDesktopNames {
|
pub struct SetDesktopNames {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetDesktopNames {
|
impl SetDesktopNames {
|
||||||
pub fn new(names: Vec<&str>) -> SetDesktopNames {
|
pub fn new(names: Vec<&str>) -> SetDesktopNames {
|
||||||
let mut data: Vec<u8> = vec![];
|
SetDesktopNames {
|
||||||
|
data: strings_to_x_buffer(names),
|
||||||
// flatten `new_names` into a continuous array of bytes
|
|
||||||
for name in names {
|
|
||||||
let mut bname = name.as_bytes().to_owned();
|
|
||||||
bname.push(0b00);
|
|
||||||
data.extend(bname)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDesktopNames { data }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EwmhRequest<'a> for SetDesktopNames {
|
ewmh_set_property! {
|
||||||
type XcbRequest = xcb::x::ChangeProperty<'a, u8>;
|
request=SetDesktopNames{
|
||||||
type EwmhCookie = xcb::VoidCookie;
|
window: root_window,
|
||||||
|
property: _NET_DESKTOP_NAMES,
|
||||||
fn xcb_request(&'a self, con: &Connection) -> Self::XcbRequest {
|
xtype: UTF8_STRING
|
||||||
xcb::x::ChangeProperty {
|
|
||||||
mode: xcb::x::PropMode::Replace,
|
|
||||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
|
||||||
property: con.atoms._NET_DESKTOP_NAMES,
|
|
||||||
r#type: con.atoms.UTF8_STRING,
|
|
||||||
data: &self.data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_cookie(&'a self, xcb_cookie: xcb::VoidCookie) -> Self::EwmhCookie {
|
|
||||||
xcb_cookie
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> EwmhVoidRequestChecked<'a> for SetDesktopNames {
|
|
||||||
type XcbRequest = xcb::x::ChangeProperty<'a, u8>;
|
|
||||||
|
|
||||||
fn xcb_request(&'a self, con: &Connection) -> xcb::x::ChangeProperty<'a, u8> {
|
|
||||||
xcb::x::ChangeProperty {
|
|
||||||
mode: xcb::x::PropMode::Replace,
|
|
||||||
window: con.con.get_setup().roots().next().unwrap().root(),
|
|
||||||
property: con.atoms._NET_DESKTOP_NAMES,
|
|
||||||
r#type: con.atoms.UTF8_STRING,
|
|
||||||
data: &self.data,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,40 +145,7 @@ pub(crate) mod net_showing_desktop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EwmhRequest<'a> for SetShowingDesktop {
|
ewmh_client_message! {
|
||||||
type XcbRequest = xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent>;
|
request=SetShowingDesktop{destination: root_window}
|
||||||
type EwmhCookie = xcb::VoidCookie;
|
|
||||||
|
|
||||||
fn xcb_request(&'a self, con: &Connection) -> Self::XcbRequest {
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_cookie(&'a self, xcb_cookie: xcb::VoidCookie) -> Self::EwmhCookie {
|
|
||||||
xcb_cookie
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> EwmhVoidRequestChecked<'a> for SetShowingDesktop {
|
|
||||||
type XcbRequest = xcb::x::SendEvent<'a, xcb::x::ClientMessageEvent>;
|
|
||||||
|
|
||||||
fn xcb_request(&'a self, con: &Connection) -> Self::XcbRequest {
|
|
||||||
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,7 @@
|
||||||
#![warn(rustdoc::broken_intra_doc_links)]
|
#![warn(rustdoc::broken_intra_doc_links)]
|
||||||
#![warn(rustdoc::private_intra_doc_links)]
|
#![warn(rustdoc::private_intra_doc_links)]
|
||||||
|
|
||||||
|
#[cfg(feature = "ewmh")]
|
||||||
pub mod ewmh;
|
pub mod ewmh;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue