Menu for choosing screen orientation on a tablet computer
Overview
I found some great sources on the Internet for how to set up a menu for choosing screen orientation on a tablet computer that doesn't have gyros or other sensors to orient the screen "up." My solution involves a number of scripts, a .desktop file, and some config entries in a few spots.
Design
I wanted a menu, with arrows, where the user selects the arrow that points up. So the current screen orientation will affect the chosen value. Research on the Internet showed that I will need to rotate the tablet input and optionally the wallpaper. My environment uses fluxbox, so the architecture will hardcode in fluxbox controls but obviously this can be adapted as needed.
Dependencies
- yad
- xrandr
- xinput
- fbsetbg (optional)
- mktrayicon (optional)
Files involved
I placed all the scripts in /usr/local/bin
. The desktop file is placed in /usr/share/applications
.
Files modified
/etc/rc.local
~/.fluxbox/keys
New files
rotate-menu.sh
rotate.sh
rotate-wallpaper.sh
rotate-trayicon.sh
rotate-trayicon.desktop
Rotate menu
The main GUI is in rotate-menu.sh
. This script uses yad (because it had way fewer dependencies than zenity) to generate a simple window with buttons. The chosen orientation is calculated relative to the current orientation, and the true orientation is passed to the Rotate script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
Rotate
The actual rotation logic is stored in a separate script, rotate.sh
. Decoupling the UI from the functions is always useful, particularly for someone who wants to run arbitary rotation commands. This script rotates the X screen, and also the stylus, eraser (other end of the stylus?), and touch inputs. Without the input rotations, hilarity can ensue. You should try it sometime just to see what it's like.
#/bin/sh
# File: rotate.sh
# Locations:
# /usr/local/bin/
# Author: bgstack15
# Startdate: 2021-10-20
# SPDX-License-Identifier: GPL-3.0
# Title: Rotate display and inputs
# Purpose: Rotates X display and also the inputs
# History:
# Usage:
# rotate.sh [left|right|normal|inverted]
# Called from rotate-menu.sh, which calculates which of the directions to use.
# Reference:
# https://forums.linuxmint.com/viewtopic.php?t=110395
# Improve:
# Dependencies:
# xinput
test -z "${DISPLAY}" && { echo "Fatal! Need DISPLAY set. Aborted." 1>&2 ; exit 1 ; }
test -z "${ROTATE_WALLPAPER_SCRIPT}" && ROTATE_WALLPAPER_SCRIPT=/usr/local/bin/rotate-wallpaper.sh
orientation="${1}"
case "${orientation}" in
normal) wacom_orientation="none" ;;
inverted) wacom_orientation="half" ;;
left) wacom_orientation="ccw" ;;
right) wacom_orientation="cw" ;;
*) echo "Invalid orientation ${orientation}. Aborted." 1>&2 ; exit 1 ;;
esac
# collect stylus, touch, and eraser IDs
xi="$( xinput list )"
stylus="$( echo "${xi}" | awk '/stylus.*slave.*pointer/{print}' | awk -F'=' '{print $2}' | awk '{print $1}' )"
touch="$( echo "${xi}" | awk '/touch.*slave.*pointer/{print}' | awk -F'=' '{print $2}' | awk '{print $1}' )"
eraser="$( echo "${xi}" | awk '/eraser.*slave.*pointer/{print}' | awk -F'=' '{print $2}' | awk '{print $1}' )"
# MAIN
xrandr -o "${orientation}"
"${ROTATE_WALLPAPER_SCRIPT}"
xsetwacom set "${stylus}" rotate "${wacom_orientation}"
xsetwacom set "${touch}" rotate "${wacom_orientation}"
xsetwacom set "${eraser}" rotate "${wacom_orientation}"
Rotate wallpaper
For additional aesthetic value, I decided to build a script that rotates the wallaper. The admin can establish symlinks in directory /etc/installed/wallpapers
, named the same as the orientations that X reports (normal, inverted, left, right). The symlinks can point to whatever you want.
$ cd /etc/installed/wallpapers
$ ln -s wallpaper_wide.jpg normal
$ ln -s wallpaper_wide.jpg inverted
$ ln -s wallpaper_tall.jpg left
$ ln -s wallpaper_tall.jpg right
The script rotate-wallpaper.sh
uses these symlinks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Tray icon
The configurations described below set up the hardware "Screen rotate" button to trigger rotate-menu.sh
. My hardware doesn't always register presses of the button, so I wanted to add a software button. This script, rotate-trayicon.sh
, uses mktrayicon to make a simple icon that runs the main GUI when clicked.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Tray icon menu entry
In case the trayicon needs to be started from the application menu, here is my rotate-trayicon.desktop
file.
[Desktop Entry]
Comment=Tray icon for asking user the desired screen orientation
Exec=rotate-trayicon.sh
Categories=Utility;TrayIcon;
GenericName=Display orientation helper tray icon
Icon=display
Keywords=display;rotate;
Name=Rotate-menu tray icon
Terminal=false
Type=Application
Configurations
To take advantage of my specific hardware's rotate-screen button, I had to assign the scancode to a keycode. References [1][1] and [2][2] are great for describing how to assign a keycode to a scancode (what happens when you press a button). If you need a reminder, use xev(1)
and showkey(1)
.
Once you know the scancode for your button, set up the setkeycode command in /etc/rc.local
.
setkeycodes 6c 132
And then in ~/.fluxbox/keys
I used this directive.
140 :Exec /usr/local/bin/rotate-menu.sh
Yes, for some reason the setkeycode and code that Fluxbox uses are not the same. I don't know why, unless one of them is not base10 or something. But I got it to work, some of the time anyway.
Comments