Git Product home page Git Product logo

python-umonitor's Introduction

umonitor

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.

Installation

Run python setup.py install. Then running umonitor should work.

For Arch Linux users there is an AUR package here.

Usage

  • 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 toggle_media.py.

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
home
docked*
---------------------------------
# Monitor is unplugged
home*
docked
---------------------------------

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
                        once
  -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
                        loading
  --daemonize           daemonize when listening to events
  --no_exec             do not run scripts after loading of a profile is
                        finished
  --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
#!/bin/sh
...
...
...
umonitor --listen --daemonize
exec i3 # your window manager of choice

Features

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

Bugs:

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

I'm open for any feature requests!

About

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.

Credits

I borrowed the edid parsing code from eds.

python-umonitor's People

Contributors

bass-03 avatar fortstatement avatar rliou92 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

python-umonitor's Issues

missing path when installing

I installed this on Manjaro and the path to the config file was missing so the cli failed.

I had to mkdir -p ~/.config/umon/

Operating System: Manjaro Linux
Kernel: Linux 4.19.88-1-MANJARO
Architecture: x86-64

DistributionNotFound error on Arch

Upgraded Syu and started receiving errors; umonitor no longer runs.

This is

Name            : python-umonitor-git
Version         : r90.6175f3f-1
Build Date      : Mon 01 Jul 2019 04:44:20 PM CDT
Install Date    : Sat 23 Nov 2019 06:54:16 AM CST

and the error received for any execution (any arguments) is:

➜  ~ umonitor -a
Traceback (most recent call last):
  File "/usr/bin/umonitor", line 6, in <module>
    from pkg_resources import load_entry_point
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3251, in <module>
    def _initialize_master_working_set():
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3234, in _call_aside
    f(*args, **kwargs)
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3263, in _initialize_master_working_set
    working_set = WorkingSet._build_master()
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 583, in _build_master
    ws.require(__requires__)
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 900, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 786, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'umonitor==20181018' distribution was not found and is required by the application

I also tried the umonitor-git package, which is:

Name            : umonitor-git
Version         : r180.0591487-1
AUR URL         : https://aur.archlinux.org/packages/umonitor-git
First Submitted : Sat 27 May 2017 06:33:32 PM CDT
Last Modified   : Thu 18 Oct 2018 10:27:42 PM CDT

but this version either complains about the config file:

➜  ~ umonitor --verbose --load .config/umon/umon.conf
Connected to server
Configuration file not found.

or segfaults:

➜  ~ umonitor -n --daemonize --verbose
[1]    2688712 segmentation fault (core dumped)  umonitor -n --daemonize --verbose

At the time I'm posting this, AUR is down for maintenance, or I'd report the package; maybe some of the dependency libraries were missed. In any case, reporting here for for posterity.

umonitor --listen --daemonize fails with AttributeError: module 'daemon' has no attribute 'DaemonContext'

Output for umonitor daemonize in my case:

➜  autostart umonitor --listen --daemonize  
Traceback (most recent call last):
  File "/usr/local/bin/umonitor", line 33, in <module>
    sys.exit(load_entry_point('umonitor==20181018', 'console_scripts', 'umonitor')())
  File "/usr/local/lib/python3.10/dist-packages/umonitor-20181018-py3.10-linux-x86_64.egg/umonitor/__init__.py", line 23, in main
    umon.run()
  File "/usr/local/lib/python3.10/dist-packages/umonitor-20181018-py3.10-linux-x86_64.egg/umonitor/umonitor.py", line 47, in run
    with daemon.DaemonContext() as my_daemon:
AttributeError: module 'daemon' has no attribute 'DaemonContext'

umonitor not working with python 3.11

Hello, I just upgraded python to 3.11 and umonitor is not working anymore.

running install
/usr/lib/python3/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
  warnings.warn(
/usr/lib/python3/dist-packages/setuptools/command/easy_install.py:146: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
  warnings.warn(
running bdist_egg
running egg_info
writing umonitor.egg-info/PKG-INFO
writing dependency_links to umonitor.egg-info/dependency_links.txt
writing entry points to umonitor.egg-info/entry_points.txt
writing requirements to umonitor.egg-info/requires.txt
writing top-level names to umonitor.egg-info/top_level.txt
reading manifest file 'umonitor.egg-info/SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'umonitor.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
running build_ext
building 'screen' extension
x86_64-linux-gnu-gcc -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -fPIC -I/usr/include/python3.11 -c umonitor/screen.c -o build/temp.linux-x86_64-cpython-311/umonitor/screen.o
umonitor/screen.c:215:12: fatal error: longintrepr.h: File o directory non esistente
  215 |   #include "longintrepr.h"
      |            ^~~~~~~~~~~~~~~
compilation terminated.
error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1

Can't Load profile if process already running

Because of this:

self._prevent_duplicate_running()

Can't load a profile when the process is already running, which is kind of annoying.

I had to delete my "laptop" profile (no external screens) because the thing kept turning off screens when I disconnected the HDMI cable, and I could not load it manually while I was debugging.

Is there a reason for this?

Thank you

Hello,

Your program works very well, and I just wanted to thank you for your work.

ImportError: No module named umonitor - Ubuntu 18.04

Hello rliou92,

I have finished "sudo python setup.py", but execution threw an error below. I'm running Ubuntu 18.04. Any insight would be greatly appreciated.

mlim@linux:~/python-umonitor$ umonitor
Traceback (most recent call last):
File "/usr/local/bin/umonitor", line 11, in
load_entry_point('umonitor==20181018', 'console_scripts', 'umonitor')()
File "/usr/lib/python2.7/dist-packages/pkg_resources/init.py", line 480, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python2.7/dist-packages/pkg_resources/init.py", line 2693, in load_entry_point
return ep.load()
File "/usr/lib/python2.7/dist-packages/pkg_resources/init.py", line 2324, in load
return self.resolve()
File "/usr/lib/python2.7/dist-packages/pkg_resources/init.py", line 2330, in resolve
module = import(self.module_name, fromlist=['name'], level=0)
File "/usr/local/lib/python2.7/dist-packages/umonitor-20181018-py2.7-linux-x86_64.egg/umonitor/init.py", line 3, in
from umonitor.umonitor import Umonitor
ImportError: No module named umonitor

UnicodeDecodeError preventing usage

I just encountered this exception on a fresh install of python-umonitor. autorandr was previously installed. I have not saved any profiles yet and it prevents from doing so.
On Archcraft, installed using yay.
Edit: tried using python setup.py install but no difference.

~$: umonitor --verbose
INFO:root:Connected to X11 server.
INFO:root:Output name b'DP-00\x7f'
INFO:root:Finished edid_to_string on output b'ACR0XV272U XV272'
INFO:root:Output name b'eDP-1-10\xf0u\xa2\xd5\xe9\x7f'
Traceback (most recent call last):
  File "/usr/bin/umonitor", line 33, in <module>
    sys.exit(load_entry_point('umonitor==20181018', 'console_scripts', 'umonitor')())
  File "/usr/lib/python3.9/site-packages/umonitor/__init__.py", line 23, in main
    umon.run()
  File "/usr/lib/python3.9/site-packages/umonitor/umonitor.py", line 53, in run
    self.view_current_status()
  File "/usr/lib/python3.9/site-packages/umonitor/umonitor.py", line 195, in view_current_status
    self.setup_info = self.get_setup_info()
  File "umonitor/screen.pyx", line 417, in screen.Screen.get_setup_info
  File "umonitor/screen.pyx", line 106, in screen.Screen._get_output_info
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf0 in position 8: invalid continuation byte

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.