Як зіставити модифікатори (наприклад, CTRL) на кнопки великого пальця миші за допомогою xbindkeys


13

Це питання вже було задано, але на нього не було відповідено належним чином. Після дозволу з @Seth я зараз запитую його знову. Це дозволить мені відповісти і, можливо, змінити питання набагато простіше. Оригінальне запитання можна знайти тут:

Позначте кнопки Ctrl та Alt на миші


Проблема:

Хоча відобразити будь-які натискання клавіш на кнопку миші за допомогою xbindkeysспільно з xdotoolабо xteздається набагато більш проблематичним відображення на ньому ключа модифікатора (наприклад, ALT , CTRL , SHIFT тощо).

Остаточне рішення має дозволити натискання CTRL + клацання (наприклад, для вибору кількох записів у списку) лише мишею.

Кілька можливих підходів до вирішення цього питання можна знайти тут на Stack Exchange, а також на інших пов'язаних з Linux форумах. Але жоден із них не працює так, як очікувалося, оскільки це призводить до інших проблем та побічних ефектів.

Примітки:

Деякі з наведених нижче прикладів включають Guile із синтаксисом Scheme та покладаються на .xbindkeysrc.scmфайл, тоді як інші покладаються на .xbindkeysrcфайл із відповідним синтаксисом. Я знаю, що вони не будуть працювати разом.

Крім того, наведені нижче фрагменти покладаються xdotoolтільки на те, але я відкритий для підходів, що включають інші додатки, наприклад, наприклад xte, хоча вони, як видається, призводять до однакових результатів, тому я xdotoolтут використовую лише дії.

Підхід A:

Оновлення .xbindkeysrcфайлу за допомогою:

"xdotool keydown ctrl"
  b:8

"xdotool keyup ctrl"
  release + b:8

Це те, що я спробував спочатку, але він має побічний ефект, коли модифікатор утримується і не може бути відпущений.

Підхід B:

Оновлення .xbindkeysrc.scmфайлу за допомогою:

(xbindkey '("b:8") "xdotool keydown ctrl")
(xbindkey '(release "b:8") "xdotool keyup ctrl")

(xbindkey '("m:0x14" "b:8") "xdotool keydown ctrl")
(xbindkey '(release "m:0x14" "b:8") "xdotool keyup ctrl")

Знайдено на веб- сайті http://www.linuxforums.org/forum/hardware-peripherals/169773-solved-map-mouse-button-modifier-key.html і намагається вирішити проблему, де міститься модифікатор (як описано під час підходу а).

Хоча він фіксує, що це працює лише частково, оскільки неможливо виконувати інші клацання миші, натиснувши кнопку великого пальця.

Підхід до C:

Оновлення .xbindkeysrcфайлу за допомогою:

"xdotool keydown ctrl"
  b:8

"xdotool keyup ctrl"
  release + control + b:8

Випробував ОП зв'язаного питання тут на askubuntu. Набагато простіший і міцніший, оскільки він не передбачає модифікаторних станів. Однак проблема залишається, тобто натискання CTRL + неможливо.

Здається, xbindkeysсама проблема тут, оскільки він розпізнає клацання, але не виконує його. Це можна перевірити з допомогою xev | grep buttonі xbindkeys -v:

Звичайний клік миші, як записано, xevповинен виглядати так:

state 0x10, button 1, same_screen YES
state 0x110, button 1, same_screen YES

А також для кнопки великого пальця:

state 0x10, button 8, same_screen YES
state 0x10, button 8, same_screen YES

Але якщо xbindkeysувімкнено вищевказану конфігурацію, вона нічого не записує. Хоча це має сенс і для кнопки великого пальця, оскільки вона відображається на CTRL і тому більше не є кнопкою миші, дивно, що кнопка 1 також не записується. Це, ймовірно, тому, що xbindkeysвін не виконує його, але сам розпізнає:

Button press !
e.xbutton.button=8
e.xbutton.state=16
"xdotool keydown ctrl"
    m:0x0 + b:8   (mouse)
got screen 0 for window 16d
Start program with fork+exec call
Button press !
e.xbutton.button=1
e.xbutton.state=20
Button release !
e.xbutton.button=1
e.xbutton.state=276
Button release !
e.xbutton.button=8
e.xbutton.state=20
"xdotool keyup ctrl"
    Release + m:0x4 + b:8   (mouse)
got screen 0 for window 16d
Start program with fork+exec call

Підхід D:

Оновлення .xbindkeysrcфайлу за допомогою:

"xdotool keydown ctrl"
  b:8

"xdotool keyup ctrl"
  release + control + b:8

"xdotool click 1"
  b:1

Просто занадто просто ... але призводить до нескінченного циклу кліків.


ОНОВЛЕННЯ:

Тим часом я купив Logitech G502 і зауважив, що після налаштування через драйвер у Windows в пам'яті пристрою зберігається не лише сам профіль, а власне натискання клавіші робиться мишею. Це насправді вирішило мою проблему в Linux!

Єдина інша миша, яку я пам’ятаю, що змогла це зробити, це Разер Коппергед ще в ті часи. Але я здогадуюсь, сьогодні є інші миші, які можуть зробити те саме.


1
ось рішення з використанням Easystroke: askubuntu.com/a/1010647/27202
ІПК

Відповіді:


8

Я витратив багато часу, намагаючись зробити цю обов'язкову роботу. Зрештою, я знайшов рішення, яке є складним, але працює добре і не передбачає програмного забезпечення сторонніх виробників. Я ділюсь цим, сподіваючись, що він допоможе людям. Крім того, я знаю, що це не ідеально з точки зору безпеки, тому будь-які конструктивні відгуки є більш ніж вітаються.

Є рішення, які справді приємні, як запропоноване тут , але це завжди страждає від обмеження xbindkeys, які захоплюють всю мишу, роблячи модифікатори + відображення клацання миші невизначеними. Плюс рішення, що базується на підставці з вищевказаного посилання, використовують ctrl + plus / ctrl + мінус, який Gimp, наприклад, не розпізнає.

Я зрозумів, що те, що ми хочемо, - це кнопка миші, яка виконує функції клавіатури, тому я використав uinput, до якого можна отримати доступ через python , написав сценарій, що монітор / dev / my-mouse для натискання кнопки великого пальця та надіслати клавішу ctrl на віртуальну клавіатуру. Ось детальні кроки:

1. Складіть правила udev

Ми хочемо, щоб пристрої були доступними (права та місцезнаходження).

Для миші:

/etc/udev/rules.d/93-mxmouse.conf.rules
------------------------------------------------------------
KERNEL=="event[0-9]*", SUBSYSTEM=="input", SUBSYSTEMS=="input", 
ATTRS{name}=="Logitech Performance MX", SYMLINK+="my_mx_mouse", 
GROUP="mxgrabber", MODE="640"

Udev шукатиме пристрій, розпізнаване ядром, з такими іменами, як event5, і я вибираю мишу з ім'ям. Інструкція SYMLINK запевняє, що я знайду свою мишку в / dev / my_mx_mouse. Пристрій буде читабельний членом групи "mxgrabber".

Щоб знайти інформацію про своє обладнання, слід запустити щось подібне

udevadm info -a -n /dev/input/eventX

Для вводу даних:

/etc/udev/rules.d/94-mxkey.rules
----------------------------------------------------
KERNEL=="uinput", GROUP="mxgrabber", MODE="660"

Немає необхідності в символьному посиланні, вхід завжди буде $/dev/uinputабо $/dev/input/uinputзалежатиме від системи, на якій ви працюєте. Просто дайте йому групу та права читати та писати звичайно.

Вам потрібно відключити мережу - підключіть мишу, і нове посилання має з’явитися в / dev. Ви можете змусити udev запускати свої правила$udevadm trigger

2. Активуйте модуль UINPUT

sudo modprobe uinput

І щоб зробити його завантаження стійким:

/etc/modules-load.d/uinput.conf
-----------------------------------------------
uinput

3. Створіть нову групу

sudo groupadd mxgrabber

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

sudo usermod -aG mxgrabber your_login

4. Сценарій Python

Вам потрібно встановити бібліотеку python-uinput (очевидно) та бібліотеку python-evdev . Використовуйте піп або ваш дистрибутивний пакет.

Сценарій досить простий, вам просто потрібно визначити код події.

#!/usr/bin/python3.5
# -*- coding: utf-8 -*-

"""
Sort of mini driver.
Read a specific InputDevice (my_mx_mouse),
monitoring for special thumb button
Use uinput (virtual driver) to create a mini keyboard
Send ctrl keystroke on that keyboard
"""

from evdev import InputDevice, categorize, ecodes
import uinput

# Initialize keyboard, choosing used keys
ctrl_keyboard = uinput.Device([
    uinput.KEY_KEYBOARD,
    uinput.KEY_LEFTCTRL,
    uinput.KEY_F4,
    ])

# Sort of initialization click (not sure if mandatory)
# ( "I'm-a-keyboard key" )
ctrl_keyboard.emit_click(uinput.KEY_KEYBOARD)

# Useful to list input devices
#for i in range(0,15):
#    dev = InputDevice('/dev/input/event{}'.format(i))
#    print(dev)

# Declare device patch.
# I made a udev rule to assure it's always the same name
dev = InputDevice('/dev/my_mx_mouse')
#print(dev)
ctrlkey_on = False

# Infinite monitoring loop
for event in dev.read_loop():
    # My thumb button code (use "print(event)" to find)
    if event.code == 280 :
        # Button status, 1 is down, 0 is up
        if event.value == 1:
            ctrl_keyboard.emit(uinput.KEY_LEFTCTRL, 1)
            ctrlkey_on = True
        elif event.value == 0:
            ctrl_keyboard.emit(uinput.KEY_LEFTCTRL, 0)
            ctrlkey_on = False

5. Насолоджуйтесь!

Все, що вам потрібно зараз, це зробити файл python виконуваним і попросити менеджера робочого столу завантажити файл при запуску. Може, також келих вина, щоб відсвяткувати добру справу!

6. Додатково безкоштовно

Я використовую xbindkeys для додаткової поведінки. Наприклад, така конфігурація може бути приємною, якщо у вас є миша з клацанням збоку колеса:

~/.xbindkeysrc
---------------------------------------------
# Navigate between tabs with side wheel buttons
"xdotool key ctrl+Tab"
  b:7
"xdotool key ctrl+shift+Tab"
  b:6

# Close tab with ctrl + right click
# --clearmodifiers ensure that ctrl state will be 
# restored if button is still pressed
"xdotool key --clearmodifiers ctrl+F4"
  control+b:3

Щоб ця остання комбінація спрацювала, ви повинні відключити налаштовану для сценарію python кнопку , інакше xbindkeys її все одно захопить. Залишається лише ключ Ctrl:

~/.Xmodmap
-------------------------------------------
! Disable button 13
! Is mapped to ctrl with uinput and python script
pointer = 1 2 3 4 5 6 7 8 9 10 11 12 0 14 15

Перезавантажити за допомогою $ xmodmap ~/.Xmodmap

7. Висновок

Як я вже говорив на початку, я не зовсім задоволений тим, що я маю дати собі права, щоб писати в / dev / uinput, навіть якщо це вважається групою "mxgrabber". Я впевнений, що це безпечніший спосіб зробити це, але я не знаю як.

Зі світлого боку, це працює дуже-дуже добре. Будь-яке поєднання клавіатури або клавіші миші, як працює з клавішею Ctrl клавіатури, тепер працює з клацанням миші !!


Дуже дякую за докладені зусилля та поділившись з нами! +1 ... Хоча я ще цього не перевіряв. До речі, я майже відмовився від цього - було б чудово, якби це працювало так, як очікувалося :)
conceptdeluxe

Ласкаво просимо ! Для мене це працює бездоганно. Якщо у вас є проблеми, дайте мені знати. Я намагаюся зробити свою відповідь повною, але, оскільки я витратив майже два дні на те, щоб вона спрацювала, я, можливо, щось забула. Буду рада допомогти / відредагувати мою публікацію.
Aurélien Cibrario

Я щойно зрозумів, що ctrl + click1 - дуже поганий вибір для закриття вкладки, оскільки вона відкриває посилання в новій вкладці. Я відредагував свою відповідь, видаливши останню частину сценарію python і налаштувавши xbindkeys, більш чисте рішення
Aurélien Cibrario

просто хочу повідомити вам, що я ще не встиг її перевірити, - але я точно зроблю це прийнятою відповіддю, якщо він працює, як очікувалося, - вибачте за очікування - я трохи зайнятий атм
conceptdeluxe

Цікаво, чи можемо ми використати вищезазначений скрипт, щоб розкрити несправний перемикач миші. У мене зношена миша. Я використовую сценарій автоматичної клавіші, щоб виправити його в Windows, але в Linux немає інструменту, щоб його виправити. Ось сценарій автоматичної клавіші для виправлення лівих кнопок autohotkey.com/board/topic/63555-debounce-mouse-keys Я сподіваюся, що хтось перенесе його до Linux за допомогою python3 - evdev
kenn

4

Я знайшов рішення з PyUserInput . Це в кінцевому підсумку є досить простим і не вимагає адміністративних прав. З встановленими python 2 та PyUserInput я використав такий сценарій:

#!/usr/bin/python
from pymouse import PyMouseEvent
from pykeyboard import PyKeyboard

k = PyKeyboard()
class MouseToButton(PyMouseEvent):
    def click(self, x, y, button, press):
        if button == 8:
            if press:    # press
                k.press_key(k.control_l_key)
            else:        # release
                k.release_key(k.control_l_key)

C = MouseToButton()
C.run()

Після надання прав на виконання сценарію, я називаю його ~/.xsessionrc, наприклад, рядком

~ / шлях / до / script.py &

Примітка . це не заважає спрацьовувати події кнопки миші. У моєму випадку я xinput set-button-mapзмінював відображення кнопок xinput і присвоював номер цікавої мені кнопки чимось, що не використовується.

Наприклад, якщо ви хочете використовувати кнопку 8 на миші, але кнопка 8 вже має функцію (наприклад, page-next), ви можете використовувати наступне.xsessionrc

logitech_mouse_id=$(xinput | grep "Logitech M705" | sed 's/^.*id=\([0-9]*\)[ \t].*$/\1/')
xinput set-button-map $logitech_mouse_id 1 2 3 4 5 6 7 12 9 10 11 12 13 14 15 16 17 18 19 20
./.xbuttonmodifier.py &

надана кнопка 12не має ніякого значення для ОС, і призначити користувальницьку функцію для кнопки 12в .xbuttonmodifier.pyсценарії, який я описав вище.


Але це не заважає оригінальній події стріляти. Отже, якщо я відображаю кнопку 8 для переключення та утримую кнопку 8 у Firefox, вона також намагається повернутися на попередню сторінку, що небажано.
user23013

1
Правда. Для вирішення цього питання я використав ідентифікатор кнопки, яка мене зацікавила, на використану кнопку в xinput. Див. Відредаговане запитання.
Максим

2

У мене часткове рішення. Я не придумав, як скасувати карту існуючої кнопки, тож ви закінчуєте натискання кнопки та потрібний модифікатор. Тож якщо ця кнопка миші має якусь діючу мету, вона все одно запуститься. Наприклад, перестановка правої кнопки миші на контрольну клавішу призведе до надсилання елемента керування + клацання.

У всякому разі, я знайшов допис на форумі, який схожий на ваше запитання, на який відповідь було встановити btnx і налаштувати свої модифікатори через це. Здається, btnx більше не доступний через репо. Є ppa, але він не працює для останнього ubuntu.

Запис на форумі: повідомлення: http://ubuntuforums.org/showthread.php?t=1245930

Але джерело доступне:

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

А саме такі файли:

/usr/local/sbin/btnx
/etc/init.d/btnx
/usr/share/pixmaps/btnx.png
/usr/share/btnx-config (directory, multiple files)
/usr/share/applications/btnx-config.desktop
/usr/share/omf/btnx-config/btnx-manual-C.omf
/usr/share/locale/de/LC_MESSAGES/btnx-config.mo
/usr/share/locale/fr/LC_MESSAGES/btnx-config.mo
/usr/share/locale/nl/LC_MESSAGES/btnx-config.mo
/usr/share/locale/ru/LC_MESSAGES/btnx-config.mo

Наступні символьні посилання:

/etc/rc0.d/K49btnx -> ../init.d/btnx
/etc/rc1.d/K49btnx -> ../init.d/btnx
/etc/rc6.d/K49btnx -> ../init.d/btnx
/etc/rc2.d/S49btnx -> ../init.d/btnx
/etc/rc3.d/S49btnx -> ../init.d/btnx
/etc/rc4.d/S49btnx -> ../init.d/btnx
/etc/rc5.d/S49btnx -> ../init.d/btnx

Отже ... якщо ви не проти побудувати з джерела ...

Отримайте залежності для btnx:

sudo apt-get install libdaemon-dev git

Якщо ви ніколи нічого не будували з джерела, вам може знадобитися також істотна збірка:

sudo apt-get install build-essential

Потім отримайте і компілюйте btnx:

git clone https://github.com/cdobrich/btnx
cd btnx
./configure
make
sudo make install
cd -

Він має окремий інструмент конфігурації GUI. Отримайте залежності для цього:

sudo apt-get install libgtk2.0-dev libglade2-dev

Тепер отримайте та компілюйте інструмент gui config:

git clone https://github.com/cdobrich/btnx-config
./configure
make
sudo make install

Тепер запустіть інструмент:

sudo btnx-config

Натисніть кнопку Виявити кнопки миші Якщо ви хочете мати можливість читати вказівки під час використання інструменту, змінити розмір вікна, яке вискочить, текст діалогу буде вирізаний пізніше, якщо ви цього не зробите, і якщо ви спробуєте змінити розмір під час виявлення, він скасується виявлення. Просто зробіть вікно трохи більше.

Натисніть кнопку "Натиснути", щоб почати розпізнавання миші, потім намагайтеся не рухати мишкою, поки текст не зміниться ... Займає близько 5-10 секунд. Текст зміниться. Коли це станеться, ігноруйте сказане та натисніть Вперед.

Натисніть кнопку "Натисніть, щоб запустити виявлення кнопки"

Тут ви кілька разів натискаєте одну кнопку миші (поки рядок стану не заповниться). Потім встановіть назву кнопки на те, що ви впізнаєте пізніше (наприклад: LeftButton) Натисніть кнопку Додати.

Повторіть це для кожної кнопки миші (не забувайте колеса прокрутки, клавіші прокрутки тощо). Можливо, ви можете пропустити будь-які кнопки, які ви не хочете робити повторно.

Після додавання всіх кнопок натисніть кнопку ОК.

У головному графічному інтерфейсі натисніть кнопку Кнопки, у лівій області виберіть кнопку, яку ви хочете зробити повторно. Він використовуватиме імена, які ви ввели у попередніх кроках. Для ваших цілей потрібно вибрати лише модифікатор ключа під комбінацією клавіш праворуч.

Не натискайте на видаленні на цьому екрані, це видалить кнопку. Вам доведеться повернутися назад і знову виявити кнопку, якщо це зробити.

Поверніться на екран Conrigurations і натисніть кнопку Перезапустити btnx.

Спробуйте нову кнопку.

Якщо ви хочете видалити програми, зупиніть програму btnx, а потім перейдіть до відповідних каталогів, що перевіряються, і видаліть:

sudo /etc/init.d/btnx stop
cd btnx
sudo make uninstall
cd -
cd btnx-config
sudo make uninstall
cd -

2
Дякую за детальну відповідь, яку ви опублікували на пастібіні. Але я боюся, що мені не дозволяється використовувати непідтверджений ppa або створювати додаток з невідомого джерела, не детально переглядаючи його на своєму пристрої. Тим не менш я дам вам голос за зусилля, які ви доклали до цього. Крім цього, я рекомендую вам оновити свою відповідь тут і скопіювати те, що ви там написали, оскільки ця інформація може бути корисною для інших, але може бути пропущеною. Нарешті я прочитав, що пакет може навіть не компілюватися під Ubuntu або Debian - ви це насправді намагалися?
conceptdeluxe

Btw: Ви можете легко отримати додаткову 100 репутацію, зв’язавши свій обліковий запис askubuntu з іншими обліковими записами Stack Exchange, наприклад, Linux та Unix.
conceptdeluxe

Так, я тестував його під Ubuntu 14.04. Я змусив праву кнопку миші надіслати контрольний ключ і підтвердив, що він працював перед публікацією. А потім майже відмовився від посади через вимогу репутації.
Стівен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.