x11-cr
x11-cr copied to clipboard
How to use X11::Display#grab_button properly?
I'm using x11-cr to write a window manager and I'm trying to grab left click but #grab_button doesn't seem to work, it seems to be accepting different types from what it's given but I can't figure out how to give it the correct types. dpy.default_root_window
and dpy.root_window scr
return a UInt64 instead of an X11::C::Window for some reason
dpy = Display.new
scr = dpy.default_screen_number
root = dpy.root_window scr
dpy.grab_button(1, Mod4Mask, root, true, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None)
loop do
ev = dpy.next_event
case ev
when ButtonEvent
File.write("~/test.txt", "works")
break
end
end
dpy.destroy_window root
dpy.close
0
In src/sled/wm.cr:12:11
12 | dpy.grab_button(1, Mod4Mask, root, true, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None)
^----------
Error: no overload matches 'X11::Display#grab_button' with types Int32, Int32, UInt64, Bool, Int64, Int32, Int32, Int64, Int64
Overloads are:
- X11::Display#grab_button(button : UInt32, modifiers : UInt32, grab_window : X11::C::Window, owner_events : Bool, event_mask : UInt32, pointer_mode : Int32, keyboard_mode : Int32, confine_to : X11::C::Window, cursor : X11::C::Cursor)
it should work, perhaps your keycode is wrong or your numlock/capslock was active?
# ...
modifiers = (ControlMask | ShiftMask).to_u32
keycode = display.keysym_to_keycode(XK_A.to_u64)
display.grab_key(keycode, modifiers, grab_window: root, owner_events: true, pointer_mode: GrabModeAsync, keyboard_mode: GrabModeAsync)
display.select_input(root, KeyPressMask)
loop do
event = display.next_event
case event
when KeyEvent
if event.release?
puts "you pressed CTRL SHIFT A"
end
end
end
X11::C::Window
and such are also just integers afaik, but yes, you need some casting then and again because the types don't match like above, but I don't think it's problematic. This example uses keypresses, not buttons, but it's the same principle I guess?
Note that I have no idea of X11, this is just some googled C code snippets glued together, but it works on my machine™
However, display.next_event
is a blocking action that does also never Fiber.yield
, which prevents any kind of concurrency code... Any idea on how to solve that? :/
Edit: The solution is to either poll check_mask_event
every few ms instead, or put the display.next_event
into a separate thread (preferrable, much less cpu intensive).
Ok so I needed grab_button
too today, and here's how you can do it: Firstly, there is a type error in the source, see PR #19. Once Tamás has merged it, you can achieve it for example like this:
root_win = display.root_window display.default_screen_number
display.grab_button(Button1.to_u32, Mod4Mask.to_u32, grab_window: root_win, owner_events: true, event_mask: ButtonPressMask.to_u32, pointer_mode: GrabModeAsync, keyboard_mode: GrabModeAsync, confine_to: None.to_u64, cursor: None.to_u64)