Comment mapper des modificateurs (par exemple CTRL) aux boutons du pouce de la souris à l'aide de xbindkeys

13

Cette question a déjà été posée mais n'a pas été répondue correctement. Après l'autorisation avec @Seth, je le redemande. Cela me permettra de répondre et éventuellement de modifier la question beaucoup plus facilement. La question d'origine se trouve ici:

Mapper les touches Ctrl et Alt aux boutons de la souris


Problème:

Bien qu'il soit très simple de mapper n'importe quelle frappe sur un bouton de la souris xbindkeysen conjonction avec xdotoolou xteil semble beaucoup plus problématique de lui mapper une touche de modification (par exemple ALT , CTRL , SHIFT, etc.).

La solution finale devrait permettre entre autres un CTRL + clic (par exemple pour sélectionner plusieurs entrées d'une liste) avec juste la souris.

Quelques approches possibles pour résoudre ce problème peuvent être trouvées ici sur Stack Exchange ainsi que sur d'autres forums liés à Linux. Mais aucun de ceux-ci ne fonctionne comme prévu car il entraîne d'autres problèmes et effets secondaires.

Remarques:

Certains des exemples ci-dessous impliquent Guile avec la syntaxe Scheme et s'appuient sur .xbindkeysrc.scmfile alors que d'autres s'appuient sur le .xbindkeysrcfichier avec sa syntaxe respective. Je suis conscient qu'ils ne fonctionneront pas ensemble.

De plus, les extraits ci-dessous ne reposent que sur xdotoolmais je suis ouvert à des approches impliquant d'autres applications comme par xteexemple - bien que cela semble conduire aux mêmes résultats et donc j'utilise uniquement des xdotoolactions ici.

Approche A:

Mise à jour du .xbindkeysrcfichier avec:

"xdotool keydown ctrl"
  b:8

"xdotool keyup ctrl"
  release + b:8

C'est ce que j'ai essayé au départ, mais cela a pour effet secondaire que le modificateur est maintenu et ne peut pas être libéré.

Approche B:

Mise à jour du .xbindkeysrc.scmfichier 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 où le modificateur est conservé (comme décrit à l'approche une).

Bien qu'il corrige qu'il ne fonctionne que partiellement car il n'est pas possible d'effectuer d'autres clics de souris lorsque vous appuyez sur le bouton du pouce.

Approche C:

Mise à jour du .xbindkeysrcfichier 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 plus 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 ce xbindkeyssoit le problème ici car il reconnaît le clic mais ne l'exécute pas. Cela peut être testé en utilisant xev | grep buttonet xbindkeys -v:

Un clic de souris normal enregistré par xevdevrait ressembler à:

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 xbindkeysconfiguration ci-dessus 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 n'est donc plus un bouton de souris, il est étrange que le bouton 1 ne soit pas également enregistré. C'est probablement parce xbindkeysqu'il ne l'exécute pas mais se 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 .xbindkeysrcfichier 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.


MISE À JOUR:

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

La seule autre souris dont je me souvienne qui était capable de le faire était la Razer Copperhead à l'époque. Mais je suppose qu'il existe aujourd'hui d'autres souris qui peuvent faire de même.

conceptdeluxe
la source
1
voici une solution utilisant Easystroke: askubuntu.com/a/1010647/27202
atti

Réponses:

8

J'ai passé beaucoup de temps à essayer de rendre ce travail contraignant. J'ai finalement trouvé une solution, ce qui est compliqué mais 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é, donc toute rétroaction constructive est plus que bienvenue.

Il existe des solutions qui sont vraiment sympas, comme celle proposée ici , mais elles souffrent toujours de la limitation des xbindkeys qui saisissent la souris entière, ce qui rend incertain le mappage des modificateurs + clics de souris. De plus, la solution basée sur la ruse du lien ci-dessus utilise ctrl + plus / ctrl + moins qui n'est pas reconnue par Gimp par exemple.

J'ai compris que ce que nous voulons, c'est un bouton de la souris qui fait office de clavier, j'ai donc utilisé uinput, accessible via python , écrit un script qui surveille / dev / ma-souris pour le clic du bouton du pouce et envoie la touche ctrl au clavier virtuel. Voici les étapes détaillées:

1. Créer des règles udev

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

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 recherchera 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 assure 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 devez 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/uinputou $/dev/input/uinputselon le système sur lequel vous vous trouvez. Donnez-lui simplement le groupe et les droits de lecture ET d'écriture 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. Activez le module UINPUT

sudo modprobe uinput

Et pour rendre le démarrage persistant:

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

3. Créer un nouveau groupe

sudo groupadd mxgrabber

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

sudo usermod -aG mxgrabber your_login

4. Script Python

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 bouton 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-en!

Il vous suffit maintenant 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 gratuitement

J'utilise xbindkeys pour un comportement supplémentaire. Par exemple, la configuration suivante peut être intéressante si vous avez une souris avec des clics côté roue:

~/.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 pris en compte 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 les droits pour écrire dans / dev / uinput, même si l'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 touches du clavier ou de la souris fonctionnant avec le bouton Ctrl du clavier fonctionne désormais avec celle de la souris !!

Aurélien Cibrario
la source
Merci beaucoup pour l'effort et le partager avec nous! +1 ... Bien que je ne l'ai pas encore testé. BTW J'ai presque renoncé à cela - ce serait génial si cela fonctionne comme prévu :)
conceptdeluxe
Vous êtes les bienvenus ! Pour moi, cela fonctionne parfaitement. Si vous avez des problèmes, faites le moi savoir. J'essaie de compléter ma réponse, mais comme j'ai passé près de deux jours à essayer de le faire fonctionner, j'ai peut-être oublié quelque chose. Sera heureux d'aider / modifier mon message.
Aurélien Cibrario
Je viens de réaliser que ctrl + click1 était un très mauvais choix pour fermer un onglet car il ouvrait un lien dans un nouvel onglet. J'ai édité ma réponse en supprimant la dernière partie du script python et en peaufinant avec xbindkeys, une solution plus propre
Aurélien Cibrario
je veux juste vous faire savoir que je n'ai pas encore eu le temps de le tester - mais je vais certainement en faire la réponse acceptée si cela fonctionne comme prévu - désolé pour l'attente - je suis un peu occupé atm
conceptdeluxe
Je me demande si nous pouvons utiliser le script ci-dessus pour éviter un interrupteur de souris défectueux. J'ai une souris usée. J'utilise un script autohotkey pour le corriger sous Windows mais il n'y a pas d'outil pour le corriger sous Linux. Voici le script Autohhotkey pour la correction du bouton gauche autohotkey.com/board/topic/63555-debounce-mouse-keys J'espère que quelqu'un le portera sur Linux en utilisant python3 - evdev
kenn
4

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 ~/.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'avais l'habitude xinput set-button-mapde changer le mappage des boutons xinput et d'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 mais que le bouton 8 a déjà une fonction (par exemple, page-next), vous pouvez utiliser ce qui suit.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 &

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

Maxime
la source
Mais cela n'empêche pas l'événement d'origine de se déclencher. Donc, si je mappe le bouton 8 pour le déplacer, et que je maintiens le bouton 8 dans Firefox, il essaie également de revenir à la page précédente, ce qui n'est pas souhaitable.
user23013
1
Vrai. Pour résoudre ce problème, j'ai changé l'identifiant du bouton qui m'intéressait en un bouton utilisé xinput. Voir la question modifiée.
Maxim
2

J'ai une solution partielle. Je n'ai pas compris comment démapper le bouton existant, vous vous retrouvez donc avec un clic de bouton et le modificateur que vous souhaitez. Donc, si ce bouton de la souris a une fonction existante, il se déclenchera toujours. Par exemple, remapper le bouton droit de la souris sur une touche de contrôle entraînera l'envoi d'un contrôle + clic.

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 via cela. Il semble que btnx ne soit plus disponible via le repo. Il y a un ppa, mais cela ne fonctionne pas pour le dernier ubuntu.

Message du forum: message: http://ubuntuforums.org/showthread.php?t=1245930

Mais la source est disponible:

Vous pouvez le compiler à partir des sources, mais cela mettra des fichiers sur votre système que le gestionnaire de packages ne peut pas conserver.

À 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

Donc ... si cela 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 de la source, vous pourriez également avoir besoin de build-essential:

sudo apt-get install build-essential

Puis 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 GUI 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

Exécutez maintenant l'outil:

sudo btnx-config

Cliquez sur Détecter les boutons de la souris. Si vous voulez pouvoir lire les instructions pendant que vous utilisez l'outil, redimensionnez la fenêtre qui apparaît, le texte de la boîte de dialogue est tronqué plus tard si vous ne le faites pas et si vous essayez de redimensionner pendant la détection, il annulera la détection. Agrandissez simplement la fenêtre.

Cliquez sur Appuyez pour démarrer la détection de la souris, puis essayez de ne pas déplacer la souris jusqu'à ce que le texte change ... Prend environ 5 à 10 secondes. Le texte va changer. Dans ce cas, ignorez ce qu'il dit et cliquez sur Transférer.

Cliquez sur le bouton "Appuyer 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). Ensuite, 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 tous les boutons que vous ne souhaitez pas remapper.

Une fois tous les boutons ajoutés, cliquez sur OK.

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

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

Revenez à l'écran Configurations et cliquez sur redémarrer btnx.

Essayez le nouveau bouton.

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

sudo /etc/init.d/btnx stop
cd btnx
sudo make uninstall
cd -
cd btnx-config
sudo make uninstall
cd -
Stephen
la source
2
Merci beaucoup pour la réponse détaillée que vous avez publiée sur pastebin. Mais je crains de ne pas être autorisé à utiliser un ppa non approuvé ou à créer une application à partir d'une source inconnue sans l'examiner en détail sur mon appareil. Néanmoins, je vais vous donner un vote pour l'effort que vous y avez consacré. En dehors de cela, je vous recommande de mettre à jour votre réponse ici et de copier ce que vous y avez écrit car ces informations pourraient être utiles pour les autres mais pourraient être ignorées. Enfin, j'ai lu que le paquet pourrait même ne pas se compiler sous Ubuntu ou Debian - avez-vous essayé cela en fait?
conceptdeluxe
Btw: Vous pouvez facilement gagner 100 points de réputation supplémentaires en reliant votre compte askubuntu à d'autres comptes Stack Exchange comme par exemple Linux et Unix.
conceptdeluxe
Oui, je l'ai testé sous Ubuntu 14.04. J'ai fait le bouton droit de la souris envoyer une clé de contrôle et confirmé que cela fonctionnait avant de poster. Et puis presque abandonné le poste en raison de l'exigence de réputation.
Stephen