fix: redraw canvas and resync slot layouts on bottom-panel toggle#12302
fix: redraw canvas and resync slot layouts on bottom-panel toggle#12302christian-byrne wants to merge 2 commits into
Conversation
Belt-and-braces for the bottom-panel/node-displacement bug. The PrimeVue Splitter changes the canvas container size which triggers the canvas ResizeObserver and the per-node Vue ResizeObservers, but both have failure modes during animated transitions (RAF batching, suspended-tab handling, stale viewport state on the first measurement). Explicitly request a slot layout resync and setDirty(true, true) on the canvas when bottomPanelVisible flips, so links stay aligned with slot connectors regardless of what the RO chain did during the transition. Mirrors the existing linearMode watcher pattern in this file.
Address review: bottomPanelVisible alone misses the focusMode case (splitter hides the panel when focusMode is on, regardless of the store flag). Compose the same condition the splitter uses so toggling focusMode while the panel is open also triggers the redraw/resync.
📝 WalkthroughWalkthroughGraphCanvas.vue now monitors the bottom panel's visibility state and triggers a canvas redraw when visibility changes. The component syncs slot and link layout for all nodes and marks the canvas as dirty to maintain correct alignment after splitter-driven size changes. ChangesBottom Panel Visibility Canvas Synchronization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Suggested labels
Suggested reviewers
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error)
✅ Passed checks (6 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
🎨 Storybook: ✅ Built — View Storybook |
🎭 Playwright: ✅ 1600 passed, 0 failed · 4 flaky📊 Browser Reports
|
📦 Bundle: 5.36 MB gzip 🟢 -169 BDetailsSummary
Category Glance App Entry Points — 26.1 kB (baseline 26.1 kB) • ⚪ 0 BMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 1.24 MB (baseline 1.24 MB) • 🔴 +281 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 82.9 kB (baseline 82.9 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 9 added / 9 removed / 2 unchanged Panels & Settings — 527 kB (baseline 527 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 10 added / 10 removed / 14 unchanged User & Accounts — 17.8 kB (baseline 17.8 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 5 added / 5 removed / 2 unchanged Editors & Dialogs — 112 kB (baseline 112 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 4 added / 4 removed UI Components — 58 kB (baseline 58 kB) • ⚪ 0 BReusable component library chunks
Status: 5 added / 5 removed / 8 unchanged Data & Services — 3.16 MB (baseline 3.16 MB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 13 added / 13 removed / 4 unchanged Utilities & Hooks — 366 kB (baseline 366 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 13 added / 13 removed / 18 unchanged Vendor & Third-Party — 9.94 MB (baseline 9.94 MB) • ⚪ 0 BExternal libraries and shared vendor chunks Status: 16 unchanged Other — 9.16 MB (baseline 9.16 MB) • ⚪ 0 BBundles that do not match a named category
Status: 57 added / 57 removed / 86 unchanged ⚡ Performance Report
All metrics
Historical variance (last 15 runs)
Trend (last 15 commits on main)
Raw data{
"timestamp": "2026-05-15T21:40:11.730Z",
"gitSha": "433f0ea709137b69724921324ed0f4ec7d34512a",
"branch": "glary/redraw-canvas-on-bottom-panel-toggle",
"measurements": [
{
"name": "canvas-idle",
"durationMs": 2155.6360000000154,
"styleRecalcs": 8,
"styleRecalcDurationMs": 7.6209999999999996,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 500.44100000000003,
"heapDeltaBytes": -9649904,
"heapUsedBytes": 58763360,
"domNodes": -265,
"jsHeapTotalBytes": 20144128,
"scriptDurationMs": 22.386,
"eventListeners": -133,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "canvas-idle",
"durationMs": 2038.770999999997,
"styleRecalcs": 11,
"styleRecalcDurationMs": 9.072999999999997,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 465.205,
"heapDeltaBytes": -9739844,
"heapUsedBytes": 58637244,
"domNodes": -257,
"jsHeapTotalBytes": 22503424,
"scriptDurationMs": 21.599,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1789.3960000000106,
"styleRecalcs": 71,
"styleRecalcDurationMs": 33.736000000000004,
"layouts": 12,
"layoutDurationMs": 3.7490000000000006,
"taskDurationMs": 762.107,
"heapDeltaBytes": 4970136,
"heapUsedBytes": 53583948,
"domNodes": -263,
"jsHeapTotalBytes": 16642048,
"scriptDurationMs": 114.81200000000001,
"eventListeners": -133,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "canvas-mouse-sweep",
"durationMs": 1783.4719999999606,
"styleRecalcs": 72,
"styleRecalcDurationMs": 34.692,
"layouts": 12,
"layoutDurationMs": 3.7369999999999997,
"taskDurationMs": 783.747,
"heapDeltaBytes": 13186120,
"heapUsedBytes": 62976208,
"domNodes": -262,
"jsHeapTotalBytes": 20144128,
"scriptDurationMs": 118.43400000000001,
"eventListeners": -131,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1763.8210000000072,
"styleRecalcs": 32,
"styleRecalcDurationMs": 17.352,
"layouts": 6,
"layoutDurationMs": 0.6659999999999999,
"taskDurationMs": 294.273,
"heapDeltaBytes": 852804,
"heapUsedBytes": 48836484,
"domNodes": 80,
"jsHeapTotalBytes": 14680064,
"scriptDurationMs": 25.262999999999998,
"eventListeners": 21,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "canvas-zoom-sweep",
"durationMs": 1719.5639999999912,
"styleRecalcs": 32,
"styleRecalcDurationMs": 15.550999999999998,
"layouts": 6,
"layoutDurationMs": 0.591,
"taskDurationMs": 277.361,
"heapDeltaBytes": 531504,
"heapUsedBytes": 49178772,
"domNodes": 78,
"jsHeapTotalBytes": 14680064,
"scriptDurationMs": 17.343999999999998,
"eventListeners": 21,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "dom-widget-clipping",
"durationMs": 555.137000000002,
"styleRecalcs": 11,
"styleRecalcDurationMs": 7.575,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 324.312,
"heapDeltaBytes": 8818668,
"heapUsedBytes": 57411168,
"domNodes": 18,
"jsHeapTotalBytes": 15728640,
"scriptDurationMs": 53.73700000000001,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "dom-widget-clipping",
"durationMs": 520.5739999999537,
"styleRecalcs": 10,
"styleRecalcDurationMs": 6.230000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 316.57599999999996,
"heapDeltaBytes": 8763140,
"heapUsedBytes": 57430172,
"domNodes": 16,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 51.907,
"eventListeners": 2,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "large-graph-idle",
"durationMs": 2021.5220000000045,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.419000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 601.725,
"heapDeltaBytes": 38811996,
"heapUsedBytes": 97373960,
"domNodes": -261,
"jsHeapTotalBytes": 33058816,
"scriptDurationMs": 83.76700000000001,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.670000000000012,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-idle",
"durationMs": 2019.3399999999997,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.427,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 536.333,
"heapDeltaBytes": 1975696,
"heapUsedBytes": 60470948,
"domNodes": -262,
"jsHeapTotalBytes": 5533696,
"scriptDurationMs": 85.978,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-pan",
"durationMs": 2111.350999999985,
"styleRecalcs": 69,
"styleRecalcDurationMs": 18.012,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1037.7189999999998,
"heapDeltaBytes": -6992992,
"heapUsedBytes": 53046608,
"domNodes": -262,
"jsHeapTotalBytes": 4280320,
"scriptDurationMs": 368.06,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-pan",
"durationMs": 2208.387000000016,
"styleRecalcs": 67,
"styleRecalcDurationMs": 17.372000000000003,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 1143.728,
"heapDeltaBytes": 41808956,
"heapUsedBytes": 103110188,
"domNodes": -265,
"jsHeapTotalBytes": 37748736,
"scriptDurationMs": 375.892,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "large-graph-zoom",
"durationMs": 3200.5249999999987,
"styleRecalcs": 66,
"styleRecalcDurationMs": 19.313,
"layouts": 60,
"layoutDurationMs": 7.93,
"taskDurationMs": 1371.661,
"heapDeltaBytes": 47322612,
"heapUsedBytes": 110110468,
"domNodes": -267,
"jsHeapTotalBytes": 33640448,
"scriptDurationMs": 485.676,
"eventListeners": -127,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333335,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "large-graph-zoom",
"durationMs": 3147.8459999999586,
"styleRecalcs": 66,
"styleRecalcDurationMs": 18.994,
"layouts": 60,
"layoutDurationMs": 7.989,
"taskDurationMs": 1307.6160000000002,
"heapDeltaBytes": 9957328,
"heapUsedBytes": 70805112,
"domNodes": -266,
"jsHeapTotalBytes": 1077248,
"scriptDurationMs": 492.4270000000001,
"eventListeners": -125,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "minimap-idle",
"durationMs": 1996.7009999999732,
"styleRecalcs": 9,
"styleRecalcDurationMs": 6.995000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 524.094,
"heapDeltaBytes": 44883820,
"heapUsedBytes": 113434104,
"domNodes": 18,
"jsHeapTotalBytes": 47591424,
"scriptDurationMs": 75.47300000000001,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "minimap-idle",
"durationMs": 2027.1159999999782,
"styleRecalcs": 7,
"styleRecalcDurationMs": 5.892000000000001,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 507.8710000000001,
"heapDeltaBytes": 2580960,
"heapUsedBytes": 63057892,
"domNodes": -266,
"jsHeapTotalBytes": 5533696,
"scriptDurationMs": 75.67999999999999,
"eventListeners": -129,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 582.285000000013,
"styleRecalcs": 48,
"styleRecalcDurationMs": 12.706999999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 371.64399999999995,
"heapDeltaBytes": 15033196,
"heapUsedBytes": 65050308,
"domNodes": 21,
"jsHeapTotalBytes": 17301504,
"scriptDurationMs": 127.01499999999999,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.669999999999998,
"p95FrameDurationMs": 16.700000000000273
},
{
"name": "subgraph-dom-widget-clipping",
"durationMs": 535.6569999999579,
"styleRecalcs": 47,
"styleRecalcDurationMs": 11.259,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 354.525,
"heapDeltaBytes": 9850164,
"heapUsedBytes": 59327548,
"domNodes": 20,
"jsHeapTotalBytes": 15990784,
"scriptDurationMs": 126.12,
"eventListeners": 8,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999727
},
{
"name": "subgraph-idle",
"durationMs": 1990.2890000000184,
"styleRecalcs": 9,
"styleRecalcDurationMs": 7.106000000000002,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 332.449,
"heapDeltaBytes": 22973440,
"heapUsedBytes": 71652804,
"domNodes": 18,
"jsHeapTotalBytes": 14417920,
"scriptDurationMs": 13.725,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-idle",
"durationMs": 2004.5010000000048,
"styleRecalcs": 10,
"styleRecalcDurationMs": 8.408,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 329.57599999999996,
"heapDeltaBytes": 22981124,
"heapUsedBytes": 71941356,
"domNodes": 20,
"jsHeapTotalBytes": 15466496,
"scriptDurationMs": 12.177000000000007,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.699999999999818
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1705.8570000000088,
"styleRecalcs": 77,
"styleRecalcDurationMs": 39.096,
"layouts": 16,
"layoutDurationMs": 4.890000000000001,
"taskDurationMs": 654.5130000000001,
"heapDeltaBytes": -5101716,
"heapUsedBytes": 63495636,
"domNodes": 64,
"jsHeapTotalBytes": 19398656,
"scriptDurationMs": 91.91000000000003,
"eventListeners": 6,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-mouse-sweep",
"durationMs": 1707.5780000000123,
"styleRecalcs": 76,
"styleRecalcDurationMs": 36.025,
"layouts": 16,
"layoutDurationMs": 4.5760000000000005,
"taskDurationMs": 630.304,
"heapDeltaBytes": 14029700,
"heapUsedBytes": 62660344,
"domNodes": 61,
"jsHeapTotalBytes": 14942208,
"scriptDurationMs": 84.293,
"eventListeners": 4,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "subgraph-transition-enter",
"durationMs": 1050.1769999999624,
"styleRecalcs": 17,
"styleRecalcDurationMs": 26.977999999999994,
"layouts": 5,
"layoutDurationMs": 11.262999999999998,
"taskDurationMs": 822.918,
"heapDeltaBytes": 82027520,
"heapUsedBytes": 222756036,
"domNodes": 13513,
"jsHeapTotalBytes": 80216064,
"scriptDurationMs": 29.57599999999999,
"eventListeners": 2527,
"totalBlockingTimeMs": 139,
"frameDurationMs": 16.66333333333332,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "viewport-pan-sweep",
"durationMs": 8131.006000000014,
"styleRecalcs": 250,
"styleRecalcDurationMs": 56.385,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3427.629,
"heapDeltaBytes": 18167392,
"heapUsedBytes": 81450660,
"domNodes": -257,
"jsHeapTotalBytes": 6115328,
"scriptDurationMs": 1134.822,
"eventListeners": -115,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "viewport-pan-sweep",
"durationMs": 8147.756999999956,
"styleRecalcs": 249,
"styleRecalcDurationMs": 54.769,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 3424.3629999999994,
"heapDeltaBytes": 15413984,
"heapUsedBytes": 74054908,
"domNodes": -264,
"jsHeapTotalBytes": 2854912,
"scriptDurationMs": 1146.911,
"eventListeners": -113,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 12575.32500000002,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 12530.067,
"heapDeltaBytes": -31161488,
"heapUsedBytes": 172611684,
"domNodes": -8331,
"jsHeapTotalBytes": 25489408,
"scriptDurationMs": 565.685,
"eventListeners": -16462,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.223333333333358,
"p95FrameDurationMs": 16.700000000000728
},
{
"name": "vue-large-graph-idle",
"durationMs": 15583.353000000045,
"styleRecalcs": 0,
"styleRecalcDurationMs": 0,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 15557.669999999998,
"heapDeltaBytes": 20115820,
"heapUsedBytes": 273690440,
"domNodes": -8331,
"jsHeapTotalBytes": 41218048,
"scriptDurationMs": 703.074,
"eventListeners": -16490,
"totalBlockingTimeMs": 0,
"frameDurationMs": 17.779999999999927,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 15493.041000000005,
"styleRecalcs": 77,
"styleRecalcDurationMs": 19.11099999999999,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 15463.238,
"heapDeltaBytes": -34429124,
"heapUsedBytes": 165210036,
"domNodes": -8329,
"jsHeapTotalBytes": -1249280,
"scriptDurationMs": 888.6229999999999,
"eventListeners": -16456,
"totalBlockingTimeMs": 5,
"frameDurationMs": 17.780000000000047,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "vue-large-graph-pan",
"durationMs": 14994.321000000014,
"styleRecalcs": 68,
"styleRecalcDurationMs": 17.739000000000004,
"layouts": 0,
"layoutDurationMs": 0,
"taskDurationMs": 14965.678,
"heapDeltaBytes": -19260052,
"heapUsedBytes": 177058456,
"domNodes": -8330,
"jsHeapTotalBytes": -14180352,
"scriptDurationMs": 897.1310000000001,
"eventListeners": -16460,
"totalBlockingTimeMs": 7,
"frameDurationMs": 17.776666666666642,
"p95FrameDurationMs": 16.799999999999272
},
{
"name": "workflow-execution",
"durationMs": 452.97799999997324,
"styleRecalcs": 18,
"styleRecalcDurationMs": 23.075999999999997,
"layouts": 4,
"layoutDurationMs": 1.246,
"taskDurationMs": 116.03900000000003,
"heapDeltaBytes": 5302512,
"heapUsedBytes": 56684072,
"domNodes": 169,
"jsHeapTotalBytes": 0,
"scriptDurationMs": 23.362999999999996,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
},
{
"name": "workflow-execution",
"durationMs": 456.8730000000869,
"styleRecalcs": 16,
"styleRecalcDurationMs": 24.368,
"layouts": 5,
"layoutDurationMs": 1.379,
"taskDurationMs": 118.40599999999998,
"heapDeltaBytes": 5148900,
"heapUsedBytes": 55427448,
"domNodes": 157,
"jsHeapTotalBytes": 262144,
"scriptDurationMs": 24.222,
"eventListeners": 71,
"totalBlockingTimeMs": 0,
"frameDurationMs": 16.666666666666668,
"p95FrameDurationMs": 16.800000000000182
}
]
} |
Codecov Report❌ Patch coverage is
@@ Coverage Diff @@
## main #12302 +/- ##
===========================================
- Coverage 74.67% 59.55% -15.13%
===========================================
Files 1526 1412 -114
Lines 95359 71885 -23474
Branches 27134 19951 -7183
===========================================
- Hits 71212 42811 -28401
- Misses 23285 28601 +5316
+ Partials 862 473 -389
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1022 files with indirect coverage changes 🚀 New features to boost your workflow:
|
PR Created by the Glary-Bot Agent
Summary
Belt-and-braces for the bottom-panel/node-displacement bug. When the bottom panel opens or closes, the PrimeVue Splitter changes the canvas container size which triggers the canvas
ResizeObserverand the per-node VueResizeObservers. Both have failure modes during animated transitions (RAF batching, suspended-tab handling, stale viewport state on the first measurement). Add an explicit watcher so the canvas is always redrawn and slot layouts re-measured after the panel toggles, regardless of what the RO chain did.Change
In
GraphCanvas.vue, watch the same composite condition the splitter uses to render the panel (bottomPanelVisible && !focusMode). When it flips:requestSlotLayoutSyncForAllNodes()— force a DOM re-measurement of every node's slot connectors so links re-aim correctly.canvasStore.canvas.setDirty(true, true)— force a full foreground + background canvas redraw.This mirrors the existing
linearModewatcher pattern in the same file (lines 285–298).Notes
bottomPanelVisible && !focusMode) rather thanbottomPanelVisiblealone, becauseLiteGraphCanvasSplitterOverlay.vuehides the panel wheneverfocusModeis on regardless of the store flag — so entering/leaving focus mode while the panel is "open" also resizes the canvas.GraphCanvasSFC (brittle integration test mostly exercising Pinia + Vue reactivity) or extracting a one-line watcher into its own composable (over-engineering for one consumer). This is a UI timing fix; an E2E regression toggling the bottom panel with Vue nodes enabled is the right shape for coverage.Verification
pnpm typecheck(vue-tsc --noEmit) cleanoxfmt,eslintclean (pre-commit hooks)Note
This is the third of three PRs that work together to fix the bottom-panel/node-displacement bug. The other two: (1) RAF-batch the per-node Vue ResizeObserver writes (#12299), (2) RAF-batch the canvas ResizeObserver (#12300).
┆Issue is synchronized with this Notion page by Unito