Como mapeio adequadamente uma tecla do teclado para um botão do mouse?


14

Resumo da pergunta: Desejo que um dos botões do mouse seja registrado como o botão esquerdo do Windows Super_Lpelo X11.


No meu gerenciador de janelas, eu posso mover as janelas mantendo o "botão esquerdo do Windows" (Super à esquerda) e arrastando uma janela com o botão esquerdo do mouse. Quero poder fazer isso sem tocar no teclado, por isso quero mapear a tecla Super esquerda para o botão 11 do mouse, para que eu possa segurar o botão 11 do mouse e clicar em + arrastar janelas.

A solução mais óbvia é usar xbindkeys e xte como este ( .xbindkeysrc):

"xte 'keydown Super_L'"
  b:11

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

Isso funciona assim:

  • Quando pressiono o botão 11 do mouse, Super_Ltambém é pressionado
  • Quando solto o botão 11 do mouse, Super_Ltambém é liberado

Mas há um problema: não consigo mover as janelas usando Super_L+ Mouse1se também estiver pressionando outro botão do mouse, como o botão 11. Com a solução acima, o botão 11 do mouse ainda está sendo registrado como pressionado e liberado, e portanto nenhum as operações do gerenciador de janelas funcionam.

Eu tentei isso usando o Cinnamon e o Awesome WM, e absolutamente nenhuma das Super_Lcombinações de teclado funciona enquanto o botão 10 ou 11 do mouse está sendo pressionado.

Um corte abaixo da média

No momento, estou solucionando esse problema fazendo com que o clique do mouse 11 mantenha o Super_Lbotão pressionado por um certo período de tempo. Dessa forma, posso clicar no botão do mouse e arrastar as coisas por um breve período:

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

Outra tentativa

Como sugerido por totti, tentei esta xbindkeysconfiguração:

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

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

Isso não funciona. Parece que a Super_Ltecla está sendo pressionada, porque assim que solto o botão 10, ela permanece pressionada para sempre (até pressionar a Super_Ltecla novamente no teclado), mas o botão do mouse ainda está sendo registrado, porque não consigo clicar e arrastar as janelas . Eu não acho que vou conseguir fazer isso funcionar usando xbindkeyse xte.


1
Em vez de vincular o botão do mouse à super chave, faça o remapeamento. Para isso, use o xmodmap . consulte a página xmodmap do wiki do arch para obter uma configuração completa.
Totti 12/03/2015

@totti: A página xmodmap wiki arco descreve como mapear chaves para outras teclas, como teclas modificadoras de swap e como reverter a rolagem, mas não menciona as teclas do teclado de mapeamento para os botões do mouse
Hubro

@totti: Com o xmodmap eu posso mapear chaves para outras teclas, e com a extensão XKB para X (e xkbset) eu posso mapear botões do mouse para teclas do teclado, mas estou tentando mapear uma tecla do teclado para um botão do mouse. Ainda não encontrei uma maneira de fazer isso.
Hubro 17/03

try: Ao pressionar o botão 11 do mouse, simule a liberação do super hold + botão 11 do mouse. O gerenciador de janelas agora pode detectar Super & rato 1 não rato 11.
totti

@totti: Pergunta
experimentada

Respostas:


5

Uma postagem do askubuntu contém uma resposta que resumirei abaixo.

O problema é que xbindkeys agarra o mouse inteiro, tornando incertos os modificadores + o mapeamento de cliques do mouse. A resposta usa o uinput via script python-uinput para monitorar /dev/my-mouseo clique do botão do polegar e enviar a Ctrlchave ao teclado virtual. Aqui estão as etapas detalhadas:

1. Faça regras do udev

Para o mouse, arquivo /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"

O Udev procurará dispositivos do kernel com nomes como event5. O SYMLINK é para localizar o mouse /dev/my_mx_mouse, legível pelo grupo mxgrabber.

Para encontrar informações de hardware, execute algo como:

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

Para uinput, arquivo /etc/udev/rules.d/94-mxkey.rules:

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

Desconecte e conecte o mouse ou force o udev a ativar as regras udevadm trigger.

2. Ative o módulo UINPUT

sudo modprobe uinput

E em /etc/modules-load.d/uinput.conf:

uinput

3. Crie um novo grupo

sudo groupadd mxgrabber
sudo usermod -aG mxgrabber your_login

4. Script Python

Instale python-uinput librarye python-evdev library.

O script abaixo requer a identificação do event.code do botão:

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

Torne o arquivo python executável e verifique se ele está carregado na inicialização.


Atualizei o script para atribuir um código de chave não utilizado aos botões do mouse (eu os configurei para F13, F14e F15, e desabilito as funções do mouse usando xinput. Depois, posso simplesmente reatribuir essas chaves ao que for necessário usando um simples xmodmap. A idéia principal é esboçada em uma essência (existem alguns valores codificados e não restauro a xinputfunção do mouse posteriormente), farei um post sobre isso com a versão final do script (e compartilharei o link aqui quando isso for feito. por sua ajuda ☺ ♥!
Zmo

Verifique também a minha nova resposta no outro thread para obter uma solução baseada em x11. Askubuntu.com/a/903389/269589
Maxim

1

Como você pode executar o script com um clique do mouse, você pode usar o seguinte truque.
1. Pressione o botão 11 para segurar a tecla super . (O botão 11 aciona um script)
2. Mova as janelas usando os outros botões do mouse
3. Pressione o botão 11 do mouse novamente para soltar a tecla super

script
Use xdotoolpara manter a tecla super pressionada
No primeiro clique no botão, crie um arquivo temporário e mantenha a tecla pressionada. No próximo clique, exclua o arquivo tmp e solte a tecla

atualizar

De acordo com a página de ajuda do ubuntu (como muitos botões do mouse) imwheelpodem remapear para uma chave.


Alguns problemas com isso: # 1 Este ainda é apenas outro truque / solução alternativa e não responde à pergunta. # 2 xbindkeys não funciona enquanto a tecla super está sendo pressionada. É como se xbindkeys estivesse em pausa e não registrasse nada até que a super tecla fosse liberada.
Hubro 24/03

Ok, após cerca de 5 minutos de pesquisa, retiro o ponto 2. Aparentemente, eu tenho que adicionar + Mod4na minha configuração xbindkeys para dar conta da super chave que está sendo mantida pressionada. A solução alternativa que você sugere é melhor que a minha, e estou mudando para ela :-) Mas ainda não responde à pergunta.
Hubro 24/03

1

Sugestão de depuração: eu tentaria monitorar o /dev/input/eventXarquivo para ver quais eventos são gerados quando você pressiona e libera esse botão, especialmente em combinações com BTN_LEFT. Aqui está um código de exemplo para você começar. Obviamente, você precisará modificá-lo para registrar todos os eventos, não apenas as teclas pressionadas.

Você também pode verificar a xevsaída, se ainda não o fez. A análise dos dois logs deve revelar o problema exato que você está tendo.

As chances são de que o mouse gere eventos extras de liberação de botão quando vários botões são pressionados. Nesse caso, suas opções seriam usar soluções alternativas de ligação de chave ou modificar a xf86-input-evdevbiblioteca para filtrar eventos indesejados (ou simular os ausentes). Eu fiz algo parecido há um tempo atrás para uma tela sensível ao toque que gerava eventos de "clique" ao tentar arrastar e soltar. A idéia era filtrar eventos de "release" que surgiam quase simultaneamente (dentro de uma pequena janela de tempo) com eventos de "click". Se meu palpite estiver correto, você essencialmente precisará implementar algo semelhante.


1

Eu descobri isso hoje cedo com outras teclas modificadoras. O problema é que você deve incluir o modificador na combinação de botões da versão. Supondo que sua chave Super esteja mapeada para o Mod4 (que deve ser o padrão, depois):

"xte 'keydown Super_L'"
  b:11

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

EDIT: Acabei de perceber que isso não responde completamente à sua pergunta, pois você ainda não poderá usar o LMB enquanto pressiona b: 11

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.