-
Notifications
You must be signed in to change notification settings - Fork 1
The Dock and Tasklist
There are multiple things shown in the screenshot, so let's break them down one by one.
First, both the dock and tasklist use the same basic template for their styling: A white circle (the color changes for the tasklist, see the very thin, purple border between the Marktext logo and the white border - that's because it's the currently active client instance), with an icon and a small white border. What's more interesting here is the subtle shadow all of them cast. That one only works because we are dealing with circular icons. Instead of some "actual" shadow drawing routine, we're using gears.color
to draw a circular gradient pattern, which gets more transparent towards the outside, in addition to having a small vertical offset. They also all have a light overlay when hovering over them, which is a bigger circle than the icon (as you can see on the Marktext logo, which I was hovering above in the screenshot).
Fundamentally, the dock is generated by using the GSettings key org.gnome.shell.favorite-apps
. This is primarily used by GNOME to store its own dock / favorites dash icons. To read it, we can use LGI:
local lgi = require("lgi")
local Gio = lgi.Gio
--- Check whether a `Gio.Settings` (GSettings) schema is valid / exits
---@param schema string The name of the shema you want to check
---@return boolean found_schema `true` if the schema is valid, otherwise `false´
local function check_schema(schema)
--- If we just blindly try to access `org.gnome.shell`, we may cause
--- a crash at runtime. To avoid this, we loop through each key that
--- Gio knows for sure exists, and when we find the one we're looking
--- for, we return `true`.
for _, s in pairs(Gio.Settings.list_schemas()) do
if s == schema then
return true
end
end
return false
end
--- Get a list of favorite apps in
--- `{ "app1.desktop", "app2.desktop", ... }`
--- format.
---@param schema string The name of the shema you want to retrive
---@return string[]? The list of favorite apps; can be `nil`
local function get_favorite_apps()
local schema = "org.gnome.shell"
if check_schema(schema) then
return Gio.Settings({ schema = schema }):get_strv("favorite-apps")
end
end
To generate these icons, we're using a modified version of menubar.utils
, which can also properly read additional actions specified by an app (in addition to being able to properly find every icon in an icon theme, but that's of no relevance here).
These actions are automatically shown in your system locale if a translation is available, hence them being shown in German here (they translate to Open a new tab
and Open a new window
, although you probably already guessed that based on the icons).
As you can see, in addition to the app's actions, there's also a "Remove from dock" option and some dashes. The latter are purely to provide a separator (I used minus characters instead of a proper widget like wibox.widget.separator
since you can only put an icon and text in an awful.menu
widget), although one neat detail is that it will first check whether the app has any actions; if not, the dashes are not shown (since they would be at the bottom, which would be kind of pointless). The remove option is a little more interesting. When clicking it, it emits a global signal (which the dock makes sure is only ever handled once, even if you create multiple docks or even require()
the module multiple times). This signal will cause the favorites to be read, to be scanned for the matching app, and for that app to be removed. We then use a function similar to the getter in the code block above to set the new dock icons:
--- For easy of readability, any validity checking has been omitted here.
Gio.Settings({ schema = "org.gnome.shell" }):set_strv("favorite-apps", new_favorites)
Finally, when hovering over a dock item, you will see a tooltip styled like the task preview, just... without the task preview. It will also only show the app's name instead of "$app_name - $window_title" (pseudo-formatting).
Basically, the tasklist is just a standard awful.tasklist
combined with the preview module provided by Bling. The only "special" things here are pretty much just the same as in the dock.