Иногда баг выглядит настолько нелепо, что проще сначала обвинить клавиатуру.
В моём случае перестали работать Ctrl+Shift+C и Ctrl+Shift+V в терминале Ptyxis, когда была включена русская раскладка.
Переключаешься на английскую — всё нормально.
Переключаешься обратно на русский — копирование и вставка через привычные сочетания перестают работать.
В итоге я полез смотреть, что там происходит внутри.
Проблема оказалась не в клавиатуре
Ptyxis — терминал для GNOME, и обработка клавиатурных сочетаний здесь идёт через GTK.
В обработчике ptyxis_terminal_capture_key_pressed_cb() клавиша из события сравнивалась с клавишей, указанной в shortcut.
На первый взгляд всё логично.
Но есть нюанс: сравнивался keyval.
А keyval зависит от текущей раскладки.
Например, физическая клавиша C:
Английская раскладка → c
Русская раскладка → с
Физически нажата та же клавиша.
Но для программы это уже два разных значения.
Получалось примерно следующее:
shortcut: c
на английской:
event = c
c == c → OK
на русской:
event = с
c == с → FAIL
Именно поэтому Ctrl+Shift+C внезапно переставал работать.
Как я это исправил
Я решил не пытаться перечислять все возможные раскладки и не добавлять в код русские буквы.
Вместо этого нужно было сравнивать физическую клавишу, а не символ, который эта клавиша породила после обработки раскладки.
Для этого я перевёл проверку на keycode.
Логика теперь выглядит так:
shortcut
↓
gtk_accelerator_parse()
↓
keyval + modifiers
↓
gdk_display_map_keyval()
↓
физический keycode
↓
сравнение с keycode события
Дополнительно учитываются модификаторы и те из них, которые GTK считает потреблёнными через gdk_key_event_get_consumed_modifiers().
В результате раскладка больше не имеет значения.
Нажата физическая клавиша C — значит это C, независимо от того, какая буква сейчас на ней находится.
Почему я не сделал простой костыль
Самый очевидный вариант — добавить поддержку русских символов непосредственно в условие.
Например:
c → c / с
v → v / м
Но это решало бы только конкретный случай.
Затем появился бы пользователь с другой раскладкой, и пришлось бы добавлять ещё варианты.
Проблема находилась уровнем ниже.
Если сочетание должно быть привязано к физической клавише, то и проверять нужно физическую клавишу.
Поэтому исправление получилось универсальнее.
Что именно изменилось
Я добавил функцию:
ptyxis_terminal_keycode_matches_accel()
Она занимается сопоставлением shortcut с физическим keycode.
А ptyxis_terminal_capture_key_pressed_cb() теперь использует эту проверку.
Исправление затрагивает терминальные действия:
copy-clipboardpaste-clipboard
При этом shortcuts не захардкожены.
Ptyxis продолжает брать их из настроек, поэтому пользовательские комбинации остаются рабочими.
Основные изменения находятся в:
src/ptyxis-terminal.c
Исходный проект основан на Ptyxis 50.1.
А потом я собрал готовый пакет
Можно, конечно, скачать исходники, установить зависимости, настроить Meson и собрать всё самостоятельно.
Но для обычного пользователя это уже лишняя работа.
Поэтому я собрал готовый .deb.
В релизе:
ptyxis_50.1-1ubuntu2local1_amd64.deb
Это локальная сборка Ptyxis 50.1 для Ubuntu 26.04 с исправлением Ctrl+Shift+C/V для нелатинских раскладок.
Скачать готовый .deb из релиза
Установить его можно обычной командой:
sudo apt install ./ptyxis_50.1-1ubuntu2local1_amd64.deb
После установки это всё тот же Ptyxis, только с исправленным поведением клавиатурных сочетаний.
Если хочется собрать самому
Для тех, кто предпочитает собрать программу из исходников:
meson setup _build --prefix=/usr/local --buildtype=release
meson compile -C _build
sudo meson install -C _build
Само исправление также полностью доступно в репозитории.
Что в итоге
Получился довольно показательный баг.
Пользователь нажимает одну и ту же физическую клавишу, а программа получает разные значения в зависимости от раскладки.
И проблема оказывается не в Ctrl, не в Shift и даже не в самом Ptyxis как терминале.
Проблема в том, что именно программа считает клавишей.
В моём случае достаточно было заменить сравнение символа на сравнение физического keycode.
Теперь можно сидеть на русской раскладке и спокойно нажимать:
Ctrl+Shift+C
Ctrl+Shift+V
без постоянного переключения языка.
А заодно получился небольшой патч, готовый .deb и повод немного покопаться внутри GTK вместо очередного переключения раскладки перед копированием.