Build only the module list the bar is showing

The center section declares both an anchored and an unanchored
arrangement and shows whichever fits, but a hidden ModuleList is still a
loaded Loader. With a center anchor set — the default — every center
module was therefore mounted twice for the life of the session: two IPC
handlers registered for the same target, two clocks ticking, two of every
timer and network fetch behind them, one set of which nothing could
reach.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-26 20:30:52 -07:00
co-authored by Claude Opus 5
parent 9e3da4e27f
commit 8728791c93
2 changed files with 14 additions and 0 deletions
+6
View File
@@ -1321,6 +1321,12 @@ Item {
property string region: ""
visible: entries.length > 0
// A hidden list must not build its modules. The center section declares
// both an anchored and an unanchored arrangement and shows whichever
// fits, so leaving the other one loaded mounts every center module
// twice — two IPC handlers registered for the same target, two clocks
// ticking, two of every timer and fetch behind them.
active: visible && entries.length > 0
sourceComponent: root.vertical ? verticalModuleList : horizontalModuleList
width: item ? item.implicitWidth : 0
height: item ? item.implicitHeight : 0
+8
View File
@@ -19,6 +19,14 @@ const fs = require('fs')
const bar = requireFromRoot('shell/plugins/bar/BarModel.js')
const barSource = fs.readFileSync(root + '/shell/plugins/bar/Bar.qml', 'utf8')
// The center section declares two arrangements and shows one; the hidden one
// must not build its modules or every center widget exists twice.
const moduleList = barSource.slice(barSource.indexOf('component ModuleList'), barSource.indexOf('component ModuleSlot'))
assert(
/active: visible && entries\.length > 0/.test(moduleList),
'bar builds only the module list it is showing'
)
// A center module is mounted twice — drawn copy plus zero-size placeholder —
// and the order they register in is not stable across a live reconfiguration,
// so panel routing has to pick the one that is actually on screen.