Làm cách nào để làm cho tất cả các ứng dụng tôn trọng bố cục xkb đã sửa đổi của tôi?


15

Tôi không thích nhảy giữa bàn phím chính và các phím di chuyển, vì vậy tôi đã thêm phần sau vào tệp bố cục xkb của mình.

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      ] };
}

Sau đó, tôi đưa những thứ này vào bố cục tại một điểm sau trong tệp. Bây giờ tôi nên có các phím con trỏ có thể truy cập thông qua AltGr + j, k, l, i (hoặc h, t, n, c như tôi đang sử dụng dvorak), v.v. Điều này hoạt động trong nhiều trường hợp (như Firefox, urxvt, Eclipse, vùng văn bản chính của LyX) nhưng một số chương trình không làm gì khi tôi cố gắng di chuyển con trỏ bằng các "phím tắt" này (như hộp thoại NetBeans và LyX).

Vì vậy, có cách nào để làm cho các chương trình khác cũng tôn trọng mong muốn của tôi? Và tại sao họ không làm việc ở nơi đầu tiên? Tôi không sử dụng DE; chỉ có WM tuyệt vời.

Biên tập:

  • Dưới đây là một tập tin bố trí bàn phím đầy đủ nhưng đơn giản. Tôi có cái này /usr/share/X11/xkb/symbols/nonpopvà tôi tải nó với setxkbmap nonpop.
  • Tôi nhận thấy rằng trong MonoDevelop di chuyển xung quanh các công trình nhưng việc chọn không. Nghĩa là, nếu tôi nhấn Shift + Right thì văn bản được chọn như bình thường, nhưng nếu tôi nhấn AltGr + Shift + n thì con trỏ chỉ di chuyển mà không chọn. Ví dụ trong Firefox cả hai cách đều có thể được sử dụng để chọn.
  • Dưới đây cuối cùng họ nói về lớp phủ trông giống như một cái gì đó mà có lẽ có thể là một giải pháp nhưng tôi đã không tìm ra cách để sử dụng chúng.

1
Tôi không có giải pháp, nhưng nếu bạn không có câu trả lời mặc dù tiền thưởng bạn đưa ra, bạn có thể thử hỏi tại unix.SE , một trang web Stackexchange tập trung vào Unix / Linux.
Glutimate

Câu trả lời:


16

Tại sao họ không làm việc

Theo bài viết của ArchWiki mà bạn đã đề cập:

  • Máy chủ X nhận mã khóa từ thiết bị đầu vào và chuyển đổi chúng sang trạng tháikeyym .

    • trạng thái là bitmask của bộ sửa đổi X (Ctrl / Shift / etc).

    • keyym là (theo /usr/include/X11/keysymdef.h) số nguyên mà

      xác định các ký tự hoặc chức năng được liên kết với mỗi phím (ví dụ: thông qua khắc có thể nhìn thấy) của bố cục bàn phím.

      Mỗi nhân vật có thể in được có keysym riêng của mình, giống như plus, a, A, hay Cyrillic_a, nhưng các phím khác cũng tạo keysyms của họ, giống như Shift_L, Lefthoặc F1.

  • Ứng dụng trong các sự kiện nhấn / phát hành chính có được tất cả các thông tin này.

    Một số ứng dụng theo dõi các từ khóa giống như Control_Lchính chúng, một số khác chỉ tìm kiếm các bit sửa đổi trong trạng thái .

Vì vậy, những gì xảy ra, khi bạn nhấn AltGr+ j:

  • Bạn nhấn AltGr. Ứng dụng nhận sự kiện KeyPress với mã khóa 108 ( <RALT>) và keyym 0xfe03 ( ISO_Level3_Shift), trạng thái là 0.

  • Bạn nhấn j(bản đồ tới tầm hiên trong dvorak mà không cần sửa đổi). Ứng dụng nhận sự kiện KeyPress với mã khóa 44 ( <AC07>), keyym 0xff51 ( Left) và trạng thái 0x80 (Mod5 Mod5 được bật).

  • Bạn phát hành j. Ứng dụng nhận sự kiện KeyRelease cho khóa <AC07>/ Leftvới cùng tham số.

  • Sau đó phát hành AltGr- sự kiện KeyRelease cho AltGr. (Nhân tiện, trạng thái ở đây vẫn là 0x80, nhưng điều đó không thành vấn đề.)

Điều này có thể được nhìn thấy nếu bạn chạy xevtiện ích.

Vì vậy, tất cả có nghĩa là, mặc dù ứng dụng có cùng mã keyym ( Left) như từ khóa thông thường <LEFT>, nhưng nó cũng nhận được mã keyym và trạng thái sửa đổi từ AltGr. Rất có thể, những chương trình không hoạt động, xem các công cụ sửa đổi và không muốn hoạt động khi một số hoạt động.

Làm thế nào để làm cho chúng hoạt động

Rõ ràng, chúng ta không thể thay đổi mọi chương trình để không tìm kiếm sửa đổi. Sau đó, tùy chọn duy nhất để thoát khỏi tình huống này là không tạo ra các từ khóa và bit trạng thái của bộ sửa đổi.

1. Nhóm riêng

Phương pháp duy nhất mà nói đến cái tâm của tôi là: xác định các phím di chuyển con trỏ vào một nhóm riêng biệt và chuyển đổi, với một phím bấm riêng biệt, cho nhóm đó trước khi nhấn các phím j, k, l, i( h, t, n, c) (nhóm chốt là phương pháp ưa thích cho một lần thay đổi nhóm, như tôi hiểu).

Ví dụ:

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)" };
};

Bây giờ, nếu bạn lần đầu tiên nhấn AltGrvà sau đó (riêng biệt) một trong các phím di chuyển, điều này sẽ hoạt động.

Tuy nhiên, điều này không hữu ích lắm, thích hợp hơn là LockGroup thay vì chốt và nhấn AltGr trước và sau khi chuyển nhóm. Thậm chí tốt hơn có thể là SetGroup- sau đó AltGr sẽ chỉ chọn nhóm đó trong khi được nhấn, nhưng điều đó tiết lộ cho các ứng dụng Các phím của AltGr ( ISO_Group_Shift/ ISO_Group_Latch/ bất cứ điều gì được xác định) (nhưng trạng thái sửa đổi vẫn sạch).

Nhưng ... cũng có một khả năng còn lại là ứng dụng cũng đọc mã khóa (mã của các khóa thực). Sau đó, nó sẽ nhận thấy các phím con trỏ giả mạo của người Viking.

2. Lớp phủ

Giải pháp nhiều cấp độ thấp hơn nữa sẽ là lớp phủ (như cùng một bài viết mô tả).

Lớp phủ đơn giản có nghĩa là một số phím (bàn phím thực) trả về mã khóa của một phím khác. Máy chủ X thay đổi mã khóa của khóa và tính toán trạng thái sửa đổi và mã khóa cho mã khóa mới đó, vì vậy ứng dụng không nên chú ý thay đổi.

Nhưng lớp phủ rất hạn chế:

  • Chỉ có 2 bit điều khiển lớp phủ trong máy chủ X (nghĩa là có thể có tối đa 2 lớp phủ).
  • Mỗi khóa chỉ có thể có 1 mã khóa thay thế.

Đối với phần còn lại, việc thực hiện khá giống với phương pháp với một nhóm riêng:

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)" };
};

SetControlscó nghĩa là thay đổi bit điều khiển trong khi phím được nhấn và khôi phục nó trên bản phát hành khóa. Có chức năng tương tự LatchControls, nhưng xkbcompcung cấp cho tôi

Error:            Unknown action LatchControls

về biên dịch keymap.

(Nhân tiện, tôi cũng sử dụng dvorak và cũng đã ánh xạ lại một số từ khóa chuyển động sang mức cao của các phím chữ cái. câu hỏi của bạn và câu trả lời này, bây giờ tôi biết lớp phủ là gì :).)


Cảm ơn! Tôi thực sự đã có một câu trả lời khác trên unix.se lúc đầu có vẻ hoàn hảo nhưng hóa ra một số ứng dụng vẫn hoạt động sai. Giải pháp này (lớp phủ) cũng hoạt động trong những trường hợp đó.
nonpop

Tôi chỉ nhận thấy rằng google chrom [e | ium] cũng không quan tâm đến điều này! :( May mắn thay tôi không sử dụng chúng nhiều.
nonpop

@nonpop goddamn chromium Tìm Tôi đã thêm một bản cập nhật cho siêu người dùng
tôi.com / 1/1320320/521612

Kinh ngạc! Tôi đã tìm kiếm điều này trong nhiều năm! Vẫn còn một vấn đề nhỏ với Chromium khi nó diễn giải một phím nhấn Overlay1_Enable. Tôi có cùng một triệu chứng như ở đây: github.com/GalliumOS/galliumos-distro/issues/362
Tarrasch

1
Tôi chỉ cố gắng khắc phục vấn đề trên. Các phím mũi tên hàng nhà của tôi giờ cũng hoạt động trong Chromium! Tôi cần sự thay đổi sau đây cho câu trả lời này. gist.github.com/Tarrasch/1293692/ từ
Tarrasch

4

Tôi có cùng một vấn đề. Thật là đau đớn.

Vậy tiêu đề là thế nào để làm cho tất cả các ứng dụng tôn trọng bố cục xkb đã sửa đổi của tôi? Chà, tôi nghĩ cách duy nhất là sửa tất cả các chương trình làm sai. Hãy làm điều đó!

Chà, sau khi báo cáo lỗi đó trong NetBeans ( Cập nhật: Tôi đã thử phiên bản mới nhất và nó hoạt động ngay bây giờ! ), Tôi nghĩ rằng tôi sẽ tiếp tục báo cáo lỗi này cho mọi ứng dụng. Ứng dụng tiếp theo trong danh sách là Speedcrunch .

Tuy nhiên, sau khi tìm kiếm các báo cáo lỗi tương tự, tôi thấy vấn đề này . Một người khác đang có cùng một vấn đề, tuyệt vời!

Sau khi đọc các bình luận, bạn sẽ hiểu rằng lỗi này sẽ xuất hiện trong tất cả các ứng dụng QT. Đây là một báo cáo lỗi QT . Không được giải quyết, nhưng có vẻ như vấn đề được giải quyết trong Qt5 .

Tuy nhiên, nếu bạn nhìn vào các bình luận, có một cách giải quyết! Đây là cách nó làm việc. Nếu bạn đang làm điều này:

key <SPCE> { [ ISO_Level3_Shift ] };

Sau đó, bạn có thể thay đổi nó thành này:

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

Và nó thực sự sẽ giải quyết vấn đề cho một số ứng dụng! Ví dụ, Speedcrunch hiện hoạt động với tôi! Yay!

Tóm lược

Ngay bây giờ bất kỳ ứng dụng nên hoạt động chính xác. Nếu không, thì bạn phải sử dụng type[Group1]="ONE_LEVEL". Nếu bạn đã có nó, thì bạn phải cập nhật phần mềm của bạn. Nếu nó vẫn không hoạt động, thì nó là ứng dụng cụ thể và bạn phải gửi báo cáo lỗi.

CẬP NHẬT (2017-09-23)

Cho đến hôm nay, tất cả các ứng dụng đều tôn trọng bố cục bàn phím của tôi. Tất cả ngoại trừ một.

Nghiêm túc, xử lý bàn phím trong Chromium là rác . Có một số vấn đề với nó:

  • Lựa chọn thay đổi không có các phím mũi tên tùy chỉnh (nhưng bản thân các phím mũi tên hoạt động tốt)
  • Nếu bạn có nhiều bố cục và trên một trong các bố cục, một số phím là đặc biệt (ví dụ: mũi tên, Backspace, v.v.), thì trên bố cục khác, phím này sẽ được gắn vào bất cứ thứ gì bạn có trên bố cục đầu tiên. Ví dụ, nếu bạn có hai bố trí: foo, barvà một số phím nào làm Backspace trong foo, sau đó nó sẽ tiếp tục làm việc như Backspace trong barngay cả khi nó được định nghĩa lại ở đó.

Trong nhiều năm, tôi đã bỏ qua những vấn đề này bằng cách đơn giản là không sử dụng crom. Tuy nhiên, ngày nay mọi thứ có xu hướng sử dụng Electron , không may được xây dựng trên Chromium.

Cách đúng để giải quyết vấn đề này là gửi báo cáo lỗi trong Chromium và hy vọng điều tốt nhất. Tôi không biết họ sẽ mất bao lâu để giải quyết vấn đề chỉ ảnh hưởng đến một vài người dùng, nhưng đó dường như là lối thoát duy nhất. Vấn đề với điều này là crom thực sự hoạt động tốt với neo(de)bố cục. Bố cục Neo có các phím mũi tên ở cấp 5, nhưng tôi không thể làm cho nó hoạt động trong bố cục tùy chỉnh của mình.

Báo cáo lỗi vẫn mở:


Cảm ơn bạn về thông tin! Cách giải quyết không giúp được tôi nên tôi đoán tôi sẽ phải báo cáo lỗi và chờ chuyển đổi qt5.
nonpop

4

Cách làm cho chúng hoạt động - Giải pháp 3

Sử dụng các cấp bổ sung và RedirectKey hành động

Giải pháp sau sử dụng phím Alt bên trái để cung cấp các phím con trỏ trên jkli, Home / End / PageUp / PageDown trên uopö và Xóa trên Backspace.

Phím Alt bên trái vẫn có thể sử dụng cho các mục đích khác cho tất cả các phím khác (như cho menu ứng dụng). Alt trái (Mod1) bị xóa khỏi trạng thái sửa đổi khi khối con trỏ được sử dụng để các ứng dụng không thể nhìn thấy nó.

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)" 
    };
};

Thánh moly! Điều đó thực sự hoạt động! Nó hoạt động xung quanh các ứng dụng bị hỏng như Chromium. Bạn có thể giải thích những định nghĩa osf là gì? Có vẻ như chúng được xác định trước nên bạn không thể đặt tên chúng ngẫu nhiên.
Aleks-Daniel Jakimenko
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.