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