Monitorcontrol - Control your monitors through code

Dual screen with BSOD
Photo by Alpha

I recently acquired an old screen to switch to a dual screen setup. Unfortunately, it does not automatically detect the input source, and I have to manually change it when I want to switch between my desktop and my laptop

Luckily, I also recently learned that you can control a bunch of things on your monitor through code, so let's write a script to help me with that!

Monitorcontrol

Let's briefly see how we can use monitorcontrol, a python package to control our monitor source.

First, we get the model of each monitor:

from monitorcontrol import get_monitors


for monitor in get_monitors():
    with monitor:
        name = monitor.get_vcp_capabilities()["model"]
        print(f" - model: {name}")

# With this code, my output is:
# - model: VG27A1A
# - model: U2515H

With this information, we can also change the input source for a given monitor. Let's say we want to set the input source of the monitor U2515H to HDMI1. We can do this with:

from monitorcontrol import InputSource
from monitorcontrol import get_monitors

for monitor in get_monitors():
    with monitor:
        if monitor.get_vcp_capabilities()["model"] == "U2515H":
            monitor.set_input_source(InputSource.HDMI1)

The logic

The logic itself is a small script made of 2 parts. The first one is the configuration part, where I would assign, for each computer, the correct input source for each screen. For example, my desktop is connected to VG27A1A through DP1, and to U2515H through HDMI2. For my laptop, it would be HDMI2 for both screens:

from enum import Enum
from monitorcontrol import InputSource


class Computer(Enum):
    One = "Desktop"
    Two = "Laptop"


CONF_SCREENS = {
    "VG27A1A": {
        Computer.One: InputSource.DP1,
        Computer.Two: InputSource.HDMI2,
    },
    "U2515H": {
        Computer.One: InputSource.HDMI1,
        Computer.Two: InputSource.HDMI2,
    },
}

The second part is a function taking an enum Computer as a parameter, which swaps all the monitor sources to this computer:

def set_monitors_source(computer: Computer):
   for monitor in get_monitors():
       with monitor:
           name = monitor.get_vcp_capabilities()["model"]
           monitor.set_input_source(CONF_SCREENS[name][computer])

And that's it! With this, I can call set_monitors_source whenever I want to change from my desktop to my laptop, without touching the screens directly.

Calling the script

I could execute this script via the command line, but I mostly need to call it from a Windows computer, where I rarely have a terminal open.

Instead, I chose to control the app from the systray, to be able to swap computers with only one click. To do this, I grabbed an icon on flaticon, and used pystray for the systray integration.

alt text

The code itself is cumbersome, so I won't list it here but can see it on the github page.

Since it also easy to do, I added shortcuts with keyboard to go to computer one or two.


And that's it! I don't have to bother touching the screen anymore, and handling this with a single click i very satisfying.

For more information on the code or to try it out yourself, you can access the complete script available here.