feat(dock): initial dock implementation

This commit is more a showcase to demonstrate how we can use the slot
package to build custom UI. It includes a minimal UPower service and
slot's parameters binding and reusable UI modules.

I feel like this is going the right direction. We still have some
improvement margin, but the code is well separated in layers. We can
easily connect to the service in different contexts.
This commit is contained in:
Aire-One 2024-12-04 23:36:33 +01:00
parent 782806b1f5
commit 7bb8653128
5 changed files with 183 additions and 0 deletions

View File

@ -59,6 +59,37 @@ slot {
slot = my_slots.build_desktop_decoration,
}
---------
-- Minimum code example to create a UPower service
local lgi = require "lgi"
local upower = lgi.require "UPowerGlib"
local gears = require "gears"
local function create_upower_service()
local service = gears.object()
service.device = upower.Client():get_display_device()
service.device.on_notify = function(d)
service:emit_signal("upower::update", d)
end
gears.timer.delayed_call(service.emit_signal, service, "upower::update", service.device)
return service
end
local upower_service = create_upower_service()
---------
-- Load the dock module
local dock = require "awesomerc.slots.dock"
slot {
target = capi.screen,
signal = "request::desktop_decoration",
slot = dock.create_desktop_decoration,
slot_params = {
upower_service = upower_service,
},
}
---------
slot {
target = capi.client,
signal = "request::default_mousebindings",

View File

@ -0,0 +1,47 @@
local battery_widget = require "awesomerc.ui.battery-widget"
local box = require "awesomerc.ui.box"
local slot = require "awesome-slot"
local ui_dock = require "awesomerc.ui.dock"
local wibox = require "wibox"
local dock = {}
function dock.create_desktop_decoration(params)
local upower_service = params.upower_service
local battery = battery_widget()
slot {
target = upower_service,
signal = "upower::update",
slot = function()
return function(_, device)
battery.battery = device.percentage
end
end,
}
return function(screen)
screen.dock = ui_dock {
screen = screen,
left_widget = {
box {
screen = screen,
bg = "#FF0000",
fg = "#FFFFFF",
widget = battery,
},
layout = wibox.layout.fixed.horizontal,
},
middle_widget = {
markup = "<b>middle</b>",
widget = wibox.widget.textbox,
},
right_widget = {
markup = "<b>right</b>",
widget = wibox.widget.textbox,
},
}
end
end
return dock

View File

@ -0,0 +1,22 @@
local gears = require "gears"
local wibox = require "wibox"
local battery_widget = {}
function battery_widget:set_battery(percentage)
self.markup = percentage
end
function battery_widget.create()
local self = wibox.widget {
widget = wibox.widget.textbox,
}
return gears.table.crush(self, battery_widget)
end
return setmetatable(battery_widget, {
__call = function(_)
return battery_widget.create()
end,
})

45
src/awesomerc/ui/box.lua Normal file
View File

@ -0,0 +1,45 @@
local background = require "wibox.container.background"
local beautiful = require "beautiful"
local margin = require "wibox.container.margin"
local shape = require "gears.shape"
local widget = require "wibox.widget"
local abs = math.abs
local dpi = beautiful.xresources.apply_dpi
local box = {}
-- 10 is an arbitrary value I found after some tests :shrug:
local CIRCLE_TO_BAR_THRESHOLD = 10
function box.shape(cr, width, height)
local s = abs(width - height) > CIRCLE_TO_BAR_THRESHOLD and shape.rounded_bar or shape.circle
return s(cr, width, height)
end
function box.new(args)
local box_widget = widget {
{
widget = margin,
draw_empty = false,
top = dpi(beautiful.bar_box_padding_y, args.screen),
bottom = dpi(beautiful.bar_box_padding_y, args.screen),
right = dpi(beautiful.bar_box_padding_x, args.screen),
left = dpi(beautiful.bar_box_padding_x, args.screen),
args.widget,
},
bg = args.bg,
fg = args.fg,
shape = box.shape,
widget = background,
}
return box_widget
end
return setmetatable(box, {
__call = function(_, ...)
return box.new(...)
end,
})

38
src/awesomerc/ui/dock.lua Normal file
View File

@ -0,0 +1,38 @@
local beautiful = require "beautiful"
local wibar = require "awful.wibar"
local wibox = require "wibox"
local dpi = beautiful.xresources.apply_dpi
local dock = {}
function dock.new(args)
local self = wibar {
screen = args.screen,
position = "top",
height = dpi(beautiful.bar_height, args.screen),
width = beautiful.bar_width, -- Width is a percentage of the screen size
margins = {
top = dpi(4),
bottom = dpi(4),
left = dpi(4),
right = dpi(4),
},
bg = "#000000",
fg = "#FFFFFF",
widget = {
args.left_widget,
args.middle_widget,
args.right_widget,
layout = wibox.layout.align.horizontal,
},
}
return self
end
return setmetatable(dock, {
__call = function(_, ...)
return dock.new(...)
end,
})