Чому вони не працюють
Відповідно до статті Аркі Вікі, яку ви згадали:
X сервер отримує клавішні коди від пристрою введення та перетворює їх у
стан та keyym .
стан - це бітова маска модифікаторів X (Ctrl / Shift / тощо).
keyym - це (відповідно /usr/include/X11/keysymdef.h
) ціле число, яке
ідентифікуйте символи або функції, пов’язані з кожною клавішею (наприклад, через видиму гравію) макета клавіатури.
Кожен друкований символ має свій власний символ клавіші, як plus
, a
, A
або
Cyrillic_a
, але інші клавіші також генерують свої символи клавіш, як
Shift_L
, Left
або F1
.
Програма в ключових подіях преси / випуску отримує всю цю інформацію.
Деякі програми відслідковують ключові ключі, як Control_L
самі по собі, інші просто шукають біти модифікатора в стані .
Що ж станеться, натиснувши AltGr+ j:
Ви натискаєте AltGr. Програма отримує KeyPress подія з кодом 108 ( <RALT>
) та keyym 0xfe03 ( ISO_Level3_Shift
), стан 0.
Ви натискаєте j(яка відображає "h" у двораку без модифікаторів). Програма отримує подію KeyPress із кодом 44 ( <AC07>
), keyym 0xff51 ( Left
) та станом 0x80 (модифікатор Mod5 увімкнено).
Ви звільняєте j. Додаток отримує KeyRelease подія для ключа
<AC07>
/ Left
з тими ж параметрами.
Потім випуск AltGr- подія KeyRelease для AltGr. (До речі, стан тут все ще 0x80, але це не має значення.)
Це можна побачити, якщо ви запускаєте xev
утиліту.
Отже, це все означає, що, хоча програма отримує той самий keyym-код ( Left
), як і від звичайного ключа <LEFT>
, він також отримує код keyym та стан модифікатора від 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 ( ISO_Group_Shift
/ ISO_Group_Latch
/ все, що визначено) (але стан модифікатора залишається чистим).
Але ... також залишається можливість, що програма також зчитує клавіші (коди реальних ключів). Тоді він помітить «підроблені» клавіші курсору.
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
означає змінити керуючий біт під час натискання клавіші та відновити його при звільненні ключа. Має бути подібна функція LatchControls
, але
xkbcomp
дає мені
Error: Unknown action LatchControls
при складанні ключових карт
(До речі, я також користуюся двораком, а також перекомпонував деякі клавіші руху на високі рівні алфавітних клавіш. А також натрапив на деякий невдалий функціонал (вибір у примітках Xfce та комутатор на робочому столі Ctrl-Alt-Left / Right). Завдяки ваше запитання та ця відповідь, тепер я знаю, що таке накладення :).)