IIO-Sensor-Proxy, Wacom Touchscreen and Auto-Rotation in Linux Mint XPS 13 (2 in 1)

The GNOME3 Desktop Environment used in Ubuntu and Fedora is more optimised for touchscreen input than many of the other Linux Desktop Environments. Most other Desktop Environments have touchscreen source but lack behind when it comes to screen-rotation of the screen itself and also the touchscreen input.

Monitor Sensor

The iio-sensor-proxy should already be incorporated into modern Linux kernels. If not use:

sudo apt install iio-sensor-proxy

Open up a terminal and type in:

monitor-sensor

The monitor-sensor should then read back from the accelerator to detect the orientation. My XPS 13 9365 is normal so the accelerator detects the normal orientation:

Turning the laptop clockwise with the left side of the screen now at the top means the accelerator detects the left-up orientation:

Returning the laptop back to normal configuration means the accelerator detects the normal orientation:

Press [Ctrl] + [ c ] to quit.

Screen

Next we can look at the output of the screen itself which can be seen using:

xrandr

For a 2 in 1 touchscreen device there will only be a single screen, Screen 0 with a list of possible displays resolutions The screen will be able to be displayed as normal, right, left or inverted:

Input Devices

The input devices in a laptop may be examined using the command:

xinput

Each laptop will have a slightly different number of devices that react to touch input:

Typically there is the response of the touchscreen itself, in this case the Wacom HID 4831 Finger Touch at id=13. There is also the screen response to any pens that can interact with the screen,in this case the Wacom HID 4831 Pen stylus and Wacom HID 4831 Pen eraser at id=12 and id=21 respectively. Finally there is also the touchpad, in this case DLL077A:01 06CB:76AF Touchpad at id=15 and the mouse in this case DLL077A:01 06CB:76AF Mouse at id=16.

We can change the screen response to a device using its full name or device id alongside a transformation matrix, for example in the normal configuration:

xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop 13 --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1

We will be able to change the orientation of a screen by using:

xrandr -0 normal

Auto-Rotation Script

Clearly when the accelerator detects an orientation, the screen and input devices should be updated to reflect changes in the sensor.

normal

xrandr -o normal
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen stylus" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen eraser" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1

right-up

xrandr -o right
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 Pen stylus" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 Pen eraser" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1

left-up

xrandr -o left
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen stylus" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen eraser" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1

bottom-up

xrandr -o inverted
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 Finger stylus" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 Finger eraser" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1

Auto-Rotation Script

We need to create a script that can read the orientation accelerator, log it to a file and then rotate the input devices if there is a change in the rotation. The script should be in a while loop and occur in the background continuously.

#!/bin/sh

killall monitor-sensor
while inotifywait -e modify /dev/shm/sensor.log; do

ORIENTATION=$(tail /dev/shm/sensor.log | grep 'orientation' | tail -1 | grep -oE '[^ ]+$')

case "$ORIENTATION" in
normal)
xrandr -o normal
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen stylus" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen eraser" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1;;
right-up)
xrandr -o right
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 Pen stylus" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 Pen eraser" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1;;
left-up)
xrandr -o left
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen stylus" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 Pen eraser" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1;;
bottom-up)
xrandr -o inverted
xinput set-prop "Wacom HID 4831 Finger touch" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 Finger stylus" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 Finger eraser" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Touchpad" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1
xinput set-prop "Wacom HID 4831 DLL077A:01 06CB:76AF Mouse" --type=float "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1;;
esac
done

Open Text Editor and copy and paste the script, modifying for your own devices. Save the file in your documents folder with the file extension .sh.

Then add the script to your Start-Up applications and reboot.