mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-14 23:34:01 -04:00
* 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
874 lines
32 KiB
QML
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;
|
|
}
|
|
}
|