web-dev-qa-db-fra.com

Comment mapper des modificateurs (par exemple CTRL) sur des boutons de la souris à l’aide de xbindkeys

Cette question a déjà été posée mais n’a jamais été traitée correctement. Après dédouanement avec @Seth, je le demande à nouveau. Cela me permettra de répondre et éventuellement de modifier la question beaucoup plus facilement. La question initiale peut être trouvée ici:

Ctrl et Alt pour les boutons du pouce de la souris


Problème:

Bien qu'il soit très simple de mapper n'importe quelle frappe sur un bouton de la souris en utilisant xbindkeys en conjonction avec xdotool ou xte, il semble beaucoup plus problématique de mapper une touche de modification (par exemple ALT, CTRL, DÉCALER etc.).

La solution finale devrait permettre i.a. a CTRL + cliquez (par exemple, pour sélectionner plusieurs entrées d'une liste) à l'aide de la souris.

Quelques solutions possibles à ce problème peuvent être trouvées ici à Stack Exchange ainsi que sur d'autres forums liés à Linux. Mais aucun de ceux-ci ne fonctionne comme prévu car ils mènent à d'autres problèmes et effets secondaires.

Notes:

Certains des exemples ci-dessous impliquent Guile avec Schéma et s'appuient sur le fichier .xbindkeysrc.scm alors que d'autres s'appuient sur le fichier .xbindkeysrc avec sa syntaxe respective. . Je suis conscient qu'ils ne travailleront pas ensemble.

De plus, les extraits ci-dessous ne s'appuient que sur xdotool mais je suis ouvert aux approches impliquant d'autres applications comme par exemple. xte également - bien qu'il semble que les deux conduisent aux mêmes résultats et, par conséquent, j'utilise uniquement les actions xdotool ici.

Approche A:

Mise à jour du fichier .xbindkeysrc avec:

"xdotool keydown ctrl"
  b:8

"xdotool keyup ctrl"
  release + b:8

C’est ce que j’ai essayé au départ, mais c’est que le modificateur est en attente et ne peut pas être publié.

Approche B:

Mise à jour du fichier .xbindkeysrc.scm avec:

(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")

Trouvé à http://www.linuxforums.org/forum/hardware-peripherals/169773-solved-map-mouse-button-modifier-key.html et tente de résoudre le problème du modificateur détenu (comme décrit à l'approche a).

Bien qu'il soit corrigé, cela ne fonctionne que partiellement car il n'est pas possible d'effectuer d'autres clics de souris tant que le bouton du pouce est enfoncé.

Approche C:

Mise à jour du fichier .xbindkeysrc avec:

"xdotool keydown ctrl"
  b:8

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

Essayé par OP de la question liée ici à askubuntu. Beaucoup plus simple et solide car il n’implique pas d’états modificateurs. Néanmoins, le problème persiste, c’est-à-dire qu’un clic CTRL + ( n’est pas possible.

Il semble que xbindkeys soit le problème car il reconnaît le clic mais ne l'exécute pas. Ceci peut être testé avec xev | grep button et xbindkeys -v:

Un clic de souris normal enregistré par xev devrait ressembler à ceci:

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

Ainsi que pour le bouton du pouce:

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

Mais lorsque la configuration ci-dessus xbindkeys est activée, elle n'enregistre rien. Bien que cela ait du sens pour le bouton du pouce car il est mappé sur CTRL et que ce n'est donc plus un bouton de la souris, il est étrange que le bouton 1 n'est pas également enregistré. C'est probablement parce que xbindkeys ne l'exécute pas mais le reconnaît lui-même:

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

Approche D:

Mise à jour du fichier .xbindkeysrc avec:

"xdotool keydown ctrl"
  b:8

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

"xdotool click 1"
  b:1

Tout simplement trop simple ... mais conduit à une boucle infinie de clics.


UPDATE:

Entre-temps, j'ai acheté un Logitech G502 et remarqué qu'une fois configuré via le pilote sous Windows, le profil lui-même est stocké dans la mémoire de l'appareil, mais la pression sur la touche est effectuée à l'aide de la souris. Cela a en fait résolu mon problème sous Linux!

La seule autre souris que je me souvienne qui ait pu le faire était la Razer Copperhead de l’époque. Mais je suppose qu'il existe d'autres souris disponibles aujourd'hui qui peuvent faire la même chose.

13
conceptdeluxe

J'ai passé beaucoup de temps à essayer de faire en sorte que la liaison fonctionne. J'ai finalement trouvé une solution compliquée mais qui fonctionne bien et n'implique pas de logiciel tiers. Je le partage ici en espérant que cela aidera les gens. En outre, je sais que ce n’est pas parfait en termes de sécurité, toute réaction constructive est donc la bienvenue.

Il y a des solutions qui sont vraiment gentilles, comme celle proposée ici , mais il souffre toujours de la limitation des xbindkeys qui saisissent la souris entière, rendant incertains les modificateurs et les correspondances de souris. De plus, la solution basée sur la guile du lien ci-dessus utilise les touches Ctrl + Plus/Ctrl + Moins qui ne sont pas reconnues par Gimp, par exemple.

J'ai compris que ce que nous voulions, c'est un bouton de souris agissant comme un clavier. J'ai donc utilisé uinput, auquel on peut accéder via python , a écrit un script qui surveille/dev/ma-souris pour le pouce Cliquez sur le bouton et envoyez la touche Ctrl au clavier virtuel. Voici les étapes détaillées:

1. Établissez des règles pour udev

Nous voulons que les appareils soient accessibles (droits et emplacement).

Pour la souris:

/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 va rechercher un périphérique reconnu par le noyau avec des noms comme event5, et je sélectionne ma souris avec le nom. L’instruction SYMLINK garantit que je trouverai ma souris dans/dev/my_mx_mouse. L'appareil sera lisible par un membre du groupe "mxgrabber".

Pour trouver des informations sur votre matériel, vous devriez exécuter quelque chose comme:

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

Pour uinput:

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

Pas besoin de lien symbolique, uinput sera toujours dans $/dev/uinput ou $/dev/input/uinput en fonction du système sur lequel vous êtes. Donnez-lui simplement le groupe et les droits de lire ET d’écrire, bien sûr.

Vous devez débrancher - branchez votre souris et le nouveau lien devrait apparaître dans/dev. Vous pouvez forcer udev à déclencher vos règles avec $udevadm trigger

2. Activer le module UINPUT

Sudo modprobe uinput

Et pour le rendre persistant au démarrage:

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

3. Créer un nouveau groupe

Sudo groupadd mxgrabber

Ou ce que vous avez appelé votre groupe d'accès. Ensuite, vous devriez vous y ajouter:

Sudo usermod -aG mxgrabber your_login

4. Python script

Vous devez installer la bibliothèque python-uinput (évidemment) et la bibliothèque python-evdev . Utilisez pip ou votre package de distribution.

Le script est assez simple, il vous suffit d’identifier le code event.code de votre bouton.

#!/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. Profitez!

Tout ce dont vous avez besoin maintenant, c'est de rendre votre fichier python exécutable et de demander à votre gestionnaire de bureau de charger le fichier au démarrage. Peut-être aussi un verre de vin pour célébrer le bon travail!

6. Extra gratuit

J'utilise xbindkeys pour un comportement supplémentaire. Par exemple, la configuration suivante peut être Nice si vous avez une souris avec des clics latéraux:

~/.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

Pour que cette dernière combinaison fonctionne , vous devez désactiver le bouton que vous avez configuré pour le script python , sinon il sera toujours saisi par xbindkeys. Seule la touche Ctrl doit rester:

~/.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

Recharger avec $ xmodmap ~/.Xmodmap

7. Conclusion

Comme je l'ai dit au début, je ne suis pas parfaitement satisfait du fait que je dois me donner le droit d'écrire à/dev/uinput, même si on pense au groupe "mxgrabber". Je suis sûr qu'il existe un moyen plus sûr de le faire, mais je ne sais pas comment.

Du côté positif, cela fonctionne vraiment, vraiment bien. Toute combinaison de clavier ou de touche de souris fonctionne comme ceci avec le bouton Ctrl du clavier. une de la souris !!

8
Aurélien Cibrario

J'ai trouvé une solution avec PyUserInput . Cela finit par être assez simple et ne nécessite pas de droits d’administration. Avec python 2 et PyUserInput installés, j'ai utilisé le script suivant:

#!/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()

Après avoir donné les droits d'exécution au script, je l'appelle avec une ligne dans ~/.xsessionrc, par exemple

~/chemin/vers/script.py &

Remarque . cela n'empêche pas le déclenchement de l'événement du bouton de la souris. Dans mon cas, j’ai utilisé xinput set-button-map pour modifier le mappage du bouton xinput et attribuer le numéro du bouton qui m’intéressait à quelque chose qui n’était pas utilisé.

Par exemple, si vous souhaitez utiliser le bouton 8 de votre souris alors que le bouton 8 a déjà une fonction (par exemple, page-next), vous pouvez utiliser le .xsessionrc suivant.

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 &

le bouton fourni 12 n'a aucune signification pour le système d'exploitation et attribue une fonction personnalisée au bouton 12 dans .xbuttonmodifier.py, le script que j'ai décrit ci-dessus.

3
Maxim

J'ai une solution partielle. Je n'ai pas trouvé comment supprimer le mappage du bouton existant, vous vous retrouvez donc avec un clic de bouton et le modificateur souhaité. Donc, si ce bouton de la souris a une utilité existante, il sera toujours déclenché. Par exemple, si vous remappez le bouton droit de la souris sur une touche de contrôle, un contrôle + clic sera envoyé.

Quoi qu'il en soit, j'ai trouvé un message de forum similaire à votre question, pour lequel la réponse était d'installer btnx et de configurer vos modificateurs à travers cela. Il semble que BTNX n'est plus disponible via le repo. Il existe un ppa, mais cela ne fonctionne pas pour le dernier Ubuntu.

Message du forum: post: http://ubuntuforums.org/showthread.php?t=12459

Mais la source est disponible:

Vous pouvez le compiler à partir des sources, mais cela placera sur votre système des fichiers que le gestionnaire de paquets ne peut pas gérer.

À savoir, les fichiers suivants:

/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

Les liens symboliques suivants:

/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

Alors ... si ça ne vous dérange pas de construire à partir de la source ...

Obtenez les dépendances pour btnx:

Sudo apt-get install libdaemon-dev git

Si vous n'avez jamais rien construit à partir des sources, vous aurez peut-être également besoin de la compilation:

Sudo apt-get install build-essential

Ensuite, récupérez et compilez btnx:

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

Il dispose d'un outil de configuration graphique distinct. Obtenez les dépendances pour cela:

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

Maintenant, récupérez et compilez l’outil de configuration gui:

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

Maintenant, lancez l'outil:

Sudo btnx-config

Cliquez sur Détecter les boutons de la souris. Si vous souhaitez pouvoir lire les instructions tout en utilisant l'outil, redimensionner la fenêtre qui apparaît, le texte de la boîte de dialogue sera tronqué ultérieurement si vous ne le faites pas et si vous essayez de le redimensionner lors de la détection, il sera annulé. la détection. Rendez la fenêtre un peu plus grande.

Cliquez sur Appuyez sur pour lancer la détection de la souris, puis essayez de ne pas déplacer la souris tant que le texte ne change pas ... Cela prend environ 5 à 10 secondes. Le texte va changer. Lorsque c'est le cas, ignorez ce qu'il dit et cliquez sur Transférer.

Cliquez sur le bouton "Appuyez pour démarrer la détection du bouton"

Ici, vous cliquerez plusieurs fois sur un bouton de votre souris (jusqu'à ce que la barre d'état se remplisse). Puis définissez le nom du bouton sur quelque chose que vous reconnaîtrez plus tard (ex: LeftButton) Cliquez sur le bouton Ajouter.

Répétez cette opération pour chaque bouton de la souris (n'oubliez pas les molettes de défilement, les clics de défilement, etc.). Vous pouvez probablement ignorer les boutons que vous ne souhaitez pas remapper.

Lorsque vous avez ajouté tous les boutons, cliquez sur OK.

Dans l'interface graphique principale, cliquez sur Boutons, dans le volet de gauche, sélectionnez le bouton que vous souhaitez remapper. Il utilisera les noms que vous avez entrés aux étapes précédentes. Pour vos besoins, vous ne devez sélectionner qu'un modificateur de touche sous Combinaison de touches à droite.

Ne cliquez pas sur supprimer sur cet écran, le bouton sera supprimé. Vous devrez revenir en arrière et détecter à nouveau le bouton si vous le faites.

Retournez à l'écran Conrigurations et cliquez sur restart btnx.

Essayez le nouveau bouton.

Si vous souhaitez désinstaller les applications, arrêtez le programme btnx, puis allez dans les répertoires respectifs de git extraits et effectuez une désinstallation:

Sudo /etc/init.d/btnx stop
cd btnx
Sudo make uninstall
cd -
cd btnx-config
Sudo make uninstall
cd -
2
Stephen