awesome/lib/awful/widget/tasklist.lua.in

206 lines
7.7 KiB
Lua

---------------------------------------------------------------------------
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008-2009 Julien Danjou
-- @release @AWESOME_VERSION@
---------------------------------------------------------------------------
-- Grab environment we need
local capi = { screen = screen,
client = client }
local ipairs = ipairs
local setmetatable = setmetatable
local table = table
local common = require("awful.widget.common")
local beautiful = require("beautiful")
local client = require("awful.client")
local util = require("awful.util")
local tag = require("awful.tag")
local flex = require("wibox.layout.flex")
--- Tasklist widget module for awful
module("awful.widget.tasklist")
-- Public structures
filter = {}
local function tasklist_label(c, args)
if not args then args = {} end
local theme = beautiful.get()
local fg_focus = args.fg_focus or theme.tasklist_fg_focus or theme.fg_focus
local bg_focus = args.bg_focus or theme.tasklist_bg_focus or theme.bg_focus
local fg_urgent = args.fg_urgent or theme.tasklist_fg_urgent or theme.fg_urgent
local bg_urgent = args.bg_urgent or theme.tasklist_bg_urgent or theme.bg_urgent
local fg_minimize = args.fg_minimize or theme.tasklist_fg_minimize or theme.fg_minimize
local bg_minimize = args.bg_minimize or theme.tasklist_bg_minimize or theme.bg_minimize
local font = args.font or theme.tasklist_font or theme.font or ""
local bg = nil
local text = "<span font_desc='"..font.."'>"
local name = ""
if c.ontop then name = name .. "" end
if client.floating.get(c) then name = name .. "" end
if c.maximized_horizontal then name = name .. '' end
if c.maximized_vertical then name = name .. "" end
if c.minimized then
name = name .. (util.escape(c.icon_name) or util.escape(c.name) or util.escape("<untitled>"))
else
name = name .. (util.escape(c.name) or util.escape("<untitled>"))
end
if capi.client.focus == c then
bg = bg_focus
if fg_focus then
text = text .. "<span color='"..util.color_strip_alpha(fg_focus).."'>"..name.."</span>"
else
text = text .. name
end
elseif c.urgent and fg_urgent then
bg = bg_urgent
text = text .. "<span color='"..util.color_strip_alpha(fg_urgent).."'>"..name.."</span>"
elseif c.minimized and fg_minimize and bg_minimize then
bg = bg_minimize
text = text .. "<span color='"..util.color_strip_alpha(fg_minimize).."'>"..name.."</span>"
else
text = text .. name
end
text = text .. "</span>"
return text, bg, nil, c.icon
end
local function tasklist_update(s, w, buttons, filter, data, style)
local clients = {}
for k, c in ipairs(capi.client.get()) do
if not (c.skip_taskbar or c.hidden
or c.type == "splash" or c.type == "dock" or c.type == "desktop")
and filter(c, s) then
table.insert(clients, c)
end
end
local function label(c) return tasklist_label(c, style) end
common.list_update(w, buttons, label, data, clients)
end
--- Create a new tasklist widget.
-- @param screen The screen to draw tasklist for.
-- @param filter Filter function to define what clients will be listed.
-- @param buttons A table with buttons binding to set.
-- @param style The style overrides default theme.
-- bg_focus The background color for focused client.
-- fg_focus The foreground color for focused client.
-- bg_urgent The background color for urgent clients.
-- fg_urgent The foreground color for urgent clients.
-- bg_minimize The background color for minimized clients.
-- fg_minimize The foreground color for minimized clients.
-- floating_icon The icon for flating clients.
-- font The font.
function new(screen, filter, buttons, style)
local w = flex.horizontal()
local data = setmetatable({}, { __mode = 'kv' })
local u = function () tasklist_update(screen, w, buttons, filter, data, style) end
capi.screen[screen]:connect_signal("tag::detach", u)
tag.attached_connect_signal(screen, "property::selected", u)
capi.client.connect_signal("property::urgent", u)
capi.client.connect_signal("property::ontop", u)
capi.client.connect_signal("property::floating", u)
capi.client.connect_signal("property::maximized_horizontal", u)
capi.client.connect_signal("property::maximized_vertical", u)
capi.client.connect_signal("property::minimized", u)
capi.client.connect_signal("property::name", u)
capi.client.connect_signal("property::icon_name", u)
capi.client.connect_signal("property::icon", u)
capi.client.connect_signal("property::skip_taskbar", u)
capi.client.connect_signal("property::hidden", u)
capi.client.connect_signal("tagged", u)
capi.client.connect_signal("untagged", u)
capi.client.connect_signal("unmanage", u)
capi.client.connect_signal("list", u)
capi.client.connect_signal("focus", u)
capi.client.connect_signal("unfocus", u)
u()
return w
end
--- Filtering function to include all clients.
-- @param c The client.
-- @param screen The screen we are drawing on.
-- @return true
function filter.allscreen(c, screen)
return true
end
--- Filtering function to include the clients from all tags on the screen.
-- @param c The client.
-- @param screen The screen we are drawing on.
-- @return true if c is on screen, false otherwise
function filter.alltags(c, screen)
-- Only print client on the same screen as this widget
if c.screen ~= screen then return false end
return true
end
--- Filtering function to include only the clients from currently selected tags.
-- @param c The client.
-- @param screen The screen we are drawing on.
-- @return true if c is in a selected tag on screen, false otherwise
function filter.currenttags(c, screen)
-- Only print client on the same screen as this widget
if c.screen ~= screen then return false end
-- Include sticky client too
if c.sticky then return true end
tags = capi.screen[screen]:tags()
for k, t in ipairs(tags) do
if t.selected then
local ctags = c:tags()
for _, v in ipairs(ctags) do
if v == t then
return true
end
end
end
end
return false
end
--- Filtering function to include only the minimized clients from currently selected tags.
-- @param c The client.
-- @param screen The screen we are drawing on.
-- @return true if c is in a selected tag on screen and is minimized, false otherwise
function filter.minimizedcurrenttags(c, screen)
-- Only print client on the same screen as this widget
if c.screen ~= screen then return false end
-- Include sticky client
if c.sticky then return true end
-- Check client is minimized
if not c.minimized then return false end
tags = capi.screen[screen]:tags()
for k, t in ipairs(tags) do
-- Select only minimized clients
if t.selected then
local ctags = c:tags()
for _, v in ipairs(ctags) do
if v == t then
return true
end
end
end
end
return false
end
--- Filtering function to include only the currently focused client.
-- @param c The client.
-- @param screen The screen we are drawing on.
-- @return true if c is focused on screen, false otherwise
function filter.focused(c, screen)
-- Only print client on the same screen as this widget
if c.screen == screen and capi.client.focus == c then
return true
end
return false
end
setmetatable(_M, { __call = function(_, ...) return new(...) end })
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80