4

While looking if someone asked this question before, I landed on this for Windows.

I'd like to do something similar (shortcut or terminal alias/command) on Linux/Ubuntu to be able to quickly switch the external monitor between landscape and portrait mode instead of having to go to Displays setting it and confirming the configuration.

Jacob Vlijm provided a Python script which works. If you have another idea I'd love to know about it.

Update: I have updated Jacob's script to work for two screens if they are connected.

user10853
  • 1,566

2 Answers2

5

The script below is to toggle rotation of either one of your screens:

#!/usr/bin/env python3
import subprocess

# --- set the name of the screen and the rotate direction below
screen = "VGA-1"
rotate = "left"
# ---

matchline = [
    l.split() for l in subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()\
    if l.startswith(screen)
    ][0]
s = matchline[
    matchline.index([s for s in matchline if s.count("+") == 2][0])+1
    ]

rotate = "normal" if s == rotate else rotate
subprocess.call(["xrandr", "--output", screen, "--rotate", rotate])

How to use

  1. Copy the script into an empty file, save it as toggle-rotate.py
  2. In the head section of the script, set:

    • the name of the screen you'd like to toggle (find out by running in a terminal the command xrandr)
    • the rotate direction, either left or right (between quotes, like in the example).

      # --- set the name of the screen and the rotate direction below
      screen = "VGA-1"
      rotate = "left"
      # ---
      
  3. Test- run it by the command (two times, from a terminal):

    python3 /path/to/toggle-rotate.py
    
  4. If all works fine, add it to a shortcut key. Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the command:

    python3 /path/to/toggle-rotate.py
    

    to a shortcut of your choice...

That's it.

Explanation

In the output of the command xrandr, the current rotation of your screen (if any) is mentioned directly after the screen's position, for example:

VGA-1 connected 1024x1280+1680+0 left (normal left inverted right x axis y axis) 376mm x 301mm

In the example, we see: 1024x1280+1680+0 left. The script looks into the line, corresponding to the screen, mentioned in the head of the script. if the screen is rotated, the script runs the (xrandr) command:

xrandr --output <screen_name> --rotate normal

if not, it runs (for example):

xrandr --output <screen_name> --rotate left

To rotate the screen counter-clockwise

Jacob Vlijm
  • 83,767
  • @user10853 Ah, that always makes me happy, you're welcome! – Jacob Vlijm Feb 20 '16 at 21:13
  • Regarding shortcuts, do you know how can I know if a combination is already being used or not other than trying? @Jacob On a related note, I will be trying your other script "take a break" :) – user10853 Feb 20 '16 at 21:34
  • Interesting conflict with Take a Break. When using the "Screen upside down" option in Take a Break while the external monitor is rotate left, the break rotates the external monitor to upside down as if it was in normal mode. When the break ends the monitor goes back to normal orientation rather than left. – user10853 Feb 20 '16 at 22:01
  • @user it is always possible that software clashes with other software. Take a Break assumes the screens are rotated normal. Could you report it as a bug at launchpad? I will fix it then. Until then, you might want to use one of the other break options of tab :) – Jacob Vlijm Feb 20 '16 at 22:08
  • I am looking for another related shortcut: Switch displays priority. – user10853 Nov 11 '16 at 18:50
  • +1 because this script and shortcut hotkey feels very similar to what I'd like to do (toggle between 2 resolutions). @JacobVlijm I'd really love your thoughts at https://askubuntu.com/q/1378237/48214 – Ryan Nov 29 '21 at 18:07
0

I have been using Jacob's script. However I am now using an adapter so I want to be able to toggle the orientation whether the monitor is connected to HDMI or through the adapter. For this I modified Javob's script and borrowed another function he wrote:

import subprocess

def screens():
    '''
    get connected screens
    '''
    output = [l for l in subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()]
    return [l.split()[0] for l in output if " connected " in l]

# --- set the name of the screen and the rotate direction below
# screen = "HDMI-1" # run "xrandr" to get the screen
rotate = "left" # the desired orientation

if "HDMI-1" in screens():
    screen = "HDMI-1"
elif "DP-1" in screens():
    screen = "DP-1"
else:
    pass
# ---

# only run if screen is declared (i.e. either HDMI-1 or DP-1 are connected)
if screen:

    matchline = [
        l.split() for l in subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()\
        if l.startswith(screen)
        ][0]
    s = matchline[
        matchline.index([s for s in matchline if s.count("+") == 2][0])+1
        ]

    rotate = "normal" if s == rotate else rotate
    subprocess.call(["xrandr", "--output", screen, "--rotate", rotate])
user10853
  • 1,566