- Вопрос или проблема
- Ответ или решение
- Решение проблемы с потерей xmodmap после сна в Ubuntu 18.04
- Проблема
- Решения и подходы
- 1. Запуск xmodmap при старте сеанса
- 2. Использование системного юнита systemd для обработки спящего режима
- 3. Скрипт для обработки спящего режима
- 4. Использование udev для автоматического восстановления привязок клавиатуры
- Заключение
Вопрос или проблема
В Ubuntu 18.04 я использую следующий скрипт автозагрузки:
[Desktop Entry]
Type=Application
Exec=/home/user/.xinitrc
Version=1.0
X-GNOME-Autostart-enabled=true
Name=xmodmap
Comment=xmodmap script
который просто xmodmap /path/.Xmodmap &
.
Когда система загружается, он работает. Когда система выходит из спящего режима, переназначение больше не работает. Как я могу это исправить?
ИЗМЕНЕНИЕ: (ответ на комментарий)
Это также не исправляет проблему:
$ cat /etc/systemd/system/xmodmapbindings.service
[Unit]
Description=xmodmap bindings
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=-/home/norake/.xinitrc
[Install]
WantedBy=sleep.target
$ cat ~/.xinitrc
#!/bin/bash
if [ "$USER" != norake ]; then
su norake -c 'sleep 5; /usr/bin/xmodmap /home/norake/.Xmodmap' &
# без su, без sleep, без fork (&): тоже не работает
else
(sleep 5; /usr/bin/xmodmap /home/norake/.Xmodmap) &
fi
sleep 30
также не работает. Конечно, скрипт, запущенный вручную, работает.
Ваши измененные настройки также “теряются”, когда вы отключаете и снова подключаете клавиатуру, и именно это здесь происходит: при переходе в режим сна генерируются события горячей замены, так как клавиатура отключается при входе в режим сна и снова включается при выходе.
С точки зрения X сервера, клавиатура, подключенная после выхода из спящего режима, является новой клавиатурой, поэтому она подключается с стандартными настройками, так же как и вторая клавиатура.
Это известная проблема драйверов USB клавиатуры и будет сложной для исправления в ядре (поскольку USB переизмеряется при возобновлении, таким образом, нам нужен метод для сохранения идентичности устройства, даже если ему присваивается новый номер), и сложно исправить в X сервере (поскольку потребуется сохранять историю устройств).
Вероятно, лучшее, что вы могли бы сделать, это запускать команду как часть запуска вашей сессии и как часть обработки горячей замены для клавиатуры, но я не могу придумать полностью чистое решение здесь.
Это мое простое кустарное решение для особого случая этой проблемы:
Моя клавиатура имеет клавишу Print, где должна быть клавиша Меню, поэтому мой xmodmap переназначает именно эту клавишу.
Я настроил сочетание клавиш (в gnome shell в моем случае) для клавиши Print, чтобы запустить
/bin/bash -c "/usr/bin/xmodmap $HOME/.Xmodmap"
Таким образом, после сна, в первый раз, когда я нажимаю клавишу Print, она вызовет xmodmap и с этого момента будет работать как клавиша меню.
(После этого у моей клавиатуры больше не будет клавиши Print.)
Этот подход должен работать, когда:
- Вам не жалко первоначального “слепого” нажатия клавиши.
- У вас есть хотя бы одна кнопка, которую вы знаете, что нажмете до того, как или как только переназначение станет актуальным.
- Первичный символ клавиши этой кнопки больше не присутствует в новом сопоставлении.
Обновление: С тех пор я усовершенствовал свое решение с помощью xdotool, чтобы также вызывать контекстное меню на этапе первоначального переназначения:
/bin/bash -c "xdotool keyup Print key --clearmodifiers Menu && /usr/bin/xmodmap $HOME/.Xmodmap"
Не забудьте заменить $USER
на ваше реальное имя пользователя:
-
Создайте свой файл
.Xmodmap
с сопоставлением, в моем случае это:keycode 96 = XF86AudioLowerVolume keycode 95 = XF86AudioMute keycode 76 = XF86AudioNext keycode 75 = XF86AudioPlay keycode 74 = XF86AudioPrev
и поместите его по пути
/home/$USER/.Xmodmap
-
Создайте предпочтение для запуска приложения (перейдите в настройки запуска приложений из меню поиска по супер-кнопке) и добавьте следующее:
Name: xmodmap Command: /bin/bash -c "sleep 7 && xmodmap ~/.Xmodmap" Comment:
и сохраните это. И закройте настройки запуска приложений
-
Теперь перейдите в папку
/usr/lib/systemd/system-sleep
, вот так:cd /usr/lib/systemd/system-sleep
-
Создайте файл с именем
xkeyboard.sh
. Вы можете сделать это так (требуются права sudo):sudo touch xkeyboard.sh
-
Теперь получите значение вашей переменной
$XAUTHORITY
. Вы можете сделать это так:echo $XAUTHORITY
В моем случае это вернёт следующее:
/run/user/1000/gdm/Xauthority
Запишите это где-нибудь.
-
Откройте ваш вновь созданный файл для редактирования, вы можете сделать это так:
sudo nano xkeyboard.sh
-
Вставьте этот код. Убедитесь, что заменили
$USER
на ваше имя пользователя и$XAUTH
на переменную, которую вы записали ранее:#!/bin/bash echo "Running xkeyboard.sh with argument: $1" >> /tmp/xkeyboard.log if [ "${1}" == "pre" ]; then echo "pre" >> /tmp/xkeyboard.log # Ничего не делать для предварительного сна elif [ "${1}" == "post" ]; then echo "post" >> /tmp/xkeyboard.log export DISPLAY=:0 # Установить переменную DISPLAY export XAUTHORITY=$XAUTH /bin/bash -c "sleep 7 && xmodmap home/$USER/.Xmodmap" >> /tmp/xkeyboard.log 2>&1 fi
В этом коде я добавил логирование в файл
/tmp/xkeyboard.log
, так что если сопоставление клавиатуры не работает, вы можете обратиться туда и проверить, в чем дело.
Вот рабочее решение, я получил помощь из различных источников, но в основном это написано мной. caps – это скрипт xmodmap (CapsLock => F13).
#!/bin/bash
USERN=cemkalyoncu
SCRIPT=/home/cemkalyoncu/Installed/caps
case $1 in
post)
DISPLAY=:0
export DISPLAY
su $USERN -c "$SCRIPT"
#screen
#su $USERN -c "sleep 30; kwin --replace &" &
esac
Я также оставил kwin --replace
, так как kwin иногда вызывает сбои и требует перезагрузки, но это не демон и должен быть отделен с помощью screen. Это только если вы используете KDE. Если не установлен, установите screen. Экспортирование дисплея здесь является ключом к его работе. Запуск от вашего имени также необходим. Даже если вы тот, кто возобновляет, это все равно не ваша учетная запись. Сон не требуется для xmodmap. Но kwin автоматически сбрасывается системой через несколько секунд после возобновления, но иногда может не сработать; таким образом, задержка необходима.
Если вам немного неприятно принуждать $DISPLAY и т.д. извне, маленький хак:
- Создайте небольшой скрипт, который будет работать постоянно:
xmodmapper.sh:
#!/bin/sh
while true; do
echo "перезагрузка xmodmap"
sleep 2
xmodmap ~/.Xmodmap
kill -STOP $$
done
-
Запустите его как часть вашей X-сессии, например, добавьте
~/xmodmapper.sh &
в ваш ~/.xinitrc -
Добавьте правило в какой-то файл udev правил:
например, /etc/udev/rules.d/80-keyboard.rule:
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="1b1c/1b2d/329", RUN+="/usr/bin/killall -CONT xmodmapper.sh"
и замените ENV{PRODUCT} на ваше USB-устройство – мое основано на этой строке syslog:
New USB device found, idVendor=1b1c, idProduct=1b2d, bcdDevice= 3.29
Это кажется мне немного более надежным, чем другие подходы, хотя YMMV. (Тем более, что у меня уже есть другие правила udev, связанные с клавиатурой.)
П.С. Сон важен, поскольку в противном случае возникает гонка, когда xmodmap вызывается до того, как Xorg успевает зарегистрировать клавиатуру, как только она подключена. Корректное решение, например, с помощью xev, оставлено на усмотрение читателя.
Ответ или решение
Решение проблемы с потерей xmodmap после сна в Ubuntu 18.04
Проблема
При использовании Ubuntu 18.04 после выхода из режима сна настройки клавиатуры, установленные с помощью xmodmap
, теряются. Эта проблема связана с тем, что после пробуждения операционная система воспринимает подключенную клавиатуру как новое устройство, что приводит к сбросу всех нестандартных привязок.
Решения и подходы
Существует несколько подходов к решению этой проблемы, каждый из которых имеет свои плюсы и минусы.
1. Запуск xmodmap при старте сеанса
Для этого простейшего метода вам необходимо добавить команду xmodmap
в настройки автозапуска приложений системы:
- Откройте меню «Запуск приложений» (Startup Applications).
- Добавьте новую запись с параметрами:
- Название: xmodmap
- Команда:
/bin/bash -c "sleep 7 && xmodmap ~/.Xmodmap"
- Комментарий: (оставьте пустым или добавьте пояснение).
Этот метод перезапустит настройки клавиатуры каждый раз при входе в систему, однако он не решает проблему при пробуждении из режима сна.
2. Использование системного юнита systemd для обработки спящего режима
Создание системы управления зависимостями позволит автоматизировать процесс восстановления настроек клавиатуры:
-
Создайте файл
xmodmap.service
в каталоге/etc/systemd/system/
:[Unit] Description=xmodmap bindings WantedBy=suspend.target hibernate.target [Service] Type=oneshot ExecStart=/bin/bash -c "sleep 5 && xmodmap ~/.Xmodmap"
-
Включите сервис:
sudo systemctl enable xmodmap
-
Перезагрузите систему и протестируйте его работу.
3. Скрипт для обработки спящего режима
Скрипт, который будет срабатывать при пробуждении, также может эффективно восстанавливать настройки клавиатуры:
-
Создайте скрипт в каталоге
/usr/lib/systemd/system-sleep/
, напримерxkeyboard.sh
, с содержимым:#!/bin/bash case $1 in post) export DISPLAY=:0 export XAUTHORITY=/run/user/$(id -u)/gdm/Xauthority sleep 5 xmodmap ~/.Xmodmap ;; esac
-
Сделайте скрипт исполняемым:
sudo chmod +x /usr/lib/systemd/system-sleep/xkeyboard.sh
Этот скрипт обеспечит выполнение команды xmodmap
при выходе из режима сна. Убедитесь, что вы используете правильный DISPLAY
и XAUTHORITY
.
4. Использование udev для автоматического восстановления привязок клавиатуры
Вы можете настроить udev
для запуска xmodmap
, когда обнаруживается клавиатура:
-
Создайте правило
80-keyboard.rules
в директории/etc/udev/rules.d/
:SUBSYSTEM=="input", ACTION=="add", RUN+="/bin/bash -c 'sleep 5 && xmodmap ~/.Xmodmap'"
-
Перезагрузите udev:
sudo udevadm control --reload-rules
Этот подход будет восстанавливать привязки при каждом подключении клавиатуры.
Заключение
Каждый из предложенных методов может быть использован в зависимости от ваших предпочтений и требований. Наиболее простой и эффективный способ — это использовать системный юнит для автоматического вызова xmodmap
после пробуждения системы. При этом важно корректно настроить переменные окружения DISPLAY
и XAUTHORITY
, чтобы обеспечить стабильную работу скрипта.
Не забывайте тестировать каждое решение, чтобы убедиться в его работоспособности. Надеюсь, эти рекомендации помогут вам решить проблему с потерей настроек клавиатуры в Ubuntu 18.04 после выхода из режима сна.