Skip to content

feat: Windows Terminal-like new-tab profile dropdown - #38

Merged
mizu-jun merged 1 commit into
masterfrom
feat/new-tab-profile-dropdown
Jul 29, 2026
Merged

feat: Windows Terminal-like new-tab profile dropdown#38
mizu-jun merged 1 commit into
masterfrom
feat/new-tab-profile-dropdown

Conversation

@mizu-jun

Copy link
Copy Markdown
Owner

Summary

First phase (P1) of the Windows-Terminal-like UX plan (docs/plans/2026-07-29-windows-terminal-like-ux.md): a button next to the tab-bar + opens a dropdown listing the configured [[profiles]] and the WSL distros detected at startup. Selecting an entry opens a new tab running that profile's shell, working directory, and environment.

What was broken before

The context-menu profile entries (OpenProfile) were a stub: they sent a plain SplitVertical and only logged the profile's shell. Profiles' shell / working_dir / env were never wired into PTY spawn.

Changes

  • proto: new ClientToServer::SplitWithShell { program, args, cwd, env } appended at the enum tail; PROTOCOL_VERSION 10 → 11 (postcard tags variants positionally). Round-trip tests for minimal/full payloads.
  • server: Pane::spawn_with_options applies extra env via CommandBuilder::env; Window::add_pane_with_options accepts a cwd override (falls back to the existing parent-CWD inheritance); handle_split_with threads the override through the existing split path (hooks / auto-log / layout broadcast unchanged). The now-unused add_pane wrapper was removed.
  • client: OpenProfile resolves the profile (config profiles first, then cached WSL distros) via the pure split_message_for_profile helper. cwd/env-only profiles run the session default shell in that directory; env is sorted for determinism.
  • client UI: ContextMenu::new_tab_dropdown reuses the existing context-menu rendering/hover/click machinery; the pill is drawn right of + with a per-frame hit rect; WSL detection runs once at startup (CREATE_NO_WINDOW already in place, no console flash).
  • i18n: tab-dropdown-new-tab added to all 8 locales (non-en/ja are first-pass translations).

Test plan

  • cargo test — full workspace green (720 client / 40 proto / 273+ server; 8 new tests)
  • cargo clippy --workspace --all-targets — no new warnings (only the pre-existing question_mark allowance)
  • cargo fmt --check
  • Desktop smoke test (Windows): opens the dropdown under the tab bar; a [[profiles]] entry with shell/working_dir spawns correctly; WSL distros listed and launch via wsl.exe -d; right-click profile entries now actually launch the profile shell
  • Desktop smoke test (Linux/macOS): dropdown shows configured profiles only (no WSL); glyph renders with the bundled font fallbacks

Compatibility

PROTOCOL_VERSION bump: the single-binary nexterm ships both halves, so upgrades are atomic for normal users. Standalone nexterm-server deployments must update server and clients together (the server drops mismatched connections during Hello, per the existing versioning contract).

🤖 Generated with Claude Code

Add a `▾` button next to the tab-bar `+` that opens a dropdown listing
the configured [[profiles]] and WSL distros detected at startup, so a
new tab can be opened directly with a specific shell / cwd / env —
matching the Windows Terminal new-tab UX.

- proto: new `ClientToServer::SplitWithShell { program, args, cwd, env }`
  appended at the enum tail; PROTOCOL_VERSION 10 -> 11 (postcard tags
  variants positionally). Postcard round-trip tests included.
- server: `Pane::spawn_with_options` gains extra-env support (applied via
  `CommandBuilder::env`); `Window::add_pane_with_options` takes a cwd
  override falling back to parent-CWD inheritance; `handle_split_with`
  threads the override through the existing split path. The unused
  `add_pane` wrapper is removed.
- client: fix the `OpenProfile` context-menu stub that only sent a plain
  `SplitVertical` and logged — it now resolves the profile (config
  profiles first, then cached WSL distros) via the pure
  `split_message_for_profile` helper (falls back to the session default
  shell for cwd/env-only profiles; env sorted for determinism).
- client UI: `ContextMenu::new_tab_dropdown` constructor reusing the
  existing menu rendering/hit-testing; `▾` pill drawn right of `+` with
  a per-frame `new_tab_dropdown_hit_rect`; WSL distros cached once at
  startup in `ClientState.wsl_profiles`.
- i18n: new `tab-dropdown-new-tab` key in all 8 locales.

Tests: 6 new unit tests (menus) + 2 proto round-trips; full suite green
(cargo test / clippy -D warnings with the existing question_mark
allowance / fmt).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@github-actions

Copy link
Copy Markdown

Coverage report


Generated by cargo llvm-cov (workspace minus nexterm-client-gpu and nexterm-i18n).

@mizu-jun
mizu-jun merged commit 15daa83 into master Jul 29, 2026
12 checks passed
mizu-jun added a commit that referenced this pull request Jul 29, 2026
@mizu-jun
mizu-jun deleted the feat/new-tab-profile-dropdown branch August 29, 2026 06:35
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