[aidan] ui/ux: canvas navigation (#85)

* dashboard: pan canvas via middle-drag and horizontal scroll over browser/chat

- Middle-mouse drag inside a browser webview is forwarded as canvas pan
  (previously eaten silently by the guest compositor).
- Horizontal-dominant wheel inside a browser webview pans the canvas
  when no ancestor in the guest page can absorb horizontal scroll;
  otherwise the page handles it.
- Horizontal-dominant wheel over a chat panel pans the canvas (chat has
  no horizontal scroller). Vertical scroll is unchanged.

Plain vertical scroll and ctrl/meta+wheel zoom over a browser stay with
chromium's defaults.

* browser: drop in-guest zoom locks so pinch and cmd+wheel zoom the page

setVisualZoomLevelLimits(1, 1) blocked pinch-to-zoom inside the webview, and
setZoomFactor(1) on every dom-ready reset any user page zoom. Both were added
back when canvas zoom was supposed to take over for ctrl+wheel; with that
reverted, chromium's native zoom handlers should run unimpeded.

* [aidan] fix: prev. commit fix. restore ctrl+wheel canvas zoom over webview cards

* [aidan] ui/ux: app navigation

* [aidan] ui/ux: gate webview preload forwarding on app interactive mode

When a view card is "interactive" (user clicked into the app), the preload stops forwarding ctrl+wheel, middle-mouse-drag, and horizontal-scroll-pan gestures so the embedded app gets every event. A mousedown notifier reports in-guest clicks to the host so it can flip the card into interactive mode without intercepting the click itself.
This commit is contained in:
Aidan
2026-06-14 07:55:34 -07:00
committed by GitHub
parent f08f71313f
commit fd10171ac1
8 changed files with 280 additions and 47 deletions
@@ -98,6 +98,8 @@ export interface DashboardLayoutState {
suspendedBrowserCards: Record<string, { dataUrl: string; capturedAt: number }>;
/** Transient: spawned cards that are about to be removed; surfaces the fade + Keep pill. */
endingBrowserCards: Record<string, { status: 'completed' | 'error'; at: number }>;
/** Transient: id of the view card the user has clicked into; preload stops forwarding canvas gestures while set. */
activeViewCardId: string | null;
}
const initialState: DashboardLayoutState = {
@@ -116,6 +118,7 @@ const initialState: DashboardLayoutState = {
pendingFocusNoteId: null,
suspendedBrowserCards: {},
endingBrowserCards: {},
activeViewCardId: null,
};
interface LayoutPayload {
@@ -565,6 +568,11 @@ const dashboardLayoutSlice = createSlice({
removeViewCard(state, action: PayloadAction<string>) {
delete state.viewCards[action.payload];
if (state.activeViewCardId === action.payload) state.activeViewCardId = null;
},
setActiveViewCardId(state, action: PayloadAction<string | null>) {
state.activeViewCardId = action.payload;
},
addBrowserCard(state, action: PayloadAction<{ url: string; expandedSessionIds?: string[] }>) {
@@ -1080,6 +1088,7 @@ export const {
setViewCardPosition,
setViewCardSize,
removeViewCard,
setActiveViewCardId,
addBrowserCard,
addBrowserCardFromBackend,
setBrowserCardPosition,