-- -*- 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