问题
我使用应用程序中的xdotool keydown Control
和xdotool keyup Control
来模拟Ctrl按下。当布局设置为us
时,一切正常,但当布局更改为其他内容(fr
或ru
)时,应用程序将停止查看ctrl事件。
问题
为什么会这样?如何使ctrl键操作在布局中统一工作?
一些信息
我用来设置布局的命令:
setxkbmap -layout us,fr -option -option "grp:lctrl_lshift_toggle,ctrl:nocaps"
带有us
布局的xev输出:
KeyPress event, serial 25, synthetic NO, window 0x4a00001,
root 0x5c, subw 0x0, time 11278564, (317,709), root:(1279,736),
state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x4a00001,
root 0x5c, subw 0x0, time 11278676, (317,709), root:(1279,736),
state 0x14, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
带有fr
布局的xev输出:
KeyPress event, serial 109, synthetic NO, window 0x4a00001,
root 0x5c, subw 0x0, time 11343218, (312,520), root:(1274,547),
state 0x2010, keycode 8 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 109, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 116, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
KeyRelease event, serial 123, synthetic NO, window 0x4a00001,
root 0x5c, subw 0x0, time 11343460, (312,520), root:(1274,547),
state 0x2010, keycode 8 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
MappingNotify event, serial 123, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 1
setxkbmap的详细输出:
Setting verbose level to 10
locale is C
Applied rules from evdev:
rules: evdev
model: pc105
layout: us,fr
options: grp:lctrl_lshift_toggle,ctrl:nocaps
Trying to build keymap using the following components:
keycodes: evdev+aliases(qwerty)
types: complete
compat: complete
symbols: pc+us+fr:2+inet(evdev)+group(lctrl_lshift_toggle)+ctrl(nocaps)
geometry: pc(pc105)
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us+fr:2+inet(evdev)+group(lctrl_lshift_toggle)+ctrl(nocaps)" };
xkb_geometry { include "pc(pc105)" };
};
控制的xmodmap输出:
$ xmodmap -pme | grep -i control
control Control_L (0x25), Control_L (0x42), Control_R (0x69)
$ xmodmap -pke | grep -i control
keycode 37 = Control_L Control_L Control_L Control_L
keycode 66 = Control_L Control_L Control_L Control_L
keycode 105 = Control_R NoSymbol Control_R
答案 0 :(得分:2)
从xev
输出中可以看到,当处于 us 模式时,Control_L
key down等同于keycode 37,状态从0x10移动到
0x14,而在 fr 模式下,您有键码8和状态0x2010没有
改变,以及几个MappingNotify事件。
状态是当前应用修饰符的位图,例如shift, 控制,alt等。它们可以用
显示xmodmap -pme
例如我(在完全不同的键盘设置上)当前是
shift Shift_L (0x32), Shift_R (0x3e)
lock
control Control_L (0x25), Control_L (0x42), Control_R (0x69)
mod1 Meta_R (0x86)
mod2 Num_Lock (0x4d)
mod3
mod4
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
这些列出 state 中的8位位置,其中包含:
您的状态0x2010包含超过这8位的值0x2000,这是一个中的2个键映射的实现方式,并显示您处于fr模式时。
如果我们看看xdotool
如何工作,当你处于状态0x2000所示的第二个键映射时,它会查找Control_L以找到键码,然后查找xmodmap -pke
中的键码当前状态的列,并没有找到Control_L。因此它需要一个备用键码8,并暂时改变映射,因此键码8 = keysym Control_L,然后发送该键事件。不幸的是,这个键码不在控制位的修饰符映射中。
因此,如果您更改键代码37的映射以使所有列都具有Control_L,那么可能会起作用。我不知道你有多少列,但做xmodmap -pke | grep 'keycode 37'
并计算它们,然后改变所有列,例如:
xmodmap -e 'keycode 37 = Control_L Control_L Control_L Control_L'
如评论中所述,xdotool key
可以使用keycode十进制数而不是keysym参数。手册页中没有提到这一点。