GithubHelp home page GithubHelp logo

dogonthehorizon / togglemon Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 85 KB

A simple program for toggling displays via xrandr on Linux.

Haskell 97.77% Makefile 2.23%
edid xrandr toggling-displays laptop monitor linux haskell

togglemon's Introduction

togglemon

A small program for toggling monitors in Linux. Ideal use case is a laptop with a single video card and single external display. Works best when triggered via a udev event for automatic display management.

Articles

The following articles have been written about togglemon:

Motivation

I used to have a few shell scripts to manually toggle the displays using xrandr, but they were rather brittle and depended on plugging the monitor into the same port on my laptop.

Rather than deal with this frustration, an overengineered program was written to make sure the minor annoyance of running a script was never encountered again. Progress!

Figuring out how this all works

Displays appear to have a directory in sys/class/drm and follow the pattern videoCard-display-number. That is, the first DisplayPort peripheral for a laptop's video card would look like card0-DP-1. The internal display appears to have e prepended to the display type (e.g. card0-eDP-1). This sysfs directory is managed by the Direct Rendering Manager (DRM for short, unfortunate as that acronym is). The contents of this directory include a few interesting files:

File Purpose
status is the display currently connected?
enabled is the display currently in use?
edid binary file containing display information

enabled can have two states:

  • disabled
  • enabled

status can have two states:

  • connected
  • disconnected

The edid file has it's own format.

The basic strategy would seem to be:

  • Get the contents of sys/class/drm
  • For each entry:
    • Check contents of status and enabled files
    • Build DisplayMatrix object (or some such)
  • Given a DisplayMatrix:
    • Find the display that is connected but disabled
    • Find the display that is connected and enabled
    • Construct an xrandr command to toggle them
    • Execute command

Iteration on Initial Design

With the ability to parse edid information it would be great to have a config format that would allow one to set xrandr display options per-display, irrespective of which port the display is plugged into.

Depending on how much information is provided in the edid file for each monitor, it may be possible to achieve this in the following way.

Implement something like ~/.config/togglemon/known_displays.yaml similar in spirit to the known_hosts file in SSH. This file contains the parsed edid information of each monitor that it's seen and gives it some kind of generated, human readable name (similar to how docker randomly names it's containers).

The user then would make their own config file (perhaps ~/.config/togglemon/config.yaml) that would reference these displays and the xrandr options they wish to be executed.

Maybe something like this:

# ~/.config/togglemon/known_displays.yaml
prancing-pangolin:
  manufacturerId: SHP
  manufacturerProductCode: 1111
  serialNumber: 123412341234
  weekOfManufacture: 52
  yearOfManufacture: 2018
  edidVersion: 1.4
# Who knows if all that information would be useful, but it would increase
# the likelihood that we would get a unique monitor from all that information.
# For example: my current laptop display does not appear to have a serial
# number (it appears zeroed out), so it's likely we can't depend on a single
# field being setup correctly.
# ~/.config/togglemon/config.yaml
prancing-pangolin:
  xrandrOpts:
    - auto
    - position 0x0

Thinking Further Afield

  • At what point is it possible to dump xrandr entirely?

togglemon's People

Contributors

dogonthehorizon avatar

Watchers

 avatar  avatar

togglemon's Issues

Support serialization

It'd be useful to support writing edid formatted files as well as reading them. If only for the testing benefits, but also because it'd be neat to have a well-tested way to write edid files.

Add debug logging

Right now the debug process is running the xformer stack in the REPL.

Ideally we want logging throughout the application that can be turned on when needed, and at different verbosity levels. For this card it's sufficient to have debug logging at all.

Probably via Katip?

Add dry-run mode

As a user, I'd like to do a dry-run before applying, so that I can see what xrandr configuration togglemon has determined for me

Write known displays to XDG data dir on every invocation

At the successful conclusion of every run we should be sure to persist any new display configurations to disk.

One idea for accomplishing this is to use a state-like Monad to keep track of displays throughout the run of the program. When we're ready to persist, if initial and terminal states are different, then write to disk, otherwise do nothing.

Profile support

As a user, I'd like to configure monitors with profiles, so I don't use static xrandr config options.

Refactor DisplayConfiguration to typeclass

Right now display configurations are contained in a sum type, but that doesn't provide an easy way to extend configurations down the road.

Better to have a typeclass that individual types implement.

Something like this perhaps:

class DisplayConfiguration a where
  getConfiguration :: [Display] -> Maybe a
  toXrandrCommand :: a -> Text

Refactor display parsing to include edid information

A display should also include it's own edid information. We may want to wrap functionality provided in edid so that we can provide a consistent naming scheme for edids found. Probably warrants it's own type (currently defining a rough one in ToggleMon.Config)

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.