Skip to content

fix(work-panel): lend width to a reopened sidebar instead of storing it - #1735

Merged
vastsa merged 2 commits into
vastsa:mainfrom
AR307:fix/work-panel-reopen-width-upstream
Oct 17, 2026
Merged

vastsa merged 2 commits into
vastsa:mainfrom
AR307:fix/work-panel-reopen-width-upstream

Conversation

@AR307

@AR307 AR307 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Keep the work panel's preferred width when a manual sidebar reopen squeezes the
panel. The reopen stored the squeezed width as the user's width, so the panel
stayed narrow after the sidebar collapsed again or the window grew, and the
narrow width survived a restart. When the squeezed width was below 244px, the
divider minimum also dropped to 1px.

  • A sidebar reopen now lends width to the sidebar instead of storing it. The
    loan lives only in renderer memory. Extra client width goes back to the panel
    first, and collapsing the sidebar or resizing the panel ends the loan.
  • Resize gestures keep the 244px minimum. A panel shown narrower than that
    starts a drag from its current width and cannot be dragged narrower.
  • Stored widths below 244px, which only the old reopen path could write, load
    as 244px.

The reopen priority of ADR 0238 is unchanged: the panel gives up width first
and MainChat lands on its 460px target. Decision 3 of that ADR, which allowed
the compact width to be persisted, is amended.

Reproduction

Reproduced against main 4f9f051e54c495ac0c5164f2ef4dd687c704bc11 on
October 17, 2026, in an 866px shell with the default 275px sidebar and a
360px panel.

Reopen the sidebar, then collapse it again

  1. Open a conversation and its work panel at 360px. The 360px panel does not
    fit beside the sidebar, so the layout collapses the sidebar.
  2. Reopen the sidebar. The panel shrinks to 131px so MainChat keeps 460px.
  3. Collapse the sidebar again.

Before: The panel stays at 131px although 416px are available.
pi.desktop.workPanel now holds {"width":131}, so the next launch also
opens the panel at 131px.

After: The reopen shows 131px without storing it. Collapsing the sidebar
restores 360px, and the stored width stays {"width":360}.

Drag the divider after the reopen

  1. After the steps above, drag the work-panel divider to make the panel
    narrower.

Before: The stored width is below 244px, so the gesture uses the 1px
compact minimum and the panel can be dragged down to a 1px sliver. Dragging it
back above 244px restores the limit, so the minimum appears and disappears.

After: The drag stops at 244px.

Any constrained reopen overwrote the preferred width. With the 800 DIP window
minimum and default widths, the squeezed width falls below 244px at shell
widths up to about 978px, or in wider windows with a wider sidebar.

Changes

  • work-panel-resize.ts:
    • workPanelRequestedWidth resolves the width the panel asks of the
      three-column budget: the preferred width, or the lent width while the
      reopened sidebar stays expanded, with extra client width given back to the
      panel first.
    • workPanelGestureMinimum gives resize gestures the 244px minimum, or the
      shown width when that is narrower.
  • Work-panel slice:
    • workPanelYieldedWidth is runtime-only state, set through
      setWorkPanelYieldedWidth.
    • setWorkPanelWidth keeps the 244px minimum and ends a loan.
    • loadWorkPanelWidth raises stored widths below 244px.
  • useAppShellRuntime:
    • The reopen sets the lent width instead of calling setWorkPanelWidth.
    • The loan ends once the sidebar has fully collapsed, whichever path
      collapsed it.
    • The sidebar resize budget and the pending dock in AppShell use the
      requested width, so the sidebar resize range follows the shown panel width.
  • WorkPanel:
    • The layout uses the requested width, except during a drag preview.
    • The gesture minimum follows the shown width.
    • A resize key that cannot move the separator commits nothing.
  • Docs:
    • ADR 0238 decision 3 is amended.
    • 01-ui-ia, 09-interaction-patterns and
      E2E-LAYOUT-three-column-width-priority are updated, with their zh-CN
      mirrors.
  • Tests:
    • Pure-function regressions in work-panel-resize.test.mjs.
    • Store regressions in the new work-panel-width-preference.test.mjs.
    • An 866px viewport scenario in scripts/e2e-three-column-layout.mjs.

Validation

Candidate: 5a8ae904f1c0324473260523f653fcda1f923535
Base main: 4f9f051e54c495ac0c5164f2ef4dd687c704bc11
Environment: Windows 11 (10.0.26200), Electron 43.6.0, Node
24.14.0, Rust 1.90.0.

  • The new layout checks fail against unmodified upstream product code:
    {"width":131} is stored, the panel stays at 131px after the sidebar
    collapses, and the drag reaches 1px. All four pass on the candidate.

  • pnpm test:e2e:layout: 82 passed on the candidate. The same 9 checks
    fail on the candidate and on unmodified upstream: the four darwin-only
    preview-header geometry checks and the sidebar group reload/fold sequence
    that ends in nextKey.

  • The new store regressions fail against the unmodified work-panel slice
    (4/4) and pass with the fix.

  • 49/49 tests passed in work-panel-resize.test.mjs,
    work-panel-width-preference.test.mjs and work-panel.test.mjs.

  • Full desktop node --test: 4,005 of 4,076 passed and 8 were
    skipped. The 63 failures are in files that failed the same way on an
    unmodified upstream run on this machine (f21c550e7):

    • remote-host SSH and sh transports;
    • macOS release and signing;
    • provider catalog tests that read the bundled snapshot through
      new URL(...).pathname;
    • POSIX permission modes;
    • the S3 settings timeout.

    sidebar-pinned-rendering also fails against the unmodified product code
    at 4f9f051e5. chat-links-performance failed only under the parallel
    run and passes on its own.

  • Workspace build, Desktop typecheck, Biome lint, style tokens,
    architecture budgets, agent-policy and git diff --check passed.

  • Documentation checks passed for 86 English/Chinese pairs and
    578 pages.

  • Manual pointer testing on an isolated fork build that carries the same
    product change: the reopen width was never stored. The only stored widths
    were the tester's own drags, 365px and then 244px.

E2E entry points

scripts/e2e-three-column-layout.mjs

The layout E2E launches the built app with throwaway profiles. The 866px case
uses CDP viewport emulation, so the native window keeps its size. No provider,
account or user profile is involved. These results do not claim macOS/Linux
runs or installer packaging.

Scope

  • The reopen priority itself is unchanged: the panel still yields first and
    MainChat lands on 460px. Auto-collapse and restore, preview mode and native
    window behavior are also unchanged.
  • The lent width is runtime-only. There is no new persisted key, and no IPC,
    host or schema change. The only persisted difference is that
    pi.desktop.workPanel never stores, and never loads, a width below 244px.
  • Keyboard resizing: a key that cannot move the separator now commits nothing.
    Previously it rewrote the same width.
  • No version, dependency or release changes. No profiles, logs or local
    artifacts are included.

Review

Suggested reviewer focus:

  • Loan lifetime: only a constrained manual reopen sets the loan. A fully
    collapsed sidebar, by any path, or an explicit resize ends it. It survives
    panel close/open and session switches while the sidebar stays expanded.
  • Space returning: extra client width goes back to the panel first, up to
    its preferred width, while MainChat stays at 460px. A narrower window keeps
    the lent width until it no longer fits; then the sidebar yields as before.
  • Gesture floor: 244px, or the shown width when narrower, so a press never
    jumps and a drag never reaches a sliver.
  • Sidebar budget: while the panel's width is lent, the sidebar resize range
    uses the shown panel width, as it did when the squeezed width was stored.
  • Existing profiles: a stored width below 244px, which only the old reopen
    path could write, loads as 244px.

AR307 and others added 2 commits October 17, 2026 15:52
Reopening the sidebar spends work-panel width so MainChat keeps its
460px target. The reopen stored that squeezed width as the preferred
width, so the panel stayed narrow after the sidebar collapsed again or
the window grew, and the narrow width survived a restart.

With a stored width below 244px, WorkPanel switched every resize
gesture to the 1px compact minimum, so a divider drag could shrink the
panel to a sliver until it was dragged back above 244px.

Lend the reopen width instead. It lives only in renderer memory, extra
client width goes back to the panel first, and collapsing the sidebar
or resizing the panel ends the loan. Committed and loaded widths keep
the 244px minimum, a gesture starts from the shown width and cannot go
narrower, and the sidebar budget and pending dock use the lent width.
@vastsa
vastsa merged commit e219a3e into vastsa:main Oct 17, 2026
6 checks passed

vastsa commented Oct 17, 2026

Copy link
Copy Markdown
Owner

Thanks for the focused fix and for documenting the narrow-window reproduction. I verified the 866px reopen/restore path, the persisted preferred width, and the 244px drag floor on the latest-main integration candidate. The targeted panel tests passed (22/22), the layout E2E passed (205/205), the updated PR CI and Docs checks are green, and the PR-base gate passed. Merged as e219a3e.

@AR307
AR307 deleted the fix/work-panel-reopen-width-upstream branch October 17, 2026 17:50
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.

2 participants