summaryrefslogtreecommitdiff
path: root/scratch
diff options
context:
space:
mode:
authorAdrian C. (anrxc) <anrxc@sysphere.org>2010-01-29 23:43:13 +0100
committerAdrian C. (anrxc) <anrxc@sysphere.org>2010-01-29 23:43:13 +0100
commitdd090013fda59ba0c77e88a618802bec9ecb4960 (patch)
tree4671c9e99e4408905799e30b7d77ab5fe58a5534 /scratch
parent5b4be976ab72351435e385101722c05ec2ffd76b (diff)
downloadawesome-configs-dd090013fda59ba0c77e88a618802bec9ecb4960.tar.xz
scratch: combined teardrop and scratchpad
First step in integrating teardrop and scratchpad. With time the operations common to both modules should be made available to both, removing all duplication. Modules are split, even though they could function as just one module, scratchpad could get tabbing support (or other means of scratching multiple clients) so let's keep things clean.
Diffstat (limited to 'scratch')
-rw-r--r--scratch/drop.lua129
-rw-r--r--scratch/init.lua12
-rw-r--r--scratch/pad.lua129
3 files changed, 270 insertions, 0 deletions
diff --git a/scratch/drop.lua b/scratch/drop.lua
new file mode 100644
index 0000000..f5cff97
--- /dev/null
+++ b/scratch/drop.lua
@@ -0,0 +1,129 @@
+-------------------------------------------------------------------
+-- Drop-down applications manager for the awesome window manager
+-------------------------------------------------------------------
+-- Coded by: * Adrian C. (anrxc) <anrxc@sysphere.org>
+-- * Lucas de Vries <lucas@glacicle.com>
+-- Licensed under the WTFPL version 2
+-- * http://sam.zoy.org/wtfpl/COPYING
+-------------------------------------------------------------------
+-- To use this module add:
+-- require("scratch")
+-- to the top of your rc.lua, and call it from a keybinding:
+-- scratch.drop(prog, vert, horiz, width, height, sticky, screen)
+--
+-- Parameters:
+-- prog - Program to run; "urxvt", "gmrun", "thunderbird"
+-- vert - Vertical; "bottom", "center" or "top" (default)
+-- horiz - Horizontal; "left", "right" or "center" (default)
+-- width - Width in absolute pixels, or width percentage
+-- when <= 1 (1 (100% of the screen) by default)
+-- height - Height in absolute pixels, or height percentage
+-- when <= 1 (0.25 (25% of the screen) by default)
+-- sticky - Visible on all tags, false by default
+-- screen - Screen (optional), mouse.screen by default
+-------------------------------------------------------------------
+
+-- Grab environment
+local pairs = pairs
+local awful = require("awful")
+local setmetatable = setmetatable
+local capi = {
+ mouse = mouse,
+ client = client,
+ screen = screen
+}
+
+-- Scratchdrop: drop-down applications manager for the awesome window manager
+module("scratch.drop")
+
+local dropdown = {}
+
+-- Create a new window for the drop-down application when it doesn't
+-- exist, or toggle between hidden and visible states when it does
+function toggle(prog, vert, horiz, width, height, sticky, screen)
+ local vert = vert or "top"
+ local horiz = horiz or "center"
+ local width = width or 1
+ local height = height or 0.25
+ local sticky = sticky or false
+ local screen = screen or capi.mouse.screen
+
+ if not dropdown[prog] then
+ dropdown[prog] = {}
+
+ -- Add unmanage signal for scratchdrop programs
+ capi.client.add_signal("unmanage", function (c)
+ for scr, cl in pairs(dropdown[prog]) do
+ if cl == c then
+ dropdown[prog][scr] = nil
+ end
+ end
+ end)
+ end
+
+ if not dropdown[prog][screen] then
+ spawnw = function (c)
+ dropdown[prog][screen] = c
+
+ -- Scratchdrop clients are floaters
+ awful.client.floating.set(c, true)
+
+ -- Client geometry and placement
+ local screengeom = capi.screen[screen].workarea
+
+ if width <= 1 then width = screengeom.width * width end
+ if height <= 1 then height = screengeom.height * height end
+
+ if horiz == "left" then x = screengeom.x
+ elseif horiz == "right" then x = screengeom.width - width
+ else x = screengeom.x+(screengeom.width-width)/2 end
+
+ if vert == "bottom" then y = screengeom.height + screengeom.y - height
+ elseif vert == "center" then y = screengeom.y+(screengeom.height-height)/2
+ else y = screengeom.y - screengeom.y end
+
+ -- Client properties
+ c:geometry({ x = x, y = y, width = width, height = height })
+ c.ontop = true
+ c.above = true
+ c.skip_taskbar = true
+ if sticky then c.sticky = true end
+ if c.titlebar then awful.titlebar.remove(c) end
+
+ c:raise()
+ capi.client.focus = c
+ capi.client.remove_signal("manage", spawnw)
+ end
+
+ -- Add manage signal and spawn the program
+ capi.client.add_signal("manage", spawnw)
+ awful.util.spawn(prog, false)
+ else
+ -- Get a running client
+ c = dropdown[prog][screen]
+
+ -- Switch the client to the current workspace
+ if c:isvisible() == false then c.hidden = true
+ awful.client.movetotag(awful.tag.selected(screen), c)
+ end
+
+ -- Focus and raise if hidden
+ if c.hidden then
+ -- Make sure it is centered
+ if vert == "center" then awful.placement.center_vertical(c) end
+ if horiz == "center" then awful.placement.center_horizontal(c) end
+ c.hidden = false
+ c:raise()
+ capi.client.focus = c
+ else -- Hide and detach tags if not
+ c.hidden = true
+ local ctags = c:tags()
+ for i, t in pairs(ctags) do
+ ctags[i] = nil
+ end
+ c:tags(ctags)
+ end
+ end
+end
+
+setmetatable(_M, { __call = function(_, ...) return toggle(...) end })
diff --git a/scratch/init.lua b/scratch/init.lua
new file mode 100644
index 0000000..eb037fc
--- /dev/null
+++ b/scratch/init.lua
@@ -0,0 +1,12 @@
+---------------------------------------------------------------
+-- Drop-down applications and scratchpad manager for awesome wm
+---------------------------------------------------------------
+-- Coded by: * Adrian C. (anrxc) <anrxc@sysphere.org>
+-- Licensed under the WTFPL version 2
+-- * http://sam.zoy.org/wtfpl/COPYING
+---------------------------------------------------------------
+
+require("scratch.pad")
+require("scratch.drop")
+
+module("scratch")
diff --git a/scratch/pad.lua b/scratch/pad.lua
new file mode 100644
index 0000000..a092f13
--- /dev/null
+++ b/scratch/pad.lua
@@ -0,0 +1,129 @@
+---------------------------------------------------------------
+-- Basic scratchpad manager for the awesome window manager
+---------------------------------------------------------------
+-- Coded by: * Adrian C. (anrxc) <anrxc@sysphere.org>
+-- Licensed under the WTFPL version 2
+-- * http://sam.zoy.org/wtfpl/COPYING
+---------------------------------------------------------------
+-- To use this module add:
+-- require("scratch")
+-- to the top of your rc.lua, and call:
+-- scratch.pad.set(c, width, height, sticky, screen)
+-- from a clientkeys binding, and:
+-- scratch.pad.toggle(screen)
+-- from a globalkeys binding.
+--
+-- Parameters:
+-- c - Client to scratch or un-scratch
+-- width - Width in absolute pixels, or width percentage
+-- when <= 1 (0.50 (50% of the screen) by default)
+-- height - Height in absolute pixels, or height percentage
+-- when <= 1 (0.50 (50% of the screen) by default)
+-- sticky - Visible on all tags, false by default
+-- screen - Screen (optional), mouse.screen by default
+---------------------------------------------------------------
+
+-- Grab environment
+local awful = require("awful")
+local capi = {
+ mouse = mouse,
+ client = client,
+ screen = screen
+}
+
+-- Scratchpad: basic scratchpad manager for the awesome window manager
+module("scratch.pad")
+
+local scratchpad = {}
+
+-- Toggle a set of properties on a client.
+local function toggleprop(c, prop)
+ c.ontop = prop.ontop or false
+ c.above = prop.above or false
+ c.hidden = prop.hidden or false
+ c.sticky = prop.stick or false
+ c.skip_taskbar = prop.task or false
+end
+
+-- Scratch the focused client, or un-scratch and tile it. If another
+-- client is already scratched, replace it with the focused client.
+function set(c, width, height, sticky, screen)
+ local width = width or 0.50
+ local height = height or 0.50
+ local sticky = sticky or false
+ local screen = screen or capi.mouse.screen
+
+ local function setscratch(c)
+ -- Scratchpad is floating and has no titlebar
+ awful.client.floating.set(c, true); awful.titlebar.remove(c)
+
+ -- Scratchpad client properties
+ toggleprop(c, {ontop=true, above=true, task=true, stick=sticky})
+
+ -- Scratchpad geometry and placement
+ local screengeom = capi.screen[screen].workarea
+ if width <= 1 then width = screengeom.width * width end
+ if height <= 1 then height = screengeom.height * height end
+
+ c:geometry({ -- Scratchpad is always centered on screen
+ x = screengeom.x + (screengeom.width - width) / 2,
+ y = screengeom.y + (screengeom.height - height) / 2,
+ width = width, height = height
+ })
+
+ -- Scratchpad should not loose focus
+ c:raise(); capi.client.focus = c
+ end
+
+ -- Prepare a table for storing clients,
+ if not scratchpad.pad then scratchpad.pad = {}
+ -- add unmanage signal for scratchpad clients
+ capi.client.add_signal("unmanage", function (c)
+ if scratchpad.pad[screen] == c then
+ scratchpad.pad[screen] = nil
+ end
+ end)
+ end
+
+ -- If the scratcphad is emtpy, store the client,
+ if not scratchpad.pad[screen] then
+ scratchpad.pad[screen] = c
+ -- then apply geometry and properties
+ setscratch(c)
+ else -- If a client is already scratched,
+ local oc = scratchpad.pad[screen]
+ -- unscratch, and compare it with the focused client
+ awful.client.floating.toggle(oc); toggleprop(oc, {})
+ -- If it matches clear the table, if not replace it
+ if oc == c then scratchpad.pad[screen] = nil
+ else scratchpad.pad[screen] = c; setscratch(c) end
+ end
+end
+
+-- Move the scratchpad to the current workspace, focus and raise it
+-- when it's hidden, or hide it when it's visible.
+function toggle(screen)
+ local screen = screen or capi.mouse.screen
+
+ -- Check if we have a client on storage,
+ if scratchpad.pad and
+ scratchpad.pad[screen] ~= nil
+ then -- and get it out, to play
+ local c = scratchpad.pad[screen]
+
+ -- If it's visible on another tag hide it,
+ if c:isvisible() == false then c.hidden = true
+ -- and move it to the current worskpace
+ awful.client.movetotag(awful.tag.selected(screen), c)
+ end
+
+ -- Focus and raise if it's hidden,
+ if c.hidden then
+ awful.placement.centered(c)
+ c.hidden = false
+ c:raise(); capi.client.focus = c
+ else -- hide it if it's not
+ c.hidden = true
+ end
+ end
+end