Created
July 24, 2016 02:47
-
-
Save topisani/8037f1fcadf476a58b06daf3d3105f14 to your computer and use it in GitHub Desktop.
Awesome titlebars
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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