GithubHelp home page GithubHelp logo

ventto / mons Goto Github PK

View Code? Open in Web Editor NEW
622.0 9.0 39.0 146 KB

POSIX Shell script to quickly manage monitors on X

License: MIT License

Shell 94.25% Makefile 5.75%
xrandr manage monitor screen laptop display arch-linux linux ubuntu posix

mons's Introduction

Mons

License Language (XRandR) Vote for mons Donate

"Mons is a Shell script to quickly manage 2-monitors display using xrandr."

Perks

  • No requirement: POSIX-compliant (minimal: xorg-xrandr)
  • Useful: Perfectly fit for laptops, quick and daily use
  • Well known: Laptop mode, projector mode, duplicate, mirror and extend
  • More: Select one or two monitors over several others
  • Extra: Cycle through every mode with only one shortcut
  • Auto: Daemon mode to automatically reset display

Installation

  • Package (AUR)
$ pacaur -S mons
  • Package (FreeBSD)
# pkg install mons
  • Manual
$ git clone --recursive https://github.com/Ventto/mons.git
$ cd mons
$ sudo make install

Note: --recursive is needed for git submodule

Usage

Without argument, it prints connected monitors list with their names and ids.
Options are exclusive and can be used in conjunction with extra options.

Information:
  -h    Prints this help and exits.
  -v    Prints version and exits.

Two monitors:
  -o    Primary monitor only.
  -s    Second monitor only.
  -d    Duplicates the primary monitor.
  -m    Mirrors the primary monitor.
  -e <side>
         Extends the primary monitor to the selected side
         [ top | left | right | bottom ].
  -n <side>
         This mode selects the previous ones, one after another. The argument
         sets the side for the extend mode.

More monitors:
  -O <mon>
        Only enables the monitor with a specified id.
  -S <mon1>,<mon2>:<pos>
        Only enables two monitors with specified ids. The specified position
        places the second monitor on the right (R) or at the top (T).

Daemon mode:
  -a    Performs an automatic display if it detects only one monitor.
  -x <script>
        Must be used in conjunction with the -a option. Every time the number
        of connected monitors changes, mons calls the given script with the
        MONS_NUMBER environment variable.

Extra (in-conjunction or alone):
  --dpi <dpi>
        Set the DPI, a strictly positive value within the range [0 ; 27432].
  --primary <mon_name>
        Select a connected monitor as the primary output. Run the script
        without argument to print monitors information, the names are in the
        second column between ids and status. The primary monitor is marked
        by an asterisk.

Examples

Two monitors

Displays monitor list:

$ mons
0: LVDS-1   (enabled)
5: VGA-1

You have an enabled one, you want to extends the second one on the right:

$ mons -e right

You want to only display the second one:

$ mons -s

With the -n option, go through every 2-mons mode consecutively:

  1. Primary monitor only
  2. Second monitor only
  3. Extend mode whose the side is set with -n <side>
  4. Mirror
  5. Duplicate

This mode is useful if you want to switch to every mode with only one shortcut.

alt 2-monitors modes

# Now in 'Second monitor mode'
$ mons -n right # -> 'Extend mode'
# Now in 'Extend mode'
$ mons -n right # -> 'Mirror mode'

Three monitors (selection mode)

Displays monitor list:

$ mons
Monitors: 3
Mode: Selection
0:* LVDS-1   (enabled)
1: DP-1      (enabled)
5: VGA-1

You may need to display only the third one:

$ mons -O 5

You may need to display the first and the third one on the right:

$ mons -S 0,5:R

Like above but you want to inverse the placement:

$ mons -S 5,0:R

DPI value

You might want to switch mode and set the DPI value. Use the --dpi <dpi> option in conjunction with all others options.

$ mons [OPTIONS] --dpi <dpi>

Primary monitor

You might choose one of your monitors as the main one. You can use the --primary <mon_name> option alone or in conjunction with all others options. <mon_name> refers to the monitor name that appears in the list of connected monitors (ex: LVDS-1 or VGA-1):

$ mons
Monitors: 3
Mode: Primary
0:* LVDS-1   (enabled)
5:  VGA-1

The * character means that the monitor is the primary one:

$ mons --primary VGA-1
Monitors: 3
Mode: Primary
0:  LVDS-1   (enabled)
5:* VGA-1

Daemon mode

This mode is useful for laptops. After unplugging all monitors except the last one, mons's "daemon" mode will reset the display and enable the latter.

Use case: "I connect a monitor to my laptop and I only want to work with that one, so I disable the native one. After a while, I will unplug the additional monitor and I need reset my display to re-activate the native one."

  • Run it as following:
$ nohup mons -a > /dev/null 2>&1 &  (all shells)
$ mons -a &!                        (zsh)
$ mons -a &; disown                 (bash)
  • You can handle N-monitors on your own by using the -x option. mons will export the ${MONS_NUMBER} environment variable and run the given Shell script everytime the number of connected monitors changes:
$ mons -a -x "<path>/generic-handler.sh"

# Use it as configuration profiles:
$ mons -a -x "<path>/home-profile.sh"
$ mons -a -x "<path>/work-profile.sh"
  • Example of script.sh:
#!/bin/sh

case ${MONS_NUMBER} in
    1)
        mons -o
        feh --no-fehbg --bg-fill "${HOME}/wallpapers/a.jpg"
        ;;
    2)
        mons -e top
        feh --no-fehbg --bg-fill "${HOME}/wallpapers/a.jpg" \
                       --bg-fill "${HOME}/wallpapers/b.jpg"
        ;;
    *)
        # Handle it manually
        ;;
esac

mons's People

Contributors

0mp avatar grembeter avatar jameswei avatar l2ol33rt avatar mschneiderwng avatar tnhh 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar

mons's Issues

Shellcheck: Double quote array expansions to avoid re-splitting elements

In src/mons.sh line 177:
            idx=$(is_enabled ${disp_mons[@]} "${plug_mons[0]}")
            ^-- SC2068: Double quote array expansions to avoid re-splitting elements.


In src/mons.sh line 180:
            disable_mons ${disp_mons[@]}
            ^-- SC2068: Double quote array expansions to avoid re-splitting elements.


In src/mons.sh line 244:
        idx=$(is_enabled ${disp_mons[@]} "${mons[$mon1]}")
        ^-- SC2068: Double quote array expansions to avoid re-splitting elements.


In src/mons.sh line 247:
        idx=$(is_enabled ${disp_mons[@]} "${mons[$mon2]}")
        ^-- SC2068: Double quote array expansions to avoid re-splitting elements.


In src/mons.sh line 250:
        disable_mons ${disp_mons[@]}
        ^-- SC2068: Double quote array expansions to avoid re-splitting elements.


In src/mons.sh line 267:
        idx=$(is_enabled ${disp_mons[@]} "${mons[${OArg}]}")
        ^-- SC2068: Double quote array expansions to avoid re-splitting elements.


In src/mons.sh line 271:
        disable_mons ${disp_mons[@]}
        ^-- SC2068: Double quote array expansions to avoid re-splitting elements.

Upgrade broke more than two monitors

Hello,

It used to work before, but now i get this error:

I run archlinux.

$ mons                                                                                                     
Monitors: 3
Mode: selection
0:  eDP1               
3:  DP1-2     (enabled)
4:  DP1-3     (enabled)
 
sfrique@sfrique-e7470: ~
$ mons -S 3,4:R                                                                                            
At most two plugged monitors for this option.

I've used this command at startup, i have a dock that in total it makes3 monitors:
mons -S 3,4:R && xrandr --output DP1-2 --primary || ( mons -O 0 && xrandr --output eDP1 --primary)

Sorry, I have no time to debug now.

HiDPI scaling

Hello, thanks for the awesome project!

I have a Dell XPS with i3wm and a screen resolution as:

Screen 0: minimum 8 x 8, current 3200 x 1800, maximum 32767 x 32767
eDP1 connected primary 3200x1800+0+0 (normal left inverted right x axis y axis) 290mm x 170mm
   3200x1800     59.98*+  47.99  

When I connect a second monitor

DP1 connected (normal left inverted right x axis y axis)
   1920x1080     60.00 +  50.00    59.94  

and I run mons -s to enable only second (FHD) monitor I have a very huge scaling which makes it almost unusable.
I have a custom xrandr script for scaling:

$ xrandr --fb 3200x1800 --output DP1 --primary --mode 1920x1080 \
         --scale-from 3200x1800 \
         --pos 0x0 --panning 3200x1800+0+0 --rotate normal \
         --output eDP1 --off

but is there a possibility to make the same with mons?

Unable to install mons

When I ran the following command this is what I got.

sudo make install
Password:
help2man -N -n "POSIX Shell script to quickly manage 2-monitors display." -h -h -v -v ./mons.sh | gzip - > mons.1.gz
/bin/sh: help2man: command not found
mkdir -p /usr/lib/libshlist
mkdir: /usr/lib/libshlist: Operation not permitted
make: *** [install] Error 1

./mons.sh: line 86: fg: no job control

I got this on a fresh install of mons and what's most perplexing is line 86 doesn't seem to have anything to do with background/foreground processes. I'm currently running the i3-manjaro image, let me know if there's any other info I should provide!

PKGBUILD Arch Linux mons-git "broken"

I tried the package mons-git from the arch aur. The sed command in there sets a path to a shell script liblist.sh inside the installation folder. This is obviously not working for a permanent installation as the build folder is often a temporary thing. Just tried installing it with trizen as aur helper. It then points to /tmp/...../liblist.sh. Which does not exists and then mons does not start. I then git cloned into the aur and build it in a folder in my home dir. As long as I leave the build folder in place everything works. If I move it away it breaks again for obvious reasons.

Feature: set primary monitor

First and foremost I'd like go give an huge thanks for this awesome CLI app. I have been using it for quite some time and enjoyed it a lot.

The only thing I feel is missing is the ability to set one monitor as primary. This is especially important when you run applications that use notifications as they are, commonly, placed on the primary monitor.

Is it possible that mons could include this in some way?

Feature Request: Ability to supply scale setting for a given monitor

When using a HiDPI display with a low DPI display, the best approach is to set the DPI to the hiDPI display, and then scale by 1.5 or 2 the external monitor.

It would be nice if mons allowed you to pass in a scale factor for a particular monitor.

For example, this blog post demonstrates using scaling to get a hidpi laptop monitor to work with a regular/low dpi external display.
https://blog.summercat.com/configuring-mixed-dpi-monitors-with-xrandr.html

RAM usage goes up when switching i3 workspaces in secondary monitor only mode

I am using a secondary monitor with the mons -s command.

Every time I switch i3 workspaces, the RAM usage goes up more and more, and doesn't get released until reboot.

I can literally just switch back and forth and the RAM goes up until it's completely full. This doesn't happen when only using primary monitor.

Tagging recent commits

Void linux has an xbps package for mons. It is currently pointing to the commit with tag 0.8.2. In order for the package to pull in recent commits, it would be very helpful if a new tag with recent commits is created with a higher version number.

Mirroring makes primary montior blank

When I use mons -m, the secondary monitor shows the screen but the primary monitor goes blank. Should there be a --same-as in the mirroring command?

Feature Request: set refresh rate

My main monitor is 120Hz, my second monitor is 60Hz. If I extend the primary monitor using mons, everything works fine, refresh rate stays at 120Hz, but after switching back to primary monitor only, the refresh rate changes to 60Hz.

It's very inconvenient, the script should allow the user to set the refresh rate.

Extend to left doesn't work

Hi,
I have 2 monitors: HDMI1 on the left, and VGA1 (set as primary) on the right.
Extend to right works but I extend to left, mons behaves like HDMI1 would be set as primary and VGA1 extended on the right.
mons still shows that VGA1 is set as primary.
Thanks

Feature Request: Flag to trigger optional rotation

I would like to add an optional flag that controls the rotation of the second monitor (normal, right, left, inverted). I wanted to open a feature request before attempting to implement this myself to get some feedback.

Please provide examples in --help and README.md

I've tried to use mons but I can't achieve anything I want. Here's my tries, all failed:

  1. mons -S DisplayPort-0,DisplayPort-1:left,DisplayPort-2:right
  2. mons -S DisplayPort-0,DisplayPort-1:L,DisplayPort-2:R 3. mons -S

Output of mons:

% mons
Monitors: 3
Mode: selection
0:*  DisplayPort-0 (enabled)         
1:   DisplayPort-1 (enabled)
2:   DisplayPort-2 (enabled)

At this point, I have no idea how to use -S parameter.

  -S <mon1>,<mon2>:<pos>
        Only enables two monitors with specified ids. The specified position
        places the second monitor on the right (R) or at the top (T).

Please provide examples in --help as well as README.md to make things clear.

EDIT: Apparently, better examples are in the README.md below, but I didn't scroll down far enough. First part of README.md is the same output as in --help so I didn't scroll down further. In this case, I'm asking for better output of --help only as README.md is good enough.

EDIT 2: I still don't know how to configure three monitors. I tried mons -S 1,0:R,2:R and I got this - far from what I wanted:

% mons             
Monitors: 3
Mode: selection
0:*  DisplayPort-0 (enabled)         
1:   DisplayPort-1 (enabled)
2:   DisplayPort-2     # <--- why not enabled?

Feature request: keybindings to move windows between monitors

Thank you very much for mons. I use it daily.

There may already be something that I missed, or it might be hard to implement within mons, but it would be amazing if a keybinding could easily move windows between monitors. When I get into extended mode, all of my windows are thrown to the second monitor and I need to move some of them back to my primary monitor. For some of them, it is quite easy, for others, that I configured in full screen and without decoration, it is a little tedious. Unplugging the 2nd monitor, however briefly to move somewhere (my primary monitor is a laptop), and replugging it requires to do this exercise all over again.

Note that I also really like the feature request #21 and if it becomes implemented, I guess that being able to switch windows easily won't be as critical as I wouldn't have to redo it each time.

Thank you!!!

Feature request: cycle through modes

First of all thanks for such a nice tool!

I would like to hook this tool to the "display" key on my laptop. So, just by hitting a single key I can cycle through different display modes. (I'm using i3 wm)

I can try to implement such feature myself but there's one question. Whether to store current mode or try to guess it from the xrand output.

Moving needed posix-shell-list's functions to mons

Is it worth copying needed posix-shell-list's functions to mons to get one-file script or keeping the lib inclusion ?

EDIT: I assume that posix-shell-list is a Shell library and mons a script that uses it.

Polybar disappearing when using mons

Whenever I use mons on my laptop, either to extend or duplicate, it makes my polybar bars disappear. I have no idea why this is happening.

Output of mons -v

Mons 0.8.2
Copyright (C) 2017 Thomas "Ventto" Venries.

License MIT: <https://opensource.org/licenses/MIT>.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

Output of polybar --version

polybar 3.1.0-70-g258f55a

Features: +alsa +curl +i3 -mpd +network +pulseaudio

mons -a; problem going from 4:3 external to 16:9 internal

I have mons -a in my .xinitrc, and an i3 hotkey to trigger mons -s after I've plugged my external in.

On unplugging the external, I get a situation where all windows on my laptop screen are restricted in width, until I run mons -o, which resolves the problem.

(In real life, I cannot see the bottom gap featured in the screenshot below, as it lies below the size of my laptop monitor.)

rose_2018-08-14-01 56 54

Feature: Duplicate and mirror on all and selected outputs

Let's say, we have a laptop with two plugged-in monitors. At start, only the primary one is turned on:

$ mons
Monitors: 3
Mode: primary
0:  eDP1      (enabled)
2:  HDMI1     
3:  DP1

We want to duplicate our desktop view on every output:

$ mons -D
$ mons
Monitors: 4
Mode: duplicate
0:  eDP1      (enabled)
2:  HDMI1     (enabled)
3:  DP1       (enabled)

Or by selection:

$ mons -o
$ mons
Monitors: 3
Mode: duplicate
0:  eDP1      (enabled)
2:  HDMI1    
3:  DP1      

$ mons -D 3
$ mons
Monitors: 3
Mode: duplicate
0:  eDP1      (enabled)
2:  HDMI1    
3:  DP1       (enabled)

$ mons -D 2,3
$ mons
Monitors: 3
Mode: duplicate
0:  eDP1      (enabled)
2:  HDMI1     (enabled)
3:  DP1       (enabled)

Same logical with -M option.

Feature Request: Auto detect previously used display and apply last setting

I use Mons on my laptop on a daily basis. I love the simplicity but I wish there was a way that it could be totally automated. I would appreciate if the -a option which daemonizes the process would also detect when a monitor was plugged in and set the display to some pre configured state, from either a configuration file or just by remembering how the user had it set previously.

I'm going to start perusing your code and see if there is a simple way for me to add this feature and submit a pull request. Let me know if this is something you feel fits your project and if so please suggest how you think this should be implemented.
Thank you!

Running daemon causes only screen connected to desktop not wake up

Hi,

I am using Mons with i3 wm to manage multi-screen setups. I have a desktop pc with single screen and starting the daemon on X start using mons -m & in .xprofile.

Also setting dpms settings and disabling screen saver with following lines in .xinitrc

xset s off
xset dpms 300 600 1800

But when the screen goes into sleep mode I can not get it back up until I plug it out and re-plug again. How can i configure mons to resolve this issue ?

Bug: mons -s works only one time

So I started to have the following problem:

I start Xorg and type in mons -s. It would switch as expected (though leaving the primary monitor turned on) to the second monitor. Now type mons -o (works) and I type mons -s again. Second time it wouldn't work and I need to restart Xorg to make it work again.

If I use xrandr it works all the time and it also properly turns off the primary monitor:

xrandr --output eDP-1 --off --output HDMI-1 --auto
xrandr --output eDP-1 --auto --output HDMI-1 --off

What exactly is the xrandr command when mons -s is executed?

Ignore intel VIRTUAL[1-9] outputs

Pretty self-explanatory.
These outputs are guarenteed to be consitently named, so there's no witch hunt through xrandr for them.
I might submit a PR if I have some time.

Makefile installs an empty manpage if help2man isn't present

The makefile autogenerates the manpage to install using the help2man command:

$(MANPAGE):
	help2man -N -n "$(PKGDESC)" -h -h -v -v ./$(SCRIPT) | gzip - > $@

If help2man isn't installed an empty manpage is generated, without make being aware of an error:

[tom@jackdaw mons]$ which help2man
help2man not found
[tom@jackdaw mons]$ help2man -N -n "POSIX Shell script to quickly manage 2-monitors display." -h -h -v -v ./mons.sh | gzip - > mons.1.gz
zsh: command not found: help2man
[tom@jackdaw mons]$ echo $?
0
[tom@jackdaw mons]$ ls -l mons.1.gz 
-rw-r--r-- 1 tom tom 20 Apr 29 10:51 mons.1.gz
[tom@jackdaw mons]$ 

This is because (quoting from the Bash manpage, although I believe the behaviour is POSIX) "The exit status of a pipeline is the exit status of the last command in the pipeline". So because gzip is successful, the pipeline as a whole is seen to have succeeded, and make happily installs the empty manpage.

There are of course various workarounds. One option is set -o pipefail although that's not POSIX, and in particular doesn't work on dash so far as I'm aware.

This patch worked for me to cause the makefile to fail rather than silently install a broken manpage:

diff --git a/Makefile b/Makefile
index b04ba89..69ad61f 100644
--- a/Makefile
+++ b/Makefile
@@ -27,11 +27,14 @@ install: $(LIB) $(MANPAGE)
        cp $(SCRIPT) $(BINDIR)/$(PKGNAME)
        sed -i -e "s#%LIBDIR%#$(LIBDIR)#" $(BINDIR)/$(PKGNAME)
 
-$(MANPAGE):
+check_help2man:
+       which help2man
+
+$(MANPAGE): check_help2man
        help2man -N -n "$(PKGDESC)" -h -h -v -v ./$(SCRIPT) | gzip - > $@
 
 uninstall:
        $(RM) -r $(LICENSEDIR) $(LIBDIR)
        $(RM) $(MANDIR)/$(MANPAGE) $(BINDIR)/$(PKGNAME)
 
-.PHONY: install uninstall
+.PHONY: install uninstall check_help2man

DPI creeping up by 1 on every execution

Hi,

I have a weird issue using mons. Whenever I switch monitors with the utility, the xrandr used DPI creeps up by 1, resulting in everything newly opened being unreasonably large after a while.

For reference, my laptop's display is a 13.3" 1080p screen for which I usually use a dpi of 120x120. The external monitor I'm connecting is a 20" 1050p one with 96x96 dpi.

This screenshot shows the bug in action (from what I see, it seems to be detecting the physical dimensions as smaller and smaller?): https://i.imgur.com/uPXV1og.jpg

Might be a problem with xrandr auto-detect, but when I use normal xrandr commands (e.g. xrandr --output eDP-1-1 --auto --output HDMI-0 --auto --right-of eDP-1-1) this bug doesn't occur.

Daemon mode causes stuttering when two monitors are connected

Firstly, great project. mons is exactly what I needed to manage multiple monitors using i3wm.

To the issue I am having: running mons in daemon mode with two monitors cause a small stuttering each dozen of seconds, that is quite noticiable when watching a video. The issue seems to be xrandr itself, that causes this stuttering when two monitors are enabled, however if only one monitor is connected there is no problem. To easily reproduce the problem, you can run in a terminal;

while true; do xrandr; done

With two monitor connected, open a video in YouTube for example. The frame rate is completely choppy. Of course, mons runs xrandr in a much slower rate (each 3 seconds it seems by looking at the code), however it is still distracting.

I don't know a good solution. Maybe this could be fixable in xrandr itself, maybe not. Or there could be another way to query the connected monitors instead of using xrandr. Any ideas?

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.