What do you think? Discuss, post comments, or ask questions at the end of this article. [More about me]

Skip to end of metadata
Go to start of metadata

I use the i3 window manager (i3 forevaa!..).  i3 gets it right here in that it doesn't give you a fancy (shmancy) GUI application to add new resolutions (hey it's a windows manager not a DE).  Plus, we can do all that from the CLI anyways...

However, I often find that I need to add a new resolution particularly when presenting or wanting to connect my machine to a projector.  Last time I needed to do this I couldn't remember the right syntax for cvt and xrandr (and had to hang my head in shame as I had to look it up).

I told myself... "self, that's not going to happen again" and wrote a quick and dirty bash script to add custom resolutions from the CLI.

Guide

First you'll need to meet some requirements:

  • running some Linux distro;
  • have cvt and xrandr installed (for Arch based distros do: sudo pacman -S xorg-server xorg-xrandr)
  • can run bash scripts (all distros should be able to do this);

The script

See below for the quick and dirty bash script.  Note this script simply allows the user to specify the output device, width, height, and refresh rate and it will calculate the CVT mode lines and create/add the resolution to your system.

#!/bin/bash

showExample() { 
    echo -e "\ne.g. \""$(basename -- "$0")" eDP1 1920 1080 60\"\n"
}

createRes() {
    cvt "$WIDTH" "$HEIGHT" "$REFRESH" | grep Modeline | sed "s/Modeline//" | xargs xrandr --newmode
}

addRes() {
    xrandr --addmode "$DEVICE" "$WIDTH"x"$HEIGHT"_"$REFRESH".00
}

switchRes() {

    while true; do
        read -p "$1" yn
        case $yn in
            [Yy]* ) xrandr --output "$DEVICE" --mode "$WIDTH"x"$HEIGHT"_"$REFRESH".00 || {
                        echo -e "\nERROR switching resolution with \"xrandr\"\n"
                        return 1
                    }; break;;
            [Nn]* ) break;;
            * ) echo "Please type \"y\" or \"n\"";;
        esac
    done
}

switchResAnyway() {
    switchRes "Adding resolution failed. Try to switch to this resolution anyway? (y/n) "
}

switchResNow() {
    switchRes "Switch to this resolution now? (y/n) "
}

# check arguments
if [ -z "$1" ]; then
    echo "Please provide an output devide as the first argument"
    showExample
    exit 128
fi

if [ -z "$2" ]; then
    echo "Please provide a screen width as the second argument"
    showExample
    exit 128
fi

if [ -z "$3" ]; then
    echo "Please provide a screen height as the third argument"
    showExample
    exit 128
fi

if [ -z "$4" ]; then
    echo "Please provide a refresh rate as the fourth argument"
    showExample
    exit 128
fi

#init
DEVICE=$1
WIDTH=$2
HEIGHT=$3
REFRESH=$4

createRes || {
    echo -e "\nERROR creating resolution with \"cvt\"\n"
    switchResAnyway
    exit 1
}

addRes || {
    echo -e "\nERROR adding resolution with \"xrandr\"\n"
    switchResAnyway
    exit 1
}

switchResNow
exit 0

Copy / paste the script into a file using your preferred text editor and make it executable.  For example, I called my script addresolution.sh  so would do

chmod +x addresolution.sh

Now, just execute it with the required arguments (device height width refresh-rate), e.g.

./addresolution.sh eDP1 1280 720 60

Easy(er)!