使用 XKB 的多个修改器层(在日语键盘上)

使用 XKB 的多个修改器层(在日语键盘上)

我有以下键盘(HHKB JP)。

图像

我正在使用 Lubuntu 14.04,并且我已经编辑/usr/share/X11/xkb/symbols/us以实现自定义布局

现在,我想使用以下键作为第 5、6、7、... 和 20 级修饰符。 (在 Windows 上,我使用 AutoHotkey 来完成此操作,现在我不能没有它们(至少是其中一些)。)

在此输入图像描述

我有两个问题。

  1. 我不知道键盘上一些非标准键的“名称”是什么(以便将它们添加到/usr/share/X11/xkb/symbols/us)。
  2. 我不知道如何添加额外的修饰符xkb(我知道xmodmap已弃用),特别是“普通”键,例如9.

我的问题是:

  1. 我如何找出神秘钥匙的名称/代码(例如key <AC01>)?
  2. 如何向任何给定的键添加任意数量的修饰符层?

注意:XKB 或许无法实现这一点。我很高兴知道有一些脚本工具可以实现这一点。

答案1

RMLVOXKB 布局在名为:Rules、Model、Layout、Variant、Options 的模型中定义。系统XKB数据库通常位于/usr/share/X11/xkb

/usr/share/X11/xkb/
├── compat       # ??? dark magic here, avoid
├── geometry     # as in physical, eg for generating layout maps
├── keycodes     # helpful for translating keycodes (from xev) to <FOO>
├── rules        # "evdev" is the important one; *.lst & *.xml are descriptions
├── symbols      # main layouts, variants, optional overrides
└── types        # ??? dark magic here, avoid

keycodes目录将定义键名类似于<CAPS><AC01>来自键实际生成的扫描码。 setxkbmap -query -verbose 10将准确显示哪些文件被访问来构建当前的键盘映射;当它显示 时keycodes: evdev+aliases(qwerty),它正在加载../keycodes/evdev文件和文件qwerty中的节../keycodes/aliases。如果您使用类似的工具xev来确定某个键正在生成什么键码,这些文件将显示映射到该代码的键名。


你的修饰符问题更难。我只看到参考8ISO 级别,我不确定这是否是 XKB 限制,或者只是没有常见布局使用更多。 (进一步检查后,我很确定您必须更改 XKB 代码才能添加额外的

            symbol    press this
level 1       a       key
level 2       A       shift+key
level 3       á       <level3>+key
level 4       Á       <level3>+shift+key
level 5       ??      <level5>+key
level 6       ??      <level5>+shift+key
level 7       ??      <level5>+<level3>+key
level 8       ??      <level5>+<level3>+shift+key

正如您所看到的,在 8 级布局中,只有 2 个键充当“新修饰符”键。请参阅/usr/share/X11/xkb/compat/level5/usr/share/X11/xkb/types/level5,其中定义了 level5 移位、闩锁和锁定行为;然后,它们通过 中定义的符号选项附加到键上/usr/share/X11/xkb/symbols/level5

如果你定义了自己的level9修改器,然后,与现有级别相结合将为您提供 8 个以上的级别,然后您将需要另一个级别修改器:

            symbol    press this
level 9       ??      <level9>+key
level 10      ??      <level9>+shift+key
level 11      ??      <level9>+<level3>+key
level 12      ??      <level9>+<level3>+shift+key
level 13      ??      <level9>+<level5>+key
level 14      ??      <level9>+<level5>+shift+key
level 15      ??      <level9>+<level5>+<level3>+key
level 16      ??      <level9>+<level5>+<level3>+shift+key

正如您所看到的,这开始是同时按下很多键。使用闩锁代替转变会减少它,但这将是一个非常复杂的布局,我们只想象添加一个级别选择器。每个额外的选择器都会使现有级别加倍。


您设想的“修饰符”可能会选择一个特定级别,这就是您认为需要这么多级别的原因。您也许可以像这样定义选择操作,并将它们放在这些键的第 3 级上,这样level3+key9就给您一个level14_latch操作,然后您接下来按的任何键都会为您提供该键的第 14 级。

编辑:另一个问题具体询问了有关制作 的问题ISO_Level4_{Shift,Latch,Lock},我演示了假的ISO_Level4_Latch使用现有的 XKB 键符号和操作。该方法对于 4、6、7 和 8 级应该有效。

答案2

这是一个老问题,但由于没有正确的答案,而且我出于自己的原因对这个问题感兴趣,所以我花时间解决了这个问题。配置 XKB 可能很棘手,但这当然可以完成。

对于第一个问题,您可以使用以下神奇命令生成一张包含当前配置的键盘上所有按键名称的图片:

setxkbmap -print | xkbcomp - - | xkbprint -color -label name - - | ps2pdf - > keynames.pdf

并查看 pdf 文件 keynames.pdf

对于第二个问题,我们必须深入了解XKB配置。我相信最好的信息来源是开发者文档。简而言之,我们需要将键映射到“真实修饰符”的组合,并且需要将这些组合映射到键的级别。

在符号文件中,我们想写例如

key <AC01>  { [ a, A, b, B, c, C, d, D, e, E, f, F, g, G,
                h, i, j, k, l, m, n, o, p, q, r, s, t, u]}; 

这意味着在 A 的按钮上,我们有符号A在第一层,A第二个,第三个,依此类推,然后将键映射到各个级别。然而,正如这个例子所表明的,对于某些修饰键来说,让每个其他级别对应于按修饰键 + Shift 键可能是有意义的,并且对于某些键,无论是否按下 Shift 都会产生相同的符号。这就是我们要完成的任务。

XKB 使用“真实”和“虚拟”修饰符来跟踪修饰符级别。虚拟的可以有任何名称,我们可以有 16 个。然而,每个键都需要对应于“真实”修饰符的组合,并且由于我们将使用大量键,因此我们也可以立即使用真实修饰符。

使事情变得复杂的是,有一个固定的“真实修饰符”列表,即八个 Shift、Lock、Control 和 Mod1 到 Mod5。然而,也可以使用这些的任意组合,因此理论上每个键有 2⁸ = 256 个不同的级别。然而,在实践中,其中一些已经在操作系统和程序中以各种方式使用,因此我们在选择它们时必须小心一些。 XKB 中每个键的符号级别也有 63 或 64 级限制,但可以使用团体将该数字乘以四。我们不会在这里使用组。

Control 和 Mod1 = Alt 修饰符是操作系统和程序常用的,因此我们不会使用它们。 Mod4 = Super 也被使用,但是我们可以将它与其他修饰符一起使用。我们首先创建一个类型将修改器组合映射到级别的文件。将以下内容写入名为 multimod_type 的文件中,并将其放置在 /usr/share/X11/xkb/types 中。

default partial xkb_types "multimod_type" {

 // We use real modifiers Shift, Mod2, Mod3, Mod4, Mod5.
 // Mod1 = Alt, so we do not use this.
 // In addition, Mod4 = Super is used by the OS, which causes
 // problems in four places. 

type "MULTIMOD" {
modifiers = Shift + Mod2 + Mod3 + Mod4 + Mod5;
map[None] = 1;
map[Shift] = 2;
map[Mod2] = 3;
map[Mod2 + Shift] = 4;
map[Mod3] = 5;
map[Mod3 + Shift] = 6;
map[Mod3 + Mod2] = 7;
map[Mod3 + Mod2 + Shift] = 8;
map[Mod4 + Mod3] = 9;
map[Mod4 + Mod3 + Shift] = 10;
map[Mod4 + Mod3 + Mod2] = 11;
map[Mod4 + Mod3 + Mod2 + Shift] = 12;
map[Mod5] = 13;
map[Mod5 + Shift] = 14;
map[Mod5 + Mod2] = 15;
map[Mod5 + Mod2 + Shift] = 16;
map[Mod5 + Mod3] = 17;
map[Mod5 + Mod3 + Shift] = 18;
map[Mod5 + Mod3 + Mod2] = 19;
map[Mod5 + Mod3 + Mod2 + Shift] = 20;
map[Mod5 + Mod4 + Mod3] = 21;
map[Mod5 + Mod4 + Mod3 + Shift] = 22;
map[Mod5 + Mod4 + Mod3 + Mod2] = 23;
map[Mod5 + Mod4 + Mod3 + Mod2 + Shift] = 24;
// Mod4 = Super is used
map[Mod4 + Shift] = 25;
// Mod4 + Mod2 is used
map[Mod4 + Mod2 + Shift] = 26;
// Mod5 + Mod4 is used
map[Mod5 + Mod4 + Shift] = 27;
// Mod5 + Mod4 + Mod2 is used
map[Mod5 + Mod4 + Mod2 + Shift] = 28;
// Level names are only for description. The values are not used.
level_name[1] = "Base";
level_name[2] = "Shift";
level_name[3] = "Alt1";
level_name[4] = "Alt1 + Shift";
level_name[5] = "Alt2";
level_name[6] = "Alt2 + Shift";
level_name[7] = "Alt3";
level_name[8] = "Alt3 + Shift";
level_name[9] = "Alt4";
level_name[10] = "Alt4 + Shift";
level_name[11] = "Alt5";
level_name[12] = "Alt5 + Shift";
level_name[13] = "Alt6";
level_name[14] = "Alt6 + Shift";
level_name[15] = "Alt7";
level_name[16] = "Alt8";
level_name[17] = "Alt9";
level_name[18] = "Alt10";
level_name[19] = "Alt11";
level_name[20] = "Alt12";
level_name[21] = "Alt13";
level_name[22] = "Alt14";
level_name[23] = "Alt15";
level_name[24] = "Alt16";
level_name[25] = "Alt17";
level_name[26] = "Alt18";
level_name[27] = "Alt19";
level_name[28] = "Alt20";
};
};

顾名思义,我们将有 20 个额外的修饰按钮,其中前 6 个可以与 Shift 结合使用。

要使用它,请修改符号文件的这个最小工作示例。我称之为 multimod_se。像往常一样将其保存在 /usr/share/X11/xkb/symbols 中。

default partial alphanumeric_keys xkb_symbols "multimod_se" {

// Include your favourite symbols
include "se"

name[Group1]="Swedish with many modifiers on A";

key.type[Group1] = "MULTIMOD";

key <AC01>  { [ a, A, b, B, c, C, d, D, e, E, f, F, g, G,
                h, i, j, k, l, m, n, o, p, q, r, s, t, u]}; 

// ----- Modifiers -----
key.type = "ONE_LEVEL";
key.repeats = False;

// We will map F1-F10 and 1-9 and 0 to the modifier keys
// The keys F1-F6 produce different symbols with shift pressed
key <FK01> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2)]};
key <FK02> { [ Hyper_R ], actions = [SetMods(modifiers=Mod3)]};
key <FK03> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod3)]};
key <FK04> { [ Hyper_R ], actions = [SetMods(modifiers=Mod3+Mod4)]};
key <FK05> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod3+Mod4)]};
key <FK06> { [ Hyper_R ], actions = [SetMods(modifiers=Mod5)]};

// We can bind buttons to include shift in order to get a
// shortcut to a modifier button + shift
key <FK07> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod5)]};
key <FK08> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod5+Shift)]};
key <FK09> { [ Hyper_R ], actions = [SetMods(modifiers=Mod3+Mod5)]};
key <FK10> { [ Hyper_R ], actions = [SetMods(modifiers=Mod3+Mod5+Shift)]};
key <AE01> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod3+Mod5)]};
key <AE02> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod3+Mod5+Shift)]};
key <AE03> { [ Hyper_R ], actions = [SetMods(modifiers=Mod3+Mod4+Mod5)]};
key <AE04> { [ Hyper_R ], actions = [SetMods(modifiers=Mod3+Mod4+Mod5+Shift)]};
key <AE05> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod3+Mod4+Mod5)]};
key <AE06> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod3+Mod4+Mod5+Shift)]};

// The following four must be defined with shift
key <AE07> { [ Hyper_R ], actions = [SetMods(modifiers=Mod4+Shift)]};
key <AE08> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod4+Shift)]};
key <AE09> { [ Hyper_R ], actions = [SetMods(modifiers=Mod4+Mod5+Shift)]};
key <AE10> { [ Hyper_R ], actions = [SetMods(modifiers=Mod2+Mod4+Mod5+Shift)]};
};

这将创建一个键盘映射,其中 F1 到 F10 和 1 到 9 以及 0 是额外的修饰键。将它们与按钮 A 一起按下将打印字母 au,并且与 Shift 一起按下我们还会打印出 AG。使用命令将符号与类型文件一起加载

setxkbmap -types complete+multimod_type multimod_se

我们包含标准类型文件完全的因为我们使用 ONE_LEVEL 类型作为修饰键,以及包含的符号文件中的一些其他类型。

一些评论: 处理修饰符的标准方法是使用规则兼容文件,但这需要一个唯一的符号,该符号对于每个修饰键不执行任何其他操作。我们可以通过直接在符号文件中定义修饰符规则来解决这个问题,如上所述。正如您所看到的,所有修饰键都带有符号 Hyper_R。

如果您需要更多修饰键,还可以包含操作系统或程序未使用的 Mod1、Control 和 Lock 的组合来表示其他内容。

相关内容