far2l icon indicating copy to clipboard operation
far2l copied to clipboard

Alt+Fx keyboard shortcuts in virtual terminal

Open qrp73 opened this issue 10 months ago • 13 comments

When far2l is launched from a virtual terminal, the Alt+Fx key combinations (e.g., Alt+F2) don't work—they are intercepted by the Linux kernel and result in the duplication of the Alt+Ctrl+Fx combination. I can't seem to solve this issue and can't find information on how to disable the kernel's handling of Alt+Fx combinations so that they are processed by the terminal application. Can anyone suggest a solution to this problem?

Also, I've noticed that SDL2 applications launched in a virtual terminal in KMSDRM mode handle Alt+Fx key combinations without allowing the kernel to intercept them. Is it possible to add support for Alt+Fx key combinations in the application running on a virtual terminal by default?

Когда far2l запускается из виртуального терминала, комбинации Alt+Fx (например, Alt+F2) не работают — они перехватываются ядром Linux и приводят к дублированию комбинации Alt+Ctrl+Fx. Мне не удается решить эту проблему — не могу найти информацию о том, как отключить обработку комбинаций Alt+Fx системой, чтобы они обрабатывались терминальным приложением. Кто-то может подсказать решение этой проблемы?

Также я заметил, что SDL2-приложения, запущенные в виртуальном терминале в режиме KMSDRM, спокойно обрабатывают комбинации Alt+Fx, не позволяя ядру их перехватывать. Возможно, есть способ добавить поддержку комбинаций клавиш Alt+Fx в приложение работающее в виртуальном терминале по умолчанию?

qrp73 avatar Mar 15 '25 07:03 qrp73

Кто-то может подсказать решение этой проблемы?

Использовать sticky keys.

Липкие управляющие кнопки если ваше окружение не дает вам использовать некоторые кнопкосочетания из-за ограничений TTY режима или если кнопкосочетание занято внешней программой то вы можете использовать липкие управляющие кнопки. Это означает кнопка, которая виртуально остается нажатой до нажатия следующей не-управляющей (цифро-символьной) кнопки: Ctrl+SPACE дает липкий CONTROL Alt+SPACE дает липкий ALT правый_Ctrl+SPACE дает липкий правый CONTROL правый_Alt+SPACE дает липкий правый ALT Другим способом получить работоспособные горячие кнопки может быть перенастройка общесистемных хоткеев в оболочках или во внешних программах (с целью освободить нужные сочетания) или же использование опции эксклюзивной обработки нажатий в параметрах ввода (только в GUI режиме).

spnethw avatar Mar 15 '25 12:03 spnethw

вопрос именно в том - как освободить комбинации Alt+Fx, чтобы они не перехватывались ядром Linux. По умолчанию они просто дублируют комбинацию Alt+Сtrl+Fx, что лишено смысла - зачем столько дублей для одного действия. А учитывая что Alt+Fx довольно частая комбинация в far2l, невозможность использовать её при запуске из виртуального терминала создает немалый дискомфорт.

Но способа как отключить обработку Alt+Fx системой я в открытом доступе не нашел. Гугл ничего не находит по этой теме. Есть много обсуждений как отключить/настроить комбинации для X11 или Wayland, но это и так понятно. А вот как это сделать для виртуального терминала Linux?

qrp73 avatar Mar 16 '25 05:03 qrp73

Спросил хорошую нейроночку. Звучит правдоподобно. Попробуйте:

Переключение виртуальных консолей (tty) с помощью Alt+F1...F12 обрабатывается непосредственно ядром Linux через настройки карты клавиатуры для консоли. Это не зависит от вашей графической среды (Cinnamon) или X11/Wayland.

Чтобы отключить Alt+F2 для переключения на tty2 и освободить эту комбинацию для вашего консольного приложения, вам нужно изменить системную карту клавиатуры, используемую в виртуальных консолях.

Вот шаги, как это сделать:

1. Определите используемую карту клавиатуры (Keymap)

Карта клавиатуры обычно соответствует вашей раскладке. Чтобы увидеть текущую конфигурацию, вы можете проверить файл /etc/vconsole.conf (если он существует) или настройки в /etc/default/keyboard.

2. Найдите файл карты клавиатуры

Стандартные карты клавиатуры находятся в каталоге /usr/share/keymaps/ (или иногда /lib/kbd/keymaps/). Они часто организованы по архитектуре (i386), типу (qwerty, dvorak и т.д.) и языку (us, ru, de и т.д.).

Например, для стандартной американской раскладки файл может быть /usr/share/keymaps/i386/qwerty/us.kmap.gz. Для русской /usr/share/keymaps/i386/qwerty/ru.kmap.gz. Вам нужно найти тот, который используется вашей системой. Если вы не уверены, us.kmap.gz - часто является основой или используется по умолчанию.

3. Создайте копию и измените карту клавиатуры

  • Важно: Не редактируйте системный файл напрямую, так как он может быть перезаписан при обновлении системы. Лучше создать копию и указать системе использовать её.

    # Перейдите в каталог с картами (путь может отличаться!)
    cd /usr/share/keymaps/i386/qwerty/
    
    # Скопируйте вашу текущую карту под новым именем, например mycustom.kmap.gz
    # Замените us.kmap.gz на ваш актуальный файл, если он другой (e.g., ru.kmap.gz)
    sudo cp us.kmap.gz mycustom.kmap.gz
    
    # Распакуйте для редактирования
    sudo gunzip mycustom.kmap.gz
    
    # Откройте файл в текстовом редакторе (используйте nano, vim, или другой)
    sudo nano mycustom.kmap
    
  • Внутри файла найдите строку, которая определяет действие для Alt+F2. Она будет выглядеть примерно так (keycode 60 обычно соответствует F2):

    alt keycode  60 = Console_2
    

    Или может быть что-то вроде:

    alt shift keycode  60 = Console_14
    
  • Чтобы отключить переключение по Alt+F2, измените Console_2 на VoidSymbol. VoidSymbol означает "ничего не делать".

    alt keycode  60 = VoidSymbol
    

    Убедитесь, что вы редактируете строку именно для alt keycode 60, а не для других модификаторов (например, shift alt).

  • Сохраните файл (в nano это Ctrl+O, Enter, Ctrl+X).

  • Сожмите файл обратно (не обязательно, но соответствует формату других файлов):

    sudo gzip mycustom.kmap
    

    Теперь у вас есть файл mycustom.kmap.gz.

4. Укажите системе использовать вашу кастомную карту

  • Способ 1: Через /etc/vconsole.conf (предпочтительно для systemd-систем) Отредактируйте или создайте файл /etc/vconsole.conf:

    sudo nano /etc/vconsole.conf
    

    Добавьте или измените строку KEYMAP, указав имя вашего файла без пути и без расширения .gz:

    KEYMAP=mycustom
    

    Сохраните файл.

  • Способ 2: Через /etc/default/keyboard (Более традиционный для Debian/Ubuntu) Отредактируйте файл /etc/default/keyboard:

    sudo nano /etc/default/keyboard
    

    Найдите строку, начинающуюся с KMAP=. Если её нет, добавьте. Укажите полный путь к вашему файлу без расширения .gz:

    KMAP=/usr/share/keymaps/i386/qwerty/mycustom.kmap
    

    Сохраните файл.

5. Примените изменения

Чтобы изменения вступили в силу немедленно (без перезагрузки), вы можете попробовать выполнить команду loadkeys или setupcon.

  • Тестирование (временно): Вы можете временно загрузить вашу карту, чтобы проверить, работает ли она, прямо из виртуальной консоли (Ctrl+Alt+F1...F6):

    sudo loadkeys /usr/share/keymaps/i386/qwerty/mycustom.kmap.gz
    

    Теперь попробуйте нажать Alt+F2. Консоль не должна переключиться, и комбинация должна быть доступна вашему приложению. Alt+F1, Alt+F3 и т.д. должны работать как обычно. Это изменение будет действовать только до перезагрузки или до следующего вызова loadkeys / setupcon.

  • Применение постоянных настроек: После редактирования /etc/vconsole.conf или /etc/default/keyboard, изменения должны примениться при следующей перезагрузке. Чтобы попытаться применить их без перезагрузки, можно использовать:

    sudo setupcon
    

    Или перезапустить сервис, отвечающий за консоль (на systemd системах):

    sudo systemctl restart systemd-vconsole-setup.service
    

    Возможно, самый надежный способ проверить постоянные изменения - это перезагрузка.

Важные замечания:

  • Резервные копии: Всегда создавайте резервные копии файлов перед их изменением.
  • Обновления: Системные обновления могут потенциально перезаписать стандартные файлы карт клавиатуры. Используя кастомное имя файла (mycustom.kmap.gz) и указав его в конфигурации, вы минимизируете риск того, что ваши изменения будут затерты. Однако, если обновится сам механизм загрузки карт, могут потребоваться корректировки.
  • dumpkeys: Чтобы увидеть, как текущая карта клавиатуры определяет Alt+F2, вы можете переключиться в виртуальную консоль (Ctrl+Alt+F3) и выполнить:
    sudo dumpkeys | grep "keycode 60"
    
    Это покажет все назначения для клавиши F2 (keycode 60) с разными модификаторами.

Теперь, после выполнения этих шагов и перезагрузки (или успешного применения через setupcon/systemctl), комбинация Alt+F2 в виртуальных консолях ядра не должна переключать tty и будет доступна для использования в ваших консольных приложениях.

unxed avatar Apr 02 '25 09:04 unxed

настройки в /etc/default/keyboard

вот его содержимое:

# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="us,ru"
XKBVARIANT=""
XKBOPTIONS="grp:alt_shift_toggle"

BACKSPACE="guess"

Стандартные карты клавиатуры находятся в каталоге /usr/share/keymaps/ (или иногда /lib/kbd/keymaps/). Они часто организованы по архитектуре (i386), типу (qwerty, dvorak и т.д.) и языку (us, ru, de и т.д.).

таких папок нет... sudo find / -name "us.kmap.*" ничего не находит...

qrp73 avatar Apr 03 '25 01:04 qrp73

А какая операционка?

unxed avatar Apr 03 '25 06:04 unxed

Debian Bookworm (Raspberry Pi OS) aarch64

$ uname -a
Linux raspi 6.12.20+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.20-1+rpt1~bpo12+1 (2025-03-19) aarch64 GNU/Linux

qrp73 avatar Apr 03 '25 07:04 qrp73

Попробуйте вот по этой инструкции:

  1. /etc/default/keyboard: Как вы и заметили, этот файл в вашей конфигурации содержит только параметры XKB.... Они относятся исключительно к настройке клавиатуры в графической среде (X11/Wayland), а не к виртуальным консолям ядра. Поэтому добавление KMAP= сюда не сработает так, как ожидалось в более старых системах.
  2. Отсутствие /usr/share/keymaps: На некоторых современных системах, особенно минималистичных или специфичных сборках (как для RPi), стандартный пакет kbd, который предоставляет эти файлы карт клавиатуры (*.kmap.gz) и утилиту loadkeys, может не быть установлен по умолчанию. Вместо него для базовой настройки консоли может использоваться systemd-vconsole-setup совместно с пакетом console-setup. Однако, для кастомизации часто все равно требуется пакет kbd.
  3. aarch64: Архитектура не должна принципиально менять механизм, но пути к файлам иногда могут немного отличаться.

Что делать:

Шаг 1: Установить пакет kbd

Это наиболее вероятная причина отсутствия файлов .kmap.gz. Пакет kbd содержит утилиты (loadkeys, dumpkeys) и сами файлы карт клавиатуры.

sudo apt update
sudo apt install kbd

Шаг 2: Проверить наличие файлов карт клавиатуры снова

После установки kbd стандартные каталоги должны появиться. Проверьте:

ls /usr/share/keymaps/
ls /lib/kbd/keymaps/ # Менее вероятно, но проверьте
# Или более конкретный поиск для aarch64 (хотя i386 часто используется как общий каталог)
sudo find /usr/share/keymaps/ /lib/kbd/keymaps/ -name "us.kmap.gz"

Скорее всего, вы найдете что-то вроде /usr/share/keymaps/i386/qwerty/us.kmap.gz. Даже на aarch64 часто используются карты из подкаталога i386, так как формат карт не зависит от архитектуры CPU.

Шаг 3: Определить используемую консольную карту

Теперь, когда kbd установлен, система, вероятно, настроена через /etc/vconsole.conf. Проверьте его содержимое:

cat /etc/vconsole.conf

Ищите строку KEYMAP=. Например:

KEYMAP=us

Если файла нет или строка KEYMAP отсутствует, система использует встроенное значение по умолчанию (обычно основанное на us) или значение, определенное console-setup во время установки. Для нашей цели будем модифицировать карту us.

Шаг 4: Создать и изменить кастомную карту

Теперь, когда вы знаете, где лежат карты (предположим, /usr/share/keymaps/i386/qwerty/), выполните шаги из предыдущего ответа, но с поправкой на реальный путь:

  1. Перейдите в каталог:
    # Замените путь на тот, что вы нашли на Шаге 2
    cd /usr/share/keymaps/i386/qwerty/
    
  2. Скопируйте: Создадим копию с понятным именем. Лучше поместить её туда же, чтобы система её нашла по имени.
    sudo cp us.kmap.gz mycustom.kmap.gz
    
  3. Распакуйте:
    sudo gunzip mycustom.kmap.gz
    
  4. Отредактируйте:
    sudo nano mycustom.kmap
    
    Найдите строку (используйте поиск Ctrl+W в nano): alt keycode 60 Измените строку alt keycode 60 = Console_2 на: alt keycode 60 = VoidSymbol Сохраните (Ctrl+O, Enter) и выйдите (Ctrl+X).
  5. Сожмите обратно:
    sudo gzip mycustom.kmap
    

Шаг 5: Указать системе использовать кастомную карту

Используем /etc/vconsole.conf, так как это стандарт для systemd-based систем вроде Debian Bookworm:

sudo nano /etc/vconsole.conf

Добавьте или измените строку KEYMAP, указав имя вашего файла без пути и расширения:

KEYMAP=mycustom

Если там были другие параметры (например, FONT), оставьте их. Сохраните и выйдите.

Шаг 6: Применить изменения

  • Временно (для теста в текущей сессии TTY): Переключитесь в любую виртуальную консоль (например, Ctrl+Alt+F3), залогиньтесь и выполните:

    # Укажите полный путь к вашему сжатому файлу
    sudo loadkeys /usr/share/keymaps/i386/qwerty/mycustom.kmap.gz
    

    Попробуйте нажать Alt+F2. Переключения быть не должно.

  • Постоянно: Чтобы изменения из /etc/vconsole.conf применились при загрузке и, возможно, немедленно, выполните:

    sudo setupcon
    

    Или перезапустите соответствующий сервис:

    sudo systemctl restart systemd-vconsole-setup.service
    

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

Теперь комбинация Alt+F2 должна быть свободна для использования в ваших консольных приложениях при работе в виртуальных консолях (tty1-tty6).

unxed avatar Apr 03 '25 09:04 unxed

Если что, такие инструкции можно добывать здесь: https://aistudio.google.com/prompts/new_chat

Сетку выбрать Gemini 2.5 Pro

А то у меня-то самого Распбиана нету

unxed avatar Apr 03 '25 11:04 unxed

  1. /etc/default/keyboard: Как вы и заметили, этот файл в вашей конфигурации содержит только параметры XKB.... Они относятся исключительно к настройке клавиатуры в графической среде (X11/Wayland), а не к виртуальным консолям ядра. Поэтому добавление KMAP= сюда не сработает так, как ожидалось в более старых системах.

Нет, этот файл никак не влияет на x11/Wayland. Он влияет только на виртуальный терминал от ядра Linux. Настройка сочетания клавиш для переключения раскладки клавитауры и настройка раскладки в этом файле влияет только на виртуальный терминал (который включается по Alt+Ctrl+F1,Alt+Ctrl+F2,...).

Настройки клавиатуры для десктопа находятся в разных файлах:

  • для скрина логином: /usr/share/greeter.ini
  • для Wayland Wayfire: ~/.config/wayfire.ini
  • для Wayland Labwc: ~/.config/labwc/environment Для X11 не знаю - не пользуюсь.

qrp73 avatar Apr 04 '25 02:04 qrp73

Шаг 1: Установить пакет kbd

Это наиболее вероятная причина отсутствия файлов .kmap.gz. Пакет kbd содержит утилиты (loadkeys, dumpkeys) и сами файлы карт клавиатуры.

sudo apt update sudo apt install kbd

Шаг 2: Проверить наличие файлов карт клавиатуры снова

этот пакет изначально установлен, но файлов карт клавиатуры нет:

$ apt-cache policy kbd
kbd:
  Installed: 2.5.1-1+b1
  Candidate: 2.5.1-1+b1
  Version table:
 *** 2.5.1-1+b1 500
        500 https://deb.debian.org/debian bookworm/main arm64 Packages
        100 /var/lib/dpkg/status

Я спрашивал у Raspberry Pi как отключить Alt+Fx в виртуальном терминале, но они сказали что это поведение задается ядром и они в этом плане ничего не кастомизировали. Единственное что сказали, что

Ctrl-Alt-Fn or Alt-Fn are Linux defaults for these things, this isn't a bug...

dumpkeys from the console will show you what is mapped there

однако dumpkeys выдает пол мегабайта текста с множеством разных ключей. Что это все значит и как отключить Alt+Fx из этого не понятно... :(

Вот как выглядит содержимое которое выдает эта команда (первые строки из 500 кБ текста):

dumpkeys output on Linux Raspi OS
keymaps 0-127
keycode   1 = Escape          
	alt	keycode   1 = Meta_Escape     
	shift	alt	keycode   1 = Meta_Escape     
	altgr	alt	keycode   1 = Meta_Escape     
	shift	altgr	alt	keycode   1 = Meta_Escape     
	control	alt	keycode   1 = Meta_Escape     
	shift	control	alt	keycode   1 = Meta_Escape     
	altgr	control	alt	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	keycode   1 = Meta_Escape     
	alt	shiftl	keycode   1 = Meta_Escape     
	shift	alt	shiftl	keycode   1 = Meta_Escape     
	altgr	alt	shiftl	keycode   1 = Meta_Escape     
	shift	altgr	alt	shiftl	keycode   1 = Meta_Escape     
	control	alt	shiftl	keycode   1 = Meta_Escape     
	shift	control	alt	shiftl	keycode   1 = Meta_Escape     
	altgr	control	alt	shiftl	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	shiftl	keycode   1 = Meta_Escape     
	alt	shiftr	keycode   1 = Meta_Escape     
	shift	alt	shiftr	keycode   1 = Meta_Escape     
	altgr	alt	shiftr	keycode   1 = Meta_Escape     
	shift	altgr	alt	shiftr	keycode   1 = Meta_Escape     
	control	alt	shiftr	keycode   1 = Meta_Escape     
	shift	control	alt	shiftr	keycode   1 = Meta_Escape     
	altgr	control	alt	shiftr	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	shiftr	keycode   1 = Meta_Escape     
	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	shift	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	altgr	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	shift	altgr	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	control	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	shift	control	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	altgr	control	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	shiftl	shiftr	keycode   1 = Meta_Escape     
	alt	ctrll	keycode   1 = Meta_Escape     
	shift	alt	ctrll	keycode   1 = Meta_Escape     
	altgr	alt	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	alt	ctrll	keycode   1 = Meta_Escape     
	control	alt	ctrll	keycode   1 = Meta_Escape     
	shift	control	alt	ctrll	keycode   1 = Meta_Escape     
	altgr	control	alt	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	ctrll	keycode   1 = Meta_Escape     
	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	shift	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	altgr	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	control	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	shift	control	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	altgr	control	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	shiftl	ctrll	keycode   1 = Meta_Escape     
	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	altgr	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	control	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	control	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	altgr	control	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	shiftr	ctrll	keycode   1 = Meta_Escape     
	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	altgr	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	control	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	control	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	altgr	control	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
	shift	altgr	control	alt	shiftl	shiftr	ctrll	keycode   1 = Meta_Escape     
keycode   2 = one             
	shift	keycode   2 = exclam          
	shift	altgr	keycode   2 = exclam          
	shift	control	keycode   2 = exclam          
	shift	altgr	control	keycode   2 = exclam          
	alt	keycode   2 = Meta_one        
	shift	alt	keycode   2 = Meta_exclam     
	altgr	alt	keycode   2 = Meta_one        
	shift	altgr	alt	keycode   2 = Meta_exclam     
	control	alt	keycode   2 = Meta_one        
	shift	control	alt	keycode   2 = Meta_exclam     
	altgr	control	alt	keycode   2 = Meta_one        
	shift	altgr	control	alt	keycode   2 = Meta_exclam     
	shift	shiftl	keycode   2 = exclam          
	shift	altgr	shiftl	keycode   2 = exclam          
	shift	control	shiftl	keycode   2 = exclam          
	shift	altgr	control	shiftl	keycode   2 = exclam          
	alt	shiftl	keycode   2 = Meta_one        
	shift	alt	shiftl	keycode   2 = Meta_exclam     
	altgr	alt	shiftl	keycode   2 = Meta_one        
	shift	altgr	alt	shiftl	keycode   2 = Meta_exclam     
	control	alt	shiftl	keycode   2 = Meta_one        
	shift	control	alt	shiftl	keycode   2 = Meta_exclam     
	altgr	control	alt	shiftl	keycode   2 = Meta_one        
	shift	altgr	control	alt	shiftl	keycode   2 = Meta_exclam     
	shift	shiftr	keycode   2 = exclam          
	shift	altgr	shiftr	keycode   2 = exclam          
	shift	control	shiftr	keycode   2 = exclam          
	shift	altgr	control	shiftr	keycode   2 = exclam          
	alt	shiftr	keycode   2 = Meta_one        
	shift	alt	shiftr	keycode   2 = Meta_exclam     
	altgr	alt	shiftr	keycode   2 = Meta_one        
	shift	altgr	alt	shiftr	keycode   2 = Meta_exclam     
	control	alt	shiftr	keycode   2 = Meta_one        
	shift	control	alt	shiftr	keycode   2 = Meta_exclam     
	altgr	control	alt	shiftr	keycode   2 = Meta_one        
	shift	altgr	control	alt	shiftr	keycode   2 = Meta_exclam     
	shift	shiftl	shiftr	keycode   2 = exclam          
	shift	altgr	shiftl	shiftr	keycode   2 = exclam          
	shift	control	shiftl	shiftr	keycode   2 = exclam          
	shift	altgr	control	shiftl	shiftr	keycode   2 = exclam          
	alt	shiftl	shiftr	keycode   2 = Meta_one        
	shift	alt	shiftl	shiftr	keycode   2 = Meta_exclam     
	altgr	alt	shiftl	shiftr	keycode   2 = Meta_one        
	shift	altgr	alt	shiftl	shiftr	keycode   2 = Meta_exclam     
	control	alt	shiftl	shiftr	keycode   2 = Meta_one        
	shift	control	alt	shiftl	shiftr	keycode   2 = Meta_exclam     
	altgr	control	alt	shiftl	shiftr	keycode   2 = Meta_one        
	shift	altgr	control	alt	shiftl	shiftr	keycode   2 = Meta_exclam     
	shift	ctrll	keycode   2 = exclam          
	shift	altgr	ctrll	keycode   2 = exclam          
	shift	control	ctrll	keycode   2 = exclam          
	shift	altgr	control	ctrll	keycode   2 = exclam          
	alt	ctrll	keycode   2 = Meta_one        
	shift	alt	ctrll	keycode   2 = Meta_exclam     
	altgr	alt	ctrll	keycode   2 = Meta_one        
	shift	altgr	alt	ctrll	keycode   2 = Meta_exclam     
	control	alt	ctrll	keycode   2 = Meta_one        
	shift	control	alt	ctrll	keycode   2 = Meta_exclam     
	altgr	control	alt	ctrll	keycode   2 = Meta_one        
	shift	altgr	control	alt	ctrll	keycode   2 = Meta_exclam     
	shift	shiftl	ctrll	keycode   2 = exclam          
	shift	altgr	shiftl	ctrll	keycode   2 = exclam          
	shift	control	shiftl	ctrll	keycode   2 = exclam          
	shift	altgr	control	shiftl	ctrll	keycode   2 = exclam          
	alt	shiftl	ctrll	keycode   2 = Meta_one        
	shift	alt	shiftl	ctrll	keycode   2 = Meta_exclam     
	altgr	alt	shiftl	ctrll	keycode   2 = Meta_one        
	shift	altgr	alt	shiftl	ctrll	keycode   2 = Meta_exclam     
	control	alt	shiftl	ctrll	keycode   2 = Meta_one        
	shift	control	alt	shiftl	ctrll	keycode   2 = Meta_exclam     
	altgr	control	alt	shiftl	ctrll	keycode   2 = Meta_one        
	shift	altgr	control	alt	shiftl	ctrll	keycode   2 = Meta_exclam     
	shift	shiftr	ctrll	keycode   2 = exclam          
	shift	altgr	shiftr	ctrll	keycode   2 = exclam          
	shift	control	shiftr	ctrll	keycode   2 = exclam          
	shift	altgr	control	shiftr	ctrll	keycode   2 = exclam          
	alt	shiftr	ctrll	keycode   2 = Meta_one        
	shift	alt	shiftr	ctrll	keycode   2 = Meta_exclam     
	altgr	alt	shiftr	ctrll	keycode   2 = Meta_one        
	shift	altgr	alt	shiftr	ctrll	keycode   2 = Meta_exclam     
	control	alt	shiftr	ctrll	keycode   2 = Meta_one        
	shift	control	alt	shiftr	ctrll	keycode   2 = Meta_exclam     
	altgr	control	alt	shiftr	ctrll	keycode   2 = Meta_one        
	shift	altgr	control	alt	shiftr	ctrll	keycode   2 = Meta_exclam     
	shift	shiftl	shiftr	ctrll	keycode   2 = exclam          
	shift	altgr	shiftl	shiftr	ctrll	keycode   2 = exclam          
	shift	control	shiftl	shiftr	ctrll	keycode   2 = exclam          
	shift	altgr	control	shiftl	shiftr	ctrll	keycode   2 = exclam          
	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_one        
	shift	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_exclam     
	altgr	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_one        
	shift	altgr	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_exclam     
	control	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_one        
	shift	control	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_exclam     
	altgr	control	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_one        
	shift	altgr	control	alt	shiftl	shiftr	ctrll	keycode   2 = Meta_exclam     
keycode   3 = two             
	shift	keycode   3 = at              
	shift	altgr	keycode   3 = at              
	control	keycode   3 = nul             
	shift	control	keycode   3 = nul             
	altgr	control	keycode   3 = nul             
	shift	altgr	control	keycode   3 = nul             
	alt	keycode   3 = Meta_two        
	shift	alt	keycode   3 = Meta_at         
	altgr	alt	keycode   3 = Meta_two        
....

В Linux Arch x64 на ПК аналогичное поведение - тоже срабатывают Alt+Fx, правда dumpkeys выдает более скромные 30 кБ более читаемого текста, хотя что с этим делать всеравно непонятно. :

dumpkeys output from Linux Arch
keymaps 0-2,4-6,8-9,12
keycode   1 = Escape
        alt     keycode   1 = Meta_Escape
        shift   alt     keycode   1 = Meta_Escape
        control alt     keycode   1 = Meta_Escape
keycode   2 = one              exclam
        alt     keycode   2 = Meta_one
        shift   alt     keycode   2 = Meta_exclam
keycode   3 = two              at               at
        control keycode   3 = nul
        shift   control keycode   3 = nul
        alt     keycode   3 = Meta_two
        shift   alt     keycode   3 = Meta_at
        control alt     keycode   3 = Meta_nul
keycode   4 = three            numbersign
        control keycode   4 = Escape
        alt     keycode   4 = Meta_three
        shift   alt     keycode   4 = Meta_numbersign
keycode   5 = four             dollar           dollar
        control keycode   5 = Control_backslash
        alt     keycode   5 = Meta_four

Гугл об этом ничего не находит, в основном интернет заполнен разными способами изменить раскладку и шорткаты для десктопа X11 или Wayland композиторов. Но для виртуального терминала все эти описания не подходят, т.к. в нем своя обработака клавиш, судя из того что пишут - на уровне ядра Linux. Но как её настраивать информации нет.

Ясно только как задать раскладки и комбинацию клавш для переключения в /etc/default/keyboard. Это работает - с такими настройками в этом файле я могу переключать раскладки us/ru в виртуальном терминале:

# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="us,ru"
XKBVARIANT=""
XKBOPTIONS="grp:alt_shift_toggle"

BACKSPACE="guess"

Отображение шрифтов в виртуальном терминале можно настроить через sudo dpkg-reconfigure console-setup, я выбрал:

UTF-8
Combined - Latin; Slavic Cyrillic; Hebrew; basic Arabic
VGA
8x16

и это работает - русский и английский текст видно. Можно переключать раскладки.

А вот как убрать шорткат Alt+Fx информации не нашел.

Однако есть интересный нюанс - когда я использую библиотеку SDL2 для обработки клавиш в своем приложении на виртуальном терминале, она спокойно обрабатывает комбинации Alt+Fx и ядро почему-то не перехватывает эти комбинации пока работает моё приложение. Возможно есть способ обрабатывать эти клавшиы из приложения без настройки шорткатов в ядре? Или SDL2 как-то по хитрому свой драйвер устанавливает чтобы обрабатывать эти кнопки?

Может можно и в far2l сделать, чтобы клавиши Alt+Fx обаратывались приложением, а не ядром? Если сделать SDL2 бекэнд к far2l, то это решило бы проблему, заодно можно было-бы выбирать с каким драйвером запускать far2l - x11, wayland, kmsdrm или другим поддерживаемым SDL2. Насколько это возможно?

qrp73 avatar Apr 04 '25 02:04 qrp73

Библиотеки вроде SDL2 (а также ncurses в определенном режиме, или приложения, использующие прямой доступ к фреймбуферу/DRM/KMS) действительно могут перехватывать события клавиатуры на виртуальной консоли до того, как их обработает стандартный механизм переключения консолей ядра.

Почему это происходит и как SDL2 это делает (упрощенно):

  1. Стандартный режим консоли (K_XLATE): По умолчанию виртуальная консоль Linux работает в режиме трансляции (XLATE). В этом режиме драйвер клавиатуры ядра читает скан-коды с физической клавиатуры, применяет к ним текущую карту клавиатуры (keymap, которую мы пытались редактировать), генерирует символы или выполняет специальные действия (как Console_2 для Alt+F2), и передает результат (например, символы) в буфер tty, откуда их читают обычные консольные приложения (вроде bash). Переключение консолей происходит именно на этом этапе обработки ядром.

  2. Режим RAW или MEDIUMRAW: Приложения, которым нужен более низкоуровневый доступ к вводу (игры, мультимедиа-приложения, некоторые TUI-библиотеки), могут переключить режим клавиатуры для текущей виртуальной консоли в RAW или MEDIUMRAW с помощью системного вызова ioctl с командой KDSKBMODE на файловый дескриптор консоли (например, /dev/tty1).

    • K_RAW: В этом режиме ядро практически не обрабатывает нажатия, а передает необработанные скан-коды (или близкие к ним коды событий) напрямую приложению. Приложение само отвечает за интерпретацию всех нажатий, включая модификаторы (Alt, Shift, Ctrl). Так как ядро не применяет свою карту клавиатуры и не ищет действия вроде Console_2, переключения консолей не происходит.
    • K_MEDIUMRAW: Похож на RAW, но ядро все еще может обрабатывать некоторые очень низкоуровневые вещи или специальные комбинации (зависит от версии ядра и конфигурации), но обычно Alt+Fx в этом режиме также передаются приложению.
  3. Как работает SDL2: Когда вы запускаете SDL2-приложение на виртуальной консоли (часто используя бэкенды вроде KMS/DRM или Framebuffer), SDL2 при инициализации подсистемы ввода:

    • Открывает нужную консоль (/dev/ttyX).
    • Переключает режим клавиатуры этой консоли в RAW или MEDIUMRAW с помощью ioctl(fd, KDSKBMODE, K_RAW).
    • Начинает читать низкоуровневые события клавиатуры напрямую (либо с tty, либо часто через /dev/input/event*, что еще надежнее обходит обработку tty).
    • Самостоятельно интерпретирует эти события, определяя, что нажаты Alt и F2, и передает это вашему коду приложения как событие SDL_KEYDOWN с соответствующими полями keysym.
    • Важно: Когда ваше SDL2-приложение корректно завершает работу, SDL2 должна восстановить предыдущий режим клавиатуры консоли (обычно K_XLATE) с помощью того же ioctl. Если приложение "упадет", консоль может остаться в режиме RAW, и тогда обычный ввод (например, в bash после выхода из игры) работать не будет до перезагрузки или ручного сброса режима.

Вывод:

Да, возможно обрабатывать Alt+Fx из приложения без настройки шорткатов в ядре, если ваше приложение (или используемая им библиотека, как SDL2) переключает виртуальную консоль в режим RAW или MEDIUMRAW. SDL2 не устанавливает свой "драйвер" в классическом смысле, а использует стандартные механизмы ядра Linux (ioctl на tty) для временного изменения режима обработки ввода для той консоли, где оно запущено.

Поэтому вам не нужно модифицировать системную карту клавиатуры (keymap), если ваша цель — использовать Alt+F2 только внутри вашего SDL2-приложения, работающего на виртуальной консоли. SDL2 уже позаботится об этом за вас, временно отключая стандартную обработку Alt+Fx ядром на время своей работы. Модификация keymap нужна, если вы хотите освободить Alt+F2 для любых консольных приложений (не только SDL2) или если вы хотите, чтобы эта комбинация никогда не переключала консоль.

unxed avatar Apr 04 '25 07:04 unxed

@anta999 ты думал в сторону ещё одного графического бекенда, но я не помню, SDL мы обсуждали, или другой какой-то фреймворк. Будто бы SDL

unxed avatar Apr 04 '25 07:04 unxed

@elfmz а мы можем в консоли ядра переключаться в RAW или MEDIUMRAW режимы автоматически? Чтоб Alt+Fx обрабатывать самостоятельно

unxed avatar Apr 04 '25 07:04 unxed