feat(coding-agent): added mouse support and fullscreen rendering to session picker

- Enabled fullscreen overlay rendering for the terminal session picker.
- Implemented full mouse support including wheel-based scrolling and click-to-select functionality.
- Anchored the session picker footer to the bottom of the viewport to correct UI flickering.
- Added comprehensive unit tests for mouse interaction and layout constancy during resizing.
This commit is contained in:
can1357
2026-06-23 02:25:30 +02:00
parent c4e23fed15
commit cffb804d3a
4 changed files with 275 additions and 18 deletions
@@ -8,8 +8,10 @@ import { FileSessionStorage } from "../session/session-storage";
/**
* Show the TUI session selector and return the selected session, or null if
* cancelled. Tab toggles between current-folder and all-projects scope; the
* all-projects list is loaded lazily via `SessionManager.listAll`.
* cancelled. Rendered as a fullscreen overlay on the terminal's alternate
* screen, so the list scrolls and rows are clickable with the mouse. Tab
* toggles between current-folder and all-projects scope; the all-projects list
* is loaded lazily via `SessionManager.listAll`.
*/
export async function selectSession(
sessions: SessionInfo[],
@@ -65,6 +67,7 @@ export async function selectSession(
loadAllSessions: () => SessionManager.listAll(storage),
allSessions: options?.allSessions,
getTerminalRows: () => ui.terminal.rows,
fillHeight: true,
},
);
return selector;
@@ -72,7 +75,18 @@ export async function selectSession(
const selector = showSelector();
selector.setOnRequestRender(() => ui.requestRender());
ui.addChild(selector);
// Present as a fullscreen overlay so the picker borrows the terminal's
// alternate screen buffer (vim/less idiom): the list scrolls and rows are
// clickable via the mouse tracking the overlay enables for its lifetime.
// Anchored top-left at full size so a mouse row maps directly to a rendered
// line (the overlay paints from screen row 0).
ui.showOverlay(selector, {
anchor: "top-left",
width: "100%",
maxHeight: "100%",
margin: 0,
fullscreen: true,
});
ui.setFocus(selector);
ui.start();
return promise;