Created
January 19, 2012 11:37
-
-
Save jaspervdj/1639530 to your computer and use it in GitHub Desktop.
Setup dual-screen and create a multi-monitor wallpaper using xrandr en RMagick
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# This script reads your monitor settings using the `xrandr` tool. It selects a | |
# random wallpaper for each monitor from a specified directory. A large image is | |
# created to fit all monitors, which can then be set using any tool. | |
require 'RMagick' | |
class Screen | |
attr_reader :name, :width, :height, :offset_x, :offset_y | |
def initialize(name, width, height, offset_x, offset_y) | |
@name = name | |
@width = width | |
@height = height | |
@offset_x = offset_x | |
@offset_y = offset_y | |
end | |
end | |
class Plane | |
attr_reader :width, :height, :screens | |
def initialize() | |
@width = 0 | |
@height = 0 | |
@screens = [] | |
end | |
def add_screen(screen) | |
@width = [@width, screen.offset_x + screen.width].max | |
@height = [@height, screen.offset_y+ screen.height].max | |
screens << screen | |
end | |
def print() | |
puts "Plane #{width}x#{height}" | |
screens.each do |s| | |
puts " Screen #{s.name}: " + | |
"#{s.width}x#{s.height} at #{s.offset_x},#{s.offset_y}" | |
end | |
end | |
end | |
def plane_from_xrandr() | |
plane = Plane.new() | |
`xrandr`.lines.each do |line| | |
if line =~ /^(.+) connected (\d+)x(\d+)\+(\d+)\+(\d+)/ then | |
screen = Screen.new($1, $2.to_i, $3.to_i, $4.to_i, $5.to_i) | |
plane.add_screen(screen) | |
end | |
end | |
return plane | |
end | |
def random_files(dir, n) | |
files = Dir.entries(dir).collect { |f| File.join(dir, f) }.select do |f| | |
File.file? f | |
end | |
files.shuffle.take(n) | |
end | |
def dual_screen() | |
plane = plane_from_xrandr() | |
plane.print() | |
if plane.screens.size == 2 then | |
primary = plane.screens.find { |s| s.name =~ /LVDS/ }.name | |
secondary = plane.screens.find { |s| s.name =~ /VGA/ }.name | |
`xrandr --output #{primary} --auto --primary` | |
`xrandr --output #{secondary} --auto --right-of #{primary}` | |
end | |
end | |
def make_wallpaper(wallpaper_dir, output_file) | |
plane = plane_from_xrandr() | |
plane.print() | |
wallpapers = random_files(wallpaper_dir, plane.screens.size) | |
image = Magick::Image.new(plane.width, plane.height) | |
plane.screens.each_with_index do |screen, i| | |
puts "Selected wallpaper #{wallpapers[i]} for screen #{i}" | |
wallpaper = Magick::Image.read(wallpapers[i]).first | |
wallpaper = wallpaper.resize_to_fill(screen.width, screen.height) | |
image = image.composite(wallpaper, screen.offset_x, screen.offset_y, | |
Magick::CopyCompositeOp) | |
end | |
puts "Writing to #{output_file}..." | |
image.write(output_file) | |
end | |
if ARGV.size >= 2 then | |
make_wallpaper(ARGV[0], ARGV[1]) | |
elsif ARGV.size == 0 then | |
dual_screen() | |
else | |
puts "Usage:" | |
puts "#{$0} <wallpaper dir> <output image> Generate a wallpaper" | |
puts "#{$0} Default dual-screen setup" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment