Как правильно сопоставить клавиатуру с кнопкой мыши?

Резюме вопроса: я хочу, чтобы одна из моих кнопок мыши была зарегистрирована как левая кнопка Windows Super_L в X11.


В моем оконном менеджере я могу перемещать окна, удерживая "левую кнопку Windows" (Left Super) и перетаскивая окно левой кнопкой мыши. Я хочу сделать это без прикосновения к клавиатуре, поэтому я хочу сопоставить левую супер-клавишу с кнопкой мыши 11, чтобы я мог удерживать кнопку мыши 11 и нажимать + перетаскивать окна.

Наиболее очевидным решением является использование xbindkeys и xte следующим образом (.xbindkeysrc):

"xte 'keydown Super_L'"
  b:11

"xte 'keyup Super_L'"
  b:11 + release

Это работает так:

  • Когда я нажимаю кнопку мыши 11, Super_L также нажимается вниз
  • Когда я отпускаю кнопку мыши 11, Super_L также освобождается

Но есть проблема: я не могу перемещать окна с помощью Super_L + Mouse1, если я также держу нажатой другую кнопку мыши, например, кнопку мыши 11. Используя приведенное выше решение, кнопка мыши 11 по-прежнему регистрируется как нажатая и отпущенная, и поэтому ни одна из операций оконного менеджера не работает.

Я пробовал это использовать Cinnamon и Awesome WM, и абсолютно ни одна из комбинаций клавиш Super_L не работает, пока нажата кнопка мыши 10 или 11.

Неподходящий хак

В настоящее время я работаю над этой проблемой, заставляя щелчок мыши 11 удерживать кнопку Super_L в течение определенного времени. That way I can click the mouse button, then drag stuff around for a brief period afterwards:

"xte 'keydown Super_L' 'usleep 250000' 'keyup Super_L'"
  b:11

Another attempt

As suggested by totti, I tried this xbindkeys конфигурация:

"xte 'mouseup 10' 'keydown Super_L'"
  b:10

"xte 'keyup Super_L'"
  b:10 + Release

Не работает It seems the Super_L key is being held down, because as soon as I release button 10 it remains held down for ever (until I press the Super_L key again on the keyboard) but the mouse button is still being registered, because I can't click&drag windows. I don't think I'm going to be able to make this work using xbindkeys а также xte,

4 ответа

В сообщении аскубунту содержится ответ, который я кратко изложу ниже.

Проблема в том, что xbindkeys захватывает всю мышь, что делает неопределенными модификаторы + отображение щелчков мыши. Ответ использует uinput через скрипт python-uinput для мониторинга /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. СИМЛИНК для поиска мыши в /dev/my_mx_mouse, читаемый группой mxgrabber,

Чтобы найти информацию об оборудовании, запустите что-то вроде:

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

Для uinput, файл /etc/udev/rules.d/94-mxkey.rules:

KERNEL=="uinput", GROUP="mxgrabber", MODE="660"

Отключите и подключите мышь или заставьте 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 library а также python-evdev library,

Приведенный ниже скрипт требует идентификации event.code кнопки:

#!/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 и убедитесь, что он загружается при запуске.

Я понял это ранее сегодня с другими ключами-модификаторами. Проблема в том, что вы должны включить модификатор в комбинацию кнопок для выпуска. Предполагая, что ваш Супер ключ сопоставлен с Mod4 (который должен быть по умолчанию, afaik):

"xte 'keydown Super_L'"
  b:11

"xte 'keyup Super_L'"
  Mod4 + b:11 + release

РЕДАКТИРОВАТЬ: только что понял, что это не полностью отвечает на ваш вопрос, так как вы все еще не сможете использовать ЛКМ, удерживая нажатой b:11

Предложение отладки: я бы попробовал следить /dev/input/eventX файл, чтобы увидеть, какие события генерируются при нажатии и отпускании этой кнопки, особенно в комбинации с BTN_LEFT, Вот пример кода, с которого можно начать. Вам, очевидно, придется изменить его, чтобы регистрировать все события, а не только нажатия клавиш.

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

Скорее всего, ваша мышь генерирует дополнительные события отпускания кнопок при нажатии нескольких кнопок. В этом случае ваши варианты будут использовать обходные пути привязки ключа или изменить xf86-input-evdev библиотека для фильтрации нежелательных событий (или имитации пропущенных). Некоторое время назад я делал нечто подобное для сенсорного экрана, который генерировал события "щелчка" при попытке перетаскивания. Идея состояла в том, чтобы отфильтровать события "выпуска", которые происходили почти одновременно (в пределах небольшого временного окна), с событиями "щелчка". Если мое предположение верно, вам, по сути, нужно реализовать нечто подобное.

Поскольку вы можете запустить скрипт одним щелчком мыши, вы можете использовать следующий трюк.
1. Нажмите кнопку 11, чтобы удерживать супер-клавишу. (Кнопка 11 запускает скрипт)
2. Перемещайте окна, используя другие кнопки мыши
3. Снова нажмите кнопку мыши 11, чтобы разблокировать супер-ключ.

скрипт
использование xdotool держать супер ключ
При первом нажатии кнопки создайте временный файл и удерживайте клавишу. При следующем нажатии удалите файл tmp и отпустите ключ,

Обновить

В соответствии со страницей помощи Ubuntu (многие кнопки мыши, как) imwheel можно переназначить на ключ.

Другие вопросы по тегам