Как я могу заставить мои клавиши стрелок ISO_Level5_Shift работать в Java Swing GUI?

У меня есть раскладка клавиатуры, которая использует ISO_Level5_Shift предоставить клавиши со стрелками. Из моего файла символов макета:

key <AC06> { type[Group1]="EIGHT_LEVEL", [ d, D, ampersand,  U2227, Home,  Home,  Greek_delta,   Greek_DELTA   ]};
key <AC07> { type[Group1]="EIGHT_LEVEL", [ h, H, parenright, U27E9, Left,  Left,  Greek_eta,     Greek_ETA,  U210F  ]};
key <AC08> { type[Group1]="EIGHT_LEVEL", [ t, T, parenleft,  U27E8, Down,  Down,  Greek_tau,     Greek_TAU     ]};
key <AC09> { type[Group1]="EIGHT_LEVEL", [ n, N, slash,      U2115, Right, Right, Greek_nu,      Greek_NU      ]};
key <AC10> { type[Group1]="EIGHT_LEVEL", [ s, S, underscore, U2237, End,   End,   Greek_sigma,   Greek_SIGMA   ]};

Они работают в большинстве программ (Firefox, Eclipse, Vim, ...). К сожалению, они не работают в любом Java Swing GUI, который я когда-либо использовал. В частности, они не работают в IntelliJ IDEA, и именно это меня особенно беспокоило.

Есть ли что-то, что я мог бы изменить в своем макете, или переменные среды, связанные с Java, или конфигурацию IDEA, которые могли бы решить эту проблему?

4 ответа

Решение

ОК, я нашел решение. Это не совсем идеально, но оно получает желаемое поведение.

Во-первых, я сбросил полное состояние конфигурации клавиатуры, используя

$ xkbcomp $DISPLAY - > now.xkb

Тогда я нашел строки

interpret Overlay1_Enable+AnyOfOrNone(all) {
    action= LockControls(controls=Overlay1);
};

и изменил его на

interpret Overlay1_Enable+AnyOfOrNone(all) {
    action= SetControls(controls=Overlay1);
};

который предотвращает "залипание" модификатора, т.е. он применяется только тогда, когда вы удерживаете клавишу нажатой.

Затем я взял ключ, который раньше был моим ISO_Level5_Shift:

key  <TAB> {
    type= "ONE_LEVEL",
    symbols[Group1]= [ ISO_Level5_Shift ]
};

и изменил его на Overlay1_Enable:

key  <TAB> {
    type= "ONE_LEVEL",
    symbols[Group1]= [ Overlay1_Enable ]
};

Затем для каждого ключа, где я хотел, чтобы изменение вступило в силу, я добавил определение наложения:

key <AD07> {
    type= "EIGHT_LEVEL",
    overlay1= <PGUP>,
    symbols[Group1]= [               g,               G,        asterisk,               G,           Prior,               G,     Greek_gamma,     Greek_GAMMA ]
};

Затем повторно применил все это с

$ xkbcomp now.xkb $DISPLAY

Полезная документация:

У меня также были проблемы с этим, вот мое решение, использующее ключ caps lock в качестве переключателя оверлея, чтобы включить навигацию, подобную emacs/vim, надеюсь, это поможет всем, кто хочет сделать что-то подобное.

// Emacs like keys with CAPS as overlay switch.

// Using ISO_Level3_Shift or ISO_Level5_Shift would also make
// most applications work and would have been more flexible,
// however they don't work in Java Swing apps (e.g. IntelliJ IDEA)
// but using overlay works

// To enable, save this file as /usr/share/X11/xkb/symbols/emacs and run:
//
//   setxkbmap -option '' "emacs"
//
// However it may not persist and can get reset back to the default by other things.
// Alternatively, insert the following into /usr/share/X11/xkb/rules/evdev.xml
// ...
// <layoutList>
//   ...
//   <layout>
//     <configItem>
//       <name>emacs</name>
//       <shortDescription>en</shortDescription>
//       <description>English (US, Emacs)</description>
//       <languageList>
//         <iso639Id>eng</iso639Id>
//       </languageList>
//     </configItem>
//   </layout>
//   ...
// </layoutList>
// ...
// Then you should be able to choose 'English (US, Emacs)' in a keyboard preference
// GUI such as fcitx and have it persist.

default partial alphanumeric_keys
xkb_symbols "basic" {

    // Base keyboard functionality, using 'us' here
    // See definitions in /usr/share/X11/xkb/symbols
    // e.g. 'include "us(intl)"' where 'intl' is defined inside the 'us' file
    include "us"

    // Press Shift_L + Shift_R together as an alternative way to toggle Caps_Lock,
    // then turn CAPS key to enable overlay1 mode when and only when holding down.
    include "shift(both_capslock)"
    key <CAPS> {actions[Group1]=[SetControls(controls=overlay1)]};

    // Emacs like navigation keys when holding down <CAPS>
    // e.g. caps + n to go down
    key <AB05> {overlay1=<LEFT>}; // b
    key <AC04> {overlay1=<RGHT>}; // f
    key <AD10> {overlay1=<UP>  }; // p
    key <AB06> {overlay1=<DOWN>}; // n
    key <AC01> {overlay1=<HOME>}; // a
    key <AD03> {overlay1=<END> }; // e
    key <AC05> {overlay1=<ESC> }; // g

    // Emacs like editing keys when holding down <CAPS>
    // Redo/Undo only work with applications that understand the them
    key <AB10> {overlay1=<UNDO>}; // /
    key <UNDO> {[Undo, Redo]};    // Shift + / -> Redo
    key <AC03> {overlay1=<DELE>}; // d

    // VIM like navigation keys when holding down <CAPS>
    key <AC06> {overlay1=<LEFT>}; // h
    key <AC09> {overlay1=<RGHT>}; // l
    key <AC08> {overlay1=<UP>  }; // k
    key <AC07> {overlay1=<DOWN>}; // j

};

В частности, они не работают в IntelliJ IDEA, и именно это меня особенно беспокоило.

Существует обходной путь - сопоставить нужные ключи на стороне IntelliJ IDEA.

  1. Перейдите в Настройки ⇒ Keymap.
  2. Найдите клавишу, которая не работает, когда нажата комбинация клавиш "iso level shift" (скажем, клавиша "Вверх").
  3. Выберите "Добавить сочетание клавиш".
  4. Нажмите комбинацию клавиш "iso level shift", которая не работает как клавиша "вверх" в IntelliJ.
  5. Применять.

Вуаля, комбинация клавиш "сдвиг уровня iso" ведет себя как клавиша "вверх" даже в IntelliJ IDEA.

Я нашел другое решение, которое требует немного больше работы, но в конечном итоге работает более надежно в большем количестве различного программного обеспечения.

Основная идея состоит в том, чтобы пропустить XKB и напрямую подключиться к механизму обработки событий ядра .

Как только вы это сделаете, вы сможете точно контролировать, какие коды клавиш видит все программное обеспечение.

В итоге я создал универсальный инструмент переназначения ключей для достижения этой цели.

Другие вопросы по тегам