xlib_display_server/xwrap/
mouse.rs1use super::{XlibError, MOUSEMASK};
3use crate::xwrap::BUTTONMASK;
4use crate::XWrap;
5use std::os::raw::{c_int, c_uint, c_ulong};
6use x11_dl::xlib;
7
8impl XWrap {
9 pub fn grab_mouse_clicks(&self, handle: xlib::Window, is_focused: bool) {
11 self.ungrab_buttons(handle);
12 if !is_focused {
13 self.grab_buttons(handle, xlib::Button1, xlib::AnyModifier);
14 self.grab_buttons(handle, xlib::Button3, xlib::AnyModifier);
15 }
16 self.grab_buttons(handle, xlib::Button1, u32::from(self.mouse_key_mask.bits()));
17 self.grab_buttons(
18 handle,
19 xlib::Button1,
20 u32::from(self.mouse_key_mask.bits()) | xlib::ShiftMask,
21 );
22 self.grab_buttons(handle, xlib::Button3, u32::from(self.mouse_key_mask.bits()));
23 self.grab_buttons(
24 handle,
25 xlib::Button3,
26 u32::from(self.mouse_key_mask.bits()) | xlib::ShiftMask,
27 );
28 }
29
30 pub fn grab_buttons(&self, window: xlib::Window, button: u32, modifiers: u32) {
33 let mods: Vec<u32> = vec![
35 modifiers,
36 modifiers | xlib::Mod2Mask,
37 modifiers | xlib::LockMask,
38 ];
39 for m in mods {
40 unsafe {
41 (self.xlib.XGrabButton)(
42 self.display,
43 button,
44 m,
45 window,
46 0,
47 BUTTONMASK as u32,
48 xlib::GrabModeAsync,
49 xlib::GrabModeAsync,
50 0,
51 0,
52 );
53 }
54 }
55 }
56
57 pub fn ungrab_buttons(&self, handle: xlib::Window) {
60 unsafe {
61 (self.xlib.XUngrabButton)(
62 self.display,
63 xlib::AnyButton as u32,
64 xlib::AnyModifier,
65 handle,
66 );
67 }
68 }
69
70 pub fn grab_pointer(&self, cursor: c_ulong) {
73 unsafe {
74 (self.xlib.XGrabPointer)(
76 self.display,
77 self.root,
78 0,
79 MOUSEMASK as u32,
80 xlib::GrabModeAsync,
81 xlib::GrabModeAsync,
82 0,
83 cursor,
84 xlib::CurrentTime,
85 );
86 }
87 }
88
89 pub fn ungrab_pointer(&self) {
92 unsafe {
93 (self.xlib.XUngrabPointer)(self.display, xlib::CurrentTime);
95 }
96 }
97
98 pub fn move_cursor_to_window(&self, window: xlib::Window) -> Result<(), XlibError> {
103 let attrs = self.get_window_attrs(window)?;
104 let point = (attrs.x + (attrs.width / 2), attrs.y + (attrs.height / 2));
105 self.move_cursor_to_point(point)
106 }
107
108 pub fn move_cursor_to_point(&self, point: (i32, i32)) -> Result<(), XlibError> {
116 if point.0 >= 0 && point.1 >= 0 {
117 let none: c_int = 0;
118 unsafe {
119 (self.xlib.XWarpPointer)(
120 self.display,
121 none as c_ulong,
122 self.root,
123 none,
124 none,
125 none as u32,
126 none as u32,
127 point.0,
128 point.1,
129 );
130 }
131 }
132 Ok(())
133 }
134
135 pub fn replay_click(&self, focused_window: xlib::Window, button: c_uint) {
138 unsafe {
139 let mut event: xlib::XButtonEvent = std::mem::zeroed();
140 event.button = button;
141 event.same_screen = xlib::True;
142 event.subwindow = self.get_default_root();
143
144 while event.subwindow != 0 {
145 event.window = event.subwindow;
146 (self.xlib.XQueryPointer)(
147 self.display,
148 event.window,
149 &mut event.root,
150 &mut event.subwindow,
151 &mut event.x_root,
152 &mut event.y_root,
153 &mut event.x,
154 &mut event.y,
155 &mut event.state,
156 );
157 }
158
159 if event.window == focused_window {
162 event.type_ = xlib::ButtonPress;
163 self.send_xevent(event.window, 0, xlib::ButtonPressMask, &mut event.into());
164
165 event.type_ = xlib::ButtonRelease;
166 self.send_xevent(event.window, 0, xlib::ButtonReleaseMask, &mut event.into());
167 }
168 }
169 }
170
171 pub fn allow_pointer_events(&self) {
174 unsafe { (self.xlib.XAllowEvents)(self.display, xlib::SyncPointer, xlib::CurrentTime) };
175 }
176}