您如何模拟用于设计软件(例如Blender)的数字键盘/小键盘?

尖叫

问题

当使用某些软件(例如Blender)时,重要的是要能够使用数字键盘,以便用户可以在设计空间中进行诸如定位自己的事情,但是许多笔记本电脑并未配备物理数字键盘常规数字条输入(键盘顶部的1-9)实际上代表了计算机的不同“符号”,这使情况变得更加复杂,因此在这类软件中通常具有完全不同的功能。

尝试的解决方案

由于许多笔记本电脑都没有数字键盘,因此在许多平台上常见的解决方案是模拟数字键盘,例如在使用键盘上的其他键的同时按住一个键(例如jkluio789代表123456789)。许多笔记本电脑都在BIOS级别上实现此功能(例如使用Fn键)。但是,如果没有这样的低级实现,则很难实现此仿真。

某些解决方案在线存在,但通常不足以与设计软件配合使用(因为它们没有实现正确的符号,并且还需要使用修饰键),或者没有对其进行深入说明大多数解决方案都集中在使用xkb上,这是一个开始使用的复杂且异常困难的体系结构。

好的解决方案的要求

一个很好的解决方案是使用模拟键盘,图形软件将其视为真正的键盘输入,并且易于使用。进一步的限制是Blender的检测使用组合键(如事实ShiftAltSuper(“命令”,“Windows键”等), Hyper),即使xkb被告知明确的改性剂,并因此将演绎一个“键盘仿真,而按住修饰键”解决方案作为完全不同的输入(即[ Numpad1+ Alt]而不是Numpad1)。因此,理想的解决方案实际上将涉及锁定机制(例如Caps Lock大写)而不是保持机制(例如Shift大写),这样就不会有修饰符被意外地传递给软件。

尖叫

快速开始

如果您不关心任何解释(我知道我可能会感到有些困惑),只需遵循一些段落开头{大括号中的粗体数字}按顺序执行以下每个步骤,您可能会在几分钟内实现此步骤。请注意,本指南假定您具有一定的Unix能力(能够创建目录,创建文件,sudo提升为root访问权限等)。还要注意,仅在指示的地方才需要root用户访问权限,因此sudo除非告知您,否则您无需使用

解决方案的一般说明

我们将使用xkb向Linux添加“锁定”(如Caps lock)数字键盘模拟。我希望我的键“ jkluio789”代表数字“ 123456789”的数字键盘表示形式,以及其他一些包含项(“ m,”->“ 0”,“-= []”-> [numpad]” -+ *“,”。“-> [数字键盘]”。“)。我将通过使用[ Shift+ Mod4+ [key]]的组合键来切换此“小键盘模式”,其中,这Mod4是我的操作系统键的修饰符代码(也称为“ Command”或“ Windows Key”,有时分配给Super的修饰符代码Hyper) ,[key]是我在模拟小键盘上使用的任何键(例如“ j”或“ [”)。

为此,我们将定义一个自定义xkb“类型”文件,该文件将告诉xkb如何解释将用于初始化键盘模拟的各种修饰键,以及一个自定义xkb“符号”文件,该文件将告诉xkb每个我们按的键应该正常运行(第1组),在数字小键盘模拟过程中应该如何运行(第2组),以及如何在两个开关之间切换以及在这两者之间进行切换(两个组的3级操作)。最后,我们将在sed每次启动新会话时将其集成到当前xkbmap中,从而使该解决方案永久化(这样,我们的解决方案就不会在每次xkb更新被擦除)。

解决方案的详细说明

目录结构

{1}我们要做的第一件事是为我们定义一个目录,以保存各种文件。您的文件看起来几乎可以是任何东西,但是我的看起来像这样

/home
  +-<username>
    +-.xkb
      +-symbols
      +-types
      +-keymap
      +-log

类型文件

一旦有了目录树,就可以在解决方案中定义实际的文件。我们要做的第一件事是定义“类型”文件。该文件将告诉您xkb如何在“级别”之间移动(例如,如何将Shift大写字母从小写字母的第一级移动到大写字母的大写级别)。这些级别有点难以掌握,特别是对于以英语为母语的人,但是国际键盘使用它们对替代字母和符号以及变音标记有很大的作用。

我们将使用它来定义我们打算如何指示密钥更改。换句话说,我们告诉我们,当没有按下修饰符时,我们期望“ 1级”行为(在“正常模式”下,通常是标准的小写字母);在按住键时,我们期望“ 2级”行为Shift(通常,当我们同时持有两个Shift+ Mod4(出于我们的目的的一种特殊情况,我们用来指示在用于修改键时,该键现在将在“正常模式”中显示为标准大写字母)和“级别3”行为在模式之间切换)。

{2}打开一个新文件,我们将其称为togglekeypad将以下代码块复制到其中,然后将其保存到types目录中\home\<username>\.xkb\types注意:您可能需要将所有实例更改Mod4为您的“命令” /“ Windows键”按钮所对应的任何修饰符(您可能需要尝试,请参见此网页的“修饰符”下的指导)或您想要的任何其他修饰符。

partial default xkb_types "togglekeypad" { // Name of this type file
        type "TOGGLEKEYPAD" { // Name of this "type"
                modifiers = Shift+Mod4; // The modifiers that this type concerns itself with
                map[Shift] = level2; // Shift brings us to level 2
                map[Mod4+Shift] = level3; // Windows key plus shift brings us to level 3
                level_name[Level1] = "Base"; // Human-readable names for each level (not really used, but convenient)
                level_name[Level2] = "Shift";
                level_name[Level3] = "Transfer";
        };
};

{3}我们还必须将此文件复制到目录/usr/share/X11/xkb/types/这将需要root特权,这不幸地破坏了xkb成为用户空间应用程序的目的,但是如果setxkbmap不这样做,我似乎无法识别该文件。欢迎提出建议!

符号文件

接下来要做的事情是告诉xkb我们,以我们在类型文件中描述的每种方式进行修改后,每个键应该做什么。

我们将说我们要在符号文件中使用两个组。这意味着每个键都有两个不同的常规行为,我们将以某种方式在它们之间进行切换,这些行为是常规的键入行为,以及新的numpad仿真行为。对于每个键,我们将说1)我们要使用TOGGLEKEYPAD类型,2)我们将定义与所有级别中两个组中的每个物理键关联的符号(即计算机看到的内容),以及3)我们将xkb为所有级别的两个组定义与每个键相关联的任何操作(应执行的任何特殊操作)。这听起来有点令人困惑,但是在看一个例子时应该更有意义。

我们在下面粘贴的符号文件中看到的第一个键是<AC07>键。根据此处显示的映射(图2),这对应于大多数键盘上的“ J”键对于此物理键,我们说的是,在正常模式下:在级别1(根据我们的类型文件,没有修饰符)中,它将仅键入“ j”,而在级别2(Shift修饰符)中,将仅键入“ J”。在级别3中,它做了一些特殊的事情:没有与级别3相关联的符号,但是有一个动作,而该动作是to LockGroup(group=2)换句话说,将我们切换到第二个组,即“键盘”组。如果我们看接下来的几行,我们会看到为同一密钥为组2定义了更多的符号和动作。它说,在级别1(无修饰符)中,不键入符号,但RedirectKey(keycode=<KP1>)换句话说,注册该键就像实际按下该<KP1>键一样,该键与小键盘上的“ 1”相对应。(注意:我们可以再次放置NoAction()并使用symbol KP_1,它是键<KP1>对应的符号,但我认为这样做会提供最佳的兼容性)。对于级别2,执行相同的操作,但将Shift修改器添加到关键点。最后,对于第3级,我们将自己锁定为第1组“标准”模式。

{4}打开一个新文件,我们将其称为togglekeypad_symbols将以下代码块复制到其中,然后将其保存到symbols目录中\home\<username>\.xkb\symbols

default partial
xkb_symbols "togglekeypad" {
    name[Group1]= "Standard";
    name[Group2]= "Keypad";

    key <AC07> { // J
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ j,  J, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP1>), RedirectKey(keyCode=<KP1>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AC08> { // K
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ k,  K, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP2>), RedirectKey(keyCode=<KP2>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AC09> { // L
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ l,  L, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP3>), RedirectKey(keyCode=<KP3>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AD07> { // U
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ u,  U, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP4>), RedirectKey(keyCode=<KP4>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AD08> { // I
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ i,  I, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP5>), RedirectKey(keyCode=<KP5>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AD09> { // O
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ o,  O, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP6>), RedirectKey(keyCode=<KP6>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AE07> { // 7
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ 7,  ampersand, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP7>), RedirectKey(keyCode=<KP7>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AE08> { // 8
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ 8,  asterisk, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],     
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP8>), RedirectKey(keyCode=<KP8>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AE09> { // 9
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ 9,  parenleft, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP9>), RedirectKey(keyCode=<KP9>), LockGroup(group=1)]
    };
    
    // NumLock
    key <AE06> { // 6
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ 6,  asciicircum, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<NMLK>), RedirectKey(keyCode=<NMLK>), LockGroup(group=1)]
    };
    
    // Bottom Row (and zero)
    key <AB07> { // M
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ m,  M, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP0>), RedirectKey(keyCode=<KP0>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AE10> { // 0
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ 0,  parenright, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KP0>), RedirectKey(keyCode=<KP0>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AB09> { // .
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ period,  greater, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KPDL>), RedirectKey(keyCode=<KPDL>, modifiers=Shift), LockGroup(group=1)]
    };
    
    // Arithmetic Operators
    key <AE11> { // -
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ minus,  underscore, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KPSU>), RedirectKey(keyCode=<KPSU>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AE12> { // +
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ equal,  plus, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KPAD>), RedirectKey(keyCode=<KPAD>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AD12> { // [
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ bracketleft,  braceleft, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KPDV>), RedirectKey(keyCode=<KPDV>, modifiers=Shift), LockGroup(group=1)]
    };
    
    key <AD12> { // ]
        type = "TOGGLEKEYPAD",
        symbols[Group1] = [ bracketright,  braceright, NoSymbol],
        actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
        
        symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
        actions[Group2] = [RedirectKey(keyCode=<KPMU>), RedirectKey(keyCode=<KPMU>, modifiers=Shift), LockGroup(group=1)]
    };
};

测试我们的键盘

{5}要按原样测试键盘配置,请打开一个Terminal窗口并键入

setxkbmap -types complete+togglekeypad -print | sed -e '/xkb_symbols/s/"[[:space:]]/+togglekeypad_symbols(togglekeypad)&/' > $HOME/.xkb/keymap/customMap
xkbcomp -I$HOME/.xkb -R$HOME/.xkb keymap/customMap $DISPLAY

这将获取xkb地图的当前设置(使用setxkbmap - print),同时设置用于的类型complete+togglekeypad(文件中的所有内容/usr/share/X11/xkb/types/complete,还包括位于的类型文件/usr/share/X11/xkb/types/togglekeypad)。然后它将输入到中sed,这会将togglekeypad文件中的符号添加togglekeypad_symbols到使用的符号文件中。最后,我们用来xkbcomp编译新的键盘映射。

请注意,在我的计算机上,假定NumLock已关闭(因为我的计算机上没有数字键盘),因此,数字键盘按键实际上会将其主要功能发送到计算机,例如Home,End,PG Up,PG Down等。 。要获取使用模拟小键盘时输入的数字,请按住Shift。我尝试了多种方法来翻转此行为(modifers在符号文件中的层之间交换参数,分配新的键以模拟NumLock键<NMLK>并进行切换),但对我而言仍然没有任何效果。值得庆幸的是,在Blender中进行测试时,它的性能完全符合预期,而无需按住Shift键。

{6}如果此时发生了可怕的错误,请不要担心,只需注销/登录(或在最坏的重启方式下),调试,然后重试。如果一切正常,就让它永久化。

使解决方案永久存在

当然,有一些更优雅的方法可以使我们的解决方案在会话之间持久化,但是对我来说,最简单,最可靠的方法是将上述命令简单地放在~/.bashrc文件末尾。我使用了这里提出解决方案解决方案增加了一些错误检查,并增加了更多的错误(因此我可以看到任何错误输出)。

{7}打开文件~/.bashrc在其末尾添加以下脚本:

    # Setup custom keyboard remapping to emulate a number pad when "Shift+Cmd+numap_key" is pressed to initialize
if [ -d $HOME/.xkb/keymap ]; then
  setxkbmap -types complete+togglekeypad -print | \
    sed -e '/xkb_symbols/s/"[[:space:]]/+togglekeypad_symbols(togglekeypad)&/' > $HOME/.xkb/keymap/customMap 2> $HOME/.xkb/log/sedErrors
  xkbcomp -w0 -I$HOME/.xkb -R$HOME/.xkb keymap/customMap $DISPLAY > $HOME/.xkb/log/outputOfCommand 2>&1
fi

{8}重新启动后,现在应该使小键盘仿真永久!

结论

尽管解释很长,但方法本身却相对简短。不足之处是Blender需要使用锁定方法才能正常工作,而我本来希望使用保持方法,而且xkb由于某种原因,它需要具有root访问权限才能识别我们的自定义类型文件。但是,总的来说,这对我来说似乎很好。如果您有任何疑问或建议,请随时将它们留在下面!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Qt Quick Controls 2屏幕数字小键盘上的数字键盘

来自分类Dev

捕获数字键盘的数字键击

来自分类Dev

如何在PC笔记本电脑上模拟数字键盘?

来自分类Dev

带小数的数字键盘

来自分类Dev

iPad中的数字键盘?

来自分类Dev

制作屏幕数字键盘

来自分类Dev

Qml TextField数字键盘

来自分类Dev

数字键盘不工作

来自分类Dev

SwiftUI:数字键盘布局

来自分类Dev

如何显示android数字键盘?

来自分类Dev

如何使用数字键盘作为鼠标?

来自分类Dev

如何强制移动浏览器拔出用于输入type =“ text”的数字键盘?

来自分类Dev

如何在iOS 7上模拟键盘动画以将“完成”按钮添加到数字键盘?

来自分类Dev

键盘编号与数字键盘按键

来自分类Dev

键盘数字键盘不起作用

来自分类Dev

Qt如何使法语键盘的点键(数字键盘)用作输入?

来自分类Dev

如何将Alertcontroller文本字段键盘更改为数字键盘?

来自分类Dev

如何使用Linix Mint在键盘上配置集成数字键盘?

来自分类Dev

如何将Alertcontroller文本字段键盘更改为数字键盘?

来自分类Dev

更改Android数字键盘中的“完成”按钮

来自分类Dev

带数字键盘和逗号的EditText

来自分类Dev

以编程方式限制EditText以显示数字键盘

来自分类Dev

数字键盘顶部出现黑条

来自分类Dev

数字键盘显示不正确

来自分类Dev

具有不同布局的数字键盘

来自分类Dev

GetKeyNameText数字键盘缺少文本

来自分类Dev

Android中的Android Open数字键盘

来自分类Dev

具有不同布局的数字键盘

来自分类Dev

Linux替代alt +数字键盘代码