모든 응용 프로그램이 수정 된 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를 사용하지 않습니다. 굉장한 WM.

편집하다:

  • 다음 은 완전하지만 단순화 된 키보드 레이아웃 파일입니다. 나는 이것을 가지고 /usr/share/X11/xkb/symbols/nonpop있고 그것을로드합니다 setxkbmap nonpop.
  • MonoDevelop에서 작품을 움직이며 선택하는 것은 아닙니다. 즉, Shift + Right를 누르면 텍스트가 평소와 같이 선택되지만 AltGr + Shift + n을 누르면 커서가 선택되지 않고 움직입니다. 예를 들어 Firefox에서는 두 가지 방법을 모두 사용하여 선택할 수 있습니다.
  • 여기에 결국 그들에 대해 이야기 오버레이 아마도 해결책이 될 수 있지만, 내가 그들을 사용하는 방법을 생각하지 않은 일처럼 보인다.

1
해결책이 없지만 바운티에도 불구하고 답변을 얻지 못하면 더 유닉스 / 리눅스 중심의 Stackexchange 사이트 인 unix.SE에 문의하십시오.
Glutanimate

답변:


16

그들은 왜 작동하지 않는가

당신이 언급 한 ArchWiki의 기사 에 따르면 :

  • X 서버는 입력 장치에서 키 코드 를 가져 와서 상태keysym으로 변환합니다 .

    • state 는 X 수정 자의 비트 마스크입니다 (Ctrl / Shift / etc).

    • keysym 은 (에 따라 /usr/include/X11/keysymdef.h)

      키보드 레이아웃의 각 키와 관련된 문자 또는 기능을 식별합니다 (예 : 보이는 조각을 통해).

      각 인쇄 가능한 문자는 자신의 keysym에이 같은이 plus, a, A, 또는 Cyrillic_a, 그러나 다른 키도 같은, 자신의 keysyms을 생성 Shift_L, Left또는 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 (Modifier Mod5가 켜져 있음)과 함께 KeyPressed 이벤트를받습니다 .

  • 당신은 해제 j합니다. 응용 프로그램은 키 KeyRelease 이벤트를 가져옵니다 <AC07>/ Left같은 매개 변수.

  • 그런 다음 AltGrAltGr에 대한 KeyRelease 이벤트를 해제하십시오 . (여기서 상태는 여전히 0x80이지만 중요하지 않습니다.)

xev유틸리티 를 실행하면 볼 수 있습니다 .

따라서 애플리케이션이 Left일반 키 와 동일한 키심 코드 ( )를 <LEFT>가져 오더라도 AltGr에서 키심 코드와 수정 자 상태도 가져옵니다. 대부분 작동하지 않는 프로그램은 수정자를보고 일부 활성 상태 일 때는 작동하지 않는 프로그램 일 것입니다.

작동시키는 방법

분명히 수정자를 찾지 않도록 모든 프로그램을 변경할 수는 없습니다. 그런 다음이 상황을 피할 수있는 유일한 옵션은 수정 자의 키심 및 상태 비트를 생성하지 않는 것입니다.

1. 별도 그룹

내 마음에 오는 유일한 방법은 다음과 같습니다 키를 누르면 이전에 해당 그룹에 별도의 키 누름으로, 별도의 그룹과 스위치에 커서 이동 키를 정의 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)" };
};

이제 먼저 AltGr이동 키 중 하나를 눌렀다가 (별도로) 누르면 이것이 작동합니다.

그러나 이것은 매우 유용하지 않으므로 LockGroup 그룹 전환 전후에 래치 대신 AltGr을 누르는 것이 더 적절 합니다. 더 나은에있을 수 있습니다 SetGroup다음 AltGr 키 만 누르면되는 동안 해당 그룹을 선택,하지만 그 응용 프로그램 AltGr 키의 keysym에 (에 호 - ISO_Group_Shift/ ISO_Group_Latch/ 정의 된대로) (깨끗하지만 수정 상태 체류).

그러나 ... 응용 프로그램이 키 코드 (실제 키의 코드)도 읽을 가능성이 있습니다. 그러면 "가짜"커서 키가 나타납니다.

2. 오버레이

보다 "낮은 수준의"솔루션은 동일한 기사에서 설명 하는 것처럼 오버레이가 됩니다 .

오버레이는 단순히 일부 실제 키보드 키가 다른 키의 키 코드를 반환한다는 의미입니다. X 서버는 키의 키 코드를 변경하고 새 키 코드의 수정 자 상태와 키 심을 계산하므로 응용 프로그램은 변경 사항을 인식하지 않아야합니다.

그러나 오버레이는 매우 제한적입니다.

  • X 서버에는 2 개의 오버레이 제어 비트 만 있습니다 (즉, 최대 2 개의 오버레이가있을 수 있음).
  • 각 키는 하나의 대체 키 코드 만 가질 수 있습니다.

나머지 부분은 구현이 별도의 그룹을 가진 메소드와 매우 유사합니다.

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을 사용하고 일부 이동 키 심을 높은 수준의 알파벳 키로 다시 매핑했으며 일부 기능이 손상되었습니다 (Ctrl-Alt-Left / Right로 Xfce 노트 및 데스크탑 스위치에서 선택). 귀하의 질문 과이 답변, 이제 ​​오버레이가 무엇인지 알고 있습니다 :).)


감사! 실제로 unix.se에 대한 또 다른 대답을 얻었 습니다. 처음에는 완벽 해 보였지만 여전히 일부 응용 프로그램이 잘못 작동하는 것으로 나타났습니다. 이 경우에도이 솔루션 (오버레이)이 작동합니다.
nonpop

Google 크롬 [e | ium]도 이것에 관심이 없다는 것을 알았습니다. :( 다행히도 나는 그다지 많이 사용하지 않습니다.
nonpop

@nonpop 빌어 먹을 크롬 ... 내 응답에 업데이트를 추가 한 superuser.com/a/1000320/521612
하기 Aleks 다니엘 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)

현재 모든 응용 프로그램은 키보드 레이아웃을 존중합니다. 하나만 빼고

심각하게 Chromium에서 키보드를 처리하는 것은 쓰레기 입니다. 그것에 몇 가지 문제가 있습니다 :

  • Shift 선택은 사용자 정의 화살표 키를 사용하지 않습니다 (그러나 화살표 키 자체는 정상적으로 작동 함)
  • 여러 레이아웃이 있고 레이아웃 중 하나에 일부 키가 특수한 경우 (예 : 화살표, 백 스페이스 등) 다른 레이아웃에서는이 키가 첫 번째 레이아웃에있는 모든 항목으로 고정됩니다. 예를 들어, 두 개의 레이아웃이있는 경우 : foo, bar어떤 키에 백 스페이스를 수행 foo한 후가에서 백 스페이스로 계속 작동, bar거기 재정의되는 경우에도 마찬가지입니다.

몇 년 동안 나는 단순히 크롬을 사용하지 않음으로써 이러한 문제를 무시했습니다. 그러나 요즘에는 Chromium에 구축 된 Electron 을 사용하는 경향이 있습니다 .

이를 해결하는 올바른 방법은 Chromium에 버그 보고서를 제출하고 최선을 다하는 것입니다. 몇 명의 사용자에게만 영향을 미치는 문제를 해결하는 데 시간이 얼마나 걸리는지는 모르겠지만 그 방법이 유일한 방법 인 것 같습니다. 이것의 문제는 크롬이 실제로 neo(de)레이아웃에서 잘 작동한다는 것 입니다. Neo 레이아웃에는 레벨 5에 화살표 키가 있지만 사용자 정의 레이아웃에서는 작동하지 않습니다.

여전히 열려있는 버그 보고서 :


정보에 대해서 감사드립니다! 해결 방법은 나에게 도움이되지 않으므로 버그를보고하고 qt5 변환을 기다려야한다고 생각합니다.
nonpop

4

작동시키는 방법-솔루션 3

추가 레벨 및 조치 RedirectKey 사용

다음 솔루션은 왼쪽 Alt 키를 사용하여 jkli의 커서 키, uopö의 Home / End / PageUp / PageDown 및 백 스페이스의 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 정의가 무엇인지 설명 할 수 있습니까? 그것들은 미리 정의되어 있으므로 임의로 이름을 지정할 수 없습니다.
Aleks-Daniel Jakimenko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.