Skip to content

Instantly share code, notes, and snippets.

@topisani
Created July 24, 2016 02:47
Show Gist options
  • Save topisani/8037f1fcadf476a58b06daf3d3105f14 to your computer and use it in GitHub Desktop.
Save topisani/8037f1fcadf476a58b06daf3d3105f14 to your computer and use it in GitHub Desktop.
Awesome titlebars
local awful = require("awful")
local abutton = require("awful.button")
local beautiful = require("beautiful")
local wibox = require("wibox")
local naughty = require("naughty")
local textbox = require("wibox.widget.textbox")
local tp_titlebar = {
widget = {},
layout = {},
visibility = {}
}
-- Cache of titlebar widgets for client
local titlebar_widgets = {}
local function textbutton()
local o = textbox()
o.colour = beautiful.fg_normal
o.content = ""
o.disabled = false
function o:set_content(content)
self.content = content
self:tp_update()
end
function o:set_disabled(disabled)
self.disabled = disabled
self:tp_update()
end
function o:set_colour(colour)
self.colour = colour
self:tp_update()
end
function o:tp_update()
if self.disabled then
self:set_markup("")
else
self:set_markup("<span foreground=\""..self.colour.."\">"..self.content.."</span>")
end
end
return o
end
function tp_titlebar.widget.title(c)
local ret = textbutton()
local function update()
ret:set_text(c.name or "<unknown>")
end
c:connect_signal("property::name", update)
update()
return ret
end
function tp_titlebar.widget.closebutton(c)
local ret = textbutton()
ret:buttons({abutton({ }, 1, function() c:kill() end)})
ret:set_content("  ")
ret:set_colour(beautiful.bg_urgent)
return ret
end
function tp_titlebar.widget.minimizebutton(c)
local ret = textbutton()
ret:buttons({abutton({ }, 1, function() c.minimized = true end)})
ret:set_content("  ")
return ret
end
function tp_titlebar.widget.floatingbutton(c)
local ret = textbutton()
ret:buttons({abutton({ }, 1, function() c.floating = not c.floating end)})
ret:set_content("  ")
local function update()
if awful.layout.getname(awful.layout.get(c.screen)) == "floating" then
ret:set_disabled(true)
elseif c.floating then
ret:set_disabled(false)
ret:set_colour(beautiful.fg_focus)
else
ret:set_disabled(false)
ret:set_colour(beautiful.fg_normal)
end
end
c:connect_signal("property::floating", update)
tag.connect_signal("propery::layout", update)
update()
return ret
end
function tp_titlebar.widget.maximizebutton(c)
local ret = textbutton()
ret:buttons({abutton({ }, 1, function() c.maximized = not c.maximized end)})
ret:set_content("  ")
local function update()
if c.floating or awful.layout.getname(awful.layout.get(c.screen)) == "floating" then
if c.maximized then
ret:set_disabled(false)
ret:set_colour(beautiful.fg_focus)
else
ret:set_disabled(false)
ret:set_colour(beautiful.fg_normal)
end
else
ret:set_disabled(true)
end
end
c:connect_signal("property::maximized", update)
c:connect_signal("property::floating", update)
tag.connect_signal("property::layout", function() update() end)
update()
return ret
end
function tp_titlebar.widget.ontopbutton(c)
local ret = textbutton()
ret:buttons({abutton({ }, 1, function() c.ontop = not c.ontop end)})
ret:set_content("  ")
local function update()
if c.floating or awful.layout.getname(awful.layout.get(c.screen)) == "floating" then
if c.ontop then
ret:set_disabled(false)
ret:set_colour(beautiful.fg_focus)
else
ret:set_disabled(false)
ret:set_colour(beautiful.fg_normal)
end
else
ret:set_disabled(true)
end
end
c:connect_signal("property::ontop", update)
c:connect_signal("property::floating", update)
tag.connect_signal("property::layout", function() update() end)
update()
return ret
end
function tp_titlebar.layout.get_widgets(c)
if titlebar_widgets[c] == nil then
titlebar_widgets[c] = {
closebutton = tp_titlebar.widget.closebutton(c),
minimizebutton = tp_titlebar.widget.minimizebutton(c),
floatingbutton = tp_titlebar.widget.floatingbutton(c),
maximizebutton = tp_titlebar.widget.maximizebutton(c),
ontopbutton = tp_titlebar.widget.ontopbutton(c),
title = tp_titlebar.widget.title(c)
}
end
return titlebar_widgets[c]
end
function tp_titlebar.layout.titlebar(c)
local buttons = awful.util.table.join(
awful.button({ }, 1, function()
client.focus = c
c:raise()
awful.mouse.client.move(c)
end),
awful.button({ }, 3, function()
client.focus = c
c:raise()
awful.mouse.client.resize(c)
end)
)
local widgets = tp_titlebar.layout.get_widgets(c)
-- Widgets that are aligned to the left
local left_layout = wibox.layout.fixed.horizontal()
left_layout:buttons(buttons)
left_layout:add(widgets.closebutton)
left_layout:add(widgets.minimizebutton)
left_layout:add(widgets.floatingbutton)
left_layout:add(widgets.maximizebutton)
left_layout:add(widgets.ontopbutton)
-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
-- The title goes in the middle
local middle_layout = wibox.layout.flex.horizontal()
widgets.title:set_align("center")
middle_layout:add(widgets.title)
middle_layout:buttons(buttons)
-- Now bring it all together
local align_left = wibox.layout.align.horizontal()
align_left:set_left(left_layout)
local align_middle = wibox.layout.align.horizontal()
align_middle:set_middle(middle_layout)
-- align_middle:set_expand("none") -- might be needed in a later update to awesome
local align_right = wibox.layout.align.horizontal()
align_right:set_right(right_layout)
local layout = wibox.layout.flex.horizontal()
layout:add(align_left)
layout:add(align_middle)
layout:add(align_right)
return layout
end
function tp_titlebar.layout.statusbar()
local layout = wibox.layout.fixed.horizontal()
local function update()
if client.focus == nil then return layout:reset() end
local widgets = tp_titlebar.layout.get_widgets(client.focus)
layout:add(widgets.closebutton)
layout:add(widgets.minimizebutton)
layout:add(widgets.floatingbutton)
layout:add(widgets.maximizebutton)
layout:add(widgets.ontopbutton)
layout:add(widgets.title)
end
client.connect_signal("unfocus", function() layout:reset() end)
client.connect_signal("focus", update)
update()
return layout
end
client.connect_signal("unmanage", function(c) titlebar_widgets[c] = nil end)
local visible_titlebars = {}
local global_titlebar_rule = 0
function tp_titlebar.visibility.is_titlebar_visible(c)
-- Visibility explicitly set for this client
if visible_titlebars[c] == true then
return true
elseif visible_titlebars[c] == false then
return false
end
-- Titlebars turned off globally
if global_titlebar_rule == 0 then
return false
end
-- Titlebars turned on globally
if global_titlebar_rule == 1 then
return true
end
-- Titlebars on auto globally. Visibility will depend on layout and client flags
if global_titlebar_rule == 2 then
if (awful.layout.get(c.screen) == awful.layout.suit.floating or awful.client.floating.get(c) == true) and not c.maximized and not c.fullscreen then
return true
end
end
return false
end
function tp_titlebar.visibility.toggle_titlebar_for_client(c, state)
c = c or client.focus
if state == nil then state = not visible_titlebars[c] end
visible_titlebars[c] = state
tp_titlebar.visibility.update_titlebar(c)
end
function tp_titlebar.visibility.reset_client_titlebar_rules()
visible_titlebars = {}
tp_titlebar.visibility.update_all_titlebars_on_screen()
end
function tp_titlebar.visibility.switch_global_titlebar_rule()
local newstate = (global_titlebar_rule + 1) % 3
global_titlebar_rule = newstate
t = {}
if newstate == 0 then t.text = "Titlebars turned off globally" end
if newstate == 1 then t.text = "Titlebars turned on globally" end
if newstate == 2 then t.text = "Showing titlebars depending on layout and client state" end
naughty.notify(t)
tp_titlebar.visibility.reset_client_titlebar_rules()
end
function tp_titlebar.visibility.update_all_titlebars_on_screen()
for _, t in pairs(awful.tag.gettags(mouse.screen)) do
for _, c in pairs(t:clients()) do
tp_titlebar.visibility.update_titlebar(c)
end
end
end
function tp_titlebar.visibility.update_titlebar(c)
if tp_titlebar.visibility.is_titlebar_visible(c) then
awful.titlebar.show(c)
else
awful.titlebar.hide(c)
end
end
client.connect_signal("focus", function(c) tp_titlebar.visibility.update_titlebar(c) end)
client.connect_signal("unfocus", function(c) if not client.focus then tp_titlebar.visibility.update_titlebar(c) end end)
client.connect_signal("property::floating", function(c) tp_titlebar.visibility.update_titlebar(c) end)
client.connect_signal("property::maximized", function(c) tp_titlebar.visibility.update_titlebar(c) end)
client.connect_signal("property::ontop", function(c) tp_titlebar.visibility.update_titlebar(c) end)
return tp_titlebar
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment