fix(bot-mode): bound the Bots home re-front so the view stops strobing
Re-fronting the Bots home tab is a close followed by a re-open, which tears down and rebuilds the entire Bots view. `openBotsHomeWorkspace` took that path on EVERY passive reconcile that found the tab open but not holding its zone's active slot, with nothing bounding the retries. That condition is not always transient. `revealTreePane` returns early for a pane in `$hiddenTreePanes` without ever activating it, `isPaneVisible` is false for a minimized zone, and a pane the tree never adopted has no group to be active in. Pinned in any of those states, every signal that reaches a surface sync — sidebar visibility flips, focus churn, group changes — bought one more full remount, and the view visibly strobed. A passive reconcile now gets one attempt. The reveal has already granted or refused the active slot by the time `openWorkspace` returns, so the budget settles on that answer directly instead of waiting for a visibility notification that is not coming: a computed store stays silent when the value does not change. Retiring the tab starts a fresh budget, and an explicit gesture is never blocked. Giving up keeps the surface rather than closing it — a closed home drops the Bots tab through to the ownerless Sessions composer, which is the hole the home exists to plug.
This commit is contained in:
@@ -316,6 +316,10 @@ const $botsHomeFronted = atom(false)
|
||||
|
||||
let botsHomeClose = null
|
||||
let suppressBotsHomeReopen = false
|
||||
// Latched while a re-front attempt has not yet been answered with visibility.
|
||||
// Cleared the moment the home is actually fronted, and whenever the tab is
|
||||
// retired — a fresh open starts the budget over. See openBotsHomeWorkspace.
|
||||
let botsHomeRefrontTried = false
|
||||
|
||||
function saveSelectedRosterBot(bot) {
|
||||
const key = botRosterKey(bot)
|
||||
@@ -13122,6 +13126,10 @@ function closeBotsHomeWorkspace() {
|
||||
const close = botsHomeClose
|
||||
botsHomeClose = null
|
||||
suppressBotsHomeReopen = true
|
||||
// Retiring the tab ends the current attempt's budget: the next open is a
|
||||
// new surface, and it gets its own re-front chance. The re-front path sets
|
||||
// the latch again AFTER calling us, so this cannot erase its own attempt.
|
||||
botsHomeRefrontTried = false
|
||||
|
||||
try {
|
||||
close()
|
||||
@@ -13209,10 +13217,27 @@ function openBotsHomeWorkspace(explicit = false) {
|
||||
// and each of those either legitimately claims the center or cleared it.
|
||||
if (botsHomeClose) {
|
||||
if (botsHomeVisible()) {
|
||||
botsHomeRefrontTried = false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// A re-front is a close + re-open, so it REMOUNTS the whole Bots view.
|
||||
// That is affordable once, against the backgrounded-tab case above. It is
|
||||
// not affordable per signal: the shell does not always answer a reveal
|
||||
// with the active slot (revealTreePane returns early for a pane in
|
||||
// $hiddenTreePanes without activating it; a minimized zone and a pane the
|
||||
// tree never adopted are never visible either). Pinned in one of those
|
||||
// states the old code re-fronted on every passive pass — sidebar flips,
|
||||
// focus churn and group changes all reach here — and the view strobed.
|
||||
// One attempt proves whether this shell will front the tab; if it will
|
||||
// not, keep the surface and wait for a signal that changes the answer.
|
||||
if (botsHomeRefrontTried && !explicit) {
|
||||
return true
|
||||
}
|
||||
|
||||
closeBotsHomeWorkspace()
|
||||
botsHomeRefrontTried = true
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -13230,6 +13255,15 @@ function openBotsHomeWorkspace(explicit = false) {
|
||||
}
|
||||
})
|
||||
|
||||
// The reveal has already either granted the tab its zone's active slot or
|
||||
// refused it, so settle the re-front budget on that answer directly rather
|
||||
// than waiting for a visibility notification to schedule another pass. A
|
||||
// computed store stays silent when the value does not change, so on the
|
||||
// shells that refuse, no such pass is coming.
|
||||
if (botsHomeVisible()) {
|
||||
botsHomeRefrontTried = false
|
||||
}
|
||||
|
||||
return typeof botsHomeClose === 'function'
|
||||
} catch {
|
||||
botsHomeClose = null
|
||||
|
||||
Reference in New Issue
Block a user