diff --git a/default/hypr/bindings/utilities.lua b/default/hypr/bindings/utilities.lua index 4f83752b..0d73b0bb 100644 --- a/default/hypr/bindings/utilities.lua +++ b/default/hypr/bindings/utilities.lua @@ -76,11 +76,11 @@ o.bind("SUPER + CTRL + ALT + T", "Show time", "omarchy-notification-time") o.bind("SUPER + CTRL + ALT + B", "Show battery remaining", "omarchy-notification-battery") o.bind("SUPER + CTRL + ALT + W", "Toggle weather", "omarchy-notification-weather") -o.bind("SUPER + CTRL + A", "Audio", "omarchy-shell omarchy.audio toggle") -o.bind("SUPER + CTRL + B", "Bluetooth", "omarchy-shell omarchy.bluetooth toggle") -o.bind("SUPER + CTRL + D", "Display", "omarchy-shell omarchy.monitor toggle") -o.bind("SUPER + CTRL + W", "Network", "omarchy-shell omarchy.network toggle") -o.bind("SUPER + CTRL + P", "Power", "omarchy-shell omarchy.power toggle") +o.bind("SUPER + CTRL + A", "Audio", "omarchy-shell shell toggle omarchy.audio") +o.bind("SUPER + CTRL + B", "Bluetooth", "omarchy-shell shell toggle omarchy.bluetooth") +o.bind("SUPER + CTRL + D", "Display", "omarchy-shell shell toggle omarchy.monitor") +o.bind("SUPER + CTRL + W", "Network", "omarchy-shell shell toggle omarchy.network") +o.bind("SUPER + CTRL + P", "Power", "omarchy-shell shell toggle omarchy.power") o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" }) o.bind("SUPER + CTRL + Z", "Zoom in", function() diff --git a/install/user/first-run/wifi.sh b/install/user/first-run/wifi.sh index 5bd42b37..87126bad 100644 --- a/install/user/first-run/wifi.sh +++ b/install/user/first-run/wifi.sh @@ -19,7 +19,7 @@ notify_update() { notify_wifi() { ( if [[ -n $(omarchy-notification-send -u critical -g 󰖩 "Click to Setup Wi-Fi" -a) ]]; then - omarchy-shell omarchy.network toggle + omarchy-shell shell toggle omarchy.network fi ) >/dev/null 2>&1 & } diff --git a/shell/plugins/bar/Bar.qml b/shell/plugins/bar/Bar.qml index bbbfb6d7..f63d96db 100644 --- a/shell/plugins/bar/Bar.qml +++ b/shell/plugins/bar/Bar.qml @@ -333,6 +333,44 @@ Item { return true } + // Resolve the live bar-widget instance for a plugin id (e.g. "omarchy.bluetooth"). + // Only widgets that expose popup open/close methods count; plain indicators + // (clock, workspaces, tray) return null. Used by shell.summon/toggle so + // panel hotkeys route through the bar instead of a per-target IpcHandler + // that goes stale when the bar reloads its widget instances. + function findPanelWidget(pluginId) { + var id = String(pluginId || "") + if (!id) return null + for (var i = 0; i < moduleSlots.length; i++) { + var slot = moduleSlots[i] + if (!slot || !slot.activeItem) continue + if (slot.moduleName !== id) continue + var item = slot.activeItem + if (typeof item.open !== "function" || typeof item.close !== "function" || item.opened === undefined) continue + return item + } + return null + } + + function summonBarWidget(pluginId) { + var item = findPanelWidget(pluginId) + if (!item || typeof item.open !== "function") return false + item.open() + return true + } + + function hideBarWidget(pluginId) { + var item = findPanelWidget(pluginId) + if (!item || typeof item.close !== "function") return false + item.close() + return true + } + + function isBarWidgetOpen(pluginId) { + var item = findPanelWidget(pluginId) + return !!item && item.opened === true + } + function entrySettings(entry) { return BarModel.entrySettings(entry) } diff --git a/shell/plugins/bar/widgets/Microphone.qml b/shell/plugins/bar/widgets/Microphone.qml index e8052964..200eae97 100644 --- a/shell/plugins/bar/widgets/Microphone.qml +++ b/shell/plugins/bar/widgets/Microphone.qml @@ -42,7 +42,7 @@ BarWidget { active: root.inUse tooltipText: root.muted ? "Microphone muted" : (root.inUse ? "Microphone in use" : "Microphone live") onPressed: function(b) { - if (b === Qt.MiddleButton) root.bar.run("omarchy-shell omarchy.audio toggle") + if (b === Qt.MiddleButton) root.bar.run("omarchy-shell shell toggle omarchy.audio") else root.toggleMute() } onWheelMoved: function(delta) { diff --git a/shell/shell.qml b/shell/shell.qml index d7098b9c..96778ec6 100644 --- a/shell/shell.qml +++ b/shell/shell.qml @@ -419,6 +419,26 @@ ShellRoot { // the second clobbering the first. property var pendingPayloads: ({}) + // Bar-widget panels (audio, bluetooth, network, power, monitor, etc.) + // are mounted inside the bar, not via the panel loader below. Route + // summon/hide/toggle to the live bar instance so panel hotkeys survive + // plugin/bar reloads: the bar re-creates the widget, while a fixed + // IpcHandler target would go stale ("first handler wins" leaves a + // destroyed instance's handler active and the new one rejected). + function isBarWidgetPanelPlugin(pluginId) { + var plugins = shell.pluginRegistry.installedPlugins + var m = plugins[String(pluginId || "")] + if (!m || !Array.isArray(m.kinds)) return false + if (m.kinds.indexOf("bar-widget") === -1) return false + // Plugins that are also panel/overlay/menu kinds are owned by the + // panel loader (e.g. omarchy.menu); let that path handle them. + var loaderKinds = ["panel", "overlay", "menu"] + for (var i = 0; i < loaderKinds.length; i++) { + if (m.kinds.indexOf(loaderKinds[i]) !== -1) return false + } + return true + } + function summon(pluginId, payloadJson) { var id = String(pluginId || "") if (!id) return false @@ -434,6 +454,13 @@ ShellRoot { console.warn("summon: plugin not enabled, not summoning:", id) return false } + // Bar widgets take no payload; payloadJson is dropped on this path. + if (shell.isBarWidgetPanelPlugin(id)) { + var summoned = shell.bar && typeof shell.bar.summonBarWidget === "function" + && shell.bar.summonBarWidget(id) + if (!summoned) console.warn("summon: no live bar widget for:", id) + return summoned === true + } var next = ({}) for (var k in openPanelIds) next[k] = openPanelIds[k] next[id] = true @@ -455,6 +482,12 @@ ShellRoot { function hide(pluginId) { var id = String(pluginId || "") if (!id) return false + if (shell.isBarWidgetPanelPlugin(id)) { + var hidden = shell.bar && typeof shell.bar.hideBarWidget === "function" + && shell.bar.hideBarWidget(id) + if (!hidden) console.warn("hide: no live bar widget for:", id) + return hidden === true + } invokeIfLoaded(id, "close", null) if (!openPanelIds[id]) return true var next = ({}) @@ -465,6 +498,11 @@ ShellRoot { function isPluginOpen(pluginId) { var id = String(pluginId || "") + if (shell.isBarWidgetPanelPlugin(id)) { + return shell.bar && typeof shell.bar.isBarWidgetOpen === "function" + ? shell.bar.isBarWidgetOpen(id) + : false + } var loader = panelLoaders[id] if (loader && loader.item && loader.item.opened !== undefined) return loader.item.opened === true