Skip to content

sessions: fix account widget missing from titlebar after IntersectionObserver optimization#312469

Merged
osortega merged 1 commit intomainfrom
sessions/fix-account-widget-intersection-observer
Apr 25, 2026
Merged

sessions: fix account widget missing from titlebar after IntersectionObserver optimization#312469
osortega merged 1 commit intomainfrom
sessions/fix-account-widget-intersection-observer

Conversation

@osortega
Copy link
Copy Markdown
Contributor

Summary

Fixes the account widget (avatar/sign-in button) disappearing from the Agent Sessions desktop titlebar after PR #312317.

Root Cause

PR #312317 introduced an IntersectionObserver optimization in MenuWorkbenchToolBar that only subscribes to IMenu.onDidChange and IActionViewItemService.onDidChange while the toolbar container is visible (isIntersecting === true).

This created a chicken-and-egg deadlock for Menus.TitleBarRightLayout:

  1. The .titlebar-right-layout-container starts with CSS display: none (empty menu → .has-no-actions class)
  2. Both registerAction2 calls for the account/update actions lived inside AccountWidgetContribution (WorkbenchPhase.AfterRestored)
  3. By the time AccountWidgetContribution ran, the IntersectionObserver had already fired with isIntersecting: false and unsubscribed from menu changes
  4. The newly registered menu items were never picked up → container stayed hidden → account widget never appeared

The session actions toolbar (Run, Terminal, Open in VS Code) was unaffected because its actions are all registered at module level and are present during the toolbar's first render.

Fix

Move the two registerAction2 calls to module level so both actions exist in Menus.TitleBarRightLayout when MenuWorkbenchToolBar first calls _updateToolbar(). The container has items from the start, remains visible, and the IntersectionObserver stays subscribed — so the subsequent actionViewItemService.register calls from AccountWidgetContribution (which require instantiationService) are correctly picked up and trigger a toolbar rebuild with the custom widgets.

The actionViewItemService.register calls remain inside the contribution. Module-level variables (_updateWidget, _accountWidget) bridge the dispatch from the module-level run() methods to the widget instances once they're created.

Copilot AI review requested due to automatic review settings April 25, 2026 00:47
…Observer optimization

PR #312317 made MenuWorkbenchToolBar use IntersectionObserver to only subscribe
to menu change events while the container is visible. This broke the account
widget in the Agent Sessions titlebar because both registerAction2 calls were
inside AccountWidgetContribution (WorkbenchPhase.AfterRestored). By the time
the contribution ran, the TitleBarRightLayout toolbar container was already
 has-no-actions class), the observer had fired with
isIntersecting:false, and it had stopped listening. The late-registered
menu items were never picked up.

Fix: move registerAction2 calls to module level so the actions are present in
Menus.TitleBarRightLayout when MenuWorkbenchToolBar first renders. The container
has items from the start, stays visible, and the IntersectionObserver keeps the
subscription active so subsequent actionViewItemService changes are picked up.
The actionViewItemService.register calls remain inside the contribution since
they require instantiationService.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@osortega osortega force-pushed the sessions/fix-account-widget-intersection-observer branch from c853472 to 5d6a04f Compare April 25, 2026 00:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression in the Agents Sessions window where the account widget (avatar/sign-in) could remain missing from the desktop titlebar after the MenuWorkbenchToolBar visibility-based (IntersectionObserver) subscription optimization.

Changes:

  • Registers the two titlebar widget actions (SessionsTitleBarUpdateWidgetAction, SessionsTitleBarAccountWidgetAction) at module load so Menus.TitleBarRightLayout is non-empty on first render.
  • Keeps IActionViewItemService.register(...) inside AccountWidgetContribution, wiring the created widget instances to module-level variables so the actions can dispatch to the instantiated widgets.
Show a summary per file
File Description
src/vs/sessions/contrib/accountMenu/browser/account.contribution.ts Moves titlebar action registration to module scope and bridges action execution to late-instantiated custom titlebar widgets.

Copilot's findings

Comments suppressed due to low confidence (2)

src/vs/sessions/contrib/accountMenu/browser/account.contribution.ts:807

  • This fix relies on the timing of these registerAction2 calls (the actions must already be present in Menus.TitleBarRightLayout before the toolbar is created). Consider adding a small unit test (similar to sessions/test/browser/layoutActions.test.ts) that imports this module and asserts MenuRegistry.getMenuItems(Menus.TitleBarRightLayout) contains sessions.action.titleBarUpdateWidget and sessions.action.titleBarAccountWidget, to prevent regressions from future refactors/optimizations.
	constructor() {
		super({
			id: SessionsTitleBarUpdateWidgetAction,
			title: localize2('agentsUpdateTitleBar', "Agents Update"),
			menu: {
				id: Menus.TitleBarRightLayout,
				group: 'navigation',
				order: 99,
				when: ContextKeyExpr.and(IsAuxiliaryWindowContext.toNegated(), SessionsWelcomeVisibleContext.toNegated()),
			}
		});
	}

	run(): void { }
});

registerAction2(class extends Action2 {
	constructor() {
		super({
			id: SessionsTitleBarAccountWidgetAction,
			title: localize2('agentsAccountStatusTitleBar', "Agents Account and Status"),
			menu: {
				id: Menus.TitleBarRightLayout,
				group: 'navigation',
				order: 100,
				when: IsAuxiliaryWindowContext.toNegated(),
			}
		});
	}

	run(): void { }
});

class AccountWidgetContribution extends Disposable implements IWorkbenchContribution {

	static readonly ID = 'workbench.contrib.sessionsWidget';

src/vs/sessions/contrib/accountMenu/browser/account.contribution.ts:770

  • Registering these commands at module load means the titlebar right toolbar can render them before AccountWidgetContribution runs (it’s still WorkbenchPhase.AfterRestored). Until actionViewItemService.register(...) executes, MenuWorkbenchToolBar will fall back to default action view items, which likely shows a plain "Agents Update" / "Agents Account and Status" entry and won’t apply the update widget’s hide/busy styling. Consider moving the actionViewItemService.register(...) setup to an earlier phase (e.g. BlockStartup/Ready) so the custom view items are available on the toolbar’s first render, or otherwise ensure these actions don’t surface as generic buttons before the widgets are registered.
// The actual widget rendering and interaction is handled by TitleBarUpdateWidget /
// TitleBarAccountWidget, which are custom view items registered via IActionViewItemService
// in AccountWidgetContribution. Those widgets attach their own DOM click handlers, so
// run() here is intentionally a no-op.
registerAction2(class extends Action2 {
  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread src/vs/sessions/contrib/accountMenu/browser/account.contribution.ts
@osortega osortega marked this pull request as ready for review April 25, 2026 01:21
@osortega osortega enabled auto-merge (squash) April 25, 2026 01:21
@osortega osortega merged commit d716c75 into main Apr 25, 2026
40 of 41 checks passed
@osortega osortega deleted the sessions/fix-account-widget-intersection-observer branch April 25, 2026 03:11
@vs-code-engineering vs-code-engineering Bot added this to the 1.118.0 milestone Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants