Skip to content

Commit 4c0be7f

Browse files
committed
docs: add design for resize mouse fix + session restore
Part 1: Reset mouse tracking on WindowSizeMsg to fix coordinate drift Part 2: -c flag to save/restore TUI session state (tabs, navigation, views) with edge case handling for deleted nodes and stale data
1 parent f3ed76a commit 4c0be7f

1 file changed

Lines changed: 135 additions & 0 deletions

File tree

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# TUI Resize Fix + Session Restore Design
2+
3+
## Part 1: Window Resize Mouse Coordinate Fix
4+
5+
### Problem
6+
7+
After terminal window resize, mouse click coordinates drift — all interactive areas (tab bar, miller columns, status bar) respond to wrong positions. The terminal reports mouse positions based on stale coordinate mapping.
8+
9+
### Root Cause
10+
11+
bubbletea's mouse tracking mode is not automatically reset when the terminal window size changes. Some terminals (tmux, screen) need the mouse tracking ANSI sequences re-sent to recalibrate.
12+
13+
Additionally, the recently added LLM anchor line may have changed the Y-offset calculation without updating mouse coordinate translation.
14+
15+
### Fix
16+
17+
1. In `WindowSizeMsg` handler, reset mouse tracking:
18+
```go
19+
case tea.WindowSizeMsg:
20+
a.width = msg.Width
21+
a.height = msg.Height
22+
// Reset mouse tracking to recalibrate coordinates
23+
return a, tea.Batch(
24+
tea.DisableMouse,
25+
tea.EnableMouseCellMotion,
26+
)
27+
```
28+
29+
2. Audit all Y-coordinate offsets in mouse handling:
30+
- `msg.Y - 1` offset for tab bar — verify against actual chrome height
31+
- If LLM anchor line is rendered, add +1 to Y offset
32+
- Status bar hit test Y coordinate check
33+
34+
### Files
35+
36+
- `cmd/mxcli/tui/app.go` — WindowSizeMsg handler, mouse Y-offset audit
37+
38+
## Part 2: Session Restore (-c flag)
39+
40+
### Overview
41+
42+
Save TUI state on exit, restore on startup with `-c` flag. Enables quick restart-verify cycles during development.
43+
44+
### Storage
45+
46+
File: `~/.mxcli/tui-session.json` (overwritten on each exit)
47+
48+
### Session State Schema
49+
50+
```json
51+
{
52+
"version": 1,
53+
"timestamp": "2026-03-26T01:30:00Z",
54+
"tabs": [
55+
{
56+
"projectPath": "/path/to/App.mpr",
57+
"millerPath": ["Project", "MyFirstModule", "Pages"],
58+
"selectedNode": "P_ComboBox_Enum",
59+
"previewMode": "MDL"
60+
}
61+
],
62+
"activeTab": 0,
63+
"viewStack": [
64+
{"type": "browser"},
65+
{"type": "overlay", "title": "mx check", "filter": "all"}
66+
],
67+
"checkNavActive": true,
68+
"checkNavIndex": 1
69+
}
70+
```
71+
72+
### Fields
73+
74+
| Field | Type | Description |
75+
|-------|------|-------------|
76+
| `version` | int | Schema version for forward compat (currently 1) |
77+
| `timestamp` | string | ISO 8601 save time |
78+
| `tabs` | []TabState | All open tabs |
79+
| `tabs[].projectPath` | string | Absolute path to .mpr file |
80+
| `tabs[].millerPath` | []string | Navigation breadcrumb path |
81+
| `tabs[].selectedNode` | string | Currently selected node name |
82+
| `tabs[].previewMode` | string | "MDL" or "NDSL" |
83+
| `activeTab` | int | Index of active tab |
84+
| `viewStack` | []ViewState | Stack of open views (browser at bottom) |
85+
| `viewStack[].type` | string | "browser", "overlay", "compare", etc. |
86+
| `viewStack[].title` | string | Overlay title (for overlay type) |
87+
| `viewStack[].filter` | string | Check filter (for check overlay) |
88+
| `checkNavActive` | bool | Whether check nav mode is active |
89+
| `checkNavIndex` | int | Current nav position |
90+
91+
### Edge Cases
92+
93+
| Scenario | Handling |
94+
|----------|----------|
95+
| Project file deleted | Skip tab, log warning, open remaining tabs |
96+
| Selected node deleted | Fall back to nearest existing parent in miller path |
97+
| Miller path partially invalid | Expand to last valid level, select first child |
98+
| Overlay data unavailable | Skip overlay restore, show browser only |
99+
| Check results stale | Re-run check on restore, don't restore old results |
100+
| All tabs invalid | Normal startup (no restore) |
101+
| Session file corrupt/missing | Ignore, normal startup |
102+
| Schema version mismatch | Ignore if version > current, attempt if <= current |
103+
104+
### Implementation
105+
106+
**New file:** `cmd/mxcli/tui/session.go`
107+
- `TUISession` struct matching JSON schema
108+
- `TabState`, `ViewState` sub-structs
109+
- `SaveSession(app *App) error` — serialize current state to file
110+
- `LoadSession() (*TUISession, error)` — read and parse session file
111+
- `sessionFilePath() string` — returns `~/.mxcli/tui-session.json`
112+
113+
**Modified files:**
114+
115+
`cmd/mxcli/tui/app.go`:
116+
- On quit (case "q"): call `SaveSession(a)` before returning `tea.Quit`
117+
- New `RestoreSession(session *TUISession)` method on App
118+
- Opens each tab's project, navigates miller path, selects node
119+
- Restores view stack (overlay, etc.) with fallbacks
120+
- Accept `*TUISession` in App constructor or Init
121+
122+
`cmd/mxcli/cmd_tui.go`:
123+
- Add `-c` / `--continue` flag
124+
- When set, call `LoadSession()` and pass to App
125+
126+
`cmd/mxcli/tui/browserview.go` / `cmd/mxcli/tui/miller.go`:
127+
- May need `NavigateToPath(path []string) bool` method
128+
- Reuse existing `navigateToNode` with path-walking
129+
130+
### Task Order
131+
132+
1. Part 1: Mouse fix (small, isolated)
133+
2. Part 2a: Session save/load infrastructure (session.go)
134+
3. Part 2b: App integration (save on quit, restore on start)
135+
4. Part 2c: CLI flag + edge case testing

0 commit comments

Comments
 (0)