summaryrefslogtreecommitdiffstats
path: root/.config/awesome/infoline.lua
diff options
context:
space:
mode:
Diffstat (limited to '.config/awesome/infoline.lua')
-rw-r--r--.config/awesome/infoline.lua183
1 files changed, 183 insertions, 0 deletions
diff --git a/.config/awesome/infoline.lua b/.config/awesome/infoline.lua
new file mode 100644
index 0000000..2b8e00c
--- /dev/null
+++ b/.config/awesome/infoline.lua
@@ -0,0 +1,183 @@
+-- -*- coding: utf-8 -*-
+--------------------------------------------------------------------------------
+-- @author Nicolas Berthier <nberthier@gmail.com>
+-- @copyright 2010 Nicolas Berthier
+--------------------------------------------------------------------------------
+--
+-- This is a module for defining infolines in awesome. An infoline is a wibox
+-- attached to a region (typically, a client or the root window).
+--
+-- Remarks:
+--
+-- - It has not been tested with multiple screens yet.
+--
+-- Example usage: (TODO --- read the comments for now, there are not many
+-- functions)
+--
+--------------------------------------------------------------------------------
+
+--{{{ Grab environment (mostly aliases)
+local setmetatable = setmetatable
+local ipairs = ipairs
+local type = type
+local pairs = pairs
+local string = string
+local print = print
+local error = error
+local io = io
+
+local client = client
+local awesome = awesome
+local wibox = wibox
+local widget = widget
+local root = root
+local screen = screen
+local mouse = mouse
+--}}}
+
+module ("infoline")
+
+-- Privata data: we use weak keys in order to allow collection of private data
+-- if keys (clients) are collected (i.e., no longer used, after having been
+-- killed for instance).
+--
+-- XXX: For now, we have at most one infoline per client, but it could be
+-- interesting to create several types of infolines (identified by indexes to be
+-- allocated by this module), and associated to, e.g., different configuration
+-- flags and positioning routine...
+local data = setmetatable ({}, { __mode = 'k' })
+
+--{{{ Infoline positioning
+
+-- XXX: this is a hack that positions an infoline at the bottom of a given area.
+local function setup_position (wb, geom)
+ local b = wb:geometry ()
+ b.x = geom.x
+ b.width = geom.width
+ b.y = geom.y + geom.height - awesome.font_height
+ b.height = awesome.font_height
+ wb:geometry (b)
+end
+
+--}}}
+
+--{{{ Configurations:
+
+-- When true, this flag indicates that an infoline is hidden if its attached
+-- client loses its focus. Otherwise, it remains always visible.
+follow_focus = true
+
+--}}}
+
+--{{{ Infoline updates
+
+function get_text (il) return il.wb.widgets[1].text end
+function set_text (il, text) il.wb.widgets[1].text = text end
+
+-- Forces a refresh of the given infoline.
+function update (il)
+ local wb = il.wb
+ local c = il.cli
+
+ if il.enabled then
+ -- XXX: Note this could be much better if we had some sort of root and
+ -- client interface unification: the following involves a priori useless
+ -- code duplication...
+ if c == root then
+ wb.screen = mouse.screen -- XXX: is this the behavior we need?
+ wb.visible = true
+ setup_position (wb, screen[mouse.screen].workarea)
+ else
+ if c:isvisible () and (not follow_focus or client.focus == c) then
+ wb.screen = c.screen
+ wb.visible = true
+ setup_position (wb, c:geometry ())
+ else -- do we have to hide it?
+ wb.visible = false
+ end
+ end
+ elseif wb.visible then --otherwise we need to hide it.
+ wb.visible = false
+ end
+end
+
+local function update_from_client (c)
+ -- Note that we may not have an infoline for this client, hence the
+ -- conditional...
+ if data[c] then update (data[c]) end
+end
+
+-- Force execution of the above function on client state modification.
+client.add_signal ("focus", update_from_client)
+client.add_signal ("unfocus", update_from_client)
+client.add_signal ("unmanage", update_from_client)
+
+--}}}
+
+--{{{ Infoline management
+
+--- Creates a new infoline, with the given initial text. Note it is not visible
+--- by default, and not attached to any client.
+function new (text)
+ local il = {
+ wb = wibox ({
+ ontop = true, -- XXX: setting a depth when attaching to
+ --a client would be much better
+ widgets = {
+ widget ({ type = "textbox", align="left" })
+ },
+ })
+ }
+ -- these will remain false until the infoline is attached to a client.
+ il.wb.visible = false
+ il.enabled = false
+ set_text (il, text or "")
+ return il
+end
+
+-- Attached infolines will react to the following client-related signals, and
+-- automatically setup their position according to the client's geometry.
+local csignals = { "property::geometry", "property::minimized",
+ "property::visible", "property::focus", "property::screen", }
+
+-- Attaches an infoline to a client. Note the infoline becomes visible at that
+-- time, if the client is currently visible (and if it has focus, when
+-- `follow_focus' holds).
+function attach (il, c)
+ data[c] = il
+ il.cli = c
+ il.enabled = true
+ update (il)
+ if c ~= root then
+ -- subscribe to client-related signals
+ for _, s in ipairs (csignals) do
+ c:add_signal (s, update_from_client)
+ end
+ end
+end
+
+--- Detach the given infoline from its client, if any.
+function dispose (il)
+ local c = il.cli
+ if c then -- note c can be nil here, if the given infoline has not been
+ --attached to any client...
+ il.enabled = false
+ update (il) -- a shortcut here would be: `il.wb.visible = false'
+ data[c] = nil
+ if c ~= root then
+ -- unsubscribe from client-related signals
+ for _, s in ipairs (csignals) do
+ c:remove_signal (s, update_from_client)
+ end
+ end
+ end
+end
+
+--}}}
+
+-- Local variables:
+-- indent-tabs-mode: nil
+-- fill-column: 80
+-- lua-indent-level: 4
+-- End:
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80