New command line options and functionality.

- Orientation can be get from the accelerometer or the current screen orientation (`rotate-screen` or `rotate-screen screen`).
- Orientation can be switched to the next orientation (`rotate-screen next`: normal->left->inverted->right->normal or `rotate-screen previous`).
- Orientation can be specified at the command line (`rotate-screen normal|left|inverted|right`).

I hope this covers most use cases!
This commit is contained in:
sphh 2021-05-19 10:19:29 +00:00 committed by GitHub
parent 9c3e761bc4
commit 3ed56ea599
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -16,33 +16,141 @@
# Run as root: NO
# Run in alternate directory: NO
#
# Anchestors:
# A possible .desktop file can look like this:
# [Desktop Entry]
# Encoding=UTF-8
# Version=1.0
# Name=Rotate
# Comment=Rotate Screen
# Type=Application
# Exec=rotate-screen
# Icon=rotation-allowed-symbolic
# Terminal=false
# Categories=Settings
# StartupNotify=true
# and could be saved in ~/.local/share/applications/rotate-screen.desktop
#
# Anchestors and ideas:
# mildmojo
# https://gist.github.com/mildmojo/48e9025070a2ba40795c
# mbinnun:
# https://gist.github.com/mildmojo/48e9025070a2ba40795c#gistcomment-2694429
#
# frgomes:
# https://github.com/frgomes/bash-scripts/blob/develop/bin/rotate
# Check for commands needed
GDBUS=$(which gdbus)
if test -z $GDBUS; then
echo "Command 'gdbus' not found."
exit 1
fi
XINPUT=$(which xinput)
if test -z $XINPUT; then
echo "Command 'xinput' not found."
exit 2
fi
XRANDR=$(which xrandr)
if test -z $XRANDR; then
echo "Command 'xrandr' not found."
fi
GDBUS=gdbus
XINPUT=xinput
XRANDR=xrandr
get_orientation () {
usage () {
# Display the usage
#
# No options
cat <<EOF
$(basename $0) [-h|--help] [screen|next|previous|normal|left|inverted|right]
Rotate the screen and all pointing devices (touchscreens, pens, touchpads, ...)
The script can handle the following typical use cases:
1. One-shot rotation (automatic detection):
You hold the device in the new orientation desired and invoke this script.
The screen and all pointing devices rotate.
Usage:
- Disable automatic screen rotation in the settings for your desktop
environment.
- Hold the device in the new orientation and call this script with "$0".
Pre-requisites:
Programs: $GDBUS, $XINPUT, $XRANDR
Hardware: Accelerometer
Package: iio-sensor-proxy
2. Automatic screen rotation, but pointing devices do not rotate:
The orientation of the screen is set by the desktop environment, but the
pointing devices are not.
Usage:
- Enable automatic screen rotation in the settings for your desktop
environment.
- Hold the device in the new orientation and call this script with
"$0 screen".
Pre-requisites:
Programs: $XINPUT, $XRANDR
Hardware: --
Package: --
3. Cycle through screen rotations:
The orientation of the screen is cycled through normal -> left -> inverted
-> right -> normal (option "next") or in reversed order (option "previous")
with each call of this script.
Usage:
- Disable automatic screen rotation in the settings for your desktop
environment.
- Call this script with "$0 next|previous".
Pre-requisites:
Programs: $XINPUT, $XRANDR
Hardware: --
Package: --
4. One-shot rotation (manual):
Independent of the actual orientation of the device, the orientation is
set to the given orientation.
Usage:
- Disable automatic screen rotation in the settings for your desktop
environment.
- Call this script with "$0 normal|inverted|left|right".
Pre-requisites:
Programs: $XINPUT, $XRANDR
Hardware: --
Package: --
Note:
Sometimes not all pointing devices are rotated. The reason is, that the
pointing device was not active at the time of rotation, as can happen with
e.g. bluetooth pens. In that case simply call the script again with the
same parameter.
Parameters:
-h, --help Display this help and exit.
screen, next, normal, left, inverted, right
The new orientation (optional). The default behaviour (no
option) is to use the orientation from the built-in
accelerometer. If 'screen' is given, use the screen's
current orientation. 'next' will switch to the next
orientation and any other option switches to the specified
orientation, regardless of the device's or the screen's
actual orientation.
EOF
}
check_commands () {
# Check for commands needed
#
# $1: The required orientation
if test $1 = auto; then
GDBUS=$(which $GDBUS)
if test -z $GDBUS; then
echo "Command 'gdbus' not found."
exit 10
fi
fi
XINPUT=$(which $XINPUT)
if test -z $XINPUT; then
echo "Command 'xinput' not found."
exit 11
fi
XRANDR=$(which $XRANDR)
if test -z $XRANDR; then
echo "Command 'xrandr' not found."
exit 12
fi
}
get_dbus_orientation () {
# Get the orientation from the DBus
#
# No options.
@ -54,10 +162,14 @@ get_orientation () {
ORIENTATION=$($GDBUS call $DBUS \
--method org.freedesktop.DBus.Properties.Get \
net.hadess.SensorProxy HasAccelerometer)
if test "$ORIENTATION" != "(<true>,)"; then
echo "No sensor available! "
echo "(Do you have the 'iio-sensor-proxy' package installed and enabled?)"
exit 10
if test $? != 0; then
echo $ORIENTATION
echo " (Is the 'iio-sensor-proxy' package installed and enabled?)"
exit 20
elif test "$ORIENTATION" != "(<true>,)"; then
echo "No sensor available!"
echo " (Does the computer has a hardware accelerometer?)"
exit 21
fi
# Get the orientation from the DBus
@ -84,7 +196,29 @@ get_orientation () {
;;
*)
echo "Orientation $ORIENTATION unknown!"
exit 11
echo " (Known orientations are: normal, bottom-up, left-up and right-up.)"
exit 22
esac
# Return the orientation found
echo $ORIENTATION
}
get_screen_orientation () {
# Get the orientation from the current screen orientation
#
# $1: The screen
ORIENTATION=$($XRANDR --current --verbose | grep $1 | cut --delimiter=" " -f6)
case $ORIENTATION in
normal|inverted|left|right)
;;
*)
echo "Current screen orientation $ORIENTATION unknown!"
exit 23
;;
esac
# Return the orientation found
@ -95,17 +229,24 @@ get_orientation () {
do_rotate () {
# Rotate screen and pointers
#
# $1: The new orientation
# $2: The screen to rotate
# $3-: The pointers to rotate
# $1: The requested mode (only "screen" gets a special treatment)
# $2: The new orientation
# $3: The screen to rotate
# $4-: The pointers to rotate
TRANSFORM='Coordinate Transformation Matrix'
MODE=$1
shift
ORIENTATION=$1
shift
# Rotate the screen
$XRANDR --output $1 --rotate $ORIENTATION
if test $MODE != screen; then
# Only rotate it, if we have not got the orientation from the screen
$XRANDR --output $1 --rotate $ORIENTATION
fi
shift
# Rotate all pointers
@ -129,20 +270,110 @@ do_rotate () {
}
# Process the command line options
MODE=auto
while true; do
case $1 in
-h|--help)
usage
exit
;;
*)
if test $# -eq 0; then
break
fi
MODE=$1
shift
;;
esac
done
# Check, if all commands, which are needed, are available
check_commands $MODE
# Get the display
XDISPLAY=$($XRANDR --current --verbose | grep primary | cut --delimiter=" " -f1)
# Get the tablet's orientation
ORIENTATION=$(get_orientation)
ret=$?
if test $ret != 0; then
echo $ORIENTATION
exit $ret
fi
case $MODE in
auto)
ORIENTATION=$(get_dbus_orientation)
ret=$?
if test $ret != 0; then
echo $ORIENTATION
echo "(To use this script, supply the orientation normal, inverted, left or right on the command line.)"
exit $ret
fi
;;
screen)
ORIENTATION=$(get_screen_orientation $XDISPLAY)
ret=$?
if test $ret != 0; then
echo $ORIENTATION
exit $ret
fi
;;
next)
ORIENTATION=$(get_screen_orientation $XDISPLAY)
ret=$?
if test $ret != 0; then
echo $ORIENTATION
exit $ret
fi
case $ORIENTATION in
normal)
ORIENTATION=left
;;
left)
ORIENTATION=inverted
;;
inverted)
ORIENTATION=right
;;
right)
ORIENTATION=normal
;;
*)
ORIENTATION=normal
;;
esac
;;
previous)
ORIENTATION=$(get_screen_orientation $XDISPLAY)
ret=$?
if test $ret != 0; then
echo $ORIENTATION
exit $ret
fi
case $ORIENTATION in
normal)
ORIENTATION=right
;;
left)
ORIENTATION=normal
;;
inverted)
ORIENTATION=left
;;
right)
ORIENTATION=inverted
;;
*)
ORIENTATION=normal
;;
esac
;;
normal|inverted|left|right)
ORIENTATION=$MODE
;;
*)
echo "Unknown command line parameter orientation $MODE"
exit 1
esac
# Get all pointers
POINTERS=$($XINPUT | grep slave | grep pointer | sed -e 's/^.*id=\([[:digit:]]\+\).*$/\1/')
# Get the display and its orientation
XDISPLAY=$($XRANDR --current --verbose | grep primary | cut --delimiter=" " -f1)
# Rotate the screen and pointers
echo "Rotate display $XDISPLAY to $ORIENTATION orientation (Pointers: $(echo $POINTERS | sed 's/\n/ /g'))"
do_rotate $ORIENTATION $XDISPLAY $POINTERS
do_rotate $MODE $ORIENTATION $XDISPLAY $POINTERS