すべてのアプリケーションが変更されたxkbレイアウトを尊重するようにするにはどうすればよいですか?


15

メインキーボードと移動キーの間をジャンプするのは好きではないので、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      ] };
}

次に、これらをファイルの後半のレイアウトに含めます。これで、AltGr + j、k、l、i(またはdvorakを使用しているためh、t、n、c)などからカーソルキーにアクセスできるようになります。これは多くの場合(Firefox、urxvt、Eclipse、 (LyXのメインテキストエリア)が、これらの「ショートカット」(NetBeansやLyXダイアログなど)を使用してカーソルを移動しようとすると、一部のプログラムは何もしません。

だから、これらの他のプログラムにも私の希望を尊重させる方法はありますか?そして、なぜ彼らはそもそも働いていないのですか?私はDEを使用していません。Awesome WMのみ。

編集:

  • 以下は、完全だが単純化されたキーボードレイアウトファイルです。私はこれを持っている/usr/share/X11/xkb/symbols/nonpopと私はそれをロードしsetxkbmap nonpopます。
  • MonoDevelopでは動き回っていますが、選択しても動きません。つまり、Shift + Rightを押すと通常どおりテキストが選択されますが、AltGr + Shift + nを押すとカーソルは選択せずに移動します。たとえば、Firefoxでは、選択に両方の方法を使用できます。
  • ここで最後に彼らは、おそらく解決策になるかもしれない何かのように見えるオーバーレイについて話しますが、私はそれらを使用する方法を理解していません。

1
私には解決策はありませんが、あなたが我慢する報奨にもかかわらず答えを得ることができなければ、より多くのUnix / Linuxを中心としたStackexchangeサイトであるunix.SEに尋ねることができます。
グルタニメート14

回答:


16

なぜ機能していないのですか

あなたが言及したArchWikiの記事によると:

  • Xサーバーは、入力デバイスからキーコードを取得し、それらをstateおよびkeysymに変換します 。

    • stateはX修飾子(Ctrl / Shift / etc)のビットマスクです。

    • keysymは(によれば/usr/include/X11/keysymdef.h)整数

      キーボードレイアウトの各キーに関連付けられている文字または機能を識別します(たとえば、目に見える彫刻を介して)。

      各印刷可能な文字は次のように、独自のキーシンボルを持ってplusaA、または Cyrillic_a、他のキーも同様、彼らのキーシンボルを生成する Shift_LLeftまたはF1

  • 主要なプレス/リリースイベントのアプリケーションは、このすべての情報を取得します。

    一部のアプリケーションはControl_L、それ自体のようにキーシムを追跡しますが、他のアプリケーションはstateの修飾子ビットを探すだけです。

AltGr+ を押すとどうなりますかj

  • を押すAltGr。アプリケーションは、キーコード108(<RALT>)およびkeysym 0xfe03(ISO_Level3_Shift)でKeyPressedイベントを取得します。状態は0です。

  • を押しますj(修飾なしでdvorakの「h」にマッピングされます)。アプリケーションは、キーコード44(<AC07>)、keysym 0xff51(Left)、および状態0x80(修飾子Mod5がオン)でKeyPressedイベントを取得します。

  • リリースしjます。アプリケーションは、同じパラメータでキー<AC07>/のKeyReleaseイベントを取得し Leftます。

  • 次にAltGr、AltGrのKeyReleaseイベントをリリースします。(ところで、ここの状態はまだ0x80ですが、それは問題ではありません。)

これは、xevユーティリティを実行すると表示されます。

つまり、アプリケーションはLeft通常のkey と同じkeysymコード()を<LEFT>取得しますが、AltGrからkeysymコードと修飾子の状態も取得します。ほとんどの場合、機能しないプログラムは修飾子を監視し、一部がアクティブなときに機能したくないと考えています。

それらを機能させる方法

どうやら、修飾子を検索しないようにすべてのプログラムを変更することはできません。この状況を回避する唯一のオプションは、修飾子のキーシムと状態ビットを生成しないことです。

1.別のグループ

私の心に来る唯一の方法は次のとおりです。キーを押す前に、そのグループに、別のキーを押すと、別のグループとスイッチでカーソル移動キーを定義しjklihtnc)(グループはラッチ好ましい方法であります私が理解するように、一度のグループ変更のために)。

例えば:

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のキーシム(ISO_Group_Shift/ ISO_Group_Latch/ whateverが定義されている)を公​​開します(ただし、修飾子の状態はクリーンなままです)。

しかし...アプリケーションがキーコード(実際のキーのコード)も読み取る可能性もあります。次に、「偽の」カーソルキーが表示されます。

2.オーバーレイ

より「低レベル」なソリューションは、オーバーレイです(同じ記事で 説明されているように)。

オーバーレイとは、単に(実際のキーボード)キーが別のキーのキーコードを返すことを意味します。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キーが押されている間に制御ビットを変更し、キーを離したときにそれを復元することを意味します。同様の機能があるはずですLatchControlsxkbcomp、私に与えます

Error:            Unknown action LatchControls

キーマップのコンパイル。

(ところで、私はdvorakも使用し、いくつかの移動キーシムを高レベルのアルファベットキーに再マップしました。また、いくつかの壊れた機能に遭遇しました(Xfceノートでの選択とCtrl-Alt-Left / Rightによるデスクトップスイッチ)。おかげであなたの質問とこの答え、今私はオーバーレイが何であるかを知っています:)。


ありがとう!実際、unix.seで別の答えがられました。最初は完璧に思えたが、一部のアプリケーションは依然として動作に問題がありました。このソリューション(オーバーレイ)は、これらの場合にも機能します。
ノンポップ14年

google chrom [e | ium]もこれを気にしないことに気付きました!:(幸いにも私はあまり利用していない。
nonpop

@nonpop goddamn Crrom…返信にアップデートを追加しましたsuperuser.com/a/1000320/521612
Aleks-Daniel Jakimenko

すごい!私はこれを何年も探してきました!のキー入力を解釈するChromiumにはまだ小さな問題がありOverlay1_Enableます。私はここと同じ症状があります:github.com/GalliumOS/galliumos-distro/issues/362
Tarrasch

1
私は上記の問題をなんとか修正することができました。ホーム行の矢印キーがChromiumでも機能するようになりました!この答えに次の変更が必要でした。gist.github.com/Tarrasch/1293692/…–
Tarrasch

4

私は同じ問題を抱えています。とてもつらいです。

そのため、タイトルは「すべてのアプリケーションに変更されたxkbレイアウトを尊重させる方法は?」です。まあ、私は唯一の方法はそれを間違って行うすべてのプログラムを修正することだと思います。そうしよう!

さて、NetBeansでそのバグを報告した後(更新:最新バージョンを試してみましたが、動作するようになりました!)、すべてのアプリケーションについてこのバグを報告し続けると思いました。リストの次のアプリケーションはSpeedcrunchでした

ただし、同様のバグレポートを探したところ、この問題が見つかりました。他の誰かが同じ問題を抱えています、素晴らしい!

コメントを読んだ後、このバグはすべてのQTアプリに存在するはずであることを理解できます。これはQTバグレポートです。解決されていませんが、Qt5で問題が解決されたようです。

ただし、コメントを見ると、回避策があります!仕組みは次のとおりです。これを行っていた場合:

key <SPCE> { [ ISO_Level3_Shift ] };

次に、これに変更できます。

key <SPCE> {
  type[Group1]="ONE_LEVEL",
  symbols[Group1] = [ ISO_Level3_Shift ]
};

そして、実際にいくつかのアプリケーションの問題を解決します!たとえば、Speedcrunchが機能するようになりました!わーい!

概要

現時点では、どのアプリケーションも正しく動作するはずです。そうでない場合は、を使用する必要がありますtype[Group1]="ONE_LEVEL"。既にお持ちの場合は、ソフトウェアを更新する必要があります。それでも機能しない場合は、アプリ固有であり、バグレポートを提出する必要があります。

更新(2017-09-23)

現在、すべてのアプリケーションは私のキーボードレイアウトを尊重しています。1つを除くすべて。

真剣に、Chromiumのキーボード処理はゴミです。それにはいくつかの問題があります:

  • シフト選択はカスタム矢印キーを使用しません(ただし、矢印キー自体は正常に機能します)
  • 複数のレイアウトがあり、いずれかのレイアウトで特別なキー(矢印、Backspaceなど)がある場合、別のレイアウトでは、このキーは最初のレイアウトにあるものに固定されます。たとえば、2つのレイアウトを持っている場合:foobarおよびいくつかのキーがでバックスペースを行いfoo、それが中にBackspaceキーとして働き続けるだろう、barそれが再定義されている場合でも。

何年もの間、私は単にクロムを使用しないことでこれらの問題を無視していました。ただし、最近では残念ながらChromium上に構築されたElectronを使用する傾向があります。

これを解決する正しい方法は、Chromiumでバグレポートを提出し、最善を尽くすことです。数人のユーザーにしか影響を与えない問題を解決するのにどれくらいの時間がかかるかわかりませんが、それが唯一の解決策のようです。これに関する問題は、クロムがneo(de)レイアウトで実際にうまく機能することです。Neoレイアウトにはレベル5に矢印キーがありますが、カスタムレイアウトで動作させることはできません。

まだ開いているバグレポート:


情報をありがとう!回避策は役に立たないので、バグを報告し、qt5変換を待つ必要があると思います。
nonpop

4

それらを機能させる方法-解決策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)" 
    };
};

聖なるモリー!それは実際に動作します!Chromiumなどの壊れたアプリケーションを回避します。これらのOSF定義が何であるか説明できますか?それらは事前に定義されているため、ランダムに名前を付けることはできません。
アレクス・ダニエル・ジャキメンコ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.