Posts tagged ‘monitor’

External monitors

When I first started using Linux over a decade ago, dual screen was a pain to set up. When I got my first laptop four years ago, setting up an external monitor was also painful. Then came xrandr and life was good. Now there are nifty little monitor switching GTK apps that allow you to drag screens around just like in Windows or MacOS.

But that’s a lot of fiddling around. For the longest time, my use case has always been either:
a) I am using only my laptop
b) I am using my laptop with my 1920×1080 external monitor connected via VGA (It’s an old laptop)

To accommodate these two use cases, I had connected my “Switch Display” (fn+F7 on my thinkpad) key to the following simple script:

  #!/bin/bash
  if ! xrandr | grep VGA1 | grep disconnected  >/dev/null ; then
      xrandr --output LVDS1 --mode 1024x768 --output VGA1 --mode 1920x1080 --above LVDS1
  else
      xrandr --auto
  fi

Succinctly, if the external monitor is connected, enable it as “above” my laptop, otherwise, just enable the laptop monitor. All I have to do is plug in or unplug my monitor, hit Fn+F7, and my display would automatically adjust itself.

For the record, I used xbindkeys to connect the button to the script with the following .xbindkeysrc:

 .xbindkeysrc                                                                                                                
  "/home/dusty/bin/check_external"
      XF86Display

This served me well until I bought myself a new television that only operates at 1360×768 on the VGA port. Further, when I’m connecting my laptop to the tv, the television is usually below the laptop monitor rather than above, as my monitor is.

So now, my check_external script looks thusly:

  #!/usr/bin/python
  import subprocess
 
  positions = {
      "1920x1080": "--above", # Monitor
      "1360x768": "--below" # TV
  }
 
  output = subprocess.check_output("xrandr", shell=True).decode("utf-8")
 
  external_connected=resolution=False
  for line in output.split("\n"):
      if external_connected:
          if "+" in line: # + represents the default resolution for that monitor
              resolution = line.split()[0] # + the resolution is in the first column
              break
      if "VGA1 connected" in line:
          external_connected=True
 
  if external_connected:
      subprocess.call(
              "xrandr --output LVDS1 --mode 1024x768 --output VGA1 --mode {resolution} {position} LVDS1".format(
                  resolution=resolution, position=positions.get(resolution, "--above")), shell=True)
  else:
      subprocess.call("xrandr --auto", shell=True)

This is Python 3 code, and works delightfully on my Arch Linux running awesome setup. I still have to do custom xrandr commands if I ever connect to someone else’s projector or monitor (this happens so rarely that I don’t think I’ve done it since Archcon last year), but normally I can get away with a quick “xrandr –auto” in those cases, which usually just clones the display. There are dozens of ways to set up monitors, but this works great for me, and I can normally have my display up and running the way I want it with a couple keystrokes.