我的自定义键盘映射仅通过 xdg_shell 应用程序起作用,而不能通过 xwayland 起作用。我已将 Sway 配置为在标题栏中显示通过 xwayland 运行的内容和未通过 xwayland 运行的内容,使用for_window [tiling] title_format "%title — $shell"
。
我的问题:这是 Sway 或 XWayland 中的错误吗,或者我可以对我的配置做些什么来使其正常工作?
版本:
- 系统:Ubuntu 20.10
- Sway:v1.5
- Xwayland:软件包版本:2:1.20.10-2
我在 X 下使用 xmodmap 创建了一个 xkb 键盘映射。示例内容:
add mod3 = Mode_switch
keycode 40 = e E U2203 U2203
(因为我运行的是 Dvorak,所以键码为 40)
这使得我的右 Alt 键Mode_Switch
(Mod3),并使 Mod3+e 写入“∃”(“存在”)。
我使用以下方式转储了我的 xkb:。xkbcomp -xkb :0 test.xkb
该文件中的相关映射是:
key <AC03> {
type[group1]= "ALPHABETIC",
type[group2]= "ALPHABETIC",
type[group3]= "ONE_LEVEL",
type[group4]= "ONE_LEVEL",
symbols[Group1]= [ e, E ],
symbols[Group2]= [ U2203, U2203 ],
symbols[Group3]= [ NoSymbol ],
symbols[Group4]= [ NoSymbol ]
};
然后我在 Sway 中xkb_file test.xkb
加载此键盘布局。这在通过 xdg_shell 的应用程序中运行良好,但在通过 xwayland 的应用程序中则不行。通过 xwayland 它就什么都没有了。
无法运行的 X 个程序示例:
- 终端
- google chrome(以默认参数启动)
本机 Wayland 示例:
- gnome 终端
- 谷歌浏览器开始
-enable-features=UseOzonePlatform -ozone-platform=wayland
xev -event keyboard
我也在比较no的输出wev -f wl_keyboard
。
在 X 和 Wayland 中,我都看到 Mode_Switch 按键,但下一个e
键变成了keysym 0x0, NoSymbol
。在 wev 中,我看到符号写得很好。请参阅下文了解确切输出。
xev -event keyboard
KeyPress event, serial 28, synthetic NO, window 0xc00001,
root 0x525, subw 0x0, time 371977355, (63,73), root:(3107,635),
state 0x0, keycode 66 (keysym 0xff7e, Mode_switch), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 28, synthetic NO, window 0xc00001,
root 0x525, subw 0x0, time 371977635, (63,73), root:(3107,635),
state 0x4000, keycode 40 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0xc00001,
root 0x525, subw 0x0, time 371977787, (63,73), root:(3107,635),
state 0x4000, keycode 40 (keysym 0x0, NoSymbol), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0xc00001,
root 0x525, subw 0x0, time 371981259, (63,73), root:(3107,635),
state 0x4000, keycode 66 (keysym 0xff7e, Mode_switch), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
wev -f wl_keyboard
[14: wl_keyboard] modifiers: serial: 0; group: 0
depressed: 00000000
latched: 00000000
locked: 00000000
[14: wl_keyboard] key: serial: 120526; time: 372129172; key: 66; state: 1 (pressed)
sym: Mode_switch (65406), utf8: ''
[14: wl_keyboard] modifiers: serial: 1; group: 0
depressed: 00000000
latched: 00000000
locked: 00000000
[14: wl_keyboard] key: serial: 120528; time: 372129674; key: 40; state: 1 (pressed)
sym: U2203 (16785923), utf8: '\u2203'
[14: wl_keyboard] key: serial: 120529; time: 372129756; key: 40; state: 0 (released)
sym: U2203 (16785923), utf8: ''
[14: wl_keyboard] key: serial: 120530; time: 372130300; key: 66; state: 0 (released)
sym: Mode_switch (65406), utf8: ''
[14: wl_keyboard] modifiers: serial: 0; group: 0
depressed: 00000000
latched: 00000000
locked: 00000000
答案1
您应该通过创建来使用 libxkbcommon 而不是 xmodmap $HOME/.config/xkb
。这文章详细介绍了 Wayland 和 XWayland 如何与用户特定的 XKB 配置协同工作。
Wayland 的键盘配置工作如下:
- 合成器通过带外通道(例如 gsettings、weston.ini 等)决定 RMLVO 键盘布局
- 合成器调用 libxkbcommon 来生成 KcCGST 键映射并将该完整键映射传递给客户端
- 客户端使用 libxkbcommon 编译该键盘映射,并将所有按键事件输入 libxkbcommon 的状态跟踪器中以获取正确的按键符号
我们的优势在于,实体之间只传递完整的键映射。更改该键映射的生成方式不会影响客户端。巧合的是,这也是 Xwayland 获取传递给它的键映射的方式,也是 Xwayland 使用用户特定布局的原因。
我也使用 Sway,自定义布局没有出现任何问题。这是我的配置带有其自己的综合 README。其中还包含其他资源。