【问题标题】:xdotool, ctrl key and keyboard layoutsxdotool、ctrl 键和键盘布局
【发布时间】:2015-08-11 11:35:10
【问题描述】:

问题

我使用应用程序中的 xdotool keydown Controlxdotool keyup Control 来模拟 Ctrl 按下。当布局设置为 us 时,一切正常,但当布局更改为其他内容(frru)时,应用程序将停止看到 ctrl 事件。

问题

为什么会这样?如何使 ctrl 键操作在布局中统一工作?

一些信息

我用来设置布局的命令:

setxkbmap -layout us,fr -option -option "grp:lctrl_lshift_toggle,ctrl:nocaps"

xev 的输出,us 布局:

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

xev 的输出,fr 布局:

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

【问题讨论】:

    标签: linux keyboard-layout xdotool


    【解决方案1】:

    xev 输出中可以看出,当处于 us 模式时,Control_L key down 相当于 keycode 37 状态从 0x10 移动到 0x14,而在 fr 模式下,您有键码 8 和状态 0x2010 没有 变化,以及几个 MappingNotify 事件。

    状态是当前应用修饰符的位图,例如移位, 控制,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 = 位 0(状态 0x1),
    2. 锁定 = 位 1(状态 0x2),
    3. 控制 = 位 2(状态 0x4)等

    您的状态 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'
    

    如 cmets 中所述,xdotool key 可以采用键码十进制数字而不是键符号参数。手册页中没有提到这一点。

    【讨论】:

    • 我的设置中已经有 'keycode 66 = Control_L Control_L Control_L Control_L',所以根据这个推理,它应该能够在映射中找到 Control_L?
    • 将 37 更改为所有 Control_L 也不会改变这一点。
    • @Rogach 您能否将xmodmap -pme|grep controlxmodmap -pke|grep Control 的输出添加到您的原始帖子中?
    • 好的,添加在问题的底部。
    • @Rogach 在你的 xev 输出中,原始状态是 0x2010,所以你必须有另一个修饰符 down,所以 4 列可能不够。试试 6 还是 8?
    猜你喜欢
    • 2013-07-25
    • 2015-01-10
    • 1970-01-01
    • 2018-07-21
    • 2010-11-19
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多