From d12b5f5c0e52bcdda4882e81363ddb79e35fae69 Mon Sep 17 00:00:00 2001 From: Jeferson Siqueira Date: Thu, 26 Jan 2017 22:26:40 -0300 Subject: [PATCH] Add xrandr.lua multiple monitor recipe (#73) --- recipes.mdwn | 3 + recipes/xrandr.lua | 147 ++++++++++++++++++++++++++++++++++++++++++++ recipes/xrandr.mdwn | 23 +++++++ 3 files changed, 173 insertions(+) create mode 100644 recipes/xrandr.lua create mode 100644 recipes/xrandr.mdwn diff --git a/recipes.mdwn b/recipes.mdwn index 41f4a52..7f56c58 100644 --- a/recipes.mdwn +++ b/recipes.mdwn @@ -12,3 +12,6 @@ The recipes section is where you can find useful snippets and tutorials on how t * [Lain Widget Library](https://github.com/copycat-killer/lain) * [[MPD current song|recipes/mpc]] + +## Others +* [[Swap Monitor Snippet|recipes/xrandr]] diff --git a/recipes/xrandr.lua b/recipes/xrandr.lua new file mode 100644 index 0000000..9e57ed1 --- /dev/null +++ b/recipes/xrandr.lua @@ -0,0 +1,147 @@ +--- Separating Multiple Monitor functions as a separeted module (taken from awesome wiki) + +local awful = require("awful") +local naughty = require("naughty") +local beautiful = require("beautiful"); + +-- A path to a fancy icon +local icon_path = ""; + +-- Get active outputs +local function outputs() + local outputs = {} + local xrandr = io.popen("xrandr -q --current") + + if xrandr then + for line in xrandr:lines() do + local output = line:match("^([%w-]+) connected ") + if output then + outputs[#outputs + 1] = output + end + end + xrandr:close() + end + + return outputs +end + +local function arrange(out) + -- We need to enumerate all permutations of horizontal outputs. + + local choices = {} + local previous = { {} } + for i = 1, #out do + -- Find all permutation of length `i`: we take the permutation + -- of length `i-1` and for each of them, we create new + -- permutations by adding each output at the end of it if it is + -- not already present. + local new = {} + for _, p in pairs(previous) do + for _, o in pairs(out) do + if not awful.util.table.hasitem(p, o) then + new[#new + 1] = awful.util.table.join(p, {o}) + end + end + end + choices = awful.util.table.join(choices, new) + previous = new + end + + return choices +end + +-- Build available choices +local function menu() + local menu = {} + local out = outputs() + local choices = arrange(out) + + for _, choice in pairs(choices) do + local cmd = "xrandr" + -- Enabled outputs + for i, o in pairs(choice) do + cmd = cmd .. " --output " .. o .. " --auto" + if i > 1 then + cmd = cmd .. " --right-of " .. choice[i-1] + end + end + -- Disabled outputs + for _, o in pairs(out) do + if not awful.util.table.hasitem(choice, o) then + cmd = cmd .. " --output " .. o .. " --off" + end + end + + local label = "" + if #choice == 1 then + label = 'Only ' .. choice[1] .. '' + else + for i, o in pairs(choice) do + if i > 1 then label = label .. " + " end + label = label .. '' .. o .. '' + end + end + + menu[#menu + 1] = { label, + cmd, + icon_path} + end + + return menu +end + +-- Display xrandr notifications from choices +local state = { iterator = nil, + timer = nil, + cid = nil } +local function xrandr() + -- Stop any previous timer + if state.timer then + state.timer:stop() + state.timer = nil + end + + -- Build the list of choices + if not state.index then + state.menu = menu() + state.index = 1 + end + + -- Select one and display the appropriate notification + local label, action, icon + local next = state.menu[state.index] + state.index = state.index + 1 + + if not next then + label, icon = "Keep the current configuration", icon_path + state.iterator = nil + else + label, action, icon = unpack(next) + end + state.cid = naughty.notify({ text = label, + icon = icon, + timeout = 4, + screen = mouse.screen, + font = beautiful.font, + replaces_id = state.cid }).id + + -- Setup the timer + state.timer = timer { timeout = 4 } + state.timer:connect_signal("timeout", + function() + state.timer:stop() + state.timer = nil + state.iterator = nil + if action then + awful.util.spawn(action, false) + end + end) + state.timer:start() +end + +return { + outputs = outputs, + arrange = arrange, + menu = menu, + xrandr = xrandr +} diff --git a/recipes/xrandr.mdwn b/recipes/xrandr.mdwn new file mode 100644 index 0000000..742e9b8 --- /dev/null +++ b/recipes/xrandr.mdwn @@ -0,0 +1,23 @@ +# Multiple Monitor Helper + +This page is intended to show how to user `xrandr.lua` script to help the way you deal with multiple monitors. +Using this snippet you can set a keybinding where you swap to all possible arrangements of monitors. + +The process of setting up this script goes as follow: + +1. Create a file called `xrandr.lua` in your file system (preferably in awesome's folder) with the [script](xrandr.lua) content. + +2. Import the script in your `rc.lua` + + local xrandr = require("/path/to/file/xrandr") + +3. Create a keybinding to the script in the appropriated globalkeys table + +Pressing this key binding will open a popup with a possible screen arrangement. +Pressing the key again will replace this popup with another possibility, eventually arriving at "keep the current configuration". + +If the key is not pressed again within four seconds, the configuration described in the current popup is applied. + + + awful.key({}, "Some Key", function() xrandr.xrandr() end) +