winit/platform_impl/linux/x11/util/
wm.rs1use std::sync::Mutex;
2
3use super::*;
4
5pub const MOVERESIZE_TOPLEFT: isize = 0;
7pub const MOVERESIZE_TOP: isize = 1;
8pub const MOVERESIZE_TOPRIGHT: isize = 2;
9pub const MOVERESIZE_RIGHT: isize = 3;
10pub const MOVERESIZE_BOTTOMRIGHT: isize = 4;
11pub const MOVERESIZE_BOTTOM: isize = 5;
12pub const MOVERESIZE_BOTTOMLEFT: isize = 6;
13pub const MOVERESIZE_LEFT: isize = 7;
14pub const MOVERESIZE_MOVE: isize = 8;
15
16static SUPPORTED_HINTS: Mutex<Vec<xproto::Atom>> = Mutex::new(Vec::new());
18static WM_NAME: Mutex<Option<String>> = Mutex::new(None);
19
20pub fn hint_is_supported(hint: xproto::Atom) -> bool {
21 (*SUPPORTED_HINTS.lock().unwrap()).contains(&hint)
22}
23
24pub fn wm_name_is_one_of(names: &[&str]) -> bool {
25 if let Some(ref name) = *WM_NAME.lock().unwrap() {
26 names.contains(&name.as_str())
27 } else {
28 false
29 }
30}
31
32impl XConnection {
33 pub fn update_cached_wm_info(&self, root: xproto::Window) {
34 *SUPPORTED_HINTS.lock().unwrap() = self.get_supported_hints(root);
35 *WM_NAME.lock().unwrap() = self.get_wm_name(root);
36 }
37
38 fn get_supported_hints(&self, root: xproto::Window) -> Vec<xproto::Atom> {
39 let atoms = self.atoms();
40 let supported_atom = atoms[_NET_SUPPORTED];
41 self.get_property(root, supported_atom, xproto::Atom::from(xproto::AtomEnum::ATOM))
42 .unwrap_or_else(|_| Vec::with_capacity(0))
43 }
44
45 #[allow(clippy::useless_conversion)]
46 fn get_wm_name(&self, root: xproto::Window) -> Option<String> {
47 let atoms = self.atoms();
48 let check_atom = atoms[_NET_SUPPORTING_WM_CHECK];
49 let wm_name_atom = atoms[_NET_WM_NAME];
50
51 let root_window_wm_check = {
73 let result = self.get_property::<xproto::Window>(
74 root,
75 check_atom,
76 xproto::Atom::from(xproto::AtomEnum::WINDOW),
77 );
78
79 let wm_check = result.ok().and_then(|wm_check| wm_check.first().cloned());
80
81 wm_check?
82 };
83
84 let child_window_wm_check = {
87 let result = self.get_property::<xproto::Window>(
88 root_window_wm_check.into(),
89 check_atom,
90 xproto::Atom::from(xproto::AtomEnum::WINDOW),
91 );
92
93 let wm_check = result.ok().and_then(|wm_check| wm_check.first().cloned());
94
95 wm_check?
96 };
97
98 if root_window_wm_check != child_window_wm_check {
100 return None;
101 }
102
103 let wm_name = {
105 let atoms = self.atoms();
106 let utf8_string_atom = atoms[UTF8_STRING];
107
108 let result =
109 self.get_property(root_window_wm_check.into(), wm_name_atom, utf8_string_atom);
110
111 let no_utf8 = if let Err(ref err) = result {
118 err.is_actual_property_type(xproto::Atom::from(xproto::AtomEnum::STRING))
119 } else {
120 false
121 };
122
123 if no_utf8 {
124 self.get_property(
125 root_window_wm_check.into(),
126 wm_name_atom,
127 xproto::Atom::from(xproto::AtomEnum::STRING),
128 )
129 } else {
130 result
131 }
132 }
133 .ok();
134
135 wm_name.and_then(|wm_name| String::from_utf8(wm_name).ok())
136 }
137}