xdotool,ctrl键和键盘布局

时间:2015-08-11 11:35:10

标签: linux keyboard-layout xdotool

问题

我使用应用程序中的xdotool keydown Controlxdotool keyup Control来模拟Ctrl按下。当布局设置为us时,一切正常,但当布局更改为其他内容(frru)时,应用程序将停止查看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

1 个答案:

答案 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位位置,其中包含:

  1. shift = bit 0(状态0x1),
  2. lock = bit 1(状态0x2),
  3. control = bit 2(状态0x4)等
  4. 您的状态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参数。手册页中没有提到这一点。