Getting docked triple-monitor setups on exwm at start of work

Table of Contents

My working triple-monitor setup

The problem: docking in to multiple monitors without restart doesn’t use them

In both my offices I have a triple-screen setup (my laptop + two externals). However, I change setups regularly; on the commute, it is only my laptop. Then, on either end of that commute, it’s triple two more external monitors (but they are a different dimension of externals in either location). The problem is that the monitors are usually not recognized at plug-in time after a daily change of locations, though my other docked accessories (mostly my keyboard) are recognized. After long suffering this, the worst-case failsafe being to restart my machine and then use autorandr, I have found a solution that almost always1 does the trick.

Solution p1: Wrappers for setting up randr

I wrote the following wrappers to configure my two locations: which monitors it expects, that resolution they will have, and where they will be physically in relation to my laptop (I choose to always have my laptop in the middle, on exwm window 1, with the larger monitor on the right and the other on the left).

My first wrapper

This is the setup I used during the COVID PHE, and still use once a week and on weekends.

(defun tsa/trimon ()
  "Set up the three-monitor home setup to be used in an exwm hook. Output via arandr."
  (interactive)
  ;; if trimon exists yet
  (if (fboundp #'tsa/trimon)
      (progn 
        (remove-hook 'exwm-randr-screen-change-hook #'tsa/campus)
        (add-hook 'exwm-randr-screen-change-hook #'tsa/trimon)))
  (setq exwm-randr-workspace-monitor-plist '(1 "DP-1-1"
                                             2 "DP-1-2"))

  (start-process-shell-command
   "xrandr" nil "xrandr --output eDP-1 --primary --mode 1600x900 --rotate normal --output DP-1 --off --output HDMI-1 --off --output DP-2 --off --output HDMI-2 --off --output DP-1-1 --mode 1600x900 --left-of eDP-1 --rotate normal --output DP-1-2 --mode 1600x900 --right-of eDP-1 --rotate normal --output DP-1-3 --off"))

My second wrapper

This is what I use every-workday at the end of my commute

(defun tsa/campus ()
  "Set up the three-monitor office setup to be used in an exwm hook, with the TV"
  (interactive)
  (if (fboundp #'tsa/campus)
      (progn 
        (remove-hook 'exwm-randr-screen-change-hook #'tsa/trimon)
        (add-hook 'exwm-randr-screen-change-hook #'tsa/campus)))
  (setq exwm-randr-workspace-monitor-plist '(2 "DP-1-2"
                                             1 "DP-1-3"))

  (start-process-shell-command
   "xrandr" nil "xrandr --output eDP-1 --primary --mode 1600x900 --rotate normal --output DP-1-3 --mode 1600x900 --left-of eDP-1 --rotate normal --output DP-1-2 --mode 1600x900 --right-of eDP-1 --rotate normal"))

Solution p2: xrandr -s 0

Those wrapper commands for setting up xrandr are necessary but not usually sufficient. Once they have been run, then xrandr usually needs a kick in the pants to actually utilize that setup. After what felt like years of dealing with this, I was given the following.3

I learned the xrandr –size4 command, which forces it to re-evaluate current connections in terms of the current xrandr setup. This works AFTER I’ve run my scripts to set external devices and their locations. After having used the right setup wrapper from above (eg tsa/trimon) I can then use the following from within my (m-x shell):

xrandr -s 0

which resets the xrandr, so if monitor changes are being ignored, start there. That -s flag has almost1 never failed me.

Footnotes

1 Occasionally (maybe once in 20 times) it results in a black screen and I have to restart. I have no idea why this happens, but it is relatively rare and I always save all buffers with C-x s2 before trying to fix my one-screen situation.

2 Default binding C-x s (save-some-buffers). Save modified file-visiting buffers. Asks user about each one.

3 Sorry, I don’t remember who or an what channel I found this idea, nor if it was actually directed at one of my queries or at some other issue.

4 -s is the xrandr shortcode for the –size command, which I use to force xrandr to re-apply the first (arg 0) of the settings we made above. See https://x.org/releases/X11R7.5/doc/man/man1/xrandr.1.html#sect5

Tory Anderson avatar
Tory Anderson
Full-time Web App Engineer, Digital Humanist, Researcher, Computer Psychologist