web-dev-qa-db-ja.com

すべてのアプリケーションに変更した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      ] };
}

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

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

編集:

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

なぜ彼らは働いていないのですか

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

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

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

    • keysymは(/usr/include/X11/keysymdef.hによると)次の整数です

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

      印刷可能な各文字には、plusaACyrillic_aなどの独自のキーシムがありますが、Shift_LLeftなどの他のキーもキーシムを生成します。またはF1

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

    Control_Lのようなキーシムを単独で追跡するアプリケーションもあれば、状態の修飾子ビットを探すだけのアプリケーションもあります。

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

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

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

  • あなたは解放します j。アプリケーションは、同じパラメーターを使用して、キー<AC07>/LeftのKeyReleaseイベントを取得します。

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

これは、xevユーティリティを実行した場合に確認できます。

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

それらを機能させる方法

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

1.別のグループ

私の頭に浮かぶ唯一の方法は、カーソル移動キーを別のグループに定義し、別のキーを押すことで、キーを押す前にそのグループに切り替えることです。 j、 k、 l、 ihtnc)(私が理解しているように、グループラッチは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のキーシム(ISO_Group_Shift/ISO_Group_Latch /定義されているものは何でも)を開示します(ただし、修飾子の状態はクリーンなままです)。

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

2.オーバーレイ

より「低レベル」のソリューションは、overlayです(同じ article で説明されています)。

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-左/右によるデスクトップスイッチ)に遭遇しました。あなたの質問とこの答え、今私はオーバーレイが何であるかを知っています:))

16
Chel

私も同じ問題を抱えてる。とても痛いです。

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

さて、 NetBeansUpdate:最新バージョンを試しましたが、今は動作します!)でそのバグを報告した後、私は、すべてのアプリケーションについてこのバグを報告し続けると思いました。リストの次のアプリケーションは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でのキーボード処理はごみです。それにはいくつかの問題があります:

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

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

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

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

それらを機能させる方法-ソリューション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)" 
    };
};
4
mgl