Skip to content

Disk picker dialog doesn't scale: add scroll, resizable columns, sort + search #80

Description

@relmer

Summary

The boot / Insert-Disk picker (AssetBootstrap::PromptBootDiskMru and PromptInsertDiskMru, rendered through a DialogPrimitive custom body hosting a DxuiListView) does not scale to large lists or long text. It was built for a handful of rows (a few MRU entries + 2 stock downloads). This is now much easier to hit since the picker also lists in-repo Apple2/Demos disks (7) alongside recents and downloads.

Problems (investigated 2026-06-26)

No scroll — dialog grows off-screen.

  • onMeasureCustomBody returns GetTotalMeasuredWidthPx() × GetRequiredHeightPx() — both auto-fit to content, unbounded. GetRequiredHeightPx() = header + rows × rowHeight (DxuiListView.cpp:1027).
  • DialogPrimitive::GetInitialWindowRect clamps only the dialog's position to the monitor work area, not its size (DialogPrimitive.cpp:1560-1561). A long list grows the dialog taller than the screen, pins it to the top, and pushes the bottom rows and the Skip/Cancel/Browse buttons off-screen, unreachable.

Custom-body input channel cannot scroll.

  • DialogInputEvent::Kind = { MouseMove, LeftButtonDown, LeftButtonUp, KeyDown }there is no wheel kind. The picker's onInputCustomBody only handles MouseMove + LeftButtonUp.
  • DxuiListView is fully scrollable (ScrollByWheelDelta, scrollbar hit-tests, keyboard) but is never given a bounded rect, nor any wheel/scrollbar/keyboard input.

Columns not resizable and overgrow.

  • MeasureColumnsPx auto-fits every column, including the stretch "Location" column, to its widest cell (DxuiListView.cpp:350-361). A long path grows the dialog wide, spilling off the right edge (again only position-clamped).
  • DxuiListView supports divider resize (mouse HitTestColumnResize + keyboard m_focusedDividerCol / Left-Right) but the picker forwards none of it. No truncation fallback either.

Wanted

  1. Scroll — clamp the dialog body to the monitor work area; hand DxuiListView a bounded rect so it enters scroll mode (it already renders a scrollbar via ScrollbarMetrics).
  2. Wheel/scroll input — add a Wheel kind (+ wheelDelta) to DialogInputEvent and forward wheel / scrollbar-click / keyboard from the custom-body channel to the list.
  3. Resizable columns — cap column widths with truncation; optionally wire divider-resize input through the dialog.
  4. Sort — wire header-click column sort (DxuiListView::SetSortIndicator already exists).
  5. Search — add a filter box to narrow rows by name/path substring.

This likely needs a DialogPrimitive custom-body input extension (wheel + capture), since this picker and future custom-body dialogs hit the same channel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions