Skip to content

Choosing a Monitor Configuration

Harry R. Schwartz edited this page Mar 3, 2018 · 2 revisions

I've got an external monitor that's occasionally hooked up to my laptop. I have several monitor configurations: the laptop could be alone, the external monitor could be on either side, the external monitor could be rotated 90°, etc.

I store these configurations in a JSON file in my home directory, and I've written a small script to select and apply them.

The Script

#!/usr/bin/env ruby

require "json"
require "fuzz"

SCREEN_LAYOUT_DEFINITIONS = File.expand_path("~/.screen-layouts.json")

class MonitorConfiguration
  def initialize(command:, name:)
    @command = command
    @name = name
  end

  def to_s
    name
  end

  def exec
    system(command)
  end

  def self.from_json(json)
    new(
      name: json.fetch("name"),
      command: json.fetch("command"),
    )
  end

  private

  attr_reader :command, :name
end

json = JSON.parse(File.read(SCREEN_LAYOUT_DEFINITIONS))
configurations = json.map { |config| MonitorConfiguration.from_json(config) }

chosen_configuration = Fuzz::Selector.new(
  configurations,
  cache: Fuzz::Cache.new("~/.cache/fuzz/change_monitor"),
).pick

chosen_configuration.exec

Configuration File (~/.screen-layouts.json)

You can use write these commands manually, if you want, but I put 'em together with the arandr GUI. It lets you visually create a configuration and provides a way to export the associated xrandr commands.

[
  {
    "name": "laptop",
    "command": "xrandr --output DP-2-1 --off --output eDP-1 --primary --mode 2560x1440 --pos 0x0 --rotate normal"
  },
  {
    "name": "external (video, left)",
    "command": "xrandr --output DP-2-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output eDP-1 --mode 2560x1440 --pos 1920x0 --rotate normal"
  },
  {
    "name": "external (text, left)",
    "command": "xrandr --output DP-2-1 --primary --mode 1920x1080 --pos 0x0 --rotate right --output eDP-1 --mode 2560x1440 --pos 1080x0 --rotate normal"
  },
  {

    "name": "external (video, right)",
    "command": "xrandr --output DP-2-1 --primary --mode 1920x1080 --pos 2560x0 --rotate normal --output eDP-1 --mode 2560x1440 --pos 0x0 --rotate normal"
  },
  {

    "name": "external (text, right)",
    "command": "xrandr --output DP-2-1 --primary --mode 1920x1080 --pos 2560x0 --rotate left --output eDP-1 --mode 2560x1440 --pos 0x0 --rotate normal"
  }
]