Adding a new monitor to my exwm setup
Table of Contents
I recently shuffled things with my office and found that I have hardware and ports for a third monitor to connect to my exwm setup. So, without further ado, how to get it going and registered with Linux/EXWM?
Edit
an easier way with arandrDownloading and installing arandr made this whole configuration much simpler than using the raw randr output. I finally made the jump when I was receiving an error at my attempts to load it manually: xrandr: Configure crtc 2 failed
. I then just installed arandr from my repos (Tumbleweed z in arandr
), lined up my monitors with the desired resolution, and hit “apply”. When I saw it worked I saved the generated configuration and loaded it into my auto-load locations instead of the below. At the end of the day, my localconfig.el (which I load at every startup) had an entry like this:
(defun tsa/trimon ()
"Set up the three-monitor home setup to be used in an exwm hook. Output via arandr."
(interactive)
(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 --pos 1600x0 --rotate normal --output DP-1 --off --output HDMI-1 --off --output DP-2 --off --output HDMI-2 --off --output DP-1-1 --mode 1600x900 --pos 0x0 --rotate normal --output DP-1-2 --mode 1600x900 --pos 3200x0 --rotate normal --output DP-1-3 --off"))
One more Gotcha was that my dock, a Totu, was failing to handle two HDMI connections, despite having two ports. Turns out that is what that USBC-in on the dock is for; HDMI take more power to transmit operate the wire than do the SVGA I was using previously, and I needed to plug in some USB-C-provided power (an old phone charger) to get it to work with two HDMI plugged in. Note that this wasn’t powering the monitor, as I couldn’t understand. This is powering the HDMI connection itself. And now I wonder if the year of issues I have assumed were just EXWM failing to deal with three monitors was, in fact, the occasional slips from having just barely sufficient power to power all the monitor connections. I’ll be watching for this.
Discover the new monitor
First, I plug my 3rd monitor into my dock. It’s a vga connector, so I get it plugged in and powered up. Ok – upon starting it, I see it has power and that it has a blank black screen (ie without a “not connected” message): it’s physically set up but needs to have the computer send meaningful stuff to it.
Get xrandr set up
xrandr is the program to handle monitors. Here are several steps.
1. Locate the screen name/port
>$ xrandr -q
# ... a bunch of stuff about my other ports and monitors ELIDED. Below is the new one:
DP-1-3 connected 1920x1080+6400+0 (normal left inverted right x axis y axis) 509mm x 286mm
1920x1080 60.00*+
1280x1024 60.02
1440x900 59.89
1280x800 59.81
1152x864 75.00
1024x768 70.07 60.00
800x600 60.32 56.25
640x480 66.67 59.94
720x400 70.08
2. Obtain the configuration line that xrandr needs
From the previous command I see that the desirable available resolution is 1920x1080 and the refresh rate is 60, so I put those into the gtf command to get the randr line I’ll need:
>$ gtf 1920 1080 60 | grep Modeline | cut -d' ' -f4-
"1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync
3. Apply randr
# Create a new resolution mode
>$ xrandr --newmode "1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync
# Add the new mode to the desired output we got from step 1 above
>$ xrandr --addmode DP-1-3 1920x1080_60.00
>$ xrandr --output DP-1-3 --mode 1920x1080_60.00
At this point our x window system should be all on-board with the new screen and is ready to use it. Now we just need exwm to utilize it.
4. Add screen to exwm
On my system I have a local-config.el that I reference for setup-specific situations, which is not under version control like my emacs.el is. For my laptop at home on the dock, I supplement it to look like this:
(setq exwm-randr-workspace-monitor-plist '(0 "eDP-1"
1 "DP-1-1"
2 "DP-1-3"))
(add-hook 'exwm-randr-screen-change-hook
(lambda ()
(start-process-shell-command
"xrandr" nil "xrandr --output DP-1-3 --right-of eDP-1 --output DP-1-1 --left-of eDP-1")))
With that elisp evaluated, then adding a new emacs workspace with C-x 5 2
and voila – I have my 3rd monitor reading and working! Once all is verified I make sure it’s persistent by adding those lines from step 3 to my ~/.xinitrc
file, so it will configure the monitor (if present) on startup.
Cautions & Conclusion
Two words of caution I discovered from mishaps in my project.
First, when I didn’t like the resolution I saw on the “new” monitor (actually about a decade old), I tried it out in my non-exwm boot (KDE), where I fiddled with the display controls to see whether it was my xrandr setup causing the blurriness. Now, I found that a lower resolution made things much less blurry – good! However, when I went to switch to the lower resolution (mostly following the steps above), I found that use of KDE to change display settings had apparently deleted my EDIT: false alarm. It was actually my exwm toggle script that had moved it safely out of the way since I was booting without exwm..xinitrc
file! Unforgivable! Fortunately I was able to recover it from a recent back up and supplement it appropriately.
Then, when I started up with my shiny new xinitrc into exwm, I found that the third monitor was goofily showing half of my 2nd monitor on it and annoying clipping things were happening. I fixed this by explicitly setting the second monitor therein, and removing the “auto” keyword. When all was said and done we had peace, and my xinitrc looked as follows, and I also added a .bak copy of it just in case bad things happen again.
-
xinitrc
# My original HDMI extra monitor xrandr --newmode "1600x900_60.00" 118.25 1600 1696 1856 2112 900 903 908 934 -hsync +vsync xrandr --addmode eDP-1 1600x900_60.00 xrandr --output eDP-1 --mode 1600x900_60.00 # My laptop monitor, which can go all the way to 4k but it isn't usable that way xrandr --addmode DP-1-1 1600x900_60.00 xrandr --output DP-1-1 --mode 1600x900_60.00 # My new 3rd monitor from this post xrandr --newmode "1440x900_59.89" 106.28 1440 1520 1672 1904 900 901 904 932 -HSync +Vsync xrandr --addmode DP-1-3 1440x900_59.89 xrandr --output DP-1-3 --mode 1440x900_59.89 xscreensaver & # my screensaver dunst & # My notification system nm-applet & # I like to see the wifi settings in my taskbar syndaemon -i 0.5 -t -K -R -d # Java requirements below wmname LG3D export _JAVA_AWT_WM_NONREPARENTING=1 # My cursors # Load cursor theme, etc # xrdb ~/.Xresources export XCURSOR_THEME=Scraft # So that the "locate" command is ready to go when necessary updatedb # and finally, start exwm! exec emacsclient -a "" -c
-
local-config.el
This is the non-controlled file that emacs/exwm uses to start everything, including the xrandr command that aligns my screens.
(setq exwm-randr-workspace-monitor-plist '(0 "eDP-1" 1 "DP-1-1" 2 "DP-1-3")) (add-hook 'exwm-randr-screen-change-hook (lambda () (start-process-shell-command "xrandr" nil "xrandr --output DP-1-3 --right-of eDP-1 --output DP-1-1 --left-of eDP-1")))
Resources
- gtf and xrandr use to find info: https://a3nm.net/blog/xrandr.html
- More on xrandr, courtesy of the typically excellent documentation from Arch Linux: https://wiki.archlinux.org/index.php/Xrandr
- exwm RandR multiscreens: https://github.com/ch11ng/exwm/wiki#randr-multi-screen