183 lines
5.7 KiB
Lua
183 lines
5.7 KiB
Lua
-- -*- 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
|