Решение проблемы с переключением по alt+shift в Linux, в приложениях на Electron

Здравствуйте, коллеги!

Хочу поделиться поделиться своим решением проблемы, которая указана в заголовке. Написанием статьи вдохновился от коллеги brnovk, который не поленился и предложил частичное (для меня) решение проблемы. Я сделал свой «костыль», который помог мне. Делюсь с вами.

Описание проблемы


Использовал Ubuntu 18.04 для работы и в последнее время заметил, что при переключении раскладки по alt+shift в таких приложениях, как Visual Studio Code, Skype, Slack и прочих, которые созданы с помощью Electron возникает следующая проблема: фокус с поля ввода, переходит к верхней панели окна (меню). По иным причинам переехал в Fedora + KDE и понял, что проблема никуда не делась. В поисках решения нашёл замечательную статью Чиним Skype своими руками. Огромное спасибо товарищу brnovk, что подробно рассказал о проблеме и поделился своим способом её решения. Но указанный в статье способ закрывал вопрос лишь с одним приложением, а именно Skype. Для меня ещё было критичным разобраться с Visual Studio Code, потому как писать сообщения с прыгающей менюшкой хоть и раздражает, но не так сильно если занимаешься разработкой. Плюс ко всему, коллега предложил решение, при котором меню приложения пропадает полностью, а мне бы не очень хотелось потерять меню в VS Code.

Пытался понять в чём дело


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

Я открыл Visual Studio Code и начал нажимать на разные сочетания Alt+<%что-нибудь%>, смотря на реакцию приложения. Практически во всех случаях все комбианции, кроме Alt+Shift отрабатывали без потери фокуса. Складывалось впечатление, что кто-то съедает нажатый Shift, который следовал после зажатия и удержания Alt и приложение думает что я нажал Alt, потом не нажал ничего, отпустил Alt и оно радостно бросало мой фокус в своё меню, что ему казалось вполне логичным.

Я открыл настройки переключения раскладки клавиатуры (ну знаете вот этот вот длинный список с чекбоксами и всевозможными настройками для клавиш) и установил переключение раскладки по кнопке Alt, без каких-либо дополнительных нажатий.

image

После этого перестал работать Alt+Tab для переключения окон. Работал только Tab, то есть кто-то снова «съедал» мой Alt. Кто этот «кто-то» вопросов уже не оставалось, а вот что с ним можно сделать я понятия не имею.

Но так как проблему решать было нужно хоть как-то, тогда в голову и пришло решение:

  1. В настройках отключить хоткей для переключения раскладки клавиатуры (снять все чекбоксы в разделе Switch to another layout);
  2. Создать свой хоткей, который бы переключал мне раскладку

Описание решения


Для начала установим программу, позволяющую назначать команды клавишам Xbindkeys. К сожалению, штатные средства не позволили мне через красивый интерфейс создать хоткей для сочетания типа Alt+Shift. Можно сделать для Alt+S, Alt+1, Alt+shift+Y и т.д. и т.п., но для нашей задачи это не подходит.

sudo dnf install xbindkeysrc

Более подробно про неё есть на ArchWiki
Далее создадим образец файла настроек для программы. Образец довольно короткий, с несколькими командами как раз то, что нужно чтобы разобраться как с ним работать:

xbindkeys -d > ~/.xbindkeysrc

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


# Examples of commands:
"xbindkeys_show"
  control+shift + q
# set directly keycode (here control + f with my keyboard)
"xterm"
  c:41 + m:0x4

В качестве хоткея можно использовать человекопонятное написание или использовать коды клавиш. У меня сработало только с кодами, но никто не запрещает Вам немного поэксперементировать.

Чтобы получить коды нужно использовать команду:

xbindkeys -k

Откроется маленькое «Иксовое» окно. Нажимать клавишы нужно только при фокусе на это окно! Только в этом случае Вы увидите в терминале что-то такое:


[podkmax@localhost ~]$ xbindkeys -k
Press combination of keys or/and click under the window.
You can use one of the two lines after "NoCommand"
in $HOME/.xbindkeysrc to bind a key.
"(Scheme function)"
    m:0x4 + c:39
    Control + s

В моём случае комбинация для клавиш Alt+Shift выглядит вот так:

m:0x8 + c:50

Теперь нужно сделать так, чтобы при нажатии на эту комбаницию, происходило именно переключение раскладки. Я нашёл только одну рабочую комманду для указания раскладки:


setxkbmap ru
setxkbmap us

Как видно из примера она умеет только включать ту или иную раскладку, поэтому ничего кроме написания скрипта мне в голову не пришло.


vim ~/layout.sh
#!/bin/bash
LAYOUT=$(setxkbmap -print | awk -F + '/xkb_symbols/ {print $2}')
if [ "$LAYOUT" == "ru" ]
        then `/usr/bin/setxkbmap us`
        else `/usr/bin/setxkbmap ru`
fi

Теперь если файлы .xbindkeysrc и layout.sh лежат в одной директории, то конечный вид файла .xbindkeysrc выглядит так:


# Examples of commands:

"xbindkeys_show"
  control+shift + q

# set directly keycode (here control + f with my keyboard)
"xterm"
  c:41 + m:0x4

# specify a mouse button
"xterm"
  control + b:2
#А вот то, что добавил я
"./layout.sh"
  m:0x8 + c:50


После этого применяем изменения:


xbindkeys -p

И можно проверять. Не забудьте отключить любые опции по переключению раскладки в штатных настройках.

Итог


Коллеги, надеюсь что данная статья сможет помочь быстро кому-то избавиться от назойливой проблемы. Лично я потратил весь свой выходной на то, чтобы разобраться и решить проблему хоть как-то, чтобы больше не отвлекаться на это в рабочее время. Написал данную статью с целью сэкономить кому-то время и нервы. Многие из Вас используют альтернативный способ переключения раскладки и не понимают в чем же проблема. Мне лично нравится переключаться по Alt+Shift. И я хочу чтобы работало именно так. Если Вы разделяете моё мнение и столкнулись с данной проблемой, эта статья должна Вам помочь.

Комментарии 56

    +2

    Решение проблем с переключением по Alt+Shift — переключение по Caps.


    setxkbmap -query                                                                                                                       
    rules:      evdev
    model:      pc105
    layout:     us,ru
    options:    terminate:ctrl_alt_bksp,grp:caps_toggle,grp_led:caps,grp:caps_toggle
    
      0
      В вышеприведенном скриншоте также есть возможность настроить переключение по Caps Lock. Чем, собственно, и пользуюсь
        +5

        На правах анекдота. Не пользовался капсом по исходному назначению несколько лет. В последнее время возникла потребность в редактировании bash-скриптов, CMake-конфигов и прочих Dockerfile'ов. И тут я обнаружил как удобно нажать один раз капс и спокойно вводить имена env-переменных (ну, за исключением символа '_') одной рукой, а в то же время с помощью другой продолжать жрать булочку!!

          +2

          Shift-Caps включает-выключает искомую функцию. Без отрыва от булочек.

            +1

            По моему ощущению, меньше нервов уходит, когда доешь булочку, помоешь руки и с комфортной скоростью наберёшь всё, что требуется, двумя руками.

          +2

          Эта проблема наблюдается не только на Electron-based приложениях. Этим грешит сам X11. И проблемы кратковременной потери фокуса наблюдаются не только при Alt+Shift комбинациях. При любых настройках смена раскладки клавиатуры уводит на доли секунды фокус с поля ввода. Как же меня бомбануло, когда я начал пользоваться tabsbook плагином для хранения заметок в браузере… В нем нужно вписать теги в pop-up окошке, которое… закрывается при уводе фокуса! Т.е. теги на двух языках вписать попросту нельзя.


          Эта проблема иксов висит багом уже несколько лет… Сейчас лень гуглить. Емнип, с 2008 года. И эту проблему решает (неожиданно) Wayland!

            +7

            Это не проблема X11. Это проблема Ubuntu и прочих дистрибутивов, которые перешли на переключение языка при помощи gtk-im (не помню как точно называется) — то есть на стороннее гномовское криворукоподелие. И баги соответствующие уже заведены в багтрекерах уже более 10 лет, но воз и ныне там.


            Как раз X переключает языки моментально (в gtk-im есть ощутимая задержка, при быстрой печати можно еще успеть один-два символа в старой раскладке напечатать, это тоже раздражает) и без потери фокуса.


            И решается все просто, без всяких макросов: выкидывается gtk-im и используется стандартное переключение раскладок X. Как именно это делается уже не подскажу, так как давно ушел со всяких гномообразных DE на dwm. А в X11 настройка выглядит так:


            Section "InputClass"
                            Identifier "system-keyboard"
                            MatchIsKeyboard "on"
                            Option "XkbLayout" "us,ru"
                            Option "XkbModel" "pc105"
                            Option "XkbVariant" "os_winkeys"
                            Option "XkbOptions" "grp:caps_toggle,compose:ralt"
            EndSection

            Переключение по CapsLock, Compose Key (для различных спецсимволов типа кавычек-ёлочек) на правом Alt.

                +1

                Значит я неверно понял проблему, так как каждый раз боролся с глюками и тормозами gtk-im в Ubuntu, и с каждым релизом ожидал, что они, наконец, исправят хотя бы пропажу фокуса.

                  0
                  Если пролистать обсуждение по ссылке до конца, можно наткнуться на неофициальный патч (PPA), портированный под последние убунту-образные дистрибутивы. В частности, у меня на Mint 19.2 MATE сработал отлично, проблема, поднятая в статье, решилась без сторонних утилит.
                    0
                    Я в своё время тоже находил этот патч, но у меня почему-то не сработало.
              –6
              Это называется «придумываем себе проблему, потом героически её решаем». Просто для переключения языков надо пользоваться модификаторами, которые при одиночном нажатии не меняют состояние программ. Эта комбинация выглядит так — Ctrl+Shift. Не благодарите.
                0
                А вы как думаете, почему при переходе на Windows 95 Microsoft поменяла дефолтную комбинацию на Left Alt + Shift?
                Потому что Ctrl + Shift конфликтует с выделением по словам во всех текстовых редакторах.
                  +1
                  Переключение по Ctrl+Shift в Firefox'е порождает аналогичные проблемы. Точнее — срабатывает во всплывающих окнах (Pocket, Lastpass) как Enter, очень напрягает.
                    –4
                    Нет, у меня не срабатывает, проверил.
                    Вынь10 и Ctrl+Shift переключение языков.
                      +1
                      Я под Ubuntu 19.10, а к такому сочетанию наглухо привык и не могу избавиться, т.к. с окошек полностью ушел только пару лет назад.
                        –4
                        Ну чините ваши линуксы, код открыт :)
                        Детские болезни, я смотрю, никуда не деваются уже десятки лет. Как были проблемы с обработкой нажатий клавиш в далёком 2004-ом, например, так и продолжаются до сих пор.
                          +2
                          Спасибо, и вам не скучать! ;)
                  0
                  Действительно, последние… 30 лет никогда не испытывал проблемы, описанной в статье — просто надо использовать CapsLock… и всё.
                    0

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

                    0

                    Спасибо. Я придерживаюсь вашей точки зрения — ОС для человека, а не наоборот. Мне тоже дешевле один раз перенастроить.

                      0
                      Не замечал этой проблемы, хотя и часто работаю в vscode. Проверил, баг есть, manjaro i3. Но, всё работает нормально если первым нажимать shift.
                        0

                        Потому что Alt активирует меню. Спасибо кэпу внтури меня.

                          –2
                          Альт активирует меню при нажатии? Ведь он должен делать это при отжатии.
                            0
                            Обычно пользователь ожидает событие при нажатии, а не отжатии. Приходилось писать ГУИ и учитывать именно подобное ожидние пользователя.
                              –3
                              А, так вот, кто пишет неправильные GUI!
                              Клик ведь в нормальных GUI состоит из нажатия и отжатия.
                                0
                                Обычно пользователь ожидает событие при нажатии, а не отжатии
                                Не знаю, где вы нашли пользователей, которые ожидают события по keydown.
                                Я всегда ожидаю события только по keyup, и очень удивляюсь, когда вдруг в каких-то редких программах натыкаюсь на действия, вызванные событием зажатия клавиши. Неприятно удивляюсь.
                                Исключение, конечно, составляю процессы, которые требуют удержания клавиши, начинающиеся в момент зажатия и заканчивающиеся в момент отжатия.

                                Вы пишете какое-то специфическое программное обеспечение?
                                0

                                А вот перепроверил… и вправду по отжатию.

                            0

                            У меня с последним обновление — в скайпе проблемы пропали, но появились в slack-е.

                              0

                              Кстати если нажимать сначала shift и потом alt проблемы нет

                                +1
                                Как видно из примера она умеет только включать ту или иную раскладку, поэтому ничего кроме написания скрипта мне в голову не пришло.

                                А вы попробуйте kbdd оно прицепом умеет полезную вещь: запоминать раскладку для конкретного окна.

                                • НЛО прилетело и опубликовало эту надпись здесь
                                  0

                                  Была такая проблема, перешёл на переключение раскладки по Win+Space.

                                    +1
                                    Win+space дает похожие проблемы, например в Firefox: теряется фокус в некоторых формах ввода
                                      0

                                      Коллега в своё время подсказал 2 шрифта. Полтора года пользуюсь, удобно.

                                    0
                                    В какой-то момент понял, что проще переучиться на win+space, оно вроде как стандарт теперь, работает как в винде, так и во всех ubuntu-based дистрибутивах.
                                      +1
                                      Если ничего не напутал, то это связано с багой 865. Для Arch Linux есть пакет в aur исправляющий её.
                                      Раньше пользовался ctrl+shift комбинацией для переключения раскладки, но переучил себя на win+space
                                        0
                                        Не пробовали переключаюсь по Shift+Alt? (это не сарказм, просто Alt отпускается раньше Shift).
                                        Была у меня похожая проблема в Windows, некоторые приложения по Alt «подсвечивали меню» и переключали фокус…
                                          0
                                            0
                                            Попробуйте выполнить
                                            setxkbmap -layout us -option; setxkbmap -layout «us,ru» -option grp:alt_shift_toggle

                                            Как мне кажется проблема в вашем оконном менджере или ещё какой-то программе берущей на себя переключение раскладки. Сами иксы такой проблемой вроде не страдают.
                                            Проверил у себя с vscode, переключается без проблем.

                                            P.S. Сам переключаю раскладку по правой клавише win(она же meta)
                                              0
                                              У данного подхода есть интересная особенность. Я привык после переключения языка (Alt + Shift) держать Shift зажатым, если мне, например, нужно начать предложение с заглавной буквы. Так вот, после смены языка Shift хоть и остается заглявным, но не влияет на регистр символов. Приходится отпускать и зажимать снова. Кто-нибудь сталкивался с подобным?
                                                0
                                                Попробуйте переключать по Shift + Alt
                                                0

                                                Я словив этот баг просто обновился до 19.10 убунты...

                                                  0
                                                  Неплохое решение. Как теперь поправить это в 19.10 убунте?
                                                  0
                                                  Всегда рекомендовал пользоваться разными клавишами для переключения раскладок. Первое время не удобно, но когда привыкаешь дает отличный прирост в скорости. Не отвлекаешься каждый раз на проверку какая текущая раскладка включена. Жмешь нужное сочетание и знаешь что включена нужная раскладка.

                                                  image
                                                    0
                                                    У меня уже много лет Ctrl+Shift, ещё с Windows 95. И вот на Ubuntu 18.04 я впервые обнаружил, что Ctrl+Shift И Shift+Ctrl — это теперь РАЗНЫЕ комбинации. Например, в PHPStorm Shift+Ctrl+F открывает окно поиска, а Ctrl+Shift+F… ну да, переключает раскладку. Пришлось некоторое время потренироваться, но в итоге привык, и теперь так и живу.
                                                      0
                                                      Ctrl+Shift И Shift+Ctrl — это теперь РАЗНЫЕ комбинации
                                                      Это же гениально. Десять лет сижу на линуксе и не знал что они разные. Возможно не было хорошего повода разобраться, а сам как то даже допустить не мог подобного. Было бы хорошим решением сделать Ctrl+Shift — первая раскладка а Shift+Ctrl — вторая. Кто нибудь так делал?
                                                      0
                                                      Проблема всегда была в том, что в линуксах комбинация срабатывает по кейдаун, а в винде — по кейап.
                                                        0
                                                        podkmax
                                                        Мой вопрос не сильно имеет отношение к статье, но просто интересно. Зачем использовать комбинацию клавиш «Alt» + «Shift», если можно использовать «Ctrl» + «Shift»? Я, например, пользуюсь второй, т.к. эта комбинация физически находится вместе и при нажатии на неё вероятность задевания других клавиш меньше.
                                                          0
                                                          Что-то никак не могу заставить работать на Ubuntu 19.10 именно комбинацию Alt+Shift, другие комбинации с обычными кнопками работают норм.

                                                          Т.е. запускаю xbindkeys -k, нажимаю Alt+Shift, он выводит:
                                                          "(Scheme function)"
                                                              m:0x9 + c:64
                                                              Shift+Alt + Alt_L
                                                          

                                                          Вставляю в файл .xbindkeysrc строку:
                                                          "/usr/bin/notify-send test"
                                                              m:0x9 + c:64
                                                          

                                                          Перезапускаю killall xbindkeys; xbindkeys -p -v и при нажатии Alt+Shift — ничего не происходит. Та же самая беда и с Ctrl+Shift, просто нажатием-отпусканием Ctrl, и т.п. Если добавить какую-нибудь обычную кнопку к комбинации (например Alt+Shift+A) — всё работает.
                                                          Может кто-нибудь подсказать в чём проблема? Возможно запущенные xorg или KDE как-то мешают?
                                                            0
                                                              0

                                                              Это чтобы переучиваться с alt+shift на shift+alt ломая столетнюю привычку?

                                                                0
                                                                Нет, alt-shift работает как всегда.
                                                                  0

                                                                  Хм, супер! Тогда надо будет попробовать, на мой KDE только портировать эти настройки осталось как-то

                                                              0
                                                              Предложенный в статье способ в целом работает, но не без проблем:

                                                              1. При нажатии Alt+Shift фокус у поля не теряется как раньше, но временно пропадает фокус у самой программы. В итоге, например, если открыть менюшку программ Kickoff, установить фокус в поле поиска и начать набирать, а потом нажать Alt+Shift — тогда менюшка закроется.

                                                              То же самое в Run Command Interface (Alt+F2)

                                                              2. При подключении по RDP к какой-нибудь венде, где установлено Alt+Shift — вообще ничего не работает — ни линуксовая переключалка ни виндовая, приходится мышкой тыкать переключать.

                                                              Может кто-то знает как эти проблемы решить?
                                                                0
                                                                Спасибо автору! Благодаря этой статье и комментариям к ней нашёл в AUR пропатченный xorg-server, который решает эту проблему. Наконец, всё заработало.

                                                                aur.archlinux.org/packages/xorg-server-bug865

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

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

                                                                Самое читаемое