From 8fa463975a885f937f345820d950900426553589 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 19 May 2026 10:50:36 +0200 Subject: [PATCH] Remove dead code --- docs/omarchy-shell.md | 9 ++- shell/README.md | 22 +++--- shell/Ui/PanelKeyCatcher.qml | 2 +- shell/plugins/README.md | 27 +++---- shell/plugins/background/Background.qml | 4 -- shell/plugins/background/manifest.json | 9 ++- shell/plugins/bar/Bar.qml | 23 +++--- shell/plugins/bar/README.md | 3 +- shell/plugins/bar/manifest.json | 9 ++- shell/plugins/bar/widgets/monitorPanel.qml | 14 +--- shell/plugins/bar/widgets/networkPanel.qml | 10 --- shell/plugins/bar/widgets/weather.qml | 31 ++++---- .../clipboard-picker/ClipboardPicker.qml | 13 ---- shell/plugins/clipboard-picker/manifest.json | 5 +- shell/plugins/dev-gallery/GalleryPanel.qml | 5 +- shell/plugins/dev-gallery/manifest.json | 9 ++- shell/plugins/emoji-picker/EmojiPicker.qml | 9 --- shell/plugins/emoji-picker/manifest.json | 5 +- shell/plugins/image-picker/ImagePicker.qml | 22 +----- shell/plugins/image-picker/manifest.json | 10 +-- shell/plugins/menu/Menu.qml | 11 --- shell/plugins/menu/manifest.json | 10 +-- shell/plugins/notifications/Service.qml | 2 - .../components/NotificationCard.qml | 71 ++----------------- shell/plugins/notifications/manifest.json | 5 +- shell/plugins/osd/Osd.qml | 4 -- shell/plugins/osd/manifest.json | 9 ++- shell/plugins/polkit/PolkitAgent.qml | 9 --- shell/plugins/polkit/manifest.json | 5 +- shell/plugins/settings/SettingsPanel.qml | 17 +++-- shell/plugins/settings/manifest.json | 9 ++- shell/scripts/indicators/idle.sh | 7 -- shell/services/BarWidgetRegistry.qml | 5 -- shell/services/PluginRegistry.qml | 9 --- shell/shell-defaults.json | 6 +- shell/shell.qml | 19 ++--- 36 files changed, 130 insertions(+), 309 deletions(-) delete mode 100755 shell/scripts/indicators/idle.sh diff --git a/docs/omarchy-shell.md b/docs/omarchy-shell.md index 127fc38c..e7aa909a 100644 --- a/docs/omarchy-shell.md +++ b/docs/omarchy-shell.md @@ -17,7 +17,6 @@ first call. "author": "You", "description": "A clock that does cool things", "kinds": ["bar-widget"], - "activation": "on-demand", "entryPoints": { "barWidget": "Widget.qml" } } ``` @@ -32,9 +31,9 @@ first call. | `menu` | Summoned menu surface | | `service` | Headless singleton, no UI | -`activation` is `persistent` (loaded at startup) or `on-demand` -(loaded by `shell summon`, unloaded by `shell hide`). On-demand -plugins can set `keepLoaded: true` to survive between summons. +Panels, overlays, and menus are loaded when summoned. Plugins can set +`keepLoaded: true` to survive between summons. First-party services are +loaded at startup. Full schema: [`shell/services/PluginRegistry.qml`](../shell/services/PluginRegistry.qml). @@ -91,7 +90,7 @@ Rules: bar widgets, `plugins[]` for everything else. 2. Settings are inline on the entry. No `config:` sub-object, no merge layers. -3. Enabled ⇔ present. +3. Third-party enabled ⇔ present; first-party plugins are always enabled. 4. `allowMultiple: true` in the manifest permits multiple instances. 5. `version: 1` is required. diff --git a/shell/README.md b/shell/README.md index 652c9435..0f15a8a4 100644 --- a/shell/README.md +++ b/shell/README.md @@ -52,7 +52,6 @@ shell should load it. Minimal example: "author": "You", "description": "A clock that does cool things", "kinds": ["bar-widget"], - "activation": "on-demand", "entryPoints": { "barWidget": "Widget.qml" }, "barWidget": { "displayName": "Cool clock", @@ -77,11 +76,10 @@ Supported `kinds`: | `service` | A headless singleton, no UI | | `bar` | Reserved for the first-party bar host (`omarchy.bar`). Third-party plugins should ship `bar-widget`s; they do not replace the host bar. | -`activation` is either `persistent` (loaded on startup, never unloaded) or -`on-demand` (loaded by `shell summon ` and unloaded by `shell hide`). -Plugins that need to outlive a single summon can set `keepLoaded: true` -(e.g. the image picker keeps its overlay window mounted between -summons). +Panels, overlays, and menus are loaded when summoned. Plugins that need +to outlive a single summon can set `keepLoaded: true` (e.g. the image +picker keeps its overlay window mounted between summons). First-party +services are loaded at startup. The full schema lives in `services/PluginRegistry.qml`. @@ -176,10 +174,7 @@ rewrites the `bar` subtree from the current `shell-defaults.json`. ] } }, - "plugins": [ - { "id": "omarchy.settings" }, - { "id": "omarchy.image-picker" } - ] + "plugins": [] } ``` @@ -191,9 +186,10 @@ rewrites the `bar` subtree from the current `shell-defaults.json`. 2. **Settings are inline on the entry.** No `config:` sub-object, no separate per-plugin settings file, no merge layers. The fields on each entry are the values the plugin sees. -3. **Enabled ⇔ present.** A plugin is enabled iff its id appears somewhere - in shell.json. For bar widgets, the bar settings UI adds/removes layout - entries; other plugin kinds are enabled with the shell IPC. +3. **Third-party enabled ⇔ present.** A third-party plugin is enabled iff + its id appears somewhere in shell.json. For bar widgets, the bar + settings UI adds/removes layout entries; other plugin kinds are enabled + with the shell IPC. First-party plugins are always enabled. 4. **Multiple instances** are allowed when a manifest sets `allowMultiple: true`. Each instance is independent — e.g. two clocks in different timezones are just two `{"id":"calendar", "timezone": ...}` diff --git a/shell/Ui/PanelKeyCatcher.qml b/shell/Ui/PanelKeyCatcher.qml index b4def79d..fd9b87f1 100644 --- a/shell/Ui/PanelKeyCatcher.qml +++ b/shell/Ui/PanelKeyCatcher.qml @@ -2,7 +2,7 @@ import QtQuick // Drop-in key dispatcher for keyboard-driven panels. Wraps panel content // and emits semantic signals so each panel keeps its own state machine -// (focusSection, selectedIndex, activation rules) while the boilerplate +// (focusSection, selectedIndex, action rules) while the boilerplate // key handling lives here. // // Usage: diff --git a/shell/plugins/README.md b/shell/plugins/README.md index 948a2e9d..aa9dee43 100644 --- a/shell/plugins/README.md +++ b/shell/plugins/README.md @@ -1,24 +1,25 @@ # First-party plugins -These plugins ship with Omarchy and are loaded by the shell at startup. +These plugins ship with Omarchy and are discovered by the shell at startup. They use the same `manifest.json` contract as third-party plugins; the only difference is that the shell flags them with `__isFirstParty: true` -so they cannot be disabled. +so they are always enabled. Services and keep-loaded panels are mounted at +startup; other panels, overlays, and menus are loaded on demand. User-installed plugins live alongside these conceptually but on disk under `~/.config/omarchy/plugins//` rather than in this directory. -| Plugin | id | kinds | activation | entry point | -|---------------|-------------------------|-----------|------------|-------------------------------------| -| Bar | `omarchy.bar` | `bar` | persistent | `bar/Bar.qml` | -| Bar settings | `omarchy.settings` | `panel` | on-demand | `settings/SettingsPanel.qml` | -| Image picker | `omarchy.image-picker` | `overlay` | on-demand | `image-picker/ImagePicker.qml` | -| Emoji picker | `omarchy.emoji-picker` | `overlay` | on-demand | `emoji-picker/EmojiPicker.qml` | -| Clipboard mgr | `omarchy.clipboard-picker`| `overlay` | on-demand | `clipboard-picker/ClipboardPicker.qml`| -| Omarchy menu | `omarchy.menu` | `menu` | on-demand | `menu/Menu.qml` | -| Notifications | `omarchy.notifications` | `service` | persistent | `notifications/Service.qml` | -| OSD | `omarchy.osd` | `panel` | persistent | `osd/Osd.qml` | -| Polkit agent | `omarchy.polkit` | `service` | persistent | `polkit/PolkitAgent.qml` | +| Plugin | id | kinds | entry point | +|---------------|---------------------------|-----------|---------------------------------------| +| Bar | `omarchy.bar` | `bar` | `bar/Bar.qml` | +| Bar settings | `omarchy.settings` | `panel` | `settings/SettingsPanel.qml` | +| Image picker | `omarchy.image-picker` | `overlay` | `image-picker/ImagePicker.qml` | +| Emoji picker | `omarchy.emoji-picker` | `overlay` | `emoji-picker/EmojiPicker.qml` | +| Clipboard mgr | `omarchy.clipboard-picker`| `overlay` | `clipboard-picker/ClipboardPicker.qml`| +| Omarchy menu | `omarchy.menu` | `menu` | `menu/Menu.qml` | +| Notifications | `omarchy.notifications` | `service` | `notifications/Service.qml` | +| OSD | `omarchy.osd` | `panel` | `osd/Osd.qml` | +| Polkit agent | `omarchy.polkit` | `service` | `polkit/PolkitAgent.qml` | ## Bar diff --git a/shell/plugins/background/Background.qml b/shell/plugins/background/Background.qml index efef5ec1..d57deded 100644 --- a/shell/plugins/background/Background.qml +++ b/shell/plugins/background/Background.qml @@ -9,10 +9,6 @@ import qs.Commons as NoctaliaCommons Item { id: root - property string omarchyPath: "" - property var shell: null - property var manifest: null - readonly property string home: Quickshell.env("HOME") readonly property string currentBackgroundLink: home + "/.config/omarchy/current/background" diff --git a/shell/plugins/background/manifest.json b/shell/plugins/background/manifest.json index 5ba0c4e5..aa00a22c 100644 --- a/shell/plugins/background/manifest.json +++ b/shell/plugins/background/manifest.json @@ -5,7 +5,10 @@ "version": "1.0.0", "author": "Omarchy", "description": "Desktop background renderer with click handling and transitions", - "kinds": ["service"], - "activation": "startup", - "entryPoints": { "service": "Background.qml" } + "kinds": [ + "service" + ], + "entryPoints": { + "service": "Background.qml" + } } diff --git a/shell/plugins/bar/Bar.qml b/shell/plugins/bar/Bar.qml index 7e0c0e51..4a19c136 100644 --- a/shell/plugins/bar/Bar.qml +++ b/shell/plugins/bar/Bar.qml @@ -222,6 +222,14 @@ Item { return index === -1 ? [] : entries.slice(index + 1) } + function canonicalWidgetId(name) { + switch (String(name)) { + case "idle": return "idleInhibitor" + case "weatherFlyout": return "weather" + default: return String(name) + } + } + function builtinModuleComponent(name) { switch (String(name)) { case "omarchy": return omarchyModuleComponent @@ -459,18 +467,6 @@ Item { return ids } - function activeTrayItemCount() { - var count = 0 - var values = SystemTray.items.values - - for (var i = 0; i < values.length; i++) { - if (values[i].status !== Status.Passive) - count++ - } - - return count - } - function trayIconSource(icon) { var value = String(icon || "") var marker = "?path=" @@ -939,7 +935,8 @@ Item { readonly property var registryComponent: { var w = root.barWidgetRegistry.widgets if (customType || builtinComponent) return null - return w[moduleName] ? w[moduleName].component : null + var registryName = root.canonicalWidgetId(moduleName) + return w[registryName] ? w[registryName].component : null } readonly property bool qmlCustom: customType === "qml" readonly property bool commandCustom: customType === "command" diff --git a/shell/plugins/bar/README.md b/shell/plugins/bar/README.md index 0e480304..0d6c048f 100644 --- a/shell/plugins/bar/README.md +++ b/shell/plugins/bar/README.md @@ -5,10 +5,9 @@ shipped as a first-party plugin of [`omarchy-shell`](../../README.md), the long-running shell host. The bar is mounted at startup and lives inside the shell for its whole session. -- `manifest.json` declares the plugin (`id: omarchy.bar`, `kind: bar`, `activation: persistent`) and points at `Bar.qml` as the entry point. +- `manifest.json` declares the plugin (`id: omarchy.bar`, `kind: bar`) and points at `Bar.qml` as the entry point. - `Bar.qml` is Omarchy-owned bar engine code, loaded by the omarchy-shell host. Users should not edit it directly. - `widgets/` holds first-party widgets — modular, interactive components shipped with Omarchy. -- `common/` holds shared QML helpers (buttons, sliders, popup cards). - The bar receives its config from the host shell as a `barConfig` property; the host loads it from `~/.config/omarchy/shell.json` (or `shell-defaults.json` when the user has no file). - `omarchy-style-bar-position` updates only the user shell.json file. diff --git a/shell/plugins/bar/manifest.json b/shell/plugins/bar/manifest.json index 1ce3b34e..d929c0a1 100644 --- a/shell/plugins/bar/manifest.json +++ b/shell/plugins/bar/manifest.json @@ -5,7 +5,10 @@ "version": "1.0.0", "author": "Omarchy", "description": "Status bar with widgets", - "kinds": ["bar"], - "activation": "persistent", - "entryPoints": { "bar": "Bar.qml" } + "kinds": [ + "bar" + ], + "entryPoints": { + "bar": "Bar.qml" + } } diff --git a/shell/plugins/bar/widgets/monitorPanel.qml b/shell/plugins/bar/widgets/monitorPanel.qml index 06d1d6a8..c551be23 100644 --- a/shell/plugins/bar/widgets/monitorPanel.qml +++ b/shell/plugins/bar/widgets/monitorPanel.qml @@ -123,7 +123,7 @@ Item { var d = displays[selectedIndex] if (d) toggleDisplay(d.name, d.enabled) } - // brightness: no semantic activation; the slider value is the action. + // brightness: no separate action; the slider value is the action. } function clampCursor() { @@ -222,18 +222,6 @@ Item { brightnessDebounce.restart() } - function toggleMirror() { - if (!internalMonitor || !externalMonitor) return - actionProc.command = ["bash", "-lc", "if hyprctl monitors -j | jq -e --arg i '" + internalMonitor + "' --arg e '" + externalMonitor + "' '.[] | select(.name == $i and .mirrorOf == $e)' >/dev/null; then hyprctl keyword monitor '" + internalMonitor + ",preferred,auto,auto'; else hyprctl keyword monitor '" + internalMonitor + ",preferred,auto,auto,mirror," + externalMonitor + "'; fi"] - if (!actionProc.running) actionProc.running = true - } - - function toggleInternal() { - if (!internalMonitor || !externalMonitor) return - actionProc.command = ["bash", "-lc", "if hyprctl monitors -j | jq -e --arg i '" + internalMonitor + "' '.[] | select(.name == $i)' >/dev/null; then hyprctl keyword monitor '" + internalMonitor + ",disable'; else hyprctl keyword monitor '" + internalMonitor + ",preferred,auto,auto'; fi"] - if (!actionProc.running) actionProc.running = true - } - function normalizeScale(scale) { var n = parseFloat(String(scale || "")) if (!isFinite(n)) return "" diff --git a/shell/plugins/bar/widgets/networkPanel.qml b/shell/plugins/bar/widgets/networkPanel.qml index aba4b357..7f771f65 100644 --- a/shell/plugins/bar/widgets/networkPanel.qml +++ b/shell/plugins/bar/widgets/networkPanel.qml @@ -196,16 +196,6 @@ iwctl known-networks list 2>/dev/null \\ Quickshell.execDetached(["bash", "-lc", "printf %s " + root.bar.shellQuote(value) + " | wl-copy"]) } - function networkTooltip() { - if (kind === "wifi") { - var f = parseFloat(frequency) - var ftext = f > 0 ? " (" + (f / 1000).toFixed(1) + " GHz)" : "" - return (label || "Wi-Fi") + ftext - } - if (kind === "ethernet") return "Connected" - return "Disconnected" - } - function networkCommand() { return [ "device=$(ip route get 1.1.1.1 2>/dev/null | awk '{ for (i = 1; i <= NF; i++) if ($i == \"dev\") { print $(i + 1); exit } }')", diff --git a/shell/plugins/bar/widgets/weather.qml b/shell/plugins/bar/widgets/weather.qml index 7f35f5fd..a475c4ad 100644 --- a/shell/plugins/bar/widgets/weather.qml +++ b/shell/plugins/bar/widgets/weather.qml @@ -14,16 +14,21 @@ Item { property bool popupOpen: false function closePopout() { popupOpen = false } + function showPopup() { + root.popupOpen = !root.popupOpen + if (root.popupOpen) root.refresh() + } + IpcHandler { target: "weather" - function show(): void { - root.popupOpen = !root.popupOpen - if (root.popupOpen) root.refresh() - } + function show(): void { root.showPopup() } + function toggle(): void { root.showPopup() } + } - function toggle(): void { - show() - } + IpcHandler { + target: "weatherFlyout" + function show(): void { root.showPopup() } + function toggle(): void { root.showPopup() } } // Parsed wttr.in j1 response. Kept on failure so stale data stays visible. @@ -58,8 +63,6 @@ Item { readonly property int refreshMinutes: Math.max(1, parseInt(setting("refreshMinutes", 15), 10) || 15) readonly property string reportLocation: wttrLocation || (areaInfo && areaInfo.areaName && areaInfo.areaName[0] ? areaInfo.areaName[0].value : "") - readonly property string reportCondition: current && current.weatherDesc && current.weatherDesc[0] ? current.weatherDesc[0].value : "" - readonly property string reportTemp: current ? formatTemp(useImperial ? current.temp_F : current.temp_C) : "" readonly property string reportTempNum: current ? String(useImperial ? current.temp_F : current.temp_C) : "" readonly property string tempUnit: "°" + (useImperial ? "F" : "C") readonly property string reportFeels: current ? formatTemp(useImperial ? current.FeelsLikeF : current.FeelsLikeC) : "" @@ -164,16 +167,6 @@ Item { return Qt.formatDate(d, "dddd") } - function maxTempForDay(day) { - if (!day) return "" - return formatTemp(useImperial ? day.maxtempF : day.maxtempC) - } - - function minTempForDay(day) { - if (!day) return "" - return formatTemp(useImperial ? day.mintempF : day.mintempC) - } - // Bare degree value (no unit letter), used in the forecast row. function bareTempForDay(day, kind) { if (!day) return "" diff --git a/shell/plugins/clipboard-picker/ClipboardPicker.qml b/shell/plugins/clipboard-picker/ClipboardPicker.qml index 346c40e4..36199f1b 100644 --- a/shell/plugins/clipboard-picker/ClipboardPicker.qml +++ b/shell/plugins/clipboard-picker/ClipboardPicker.qml @@ -7,11 +7,6 @@ import qs.Commons Item { id: root - property string omarchyPath: Quickshell.env("OMARCHY_PATH") || (Quickshell.env("HOME") + "/.local/share/omarchy") - property var shell: null - property var manifest: null - property var pluginRegistry: null - property bool opened: false property string filterText: "" property int selectedIndex: 0 @@ -153,14 +148,6 @@ Item { root.rebuildDisplay() } } - - IpcHandler { - target: "clipboard-picker" - function summon(): string { root.open("{}"); return "ok" } - function hide(): string { root.close(); return "ok" } - function toggle(): string { root.toggle(); return "ok" } - function ping(): string { return "ok" } - } PanelWindow { id: panel visible: root.opened diff --git a/shell/plugins/clipboard-picker/manifest.json b/shell/plugins/clipboard-picker/manifest.json index 3fc56c36..0ea048f7 100644 --- a/shell/plugins/clipboard-picker/manifest.json +++ b/shell/plugins/clipboard-picker/manifest.json @@ -5,8 +5,9 @@ "version": "1.0.0", "author": "Omarchy", "description": "A clipboard manager to view and paste history", - "kinds": ["overlay"], - "activation": "on-demand", + "kinds": [ + "overlay" + ], "keepLoaded": true, "entryPoints": { "overlay": "ClipboardPicker.qml" diff --git a/shell/plugins/dev-gallery/GalleryPanel.qml b/shell/plugins/dev-gallery/GalleryPanel.qml index 2305a323..5633c11d 100644 --- a/shell/plugins/dev-gallery/GalleryPanel.qml +++ b/shell/plugins/dev-gallery/GalleryPanel.qml @@ -63,10 +63,7 @@ Item { } // ---- host injections ---------------------------------------------------- - property var barWidgetRegistry: null - property var pluginRegistry: null property var shell: null - property var manifest: null // ---- theme -------------------------------------------------------------- readonly property color foreground: Color.foreground @@ -104,7 +101,7 @@ Item { property string focusSection: "cursor-surface" property int selectedIndex: 0 - // Demo state mutated by activation. + // Demo state mutated by interaction. property string choiceDemoValue: "top" property bool toggleDemoOn: true property bool toggleSquareOn: false diff --git a/shell/plugins/dev-gallery/manifest.json b/shell/plugins/dev-gallery/manifest.json index 4a37137b..5491a9be 100644 --- a/shell/plugins/dev-gallery/manifest.json +++ b/shell/plugins/dev-gallery/manifest.json @@ -5,7 +5,10 @@ "version": "1.0.0", "author": "Omarchy", "description": "Visual reference for omarchy-shell common UI components. Summon with: omarchy-shell shell summon omarchy.dev-gallery '{}' (or run: omarchy dev ui-preview).", - "kinds": ["panel"], - "activation": "on-demand", - "entryPoints": { "panel": "GalleryPanel.qml" } + "kinds": [ + "panel" + ], + "entryPoints": { + "panel": "GalleryPanel.qml" + } } diff --git a/shell/plugins/emoji-picker/EmojiPicker.qml b/shell/plugins/emoji-picker/EmojiPicker.qml index d4297622..005fb8ed 100644 --- a/shell/plugins/emoji-picker/EmojiPicker.qml +++ b/shell/plugins/emoji-picker/EmojiPicker.qml @@ -10,7 +10,6 @@ Item { property string omarchyPath: Quickshell.env("OMARCHY_PATH") || (Quickshell.env("HOME") + "/.local/share/omarchy") property var shell: null property var manifest: null - property var pluginRegistry: null property bool opened: false property string filterText: "" @@ -163,14 +162,6 @@ Item { } ListModel { id: displayModel } - IpcHandler { - target: "emoji-picker" - function summon(): string { root.open("{}"); return "ok" } - function hide(): string { root.close(); return "ok" } - function toggle(): string { root.toggle(); return "ok" } - function ping(): string { return "ok" } - } - FileView { path: root.omarchyPath + "/shell/plugins/emoji-picker/emojis.json" onLoaded: root.loadEmojis(text()) diff --git a/shell/plugins/emoji-picker/manifest.json b/shell/plugins/emoji-picker/manifest.json index 3b85b9a7..fe9ad8be 100644 --- a/shell/plugins/emoji-picker/manifest.json +++ b/shell/plugins/emoji-picker/manifest.json @@ -5,8 +5,9 @@ "version": "1.0.0", "author": "Omarchy", "description": "An emoji picker to copy or type emojis", - "kinds": ["overlay"], - "activation": "on-demand", + "kinds": [ + "overlay" + ], "keepLoaded": true, "entryPoints": { "overlay": "EmojiPicker.qml" diff --git a/shell/plugins/image-picker/ImagePicker.qml b/shell/plugins/image-picker/ImagePicker.qml index 50386423..5754ea4b 100644 --- a/shell/plugins/image-picker/ImagePicker.qml +++ b/shell/plugins/image-picker/ImagePicker.qml @@ -9,16 +9,9 @@ import qs.Commons Item { id: root - // Injected by omarchy-shell. Optional here — the picker doesn't need - // omarchyPath itself, but every plugin gets it so user-installed scripts - // referenced by other plugins can stay path-portable. + // Injected by omarchy-shell so helper scripts resolve without relying on + // OMARCHY_PATH being set in the environment. property string omarchyPath: "" - // Set by omarchy-shell when summoning the overlay; not currently consumed but - // declared so the host's onLoaded injection doesn't trip a missing-property - // warning. - property var shell: null - property var manifest: null - property string imageDirs: Quickshell.env("OMARCHY_IMAGE_SELECTOR_DIRS") || Quickshell.env("OMARCHY_IMAGE_SELECTOR_DIR") || Quickshell.env("OMARCHY_STOCK_BACKGROUNDS_DIR") || (Quickshell.env("HOME") + "/.config/omarchy/current/theme/backgrounds") property string imageRows: "" property string loadedImageRows: "" @@ -120,17 +113,6 @@ Item { return nameForPath(path).toLowerCase().indexOf(needle) !== -1 || labelForPath(path).toLowerCase().indexOf(needle) !== -1 } - function matchingCount() { - if (!filterText) return imageArray.length - - var count = 0 - for (var i = 0; i < imageArray.length; i++) { - if (itemMatches(i)) count++ - } - - return count - } - function firstMatchingIndex() { for (var i = 0; i < imageArray.length; i++) { if (itemMatches(i)) return i diff --git a/shell/plugins/image-picker/manifest.json b/shell/plugins/image-picker/manifest.json index 3c356421..debd1877 100644 --- a/shell/plugins/image-picker/manifest.json +++ b/shell/plugins/image-picker/manifest.json @@ -5,11 +5,11 @@ "version": "1.0.0", "author": "Omarchy", "description": "Image-grid selector overlay used for wallpapers, themes, and any other directory of images", - "kinds": ["overlay"], - "activation": "on-demand", + "kinds": [ + "overlay" + ], "keepLoaded": true, - "entryPoints": { "overlay": "ImagePicker.qml" }, - "ipc": { - "summon": "image-picker" + "entryPoints": { + "overlay": "ImagePicker.qml" } } diff --git a/shell/plugins/menu/Menu.qml b/shell/plugins/menu/Menu.qml index bdf06288..507cac0e 100644 --- a/shell/plugins/menu/Menu.qml +++ b/shell/plugins/menu/Menu.qml @@ -9,9 +9,6 @@ Item { // Injected by omarchy-shell when this plugin is summoned. property string omarchyPath: Quickshell.env("OMARCHY_PATH") || (Quickshell.env("HOME") + "/.local/share/omarchy") - property var shell: null - property var manifest: null - property var pluginRegistry: null // Plugin lifecycle hooks. The host calls open(payloadJson) after // `omarchy-shell shell summon omarchy.menu ...` and close() when hidden. @@ -71,14 +68,6 @@ Item { property int visibleRowsHeight: rowListHeight(layoutSerial, displayModel.count, filterText, searchDivider) property int cardHeight: Math.min(Math.max(Style.space(220), contentMargin * 2 + headerHeight + contentSpacing + visibleRowsHeight), panel.height - Style.gapsOut * 2) - function shellQuote(value) { - return "'" + String(value).replace(/'/g, "'\\''") + "'" - } - - function decodeField(value) { - return String(value || "").replace(/\v/g, "\n").replace(/\f/g, "\t") - } - function withAlpha(color, alpha) { return Qt.rgba(color.r, color.g, color.b, alpha) } diff --git a/shell/plugins/menu/manifest.json b/shell/plugins/menu/manifest.json index 7a0ea37d..2154ba0d 100644 --- a/shell/plugins/menu/manifest.json +++ b/shell/plugins/menu/manifest.json @@ -5,11 +5,11 @@ "version": "1.0.0", "author": "Omarchy", "description": "Quickshell-powered Omarchy command menu", - "kinds": ["menu"], - "activation": "on-demand", + "kinds": [ + "menu" + ], "keepLoaded": true, - "entryPoints": { "menu": "Menu.qml" }, - "ipc": { - "summon": "menu" + "entryPoints": { + "menu": "Menu.qml" } } diff --git a/shell/plugins/notifications/Service.qml b/shell/plugins/notifications/Service.qml index cc2d2baa..3eff0eea 100644 --- a/shell/plugins/notifications/Service.qml +++ b/shell/plugins/notifications/Service.qml @@ -17,9 +17,7 @@ Item { id: service // Injected by omarchy-shell (the first-party service loader). - property string omarchyPath: "" property var shell: null - property var manifest: null readonly property string home: Quickshell.env("HOME") // History + DND live under XDG_STATE_HOME: they're persistent user state diff --git a/shell/plugins/notifications/components/NotificationCard.qml b/shell/plugins/notifications/components/NotificationCard.qml index 381c2c3d..8ece4a0c 100644 --- a/shell/plugins/notifications/components/NotificationCard.qml +++ b/shell/plugins/notifications/components/NotificationCard.qml @@ -34,28 +34,6 @@ Rectangle { signal closeRequested() signal cardClicked() - signal imageClicked() - - // Media mode = the notification carries a real screenshot or screen - // recording preview. Quickshell normalizes file paths from `-i` and the - // `image-path` hint into `image://icon//` (double slash - // marks an absolute filesystem path vs a themed icon name like - // `image://icon/firefox`). - function _imageFilePath(s) { - if (!s) return "" - if (s.indexOf("image://icon//") === 0) return s.substring("image://icon/".length) - if (s.indexOf("file://") === 0) return decodeURIComponent(s.substring(7)) - return "" - } - function _isMediaFile(path) { - if (!path) return false - var lower = path.toLowerCase() - return lower.endsWith(".png") || lower.endsWith(".jpg") || - lower.endsWith(".jpeg") || lower.endsWith(".webp") || - lower.endsWith(".gif") - } - readonly property string mediaImageSource: "" - readonly property bool mediaMode: false // Use only what the notification explicitly carries — no themed-icon // theme-lookup fallback because Quickshell's icon image provider returns // a placeholder for missing names (rather than erroring), which means @@ -64,7 +42,7 @@ Rectangle { // `appIcon` (-i flag) still get one. readonly property string smallIconSource: image.length > 0 ? image : appIcon readonly property bool hasGlyph: glyph.length > 0 - readonly property bool hasSmallIcon: !mediaMode && (smallIconSource.length > 0 || hasGlyph) + readonly property bool hasSmallIcon: smallIconSource.length > 0 || hasGlyph readonly property bool chromiumDerived: { var source = (app + "\n" + appIcon).toLowerCase() return source.indexOf("chrom") >= 0 || source.indexOf("brave") >= 0 || @@ -75,7 +53,6 @@ Rectangle { readonly property color dimColor: Qt.darker(Color.notifications.text, 1.4) readonly property color bodyColor: Qt.darker(Color.notifications.text, 1.15) - readonly property color hoverColor: Qt.rgba(Color.notifications.text.r, Color.notifications.text.g, Color.notifications.text.b, 0.14) readonly property color accentColor: urgency === 2 ? Color.urgent : (urgency === 0 ? dimColor : Color.notifications.countdown) function sanitizeBody(s) { @@ -111,9 +88,8 @@ Rectangle { ColumnLayout { id: mainColumn - // Inset by the card border so the hero image (and the text row) don't - // paint over the card's outer border. Without this the left/right/top - // border is invisible under the image. + // Inset by the card border so the content doesn't paint over the card's + // outer border. anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right @@ -122,46 +98,7 @@ Rectangle { anchors.rightMargin: root.border.width spacing: 0 - // Hero image strip (media notifications only). PreserveAspectCrop so - // the preview looks like a clean banner without dark letterboxing. - Item { - Layout.fillWidth: true - Layout.preferredHeight: Style.space(140) - visible: root.mediaMode - clip: true - - Image { - anchors.fill: parent - source: root.mediaImageSource - fillMode: Image.PreserveAspectCrop - sourceSize.width: width > 0 ? width * Screen.devicePixelRatio : 0 - sourceSize.height: height > 0 ? height * Screen.devicePixelRatio : 0 - asynchronous: true - smooth: true - cache: false - } - - // Bottom divider matching the card border so the screenshot is - // visually framed on every side (card border wraps top/left/right; - // this line completes the bottom). - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: root.border.width - color: root.urgency === 2 ? Color.urgent : Color.notifications.border - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: root.imageClicked() - } - - } - - // Text content. Always rendered — for media notifications this carries - // the summary/body ("Screenshot saved" etc) under the hero image. + // Text content. RowLayout { Layout.fillWidth: true Layout.leftMargin: Style.space(12) diff --git a/shell/plugins/notifications/manifest.json b/shell/plugins/notifications/manifest.json index 9badbb7c..61cdb188 100644 --- a/shell/plugins/notifications/manifest.json +++ b/shell/plugins/notifications/manifest.json @@ -5,8 +5,9 @@ "version": "1.0.0", "author": "Omarchy", "description": "Notification daemon, popups, and history", - "kinds": ["service"], - "activation": "persistent", + "kinds": [ + "service" + ], "keepLoaded": true, "entryPoints": { "service": "Service.qml" diff --git a/shell/plugins/osd/Osd.qml b/shell/plugins/osd/Osd.qml index f6ab65ff..40c38453 100644 --- a/shell/plugins/osd/Osd.qml +++ b/shell/plugins/osd/Osd.qml @@ -7,10 +7,6 @@ import qs.Commons Item { id: root - property string omarchyPath: "" - property var shell: null - property var manifest: null - property bool opened: false property string icon: "" property string message: "" diff --git a/shell/plugins/osd/manifest.json b/shell/plugins/osd/manifest.json index 83bf5c67..b2026048 100644 --- a/shell/plugins/osd/manifest.json +++ b/shell/plugins/osd/manifest.json @@ -4,8 +4,11 @@ "name": "On-screen display", "version": "1.0.0", "description": "Quickshell volume, brightness, and status overlays.", - "kinds": ["panel"], - "activation": "persistent", + "kinds": [ + "panel" + ], "keepLoaded": true, - "entryPoints": { "panel": "Osd.qml" } + "entryPoints": { + "panel": "Osd.qml" + } } diff --git a/shell/plugins/polkit/PolkitAgent.qml b/shell/plugins/polkit/PolkitAgent.qml index e6b3b916..342a0aad 100644 --- a/shell/plugins/polkit/PolkitAgent.qml +++ b/shell/plugins/polkit/PolkitAgent.qml @@ -8,10 +8,6 @@ import qs.Commons Item { id: root - property string omarchyPath: "" - property var shell: null - property var manifest: null - property string fontFamily: Quickshell.env("OMARCHY_MENU_FONT") || "monospace" property color accent: Color.accent property color background: Color.menu.background @@ -19,7 +15,6 @@ Item { property color border: foreground readonly property int cornerRadius: Style.cornerRadius property int contentMargin: Style.spacing.panelPadding - property int contentSpacing: Style.spacing.rowPaddingX property int fieldHeight: Math.max(Style.space(42), Style.spacing.controlHeight) property bool closing: false @@ -42,10 +37,6 @@ Item { function withAlpha(color, alpha) { return Qt.rgba(color.r, color.g, color.b, alpha) } - function messageText() { - return "Authentication is needed..." - } - function promptLooksFingerprint(text) { var s = String(text || "").toLowerCase() return s.indexOf("finger") !== -1 || s.indexOf("fprint") !== -1 || s.indexOf("swipe") !== -1 diff --git a/shell/plugins/polkit/manifest.json b/shell/plugins/polkit/manifest.json index fc690431..1e80b655 100644 --- a/shell/plugins/polkit/manifest.json +++ b/shell/plugins/polkit/manifest.json @@ -5,8 +5,9 @@ "version": "1.0.0", "author": "Omarchy", "description": "Theme-aware authentication dialog for privileged actions.", - "kinds": ["service"], - "activation": "persistent", + "kinds": [ + "service" + ], "keepLoaded": true, "entryPoints": { "service": "PolkitAgent.qml" diff --git a/shell/plugins/settings/SettingsPanel.qml b/shell/plugins/settings/SettingsPanel.qml index 3d32ec31..d137679f 100644 --- a/shell/plugins/settings/SettingsPanel.qml +++ b/shell/plugins/settings/SettingsPanel.qml @@ -153,7 +153,7 @@ Item { ] } }, - plugins: [{ id: "omarchy.osd" }] + plugins: [] }) property var defaultConfig: builtinShellConfig @@ -355,11 +355,20 @@ Item { function onChanged() { root.catalogRevision++ } } + function canonicalWidgetId(id) { + switch (String(id || "")) { + case "idle": return "idleInhibitor" + case "weatherFlyout": return "weather" + default: return String(id || "") + } + } + function widgetMetadata(id) { var key = String(id || "") - if (root.barWidgetRegistry && root.barWidgetRegistry.has(key)) - return root.barWidgetRegistry.metadataFor(key) || {} - if (builtinWidgetMeta[key]) return builtinWidgetMeta[key] + var canonicalKey = canonicalWidgetId(key) + if (root.barWidgetRegistry && root.barWidgetRegistry.has(canonicalKey)) + return root.barWidgetRegistry.metadataFor(canonicalKey) || {} + if (builtinWidgetMeta[canonicalKey]) return builtinWidgetMeta[canonicalKey] var manifest = root.pluginRegistry ? root.pluginRegistry.installedPlugins[key] : null if (manifest) { diff --git a/shell/plugins/settings/manifest.json b/shell/plugins/settings/manifest.json index 8c9a9ffa..0f27fdc9 100644 --- a/shell/plugins/settings/manifest.json +++ b/shell/plugins/settings/manifest.json @@ -5,7 +5,10 @@ "version": "1.0.0", "author": "Omarchy", "description": "Customize the Omarchy bar position and widgets", - "kinds": ["panel"], - "activation": "on-demand", - "entryPoints": { "panel": "SettingsPanel.qml" } + "kinds": [ + "panel" + ], + "entryPoints": { + "panel": "SettingsPanel.qml" + } } diff --git a/shell/scripts/indicators/idle.sh b/shell/scripts/indicators/idle.sh deleted file mode 100755 index ebb5f4f5..00000000 --- a/shell/scripts/indicators/idle.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -if pgrep -x hypridle >/dev/null; then - echo '{"text": ""}' -else - echo '{"text": "󱫖", "tooltip": "Idle lock disabled", "class": "active"}' -fi diff --git a/shell/services/BarWidgetRegistry.qml b/shell/services/BarWidgetRegistry.qml index 049a379f..6639d298 100644 --- a/shell/services/BarWidgetRegistry.qml +++ b/shell/services/BarWidgetRegistry.qml @@ -34,11 +34,6 @@ QtObject { changed() } - function componentFor(id) { - var entry = widgets[String(id)] - return entry ? entry.component : null - } - function metadataFor(id) { var entry = widgets[String(id)] return entry ? entry.metadata : null diff --git a/shell/services/PluginRegistry.qml b/shell/services/PluginRegistry.qml index 259baa95..327d1d50 100644 --- a/shell/services/PluginRegistry.qml +++ b/shell/services/PluginRegistry.qml @@ -181,15 +181,6 @@ QtObject { pluginsChanged() } - function manifestsOfKind(kind) { - var result = [] - for (var id in installedPlugins) { - var m = installedPlugins[id] - if (m && Array.isArray(m.kinds) && m.kinds.indexOf(kind) !== -1) result.push(m) - } - return result - } - // ---------------------------------------------------------------- scanning // Output format produced by the rescan script: diff --git a/shell/shell-defaults.json b/shell/shell-defaults.json index a8fc6c2b..f6994ff7 100644 --- a/shell/shell-defaults.json +++ b/shell/shell-defaults.json @@ -61,9 +61,5 @@ ] } }, - "plugins": [ - { - "id": "omarchy.osd" - } - ] + "plugins": [] } diff --git a/shell/shell.qml b/shell/shell.qml index 5afe1aa6..c2c7e4ea 100644 --- a/shell/shell.qml +++ b/shell/shell.qml @@ -57,11 +57,7 @@ ShellRoot { right: [{ id: "audioPanel" }] } }, - plugins: [ - { id: "omarchy.settings" }, - { id: "omarchy.image-picker" }, - { id: "omarchy.osd" } - ] + plugins: [] }) property var defaultsConfig: builtinShellConfig @@ -117,8 +113,6 @@ ShellRoot { } readonly property var barConfig: shellConfig && isPlainObject(shellConfig.bar) ? shellConfig.bar : builtinShellConfig.bar - readonly property var pluginsConfig: shellConfig && Array.isArray(shellConfig.plugins) ? shellConfig.plugins : [] - FileView { id: defaultsFile path: shell.defaultsPath @@ -217,15 +211,14 @@ ShellRoot { console.warn("first-party service load failed for " + key + ": " + comp.errorString()) return } - var inst = comp.createObject(firstPartyServiceHost, { - omarchyPath: shell.omarchyPath, - shell: shell, - manifest: manifest - }) + var inst = comp.createObject(firstPartyServiceHost) if (!inst) { console.warn("first-party service createObject returned null for", key) return } + if ("omarchyPath" in inst) inst.omarchyPath = shell.omarchyPath + if ("shell" in inst) inst.shell = shell + if ("manifest" in inst) inst.manifest = manifest var snext = ({}) for (var sk in _firstPartyServices) snext[sk] = _firstPartyServices[sk] snext[key] = inst @@ -323,8 +316,6 @@ ShellRoot { // QML to notice the change. property var openPanelIds: ({}) - function isPanelOpen(id) { return openPanelIds[id] === true } - // Pending payloads to deliver to a plugin's open() once its loader resolves. // Keyed by plugin id; the value is an array so two summon() calls before // the Loader resolves both reach the plugin in arrival order rather than