Merge pull request #6391 from basecamp/bar-startup-churn
Load each bar widget's component once
This commit is contained in:
+22
-4
@@ -700,6 +700,12 @@ ShellRoot {
|
||||
source: "plugin"
|
||||
}
|
||||
|
||||
// A load already in flight for this URL registers itself when it
|
||||
// finishes. Starting a second one produces a second Component for the
|
||||
// same widget, and swapping a slot's component rebuilds its item —
|
||||
// briefly running two of the widget, each registering its IPC handler.
|
||||
if (existing && existing.url === url && !existing.component) continue
|
||||
|
||||
// If the component URL is unchanged, just refresh the metadata in
|
||||
// place. We can't skip this even when the URL matches: manifests can
|
||||
// change schema, defaults, or sourceDir between rescans, and the
|
||||
@@ -769,17 +775,29 @@ ShellRoot {
|
||||
}
|
||||
}
|
||||
|
||||
function setPluginWidgetComponent(registryKey, entry) {
|
||||
var next = ({})
|
||||
for (var k in pluginWidgetComponents) if (k !== registryKey) next[k] = pluginWidgetComponents[k]
|
||||
if (entry) next[registryKey] = entry
|
||||
pluginWidgetComponents = next
|
||||
}
|
||||
|
||||
function loadPluginWidget(registryKey, url, meta) {
|
||||
// Claim the key before the component exists. Qt.createComponent is
|
||||
// asynchronous and syncPluginWidgets runs several times while the shell
|
||||
// starts, so without a marker the later passes cannot tell a load in
|
||||
// flight from one that never happened.
|
||||
setPluginWidgetComponent(registryKey, { url: url, component: null })
|
||||
|
||||
var comp = Qt.createComponent(url, Component.Asynchronous)
|
||||
function finalize() {
|
||||
if (comp.status === Component.Ready) {
|
||||
shell.barWidgetRegistry.register(registryKey, comp, meta)
|
||||
var next = ({})
|
||||
for (var k in pluginWidgetComponents) next[k] = pluginWidgetComponents[k]
|
||||
next[registryKey] = { url: url, component: comp }
|
||||
pluginWidgetComponents = next
|
||||
shell.setPluginWidgetComponent(registryKey, { url: url, component: comp })
|
||||
} else if (comp.status === Component.Error) {
|
||||
console.warn("Plugin widget " + registryKey + " failed: " + comp.errorString())
|
||||
// Drop the claim so a later rescan can retry.
|
||||
shell.setPluginWidgetComponent(registryKey, null)
|
||||
shell.pluginRegistry.pluginLoadFailed(registryKey, comp.errorString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +230,24 @@ for panel_id in omarchy.audio omarchy.bluetooth omarchy.monitor omarchy.network
|
||||
done
|
||||
pass "direct panel IPC opens and closes default panels"
|
||||
|
||||
# Each widget registers its IPC handler once per bar, and the bar is
|
||||
# instantiated once per screen, so Quickshell reports one collision per screen
|
||||
# past the first. Anything beyond that is two instances on the same screen —
|
||||
# the shape duplicate component loads produced, where a sync pass that ran
|
||||
# while a widget's asynchronous load was still in flight started a second one.
|
||||
# Checked before the reload below, which rebuilds widgets by design.
|
||||
screens=$(hyprctl -j monitors 2>/dev/null | jq 'length' 2>/dev/null || true)
|
||||
[[ $screens =~ ^[0-9]+$ ]] && (( screens > 0 )) || screens=1
|
||||
# No matches is the good case, and pipefail would otherwise abort the run.
|
||||
worst=$(grep -oE "another handler is registered for target [a-z.-]+" "$log" |
|
||||
sort | uniq -c | sort -rn | head -1 | awk '{print $1}' || true)
|
||||
worst=${worst:-0}
|
||||
if (( worst > screens - 1 )); then
|
||||
grep "another handler is registered for target" "$log" | sed 's/^/ /' | head -20 >&2
|
||||
fail_with_log "each widget registers its IPC handler once per screen (saw $worst for $screens screen(s))"
|
||||
fi
|
||||
pass "each widget registers its IPC handler once per screen"
|
||||
|
||||
HOME="$test_home" OMARCHY_PATH="$test_root" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-bar-plugin" remove omarchy.audio
|
||||
|
||||
for _ in {1..80}; do
|
||||
@@ -257,3 +275,4 @@ jq -e 'all(.[]; .id != "omarchy.audio")' <<<"$geometry" >/dev/null || {
|
||||
}
|
||||
|
||||
pass "bar remove reloads shell config and updates bar layout"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user