1 | // Welcome to the util module, where we try to keep you from shooting yourself in the foot. |
2 | // *results may vary |
3 | |
4 | use std::{ |
5 | mem::{self, MaybeUninit}, |
6 | ops::BitAnd, |
7 | os::raw::*, |
8 | }; |
9 | |
10 | mod client_msg; |
11 | pub mod cookie; |
12 | mod cursor; |
13 | mod geometry; |
14 | mod hint; |
15 | mod icon; |
16 | mod input; |
17 | pub mod keys; |
18 | pub(crate) mod memory; |
19 | mod mouse; |
20 | mod randr; |
21 | mod window_property; |
22 | mod wm; |
23 | mod xmodmap; |
24 | |
25 | pub use self::{ |
26 | geometry::*, hint::*, input::*, mouse::*, window_property::*, wm::*, xmodmap::ModifierKeymap, |
27 | }; |
28 | |
29 | use super::{atoms::*, ffi, VoidCookie, X11Error, XConnection, XError}; |
30 | use x11rb::protocol::xproto::{self, ConnectionExt as _}; |
31 | |
32 | pub fn maybe_change<T: PartialEq>(field: &mut Option<T>, value: T) -> bool { |
33 | let wrapped: Option = Some(value); |
34 | if *field != wrapped { |
35 | *field = wrapped; |
36 | true |
37 | } else { |
38 | false |
39 | } |
40 | } |
41 | |
42 | pub fn has_flag<T>(bitset: T, flag: T) -> bool |
43 | where |
44 | T: Copy + PartialEq + BitAnd<T, Output = T>, |
45 | { |
46 | bitset & flag == flag |
47 | } |
48 | |
49 | impl XConnection { |
50 | // This is impoartant, so pay attention! |
51 | // Xlib has an output buffer, and tries to hide the async nature of X from you. |
52 | // This buffer contains the requests you make, and is flushed under various circumstances: |
53 | // 1. `XPending`, `XNextEvent`, and `XWindowEvent` flush "as needed" |
54 | // 2. `XFlush` explicitly flushes |
55 | // 3. `XSync` flushes and blocks until all requests are responded to |
56 | // 4. Calls that have a return dependent on a response (i.e. `XGetWindowProperty`) sync internally. |
57 | // When in doubt, check the X11 source; if a function calls `_XReply`, it flushes and waits. |
58 | // All util functions that abstract an async function will return a `Flusher`. |
59 | pub fn flush_requests(&self) -> Result<(), XError> { |
60 | unsafe { (self.xlib.XFlush)(self.display) }; |
61 | //println!("XFlush"); |
62 | // This isn't necessarily a useful time to check for errors (since our request hasn't |
63 | // necessarily been processed yet) |
64 | self.check_errors() |
65 | } |
66 | |
67 | pub fn sync_with_server(&self) -> Result<(), XError> { |
68 | unsafe { (self.xlib.XSync)(self.display, ffi::False) }; |
69 | //println!("XSync"); |
70 | self.check_errors() |
71 | } |
72 | } |
73 | |