diff --git a/libs/builder.lua b/libs/builder.lua
index 0e0956d..6ca8a74 100644
--- a/libs/builder.lua
+++ b/libs/builder.lua
@@ -48,7 +48,7 @@ return function(description,opts)
return require(struct.widget)(gears.table.join({
layout = (struct.layout and inner_builder(struct.layout)), client = (struct.client and c),
screen = (struct.screen and s)
- },struct.options or {}))
+ },struct.options or {},opts.passthrough or {}))
elseif struct.list then -- List descriptions
local list = {
layout = wibox.layout.fixed[(
diff --git a/libs/context_menu.lua b/libs/context_menu.lua
index 529da0f..f2b557a 100644
--- a/libs/context_menu.lua
+++ b/libs/context_menu.lua
@@ -11,7 +11,7 @@ local function position_popup(popup,widget,style)
popup:move_next_to(mouse.current_wibox)
-- Figure out the geometry of the base widget
local widget_geo
- for k,v in pairs(mouse.current_widgets) do
+ for k,v in pairs(mouse.current_widgets or {}) do
if widget == v then
widget_geo = mouse.current_widget_geometries[k]
end
@@ -30,6 +30,8 @@ local function position_popup(popup,widget,style)
end
return function(args)
+ -- A way to communicate that all widgets in menu got closed
+ args.on_close = args.on_close or function() end
local style = awmtk2.create_style("menu", awmtk2.default, args.style)
local templates = awmtk2.create_template_lib("menu", awmtk2.templates, args.templates)
local t = awmtk2.build_templates(templates,style)
@@ -42,26 +44,22 @@ return function(args)
forced_width = style.button.forced_width,
forced_height = style.button.forced_height
}))
+ local onpress = function(widget)
+ style.button.onrelease(widget)
+ if root_layer.focused then
+ root_layer.focused:emit_signal("cascade::kill")
+ end
+ end
if type(element[2]) == "string" then
new_element:connect_signal("button::press",style.button.onpress)
new_element:connect_signal("button::press",function(widget)
awful.spawn(element[2])
end)
- new_element:connect_signal("button::release",function(widget)
- style.button.onrelease(widget)
- if root_layer.focused then
- root_layer.focused:emit_signal("cascade_close")
- end
- end)
+ new_element:connect_signal("button::release",onpress)
elseif type(element[2]) == "function" then
new_element:connect_signal("button::press",style.button.onpress)
new_element:connect_signal("button::press",element[2])
- new_element:connect_signal("button::release",function(widget)
- style.button.onrelease(widget)
- if root_layer.focused then
- root_layer.focused:emit_signal("cascade_close")
- end
- end)
+ new_element:connect_signal("button::release",onpress)
elseif type(element[2]) == "table" then
local layout = {
spacing = style.base.spacing,
@@ -82,18 +80,20 @@ return function(args)
return
end
if layer.focused then
- layer.focused:emit_signal("cascade_close")
+ layer.focused:emit_signal("cascade::close")
end
layer.focused = widget
position_popup(next_layer, new_element, style)
end
- new_element:connect_signal("cascade_close",function()
+ local onclose = function()
style.button.onrelease(new_element)
if layout.focused then
- layout.focused:emit_signal("cascade_close")
+ layout.focused:emit_signal("cascade::close")
end
next_layer.visible = false
- end)
+ end
+ new_element:connect_signal("cascade::close",onclose)
+ new_element:connect_signal("cascade::kill",onclose)
-- that sweet "just move the mouse 4head" navigation
if style.base.menu_slide then
new_element:connect_signal("mouse::enter",open_layer)
diff --git a/libs/debug.lua b/libs/debug.lua
index a341515..6c9fa86 100644
--- a/libs/debug.lua
+++ b/libs/debug.lua
@@ -1,7 +1,6 @@
local naughty = require("naughty")
local debug = {}
--- Thanks, u/skhil
--- (https://www.reddit.com/r/awesomewm/comments/te49nb/why_does_awesomes_ram_consumption_get_higher_and/)
+-- from (https://www.reddit.com/r/awesomewm/comments/te49nb/why_does_awesomes_ram_consumption_get_higher_and/)
function debug.print_awesome_memory_stats(message)
print(os.date(), "\nLua memory usage:", collectgarbage("count"))
out_string = tostring(os.date()) .. "\nLua memory usage:"..tostring(collectgarbage("count")).."\n"
diff --git a/modules/desktop.lua b/modules/desktop.lua
index 88d2d2c..074ade0 100644
--- a/modules/desktop.lua
+++ b/modules/desktop.lua
@@ -6,6 +6,7 @@ local beautiful = require("beautiful")
local builder = require("builder")
local mbarutils = require("menubar").utils
local menugen = require("context_menu")
+local json = require("dkjson")
local function read_file(fname)
local fhandler = io.open(fname,"r")
@@ -16,53 +17,6 @@ local function read_file(fname)
end
end
-do -- {{{ Root menu
-local style = awmtk2.create_style("root_menu",awmtk2.default,{})
-local templates = awmtk2.create_template_lib("root_menu",awmtk2.templates,{})
-local t = awmtk2.build_templates(templates,style)
-local config_file = io.open(root_path.."/themes/"..global.theme.."/config/root_menu.json","r")
-local config
-if config_file then
- config = config_file:read("*a")
- config_file:close()
-else
- config = [[{"list": [
- {"widget": "widgets.rootmenu"}
- ],
- "vertical": true
-}]]
-end
-local root_menu = awful.popup(t.popup(builder(
- config,
- {
- style = style,
- screen = mouse.screen,
- }
-)))
-local buttons = root.buttons()
-root.buttons(gears.table.join(buttons,
- awful.button({}, 3, function()
- if root_menu.visible then
- local roots = root_menu.widget:get_children_by_id("menu_root")
- for k,v in pairs(roots) do
- for _,w in ipairs(v.children) do
- if type(w) == "table" and w.emit_signal then
- w:emit_signal("cascade_close")
- end
- end
- end
- end
- root_menu.visible = (not root_menu.visible)
- if root_menu.visible then
- root_menu:move_next_to(gears.table.join(mouse.coords(),{
- width = 0,
- height = 0
- }))
- end
- end)
-))
-end -- }}}
-
-- {{{ Placeholder Icons
client.connect_signal("request::titlebars",function(c)
if (not c.icon) and beautiful.icon_default then
@@ -71,12 +25,20 @@ client.connect_signal("request::titlebars",function(c)
end)
-- }}}
--- {{{ Global widgets
-local runmenu = require("widgets.dismal")({
- x = 0,
- y = 26
-})
--- }}}
+do -- {{{ Global widgets
+local config_file = io.open(root_path.."/themes/"..global.theme.."/config/global.json","r")
+local config
+if config_file then
+ config = config_file:read("*a")
+ config_file:close()
+else
+ config = "[]"
+end
+for k,v in pairs(json.decode(config) or {}) do
+ require(k)(v)
+end
+end -- }}}
+
do -- {{{ Titlebars
local titlebar_config = {}
diff --git a/modules/xdg_data.lua b/modules/xdg_data.lua
index c17d378..76c6c47 100644
--- a/modules/xdg_data.lua
+++ b/modules/xdg_data.lua
@@ -82,8 +82,8 @@ for k,v in pairs(desktop_dirs) do
end,
output_done = function()
-- Call a global signal
- awesome.emit_signal("xdg::dir_finished",v)
desktop_dirs_complete = desktop_dirs_complete + 1
+ awesome.emit_signal("xdg::dir_finished",v)
end
})
end
diff --git a/themes/reno98/config/client_menu.json b/themes/reno98/config/client_menu.json
new file mode 100644
index 0000000..17fff5a
--- /dev/null
+++ b/themes/reno98/config/client_menu.json
@@ -0,0 +1,7 @@
+{
+ "list": [
+ {"widget": "widgets.clientcontrols"},
+ {"widget": "widgets.clientbuttons"}
+ ],
+ "vertical":true
+}
diff --git a/themes/reno98/config/global.json b/themes/reno98/config/global.json
new file mode 100644
index 0000000..683ea04
--- /dev/null
+++ b/themes/reno98/config/global.json
@@ -0,0 +1,7 @@
+{
+ "widgets.dismal":{
+ "x":0,
+ "y":26
+ },
+ "widgets.rootmenu":{}
+}
diff --git a/themes/reno98/config/root_menu.json b/themes/reno98/config/root_menu.json
new file mode 100644
index 0000000..a61658b
--- /dev/null
+++ b/themes/reno98/config/root_menu.json
@@ -0,0 +1,22 @@
+{
+ "list": [
+ {"widget": "widgets.base.popuptitle",
+ "options":{
+ "icon":"icons/reno98.png",
+ "title":"Reno 98"
+ }
+ },
+ {"widget": "widgets.base.tagswitcher",
+ "screen":true
+ },
+ {"widget": "widgets.rootcontrols"},
+ {"widget": "widgets.xdgmenu",
+ "options": {
+ "exclude_category": [
+ "Other"
+ ]
+ }
+ }
+ ],
+ "vertical": true
+}
diff --git a/themes/reno98/config/titlebar_top.json b/themes/reno98/config/titlebar_top.json
index c55f941..0f66a5b 100644
--- a/themes/reno98/config/titlebar_top.json
+++ b/themes/reno98/config/titlebar_top.json
@@ -1,9 +1,9 @@
{
"align": {
"left": [
- {
- "builtin": "iconwidget",
- "client": true
+ {
+ "widget":"widgets.clientmenu",
+ "client":true
}
],
"center": [
diff --git a/themes/reno98/config/wibar_top.json b/themes/reno98/config/wibar_top.json
index 67264e1..d1d6c26 100644
--- a/themes/reno98/config/wibar_top.json
+++ b/themes/reno98/config/wibar_top.json
@@ -10,6 +10,7 @@
{ "widget": "widgets.base.subpanel",
"layout": {
"list": [
+ { "widget": "widgets.base.systray" },
{ "widget": "widgets.base.clock" }
]
}
diff --git a/themes/reno98/icons/lock.png b/themes/reno98/icons/lock.png
new file mode 100644
index 0000000..cc3cdab
Binary files /dev/null and b/themes/reno98/icons/lock.png differ
diff --git a/themes/reno98/icons/power.png b/themes/reno98/icons/power.png
new file mode 100644
index 0000000..94be34c
Binary files /dev/null and b/themes/reno98/icons/power.png differ
diff --git a/themes/reno98/icons/reno98.png b/themes/reno98/icons/reno98.png
new file mode 100644
index 0000000..b1e98ef
Binary files /dev/null and b/themes/reno98/icons/reno98.png differ
diff --git a/themes/reno98/icons/sleep.png b/themes/reno98/icons/sleep.png
new file mode 100644
index 0000000..1000808
Binary files /dev/null and b/themes/reno98/icons/sleep.png differ
diff --git a/themes/reno98/icons/unknown-app.png b/themes/reno98/icons/unknown-app.png
index e4f5121..0d0f8bd 100644
Binary files a/themes/reno98/icons/unknown-app.png and b/themes/reno98/icons/unknown-app.png differ
diff --git a/themes/reno98/icons/unknown-app.svg b/themes/reno98/icons/unknown-app.svg
deleted file mode 100644
index 5206870..0000000
--- a/themes/reno98/icons/unknown-app.svg
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
diff --git a/themes/reno98/theme.lua b/themes/reno98/theme.lua
index f8bc444..163b6af 100644
--- a/themes/reno98/theme.lua
+++ b/themes/reno98/theme.lua
@@ -1,3 +1,4 @@
+-- Reno98 - a retro replica of a very recognizable theme
local theme_assets = require("beautiful.theme_assets")
local xresources = require("beautiful.xresources")
local dpi = xresources.apply_dpi
@@ -8,7 +9,7 @@ local themes_path = root_path.."/themes/"
local theme = {}
-theme.font = "Liberation Sans 8"
+theme.font = "Terminus 8"
theme.bg_normal = "#c0c0c0"
theme.bg_focus = "#808080"
@@ -54,13 +55,9 @@ theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
)
theme.menu_height = dpi(15)
theme.menu_width = dpi(100)
+theme.systray_icon_spacing = 2
-- Define the image to load
-theme.titlebar_close_button_normal = themes_path.."reno98/titlebar/close_normal.png"
-theme.titlebar_close_button_focus = themes_path.."reno98/titlebar/close_focus.png"
-
-theme.titlebar_minimize_button_normal = themes_path.."reno98/titlebar/minimize_normal.png"
-theme.titlebar_minimize_button_focus = themes_path.."reno98/titlebar/minimize_focus.png"
theme.titlebar_ontop_button_normal_inactive = themes_path.."reno98/titlebar/ontop_normal_inactive.png"
theme.titlebar_ontop_button_focus_inactive = themes_path.."reno98/titlebar/ontop_focus_inactive.png"
@@ -77,6 +74,15 @@ theme.titlebar_floating_button_focus_inactive = themes_path.."reno98/titlebar/f
theme.titlebar_floating_button_normal_active = themes_path.."reno98/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_active = themes_path.."reno98/titlebar/floating_focus_active.png"
+theme = theme_assets.recolor_titlebar(theme,theme.fg_normal,"normal")
+theme = theme_assets.recolor_titlebar(theme,theme.fg_focus,"focus")
+
+theme.titlebar_close_button_normal = themes_path.."reno98/titlebar/close_normal.png"
+theme.titlebar_close_button_focus = themes_path.."reno98/titlebar/close_focus.png"
+
+theme.titlebar_minimize_button_normal = themes_path.."reno98/titlebar/minimize_normal.png"
+theme.titlebar_minimize_button_focus = themes_path.."reno98/titlebar/minimize_focus.png"
+
theme.titlebar_maximized_button_normal_inactive = themes_path.."reno98/titlebar/maximized_normal_inactive.png"
theme.titlebar_maximized_button_focus_inactive = themes_path.."reno98/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_active = themes_path.."reno98/titlebar/maximized_normal_active.png"
@@ -342,10 +348,34 @@ theme.widgets = {
margins = 0
}
},
+ root_menu = {
+ base = {
+ spacing = 2
+ }
+ },
+ client_menu = {
+ base = {
+ spacing = 2
+ }
+ },
+ taglist = {
+ base = {
+ spacing = 2
+ },
+ button = {
+ bgimage_focus = theme.bgimage_inset,
+ bgimage_normal = theme.bgimage_outset,
+ margins = 2
+ },
+ container = {
+ margins = 3
+ }
+ },
subpanel = {
container = {
bgimage = theme.bgimage_inset,
- bg = theme.bgimage_normal
+ bg = theme.bgimage_normal,
+ margins = 2
}
},
dismal = {
@@ -370,19 +400,26 @@ theme.widgets = {
base = {
-- Enables the ability to just drag the mouse on an entry to open it
menu_slide = true,
- spacing = 1
+ spacing = 2
},
button = {
forced_height = 20,
forced_width = 160
},
- popup = {
- margins = 2
+ },
+ systray = {
+ container = {
+ bgimage = function() end,
+ margins = 0
}
},
- root_menu = {
- popup = {
- margins = 2
+ client_buttons = {
+ button = {
+ forced_width = 20,
+ forced_height = 20
+ },
+ base = {
+ spacing = 2
}
},
titlebar = {
diff --git a/widgets/base/popuptitle.lua b/widgets/base/popuptitle.lua
new file mode 100644
index 0000000..d762c6e
--- /dev/null
+++ b/widgets/base/popuptitle.lua
@@ -0,0 +1,17 @@
+-- Base for widgets
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+return function(args)
+ local style = awmtk2.create_style("popuptitle",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("popuptitle",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local widget = wibox.widget(t.container(t.article({
+ icon = root_path.."/themes/"..global.theme.."/"..args.icon,
+ title = args.title
+ })))
+ return widget
+end
diff --git a/widgets/base/systray.lua b/widgets/base/systray.lua
new file mode 100644
index 0000000..2ebdae9
--- /dev/null
+++ b/widgets/base/systray.lua
@@ -0,0 +1,16 @@
+-- Base for widgets
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+return function(args)
+ local style = awmtk2.create_style("systray",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("systray",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local widget = wibox.widget(t.container({
+ widget = wibox.widget.systray
+ }))
+ return widget
+end
diff --git a/widgets/base/tagswitcher.lua b/widgets/base/tagswitcher.lua
new file mode 100644
index 0000000..c7d33e1
--- /dev/null
+++ b/widgets/base/tagswitcher.lua
@@ -0,0 +1,58 @@
+-- Base for widgets
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+return function(args)
+ local style = awmtk2.create_style("taglist",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("taglist",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local widget = wibox.widget(t.container(awful.widget.taglist({
+ screen = args.screen,
+ filter = awful.widget.taglist.filter.all,
+ style = {
+ shape = style.button.shape
+ },
+ layout = {
+ spacing = style.base.spacing,
+ spacing_widget = style.base.spacing_widget,
+ layout = style.base.layout or wibox.layout.fixed.horizontal
+ },
+ widget_template = t.button(t.article({
+ icon_id = "icon_role",
+ title_id = "text_role"
+ }),{
+ id = "background",
+ create_callback = function(self, tag, index, tags)
+ self:connect_signal("button::press",function(self,x,y,b)
+ if b == 1 then
+ awful.tag.viewmore({tag})
+ elseif b == 3 then
+ awful.tag.viewtoggle(tag)
+ end
+ end)
+ local bg = self:get_children_by_id("background")[1]
+ if tag.selected then
+ bg.bgimage = style.button.bgimage_focus
+ bg.bg = style.button.bg_focus
+ else
+ bg.bgimage = style.button.bgimage_normal
+ bg.bg = style.button.bg_normal
+ end
+ end,
+ update_callback = function(self, tag, index, tags)
+ local bg = self:get_children_by_id("background")[1]
+ if tag.selected then
+ bg.bgimage = style.button.bgimage_focus
+ bg.bg = style.button.bg_focus
+ else
+ bg.bgimage = style.button.bgimage_normal
+ bg.bg = style.button.bg_normal
+ end
+ end
+ })
+ })))
+ return widget
+end
diff --git a/widgets/clientbuttons.lua b/widgets/clientbuttons.lua
new file mode 100644
index 0000000..cf41053
--- /dev/null
+++ b/widgets/clientbuttons.lua
@@ -0,0 +1,85 @@
+--
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+return function(args)
+ local style = awmtk2.create_style("client_buttons",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("client_buttons",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local floating_on = beautiful.titlebar_floating_button_normal_inactive
+ local floating_off = beautiful.titlebar_floating_button_normal_active
+ local ontop_on = beautiful.titlebar_ontop_button_normal_inactive
+ local ontop_off = beautiful.titlebar_ontop_button_normal_active
+ local sticky_on = beautiful.titlebar_sticky_button_normal_inactive
+ local sticky_off = beautiful.titlebar_sticky_button_normal_active
+ local floating = wibox.widget(t.button({
+ image = (client.focus and client.focus.floating and floating_on) or floating_off,
+ widget = wibox.widget.imagebox,
+ id = "icon"
+ },{
+ forced_height = style.button.forced_height,
+ forced_width = style.button.forced_width
+ }))
+ floating:connect_signal("button::press",style.button.onpress)
+ floating:connect_signal("button::release",style.button.onrelease)
+ floating:connect_signal("button::press",function(widget)
+ client.focus.floating = (not client.focus.floating)
+ widget:emit_signal("widget::update",widget)
+ end)
+ floating:connect_signal("widget::update",function(widget)
+ local icon = widget:get_children_by_id("icon")[1]
+ icon.image = (client.focus.floating and floating_on) or floating_off
+ end)
+ local ontop = wibox.widget(t.button({
+ image = (client.focus and client.focus.ontop and ontop_on) or ontop_off,
+ widget = wibox.widget.imagebox,
+ id = "icon"
+ },{
+ forced_height = style.button.forced_height,
+ forced_width = style.button.forced_width
+ }))
+ ontop:connect_signal("button::press",style.button.onpress)
+ ontop:connect_signal("button::release",style.button.onrelease)
+ ontop:connect_signal("button::press",function(widget)
+ client.focus.ontop = (not client.focus.ontop)
+ widget:emit_signal("widget::update",widget)
+ end)
+ ontop:connect_signal("widget::update",function(widget)
+ local icon = widget:get_children_by_id("icon")[1]
+ icon.image = (client.focus.ontop and ontop_on) or ontop_off
+ end)
+ local sticky = wibox.widget(t.button({
+ image = (client.focus and client.focus.sticky and sticky_on) or sticky_off,
+ widget = wibox.widget.imagebox,
+ id = "icon"
+ },{
+ forced_height = style.button.forced_height,
+ forced_width = style.button.forced_width
+ }))
+ sticky:connect_signal("button::press",style.button.onpress)
+ sticky:connect_signal("button::release",style.button.onrelease)
+ sticky:connect_signal("button::press",function(widget)
+ client.focus.sticky = (not client.focus.sticky)
+ widget:emit_signal("widget::update",widget)
+ end)
+ sticky:connect_signal("widget::update",function(widget)
+ local icon = widget:get_children_by_id("icon")[1]
+ icon.image = (client.focus.sticky and sticky_on) or sticky_off
+ end)
+ client.connect_signal("focus",function(c)
+ sticky:emit_signal("widget::update")
+ ontop:emit_signal("widget::update")
+ floating:emit_signal("widget::update")
+ end)
+ local widget = wibox.widget({
+ floating,
+ ontop,
+ sticky,
+ layout = wibox.layout.fixed.horizontal,
+ spacing = style.base.spacing
+ })
+ return widget
+end
diff --git a/widgets/clientcontrols.lua b/widgets/clientcontrols.lua
new file mode 100644
index 0000000..e4e8498
--- /dev/null
+++ b/widgets/clientcontrols.lua
@@ -0,0 +1,64 @@
+-- Basic client control keys
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+local menugen = require("context_menu")
+
+return function(args)
+ local style = awmtk2.create_style("client_controls",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("client_controls",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local move_to_tag = {}
+ local add_to_tag = {}
+ awful.screen.connect_for_each_screen(function(s)
+ table.insert(move_to_tag,{
+ "Screen "..s.index,
+ (function()
+ local t = {}
+ for k,v in pairs(s.tags) do
+ table.insert(t,{v.name,function()
+ if client.focus then
+ client.focus:tags({v})
+ end
+ end})
+ end
+ return t
+ end)()
+ })
+ table.insert(add_to_tag,{
+ "Screen "..s.index,
+ (function()
+ local t = {}
+ for k,v in pairs(s.tags) do
+ table.insert(t,{v.name,function()
+ if client.focus then
+ local tags = client.focus:tags()
+ for k,tag in pairs(tags) do
+ if v == tag then
+ table.remove(tags,k)
+ client.focus:tags(tags)
+ return
+ end
+ end
+ table.insert(tags,v)
+ client.focus:tags(tags)
+ end
+ end})
+ end
+ return t
+ end)()
+ })
+ end)
+ local widget = menugen({
+ items = {
+ { "Kill client", function() client.focus:kill() end },
+ { "Raise client", function() client.focus:raise() end},
+ { "Lower client", function() client.focus:lower() end},
+ { "Move to tag", move_to_tag },
+ { "Switch on tag", add_to_tag }
+ },
+ })
+ return widget
+end
diff --git a/widgets/clientmenu.lua b/widgets/clientmenu.lua
new file mode 100644
index 0000000..df82746
--- /dev/null
+++ b/widgets/clientmenu.lua
@@ -0,0 +1,69 @@
+-- Base for widgets
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+local menugen = require("context_menu")
+local builder = require("builder")
+local style = awmtk2.create_style("client_menu",awmtk2.default,{})
+local templates = awmtk2.create_template_lib("client_menu",awmtk2.templates,{})
+local t = awmtk2.build_templates(templates,style)
+
+-- Create a global context menu for clients first
+if not context_menu then
+local config_file = io.open(root_path.."/themes/"..global.theme..'/config/client_menu.json',"r")
+local config
+if config_file then
+ config = config_file:read("*a")
+ config_file:close()
+else
+ config = [[{"list":[{"widget":"widgets.clientcontrols"}]}]]
+end
+context_menu = awful.popup(t.popup(builder(
+ config,
+ {
+ style = style.base,
+ }
+)))
+context_menu:connect_signal("button::press",function(self,x,y,b)
+ if b == 3 then
+ context_menu.visible = false
+ end
+end)
+context_menu:connect_signal("property::visible",function(self,x,y,b)
+ if not context_menu.visible then
+ local children = context_menu.widget:get_children_by_id("menu_root")
+ for k,v in pairs(children) do
+ for k2,v2 in pairs(v.children) do
+ v2:emit_signal("cascade::close")
+ end
+ end
+ end
+end)
+client.connect_signal("focus",function()
+ context_menu.visible = false
+end)
+for _,layout in pairs(context_menu.widget:get_children_by_id("menu_root")) do
+ for _,button in pairs(layout.children) do
+ button:connect_signal("cascade::kill",function()
+ context_menu.visible = false
+ end)
+ end
+end
+end
+
+return function(args)
+ local widget = wibox.widget({
+ widget = awful.widget.clienticon,
+ client = args.client
+ })
+ widget:connect_signal("button::press",function()
+ context_menu.visible = (not context_menu.visible)
+ if context_menu.visible then
+ context_menu.x = mouse.coords().x
+ context_menu.y = mouse.coords().y
+ end
+ end)
+ return widget
+end
diff --git a/widgets/rootbuttons.lua b/widgets/rootbuttons.lua
new file mode 100644
index 0000000..cf41053
--- /dev/null
+++ b/widgets/rootbuttons.lua
@@ -0,0 +1,85 @@
+--
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+return function(args)
+ local style = awmtk2.create_style("client_buttons",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("client_buttons",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local floating_on = beautiful.titlebar_floating_button_normal_inactive
+ local floating_off = beautiful.titlebar_floating_button_normal_active
+ local ontop_on = beautiful.titlebar_ontop_button_normal_inactive
+ local ontop_off = beautiful.titlebar_ontop_button_normal_active
+ local sticky_on = beautiful.titlebar_sticky_button_normal_inactive
+ local sticky_off = beautiful.titlebar_sticky_button_normal_active
+ local floating = wibox.widget(t.button({
+ image = (client.focus and client.focus.floating and floating_on) or floating_off,
+ widget = wibox.widget.imagebox,
+ id = "icon"
+ },{
+ forced_height = style.button.forced_height,
+ forced_width = style.button.forced_width
+ }))
+ floating:connect_signal("button::press",style.button.onpress)
+ floating:connect_signal("button::release",style.button.onrelease)
+ floating:connect_signal("button::press",function(widget)
+ client.focus.floating = (not client.focus.floating)
+ widget:emit_signal("widget::update",widget)
+ end)
+ floating:connect_signal("widget::update",function(widget)
+ local icon = widget:get_children_by_id("icon")[1]
+ icon.image = (client.focus.floating and floating_on) or floating_off
+ end)
+ local ontop = wibox.widget(t.button({
+ image = (client.focus and client.focus.ontop and ontop_on) or ontop_off,
+ widget = wibox.widget.imagebox,
+ id = "icon"
+ },{
+ forced_height = style.button.forced_height,
+ forced_width = style.button.forced_width
+ }))
+ ontop:connect_signal("button::press",style.button.onpress)
+ ontop:connect_signal("button::release",style.button.onrelease)
+ ontop:connect_signal("button::press",function(widget)
+ client.focus.ontop = (not client.focus.ontop)
+ widget:emit_signal("widget::update",widget)
+ end)
+ ontop:connect_signal("widget::update",function(widget)
+ local icon = widget:get_children_by_id("icon")[1]
+ icon.image = (client.focus.ontop and ontop_on) or ontop_off
+ end)
+ local sticky = wibox.widget(t.button({
+ image = (client.focus and client.focus.sticky and sticky_on) or sticky_off,
+ widget = wibox.widget.imagebox,
+ id = "icon"
+ },{
+ forced_height = style.button.forced_height,
+ forced_width = style.button.forced_width
+ }))
+ sticky:connect_signal("button::press",style.button.onpress)
+ sticky:connect_signal("button::release",style.button.onrelease)
+ sticky:connect_signal("button::press",function(widget)
+ client.focus.sticky = (not client.focus.sticky)
+ widget:emit_signal("widget::update",widget)
+ end)
+ sticky:connect_signal("widget::update",function(widget)
+ local icon = widget:get_children_by_id("icon")[1]
+ icon.image = (client.focus.sticky and sticky_on) or sticky_off
+ end)
+ client.connect_signal("focus",function(c)
+ sticky:emit_signal("widget::update")
+ ontop:emit_signal("widget::update")
+ floating:emit_signal("widget::update")
+ end)
+ local widget = wibox.widget({
+ floating,
+ ontop,
+ sticky,
+ layout = wibox.layout.fixed.horizontal,
+ spacing = style.base.spacing
+ })
+ return widget
+end
diff --git a/widgets/rootcontrols.lua b/widgets/rootcontrols.lua
new file mode 100644
index 0000000..6cea1b7
--- /dev/null
+++ b/widgets/rootcontrols.lua
@@ -0,0 +1,25 @@
+-- Base for widgets
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+local menugen = require("context_menu")
+
+return function(args)
+ local style = awmtk2.create_style("root_menu",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("root_menu",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ local widget = menugen({
+ items = {
+ {"Awesome", {
+ {"open config dir", "xdg-open "..root_path},
+ {"open docs", "xdg-open https://awesomewm.org/doc/api/"},
+ {"restart", function() awesome.restart() end},
+ {"quit", function() awesome.quit() end}
+ }, beautiful.awesome_icon},
+ {"open terminal", global.terminal}
+ },
+ })
+ return widget
+end
diff --git a/widgets/rootmenu.lua b/widgets/rootmenu.lua
index 524e8ea..7ecfe9b 100644
--- a/widgets/rootmenu.lua
+++ b/widgets/rootmenu.lua
@@ -1,25 +1,71 @@
--- Base for widgets
local awmtk2 = require("awmtk2")
local wibox = require("wibox")
local gears = require("gears")
local awful = require("awful")
local beautiful = require("beautiful")
-local menugen = require("context_menu")
+local builder = require("builder")
return function(args)
- local style = awmtk2.create_style("root_menu",awmtk2.default,args.style)
- local templates = awmtk2.create_template_lib("root_menu",awmtk2.templates,args.templates)
+ local style = awmtk2.create_style("root_menu",awmtk2.default,{})
+ local templates = awmtk2.create_template_lib("root_menu",awmtk2.templates,{})
local t = awmtk2.build_templates(templates,style)
- local widget = menugen({
- items = {
- {"Awesome", {
- {"open config dir", "xdg-open "..root_path},
- {"open docs", "xdg-open https://awesomewm.org/doc/api/"},
- {"restart", function() awesome.restart() end},
- {"quit", function() awesome.quit() end}
- }, beautiful.awesome_icon},
- {"open terminal", global.terminal}
- }
- })
- return widget
-end
+ local config_file = io.open(root_path.."/themes/"..global.theme.."/config/root_menu.json","r")
+ local config
+ if config_file then
+ config = config_file:read("*a")
+ config_file:close()
+ else
+ config = [[{"list": [{"widget": "widgets.rootcontrols"}],"vertical": true}]]
+ end
+ -- TODO: Refactor this whole mess
+ root_menu = awful.popup(t.popup({
+ markup = "brainhurt the game",
+ widget = wibox.widget.textbox
+ }))
+ root_menu:connect_signal("button::press",function(self,x,y,b)
+ if b == 3 then
+ root_menu.visible = false
+ end
+ end)
+ root_menu._menu_private = {}
+ root_menu.widget = wibox.widget(t.popup(builder(
+ config,
+ {
+ style = style.base,
+ screen = mouse.screen,
+ passthrough = {
+ parent = root_menu,
+ _tracking_layer = root_menu._menu_private
+ }
+ }
+ )).widget)
+ for _,layout in pairs(root_menu.widget:get_children_by_id("menu_root")) do
+ print(layout)
+ for _,button in pairs(layout.children) do
+ button:connect_signal("cascade::kill",function()
+ root_menu.visible = false
+ end)
+ end
+ end
+ root_menu:connect_signal("property::visible",function()
+ local roots = root_menu.widget:get_children_by_id("menu_root")
+ for k,v in pairs(roots) do
+ for _,w in ipairs(v.children) do
+ w:emit_signal("cascade::close")
+ end
+ end
+ end)
+ local buttons = root.buttons()
+ root.buttons(gears.table.join(buttons,
+ awful.button({}, 3, function()
+ root_menu.visible = (not root_menu.visible)
+ if root_menu.visible then
+ root_menu:move_next_to(gears.table.join(mouse.coords(),{
+ width = 0,
+ height = 0
+ }))
+ end
+ end)
+ ))
+ return root_menu
+end
diff --git a/widgets/xdgmenu.lua b/widgets/xdgmenu.lua
new file mode 100644
index 0000000..41abdfc
--- /dev/null
+++ b/widgets/xdgmenu.lua
@@ -0,0 +1,99 @@
+-- Generic application menu
+local awmtk2 = require("awmtk2")
+local wibox = require("wibox")
+local gears = require("gears")
+local awful = require("awful")
+local beautiful = require("beautiful")
+local menugen = require("context_menu")
+local menuutils = require("menubar").utils
+
+return function(args)
+ local style = awmtk2.create_style("xdg_menu",awmtk2.default,args.style)
+ local templates = awmtk2.create_template_lib("xdg_menu",awmtk2.templates,args.templates)
+ local t = awmtk2.build_templates(templates,style)
+ -- Add a "loading" indicator while XDG is still parsing data
+ local widget = wibox.widget({
+ t.container({
+ markup = "Loading XDG menu...",
+ widget = wibox.widget.textbox
+ }),
+ layout = wibox.layout.fixed.vertical,
+ id = "xdg_menu_root"
+ })
+
+ local function exclude(name)
+ for k,v in pairs(args.exclude or {}) do
+ if name:match(v) then
+ return true
+ end
+ end
+ return false
+ end
+
+ awesome.connect_signal("xdg::all_finished",function()
+ if not args.parent then return end
+ local items = {}
+ for k,v in pairs(xdg.categories) do
+ local noprocess = false
+ for k2,v2 in pairs(args.exclude_category or {}) do
+ if k == v2 then
+ noprocess = true
+ end
+ end
+ if (not noprocess) and (#v.apps > 0) then
+ local category = {k,{},menuutils.lookup_icon_uncached(v.icon)}
+ for _,item in pairs(v.apps) do
+ if not exclude(item.name) then
+ table.insert(category[2], {
+ item.name,
+ item.exec:gsub("%%%w","") or "",
+ gears.filesystem.file_readable(item.icon or "") and item.icon
+ })
+ end
+ end
+ table.insert(items,category)
+ end
+ end
+ -- uhhh there's a lot of things about async, some of which i can't explain
+ local xdg_menu_root = widget:get_children_by_id("xdg_menu_root")[1]
+ xdg_menu_root:reset()
+ local menu = wibox.widget(menugen({
+ items = items,
+ }))
+ local menu_root = menu:get_children_by_id("menu_root")[1]
+ for k,v in pairs(menu_root.children) do
+ v:connect_signal("cascade::kill",function()
+ args.parent.visible = false
+ end)
+ args.parent:connect_signal("property::visible",function()
+ if not args.parent.visible then
+ v:emit_signal("cascade::close")
+ end
+ end)
+ menu:connect_signal("widget::redraw_needed",function()
+ if not menu.visible then
+ v:emit_signal("cascade::close")
+ end
+ end)
+ end
+ local appswitch = wibox.widget(t.button(t.textbox({
+ markup = "Applications",
+ id = "apptext"
+ })))
+ appswitch:connect_signal("button::press",function(self)
+ menu.visible = (not menu.visible)
+ local textbox = appswitch:get_children_by_id("apptext")[1]
+ if menu.visible then
+ style.button.onpress(self)
+ textbox:set_markup("Applications")
+ else
+ style.button.onrelease(self)
+ textbox:set_markup("Applications")
+ end
+ end)
+ menu.visible = false
+ xdg_menu_root:add(appswitch)
+ xdg_menu_root:add(menu)
+ end)
+ return widget
+end