awesome/lib/awful/titlebar.lua.in

172 lines
5.9 KiB
Lua
Raw Normal View History

---------------------------------------------------------------------------
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008 Julien Danjou
-- @release @AWESOME_VERSION@
---------------------------------------------------------------------------
-- Grab environment we need
local math = math
local pairs = pairs
local otable = otable
local capi =
{
wibox = wibox,
widget = widget,
button = button,
client = client,
}
local beautiful = require("awful.beautiful")
local hooks = require("awful.hooks")
local util = require("awful.util")
local widget = require("awful.widget")
--- Titlebar module for awful
module("awful.titlebar")
-- Privata data
local data = otable()
--- Create a standard titlebar.
-- @param c The client.
-- @param args Arguments.
-- fg: the foreground color.
-- bg: the background color.
-- fg_focus: the foreground color for focused window.
-- fg_focus: the background color for focused window.
-- width: the titlebar width
function add(c, args)
if not c or c.type ~= "normal" then return end
if not args then args = {} end
local theme = beautiful.get()
-- Store colors
data[c] = {}
data[c].fg = args.fg or theme.titlebar_fg_normal or theme.fg_normal
data[c].bg = args.bg or theme.titlebar_bg_normal or theme.bg_normal
data[c].fg_focus = args.fg_focus or theme.titlebar_fg_focus or theme.fg_focus
data[c].bg_focus = args.bg_focus or theme.titlebar_bg_focus or theme.bg_focus
data[c].width = args.width
local tb = capi.wibox(args)
local title = capi.widget({ type = "textbox", name = "title", align = "flex" })
title.text = " " .. util.escape(c.name) .. " "
-- Redirect relevant events to the client the titlebar belongs to
local bts =
{
capi.button({ }, 1, function (t) capi.client.focus = t.client t.client:raise() t.client:mouse_move() end),
capi.button({ args.modkey }, 1, function (t) t.client:mouse_move() end),
capi.button({ args.modkey }, 3, function (t) t.client:mouse_resize() end)
}
title:buttons(bts)
function title.mouse_enter(s) hooks.user.call('mouse_enter', c) end
local appicon = capi.widget({ type = "imagebox", name = "appicon", align = "left" })
appicon.image = c.icon
-- Also redirect events for appicon (So the entire titlebar behaves consistently)
appicon:buttons(bts)
function appicon.mouse_enter(s) hooks.user.call('mouse_enter', c) end
local closef
if theme.titlebar_close_button_focus then
closef = widget.button({ name = "closef", align = "right",
image = theme.titlebar_close_button_focus })
end
local close
if theme.titlebar_close_button_normal then
close = widget.button({ name = "close", align = "right",
image = theme.titlebar_close_button_normal })
end
if close or closef then
-- Bind kill button, also allow moving and resizing on this widget
local bts =
{
capi.button({ }, 1, nil, function (t) t.client:kill() end),
capi.button({ args.modkey }, 1, function (t) t.client:mouse_move() end),
capi.button({ args.modkey }, 3, function (t) t.client:mouse_resize() end)
}
if close then
close:buttons(bts)
function close.mouse_enter(s) hooks.user.call('mouse_enter', c) end
end
if closef then
closef:buttons(bts)
-- Needed for sloppy focus beheaviour
function closef.mouse_enter(s) hooks.user.call('mouse_enter', c) end
end
end
tb.widgets = { appicon, title, closef, close }
c.titlebar = tb
update(c)
update(c, "geometry")
end
--- Update a titlebar. This should be called in some hooks.
-- @param c The client to update.
-- @param prop The property name which has changed.
function update(c, prop)
if c.titlebar and data[c] then
local widgets = c.titlebar.widgets
local title, close, closef
for k, v in pairs(widgets) do
if v.name == "title" then title = v
elseif v.name == "close" then close = v
elseif v.name == "closef" then closef = v
elseif v.name == "appicon" then appicon = v end
if title and close and closef and appicon then break end
end
if prop == "name" then
if title then
title.text = " " .. util.escape(c.name) .. " "
end
elseif prop == "icon" then
if appicon then
appicon.image = c.icon
end
elseif prop == "geometry" then
if data[c].width then
if c.titlebar.position == "top"
or c.titlebar.position == "bottom" then
local w = math.min(data[c].width, c:geometry().width + 2 * c.border_width)
c.titlebar:geometry({ width = w })
else
local w = math.min(data[c].width, c:geometry().height + 2 * c.border_width)
c.titlebar:geometry({ height = w })
end
end
end
if capi.client.focus == c then
c.titlebar.fg = data[c].fg_focus
c.titlebar.bg = data[c].bg_focus
if closef then closef.visible = true end
if close then close.visible = false end
else
c.titlebar.fg = data[c].fg
c.titlebar.bg = data[c].bg
if closef then closef.visible = false end
if close then close.visible = true end
end
end
end
--- Remove a titlebar from a client.
-- @param c The client.
function remove(c)
c.titlebar = nil
data[c] = nil
end
-- Register standards hooks
hooks.focus.register(update)
hooks.unfocus.register(update)
hooks.property.register(update)
hooks.unmanage.register(remove)
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80