Comment mapper correctement une touche du clavier à un bouton de la souris?


14

Résumé de la question: Je souhaite qu'un de mes boutons de souris soit enregistré comme bouton Windows gauche Super_Lpar X11.


Dans mon gestionnaire de fenêtres, je peux déplacer des fenêtres en maintenant le "bouton gauche de Windows" (Left Super) et en faisant glisser une fenêtre avec le bouton gauche de la souris. Je veux pouvoir le faire sans toucher au clavier, donc je veux mapper la touche Super gauche au bouton de la souris 11, de cette façon je peux maintenir le bouton 11 et cliquer + faire glisser les fenêtres.

La solution la plus évidente consiste à utiliser xbindkeys et xte comme ceci ( .xbindkeysrc):

"xte 'keydown Super_L'"
  b:11

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

Cela fonctionne comme ceci:

  • Lorsque j'appuie sur le bouton de la souris 11, Super_Lest également enfoncé
  • Lorsque je relâche le bouton de la souris 11, Super_Lest également libéré

Mais il y a un problème: je ne peux pas déplacer les fenêtres en utilisant Super_L+ Mouse1si je maintiens également un autre bouton de la souris, comme le bouton de la souris 11. En utilisant la solution ci-dessus, le bouton de la souris 11 est toujours enregistré comme pressé et relâché, et donc aucun des les opérations du gestionnaire de fenêtres fonctionnent.

J'ai essayé ceci en utilisant à la fois Cinnamon et Awesome WM, et absolument aucune des Super_Lcombinaisons de clavier ne fonctionne pendant que le bouton 10 ou 11 de la souris est maintenu enfoncé.

Un hack de qualité inférieure

Je suis actuellement en train de contourner ce problème en provoquant un clic de la souris sur le Super_Lbouton pendant un certain temps. De cette façon, je peux cliquer sur le bouton de la souris, puis faire glisser des éléments pendant une brève période après:

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

Une autre tentative

Comme suggéré par totti, j'ai essayé cette xbindkeysconfiguration:

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

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

Ça ne marche pas. Il semble que la Super_Ltouche soit maintenue enfoncée, car dès que je relâche le bouton 10, elle reste enfoncée pour toujours (jusqu'à ce que j'appuie à Super_Lnouveau sur la touche du clavier) mais le bouton de la souris est toujours en cours d'enregistrement, car je ne peux pas cliquer et faire glisser les fenêtres . Je ne pense pas que je vais pouvoir faire ce travail en utilisant xbindkeyset xte.


1
Au lieu de lier le bouton de la souris à la super clé, effectuez un remappage. Pour cela, utilisez xmodmap . voir la page arch wiki xmodmap pour une configuration complète.
totti

@totti: La page arch wiki xmodmap décrit comment mapper des touches à d'autres touches, comment échanger des touches de modification et comment inverser le défilement, mais elle ne mentionne pas le mappage des touches du clavier aux boutons de la souris
Hubro

@totti: Avec xmodmap, je peux mapper des touches à d'autres touches, et avec l'extension XKB pour X (et xkbset), je peux mapper des boutons de souris à des touches de clavier, mais j'essaie de mapper une touche de clavier à un bouton de souris. Je n'ai toujours pas trouvé de moyen de le faire.
Hubro

essayer: En maintenant le bouton 11 de la souris enfoncé, simulez le maintien super + le relâchement du bouton 11 de la souris. Le gestionnaire de fenêtres peut maintenant détecter les super & souris 1 et non la souris 11.
totti

@totti: Question testée et modifiée
Hubro

Réponses:


5

Un post askubuntu contient une réponse que je résumerai ci-dessous.

Le problème est que xbindkeys saisit la souris entière, rendant le mappage des modificateurs + clics de souris incertain. La réponse utilise uinput via un script python-uinput pour surveiller /dev/my-mousele clic du bouton du pouce et envoyer la Ctrlclé au clavier virtuel. Voici les étapes détaillées:

1. Créer des règles udev

Pour la souris, limez /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 les périphériques du noyau avec des noms comme event5. Le SYMLINK sert à trouver la souris /dev/my_mx_mouse, lisible par le groupe mxgrabber.

Pour trouver des informations sur le matériel, exécutez quelque chose comme:

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

Pour uinput, fichier /etc/udev/rules.d/94-mxkey.rules:

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

Débranchez et branchez votre souris, ou forcez udev à déclencher les règles avec udevadm trigger.

2. Activez le module UINPUT

sudo modprobe uinput

Et dans /etc/modules-load.d/uinput.conf:

uinput

3. Créer un nouveau groupe

sudo groupadd mxgrabber
sudo usermod -aG mxgrabber your_login

4. Script Python

Installez python-uinput libraryet python-evdev library.

Le script ci-dessous nécessite d'identifier le code événementiel du 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. Finition

Rendez le fichier python exécutable et assurez-vous qu'il est chargé au démarrage.


J'ai mis à jour le script pour attribuer un code clé inutilisé aux boutons de la souris (je les ai configurés pour F13, F14et F15, et désactiver les fonctions de la souris en utilisant xinput. Ensuite, je peux simplement réaffecter ces clés à tout ce dont j'ai besoin en utilisant un simple xmodmap. L'idée principale est rédigée dans un sens (il y a des valeurs codées en dur et je ne restaure pas la xinputfonction de la souris par la suite), je ferai un blog à ce sujet avec la version finale du script (et partagerai le lien ici quand ce sera fait. Merci vous pour votre aide! ♥ ♥
zmo

Consultez également ma nouvelle réponse sur l'autre thread pour une solution basée sur x11 askubuntu.com/a/903389/269589
Maxim

1

Comme vous pouvez exécuter le script sur un clic de souris, vous pouvez utiliser l'astuce suivante.
1. Appuyez sur le bouton 11 pour maintenir la super touche . (Le bouton 11 déclenche un script)
2. Déplacez les fenêtres à l'aide des autres boutons de la souris
3. Appuyez à nouveau sur le bouton 11 pour relâcher la super touche

script
Utilisez xdotoolpour maintenir la super touche
Au premier clic sur le bouton, créez un fichier temporaire et maintenez la touche. Au prochain clic, supprimez le fichier tmp et relâchez la clé,

mise à jour

Selon la page d'aide d'ubuntu (comment faire de nombreux boutons de souris), vous imwheelpouvez remapper une clé.


Quelques problèmes avec cela: # 1 Ce n'est encore qu'un autre hack / solution de contournement, et ne répond pas à la question. # 2 xbindkeys ne fonctionne pas pendant que la super clé est maintenue enfoncée. C'est comme si xbindkeys était en pause et n'enregistrait rien jusqu'à ce que la super clé soit libérée.
Hubro

Ok, après environ 5 minutes de recherche, je retire le point # 2. Apparemment, je dois ajouter + Mod4ma configuration xbindkeys pour tenir compte de la super clé maintenue enfoncée. La solution de contournement que vous proposez est meilleure que la mienne, et j'y passe :-) Mais cela ne répond toujours pas à la question.
Hubro

1

Suggestion de débogage: j'essaierais de surveiller le /dev/input/eventXfichier pour voir quels événements sont générés lorsque vous appuyez et relâchez ce bouton, en particulier en combinaison avec BTN_LEFT. Voici un exemple de code pour vous aider à démarrer. Vous devrez évidemment le modifier pour enregistrer tous les événements, pas seulement les appuis sur les touches.

Vous pouvez également vouloir vérifier la xevsortie, si vous ne l'avez pas déjà fait. L'analyse des deux journaux devrait révéler le problème exact que vous rencontrez.

Il est probable que votre souris génère des événements de relâchement de bouton supplémentaires lorsque plusieurs boutons sont enfoncés. Dans ce cas, vos options seraient d'utiliser des solutions de contournement de liaison de clés ou de modifier la xf86-input-evdevbibliothèque pour filtrer les événements indésirables (ou simuler ceux qui manquent). J'ai fait quelque chose de similaire il y a quelque temps pour un écran tactile qui générait des événements de "clic" lorsque j'essayais de faire glisser et déposer. L'idée était de filtrer les événements de «libération» qui arrivaient presque simultanément (dans une petite fenêtre de temps) avec des événements de «clic». Si ma supposition est correcte, vous devrez essentiellement implémenter quelque chose de similaire.


1

J'ai compris cela plus tôt dans la journée avec d'autres touches de modification. Le problème est que vous devez inclure le modificateur dans la combinaison de boutons de la version. En supposant que votre clé Super est mappée sur Mod4 (qui devrait être la valeur par défaut, afaik):

"xte 'keydown Super_L'"
  b:11

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

EDIT: Je viens de réaliser que cela ne répond pas complètement à votre question car vous ne pourrez toujours pas utiliser LMB tout en maintenant b: 11

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.