機能しない理由
あなたが言及した ArchWiki の記事によると:
-
X サーバーは キーコード を取得します 入力デバイスから状態に変換します およびkeysym .
-
状態 X 修飾子 (Ctrl/Shift/etc) のビットマスクです。
-
キーシム は (
<ブロック引用>/usr/include/X11/keysymdef.h
によると) ) 整数キーボード レイアウトの各キーに関連付けられている文字または機能を識別します (例:目に見える刻印を介して)。
plus
のように、印刷可能な各文字には独自のキーシムがあります。 、a
、A
、またはCyrillic_a
、しかし他のキーもShift_L
のようにキーシムを生成します 、Left
またはF1
.
-
-
キー プレス/リリース イベントのアプリケーションは、このすべての情報を取得します。
一部のアプリケーションは
Control_L
のようなキーシムを追跡します state の修飾子ビットを探すだけの場合もあります。 .
AltGr を押すとどうなるか +j :
-
AltGr を押します .アプリケーションは keycode108 (
<RALT>
) で KeyPressed イベントを取得します ) および keysym 0xfe03 (ISO_Level3_Shift
)、状態は 0 です。 -
j を押します (修飾子なしで dvorak の「h」にマップされます)。アプリケーションは、キーコード 44 (
<AC07>
) で KeyPressed イベントを取得します。 )、keysym 0xff51(Left
) および状態 0x80 (修飾子 Mod5 がオン)。 -
あなたは j を解放します .アプリケーションは、キー
<AC07>
の KeyRelease イベントを取得します /Left
同じパラメータで。 -
次に AltGr を放します — AltGr の KeyRelease イベント。 (ちなみに、ここの状態はまだ 0x80 ですが、それは問題ではありません。)
これは、xev
を実行すると確認できます。
つまり、アプリケーションは同じ keysym コード (Left
) を取得しますが、 ) 通常のキー <LEFT>
と同様 また、AltGr から keysym コードと modifier 状態も取得します。ほとんどの場合、動作しないプログラムは、修飾子を監視し、いくつかがアクティブなときに動作したくない.
機能させる方法
どうやら、修飾子を探さないようにすべてのプログラムを変更することはできないようです。この状況を回避する唯一のオプションは、修飾子のキーシムと状態ビットを生成しないことです。
1.別のグループ
私の頭に浮かぶ唯一の方法は、別のグループでカーソル移動キーを定義し、キーを押す前に別のキーを押してそのグループに切り替えることです j 、k , l 、私 (h
,t
、 n
、 c
) (私が理解しているように、グループ ラッチは、1 回のグループ変更に適した方法です)。
例:
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)" };
};
ここで、最初に AltGr を押すと 次に、(個別に) 移動キーの 1 つを使用すると、これが機能するはずです。
ただし、これはあまり役に立ちません。より適切なのは LockGroup
です。 ラッチの代わりに、グループ切り替えの前後に AltGr を押します。たぶん SetGroup
に — 次に、AltGr は押されている間だけそのグループを選択しますが、それはアプリケーションに AltGr の keysym(ISO_Group_Shift
/ISO_Group_Latch
/定義されているものは何でも) (ただし、修飾子の状態はクリーンなままです)。
しかし... アプリケーションがキーコード (実際のキーのコード) も読み取る可能性が残されています。次に、「偽の」カーソル キーに気付きます。
2.オーバーレイ
より「低レベル」のソリューションは、overlay です。 (同じ記事が説明しているように).
オーバーレイ 単純に、ある (実際のキーボードの) キーが別のキーのキーコードを返すことを意味します。 X サーバーはキーのキーコードを変更し、その新しいキーコードの修飾子の状態とキーシムを計算するため、アプリケーションは変更に気付かないはずです。
ただし、オーバーレイは非常に限られています:
- X サーバーには 2 つのオーバーレイ制御ビットしかありません (つまり、最大 2 つのオーバーレイが存在できます)。
- 各キーには代替キーコードを 1 つだけ含めることができます。
残りについては、実装は個別のグループを使用したメソッドと非常に似ています:
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)" };
};
SetControls
キーが押されている間に制御ビットを変更し、キーを離すと元に戻すことを意味します。同様の機能 LatchControls
があるはずです 、しかしxkbcomp
私にくれます
Error: Unknown action LatchControls
キーマップのコンパイルについて。
(ちなみに、私も dvorak を使用しており、いくつかの移動キーシムを高レベルのアルファベット キーに再マッピングしました。また、いくつかの壊れた機能 (Xfce ノートでの選択と Ctrl-Alt-Left/Right によるデスクトップ スイッチ) に遭遇しました)。そしてこの答え、今私はオーバーレイが何であるかを知っています:))
それらを機能させる方法 - 解決策 3
追加のレベルとアクション RedirectKey の使用
次のソリューションでは、左 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)"
};
};
私も同じ問題を抱えてる。とても痛いです。
というわけで、タイトルは「修正した xkb レイアウトをすべてのアプリケーションに反映させる方法は?」です。まあ、唯一の方法は、それを正しく行わないすべてのプログラムを修正することだと思います。やってみましょう!
さて、NetBeans のそのバグを報告した後 (更新:最新バージョンを試してみたところ、今は動作します! )、すべてのアプリケーションについてこのバグを報告し続けると思いました。リストの次のアプリケーションは Speedcrunch でした .
ただし、同様のバグ レポートを探したところ、この問題が見つかりました。他の誰かが同じ問題を抱えています。すばらしい!
コメントを読むと、このバグはすべての QT アプリに存在するはずであることがわかります。ここに QT バグレポートがあります。解決されていませんが、Qt5 で問題が解決されたようです .
ただし、コメントを見ると、回避策があります。これがどのように機能するかです。これを行っていた場合:
key <SPCE> { [ ISO_Level3_Shift ] };
次に、これを次のように変更できます:
key <SPCE> {
type[Group1]="ONE_LEVEL",
symbols[Group1] = [ ISO_Level3_Shift ]
};
そして、それは実際にいくつかのアプリケーションの問題を解決します!たとえば、スピードクランチ 今私のために働く!やった!
まとめ
現在、どのアプリケーションも正しく動作するはずです。そうでない場合は、 type[Group1]="ONE_LEVEL"
を使用する必要があります .すでにお持ちの場合は、ソフトウェアを更新する必要があります。それでも機能しない場合は、アプリ固有のものであり、バグ レポートを送信する必要があります。
更新 (2017 年 9 月 23 日)
今日現在、すべてのアプリケーションが私のキーボード レイアウトを尊重しています。 1 つを除いてすべて。
真剣に、Chromium でのキーボード処理はゴミです .これにはいくつかの問題があります:
- Shift 選択はカスタム矢印キーでは機能しません (ただし、矢印キー自体は正常に機能します)
- 複数のレイアウトがあり、レイアウトの 1 つに特別なキー (矢印、Backspace など) がある場合、別のレイアウトでは、このキーは最初のレイアウトのキーに固定されます。たとえば、2 つのレイアウトがある場合:
foo
,bar
そしていくつかのキーはfoo
で Backspace を行います 、その後bar
でバックスペースとして機能し続けます たとえそこで再定義されたとしても。
何年もの間、クロムを使わないことでこれらの問題を無視してきました。ただし、最近では、残念ながら Chromium 上に構築されている Electron を使用する傾向があります。
これを解決する正しい方法は、Chromium でバグ レポートを送信し、最善を尽くすことです。数人のユーザーにしか影響を与えていない問題を解決するのにどれくらいの時間がかかるかわかりませんが、それが唯一の解決策のようです。これに関する問題は、クロムが実際に neo(de)
で正常に動作することです レイアウト。 Neo レイアウトにはレベル 5 の矢印キーがありますが、カスタム レイアウトでは機能しません。
未解決のバグ レポート:
- プルマ – https://github.com/mate-desktop/pluma/issues/17