Skip to content

Commit d29943e

Browse files
sandy081Copilot
andauthored
sessions: refine editor header structure (#329270)
* sessions: move layout actions to editor header Place the overflow before the separated Hide Editor and Toggle Details controls, preserve stable action visibility, and move Code Review into overflow when the editor collapses.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: refine editor header action placement Keep Code Review inline while the editor is visible and first in overflow when collapsed. Bridge extension editor-title actions into the right header while preserving their groups.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: preserve editor title action semantics Forward active editor resources to bridged header actions and keep non-navigation extension groups in overflow. Update header placement coverage accordingly.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix editor header action context Name each editor header toolbar for assistive technology and resolve Changes editor resources to their owning session before running Code Review.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: refine editor header structure Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: cover editor header layout fixtures Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * editor: measure header breadcrumb control width Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: remove unused session sequencer Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: unify light editor header background Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e347ab9 commit d29943e

9 files changed

Lines changed: 188 additions & 95 deletions

File tree

.github/skills/sessions/SKILL.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,18 @@ Then read the relevant spec for the area you are changing (see table below). If
3939
- **A sash element's `left`/`top` is the hit-area edge, not the split boundary**: `SplitView.getSashPosition` returns the exact boundary after the preceding view, then `Sash.layout` subtracts half the sash size so the draggable element is centered on that boundary. Align the Sessions/Editor and bottom-Panel grid sash hit areas to `agents.layout.floatingPanelGap`; do not apply that token to independent geometry such as the Auxiliary Bar's leading padding.
4040
- **Wrong menu IDs**: Never use `MenuId.*` from `vs/platform/actions` for Agents window UI. Always use `Menus.*` from `browser/menus.ts`.
4141
- **Editor-group header existence must not depend on an editor-provided scope**: the group-level `showHeader` option enables both header actions and header-hosted breadcrumbs; each menu item gates itself with an active-editor `when` clause. An editor's optional `scopedInstantiationService` property only supplies context for evaluating those clauses, and breadcrumbs compose into the same fixed-height header row rather than creating a second persistent slot.
42-
- **Stable header action hosts must stay layout-transparent**: adding wrapper elements around the primary/secondary `MenuWorkbenchToolBar`s can change their established flex sizing and overflow behavior. Use layout-transparent hosts (`display: contents`) when stable DOM ownership is needed, and keep the toolbar boxes participating in the original primary/secondary flex layout.
42+
- **Editor-header DOM must mirror its visual groups**: breadcrumbs are a direct child of the header and a sibling of one actions container; that actions container directly owns the primary and secondary action hosts. Create the actions container and its hosts inside the `showHeader` construction branch, then attach it after breadcrumbs so ownership and DOM order stay explicit.
43+
- **Editor-header state belongs to the owned nodes and widgets, not their parent or CSS marker classes**: do not add placement/state classes to the title parent, branch layout on the `showHeader` option after construction, or infer action presence from `has-no-actions`. Use the created header element to distinguish placement and `MenuWorkbenchToolBar.getItemsLength()` to derive visibility; the toolbar may still set its internal compatibility class, but header logic and styling must not depend on it.
44+
- **Secondary editor-header actions need a structural trailing column**: custom secondary view items can stretch their host, so `margin-left: auto` plus content-sized flex is not sufficient. Use an actions grid with a flexible leading column and explicit secondary/separator/layout columns so secondary-only states remain trailing regardless of child sizing.
45+
- **Breadcrumbs and editor-header actions share an edge, not a parent gap**: do not add `column-gap` to the header row; it creates a visible hole between the flexed breadcrumb box and actions box. Breadcrumb content owns its trailing breathing room, while the two sibling containers remain contiguous.
46+
- **Header actions must not retain an empty leading grid track beside breadcrumbs**: when breadcrumbs are visible, make the actions grid content-sized with auto columns; otherwise its flexible primary column becomes a visible hole inside the actions element. Only use the full-width `1fr` primary column when breadcrumbs are absent, where it keeps primary actions left-anchored and secondary/layout actions trailing.
47+
- **Header breadcrumb layout measures the control, not its padded wrapper**: `.breadcrumbs-below-tabs` has Sessions-owned left padding, and `clientWidth` includes that padding. Pass `breadcrumbsControl.domNode.clientWidth` to `BreadcrumbsControl.layout()` so the widget receives its actual usable width and does not overrun or clip its trailing scroll range.
48+
- **Header-hosted breadcrumbs inherit the shared header background**: the breadcrumb widget generates a light-theme background on its inner `.monaco-breadcrumbs` surface, which contrasts with the editor-header tab background inherited by sibling actions. Override both the control and inner widget surface to transparent in the Sessions-scoped header breadcrumb stylesheet so the entire row uses one theme-owned surface color.
4349
- **Hidden header widgets must collapse their parent box**: hiding only an inner control leaves the stable parent with its previous inline width, which can push sibling header actions to the right. Mirror visibility onto the parent container and define the common row height on the shared header, not on one child widget, so Changes actions and file breadcrumbs align without stale geometry.
4450
- **An empty editor-group header must collapse completely**: keep the stable header content hidden by default and show it only when breadcrumbs are visible or a primary/secondary menu host has actions. Hiding only the children can leave the header border or reserved height visible as an empty row.
4551
- **Title content spans the full editor-group width**: breadcrumbs and tabs use the full group width in every layout. Only the editor pane is narrowed beside the docked detail panel; do not thread the editor content inset through `EditorTitleControl.layout()`.
4652
- **Agents header styling must not modify shared editor CSS**: keep `vs/workbench` editor styles byte-for-byte unchanged so normal VS Code windows cannot regress. Add an explicit header-placement class in shared DOM code, then put every visual override under a Sessions-owned stylesheet scoped to `.agent-sessions-workbench.dock-detail-panel`.
47-
- **Header presentation has its own control**: `EditorGroupView` passes `menuIds` and `showHeader` to `EditorTitleControl`, which creates `EditorHeaderControl` when enabled and hosts breadcrumbs in its leading container. `EditorHeaderControl` owns header DOM, menu toolbars, scoped action rendering, visibility, and fixed height; `EditorTitleControl` owns tabs/breadcrumbs and includes the header height in its total.
53+
- **Header presentation has its own control**: `EditorGroupView` passes `menuIds` and `showHeader` to `EditorTitleControl`, which creates `EditorHeaderControl` when enabled. `EditorHeaderControl` owns header DOM, breadcrumbs, menu toolbars, scoped action rendering, visibility, and fixed height; `EditorTitleControl` owns tabs and includes the header height in its total.
4854
- **The title-owned header is a child of the title container and follows its recreate lifecycle**: create it after the tabs inside `EditorTitleControl.parent`, include its height in the title control's layout result, and rebuild it with tabs/breadcrumbs after `clearNode(parent)` when editor options change. Do not make it a sibling that requires separate DOM cleanup and duplicate group layout subtraction.
4955
- **Header visibility updates distinguish creation from live changes**: `updateHeaderVisibility(relayout)` updates DOM/state in both cases, but creation and option-driven reconstruction pass `false` because their caller already owns layout. Live menu-item and breadcrumb changes pass `true` so the parent group is explicitly relaid out.
5056
- **Durable chat source/origin references**: Store only `turnId` in durable fork/side-chat references. Active versus historical is mutable lifecycle state that consumers must resolve against the current `activeTurn` and retained `turns` when needed; do not encode lifecycle state in the reference type.

src/vs/sessions/LAYOUT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ The entire third-pane redesign is gated behind the experimental setting `session
255255

256256
- The auxiliary bar is removed from the workbench grid and **docked inside the editor part** (absolutely positioned on the right, below the editor tab strip); the grid's top-right row becomes `Sessions | Editor`, and the editor part spans the editor + detail-panel width.
257257
- The editor group's **tab strip and header-hosted breadcrumbs span the full width**, while the editor content is inset on the right by the detail-panel width via the concrete `EditorPart.setContentRightInset(px)` method (`EditorPart`/`EditorGroupView`; not on the `IEditorPart` interface; `0` = no-op for all other layouts). The detail panel is always docked on the right, so no left margin is needed.
258-
- A **full-width header** sits below the tab bar, spanning the editor content and docked detail panel. `SinglePaneMainEditorPart.getGroupViewOptions()` enables it with `showHeader` and supplies `Menus.SessionsEditorHeaderPrimary`, `Menus.SessionsEditorHeaderSecondary`, and `Menus.SessionsEditorHeaderLayout`. `EditorHeaderControl` owns the header DOM, evaluates those menus, renders their leading/trailing toolbars, and exposes its fixed visible height to `EditorTitleControl`; the title control hosts breadcrumbs there and includes that height in its layout. The trailing actions toolbar keeps secondary view actions under its `...` overflow. A separator follows that toolbar, then the layout toolbar renders **Hide Editor** and **Toggle Details**. Menu items own their active-editor `when` clauses. `SessionChangesEditor.scopedInstantiationService` only supplies its editor-scoped context for evaluating those clauses; its presence does not control whether the header is created.
259-
- Text-file breadcrumbs reuse that **same fixed-height header row**. When `IEditorGroupViewOptions.showHeader` is enabled, `EditorTitleControl` creates `BreadcrumbsControl` directly in the header's stable primary region; otherwise it keeps the standard below-tabs placement in the title container. Editors without breadcrumbs or applicable menu actions hide the row and report zero header height.
258+
- A **full-width header** sits below the tab bar, spanning the editor content and docked detail panel. `SinglePaneMainEditorPart.getGroupViewOptions()` enables it with `showHeader` and supplies `Menus.SessionsEditorHeaderPrimary`, `Menus.SessionsEditorHeaderSecondary`, and `Menus.SessionsEditorHeaderLayout`. `EditorHeaderControl` owns the header DOM, evaluates those menus, renders their toolbars, and exposes its fixed visible height to `EditorTitleControl`; the title control includes that height in its layout. The header directly contains breadcrumbs followed by one actions container. That actions container owns the primary and secondary action hosts, followed by a separator and the layout-action host for **Hide Editor** and **Toggle Details**. Menu items own their active-editor `when` clauses. `SessionChangesEditor.scopedInstantiationService` only supplies its editor-scoped context for evaluating those clauses; its presence does not control whether the header is created.
259+
- Text-file breadcrumbs reuse that **same fixed-height header row**. When `IEditorGroupViewOptions.showHeader` is enabled, `EditorTitleControl` creates `BreadcrumbsControl` directly in the header; otherwise it keeps the standard below-tabs placement in the title container. Header padding defines the shared left anchor for breadcrumbs and primary actions, so either starts at the same inset when the other is absent. Header-hosted breadcrumbs lay out at their actual flexed width, accounting for the header padding and sibling actions instead of using the full editor-group width. Editors without breadcrumbs or applicable menu actions hide the row and report zero header height.
260260
- A vertical **sash** on the left edge of the docked panel resizes it (`DockedAuxiliaryBarController` in `browser/dockedAuxiliaryBarController.ts` owns `layout()` / `_ensureSash()`, created/driven by `SinglePaneMainEditorPart`). The preferred first-open width is 300px; explicit user resizes persist via the part-sizes snapshot. While the panel is visible it clamps to `[220px, editorWidth - 300px]`; dragging the raw sash width down to ~0 hides the docked detail panel, leaving the editor content visible. Temporary width growth from collapsing the sessions list is restored before persistence and must not become the user's detail width.
261261
- Collapsing the sessions list transfers the freed sidebar width to the editor grid node when the editor content is **visible**, and to the **detail panel** (`_dockedAuxiliaryBarWidth`, with the editor node kept equal to it) when the editor content is **hidden** (detail-only). Reopening the sessions list restores the pre-collapse editor-node width / detail width. Keeping the hidden-editor node equal to the detail width ensures the width-based reveal-sync never mistakes a wide detail-only node for a revealed editor.
262262
- When the editor part is hidden while the docked detail panel remains visible, the editor grid node stays visible for the shared tab strip but shrinks to the persisted detail-panel width, letting the Sessions part absorb the freed editor-content space. The detail panel fills that narrowed node below the tab strip and the editor content area collapses to zero. Its sash remains available so dragging the raw requested detail width below its 220px minimum hides the detail panel; the clamped visible width must not decide this. When a visible editor and its details no longer fit within the node, resize handling hides the details first and leaves editor content visible.

src/vs/sessions/browser/media/workbench.css

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,7 @@
294294
background: var(--vscode-agentsPanel-border);
295295
}
296296

297-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header-toolbars {
298-
border-bottom: var(--vscode-strokeThickness) solid var(--vscode-agentsPanel-border);
299-
}
300-
301-
.agent-sessions-workbench.dock-detail-panel .part.editor:not(.modal-editor-part) .editor-group-container:not(:has(.editor-group-header-toolbars)) > .title {
297+
.agent-sessions-workbench.dock-detail-panel .part.editor:not(.modal-editor-part) .editor-group-container > .title {
302298
border-bottom: var(--vscode-strokeThickness) solid var(--vscode-agentsPanel-border);
303299
box-sizing: border-box;
304300
}

src/vs/sessions/contrib/changes/browser/media/sessionChangesEditor.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
/* Diff-stats item (rich "N files +X -Y" rendering) styling, keyed off the item's
8080
* own marker class so it applies in both the classic internal changes-editor
8181
* header and the single-pane editor-group header (where it renders inside
82-
* `.editor-group-header-primary`). It remains fully interactive/clickable, so no
82+
* `.editor-group-header-primary-actions`). It remains fully interactive/clickable, so no
8383
* hover-background override is needed here -- it keeps the normal toolbar hover. */
8484
.changes-diff-stats-action-rich {
8585
flex: 1 1 auto;

src/vs/sessions/contrib/editor/browser/media/editorBreadcrumbs.css

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,64 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs {
7-
padding: 0;
6+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs {
7+
flex: 9999 1 auto;
8+
min-width: 0;
9+
overflow: hidden;
10+
padding-left: var(--vscode-spacing-size40, 4px);
811
}
912

10-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs.hidden {
13+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs.hidden {
1114
display: none;
1215
}
1316

14-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control {
17+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control {
1518
flex: 1 100%;
19+
width: 100%;
1620
height: 22px;
21+
background-color: transparent;
1722
border-bottom: none;
1823
cursor: default;
1924
}
2025

21-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-icon-label,
22-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .outline-element-icon {
26+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumbs {
27+
background-color: transparent;
28+
}
29+
30+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-icon-label,
31+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .outline-element-icon {
2332
height: 22px;
2433
line-height: 22px;
2534
}
2635

27-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-icon-label::before {
36+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-icon-label::before {
2837
height: 22px;
2938
}
3039

31-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .outline-element-icon {
40+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .outline-element-icon {
3241
padding-right: var(--vscode-spacing-size40, 4px);
3342
}
3443

35-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item {
44+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item {
3645
max-width: 80%;
3746
}
3847

39-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item::before {
48+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item::before {
4049
display: flex;
4150
align-items: center;
4251
justify-content: center;
4352
width: 16px;
4453
height: 22px;
4554
}
4655

47-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item:first-of-type::before {
56+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item:first-of-type::before {
4857
display: none;
4958
}
5059

51-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item:last-child {
52-
padding-right: 8px;
60+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item:last-child {
61+
padding-right: var(--vscode-spacing-size80, 8px);
5362
}
5463

55-
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header .breadcrumbs-in-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item:last-child .codicon:last-child {
64+
.agent-sessions-workbench.dock-detail-panel .part.editor .editor-group-header > .breadcrumbs-below-tabs .breadcrumbs-control .monaco-breadcrumb-item:last-child .codicon:last-child {
5665
display: none;
5766
}

0 commit comments

Comments
 (0)