From dd090013fda59ba0c77e88a618802bec9ecb4960 Mon Sep 17 00:00:00 2001 From: "Adrian C. (anrxc)" Date: Fri, 29 Jan 2010 23:43:13 +0100 Subject: 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. --- scratch/drop.lua | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 scratch/drop.lua (limited to 'scratch/drop.lua') 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) +-- * Lucas de Vries +-- 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 }) -- cgit v1.2.3