Route panel hotkeys through the shell IPC target so they survive reloads
Bar-widget panels (audio, bluetooth, network, power, monitor) used to be toggled via their own per-plugin IpcHandler targets. Quickshell resolves duplicate targets first-handler-wins, so after a plugin or bar reload the stale handler of the destroyed widget instance kept claiming the target and the hotkeys went dead. The shell root's IpcHandler lives outside the reload cycle, so summon, hide, and toggle now go through `omarchy-shell shell toggle <plugin>` and the shell routes to the live widget instance via the bar's slot registry. Panel plugins that are also panel/overlay/menu kinds keep using the panel loader path. Failures to find a live widget are logged so a widget missing from the bar layout stays diagnosable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6bb3cb666b
commit
e1cdc9005e
@@ -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 + B", "Show battery remaining", "omarchy-notification-battery")
|
||||||
o.bind("SUPER + CTRL + ALT + W", "Toggle weather", "omarchy-notification-weather")
|
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 + A", "Audio", "omarchy-shell shell toggle omarchy.audio")
|
||||||
o.bind("SUPER + CTRL + B", "Bluetooth", "omarchy-shell omarchy.bluetooth toggle")
|
o.bind("SUPER + CTRL + B", "Bluetooth", "omarchy-shell shell toggle omarchy.bluetooth")
|
||||||
o.bind("SUPER + CTRL + D", "Display", "omarchy-shell omarchy.monitor toggle")
|
o.bind("SUPER + CTRL + D", "Display", "omarchy-shell shell toggle omarchy.monitor")
|
||||||
o.bind("SUPER + CTRL + W", "Network", "omarchy-shell omarchy.network toggle")
|
o.bind("SUPER + CTRL + W", "Network", "omarchy-shell shell toggle omarchy.network")
|
||||||
o.bind("SUPER + CTRL + P", "Power", "omarchy-shell omarchy.power toggle")
|
o.bind("SUPER + CTRL + P", "Power", "omarchy-shell shell toggle omarchy.power")
|
||||||
o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" })
|
o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" })
|
||||||
|
|
||||||
o.bind("SUPER + CTRL + Z", "Zoom in", function()
|
o.bind("SUPER + CTRL + Z", "Zoom in", function()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ notify_update() {
|
|||||||
notify_wifi() {
|
notify_wifi() {
|
||||||
(
|
(
|
||||||
if [[ -n $(omarchy-notification-send -u critical -g "Click to Setup Wi-Fi" -a) ]]; then
|
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
|
fi
|
||||||
) >/dev/null 2>&1 &
|
) >/dev/null 2>&1 &
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -333,6 +333,44 @@ Item {
|
|||||||
return true
|
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) {
|
function entrySettings(entry) {
|
||||||
return BarModel.entrySettings(entry)
|
return BarModel.entrySettings(entry)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ BarWidget {
|
|||||||
active: root.inUse
|
active: root.inUse
|
||||||
tooltipText: root.muted ? "Microphone muted" : (root.inUse ? "Microphone in use" : "Microphone live")
|
tooltipText: root.muted ? "Microphone muted" : (root.inUse ? "Microphone in use" : "Microphone live")
|
||||||
onPressed: function(b) {
|
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()
|
else root.toggleMute()
|
||||||
}
|
}
|
||||||
onWheelMoved: function(delta) {
|
onWheelMoved: function(delta) {
|
||||||
|
|||||||
@@ -419,6 +419,26 @@ ShellRoot {
|
|||||||
// the second clobbering the first.
|
// the second clobbering the first.
|
||||||
property var pendingPayloads: ({})
|
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) {
|
function summon(pluginId, payloadJson) {
|
||||||
var id = String(pluginId || "")
|
var id = String(pluginId || "")
|
||||||
if (!id) return false
|
if (!id) return false
|
||||||
@@ -434,6 +454,13 @@ ShellRoot {
|
|||||||
console.warn("summon: plugin not enabled, not summoning:", id)
|
console.warn("summon: plugin not enabled, not summoning:", id)
|
||||||
return false
|
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 = ({})
|
var next = ({})
|
||||||
for (var k in openPanelIds) next[k] = openPanelIds[k]
|
for (var k in openPanelIds) next[k] = openPanelIds[k]
|
||||||
next[id] = true
|
next[id] = true
|
||||||
@@ -455,6 +482,12 @@ ShellRoot {
|
|||||||
function hide(pluginId) {
|
function hide(pluginId) {
|
||||||
var id = String(pluginId || "")
|
var id = String(pluginId || "")
|
||||||
if (!id) return false
|
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)
|
invokeIfLoaded(id, "close", null)
|
||||||
if (!openPanelIds[id]) return true
|
if (!openPanelIds[id]) return true
|
||||||
var next = ({})
|
var next = ({})
|
||||||
@@ -465,6 +498,11 @@ ShellRoot {
|
|||||||
|
|
||||||
function isPluginOpen(pluginId) {
|
function isPluginOpen(pluginId) {
|
||||||
var id = String(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]
|
var loader = panelLoaders[id]
|
||||||
if (loader && loader.item && loader.item.opened !== undefined)
|
if (loader && loader.item && loader.item.opened !== undefined)
|
||||||
return loader.item.opened === true
|
return loader.item.opened === true
|
||||||
|
|||||||
Reference in New Issue
Block a user