1 ---------------------------------------------------------------
2 -- Basic scratchpad manager for the awesome window manager
3 ---------------------------------------------------------------
4 -- Coded by: * Adrian C. (anrxc) <anrxc@sysphere.org>
5 -- Licensed under the WTFPL version 2
6 -- * http://sam.zoy.org/wtfpl/COPYING
7 ---------------------------------------------------------------
8 -- To use this module add:
10 -- to the top of your rc.lua, and call:
11 -- scratch.pad.set(c, width, height, sticky, screen)
12 -- from a clientkeys binding, and:
13 -- scratch.pad.toggle(screen)
14 -- from a globalkeys binding.
17 -- c - Client to scratch or un-scratch
18 -- width - Width in absolute pixels, or width percentage
19 -- when <= 1 (0.50 (50% of the screen) by default)
20 -- height - Height in absolute pixels, or height percentage
21 -- when <= 1 (0.50 (50% of the screen) by default)
22 -- sticky - Visible on all tags, false by default
23 -- screen - Screen (optional), mouse.screen by default
24 ---------------------------------------------------------------
27 local awful = require("awful")
34 -- Scratchpad: basic scratchpad manager for the awesome window manager
39 -- Toggle a set of properties on a client.
40 local function toggleprop(c, prop)
41 c.ontop = prop.ontop or false
42 c.above = prop.above or false
43 c.hidden = prop.hidden or false
44 c.sticky = prop.stick or false
45 c.skip_taskbar = prop.task or false
48 -- Scratch the focused client, or un-scratch and tile it. If another
49 -- client is already scratched, replace it with the focused client.
50 function set(c, width, height, sticky, screen)
52 height = height or 0.50
53 sticky = sticky or false
54 screen = screen or capi.mouse.screen
56 local function setscratch(c)
57 -- Scratchpad is floating and has no titlebar
58 awful.client.floating.set(c, true); awful.titlebar.remove(c)
60 -- Scratchpad client properties
61 toggleprop(c, {ontop=true, above=true, task=true, stick=sticky})
63 -- Scratchpad geometry and placement
64 local screengeom = capi.screen[screen].workarea
65 if width <= 1 then width = screengeom.width * width end
66 if height <= 1 then height = screengeom.height * height end
68 c:geometry({ -- Scratchpad is always centered on screen
69 x = screengeom.x + (screengeom.width - width) / 2,
70 y = screengeom.y + (screengeom.height - height) / 2,
71 width = width, height = height
74 -- Scratchpad should not loose focus
75 c:raise(); capi.client.focus = c
78 -- Prepare a table for storing clients,
79 if not scratchpad.pad then scratchpad.pad = {}
80 -- add unmanage signal for scratchpad clients
81 capi.client.add_signal("unmanage", function (c)
82 if scratchpad.pad[screen] == c then
83 scratchpad.pad[screen] = nil
88 -- If the scratcphad is emtpy, store the client,
89 if not scratchpad.pad[screen] then
90 scratchpad.pad[screen] = c
91 -- then apply geometry and properties
93 else -- If a client is already scratched,
94 local oc = scratchpad.pad[screen]
95 -- unscratch, and compare it with the focused client
96 awful.client.floating.toggle(oc); toggleprop(oc, {})
97 -- If it matches clear the table, if not replace it
98 if oc == c then scratchpad.pad[screen] = nil
99 else scratchpad.pad[screen] = c; setscratch(c) end
103 -- Move the scratchpad to the current workspace, focus and raise it
104 -- when it's hidden, or hide it when it's visible.
105 function toggle(screen)
106 screen = screen or capi.mouse.screen
108 -- Check if we have a client on storage,
109 if scratchpad.pad and
110 scratchpad.pad[screen] ~= nil
111 then -- and get it out, to play
112 local c = scratchpad.pad[screen]
114 -- If it's visible on another tag hide it,
115 if c:isvisible() == false then c.hidden = true
116 -- and move it to the current worskpace
117 awful.client.movetotag(awful.tag.selected(screen), c)
120 -- Focus and raise if it's hidden,
122 awful.placement.centered(c)
124 c:raise(); capi.client.focus = c
125 else -- hide it if it's not