Sometimes you're lucky enough to have access to an extra monitor.  If you're using i3, or any other desktop interface that doesn't have a gui or some simplified means for display management, setting up that second monitor might be something of a challenge.  In this brief tutorial, we'll cover how to set up and use multiple monitors with i3.  We'll use xrandr and i3-msg to orient our displays and place the workspaces we want on whatever monitor we want.

I would like to briefly note that while I love to use an external monitor when one is available, switching back and forth between, say, just a laptop, and a laptop + external display can cause some development performance issues.  Considering the implications raises an annoyingly common question: are you better off developing a single skill, or developing the skill of developing a skill?  Enjoy, Alice.

Now back to setting up multiple screens.

Background:

RandR, short for the Resize, Rotate and Reflect Extension, is a standard that specifies how to manipulate windows on screens, and is itself an extension of an earlier, similar standard developed in 2001 called RANDR.  Most systems with an X Window system installed include a program called xrandr which is a command line interface for the RandR Extension.

Now how to use that second display?

For the purposes of this tutorial, I'm using a laptop and have a single external screen.

Discovering Connected Displays:

Let's look at what's connected by using xrandr:

$ xrandr --query

To reduce the clutter, we can use grep:

$ xrandr --query | grep connected
eDP-1 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 194mm
DP-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 disconnected (normal left inverted right x axis y axis)

With nothing plugged into the laptop, xrandr reports only a single display.  Let's try connecting our external display, and querying again:

$ xrandr --query | grep connected
eDP-1 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 194mm
DP-1 disconnected (normal left inverted right x axis y axis)
DP-2 disconnected (normal left inverted right x axis y axis)
DP-3 connected (normal left inverted right x axis y axis)

Okay!  A display is connected on DP-3, but the screen displays nothing.

Using External Display:

Let's assume we don't know anything about the external display.  In order to use it, we need to know what resolutions it supports.  Let's find out:

$ xrandr --prop
...
DP-3 connected (normal left inverted right x axis y axis)
	EDID: 
		00ffffffffffff0010ac4df053413644
		1618010380331d78eadd45a3554fa027
		125054a54b00714f8180a9c0d1c00101
		010101010101023a801871382d40582c
		4500fd1e1100001e000000ff00303948
		4b43343553443641530a000000fc0044
		454c4c204532333134480a20000000fd
		00384c1e5311000a2020202020200068
	Content Protection: Undesired 
		supported: Undesired, Desired, Enabled
	Broadcast RGB: Automatic 
		supported: Automatic, Full, Limited 16:235
	audio: auto 
		supported: force-dvi, off, auto, on
	link-status: Good 
		supported: Good, Bad
	CONNECTOR_ID: 91 
		supported: 91
	non-desktop: 0 
		range: (0, 1)
   1920x1080     60.00 +
   1600x900      60.00  
   1280x1024     75.02    60.02  
   1152x864      75.00  
   1024x768      75.03    60.00  
   800x600       75.00    60.32  
   640x480       75.00    59.94  
   720x400       70.08  

So it supports several modes (i.e. a set of settings including resolution, frequency, etc), including one with a  resolution of 1920x1080 (ie 1080p)!

Armed with a resolution we can now start using it:

$ xrandr --output DP-3 --mode 1920x1080

And the external monitor is on, and mirroring the laptop's display.  Great!

Extending the Desktop:

While mirroring is good for some situations, it would be nice to have the external monitor extending my laptop's screen.  We can do this by using the orientation arguments of --right-of, --left-of, --above, and --below.  My external display is to the right on my laptop, so to extend the displays in a logical way I can do the following (recalling that my laptop's display is connected on eDP-1):

$ xrandr --output DP-3 --right-of eDP-1

Moving the mouse over to the second monitor works as expected.  Great!

Multiple Displays and i3:

In order to make this setup functional, we need to be able to place whatever we want on the external display.  We can get a certain amount of functionality out of simply moving windows around the same way we would inside a single workspace, i.e. with <mod>+shift+{j, k, l, ;} (the default i3-window moving commands).

I can for instance, move a single window from my laptop's screen to my external monitor by using <mod>+shift+; (i.e. move right).

However what if I want to move an entire workspace on to the external monitor?  Enter i3-msg!

If I want to move workspace 4, in its entirety, to the external monitor, I can do the following:

$ i3-msg "workspace 4, move workspace to output DP-3"

Now using <mod>+4 changes the focus to the external monitor.

Further, you can create a new workspace on either monitor simply by having it focused when creating the new space!

Resetting the Situation:

A minor caveat of this system is that if I were to unplug the external monitor while there were windows open on it, they wouldn't be automatically moved back to the laptop's screen.  We can remedy this situation with the --auto switch:

$ xrandr --auto

You should now be ready to use xrandr to control and orient multiple screens while using i3 and be able to move workspaces using i3-msg!

References:

# Reads: 2981