summaryrefslogtreecommitdiff
path: root/scratch/drop.lua
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/drop.lua
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/drop.lua')
-rw-r--r--scratch/drop.lua129
1 files changed, 129 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 })