xlib_display_server/xwrap/
setters.rs1use super::WindowHandle;
3use crate::{XWrap, XlibWindowHandle};
4use leftwm_core::models::TagId;
5use std::ffi::CString;
6use std::os::raw::{c_long, c_ulong};
7use x11_dl::xlib;
8
9impl XWrap {
10 pub fn append_property_long(
15 &self,
16 window: xlib::Window,
17 property: xlib::Atom,
18 r#type: xlib::Atom,
19 data: &[c_long],
20 ) {
21 unsafe {
22 (self.xlib.XChangeProperty)(
23 self.display,
24 window,
25 property,
26 r#type,
27 32,
28 xlib::PropModeAppend,
29 data.as_ptr().cast::<u8>(),
30 data.len() as i32,
31 );
32 }
33 }
34
35 pub fn replace_property_long(
38 &self,
39 window: xlib::Window,
40 property: xlib::Atom,
41 r#type: xlib::Atom,
42 data: &[c_long],
43 ) {
44 unsafe {
45 (self.xlib.XChangeProperty)(
46 self.display,
47 window,
48 property,
49 r#type,
50 32,
51 xlib::PropModeReplace,
52 data.as_ptr().cast::<u8>(),
53 data.len() as i32,
54 );
55 }
56 }
57
58 pub fn set_client_list(&self) {
61 unsafe {
62 (self.xlib.XDeleteProperty)(self.display, self.root, self.atoms.NetClientList);
63 }
64 for w in &self.managed_windows {
65 let list = vec![*w as c_long];
66 self.append_property_long(self.root, self.atoms.NetClientList, xlib::XA_WINDOW, &list);
67 }
68 }
69
70 pub fn set_current_desktop(&self, current_tag: Option<TagId>) {
72 let indexes: Vec<u32> = match current_tag {
73 Some(tag) => vec![tag as u32 - 1],
74 None => vec![0],
75 };
76 self.set_desktop_prop(&indexes, self.atoms.NetCurrentDesktop);
77 }
78
79 #[allow(clippy::cast_lossless)]
100 pub fn set_desktop_prop(&self, data: &[u32], atom: c_ulong) {
101 let x_data: Vec<c_long> = data.iter().map(|x| *x as c_long).collect();
102 self.replace_property_long(self.root, atom, xlib::XA_CARDINAL, &x_data);
103 }
104
105 pub fn set_desktop_prop_c_ulong(&self, value: c_ulong, atom: c_ulong, r#type: c_ulong) {
107 let data = vec![value as c_long];
108 self.replace_property_long(self.root, atom, r#type, &data);
109 }
110
111 pub fn set_desktop_prop_string(&self, value: &str, atom: c_ulong, encoding: xlib::Atom) {
114 if let Ok(cstring) = CString::new(value) {
115 unsafe {
116 (self.xlib.XChangeProperty)(
117 self.display,
118 self.root,
119 atom,
120 encoding,
121 8,
122 xlib::PropModeReplace,
123 cstring.as_ptr().cast::<u8>(),
124 value.len() as i32,
125 );
126 std::mem::forget(cstring);
127 }
128 }
129 }
130
131 pub fn set_state(
133 &self,
134 handle: WindowHandle<XlibWindowHandle>,
135 toggle_to: bool,
136 atom: xlib::Atom,
137 ) {
138 let WindowHandle(XlibWindowHandle(h)) = handle;
139 let mut states = self.get_window_states_atoms(h);
140 if toggle_to {
141 if states.contains(&atom) {
142 return;
143 }
144 states.push(atom);
145 } else {
146 let Some(index) = states.iter().position(|s| s == &atom) else {
147 return;
148 };
149 states.remove(index);
150 }
151 self.set_window_states_atoms(h, &states);
152 }
153
154 pub fn set_window_border_color(&self, window: xlib::Window, mut color: c_ulong) {
157 unsafe {
158 color |= 0xff00_0000;
160 (self.xlib.XSetWindowBorder)(self.display, window, color);
161 }
162 }
163
164 pub fn set_background_color(&self, mut color: c_ulong) {
165 unsafe {
166 color |= 0xff00_0000;
168 (self.xlib.XSetWindowBackground)(self.display, self.root, color);
169 (self.xlib.XClearWindow)(self.display, self.root);
170 (self.xlib.XFlush)(self.display);
171 (self.xlib.XSync)(self.display, 0);
172 }
173 }
174
175 pub fn set_window_config(
177 &self,
178 window: xlib::Window,
179 mut window_changes: xlib::XWindowChanges,
180 unlock: u32,
181 ) {
182 unsafe { (self.xlib.XConfigureWindow)(self.display, window, unlock, &mut window_changes) };
183 self.sync();
184 }
185
186 pub fn set_window_desktop(&self, window: xlib::Window, current_tag: &TagId) {
188 let mut indexes: Vec<c_long> = vec![*current_tag as c_long - 1];
189 if indexes.is_empty() {
190 indexes.push(0);
191 }
192 self.replace_property_long(window, self.atoms.NetWMDesktop, xlib::XA_CARDINAL, &indexes);
193 }
194
195 pub fn set_window_states_atoms(&self, window: xlib::Window, states: &[xlib::Atom]) {
197 let data: Vec<c_long> = states.iter().map(|x| *x as c_long).collect();
198 self.replace_property_long(window, self.atoms.NetWMState, xlib::XA_ATOM, &data);
199 }
200
201 pub fn set_window_urgency(&self, window: xlib::Window, is_urgent: bool) {
202 if let Some(mut wmh) = self.get_wmhints(window) {
203 if ((wmh.flags & xlib::XUrgencyHint) != 0) == is_urgent {
204 return;
205 }
206 wmh.flags = if is_urgent {
207 wmh.flags | xlib::XUrgencyHint
208 } else {
209 wmh.flags & !xlib::XUrgencyHint
210 };
211 self.set_wmhints(window, &mut wmh);
212 }
213 }
214
215 pub fn set_wmhints(&self, window: xlib::Window, wmh: &mut xlib::XWMHints) {
217 unsafe { (self.xlib.XSetWMHints)(self.display, window, wmh) };
218 }
219
220 pub fn set_wm_states(&self, window: xlib::Window, states: &[c_long]) {
222 self.replace_property_long(window, self.atoms.WMState, self.atoms.WMState, states);
223 }
224}