?

Log in

No account? Create an account

Переназначение кнопок мыши в linux. - Мысли злого плебея — ЖЖ

29 июл 2017

10:07 pm - Переназначение кнопок мыши в linux.

Previous Entry Поделиться Next Entry

В windows такой фокус не предусмотрен. Там это делается сторонними программами, например X-Mouse Button Control, которые реализуют фильтр сообщений от мыши.
В Linux есть три способа для этого:
-внешний фильтр xbindkeys;
-переназначения порядка кнопок в xmodmap;
-переназначение порядка кнопок в xinput.


В linux кнопки мыши идут под номерами от 1 до 9 или 32, в источниках по разному пишут: судя по выхлопу xkbcomp их 9, xmodmap пишет про 20, а в документации evdev пишут про 32.
Их назначение.

Номер кнопки Положение кнопки на мыше logitech Назначение
1 левая кнопка Ввод
2 нажатие на колесико прокрутки linux ничего не делает
3 правая кнопка контекстное меню
4 прокрутка колесика от себя смещение экрана в направлении Z+(вертикальной плоскости)
5 прокрутка колесика на               себя смещение экрана в направлении Z-(вертикальной плоскости)
6 сдвиг колесика прокрутки влево смещение экрана в направлении X- (горизонтальной плоскости)
7 сдвиг колесика прокрутки вправо смещение экрана в направлении X+ (горизонтальной плоскости)
8 ближняя кнопка для большого пальца назад
9 дальняя кнопка для большого пальца вперед


Какой номер имеет каждая физическая кнопка мыши определяется командой: "xev | grep -A2 --line-buffered '^ButtonPress' | sed -nE '/button /s/^.*(button[[:space:]]+[[:digit:]]+).*$/\1/ p'".



Для переопределения кнопок мыши может понадобиться определение ее имени.
Для получения имени мыши весящей на отдельном гнезде, необходимо выполнить команду "grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | sed -nE '/Name=/,/Handlers=.*mouse/ {/Name=/N; /Handlers=.*kbd/bskip;/Handlers=.*mouse/s/^.*Name=["]([^"]+)["].*$/\1/p;:skip}'".
Если в гнезде висит мышь с клавиатурой, например комплект из беспроводной мыши и клавиатуры, то надо выполнить команду "grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | grep -EB1 'Handlers.*kbd' | sed -nE 's/^.*Name=["]([^"]+)["].*$/\1/p'".
Вывод имен мышей сидящих в отдельном гнезде или с клавиатурой:"grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | sed -nE 's/^.*Name=["]([^"]+)["].*$/\1/p'".
Для вывода имени мыши содержащей какую-то последовательность символов, надо предыдущие команды дополнить окончанием похожим на " | grep 'Logitech M'",где "Logitech M" может быть любой требуемой строкой.

Тогда получится что-то такое: "grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | sed -nE '/Name=/,/Handlers=.*mouse/ {/Name=/N; /Handlers=.*kbd/bskip;/Handlers=.*mouse/s/^.*Name=["]([^"]+)["].*$/\1/p;:skip}' | grep "Logitech M"".


1. Переназначение при помощи xmodmap.

При помощи xmodmap можно только изменить номерацию кнопок мыши, причеем только у всех мышей сразу. Это самая удобная команда. Только linuxоиды ищуют трудный путь, поэтому они предпологают в ближайшее время эту лазейку заблокировать. Например, что бы 6 и 7 кнопки действовали как вперед/назад надо выполнить такую команду: 'xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"'. Заменить левую кнопку с правой: 'xmodmap -e "pointer = 3 2 1"'. Заблокировать левую кнопку: 'xmodmap -e "pointer = 0"'. Заблокировать все кнопки: 'xmodmap -e "pointer = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"'. Разблокировать все кнопки: 'xmodmap -e "pointer = default"'. Изменить направление вращения колеса прокрутки: 'xmodmap -e "pointer = 1 2 3 5 4"'. Вывод текущего состояния: 'xmodmap -pp'. Из этих примеров видно, что позиционному положению числа в команде соответствует физический номер кнопки, а это число новое значение. Цифра 0 означает заблокированную кнопку. Единственно эта программа глючит при назначении нескольким кнопкам одного номера кнопки. Команда не требует root прав, поэтому возможно незаметно кому-нибудь заблокировать мышь:)


2. Переназначение при помощи xinput. Похожа на предыдущий случай, но переназначает кнопки у конкретной мыши.

Формат команды такой: "xinput -set-button-map "id мыши" 1 2 3 4 5 6 7 8 9..." - где "id мыши" получается из выхлопа команды xinput без параметров, а последующие цифры аналогичны используемым в команде xmodmap.Использовать просто число в качестве id мыши нельзя, так как после перезагрузки компьютера оно может быть другим. Поэтому надо использовать скрипты такого вида.

Например переназначение кнопок на колесике мыши logitech для перемещения вперед-назад в интернете: "xinput set-button-map "$(xinput | awk -F'[=]' '/Logitech M/ {print $2}' | awk '{print $1}')" 1 2 3 4 5 8 9 6 7" или так "xinput set-button-map "$(xinput | sed -nE '/Logitech M/s/^.*id=([[:digit:]]+).*$/\1/p')" 1 2 3 4 5 8 9 6 7".

Тоже самое, если неизвестен производитель мыши, но известно, что она одна в компьютере и висит на одном гнезде без клваиатуры: "xinput set-button-map "$(xinput | sed -nE "/$(grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | sed -nE '/Name=/,/Handlers=.*mouse/ {/Name=/N; /Handlers=.*kbd/bskip;/Handlers=.*mouse/s/^.*Name=["]([^"]+)["].*$/\1/p;:skip}')/s/^.*id=([[:digit:]]+).*$/\1/p")" 1 2 3 4 5 8 9 6 7".

Если неизвестен производитель мыши, но изввестно, что она висит в одном гнезде с клавиатурой:"xinput set-button-map "$(xinput | sed -nE "/$(grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | grep -EB1 'Handlers.*kbd' | sed -nE 's/^.*Name=["]([^"]+)["].*$/\1/p')/s/^.*id=([[:digit:]]+)[[:space:]]+\[slave[[:space:]]+pointer.*\]/\1/p")" 1 2 3 4 5 8 9 6 7".


3. Переназначение при помощи xbindkeys.

Это самый неудобный и медленный способ, так как требует файла снастройками и вызывает внешнюю команду, которая будет эмулировать нажатие другой кнопки. Зато он самый гибкий. При помощи него можно на кнопку мыши повесить любую программу.
Для его работы необходимо создать текстовый файл "~/.xbindkeysrc". Этот файл содержит пары строк. Первая строка в каждой паре обозначает выполняемую команду, а вторя - нажую кнопку. Кроме мыши они может обрабатывать нажатия на клавиатуру. То есть команда предназначена для создания горячих клавиш.

В linux существует две команды эмулирующие нажатия кнопок: xte и xvkbd. Можно использовать любую в качестве первой строки.
Во второй строке описываетсмя нажатая комбинация кнопок. Для мыши она выглядит так: "b:<номер кнопки мыши>".

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

Использование xte для симуляции нажатия на 8 или 9 кнопку мыши.
# Back
"xte 'mousedown 8' 'mouseup 8'"
  b:6

# Forward
"xte 'mousedown 9' 'mouseup 9'"
  b:7

Использование xte для симуляции нажатия на <Alt>+стрелка
# Back
"xte 'keydown Alt_L' 'key Left' 'keyup Alt_L'"
  b:6

# Forward
"xte 'keydown Alt_L' 'key Right' 'keyup Alt_L'"
  b:7

Использование xvkbd для симуляции мультимедиа кнопок вперед-назад
# Back
"xvkbd -xsendevent -text "\[XF86Back]"
  b:6

# Forward
"xvkbd -xsendevent -text "\[XF86Forward]"
  b:7

После чего запустить xbindkeys.


Все три способа требуют после перезагрузки выполнить какую-то команду, поэтому необходимо создать ярлык (текстовый файл с расширением .desktop) в автозагрузке (папке "~/.config/autostart/").


Мой ярлык.
[Desktop Entry]
Type=Application
Exec=xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
X-GNOME-Autostart-enabled=true
NoDisplay=true
Hidden=false
Name="mouse button exchange"
Comment="6->8 7->9 8->6 9->7"
X-GNOME-Autostart-Delay=0

Можно было бы такой, что бы никто не понял, при помощи xinput. Зато умный как утка.
[Desktop Entry]
Type=Application
Exec=xinput set-button-map "$(xinput | sed -nE "/$(grep -E "Name=|Handlers" /proc/bus/input/devices | grep -EB1 'Handlers.*mouse' | sed -nE '/Name=/,/Handlers=.*mouse/ {/Name=/N; /Handlers=.*kbd/bskip;/Handlers=.*mouse/s/^.*Name=["]([^"]+)["].*$/\1/p;:skip}')/s/^.*id=([[:digit:]]+).*$/\1/p")" 1 2 3 4 5 8 9 6 7
X-GNOME-Autostart-enabled=true
NoDisplay=true
Hidden=false
Name="mouse button exchange"
Comment="6->8 7->9 8->6 9->7"
X-GNOME-Autostart-Delay=0

Самый простой для xbindkeys.
[Desktop Entry]
Type=Application
Exec=xbindkeys
X-GNOME-Autostart-enabled=true
NoDisplay=true
Hidden=false
Name="mouse button exchange"
Comment="6->8 7->9 8->6 9->7"
X-GNOME-Autostart-Delay=0