Closed JuanPotato closed 4 years ago
I'll add magic number constants tomorrow
Doesn't work on my machine. Let's discuss further
Any news on this?
Seems like the mask is the problem. It works for me on Fedora 31 if I change the mask to xcb::NONE
It seems that the mask behaviour may be distro-specific - see https://stackoverflow.com/questions/35906243/no-error-on-xcb-grab-key-but-event-loop-not-catching-global-hotkey
I can confirm it works on my Linux Mint with @expectocode's patch (pasted here as text to make it easier to git apply
):
--- a/src/lib/mod.rs
+++ b/src/lib/mod.rs
@@ -136,7 +136,7 @@ pub fn grab_escape_key(conn: &xcb::Connection, root: u32) {
&conn,
true,
root,
- xcb::MOD_MASK_ANY as u16,
+ xcb::NONE as u16,
9, // ESCAPE, would be nice if wasn't a magic number
xcb::GRAB_MODE_ASYNC as u8,
xcb::GRAB_MODE_ASYNC as u8,
So the mask thing turned out to be pretty annoying - MOD_MASK_ANY really should have done it, but just doesn't do what it's supposed to. And using xcb::NONE only grabs ESC with no modifiers, which isn't a good experience since that would not pick up Caps Lock + ESC or Num Lock + ESC which people might have on. So I've emulated MOD_MASK_ANY by sending off 256 different grab key requests, so we get every single combination of modifiers. If this turns out to be too many requests, I guess we could drop down to only grabbing those which are reasonable for people to have on for a while (ie not Shift, Ctrl etc). But for consistency I'm happy with grabbing all modifiers, so I'm going to merge this now.
Another option is to grab every modifier, but not every modifier combination. This would pick up Num Lock + ESC but not Num Lock + Shift + Esc, which could be acceptable. This is what I did in 59d4fa2 and I wouldn't mind going back to that later if the combinations turn out to be a problem.
@pickfire thanks for poking us!
@expectocode This grabs the wrong key on my laptop since I swapped my keys.
setxkbmap -layout 'us,us,us' -variant 'dvorak,dvp,' -option 'compose:ralt,ctrl:swapcaps,grp:rctrl_rshift_toggle,terminate:ctrl_alt_bksp'
@pickfire what key does it grab? Could you run xev
, press ESC, and paste the result? It should say keycode 9. I'm not familiar with all the options in your command there, I use setxkbmap us -variant dvp -option ctrl:swapcaps -option compose:ralt
personally.
setxkbmap is broken, don't use it. You should be setting those options in /etc/Xorg.conf(.d), and for swapping keys, either create a custom xkb layout or remap your keyboard at the evdev level. Anything else will cause you grief.
66
That was the old one, the new one uses .Xmodmap
which is supported by fcitx, the IME I used.
! swap caps lock with escape
clear Lock
keycode 9 = Caps_Lock
keycode 66 = Escape NoSymbol Escape
! swap control with alt
clear control
clear mod1
keycode 37 = Alt_L Meta_L Alt_L Meta_L Alt_L Meta_L Alt_L Meta_L
keycode 105 = Alt_R Meta_R Alt_R Meta_R Alt_R Meta_R Alt_R Meta_R
keycode 64 = Control_L NoSymbol Control_L NoSymbol Control_L Control_L
keycode 108 = Control_R NoSymbol Control_R NoSymbol Control_R Control_R
add control = Control_L Control_R
add mod1 = Alt_L Meta_L
! f1 f2 f3 f4 undo cut copy paste
!keycode 67 = Undo F1 F1 F1 F1 F1 XF86Switch_VT_1 F1 F1 XF86Switch_VT_1
!keycode 68 = XF86Cut F2 F2 F2 F2 F2 XF86Switch_VT_2 F2 F2 XF86Switch_VT_2
!keycode 69 = XF86Copy F3 F3 F3 F3 F3 XF86Switch_VT_3 F3 F3 XF86Switch_VT_3
!keycode 70 = XF86Paste F4 F4 F4 F4 F4 XF86Switch_VT_4 F4 F4 XF86Switch_VT_4
xmodmap is even worse.
@9ary What if my system is not just used by me and I want to switch the layout back?
What I tried is get all the keys and find the escape keycode by keysym.
let setup = conn.get_setup();
let cookie = xcb::get_keyboard_mapping(
&conn,
setup.min_keycode(),
setup.max_keycode() - setup.min_keycode() + 1,
);
let reply = cookie.get_reply().expect("failed to get keyboard mapping");
let keysyms = reply.keysyms();
let nkeycodes = keysyms.len() as u8 / reply.keysyms_per_keycode();
for keycode_idx in 0..nkeycodes {
print!("keycode {}", setup.min_keycode() + keycode_idx);
for keysym_idx in 0..reply.keysyms_per_keycode() {
let keysym = keysyms[(keysym_idx + keycode_idx * reply.keysyms_per_keycode()) as usize];
print!(" {}", keysym);
if keysym == 0xff1b { // escape key
break
}
}
println!();
}
But currently it breaks halfway:
keycode 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
keycode 9 65509 0 65509 0 65509 0 0 0 0 0 0 0 0 0 0
keycode 10 49 33 49 33 49 33 0 0 0 0 0 0 0 0 0
keycode 11 50 64 50 64 50 64 0 0 0 0 0 0 0 0 0
keycode 12 51 35 51 35 51 35 0 0 0 0 0 0 0 0 0
keycode 13 52 36 52 36 52 36 0 0 0 0 0 0 0 0 0
keycode 14 53 37 53 37 53 37 0 0 0 0 0 0 0 0 0
keycode 15 54 94 54 94 65106 65106 65106 65106 54 94 65106 65106 0 0 0
keycode 16 55 38 55 38 55 38 0 0 0 0 0 0 0 0 0
https://stackoverflow.com/questions/18689863/obtain-keyboard-layout-and-keysyms-with-xcb Xcb seemed hard to me in the beginning such that documentation is not complete and not many examples are available online.
@9ary fcitx is here helping me, I can switch my keymap but not fully, most of the home devices are used by few people.
What if my system is not just used by me and I want to switch the layout back?
That's not a problem, you already have your system set up for multiple keymaps. Other users can easily switch keymaps as they want. You might even be able to configure this per user (with ~/.local), but I'm not sure about that one.
Take a look at this SO answer. I don't agree with his recommendation to "call 10 different binaries upon login", changing settings that way is broken. Changes will randomly revert themselves, many things don't or can't support these changes properly either, one example being your problem.
@9ary Still I hoped it can be supported.
(for future reference, see #17)
Please test this, it should let everything else passthrough except for ESC. Also should be pretty easy to add another key to quit key if we want.