non*_*pop 17 linux keyboard-layout xkb
我不喜欢在主键盘和移动键之间跳转,所以我在我的 xkb 布局文件中添加了以下内容。
hidden partial xkb_symbols "movement"
{
key <AD08> { [ NoSymbol, NoSymbol, Up, Up ] };
key <AC08> { [ NoSymbol, NoSymbol, Down, Down ] };
key <AC07> { [ NoSymbol, NoSymbol, Left, Left ] };
key <AC09> { [ NoSymbol, NoSymbol, Right, Right ] };
key <AD09> { [ NoSymbol, NoSymbol, Prior, Prior ] };
key <AB09> { [ NoSymbol, NoSymbol, Next, Next ] };
key <AB07> { [ NoSymbol, NoSymbol, Home, Home ] };
key <AB08> { [ NoSymbol, NoSymbol, End, End ] };
key <AC06> { [ NoSymbol, NoSymbol, Delete, Delete ] };
}
Run Code Online (Sandbox Code Playgroud)
然后我稍后将这些包含在文件中的布局中。现在我应该可以通过 AltGr + j,k,l,i(或 h,t,n,c,因为我使用的是 dvorak)等来访问光标键。这在许多情况下都有效(如 Firefox、urxvt、Eclipse、 LyX 的主要文本区域),但是当我尝试使用这些“快捷方式”(如 NetBeans 和 LyX 对话框)移动光标时,有些程序什么也不做。
那么,有没有办法让这些其他程序也尊重我的意愿?为什么他们一开始就不工作?我没有使用 DE;只有真棒WM。
编辑:
Che*_*hel 19
根据您提到的ArchWiki 文章:
X 服务器从输入设备获取键码并将它们转换为 state和keysym。
state是 X 修饰符(Ctrl/Shift/等)的位掩码。
keysym是(根据/usr/include/X11/keysymdef.h)的整数
识别与键盘布局的每个键(例如,通过可见雕刻)相关联的字符或功能。
每个可打印字符都有自己的键符,例如plus, a, A, or
Cyrillic_a,但其他键也会生成它们的键符,例如
Shift_L, Leftor F1。
按键按下/释放事件中的应用程序获取所有这些信息。
一些应用程序像Control_L自己一样跟踪键符,其他应用程序只是在state 中查找修饰符位。
那么当你按下AltGr+时会发生什么j:
你按AltGr。应用程序使用键码 108 ( <RALT>) 和键符 0xfe03 ( ISO_Level3_Shift)获取 KeyPressed 事件,状态为 0。
您按下j(在没有修饰符的情况下映射到 dvorak 中的“h”)。应用程序使用键码 44 ( <AC07>)、键符 0xff51 ( Left) 和状态 0x80(修改器 Mod5 开启)获取 KeyPressed 事件。
你释放j。应用程序使用相同的参数获取键<AC07>/ 的KeyRelease 事件
Left。
然后释放AltGr——AltGr 的 KeyRelease 事件。(顺便说一下,这里的状态仍然是 0x80,但这并不重要。)
如果您运行xev实用程序,则可以看到这一点。
所以,这一切都意味着,虽然应用程序Left从普通 key获取相同的键符代码 ( ) <LEFT>,但它也从 AltGr 获取键符代码和修饰符状态。最有可能的是,那些不工作的程序,看着修改器并且不想在某些程序处于活动状态时工作。
显然,我们不能将每个程序更改为不寻找修饰符。那么避免这种情况的唯一选择是不生成修饰符的键符和状态位。
我想到的唯一方法是:在单独的组中定义光标移动键,并在按下j, k, l, i( h,
t, n, c)键之前通过单独的按键切换到该组(组锁存是首选方法据我了解,一次组更改)。
例如:
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compatibility {
include "complete"
interpret ISO_Group_Latch { action = LatchGroup(group=2); };
};
xkb_symbols {
include "pc+us(dvorak)+inet(evdev)"
key <RALT> { [ ISO_Group_Latch ] };
key <AC07> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Left ]
};
key <AC08> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Down ]
};
key <AC09> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Right ]
};
key <AD08> {
type[Group2] = "ONE_LEVEL",
symbols[Group2] = [ Up ]
};
};
xkb_geometry { include "pc(pc104)" };
};
Run Code Online (Sandbox Code Playgroud)
现在,如果您先按下AltGr然后(单独)一个移动键,这应该可以工作。
但是,这不是很有用,更合适的是LockGroup
在组切换前后而不是闩锁并按AltGr。更好的可能是SetGroup- 然后 AltGr 只会在被按下时选择该组,但这会向应用程序公开 AltGr 的键符(ISO_Group_Shift//ISO_Group_Latch定义的任何内容)(但修饰符状态保持干净)。
但是......还有一种可能性是应用程序还读取键码(真实键的代码)。然后它会注意到“假”光标键。
更“低级”的解决方案是覆盖(如同一篇文章 所述)。
覆盖只是意味着某些(真实键盘)键返回另一个键的键码。X 服务器更改键的键码并计算该新键码的修饰符状态和键符,因此应用程序不应注意到更改。
但是叠加非常有限:
至于其余的,实现与具有单独组的方法非常相似:
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compatibility {
include "complete"
interpret Overlay1_Enable {
action = SetControls(controls=overlay1);
};
};
xkb_symbols {
include "pc+us(dvorak)+inet(evdev)"
key <RALT> {
type[Group1] = "ONE_LEVEL",
symbols[Group1] = [ Overlay1_Enable ]
};
key <AC07> { overlay1 = <LEFT> };
key <AC08> { overlay1 = <DOWN> };
key <AC09> { overlay1 = <RGHT> };
key <AD08> { overlay1 = <UP> };
};
xkb_geometry { include "pc(pc104)" };
};
Run Code Online (Sandbox Code Playgroud)
SetControls意味着在按键被按下时改变控制位并在按键释放时恢复它。应该有类似的功能LatchControls,但
xkbcomp给了我
Error: Unknown action LatchControls
Run Code Online (Sandbox Code Playgroud)
关于键盘映射编译。
(顺便说一下,我也使用了 dvorak 并且还重新映射了一些移动键符到高级字母键。并且还遇到了一些损坏的功能(在 Xfce 笔记中选择和通过 Ctrl-Alt-Left/Right 切换桌面)。感谢你的问题和这个答案,现在我知道覆盖是什么:))
小智 6
以下解决方案使用左 Alt 键在 jkli 上提供光标键,在 uopö 上使用 Home/End/PageUp/PageDown,在 Backspace 上使用 Delete。
左 Alt 键仍可用于所有其他键的其他用途(如应用程序菜单)。当使用光标块时,左 Alt (Mod1) 从修改器状态中删除,因此应用程序无法看到它。
xkb_keymap {
xkb_keycodes {
include "evdev+aliases(qwertz)"
};
xkb_types {
include "complete"
};
xkb_compat {
include "complete"
interpret osfLeft {
action = RedirectKey(keycode=<LEFT>, clearmodifiers=Mod1);
};
interpret osfRight {
action = RedirectKey(keycode=<RGHT>, clearmodifiers=Mod1);
};
interpret osfUp {
action = RedirectKey(keycode=<UP>, clearmodifiers=Mod1);
};
interpret osfDown {
action = RedirectKey(keycode=<DOWN>, clearmodifiers=Mod1);
};
interpret osfBeginLine {
action = RedirectKey(keycode=<HOME>, clearmodifiers=Mod1);
};
interpret osfEndLine {
action = RedirectKey(keycode=<END>, clearmodifiers=Mod1);
};
interpret osfPageUp {
action = RedirectKey(keycode=<PGUP>, clearmodifiers=Mod1);
};
interpret osfPageDown {
action = RedirectKey(keycode=<PGDN>, clearmodifiers=Mod1);
};
interpret osfDelete {
action = RedirectKey(keycode=<DELE>, clearmodifiers=Mod1);
};
};
xkb_symbols {
include "pc+de(nodeadkeys)"
include "inet(evdev)"
include "compose(rwin)"
key <LALT> {
type[Group1] = "ONE_LEVEL",
symbols[Group1] = [ ISO_Level5_Shift ]
};
modifier_map Mod1 { <LALT> };
key <AC07> {
type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
symbols[Group1] = [ j, J, dead_belowdot, dead_abovedot, osfLeft, osfLeft, osfLeft, osfLeft ]
};
key <AC08> {
type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
symbols[Group1] = [ k, K, kra, ampersand, osfDown, osfDown, osfDown, osfDown ]
};
key <AC09> {
type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
symbols[Group1] = [ l, L, lstroke, Lstroke, osfRight, osfRight, osfRight, osfRight ]
};
key <AC10> {
type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
symbols[Group1] = [ odiaeresis, Odiaeresis, doubleacute, doubleacute, osfPageDown, osfPageDown, osfPageDown, osfPageDown ]
};
key <AD07> {
type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
symbols[Group1] = [ u, U, downarrow, uparrow, osfBeginLine, osfBeginLine, osfBeginLine, osfBeginLine ]
};
key <AD08> {
type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
symbols[Group1] = [ i, I, rightarrow, idotless, osfUp, osfUp, osfUp, osfUp ]
};
key <AD09> {
type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
symbols[Group1] = [ o, O, oslash, Oslash, osfEndLine, osfEndLine, osfEndLine, osfEndLine ]
};
key <AD10> {
type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
symbols[Group1] = [ p, P, thorn, THORN, osfPageUp, osfPageUp, osfPageUp, osfPageUp ]
};
key <BKSP> {
type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
symbols[Group1] = [ BackSpace, BackSpace, BackSpace, BackSpace, osfDelete, osfDelete, osfDelete, osfDelete ]
};
};
xkb_geometry {
include "pc(pc105)"
};
};
Run Code Online (Sandbox Code Playgroud)
我也有同样的问题。这太痛苦了。
所以标题是“如何让所有应用程序尊重我修改后的 xkb 布局?”。好吧,我认为唯一的方法是修复所有错误执行的程序。让我们这样做!
好吧,在报告NetBeans中的错误之后(更新:我已经尝试了最新版本,现在可以使用了!),我想我会继续为每个应用程序报告这个错误。名单上的下一个应用程序是Speedcrunch。
但是,在寻找类似的错误报告后,我发现了这个问题。别人也有同样的问题,太好了!
阅读评论后,您将了解此错误应该存在于所有 QT 应用程序中。这是一个QT 错误报告。未解决,但问题似乎已在 Qt5 中解决。
但是,如果您查看评论,则有一种解决方法!下面是它的工作原理。如果你这样做:
key <SPCE> { [ ISO_Level3_Shift ] };
Run Code Online (Sandbox Code Playgroud)
然后你可以把它改成这样:
key <SPCE> {
type[Group1]="ONE_LEVEL",
symbols[Group1] = [ ISO_Level3_Shift ]
};
Run Code Online (Sandbox Code Playgroud)
它实际上会解决一些应用程序的问题!例如,Speedcrunch现在对我有用!好极了!
现在任何应用程序都应该可以正常工作。如果没有,那么你必须使用type[Group1]="ONE_LEVEL". 如果您已经拥有它,那么您必须更新您的软件。如果它仍然不起作用,那么它是特定于应用程序的,您必须提交错误报告。
截至今天,所有应用程序都尊重我的键盘布局。除了一个。
说真的,Chromium 中的键盘处理是垃圾。它有几个问题:
foo,bar并且某些键在 中执行 Backspace foo,那么bar即使在那里重新定义它,它也会继续作为 Backspace in 工作。多年来,我只是通过不使用铬来忽略这些问题。然而,现在人们倾向于使用Electron,不幸的是它建立在 Chromium 上。
解决此问题的正确方法是在 Chromium 中提交错误报告并希望最好。我不知道他们需要多长时间才能解决一个只影响几个用户的问题……但这似乎是唯一的出路。问题在于,铬实际上与neo(de)布局配合得很好。Neo 布局在 level5 上有箭头键,但我无法让它在我的自定义布局中工作。
| 归档时间: |
|
| 查看次数: |
3478 次 |
| 最近记录: |