Bind Alt+Tab to a Logitech mouse button on Kubuntu

Note: this is not a duplicate of either this or this, as I will make clear.

I have a Logitech Proteus Core mouse. Under Windows 10, I have set one of its buttons (the small one labeled "G9" on top of the mouse) to show a task list, which can be brought up using the Win+Tab keys. Note that this stays up even if you release both the Win and the Tab keys, it only goes away once you click on the Window you want to go to. So the workflow is: push and release the G9 mouse button, click the window I want.

I want a similar behavior under Kubuntu 15.04. AFAIK, there is no way to bring up a similar task list, which stays up until you click on something, without having to hold down any keys.

So my idea was to emulate Alt+Tab with this button. The workflow I have in mind is: push G9 (shortcut for "push alt, push tab, realease tab") => select the window I want, release G9 (shortcut for "release alt").

The problem is that, as far as I can tell, this G9 button is not being read by the OS as a normal mouse button. If I run:

xbindkeys -mk

And click the G9 button, I get this output:

"(Scheme function)"
m:0x40 + c:23
Mod4 + Tab
"(Scheme function)"
m:0x40 + c:133
Mod4 + Super_L

Note: I am running this in a VM for testing purposes. Let me know if that can affect things, although I'd need it to work in this case as well.

If I run:

xev | grep button

I get no output when I click the G9 button I'm interested in. If I click other buttons, I get expected outputs like:

state 0x0, button 2, same_screen YES

This is weird, but I thought I could just add what xbindkeys -mk outputs to my ~/.xbindkeysrc:

"xte 'keydown Alt_L' 'key Tab'"
  m:0x40 + c:23 + Release

Obviously, even if this worked, it wouldn't do what I want it to, but it doesn't even work. Nothing happens when I click the G9 button after running:

xbindkeys -v -n

Which gives this warning:

Please verify that there is not another program running which captures one of the keys captured by xbindkeys. It seems that there is a conflict, and xbindkeys can't grab all the keys defined in its configuration file.

If I type the xte command in the console, it brings up the task selection alt+tab menu. Nothing for the bound mouse button however.

If I assign the same xte call to another button, one that's shown by the xev output (I tried the right mouse button), it's still not executed (it seems like only the tab is executed, as it tabs things in the text editor), but the warning is gone, and the regular function of the button is also gone:

How can I get the Alt+Tab behavior I described when clicking the G9 button? What about another button, one that xev detects, like b:3?

Note: this mouse saves the configuration made from its Windows software internally. So all my other buttons keep their functions in the VM: back/forward in browser, switch browser tabs etc. The Logitech software allows macro recordings in Windows, but it doesn't allow specifying different actions for push / release events, AFAIK.

If there is a way to record the right macro under Windows, or there is a way to simplify what I want to achieve under Kubuntu - that is, use the G9 button to get similar functionality to alt+tab -, I would also accept those solutions.


evrouter can help to do that. It will even allow to release G9 before selecting the task from the list.

http://www.bedroomlan.org/projects/evrouter

I've built it from source and installed with checkinstall, but there is something that looks like a repository there.

Hooks

It can be configured in the ~/.evrouterrc:

"Logitech Gaming Mouse G300" "/dev/input/event.*" any key/272 "SHELL//home/velkan/click.sh"

"Logitech Gaming Mouse G300" "/dev/input/event.*" any key/275 "SHELL//home/velkan/atab.sh"

Running sudo evrouter -d /dev/input/event* and clicking around will help to compose these lines.

"Logitech Gaming Mouse G300" is the name of my mouse.

"/dev/input/event.*" means that input will be intercepted regardless of the name of device file to which the mouse is bound.

any - means that the event will be accepted with any Alt/Ctrl/Shift modifier.

key/272 - left mouse button.

key/275 - back mouse button (on G4 for me).

"SHELL//home/velkan/click.sh" - run /home/velkan/click.sh when that event occurs.

Alt-Tab scripts

So, the /home/velkan/atab.sh script (that is bound to G4 in this case):

#!/bin/bash

mktemp /tmp/evr-alt-tab-XXXX

/usr/bin/xte 'usleep 100000' 'keydown Alt_L' 'usleep 50000' 'key Tab'

It creates a temporary file that will inform the click.sh (bound to the left button) that it needs to release Alt.

click.sh script:

#!/bin/bash

if [ -e /tmp/evr-alt-tab-???? ]; then
    /usr/bin/xte 'usleep 100000' 'keyup Alt_L'
    rm /tmp/evr-alt-tab-????
fi

Activating evrouter on startup

Haven't tried that on KDE.

Launch script /usr/local/sbin/evrouter_launch.sh:

#!/bin/sh
/usr/local/bin/evrouter /dev/input/event* 0<&- > /dev/null

(or it may be /usr/bin/evrouter instead of /usr/local/bin/evrouter)

Config /etc/lightdm/lightdm.conf to start evrouter with the desktop manager:

[SeatDefaults]
autologin-user=
session-setup-script=/usr/local/sbin/evrouter_launch.sh

I got it done using ideas from Velkan's answer. I'll list the necessary steps.

  1. First of all, the Win+Tab macro I had set on the G9 button in Windows was interfering with how Linux detects the mouse. Instead of detecting the mouse button, it simply detected the Win and Tab keys in xev. I believe the mouse is internally set to send these if you configure the button as a "Multikey Macro" in its Windows software.

    To fix this, don't set the button to use a Multikey Macro in Windows. Set it to anything else. I set it to be a middle click.

  2. Now, xev | grep button detected the G9 as button 2.

  3. I wrote this script in ~/alttab.sh, which is a combination of Velkan's scripts:

    #!/bin/bash
    
    if [ -e /tmp/alt-tab-mouse-script-???? ]; then
       xte 'usleep 100000' 'keyup Alt_L'
       rm /tmp/alt-tab-mouse-script-????
    else
       mktemp /tmp/alt-tab-mouse-script-XXXX
       xte 'usleep 100000' 'keydown Alt_L' 'usleep 50000' 'key Tab'
    fi
    
  4. I added this in my ~/.xbindkeysrc. We need two lines to make the click work in both states: when alt is down and when it isn't.

    "~/alttab.sh"
      b:2 + Release 
    
    "~/alttab.sh"
      Alt + b:2
    

This worked great for me. The flow is: click G9 (push and release), select the window you want (left click or mouse wheel), then click G9 again to go to that Window. You can modify the first if in the .sh file to also send a mouseclick 1 before keyupping alt, if you want to go directly to the window you click on with the G9 button in the windows display.

I also experimented with removing the usleep calls. It worked for me without them.

The behavior is not exactly like the Windows one, but I find it close enough. Perhaps even more convenient, since you can make the selection with the same button, so you don't have to move your finger to another button!