184 lines
6.2 KiB
Lua
184 lines
6.2 KiB
Lua
---------------------------------------------------------------------------
|
|
-- @author Julien Danjou <julien@danjou.info>
|
|
-- @copyright 2008 Julien Danjou
|
|
-- @release @AWESOME_VERSION@
|
|
---------------------------------------------------------------------------
|
|
|
|
-- Grab environment we need
|
|
local math = math
|
|
local image = image
|
|
local pairs = pairs
|
|
local otable = otable
|
|
local capi =
|
|
{
|
|
wibox = wibox,
|
|
widget = widget,
|
|
button = button,
|
|
client = client,
|
|
}
|
|
local beautiful = require("beautiful")
|
|
local hooks = require("awful.hooks")
|
|
local util = require("awful.util")
|
|
local widget = require("awful.widget")
|
|
local mouse = require("awful.mouse")
|
|
|
|
--- 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", 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() mouse.client.move(t.client) end),
|
|
capi.button({ args.modkey }, 1, function (t) mouse.client.move(t.client) end),
|
|
capi.button({ args.modkey }, 3, function (t) mouse.client.resize(t.client) end)
|
|
}
|
|
title:buttons(bts)
|
|
function title.mouse_enter(s) hooks.user.call('mouse_enter', c) end
|
|
|
|
local appicon = capi.widget({ type = "imagebox", 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({ align = "right",
|
|
image = image(theme.titlebar_close_button_focus) })
|
|
end
|
|
|
|
local close
|
|
if theme.titlebar_close_button_normal then
|
|
close = widget.button({ align = "right",
|
|
image = 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) mouse.client.move(t.client) end),
|
|
capi.button({ args.modkey }, 3, function (t) mouse.client.resize(t.client) end)
|
|
}
|
|
if close then
|
|
local rbts = close:buttons()
|
|
for k, v in pairs(rbts) do
|
|
bts[#bts + 1] = v
|
|
end
|
|
close:buttons(bts)
|
|
function close.mouse_enter(s) hooks.user.call('mouse_enter', c) end
|
|
end
|
|
if closef then
|
|
local rbts = closef:buttons()
|
|
for k, v in pairs(rbts) do
|
|
bts[#bts + 1] = v
|
|
end
|
|
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 = appicon, title = title,
|
|
closef = closef, close = close }
|
|
|
|
-- Store old geometry (including borders)
|
|
local old_geom = c:geometry()
|
|
|
|
c.titlebar = tb
|
|
|
|
-- Resize the client so the same amount of space is occupied as before.
|
|
c:geometry(old_geom)
|
|
|
|
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
|
|
if prop == "name" then
|
|
if widgets.title then
|
|
widgets.title.text = " " .. util.escape(c.name) .. " "
|
|
end
|
|
elseif prop == "icon" then
|
|
if widgets.appicon then
|
|
widgets.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)
|
|
c.titlebar:geometry({ width = w })
|
|
else
|
|
local w = math.min(data[c].width, c:geometry().height)
|
|
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 widgets.closef then widgets.closef.visible = true end
|
|
if widgets.close then widgets.close.visible = false end
|
|
else
|
|
c.titlebar.fg = data[c].fg
|
|
c.titlebar.bg = data[c].bg
|
|
if widgets.closef then widgets.closef.visible = false end
|
|
if widgets.close then widgets.close.visible = true end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Remove a titlebar from a client.
|
|
-- @param c The client.
|
|
function remove(c)
|
|
local old_geom = c:geometry()
|
|
c.titlebar = nil
|
|
data[c] = nil
|
|
-- Resize the client so the same amount of space is occupied as before.
|
|
c:geometry(old_geom)
|
|
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
|