Files
cmleon51 36ff537e9a settings: explain why the autostart settings page is empty (#3754)
* settings: explain why the autostart settings page is empty

Fixed an issue where the autostart apps page was blank if
"xdg-desktop-autostart" was inactive.

The page was still reachable through the search function but not present
in the "Applicatiosn" settings sidebar tab.

* settings: point unavailable autostart applications to new docs section
2026-10-11 16:46:42 -04:00

874 lines
32 KiB
QML

pragma Singleton
import QtQuick
import Quickshell
import qs.Common
import qs.Services
Singleton {
id: root
readonly property string pluginPrefix: "plugin:"
readonly property var structure: [
{
"id": "personalization",
"text": I18n.tr("Wallpaper & colors"),
"icon": "wallpaper",
"hint": I18n.tr("Theme, palette, dark mode", "settings sidebar hint for the wallpaper and colors page"),
"tabIndex": 0,
"hubHeader": "WallpaperColorsTab",
"aliases": ["wallpaper", "colors", "wallpaper_colors", "theme_cursor_icons"],
"children": [
{
"id": "theme",
"hidden": true,
"text": I18n.tr("Theme & colors"),
"icon": "format_paint",
"tabIndex": 10,
"hint": I18n.tr("Theme, light and dark, matugen")
},
{
"id": "theme_schedule",
"hidden": true,
"text": I18n.tr("Dark mode"),
"icon": "dark_mode",
"tabIndex": 51,
"hint": I18n.tr("Schedule, sunset, wallpaper brightness")
},
{
"id": "wallpaper_cycling",
"hidden": true,
"text": I18n.tr("Automatic cycling"),
"icon": "autorenew",
"tabIndex": 52,
"hint": I18n.tr("Folder, interval, daily time")
},
{
"id": "theme_apps",
"advanced": true,
"text": I18n.tr("App theming"),
"icon": "apps",
"tabIndex": 50,
"hint": I18n.tr("GTK, Qt, portal, matugen templates")
},
{
"id": "palette_inject",
"advanced": true,
"text": I18n.tr("Injected palettes", "settings page title, external palette commands merged into matugen"),
"icon": "colorize",
"tabIndex": 64,
"hint": I18n.tr("External palette commands, namespaces", "settings sidebar hint for the injected palettes page")
}
]
},
{
"id": "theme_surfaces",
"aliases": ["interface", "interface_style"],
"text": I18n.tr("Interface style"),
"icon": "layers",
"tabIndex": 48,
"hubHeader": "ThemeSurfacesTab",
"hint": I18n.tr("Blur, shadows, corners", "settings sidebar hint for the interface style page"),
"children": [
{
"id": "surface_shadows",
"hidden": true,
"text": I18n.tr("Shadows"),
"icon": "tonality",
"tabIndex": 53,
"hint": I18n.tr("Intensity, color, light direction")
}
]
},
{
"id": "typography",
"aliases": ["fonts", "fonts_motion"],
"text": I18n.tr("Fonts & motion"),
"icon": "text_fields",
"tabIndex": 14,
"hint": I18n.tr("Fonts, scale, animations", "settings sidebar hint for the fonts and motion page")
},
{
"id": "separator_1",
"separator": true
},
{
"id": "dankbar",
"aliases": ["bar"],
"text": I18n.tr("Bar"),
"icon": "toolbar",
"hint": I18n.tr("Layout, position, appearance", "settings hub hint for the bar pages"),
"hubHeader": "BarHubHeader",
"children": [
{
"id": "dankbar_settings",
"hidden": true,
"aliases": ["dank_island", "island"],
"text": I18n.tr("General", "adjective, settings page and section title for general options"),
"icon": "tune",
"tabIndex": 3,
"hint": I18n.tr("Position, displays, auto-hide, behavior")
},
{
"id": "dankbar_appearance",
"hidden": true,
"aliases": ["frame"],
"text": I18n.tr("Appearance", "settings page and section title for visual options"),
"icon": "palette",
"tabIndex": 6,
"hint": I18n.tr("Background, corners, spacing, widget style")
},
{
"id": "dankbar_dot",
"hidden": true,
"aliases": ["dot", "dankdot"],
"text": I18n.tr("Dot", "bar layout: free-floating dot that opens island activities"),
"icon": "blur_on",
"tabIndex": 65,
"hint": I18n.tr("A floating companion that works alongside any bar layout", "bar settings: what the dot is")
}
]
},
{
"id": "dankbar_widgets",
"text": I18n.tr("Bar widgets"),
"icon": "widgets",
"tabIndex": 22,
"hubHeader": "WidgetsTab",
"aliases": ["bar_widgets", "workspaces", "workspaces_widgets"],
"hint": I18n.tr("Add, reorder, configure", "settings sidebar hint for the bar widgets page"),
"children": [
{
"id": "bar_widget",
"hidden": true,
"titleFrom": "selectedWidgetTitle",
"text": I18n.tr("Widget settings"),
"icon": "tune",
"tabIndex": 54,
"hint": I18n.tr("Options of one widget instance")
}
]
},
{
"id": "dock",
"text": I18n.tr("Dock"),
"aliases": ["desktop", "dock_launcher"],
"icon": "dock_to_bottom",
"hubHeader": "DockHubHeader",
"hint": I18n.tr("Position, pinned apps, trash", "settings sidebar hint for the dock page"),
"children": [
{
"id": "dock_general",
"text": I18n.tr("General"),
"icon": "tune",
"tabIndex": 5,
"hint": I18n.tr("Displays, taskbar, auto-hide")
},
{
"id": "dock_widgets",
"text": I18n.tr("Apps & widgets"),
"icon": "widgets",
"tabIndex": 57,
"hint": I18n.tr("Add, remove and configure dock items")
},
{
"id": "dock_appearance",
"text": I18n.tr("Appearance"),
"icon": "palette",
"tabIndex": 58,
"hint": I18n.tr("Size, padding, opacity, borders")
},
{
"id": "dock_advanced",
"advanced": true,
"text": I18n.tr("Advanced"),
"icon": "settings",
"tabIndex": 59,
"hint": I18n.tr("Layers, fullscreen, exclusive zone")
}
]
},
{
"id": "launcher",
"text": I18n.tr("Launcher"),
"icon": "grid_view",
"tabIndex": 9,
"hint": I18n.tr("Style, search, hidden apps", "settings sidebar hint for the launcher page")
},
{
"id": "dank_dash",
"text": I18n.tr("Dashboard", "settings page name for the dank dash popout"),
"icon": "space_dashboard",
"tabIndex": 43,
"aliases": ["dashboard", "dashboards_osd"],
"hint": I18n.tr("Tabs and weather")
},
{
"id": "desktop_widgets",
"text": I18n.tr("Desktop widgets"),
"icon": "widgets",
"tabIndex": 27,
"hubHeader": "DesktopWidgetsTab",
"hint": I18n.tr("Clocks, monitors, plugins", "settings sidebar hint for the desktop widgets page"),
"children": [
{
"id": "desktop_widget",
"hidden": true,
"titleFrom": "selectedWidgetTitle",
"text": I18n.tr("Widget settings"),
"icon": "tune",
"tabIndex": 63,
"hint": I18n.tr("Options of one widget instance")
}
]
},
{
"id": "separator_2",
"separator": true
},
{
"id": "notifications",
"text": I18n.tr("Notifications"),
"icon": "notifications",
"tabIndex": 17,
"hubHeader": "NotificationsTab",
"hint": I18n.tr("Popups, do not disturb, rules"),
"children": [
{
"id": "notification_rules",
"hidden": true,
"text": I18n.tr("Rules"),
"icon": "rule_settings",
"tabIndex": 55,
"hint": I18n.tr("Mute, ignore and priority rules per app")
}
]
},
{
"id": "osd",
"text": I18n.tr("On-screen displays"),
"icon": "picture_in_picture",
"tabIndex": 18,
"hint": I18n.tr("Volume, brightness, caps lock", "settings sidebar hint for the on-screen displays page")
},
{
"id": "wellbeing",
"text": I18n.tr("Digital wellbeing", "settings page and dashboard tab title, screen time tracking"),
"icon": "digital_wellbeing",
"tabIndex": 67,
"aliases": ["screen_time"],
"hint": I18n.tr("Screen time and app limits", "settings sidebar hint and dashboard tab description for digital wellbeing")
},
{
"id": "sound_media",
"aliases": ["sound", "media"],
"text": I18n.tr("Sound & media"),
"icon": "volume_up",
"children": [
{
"id": "audio",
"text": I18n.tr("Audio", "settings page name"),
"icon": "headphones",
"tabIndex": 29,
"hint": I18n.tr("Output and input devices")
},
{
"id": "sounds",
"text": I18n.tr("Sounds", "noun, settings page name for system sounds"),
"icon": "volume_up",
"tabIndex": 15,
"soundsOnly": true,
"hint": I18n.tr("System sound theme and events")
},
{
"id": "media_player",
"text": I18n.tr("Media player"),
"icon": "music_note",
"tabIndex": 16,
"hint": I18n.tr("Visualizer, album art, excluded players")
}
]
},
{
"id": "separator_3",
"separator": true
},
{
"id": "displays",
"text": I18n.tr("Displays"),
"icon": "monitor",
"hint": I18n.tr("Layout, scale, night mode", "settings sidebar hint for the displays page"),
"children": [
{
"id": "display_config",
"text": I18n.tr("Configuration", "settings page name under displays"),
"icon": "display_settings",
"tabIndex": 24,
"hint": I18n.tr("Arrangement, resolution, scale, profiles")
},
{
"id": "display_gamma",
"text": I18n.tr("Gamma control"),
"icon": "brightness_6",
"tabIndex": 25,
"hint": I18n.tr("Night mode, gamma, contrast")
},
{
"id": "display_widgets",
"text": I18n.tr("Display assignment"),
"icon": "widgets",
"tabIndex": 26,
"hint": I18n.tr("Which displays show the dock, popups, OSDs and wallpaper")
}
]
},
{
"id": "input",
"text": I18n.tr("Input", "noun, settings page name for input devices"),
"icon": "keyboard",
"hint": I18n.tr("Shortcuts, keyboard, mouse", "settings sidebar hint for the input page"),
"children": [
{
"id": "keybinds",
"text": I18n.tr("Keyboard shortcuts"),
"icon": "keyboard_command_key",
"tabIndex": 2,
"shortcutsOnly": true,
"hint": I18n.tr("Compositor and shell key bindings")
},
{
"id": "keyboard",
"text": I18n.tr("Keyboard", "settings page name"),
"icon": "keyboard",
"tabIndex": 45,
"inputCapable": true,
"hint": I18n.tr("Layouts, repeat rate, num lock")
},
{
"id": "mouse_touchpad",
"text": I18n.tr("Mouse & touchpad"),
"icon": "mouse",
"tabIndex": 44,
"pointerCapable": true,
"hint": I18n.tr("Speed, scrolling, tap to click")
}
]
},
{
"id": "power_battery",
"text": I18n.tr("Power & battery"),
"icon": "power_settings_new",
"aliases": ["power", "power_security"],
"children": [
{
"id": "power_sleep",
"text": I18n.tr("Power & sleep"),
"icon": "power_settings_new",
"tabIndex": 21,
"hint": I18n.tr("Idle timeouts, power menu, custom actions")
},
{
"id": "battery",
"text": I18n.tr("Battery"),
"icon": "battery_charging_full",
"tabIndex": 42,
"hint": I18n.tr("Charge limit, alerts, power profiles")
}
]
},
{
"id": "network",
"text": I18n.tr("Network", "noun, settings page and widget title"),
"icon": "wifi",
"hint": I18n.tr("Wi-Fi, Ethernet, VPN", "settings sidebar hint for the network page"),
"dmsOnly": true,
"children": [
{
"id": "network_wifi",
"text": I18n.tr("Wi-Fi", "wireless network, page and section title"),
"icon": "wifi",
"tabIndex": 40,
"hint": I18n.tr("Networks, saved networks, hotspot")
},
{
"id": "network_ethernet",
"text": I18n.tr("Ethernet"),
"icon": "settings_ethernet",
"tabIndex": 39,
"hint": I18n.tr("Adapters and saved configurations")
},
{
"id": "network_vpn",
"text": I18n.tr("VPN", "virtual private network, widget and page title"),
"icon": "vpn_key",
"tabIndex": 41,
"hint": I18n.tr("Connections and autoconnect")
},
{
"id": "network_cellular",
"text": I18n.tr("Cellular"),
"icon": "network_cell",
"tabIndex": 47,
"cellularOnly": true,
"hint": I18n.tr("Modem and mobile data")
},
{
"id": "network_status",
"advanced": true,
"text": I18n.tr("Status"),
"icon": "lan",
"tabIndex": 7,
"hint": I18n.tr("Backend and connection preference")
}
]
},
{
"id": "separator_4",
"separator": true
},
{
"id": "user_accounts",
"text": I18n.tr("Users & accounts", "settings sidebar category"),
"icon": "account_circle",
"hubHeader": "UserAccountsTab",
"tabIndex": 60,
"children": [
{
"id": "users",
"text": I18n.tr("Accounts", "settings page name for user accounts"),
"icon": "manage_accounts",
"tabIndex": 35,
"hint": I18n.tr("Users", "hint under the accounts settings sidebar entry")
},
{
"id": "user_create",
"hidden": true,
"text": I18n.tr("Add user", "button and settings page title, creates a new user account"),
"icon": "person_add",
"tabIndex": 61
}
]
},
{
"id": "security_accounts",
"aliases": ["security"],
"text": I18n.tr("Security"),
"icon": "lock",
"children": [
{
"id": "lock_screen",
"text": I18n.tr("Lock screen"),
"icon": "lock",
"tabIndex": 11,
"hint": I18n.tr("Layout, authentication, screensaver")
},
{
"id": "greeter",
"text": I18n.tr("Greeter", "noun, login screen settings page and greeter account badge"),
"icon": "login",
"tabIndex": 31,
"greeterOnly": true,
"hint": I18n.tr("Login screen appearance and authentication")
},
{
"id": "greeter_auth",
"hidden": true,
"greeterOnly": true,
"text": I18n.tr("Authentication"),
"icon": "fingerprint",
"tabIndex": 62
}
]
},
{
"id": "separator_5",
"separator": true
},
{
"id": "applications",
"text": I18n.tr("Applications"),
"icon": "apps",
"hint": I18n.tr("Defaults, autostart, rules", "settings sidebar hint for the applications page"),
"children": [
{
"id": "default_apps",
"text": I18n.tr("Default apps"),
"icon": "star",
"tabIndex": 34,
"hint": I18n.tr("Browser, terminal, file manager, media")
},
{
"id": "autostart",
"text": I18n.tr("Autostart apps"),
"icon": "line_start",
"tabIndex": 36,
"hint": I18n.tr("Apps and commands started with the session")
},
{
"id": "window_rules",
"text": I18n.tr("Window rules"),
"icon": "select_window",
"tabIndex": 38,
"windowRulesCapable": true,
"hint": I18n.tr("Floating, opacity and placement rules per app")
},
{
"id": "running_apps",
"advanced": true,
"text": I18n.tr("Running apps"),
"icon": "app_registration",
"tabIndex": 19,
"hyprlandNiriOnly": true,
"hint": I18n.tr("App ID substitutions")
}
]
},
{
"id": "date_time_region",
"aliases": ["datetime", "region"],
"text": I18n.tr("Date, time & region"),
"icon": "schedule",
"hint": I18n.tr("Clock, weather, locale", "settings sidebar hint for the date, time and region page"),
"children": [
{
"id": "time_weather",
"text": I18n.tr("Time & weather"),
"icon": "schedule",
"tabIndex": 1,
"hint": I18n.tr("Clock format, calendar, weather location")
},
{
"id": "weather",
"text": I18n.tr("Weather"),
"icon": "partly_cloudy_day",
"tabIndex": 56,
"hint": I18n.tr("Forecast and conditions")
},
{
"id": "locale",
"text": I18n.tr("Locale", "settings page name for language and region"),
"icon": "language",
"tabIndex": 30,
"hint": I18n.tr("Language, time and date locale")
}
]
},
{
"id": "system",
"text": I18n.tr("System & integrations"),
"icon": "memory",
"hint": I18n.tr("Updates, clipboard, %1", "settings sidebar hint for the system and integrations page, %1 is the compositor name").arg(CompositorService.displayName),
"children": [
{
"id": "updater",
"text": I18n.tr("Software updates", "settings page, modal and bar widget title, DMS and system package updates"),
"icon": "system_update_alt",
"tabIndex": 20,
"hint": I18n.tr("DMS and system updates", "settings sidebar hint for the software updates page")
},
{
"id": "updater_changelog",
"hidden": true,
"text": I18n.tr("Release notes", "settings page and card title, notes for a DMS release"),
"icon": "auto_awesome",
"tabIndex": 66,
"hint": I18n.tr("Summary, highlights, links", "settings sidebar hint for the release notes page")
},
{
"id": "clipboard",
"text": I18n.tr("Clipboard", "noun, settings page name and launcher section title"),
"icon": "content_paste",
"tabIndex": 23,
"clipboardOnly": true,
"hint": I18n.tr("History size, retention, paste behavior")
},
{
"id": "compositor_layout",
"text": CompositorService.displayName,
"icon": "layers",
"tabIndex": 37,
"layoutCapable": true,
"hint": I18n.tr("Gaps, window borders, corner radius")
},
{
"id": "multiplexers",
"advanced": true,
"text": I18n.tr("Multiplexers", "settings page name for terminal multiplexers like tmux"),
"icon": "terminal",
"tabIndex": 32,
"hint": I18n.tr("tmux, zellij, and herdr sessions", "settings page description for terminal multiplexer sessions; tmux, zellij, and herdr are product names")
},
{
"id": "printers",
"advanced": true,
"text": I18n.tr("Printers", "settings page name and control center widget title"),
"icon": "print",
"tabIndex": 8,
"cupsOnly": true,
"hint": I18n.tr("CUPS printers, jobs and classes")
}
]
},
{
"id": "plugins",
"text": I18n.tr("Plugins"),
"icon": "extension",
"hint": I18n.tr("Browse, install, registries"),
"tabIndex": 12,
"hubHeader": "PluginsHubHeader",
"children": [
{
"id": "plugins_manage",
"hidden": true,
"text": I18n.tr("Manage Registries", "plugin registry management"),
"icon": "folder_open",
"tabIndex": 28,
"hint": I18n.tr("Plugin directory and registries")
}
]
},
{
"id": "separator_6",
"separator": true
},
{
"id": "about",
"text": I18n.tr("About", "settings page name"),
"icon": "info",
"hint": I18n.tr("Version, links, diagnostics"),
"tabIndex": 13
}
]
readonly property var pageMap: buildPageMap(structure)
readonly property var normalizedIds: buildNormalizedIds(pageMap)
readonly property var tabIndexToPage: buildTabIndexMap(pageMap)
readonly property var pluginHubRows: buildPluginRows(PluginService.availablePluginsList)
function buildPageMap(entries) {
const map = {};
for (const entry of entries) {
if (entry.separator)
continue;
const hub = Object.assign({}, entry, {
"kind": entry.children ? "hub" : "leaf",
"parentId": ""
});
map[entry.id] = hub;
for (const child of entry.children || []) {
map[child.id] = Object.assign({}, child, {
"kind": "leaf",
"parentId": entry.id
});
}
}
return map;
}
function buildNormalizedIds(map) {
const out = {};
for (const id in map) {
out[normalizeId(id)] = id;
for (const alias of map[id].aliases || [])
out[normalizeId(alias)] = id;
}
return out;
}
function buildTabIndexMap(map) {
const out = {};
for (const id in map) {
const entry = map[id];
if (entry.tabIndex === undefined)
continue;
if (out[entry.tabIndex] === undefined || entry.kind === "leaf")
out[entry.tabIndex] = id;
}
return out;
}
function buildPluginRows(plugins) {
const rows = (plugins || []).map(plugin => ({
"id": pluginPrefix + plugin.id,
"kind": "plugin",
"parentId": "plugins",
"pluginId": plugin.id,
"text": plugin.name || plugin.id,
"icon": plugin.icon || "extension",
"hint": plugin.description || "",
"hasSettings": !!plugin.settings && plugin.type !== "desktop"
}));
rows.sort((a, b) => a.text.localeCompare(b.text));
return rows;
}
function normalizeId(name) {
const normalized = String(name).toLowerCase().replace(/[_\-\s]/g, "");
return normalized === "compositor" ? "workspaces" : normalized;
}
function isPluginPage(id) {
return String(id).startsWith(pluginPrefix);
}
function pluginIdOf(id) {
return String(id).slice(pluginPrefix.length);
}
function page(id) {
if (!id)
return null;
if (isPluginPage(id))
return pluginPage(pluginIdOf(id));
return pageMap[id] ?? null;
}
function pluginPage(pluginId) {
const row = pluginHubRows.find(candidate => candidate.pluginId === pluginId);
if (row)
return row;
return {
"id": pluginPrefix + pluginId,
"kind": "plugin",
"parentId": "plugins",
"pluginId": pluginId,
"text": pluginId,
"icon": "extension",
"hint": "",
"hasSettings": false
};
}
function parentOf(id) {
return page(id)?.parentId ?? "";
}
function tabIndexForPage(id) {
const entry = page(id);
if (!entry || entry.tabIndex === undefined)
return -1;
return entry.tabIndex;
}
function pageForTabIndex(tabIndex) {
return tabIndexToPage[tabIndex] ?? "";
}
function isVisible(entry) {
if (!entry)
return false;
if (entry.dmsOnly && !NetworkService.networkAvailable)
return false;
if (entry.cupsOnly && !CupsService.cupsAvailable)
return false;
if (entry.shortcutsOnly && !KeybindsService.available)
return false;
if (entry.soundsOnly && MultimediaService.unavailable)
return false;
if (entry.hyprlandNiriOnly && !CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isMango)
return false;
if (entry.windowRulesCapable && !CompositorService.supportsWindowRules)
return false;
if (entry.layoutCapable && !CompositorService.supportsLayoutConfig)
return false;
if (entry.inputCapable && !CompositorService.supportsInputConfig)
return false;
if (entry.pointerCapable && !CompositorService.supportsPointerConfig)
return false;
if (entry.clipboardOnly && (!DMSService.isConnected || DMSService.apiVersion < 23))
return false;
if (entry.greeterOnly)
GreeterService.ensureDetected();
if (entry.greeterOnly && !GreeterService.available)
return false;
if (entry.autostartOnly)
DesktopService.ensureProbed();
if (entry.autostartOnly && !DesktopService.autostartAvailable)
return false;
if (entry.cellularOnly && (NetworkService.cellularDevices?.length ?? 0) === 0)
return false;
if (entry.kind === "hub" && !entry.hubHeader && visibleLeaves(entry.id).length === 0)
return false;
return true;
}
function visibleLeaves(hubId) {
const hub = pageMap[hubId];
if (!hub?.children)
return [];
return hub.children.filter(child => isVisible(child));
}
readonly property var groupAccents: ["purple", "blue", "green", "orange", "pink", "teal", "yellow", "red"]
function accentFor(pageId) {
const entry = page(pageId);
if (!entry)
return "";
const topId = entry.parentId || entry.id;
let group = 0;
for (const item of structure) {
if (item.separator) {
group++;
continue;
}
if (item.id === topId)
return groupAccents[group] ?? "";
}
return "";
}
function hubHint(entry) {
return entry.hint || visibleLeaves(entry.id).filter(child => entry.hubHeader || !child.hidden).map(child => child.text).join(", ");
}
function hubMainRows(hubId) {
const hub = pageMap[hubId];
if (!hub?.children)
return [];
return hub.children.filter(child => !child.advanced && !child.hidden && isVisible(child));
}
function hubMoreRows(hubId) {
const hub = pageMap[hubId];
if (!hub?.children)
return [];
return hub.children.filter(child => child.advanced && !child.hidden && isVisible(child));
}
function hubRows(hubId) {
return hubMainRows(hubId).concat(hubMoreRows(hubId));
}
function resolvePage(name) {
if (!name)
return "";
const raw = String(name).trim();
if (isPluginPage(raw))
return raw;
const id = normalizedIds[normalizeId(raw)];
if (!id)
return "";
const entry = pageMap[id];
if (entry.kind !== "hub" || entry.hubHeader)
return id;
const leaves = visibleLeaves(id);
return leaves.length === 1 ? leaves[0].id : id;
}
function listPageIds() {
const ids = [];
for (const entry of structure) {
if (entry.separator)
continue;
ids.push(entry.id);
for (const child of entry.children || [])
ids.push(child.id);
}
for (const row of pluginHubRows)
ids.push(row.id);
return ids;
}
}