SpawnTab on a not-yet-attached SSH domain implicitly attaches it,
which spawns a default tab, then the explicit SpawnTab adds another,
resulting in two du5t tabs. Use AttachDomain instead, which attaches
and ensures a single tab without duplicating it.
Right button had no default binding, so plain right-click did nothing.
Added mods="NONE" -> PasteFrom("Clipboard"). Full-screen apps that
enable mouse reporting (e.g. Claude Code's TUI) swallow unmodified
clicks before they reach wezterm, so also bound the same paste action
to mods="SHIFT", which wezterm always treats as a local override
regardless of the app's mouse capture. Kept the existing Ctrl+Shift
binding for compatibility.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Purely cosmetic: prefixes each InputSelector choice label (main menu,
settings, font/connection/other settings, SSH domain edit list, font
picker's manual-entry fallback) with a representative emoji so the
menus are easier to scan at a glance.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Synced font, font_size, and ssh_domains to match the user's real
.wezterm.lua (compared with CRLF stripped, since the live file uses
Windows line endings): Korean font is "Noto Sans KR" (not the CJK
variant), font_size is 9, and the du5t SSH domain (172.30.1.41:228,
user gm, multiplexing = "None") is now a real default entry instead of
a commented-out example.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both the 0.5s and 2s wezterm.time.call_after delays in gui-startup
still hit "domain name du5t is invalid" -- guessing a fixed delay for
mux domain registration isn't reliable. Moved the auto-connect attempt
into update-right-status, which only starts firing once the window is
actually up and rendering (well past the registration race), and made
it generic: it looks at config.ssh_domains[1] instead of hardcoding
"du5t", so it auto-connects to whatever SSH domain happens to be
registered, or does nothing if none are configured. Runs exactly once
per session via startup_ssh_connect_tried.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Gives ssh_domains more time to finish registering in the mux before
the du5t tab spawn is attempted.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Setting domain = { DomainName = "du5t" } directly in gui-startup's
spawn_window failed with "domain name du5t is invalid" -- at the
moment gui-startup fires, WezTerm hasn't finished registering
ssh_domains into the mux yet, so the very first spawn always races
against domain registration regardless of restarting the app.
Now the initial window spawns on the local domain as before (always
available), and half a second later a new tab is spawned against the
du5t domain and activated -- by then domain registration should be
complete. The local tab remains as tab 1, a safety net if the SSH
connection fails for any reason.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
gui-startup now spawns the initial window's pane against the du5t
ssh_domains entry (domain = { DomainName = "du5t" }) instead of the
default local domain, so the first pane is already connected instead
of showing a local cmd shell. The main menu still pops up on top as
before.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Plain double-click is already the word-selection gesture inside a
pane, so binding the new-window action there would break normal text
selection. Reusing the Ctrl+Shift modifier convention already proven
to work for the menu-open binding avoids that collision.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Dropped the "☰ Menu" / "Ctrl+Shift+Click / Ctrl+a m" left-status
text per request; the menu still opens the same way, it's just no
longer labeled in the tab bar.
- Dragging a tab out of the fancy tab bar to pop it into its own
window turned out not to work reliably on this WezTerm build.
Replaced that expectation with an explicit Leader+Enter keybinding
that calls pane:move_to_new_window() (documented mux Pane method),
a scripted equivalent that doesn't depend on the drag gesture.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
wezterm ls-fonts --list-system's real output is a ready-to-paste code
snippet per font (`wezterm.font("Name", {weight=...}) -- (AKA: ...)
path, DirectWrite`), not a bare quoted family name. The picker's
fallback branch treated any non-matching line as a literal font name,
so selecting one of these snippet entries wrote its full text --
including a literal "})" substring from the embedded example call --
into config.font, corrupting the file (confirmed against a user's
actual .wezterm.lua that failed to parse after picking a Korean font
this way).
Fixed the parser to only accept `wezterm.font("Name"` lines (or a
bare quoted string) and extract just the family name, dropping
anything else instead of guessing. Also anchored get_current_fonts and
set_fonts's block-matching patterns to require the closing "})" be on
its own line, so a stray "})" embedded inside a font value can no
longer be mistaken for the block's real end.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
wezterm ls-fonts --list-system runs synchronously and blocks the UI
thread while it walks every installed font, which happens right after
the previous menu overlay closes -- during that gap the underlying
shell was briefly visible before the font picker rendered. Caching the
parsed result means the blocking call only happens once; gui-startup
also warms the cache immediately so even the first font settings visit
in a session is instant.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
show_font_picker runs `wezterm ls-fonts --list-system` via
wezterm.run_child_process, parses out unique font family names, and
presents them through the existing fuzzy InputSelector so English/
Korean font menu entries no longer require typing an exact,
correctly-spelled font name. A "직접 입력..." choice at the top falls
back to the previous free-text prompt_font flow, also used
automatically if the font list can't be retrieved.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
window_decorations = "INTEGRATED_BUTTONS | RESIZE" drops the separate
OS title bar and draws minimize/maximize/close directly in the fancy
tab bar strip instead, now that use_fancy_tab_bar is enabled.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Alt+Left-click never reached our show-main-menu binding because
WezTerm's own default mouse bindings already claim ALT+drag on a
pane as the start of rectangular/block text selection, swallowing
the click before our handler saw it. Rebound the menu trigger to
Ctrl+Shift+Left-click, which isn't claimed by any default gesture,
and updated the status bar hint text to match.
- use_fancy_tab_bar = true: the retro (lightweight) tab bar has no
per-tab close button at all; the native/OS-style bar shows a
hover close (x) button per tab and supports dragging a tab out of
the strip to pop it into its own window (the closest native
equivalent to an explicit "open in new window" button).
- format-tab-title now renders just the terminal/process name instead
of "index: name [domain]" -- shorter titles leave the native tab
bar's close button room to render, and per-host color-coding already
conveys the domain without needing it spelled out in text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
notify() now accepts an optional duration override; the SSH domain
save/update toasts use it to stay up 10s (vs the default 4s) and lead
with a bold warning that connecting immediately will fail and
wezterm-gui.exe needs a full restart (Task Manager End Task, not just
reload) before the new/edited domain is usable.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
config.font is set via wezterm.font_with_fallback({ primary, korean }),
a multi-line block that the existing single-line set_config_value
can't touch. Added get_current_fonts (reads both font names straight
out of the config file text, for display) and set_fonts (replaces the
whole font_with_fallback body in one shot, lazy-matched between the
"{" and the closing "})"), plus two new font settings menu entries
("영어 폰트" / "한글 폰트") that prompt for one name at a time while
keeping the other font unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Without it, WezTerm tries to run its own mux protocol over the SSH
session (spawning `wezterm cli --prefer-mux proxy` on the remote),
which fails with "Please install the same version of wezterm on both
the client and server" whenever the remote host doesn't have wezterm
installed -- the case for a plain SSH target. multiplexing = "None"
makes the domain behave like a normal SSH terminal instead.
update_ssh_domain's match pattern is now a lazy "match to the next
closing brace" instead of assuming an exact 3-field shape, so it can
still find and replace entries saved before this change (without the
multiplexing field) as well as ones saved after.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- SSH domain add flow gains a 4th, optional "port" step; a non-empty
port is appended to remote_address as "host:port" (WezTerm's native
way to specify a non-default SSH port), matching how existing
entries are parsed back out via the new split_remote_address helper.
- New "SSH 도메인 수정" entry in connection settings lists existing
config.ssh_domains entries; picking one re-prompts each field
(name/address/port/username) with the current value shown in the
description, where leaving a field blank keeps the old value instead
of cancelling (unlike the add flow, where blank cancels).
- update_ssh_domain locates the exact entry block by its original name
(pattern built from append_ssh_domain's fixed write format, escaped
for Lua pattern safety) and replaces it wholesale, so a rename is
just "old name matched, new block written".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
config.ssh_domains is only registered into wezterm's mux domain list
at process startup; ReloadConfiguration picks up simple value changes
(font, colors, etc.) but does not re-register newly added ssh domains.
Selecting a freshly-saved domain from the main menu before a full
restart fails with "domain name ... is invalid" since it's absent
from the mux's domain list. Updated the save notification to tell the
user a restart (not just reload) is required.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Main menu now lists each registered config.ssh_domains entry as a
choice (selecting one spawns a tab attached to that SSH domain via
SpawnTab), with a single "설정" entry below them that opens what used
to be the main menu (font/connection/other settings, launcher,
reload) -- renamed to show_settings_menu.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The real bug was the invalid initial_value field (fixed previously),
not Enter bleed-through from InputSelector. The defer-via-status-tick
workaround left a gap (up to the status update interval) between the
InputSelector closing and the PromptInputLine actually capturing
keyboard input -- during that gap the underlying shell was visible
(the reported flash) and any keystrokes typed during it went to the
shell instead of the field. This is especially damaging for the
3-step SSH domain flow, where hitting the gap on any step submits an
empty line and the whole entry is silently cancelled without saving.
Calling perform_action synchronously, as before the call_after/defer
detour, removes the gap entirely.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The user's WezTerm build (20240203-110809) rejects `initial_value` as a
PromptInputLine field (only `action`/`description` are valid on that
version), so constructing the action errored out immediately and the
whole callback died silently -- the prompt never appeared and the
underlying shell showed through. Current values are now shown inline
in the description text instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Deferring the PromptInputLine open by one tick via wezterm.time.call_after
did not fix the InputSelector -> PromptInputLine chaining issue on the
user's WezTerm build (the box never appeared at all, straight back to the
shell) — consistent with call_after being unavailable/erroring and silently
aborting the callback. Replaced it with a pending_action flag drained on the
next update-right-status tick, an event hook already confirmed working via
the existing status bar, removing the dependency on wezterm.time entirely.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Selecting a settings item from an InputSelector menu (font size, line height,
color scheme, opacity, scrollback lines, max FPS, SSH domain add) would open
a PromptInputLine that closed instantly, dumping back to the shell — the
Enter that confirmed the InputSelector choice was bleeding into the newly
opened PromptInputLine. Deferring the PromptInputLine open by one tick via
wezterm.time.call_after fixes it. SSH domain registration now asks for name,
address, and username one at a time instead of a single comma-separated line.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>