diff options
Diffstat (limited to 'scratch')
-rw-r--r-- | scratch/drop.lua | 129 | ||||
-rw-r--r-- | scratch/init.lua | 12 | ||||
-rw-r--r-- | scratch/pad.lua | 129 |
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 |