Skip to content

Feature: name each split pane in place, and rearrange it by dragging - #73

Merged
DevMando merged 1 commit into
mainfrom
feature/split-view-drag-and-drop
Sep 11, 2026
Merged

DevMando merged 1 commit into
mainfrom
feature/split-view-drag-and-drop

Conversation

@DevMando

Copy link
Copy Markdown
Owner

Summary

Split view gains a header on every pane naming the agent shown beneath it, and you rearrange the
layout by dragging rather than by picking agents from per-pane dropdowns. Dragging a tab onto a
pane places that agent there; dragging one pane's header onto another swaps them.

Why this matters

Split view could show two, three, or four agents at once, but nothing in a pane said which agent
it was. The names lived in a strip along the top, so identifying a pane meant matching position
against that strip — and with four panes of similar-looking conversations, that is genuinely hard.
Rearranging meant opening a dropdown per pane and choosing from a list, which is a lot of clicks
for something that is fundamentally spatial.

What is new

  • Per-pane headers. Each pane names its own agent, so you read the name where the agent is.
  • The tab strip becomes a list of what is not on screen. Agents already visible in a pane
    drop out of it, so the strip stops duplicating what you can already see.
  • Drag a tab onto a pane to put that agent there, replacing whatever was in it.
  • Drag one pane's header onto another to swap the two agents.
  • Every drop target says what it will do before you release — replace, swap, or create.
  • Dragging onto a single, unsplit chat starts a split, and the half you hover decides which
    side the dragged agent lands on. The agent you were already reading stays where it is.
  • The per-pane dropdowns are gone. The tab menu still offers "Add to split view" for anyone who
    would rather not drag.
  • The move cursor appears only over the agent's name, not over the badge or the ... button —
    those are things you click, and a move cursor there would promise a drag that cannot start.

Scope and risk

Medium. MainWindow.Split.cs is substantially reworked (+549/−), and split view is a feature
people arrange once and then rely on, so a regression here is annoying rather than subtle.

Things worth a reviewer's attention:

  • Drag-and-drop in WinUI fails quietly when a target is not hit-testable. A Grid with a null
    Background previews a drop correctly but never fires it. That exact bug was hit and fixed here
    by giving the single-view target a scrim brush; all three drop targets were then audited for the
    same problem. It is the failure mode to re-check if any target is added later.
  • ProtectedCursor applies to an element and its children, which is why the drag handle wraps
    only the label rather than the header row. Widening that wrapper would put the move cursor back
    over the ... button.
  • Border is sealed, so the drag handle is DragHandleGrid : Grid. The cursor is set at
    Loaded rather than in the constructor — assigning it during construction fast-fails in WinUI.

Verification

  • dotnet build src/MandoCode.Desktopsucceeded, 0 warnings, 0 errors.
  • dotnet test src/MandoCode.Desktop.Tests489 passed, 0 failed.
  • Drag, drop, swap, replace, and split-creation were exercised by hand in a running app, including
    the single-agent case where a drop starts the split.

Not covered, and worth being plain about: split view has no automated tests. Everything above
is either a build-level check or a manual pass. The drag-and-drop paths in particular are WinUI
input behaviour that the current test setup cannot reach, so the hit-testability bug described
above was found by clicking, not by a test, and a similar regression would be found the same way.

Rebase note

This branch predates the 0.15.0 changelog audit (#71) and the engine pin (#72). Rebasing it onto
main surfaced two stale edits it was carrying, both dropped rather than replayed:

The changelog diff here is therefore just the one new Added entry.

A strip along the top is a poor map for a spatial layout: with four panes you
had to hold 'second chip means bottom-left' in your head, which is the work
the split is meant to save. Each pane now carries a header naming the agent
beneath it, and the per-pane dropdowns are gone.

The header is a SIBLING of the agent view in the same grid cell, not a
wrapper around it. Wrapping would reparent the view, and reparenting tears
down its WebView2 — the constraint this file is built around.

Dragging replaces the pickers. A tab dropped on a pane puts that agent there;
a pane header dropped on another swaps the two; with one agent open, a drop
starts a split and the half you hover decides which side the newcomer takes.
All of it is reordering one list, so the model needed no changes.

A WebView2 swallows drags over its own surface, which is why the drop targets
are full-pane overlays: an XAML element drawn on top takes the drag back,
because the OS retargets to whatever is topmost. The file-attachment drop
already relies on this; the difference here is that an agent drag starts in
XAML, so the targets can go up immediately rather than waiting for the
WebView to report a drag it has already captured.

Two things that had to be got right rather than assumed. A Grid with a null
Background takes no part in hit testing, so the single-view target drew its
preview and then never received the drop. And ProtectedCursor applies to an
element AND its children, so the move cursor had to wrap the name alone —
over the '...' button it would have promised a drag that cannot start there,
since the button swallows the press.

Also corrects the changelog: the Desktop test count was stated as 330 and is
now 423, the engine pin entry named a commit the pin had already moved off,
and the fix for snapshot/history/note lists losing their scroll position on
delete was never recorded.
@DevMando
DevMando merged commit dfefeb8 into main Sep 11, 2026
1 check passed
@DevMando
DevMando deleted the feature/split-view-drag-and-drop branch September 11, 2026 03:51
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.

1 participant