diff --git a/docker-widget/clickable-container.lua b/docker-widget/clickable-container.lua
new file mode 100644
index 00000000..6b57aa24
--- /dev/null
+++ b/docker-widget/clickable-container.lua
@@ -0,0 +1,59 @@
+local wibox = require('wibox')
+local beautiful = require('beautiful')
+
+local create_click_events = function(widget)
+
+ local container = wibox.widget {
+ widget,
+ widget = wibox.container.background
+ }
+
+ -- Old and new widget
+ local old_cursor, old_wibox
+
+ -- Mouse hovers on the widget
+ container:connect_signal(
+ 'mouse::enter',
+ function()
+ container.bg = beautiful.groups_bg
+ -- Hm, no idea how to get the wibox from this signal's arguments...
+ local w = mouse.current_wibox
+ if w then
+ old_cursor, old_wibox = w.cursor, w
+ w.cursor = 'hand1'
+ end
+ end
+ )
+
+ -- Mouse leaves the widget
+ container:connect_signal(
+ 'mouse::leave',
+ function()
+ container.bg = beautiful.leave_event
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ end
+ )
+
+ -- Mouse pressed the widget
+ container:connect_signal(
+ 'button::press',
+ function()
+ container.bg = beautiful.press_event
+ end
+ )
+
+ -- Mouse releases the widget
+ container:connect_signal(
+ 'button::release',
+ function()
+ container.bg = beautiful.release_event
+ end
+ )
+
+ return container
+end
+
+return create_click_events
diff --git a/docker-widget/docker.lua b/docker-widget/docker.lua
index f5ce7fac..7dc2b027 100644
--- a/docker-widget/docker.lua
+++ b/docker-widget/docker.lua
@@ -15,363 +15,406 @@ local naughty = require("naughty")
local gears = require("gears")
local beautiful = require("beautiful")
-local HOME_DIR = os.getenv("HOME")
-local WIDGET_DIR = HOME_DIR .. '/.config/awesome/awesome-wm-widgets/docker-widget'
-local ICONS_DIR = WIDGET_DIR .. '/icons/'
+--- Utility Function to handle alternative paths
+local function script_path()
+ local str = debug.getinfo(2, "S").source:sub(2)
+ return str:match("(.*/)")
+end
+
+local WIDGET_DIR = script_path()
+local ICONS_DIR = WIDGET_DIR .. "/icons/"
+
+local clickable_container = require(WIDGET_DIR .. "clickable-container")
local LIST_CONTAINERS_CMD = [[bash -c "docker container ls -a -s -n %s]]
.. [[ --format '{{.Names}}::{{.ID}}::{{.Image}}::{{.Status}}::{{.Size}}'"]]
--- Utility function to show warning messages
local function show_warning(message)
- naughty.notify{
- preset = naughty.config.presets.critical,
- title = 'Docker Widget',
- text = message}
+ naughty.notify({
+ preset = naughty.config.presets.critical,
+ title = "Docker Widget",
+ text = message,
+ })
end
-local popup = awful.popup{
- ontop = true,
- visible = false,
- shape = gears.shape.rounded_rect,
- border_width = 1,
- border_color = beautiful.bg_focus,
- maximum_width = 400,
- offset = { y = 5 },
- widget = {}
-}
-
-local docker_widget = wibox.widget {
- {
- {
- id = 'icon',
- widget = wibox.widget.imagebox
- },
- margins = 4,
- layout = wibox.container.margin
- },
- shape = function(cr, width, height)
- gears.shape.rounded_rect(cr, width, height, 4)
- end,
- widget = wibox.container.background,
- set_icon = function(self, new_icon)
- self:get_children_by_id("icon")[1].image = new_icon
- end
-}
+local popup = awful.popup({
+ ontop = true,
+ visible = false,
+ shape = gears.shape.rounded_rect,
+ border_width = 1,
+ border_color = beautiful.bg_focus,
+ maximum_width = 400,
+ offset = { y = 5 },
+ widget = {},
+})
+
+local docker_widget = wibox.widget({
+ {
+ {
+ id = "icon",
+ widget = wibox.widget.imagebox,
+ },
+ margins = 4,
+ layout = wibox.container.margin,
+ },
+ layout = wibox.layout.fixed.horizontal,
+ set_icon = function(self, new_icon)
+ self:get_children_by_id("icon")[1].image = new_icon
+ end,
+})
+
+local docker_widget_button = wibox.widget({
+ {
+ docker_widget,
+ widget = wibox.container.margin,
+ },
+ widget = clickable_container,
+})
local parse_container = function(line)
- local name, id, image, status, how_long, size = line:match('(.*)::(.*)::(.*)::(%w*) (.*)::(.*)')
- local actual_status
- if status == 'Up' and how_long:find('Paused') then actual_status = 'Paused'
- else actual_status = status end
-
- how_long = how_long:gsub('%s?%(.*%)%s?', '')
-
- local container = {
- name = name,
- id = id,
- image = image,
- status = actual_status,
- how_long = how_long,
- size = size,
- is_up = function() return status == 'Up' end,
- is_paused = function() return actual_status:find('Paused') end,
- is_exited = function() return status == 'Exited' end
- }
- return container
+ print(line)
+ local name, id, image, status, how_long, size = line:match("(.*)::(.*)::(.*)::(%w*)(.*)::(.*)")
+ local actual_status = ""
+ if status == "Up" and status:find("Paused") then
+ actual_status = "Paused"
+ else
+ actual_status = status
+ end
+
+ -- if how_long is null, then set it equal to status
+ if how_long == nil then
+ how_long = status
+ else
+ how_long = how_long:gsub("%s?%(.*%)%s?", "")
+ end
+
+ local container = {
+ name = name,
+ id = id,
+ image = image,
+ status = actual_status,
+ how_long = how_long,
+ size = size,
+ is_up = function()
+ return status == "Up"
+ end,
+ is_paused = function()
+ return actual_status:find("Paused")
+ end,
+ is_exited = function()
+ return status == "Exited"
+ end,
+ }
+ return container
end
local status_to_icon_name = {
- Up = ICONS_DIR .. 'play.svg',
- Exited = ICONS_DIR .. 'square.svg',
- Paused = ICONS_DIR .. 'pause.svg'
+ Up = ICONS_DIR .. "play.svg",
+ Exited = ICONS_DIR .. "square.svg",
+ Paused = ICONS_DIR .. "pause.svg",
}
local function worker(user_args)
-
- local args = user_args or {}
-
- local icon = args.icon or ICONS_DIR .. 'docker.svg'
- local number_of_containers = args.number_of_containers or -1
-
- docker_widget:set_icon(icon)
-
- local rows = {
- { widget = wibox.widget.textbox },
- layout = wibox.layout.fixed.vertical,
- }
-
- local function rebuild_widget(containers, errors, _, _)
- if errors ~= '' then
- show_warning(errors)
- return
- end
-
- for i = 0, #rows do rows[i]=nil end
-
- for line in containers:gmatch("[^\r\n]+") do
-
- local container = parse_container(line)
-
-
- local status_icon = wibox.widget {
- image = status_to_icon_name[container['status']],
- resize = false,
- widget = wibox.widget.imagebox
- }
-
-
- local start_stop_button
- if container.is_up() or container.is_exited() then
- start_stop_button = wibox.widget {
- {
- {
- id = 'icon',
- image = ICONS_DIR .. (container:is_up() and 'stop-btn.svg' or 'play-btn.svg'),
- opacity = 0.4,
- resize = false,
- widget = wibox.widget.imagebox
- },
- left = 2,
- right = 2,
- layout = wibox.container.margin
- },
- shape = gears.shape.circle,
- bg = '#00000000',
- widget = wibox.container.background
- }
- local old_cursor, old_wibox
- start_stop_button:connect_signal("mouse::enter", function(c)
- c:set_bg('#3B4252')
-
- local wb = mouse.current_wibox
- old_cursor, old_wibox = wb.cursor, wb
- wb.cursor = "hand1"
- c:get_children_by_id("icon")[1]:set_opacity(1)
- c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed') end)
- start_stop_button:connect_signal("mouse::leave", function(c)
- c:set_bg('#00000000')
- if old_wibox then
- old_wibox.cursor = old_cursor
- old_wibox = nil
- end
- c:get_children_by_id("icon")[1]:set_opacity(0.4)
- c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
- end)
-
- start_stop_button:buttons(
- gears.table.join( awful.button({}, 1, function()
- local command
- if container:is_up() then command = 'stop' else command = 'start' end
-
- status_icon:set_opacity(0.2)
- status_icon:emit_signal('widget::redraw_needed')
-
- spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function()
- if errors ~= '' then show_warning(errors) end
- spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
- function(stdout, stderr)
- rebuild_widget(stdout, stderr)
- end)
- end)
- end) ) )
- else
- start_stop_button = nil
- end
-
-
- local pause_unpause_button
- if container.is_up() then
- pause_unpause_button = wibox.widget {
- {
- {
- id = 'icon',
- image = ICONS_DIR .. (container:is_paused() and 'unpause-btn.svg' or 'pause-btn.svg'),
- opacity = 0.4,
- resize = false,
- widget = wibox.widget.imagebox
- },
- left = 2,
- right = 2,
- layout = wibox.container.margin
- },
- shape = gears.shape.circle,
- bg = '#00000000',
- widget = wibox.container.background
- }
- local old_cursor, old_wibox
- pause_unpause_button:connect_signal("mouse::enter", function(c)
- c:set_bg('#3B4252')
- local wb = mouse.current_wibox
- old_cursor, old_wibox = wb.cursor, wb
- wb.cursor = "hand1"
- c:get_children_by_id("icon")[1]:set_opacity(1)
- c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
- end)
- pause_unpause_button:connect_signal("mouse::leave", function(c)
- c:set_bg('#00000000')
- if old_wibox then
- old_wibox.cursor = old_cursor
- old_wibox = nil
- end
- c:get_children_by_id("icon")[1]:set_opacity(0.4)
- c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
- end)
-
- pause_unpause_button:buttons(
- gears.table.join( awful.button({}, 1, function()
- local command
- if container:is_paused() then command = 'unpause' else command = 'pause' end
-
- status_icon:set_opacity(0.2)
- status_icon:emit_signal('widget::redraw_needed')
-
- awful.spawn.easy_async('docker ' .. command .. ' ' .. container['name'], function(_, stderr)
- if stderr ~= '' then show_warning(stderr) end
- spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
- function(stdout, container_errors)
- rebuild_widget(stdout, container_errors)
- end)
- end)
- end) ) )
- else
- pause_unpause_button = nil
- end
-
- local delete_button
- if not container.is_up() then
- delete_button = wibox.widget {
- {
- {
- id = 'icon',
- image = ICONS_DIR .. 'trash-btn.svg',
- opacity = 0.4,
- resize = false,
- widget = wibox.widget.imagebox
- },
- margins = 4,
- layout = wibox.container.margin
- },
- shape = gears.shape.circle,
- bg = '#00000000',
- widget = wibox.container.background
- }
- delete_button:buttons(
- gears.table.join( awful.button({}, 1, function()
- awful.spawn.easy_async('docker rm ' .. container['name'], function(_, rm_stderr)
- if rm_stderr ~= '' then show_warning(rm_stderr) end
- spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
- function(lc_stdout, lc_stderr)
- rebuild_widget(lc_stdout, lc_stderr) end)
- end)
- end)))
-
- local old_cursor, old_wibox
- delete_button:connect_signal("mouse::enter", function(c)
- c:set_bg('#3B4252')
- local wb = mouse.current_wibox
- old_cursor, old_wibox = wb.cursor, wb
- wb.cursor = "hand1"
- c:get_children_by_id("icon")[1]:set_opacity(1)
- c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
- end)
- delete_button:connect_signal("mouse::leave", function(c)
- c:set_bg('#00000000')
- if old_wibox then
- old_wibox.cursor = old_cursor
- old_wibox = nil
- end
- c:get_children_by_id("icon")[1]:set_opacity(0.4)
- c:get_children_by_id("icon")[1]:emit_signal('widget::redraw_needed')
- end)
- else
- delete_button = nil
- end
-
-
- local row = wibox.widget {
- {
- {
- {
- {
- status_icon,
- margins = 8,
- layout = wibox.container.margin
- },
- valign = 'center',
- layout = wibox.container.place
- },
- {
- {
- {
- markup = '' .. container['name'] .. '',
- widget = wibox.widget.textbox
- },
- {
- text = container['size'],
- widget = wibox.widget.textbox
- },
- {
- text = container['how_long'],
- widget = wibox.widget.textbox
- },
- forced_width = 180,
- layout = wibox.layout.fixed.vertical
- },
- valign = 'center',
- layout = wibox.container.place
- },
- {
- {
- start_stop_button,
- pause_unpause_button,
- delete_button,
- layout = wibox.layout.align.horizontal
- },
- forced_width = 90,
- valign = 'center',
- haligh = 'center',
- layout = wibox.container.place,
- },
- spacing = 8,
- layout = wibox.layout.align.horizontal
- },
- margins = 8,
- layout = wibox.container.margin
- },
- bg = beautiful.bg_normal,
- widget = wibox.container.background
- }
-
-
- row:connect_signal("mouse::enter", function(c) c:set_bg(beautiful.bg_focus) end)
- row:connect_signal("mouse::leave", function(c) c:set_bg(beautiful.bg_normal) end)
-
- table.insert(rows, row)
- end
-
- popup:setup(rows)
- end
-
- docker_widget:buttons(
- gears.table.join(
- awful.button({}, 1, function()
- if popup.visible then
- docker_widget:set_bg('#00000000')
- popup.visible = not popup.visible
- else
- docker_widget:set_bg(beautiful.bg_focus)
- spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers),
- function(stdout, stderr)
- rebuild_widget(stdout, stderr)
- popup:move_next_to(mouse.current_widget_geometry)
- end)
- end
- end)
- )
- )
-
- return docker_widget
+ local args = user_args or {}
+
+ local icon = args.icon or ICONS_DIR .. "docker.svg"
+ local number_of_containers = args.number_of_containers or -1
+
+ docker_widget:set_icon(icon)
+
+ local rows = {
+ { widget = wibox.widget.textbox },
+ layout = wibox.layout.fixed.vertical,
+ }
+
+ local function rebuild_widget(containers, errors, _, _)
+ if errors ~= "" then
+ show_warning(errors)
+ return
+ end
+
+ for i = 0, #rows do
+ rows[i] = nil
+ end
+
+ for line in containers:gmatch("[^\r\n]+") do
+ local container = parse_container(line)
+
+ local status_icon = wibox.widget({
+ image = status_to_icon_name[ container["status"] ],
+ resize = false,
+ widget = wibox.widget.imagebox,
+ })
+
+ local start_stop_button
+ if container.is_up() or container.is_exited() then
+ start_stop_button = wibox.widget({
+ {
+ {
+ id = "icon",
+ image = ICONS_DIR .. (container:is_up() and "stop-btn.svg" or "play-btn.svg"),
+ opacity = 0.4,
+ resize = false,
+ widget = wibox.widget.imagebox,
+ },
+ left = 2,
+ right = 2,
+ layout = wibox.container.margin,
+ },
+ shape = gears.shape.circle,
+ bg = "#00000000",
+ widget = wibox.container.background,
+ })
+ local old_cursor, old_wibox
+ start_stop_button:connect_signal("mouse::enter", function(c)
+ c:set_bg("#3B4252")
+
+ local wb = mouse.current_wibox
+ old_cursor, old_wibox = wb.cursor, wb
+ wb.cursor = "hand1"
+ c:get_children_by_id("icon")[1]:set_opacity(1)
+ c:get_children_by_id("icon")[1]:emit_signal("widget::redraw_needed")
+ end)
+ start_stop_button:connect_signal("mouse::leave", function(c)
+ c:set_bg("#00000000")
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ c:get_children_by_id("icon")[1]:set_opacity(0.4)
+ c:get_children_by_id("icon")[1]:emit_signal("widget::redraw_needed")
+ end)
+
+ start_stop_button:buttons(awful.util.table.join(awful.button({}, 1, function()
+ local command
+ if container:is_up() then
+ command = "stop"
+ else
+ command = "start"
+ end
+
+ status_icon:set_opacity(0.2)
+ status_icon:emit_signal("widget::redraw_needed")
+
+ spawn.easy_async("docker " .. command .. " " .. container["name"], function()
+ if errors ~= "" then
+ show_warning(errors)
+ end
+ spawn.easy_async(
+ string.format(LIST_CONTAINERS_CMD, number_of_containers),
+ function(stdout, stderr)
+ rebuild_widget(stdout, stderr)
+ end
+ )
+ end)
+ end)))
+ else
+ start_stop_button = nil
+ end
+
+ local pause_unpause_button
+ if container.is_up() then
+ pause_unpause_button = wibox.widget({
+ {
+ {
+ id = "icon",
+ image = ICONS_DIR .. (container:is_paused() and "unpause-btn.svg" or "pause-btn.svg"),
+ opacity = 0.4,
+ resize = false,
+ widget = wibox.widget.imagebox,
+ },
+ left = 2,
+ right = 2,
+ layout = wibox.container.margin,
+ },
+ shape = gears.shape.circle,
+ bg = "#00000000",
+ widget = wibox.container.background,
+ })
+ local old_cursor, old_wibox
+ pause_unpause_button:connect_signal("mouse::enter", function(c)
+ c:set_bg("#3B4252")
+ local wb = mouse.current_wibox
+ old_cursor, old_wibox = wb.cursor, wb
+ wb.cursor = "hand1"
+ c:get_children_by_id("icon")[1]:set_opacity(1)
+ c:get_children_by_id("icon")[1]:emit_signal("widget::redraw_needed")
+ end)
+ pause_unpause_button:connect_signal("mouse::leave", function(c)
+ c:set_bg("#00000000")
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ c:get_children_by_id("icon")[1]:set_opacity(0.4)
+ c:get_children_by_id("icon")[1]:emit_signal("widget::redraw_needed")
+ end)
+
+ pause_unpause_button:buttons(awful.util.table.join(awful.button({}, 1, function()
+ local command
+ if container:is_paused() then
+ command = "unpause"
+ else
+ command = "pause"
+ end
+
+ status_icon:set_opacity(0.2)
+ status_icon:emit_signal("widget::redraw_needed")
+
+ awful.spawn.easy_async("docker " .. command .. " " .. container["name"], function(_, stderr)
+ if stderr ~= "" then
+ show_warning(stderr)
+ end
+ spawn.easy_async(
+ string.format(LIST_CONTAINERS_CMD, number_of_containers),
+ function(stdout, container_errors)
+ rebuild_widget(stdout, container_errors)
+ end
+ )
+ end)
+ end)))
+ else
+ pause_unpause_button = nil
+ end
+
+ local delete_button
+ if not container.is_up() then
+ delete_button = wibox.widget({
+ {
+ {
+ id = "icon",
+ image = ICONS_DIR .. "trash-btn.svg",
+ opacity = 0.4,
+ resize = false,
+ widget = wibox.widget.imagebox,
+ },
+ margins = 4,
+ layout = wibox.container.margin,
+ },
+ shape = gears.shape.circle,
+ bg = "#00000000",
+ widget = wibox.container.background,
+ })
+ delete_button:buttons(awful.util.table.join(awful.button({}, 1, function()
+ awful.spawn.easy_async("docker rm " .. container["name"], function(_, rm_stderr)
+ if rm_stderr ~= "" then
+ show_warning(rm_stderr)
+ end
+ spawn.easy_async(
+ string.format(LIST_CONTAINERS_CMD, number_of_containers),
+ function(lc_stdout, lc_stderr)
+ rebuild_widget(lc_stdout, lc_stderr)
+ end
+ )
+ end)
+ end)))
+
+ local old_cursor, old_wibox
+ delete_button:connect_signal("mouse::enter", function(c)
+ c:set_bg("#3B4252")
+ local wb = mouse.current_wibox
+ old_cursor, old_wibox = wb.cursor, wb
+ wb.cursor = "hand1"
+ c:get_children_by_id("icon")[1]:set_opacity(1)
+ c:get_children_by_id("icon")[1]:emit_signal("widget::redraw_needed")
+ end)
+ delete_button:connect_signal("mouse::leave", function(c)
+ c:set_bg("#00000000")
+ if old_wibox then
+ old_wibox.cursor = old_cursor
+ old_wibox = nil
+ end
+ c:get_children_by_id("icon")[1]:set_opacity(0.4)
+ c:get_children_by_id("icon")[1]:emit_signal("widget::redraw_needed")
+ end)
+ else
+ delete_button = nil
+ end
+
+ local row = wibox.widget({
+ {
+ {
+ {
+ {
+ status_icon,
+ margins = 8,
+ layout = wibox.container.margin,
+ },
+ valigh = "center",
+ layout = wibox.container.place,
+ },
+ {
+ {
+ {
+ markup = "" .. container["name"] .. "",
+ widget = wibox.widget.textbox,
+ },
+ {
+ text = container["size"],
+ widget = wibox.widget.textbox,
+ },
+ {
+ text = container["how_long"],
+ widget = wibox.widget.textbox,
+ },
+ forced_width = 180,
+ layout = wibox.layout.fixed.vertical,
+ },
+ valigh = "center",
+ layout = wibox.container.place,
+ },
+ {
+ {
+ start_stop_button,
+ pause_unpause_button,
+ delete_button,
+ layout = wibox.layout.align.horizontal,
+ },
+ forced_width = 90,
+ valign = "center",
+ haligh = "center",
+ layout = wibox.container.place,
+ },
+ spacing = 8,
+ layout = wibox.layout.align.horizontal,
+ },
+ margins = 8,
+ layout = wibox.container.margin,
+ },
+ bg = beautiful.bg_normal,
+ widget = wibox.container.background,
+ })
+
+ row:connect_signal("mouse::enter", function(c)
+ c:set_bg(beautiful.bg_focus)
+ end)
+ row:connect_signal("mouse::leave", function(c)
+ c:set_bg(beautiful.bg_normal)
+ end)
+
+ table.insert(rows, row)
+ end
+
+ popup:setup(rows)
+ end
+
+ docker_widget_button:buttons(awful.util.table.join(awful.button({}, 1, function()
+ if popup.visible then
+ popup.visible = not popup.visible
+ else
+ spawn.easy_async(string.format(LIST_CONTAINERS_CMD, number_of_containers), function(stdout, stderr)
+ rebuild_widget(stdout, stderr)
+ popup:move_next_to(mouse.current_widget_geometry)
+ end)
+ end
+ end)))
+
+ return docker_widget_button
end
-return setmetatable(docker_widget, { __call = function(_, ...) return worker(...) end })
+return setmetatable(docker_widget, {
+ __call = function(_, ...)
+ return worker(...)
+ end,
+})