UPDATE: The code shown here is not up to date anymore. See Touchgreat for an up to date post.
Ok, the title is not really good but I have no idea how to call it. I want to switch workspace with a 4-finger swipe, but not the simple way. All programms that feature this functionality simple execute a key combination that then switches the workspace. I want to really move the workspace with the swipe, like on a mac. look
Configuring Compiz
I don’t know if it is possible to do it without compiz because you need to be able to set very specific settings. With the “Rotate Cube” plugin it is possible to initiate a cube rotion with a key combination and then rotate the cube with the mouse. This is the thing that is important for this to work.
libinput
The best way on a modern linux system to recognize gestures is libinput. But for example in my ubuntu repository is version 1.2.x. This version is very old and does not work really good. I compiled version 1.5.2 from source, there are many tutorials out there for changing from synaptics to libinput.
libinput-debug-events
With libinput-debug-events it is possible to print all events that libinput registers. When swiping with multiple fingers the output looks like this:
There is a GESTURE_SWIPE_BEGIN event, then multiple GESTURE_SWIPE_UPDATE and at the end a GESTURE_SWIPE_END.
So it should be possible to catch the BEGIN initiate a cube rotation with xdotool, rotate the cube and on an END stop the cube rotation. The only problem is that mouse doesn’t move when swiping, so this also must be done with xdotool
The user must be in the group input
1
sudo gpasswd -a $USER input
Log off and back in afterwards.
xdotool
With the xdotool it is possible to simulate key events, mouse events and many other things.
The following script rotates the cube:
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
xdotool keydown Control_L+Alt_L mousedown 1; # initiate the cube rotation
sleep 0.2; xdotool mousemove_relative -- -100 0; # move the mouse -100px on the x
sleep 0.2; xdotool mousemove_relative -- -100 0;
sleep 0.2; xdotool mousemove_relative -- -100 0;
sleep 0.2; xdotool mousemove_relative -- -100 0;
sleep 0.2; xdotool mousemove_relative -- -100 0;
sleep 0.2; xdotool mousemove_relative -- -100 0;
sleep 0.2; xdotool mousemove_relative -- -100 0;
xdotool mouseup 1 keyup Control_L+Alt_L; # stop the cube rotation
The plan
So this is my plan:
Grab the GESTURE_PINCH_BEGIN event from libinput-debug-events and start the cube rotation with xdotool
On GESTURE_PINCH_UPDATE move the mouse with xdotool
Stop the switching on GESTURE_PINCH_END
The code
I will just drop the code here and describe it with comments: