Skip to content


Folders and files

Last commit message
Last commit date

Latest commit


Repository files navigation


Manage monitor configuration automatically

The goal of this project is to implement desktop environment independent dynamic monitor management. Dynamic monitor management means that the positions and resolutions of the monitors will automatically be updated whenever monitors are hotplugged. This program is written in Cython using XCB to directly communicate with the X11 server. This program is targeted at users who are using a window manager on a laptop who hotplug monitors frequently.


Run python install. Then running umonitor should work.

For Arch Linux users there is an AUR package here.


  • Setup your monitor resolutions and positions using xrandr or related tools (arandr is a good one).
  • Run umonitor --save <profile_name>.
  • Run umonitor --listen --daemonize to daemonize the program and begin automatically applying monitor setup.

The configuration file is stored in ~/.config/umon/umon.conf. You can load a profile manually by executing umonitor --load <profile_name>. Profiles can be deleted umonitor --delete <profile_name>.

umonitor runs all scripts automatically in ~/.config/umon after a profile has been loaded. An example script that I use can be seen in

Example scenario: You are working on a laptop. You want to save the monitor configuration of just the laptop screen into the profile name called 'home'. At home you plug in an external monitor, and you want to save that configuration as 'docked'.

# With only the laptop screen (no external monitors)
$ umonitor --save home
Profile home saved!

# Plug in external monitor

# Setup your desired configuration
$ xrandr --output HDMI-1 --mode 1920x1080 --pos 1600x0
$ xrandr --output eDP1 --mode 1600x900 --pos 0x0

# Save the current configuration into a profile
$ umonitor --save docked
Profile docked saved!

# Begin autodetecting changes in monitor
$ umonitor --listen
# Monitor is unplugged

Program help can be viewed through umonitor --help.

$ umonitor --help
usage: umonitor [-h]
                [-w | -s PROFILE | -l PROFILE | -d PROFILE | -a | -n | -g]
                [--dry_run] [-v] [-f] [--daemonize]

Manage monitor configuration.

optional arguments:
  -h, --help            show this help message and exit
  -w, --view            view configuration file
  -s PROFILE, --save PROFILE
                        saves current setup into profile name
  -l PROFILE, --load PROFILE
                        load setup from profile name
  -d PROFILE, --delete PROFILE
                        delete profile name from configuration file
  -a, --autoload        load profile that matches with current configuration
  -n, --listen          listens for changes in the setup, and applies the new
                        configuration automatically
  -g, --get_active_profile
                        returns current active profile
  --dry_run             run program without changing configuration
  -v, --verbose         set verbosity level, 1 = info, 2 = debug
  -f, --force           disable all outputs even if they do not change during
  --daemonize           daemonize when listening to events
  --no_exec             do not run scripts after loading of a profile is
  --no_poll             do not poll for monitor change event, instead use a
                        blocking call

If you would like to auto start this program, you can add the program to your .xinitrc:

$ cat ~/.xinitrc
umonitor --listen --daemonize
exec i3 # your window manager of choice


Give me some feedback!

  • What is saved and applied dynamically:
    • Monitor vendor name + model number
    • Crtc x and y position
    • Resolution and refresh rate
    • Primary output
    • Rotation
  • Runs scripts in ~/.config/umon with the currently loaded parameter stored in the environment variable UMONITOR_PROFILE.
  • Valgrind clean


  • Tell me! Run umonitor with the --verbose flag to get debugging output

I'm open for any feature requests!


This is a Python rewrite of my earlier program umonitor, which was written in C. A higher level language such as Python allows quicker development times and easier maintenance.


I borrowed the edid parsing code from eds.


Manage monitor configuration automatically.








No releases published


No packages published