applications
Installed desktop entries, indexed by window app_id.
text {
content = computed({ mantle.workspaces, mantle.applications }, function(workspaces, applications)
local client = workspaces.active_client
if client == nil then
return ""
end
local index = applications.by_app_id[client.app_id]
return index and applications.entries[index].name or client.app_id
end, ""),
}
State
mantle.applications:get() returns ApplicationsState, nil before the first push. A field marked ? may be absent.
mantle.applications payload.
| Field | Type | Description |
|---|---|---|
by_app_id | table<string, integer> | Window app_id to its 1-based index: entries[by_app_id[app_id]]. Keys are exact StartupWMClass and desktop ids, then lowercased and last-dot-segment guesses. |
entries | AppSummary[] | Installed entries, sorted by name (byte order), including NoDisplay entries for window lookup. Launchers omit entries with no_display = true. Hidden entries are excluded. A change under an applications directory rescans 250 ms after the last event. |
AppSummary
One Type=Application desktop entry; display data only, argv stays private.
| Field | Type | Description |
|---|---|---|
comment? | string | Comment=, unlocalized, e.g. "Web Browser"; nil without the key. |
generic_name? | string | GenericName=, unlocalized, e.g. "Text Editor"; nil without the key. |
icon? | string | Icon= as written, a theme name or absolute path, both accepted by icon { name }; nil without the key. |
id | string | Desktop file id, e.g. "org.telegram.desktop"; the argument of "launch". |
keywords | string[] | Keywords= split on ;, for search; empty without the key. |
name | string | Name=, unlocalized: Name[xx] is not read. |
no_display | boolean | NoDisplay=true: omit from launchers, but keep its name and icon for window lookup. |
Actions
Call each as mantle.applications:<action>(arguments...); ? marks an argument you may omit.
| Action | Arguments | Description |
|---|---|---|
refresh | Rescans installed desktop entries. The directories are watched, so only a failed watch (logged) needs this. | |
launch | id: string, opts?: LaunchOpts | Launches entries[].id, detached; Terminal=true entries run in $TERMINAL. opts.env sets a variable to a string or unsets it with false. |
open_url | url: string | Opens an http, https or mailto URL with xdg-open. One over 2048 bytes or holding whitespace or a control character is refused. |
LaunchOpts
Options of a detached launch: process.detach’s third argument and launch’s second.
| Field | Type | Description |
|---|---|---|
env? | table<string, string|false> | Changes to the Supervisor’s environment: NAME = "value" sets, NAME = false unsets. |
Backend
Reads applications/ under $XDG_DATA_HOME (default ~/.local/share), then each absolute $XDG_DATA_DIRS
entry (default /usr/local/share:/usr/share), subdirectories included, four levels deep. The first file for a desktop id wins, so a
copy under ~/.local/share/applications overrides the system one. Type=Application entries with
Name and a non-empty Exec are listed, including NoDisplay=true entries so windows can resolve
their names and icons. Launchers filter out entries with no_display = true; Hidden=true entries
are excluded entirely. inotify watches every
directory, including ones created later. launch spawns the Exec command detached, dropping field
codes such as %u; a Terminal=true entry runs as $TERMINAL -e command args. launch(id, { env = { NAME = "value", OTHER = false } })
sets or unsets variables for that launch (a string sets, false unsets; for a Terminal=true entry they apply to the $TERMINAL process); a single-instance app that is already running passes the launch to
its existing process, which keeps its old environment. open_url takes no options: use
process.detach("xdg-open", { url }, { env = ... }).
How do I…
| Task | Answer |
|---|---|
| Hide an app from a launcher | Copy its .desktop file to ~/.local/share/applications and add NoDisplay=true; filter entry.no_display in the launcher |
Gotchas
| Trap | Fix |
|---|---|
launch of a terminal app does nothing | Terminal=true needs $TERMINAL in the Supervisor’s environment, not an interactive shell’s. mantle log names the refusal |
See also: App launcher recipe.