winit/platform_impl/linux/x11/util/
hint.rs
1use crate::platform::x11::WindowType;
2use std::sync::Arc;
3
4use super::*;
5
6#[derive(Debug)]
7#[allow(dead_code)]
8pub enum StateOperation {
9 Remove = 0, Add = 1, Toggle = 2, }
13
14impl From<bool> for StateOperation {
15 fn from(op: bool) -> Self {
16 if op {
17 StateOperation::Add
18 } else {
19 StateOperation::Remove
20 }
21 }
22}
23
24impl WindowType {
25 pub(crate) fn as_atom(&self, xconn: &Arc<XConnection>) -> xproto::Atom {
26 use self::WindowType::*;
27 let atom_name = match *self {
28 Desktop => _NET_WM_WINDOW_TYPE_DESKTOP,
29 Dock => _NET_WM_WINDOW_TYPE_DOCK,
30 Toolbar => _NET_WM_WINDOW_TYPE_TOOLBAR,
31 Menu => _NET_WM_WINDOW_TYPE_MENU,
32 Utility => _NET_WM_WINDOW_TYPE_UTILITY,
33 Splash => _NET_WM_WINDOW_TYPE_SPLASH,
34 Dialog => _NET_WM_WINDOW_TYPE_DIALOG,
35 DropdownMenu => _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
36 PopupMenu => _NET_WM_WINDOW_TYPE_POPUP_MENU,
37 Tooltip => _NET_WM_WINDOW_TYPE_TOOLTIP,
38 Notification => _NET_WM_WINDOW_TYPE_NOTIFICATION,
39 Combo => _NET_WM_WINDOW_TYPE_COMBO,
40 Dnd => _NET_WM_WINDOW_TYPE_DND,
41 Normal => _NET_WM_WINDOW_TYPE_NORMAL,
42 };
43
44 let atoms = xconn.atoms();
45 atoms[atom_name]
46 }
47}
48
49pub struct MotifHints {
50 hints: MwmHints,
51}
52
53struct MwmHints {
54 flags: u32,
55 functions: u32,
56 decorations: u32,
57 input_mode: u32,
58 status: u32,
59}
60
61#[allow(dead_code)]
62mod mwm {
63 pub const MWM_HINTS_FUNCTIONS: u32 = 1 << 0;
66 pub const MWM_HINTS_DECORATIONS: u32 = 1 << 1;
67
68 pub const MWM_FUNC_ALL: u32 = 1 << 0;
69 pub const MWM_FUNC_RESIZE: u32 = 1 << 1;
70 pub const MWM_FUNC_MOVE: u32 = 1 << 2;
71 pub const MWM_FUNC_MINIMIZE: u32 = 1 << 3;
72 pub const MWM_FUNC_MAXIMIZE: u32 = 1 << 4;
73 pub const MWM_FUNC_CLOSE: u32 = 1 << 5;
74}
75
76impl MotifHints {
77 pub fn new() -> MotifHints {
78 MotifHints {
79 hints: MwmHints { flags: 0, functions: 0, decorations: 0, input_mode: 0, status: 0 },
80 }
81 }
82
83 pub fn set_decorations(&mut self, decorations: bool) {
84 self.hints.flags |= mwm::MWM_HINTS_DECORATIONS;
85 self.hints.decorations = decorations as u32;
86 }
87
88 pub fn set_maximizable(&mut self, maximizable: bool) {
89 if maximizable {
90 self.add_func(mwm::MWM_FUNC_MAXIMIZE);
91 } else {
92 self.remove_func(mwm::MWM_FUNC_MAXIMIZE);
93 }
94 }
95
96 fn add_func(&mut self, func: u32) {
97 if self.hints.flags & mwm::MWM_HINTS_FUNCTIONS != 0 {
98 if self.hints.functions & mwm::MWM_FUNC_ALL != 0 {
99 self.hints.functions &= !func;
100 } else {
101 self.hints.functions |= func;
102 }
103 }
104 }
105
106 fn remove_func(&mut self, func: u32) {
107 if self.hints.flags & mwm::MWM_HINTS_FUNCTIONS == 0 {
108 self.hints.flags |= mwm::MWM_HINTS_FUNCTIONS;
109 self.hints.functions = mwm::MWM_FUNC_ALL;
110 }
111
112 if self.hints.functions & mwm::MWM_FUNC_ALL != 0 {
113 self.hints.functions |= func;
114 } else {
115 self.hints.functions &= !func;
116 }
117 }
118}
119
120impl Default for MotifHints {
121 fn default() -> Self {
122 Self::new()
123 }
124}
125
126impl XConnection {
127 pub fn get_motif_hints(&self, window: xproto::Window) -> MotifHints {
128 let atoms = self.atoms();
129 let motif_hints = atoms[_MOTIF_WM_HINTS];
130
131 let mut hints = MotifHints::new();
132
133 if let Ok(props) = self.get_property::<u32>(window, motif_hints, motif_hints) {
134 hints.hints.flags = props.first().cloned().unwrap_or(0);
135 hints.hints.functions = props.get(1).cloned().unwrap_or(0);
136 hints.hints.decorations = props.get(2).cloned().unwrap_or(0);
137 hints.hints.input_mode = props.get(3).cloned().unwrap_or(0);
138 hints.hints.status = props.get(4).cloned().unwrap_or(0);
139 }
140
141 hints
142 }
143
144 #[allow(clippy::unnecessary_cast)]
145 pub fn set_motif_hints(
146 &self,
147 window: xproto::Window,
148 hints: &MotifHints,
149 ) -> Result<VoidCookie<'_>, X11Error> {
150 let atoms = self.atoms();
151 let motif_hints = atoms[_MOTIF_WM_HINTS];
152
153 let hints_data: [u32; 5] = [
154 hints.hints.flags as u32,
155 hints.hints.functions as u32,
156 hints.hints.decorations as u32,
157 hints.hints.input_mode as u32,
158 hints.hints.status as u32,
159 ];
160
161 self.change_property(
162 window,
163 motif_hints,
164 motif_hints,
165 xproto::PropMode::REPLACE,
166 &hints_data,
167 )
168 }
169}