Skip to content

fix(ui): align submenu items with the parent row - #1627

Merged
eugenioenko merged 1 commit into
mainfrom
fix/submenu-row-alignment
Nov 15, 2026
Merged

eugenioenko merged 1 commit into
mainfrom
fix/submenu-row-alignment

Conversation

@eugenioenko

@eugenioenko eugenioenko commented Nov 15, 2026 •

Copy link
Copy Markdown
Owner

Submenus placed their top border on the hovered parent row, leaving the first child item one row too low. Move the submenu up one row so its first item aligns with the parent, while retaining screen-edge clamping.

Validation: TestContextMenuSubmenuRowAlignment covers first and later parent items, opening to the left, bottom-edge clamping, and clicking the rendered child row. It fails before the fix and passes afterward. All context-menu tests, make test, make lint, and make build pass.

Before/after text screenshots from the real binary (--size 100x26 --exec 'key alt+o; key right; screenshot PATH; quit'), cropped to the menus:

Before:

┌───────────────────────────┐
│ Editor                  › ┌─────────────────────────┐
│ Code Assist             › │  Word Wrap              │─
│ Appearance              › │✓ Line Numbers           │
│ Diff Views              › │  Indent Guides          │
│ Git Files               › │✓ Syntax Highlight       │
│───────────────────────────│  Bracket Colors         │
│ Theme                     │─────────────────────────│
│ Settings         Ctrl+K , │✓ Auto Indent            │
└───────────────────────────│✓ Auto Dedent            │
                            │─────────────────────────│
                            │ Indentation             │
                            │─────────────────────────│
                            │✓ Git Gutter             │
                            │✓ Scrollbar Git Marks    │
                            └─────────────────────────┘

After:

┌───────────────────────────┌─────────────────────────┐
│ Editor                  › │  Word Wrap              │
│ Code Assist             › │✓ Line Numbers           │─
│ Appearance              › │  Indent Guides          │
│ Diff Views              › │✓ Syntax Highlight       │
│ Git Files               › │  Bracket Colors         │
│───────────────────────────│─────────────────────────│
│ Theme                     │✓ Auto Indent            │
│ Settings         Ctrl+K , │✓ Auto Dedent            │
└───────────────────────────│─────────────────────────│
                            │ Indentation             │
                            │─────────────────────────│
                            │✓ Git Gutter             │
                            │✓ Scrollbar Git Marks    │
                            └─────────────────────────┘

Summary by CodeRabbit

  • Bug Fixes
    • Fixed submenu vertical alignment so child menus line up correctly with their parent items, including when opening to the left or near the bottom of the screen. This keeps the submenu’s first row and label positioned consistently and preserves access to its commands.

@github-actions

github-actions Bot commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

Binaries

Built from 794b6cb7b260. Links expire on Nov 29, 2026.

Try it in the browser (emulated): runs this build in 32-bit Linux emulated inside the page, with no download or sign-in. It is much slower than a native build and is meant for quick checks of behavior and UI, not performance or terminal compatibility. Startup takes up to a minute.

Platform Download
Linux x64 ttt-pr-1627-linux-amd64
macOS Apple Silicon ttt-pr-1627-darwin-arm64
macOS Intel ttt-pr-1627-darwin-amd64
Windows x64 ttt-pr-1627-windows-amd64

Downloads need a GitHub sign-in and arrive as zips. On Linux and macOS, run chmod +x ttt after unzipping. These binaries run this pull request's code, so only run them if you trust it.

@coderabbitai

coderabbitai Bot commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Submenus now start one row higher relative to the parent menu. Tests cover placement for top, later-item, left-opening, and bottom-clamped cases, including child command execution.

Changes: Submenu alignment

Layer / File(s) Summary
Submenu placement and validation
internal/ui/contextmenu_widget.go, internal/ui/contextmenu_widget_test.go
Submenu vertical placement uses the parent row plus the selected item index. Table-driven tests check alignment, bounds, rendered labels, and child command execution.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: arimxyer, jay23606

Merge Risk: Minimal · up to 794b6

Submenus now line up with the hovered parent item. The change is small and covered by new tests, and no merge-blocking risk was identified.

Pre-merge checks: Passed 4

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "fix(ui): align submenu items with the parent row" matches the main change. The raw summary shows a one-line change in internal/ui/contextmenu_widget.go that moves submenu placement from y +…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "fix(ui): align submenu items with the parent row" matches the main change. The raw summary shows a one-line change in internal/ui/contextmenu_widget.go that moves submenu placement from y + 1 + submenuIndex to y + submenuIndex, so the first child aligns with the hovered parent item. The added test TestContextMenuSubmenuRowAlignment covers this alignment, and the PR objectives state the same goal. The title is concise, specific, and follows a conventional commit style.

Finishing Touches

Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between adfa9e9 and 794b6cb.

Files selected for processing: 2

  • internal/ui/contextmenu_widget.go
  • internal/ui/contextmenu_widget_test.go

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

@github-actions

Copy link
Copy Markdown
Contributor

Editor, diff, and log benchmarks

Comparing adfa9e9109e0 with 794b6cb7b260 on the same runner: fastest of 3 alternating passes at 5x each, -short (2,000-line large file).

Allocated bytes measure total allocation per operation, not peak or retained RAM.

Logs are opened by each side's built ttt binary, 1x per pass, timed from launch until the first frame shows the log; _wrap rows start with word wrap on, and _edit opens a log committed to git, types a character, and moves down 20 lines. Time includes process startup, so the 1 MiB case is mostly startup; peak RSS is the process's maximum resident memory. The 1, 128, and 256 MiB fixtures are generated once outside timing and shared across both checkouts, so reads may use the OS file cache.

Code files open a 64 MiB Go file, this repository's sources repeated, with LSP and the git gutter off; _type also types 20 characters and _enter presses Enter 10 times before quitting.

Editor

Geometric-mean change: time +0.2%, allocated bytes 0.0%, allocations 0.0%.

Click here to see benchmark details
Benchmark Base PR Time change Base allocs PR allocs Allocation change
go/redraw 231 µs 227 µs -1.4% 35 35 0.0%
go/cursor_down 241 µs 240 µs -0.6% 37 37 0.0%
go/page_down 1.4 ms 1.3 ms -5.5% 3017 3016 0.0%
go/wheel_scroll 410 µs 417 µs +1.7% 1507 1507 0.0%
go/type_and_delete 457 µs 458 µs +0.2% 102 102 0.0%
go/open_large_first 7.4 ms 7.7 ms +3.2% 48363 48367 0.0%
go/open_large 1.8 ms 1.9 ms +5.1% 2597 2597 0.0%
go/jump_to_end_large 6.4 ms 6.6 ms +2.2% 11082 11083 0.0%
go/redraw_git_changes_large 276 µs 274 µs -1.0% 87 87 0.0%
go/wheel_scroll_git_changes_large 470 µs 471 µs +0.3% 1571 1570 -0.1%
go/type_and_delete_git_changes_large 569 µs 568 µs -0.3% 217 217 0.0%
go/edit_top_view_end_large 1.1 ms 903 µs -15.2% 2814 2814 0.0%
ts/redraw 234 µs 233 µs -0.3% 37 37 0.0%
ts/cursor_down 249 µs 250 µs +0.3% 38 38 0.0%
ts/page_down 3.4 ms 3.7 ms +9.4% 13518 13519 0.0%
ts/wheel_scroll 1.8 ms 1.8 ms +2.9% 12037 12036 0.0%
ts/type_and_delete 471 µs 481 µs +2.1% 114 114 0.0%
ts/open_large_first 25.5 ms 25.8 ms +1.2% 204600 204605 0.0%
ts/open_large 2.5 ms 2.6 ms +5.0% 3869 3871 +0.1%
ts/jump_to_end_large 18.6 ms 18.3 ms -1.6% 62315 62315 0.0%
ts/edit_top_view_end_large 993 µs 1.0 ms +1.4% 3412 3411 0.0%
cpp/redraw 235 µs 239 µs +1.5% 36 36 0.0%
cpp/cursor_down 260 µs 255 µs -2.1% 38 38 0.0%
cpp/page_down 5.0 ms 4.9 ms -0.9% 7946 7948 0.0%
cpp/wheel_scroll 1.0 ms 1.0 ms +0.5% 1982 1983 +0.1%
cpp/type_and_delete 498 µs 493 µs -0.9% 114 114 0.0%
cpp/open_large_first 169.8 ms 168.3 ms -0.9% 1386890 1386872 0.0%
cpp/open_large 5.9 ms 5.3 ms -9.0% 5304 5296 -0.2%
cpp/jump_to_end_large 36.5 ms 36.0 ms -1.2% 63503 63506 0.0%
cpp/type_while_catching_up_large 685 µs 674 µs -1.6% 139 139 0.0%
cpp/edit_top_view_end_large 1.2 ms 1.2 ms -1.2% 4347 4347 0.0%
python/redraw 236 µs 240 µs +1.9% 37 37 0.0%
python/cursor_down 252 µs 246 µs -2.6% 38 38 0.0%
python/page_down 1.7 ms 1.7 ms -0.2% 3430 3430 0.0%
python/wheel_scroll 493 µs 493 µs 0.0% 1831 1831 0.0%
python/type_and_delete 492 µs 493 µs +0.3% 113 113 0.0%
python/open_large_first 7.8 ms 7.8 ms -0.7% 45996 45997 0.0%
python/open_large 2.3 ms 2.4 ms +6.9% 3623 3623 0.0%
python/jump_to_end_large 9.8 ms 10.0 ms +2.6% 12857 12858 0.0%
python/edit_top_view_end_large 1.1 ms 1.2 ms +9.8% 4261 4262 0.0%
Benchmark Base allocated bytes PR allocated bytes Change
go/redraw 1587 B 1587 B 0.0%
go/cursor_down 1659 B 1659 B 0.0%
go/page_down 341137 B 340832 B -0.1%
go/wheel_scroll 111926 B 111926 B 0.0%
go/type_and_delete 4803 B 4803 B 0.0%
go/open_large_first 5.8 MiB 5.8 MiB +0.1%
go/open_large 455435 B 455444 B 0.0%
go/jump_to_end_large 1.5 MiB 1.5 MiB 0.0%
go/redraw_git_changes_large 12675 B 12675 B 0.0%
go/wheel_scroll_git_changes_large 123582 B 123531 B 0.0%
go/type_and_delete_git_changes_large 28792 B 28792 B 0.0%
go/edit_top_view_end_large 134977 B 134870 B -0.1%
ts/redraw 1859 B 1859 B 0.0%
ts/cursor_down 1793 B 1793 B 0.0%
ts/page_down 1.3 MiB 1.3 MiB 0.0%
ts/wheel_scroll 1.0 MiB 1.0 MiB -0.1%
ts/type_and_delete 6590 B 6590 B 0.0%
ts/open_large_first 19.7 MiB 19.7 MiB +0.1%
ts/open_large 517446 B 518137 B +0.1%
ts/jump_to_end_large 6.0 MiB 6.0 MiB 0.0%
ts/edit_top_view_end_large 166972 B 166963 B 0.0%
cpp/redraw 1616 B 1616 B 0.0%
cpp/cursor_down 1688 B 1688 B 0.0%
cpp/page_down 876344 B 876257 B 0.0%
cpp/wheel_scroll 155270 B 155718 B +0.3%
cpp/type_and_delete 5577 B 5568 B -0.2%
cpp/open_large_first 149.5 MiB 149.4 MiB 0.0%
cpp/open_large 719116 B 702264 B -2.3%
cpp/jump_to_end_large 8.5 MiB 8.5 MiB +0.1%
cpp/type_while_catching_up_large 9652 B 9652 B 0.0%
cpp/edit_top_view_end_large 254126 B 254126 B 0.0%
python/redraw 1856 B 1856 B 0.0%
python/cursor_down 1732 B 1732 B 0.0%
python/page_down 282281 B 282281 B 0.0%
python/wheel_scroll 100134 B 100134 B 0.0%
python/type_and_delete 6944 B 6944 B 0.0%
python/open_large_first 5.2 MiB 5.2 MiB +0.1%
python/open_large 516712 B 516787 B 0.0%
python/jump_to_end_large 1.3 MiB 1.3 MiB 0.0%
python/edit_top_view_end_large 210398 B 210440 B 0.0%

Diff views

Geometric-mean change: time +0.5%, allocated bytes 0.0%, allocations 0.0%.

Click here to see benchmark details
Benchmark Base PR Time change Base allocs PR allocs Allocation change
go/split/redraw 253 µs 252 µs -0.5% 43 43 0.0%
go/split/wheel_scroll 559 µs 559 µs 0.0% 2792 2792 0.0%
go/split/type_and_delete 527 µs 532 µs +0.9% 133 133 0.0%
go/split/enter_and_backspace 1.1 ms 887 µs -16.0% 2095 2095 0.0%
go/split/page_down 1.6 ms 1.5 ms -5.9% 4235 4235 0.0%
go/split/open_large 4.5 ms 4.4 ms -2.6% 15312 15313 0.0%
go/split/open_large_full_file 3.9 ms 4.0 ms +1.1% 14024 14023 0.0%
go/split/jump_to_end_large 2.0 ms 2.0 ms -2.1% 4996 4996 0.0%
go/split/expand_gap 740 µs 744 µs +0.5% 3255 3255 0.0%
go/unified/redraw 231 µs 234 µs +1.4% 38 38 0.0%
go/unified/wheel_scroll 452 µs 450 µs -0.4% 1528 1528 0.0%
go/unified/type_and_delete 478 µs 490 µs +2.5% 123 124 +0.8%
go/unified/page_down 1.4 ms 1.4 ms +0.3% 3019 3020 0.0%
go/unified/open_large 3.2 ms 3.2 ms +2.0% 12776 12775 0.0%
go/unified/open_large_full_file 3.6 ms 3.8 ms +3.6% 12645 12646 0.0%
go/unified/jump_to_end_large 1.8 ms 1.8 ms +0.6% 3276 3275 0.0%
go/unified/expand_gap 657 µs 684 µs +4.1% 1877 1877 0.0%
go/split_wrap/redraw 255 µs 255 µs 0.0% 135 135 0.0%
go/split_wrap/wheel_scroll 554 µs 578 µs +4.2% 2882 2883 0.0%
go/split_wrap/type_and_delete 721 µs 747 µs +3.6% 310 309 -0.3%
go/split_wrap/resize 1.5 ms 1.7 ms +13.7% 3879 3879 0.0%
go/unified_wrap/redraw 233 µs 243 µs +4.3% 84 84 0.0%
go/unified_wrap/wheel_scroll 457 µs 447 µs -2.0% 1575 1574 -0.1%
go/unified_wrap/resize 908 µs 916 µs +0.9% 1795 1795 0.0%
go/toggle_split_unified 329 µs 331 µs +0.6% 1608 1608 0.0%
go/switch_diff_and_file_tab 303 µs 299 µs -1.1% 1078 1078 0.0%
go/open_changes_large 4.8 ms 4.8 ms -0.5% 14973 14973 0.0%
commit_detail/open_many_files 31.9 ms 32.1 ms +0.6% 19282 19277 0.0%
commit_detail/wheel_scroll 740 µs 761 µs +2.7% 3072 3072 0.0%
Benchmark Base allocated bytes PR allocated bytes Change
go/split/redraw 2032 B 2032 B 0.0%
go/split/wheel_scroll 177462 B 177462 B 0.0%
go/split/type_and_delete 19097 B 19097 B 0.0%
go/split/enter_and_backspace 162342 B 162336 B 0.0%
go/split/page_down 380404 B 380408 B 0.0%
go/split/open_large 2.3 MiB 2.3 MiB 0.0%
go/split/open_large_full_file 2.8 MiB 2.8 MiB 0.0%
go/split/jump_to_end_large 384707 B 384664 B 0.0%
go/split/expand_gap 562478 B 562521 B 0.0%
go/unified/redraw 1888 B 1888 B 0.0%
go/unified/wheel_scroll 112328 B 112267 B -0.1%
go/unified/type_and_delete 18809 B 18844 B +0.2%
go/unified/page_down 335712 B 335715 B 0.0%
go/unified/open_large 2.0 MiB 2.0 MiB 0.0%
go/unified/open_large_full_file 2.7 MiB 2.7 MiB -0.3%
go/unified/jump_to_end_large 300612 B 300715 B 0.0%
go/unified/expand_gap 411248 B 411172 B 0.0%
go/split_wrap/redraw 2768 B 2768 B 0.0%
go/split_wrap/wheel_scroll 178185 B 178236 B 0.0%
go/split_wrap/type_and_delete 263276 B 263241 B 0.0%
go/split_wrap/resize 2.1 MiB 2.1 MiB 0.0%
go/unified_wrap/redraw 2256 B 2256 B 0.0%
go/unified_wrap/wheel_scroll 112760 B 112638 B -0.1%
go/unified_wrap/resize 1.4 MiB 1.4 MiB 0.0%
go/toggle_split_unified 75670 B 75670 B 0.0%
go/switch_diff_and_file_tab 48675 B 48675 B 0.0%
go/open_changes_large 2.7 MiB 2.7 MiB 0.0%
commit_detail/open_many_files 4.2 MiB 4.2 MiB 0.0%
commit_detail/wheel_scroll 331208 B 331172 B 0.0%

Log files

Geometric-mean change: time -0.9%, peak RSS 0.0%.

Click here to see benchmark details
Benchmark Base PR Time change Base peak RSS PR peak RSS Peak RSS change
1MiB 61.8 ms 64.3 ms +3.9% 26.6 MiB 26.5 MiB -0.4%
128MiB 156.4 ms 150.5 ms -3.8% 171.4 MiB 171.2 MiB -0.1%
256MiB 239.0 ms 238.1 ms -0.4% 315.2 MiB 315.5 MiB +0.1%
1MiB_wrap 70.5 ms 69.2 ms -1.8% 28.2 MiB 28.1 MiB -0.3%
128MiB_wrap 152.6 ms 146.9 ms -3.7% 171.3 MiB 171.4 MiB +0.1%
256MiB_wrap 241.8 ms 240.0 ms -0.7% 315.4 MiB 315.1 MiB -0.1%
128MiB_edit 1834.3 ms 1839.6 ms +0.3% 460.8 MiB 464.7 MiB +0.8%

Code files

Geometric-mean change: time +1.2%, peak RSS -1.0%.

Click here to see benchmark details
Benchmark Base PR Time change Base peak RSS PR peak RSS Peak RSS change
64MiB 281.8 ms 292.0 ms +3.6% 243.9 MiB 237.0 MiB -2.8%
64MiB_type 1512.2 ms 1538.0 ms +1.7% 253.0 MiB 253.0 MiB 0.0%
64MiB_enter 1243.3 ms 1222.5 ms -1.7% 291.0 MiB 290.8 MiB -0.1%

Timing changes are informational because shared CI runners are noisy; a benchmark error still fails the job.

@github-actions

Copy link
Copy Markdown
Contributor

Binary size

Comparing adfa9e9109e0 (base) with 794b6cb7b260 (PR). Threshold: 256 KB.

Target Base PR Delta %
linux/amd64 18.67 MB 18.67 MB +0 KB 0.0%
darwin/amd64 19.08 MB 19.08 MB +0 KB 0.0%
darwin/arm64 17.85 MB 17.85 MB +0 KB 0.0%
windows/amd64 19.19 MB 19.19 MB +0 KB 0.0%

@eugenioenko
eugenioenko merged commit 6c25a0e into main Nov 15, 2026
33 of 34 checks passed
@eugenioenko
eugenioenko deleted the fix/submenu-row-alignment branch November 15, 2026 04:28
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