mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
fix(links): open links on Ctrl+click on Windows and Linux
The link modifier was `mods.platform`, which gpui maps to ⌘ on macOS but to the Win/Super key elsewhere — a key the OS mostly swallows, so on Windows and Linux neither the hover underline nor click-to-open could be triggered at all. `config.json`'s own docs already promised "⌘/Ctrl-click"; this is the implementation catching up. Use `Modifiers::secondary()` (⌘ on macOS, Ctrl elsewhere) at all three sites: the click handler, the hover probe, and the app-level modifier tracking that pushes the state down to background panes. Not `platform || control` — that would steal ⌃-click on macOS, where it means "right click". Ctrl+click still falls through to mouse-tracking TUIs when there's no link under the cursor, since `open_link_at` reports whether it consumed the click. Fixes #183
This commit is contained in:
+2
-2
@@ -17,7 +17,7 @@
|
||||
- **Tabs & splits** — always open in the current directory
|
||||
- **Repo-grouped sidebar** — the left tab sidebar groups rows under a header per git repository, non-repo tabs in a trailing *Scratch* section; branch switches and in-repo `cd`s never move a row (`sidebar_grouping` in `config.json`: `repo` default, `none` for a flat list)
|
||||
- **Command palette** <kbd>⌘ P</kbd> · scrollback search <kbd>⌘ F</kbd>
|
||||
- **⌘-click links** · desktop notifications · copy on select (opt-in, Settings → Terminal → Clipboard)
|
||||
- **⌘/Ctrl-click links** (⌘ on macOS, Ctrl on Windows/Linux) · desktop notifications · copy on select (opt-in, Settings → Terminal → Clipboard)
|
||||
- **Smart double-click selection** — double-click grabs the whole URL, file path, bracket/quote pair, or dictionary-segmented CJK word under the cursor; Shift-click extends a selection (toggle in Settings → Terminal → Mouse; word separators via `word_separators` in `config.json`)
|
||||
- **Eight themes, plus your own** — YAML seed themes with solid, gradient, or image backgrounds; iTerm2 `.itermcolors` import; in-app color editor with a background-image picker
|
||||
- **Sync with system** — Settings → Appearance; pick separate light and dark themes and tty7 follows the OS appearance live (`theme_follow_system`, `theme_preset_light` / `theme_preset_dark` in `config.json`)
|
||||
@@ -48,7 +48,7 @@ and SFTP without shelling out to `ssh`. There is no system-ssh compat mode.
|
||||
- **`~/.ssh/config` aliases** — type one to connect (resolved natively — common fields, best-effort — over russh), or import them as profiles in Settings
|
||||
- **GUI auth** — in-pane sheets for password, key passphrase, 2FA, and host-key confirmation (new vs. changed)
|
||||
- **Built-in SFTP** — a slide-in file panel: browse, upload / download, rename / delete / chmod, drag to Finder
|
||||
- **Port forwarding** — Local / Remote / Dynamic, preconfigured or added live, plus ⌘-click `localhost:PORT` to auto-forward
|
||||
- **Port forwarding** — Local / Remote / Dynamic, preconfigured or added live, plus ⌘/Ctrl-click `localhost:PORT` to auto-forward
|
||||
- **Jump hosts & proxies** — multi-hop via profile references or `ProxyJump`, ProxyCommand, SOCKS5 / HTTP
|
||||
|
||||
| Entry point | Connects via |
|
||||
|
||||
@@ -1189,8 +1189,11 @@ impl TerminalElement {
|
||||
let button = ev.button;
|
||||
let clicks = ev.click_count;
|
||||
view.update(cx, |v, cx| {
|
||||
// Cmd+click opens a URL under the cursor.
|
||||
let link_modifier = mods.platform || v.link_modifier_down();
|
||||
// Secondary+click (⌘ on macOS, Ctrl on Windows/Linux) opens a
|
||||
// URL under the cursor. Not the raw platform key: that's Win/
|
||||
// Super off macOS, which the OS mostly swallows — and every
|
||||
// other terminal there opens links on Ctrl+click.
|
||||
let link_modifier = mods.secondary() || v.link_modifier_down();
|
||||
if link_modifier && button == MouseButton::Left && v.open_link_at(col, row, cx) {
|
||||
return;
|
||||
}
|
||||
@@ -1244,7 +1247,7 @@ impl TerminalElement {
|
||||
if !mods.shift {
|
||||
v.mouse_motion(col, row, &mods);
|
||||
}
|
||||
let include_files = mods.platform || v.link_modifier_down();
|
||||
let include_files = mods.secondary() || v.link_modifier_down();
|
||||
v.hover_link_at(col, row, include_files, cx);
|
||||
} else {
|
||||
v.clear_hovered_link(cx);
|
||||
|
||||
+3
-2
@@ -44,7 +44,7 @@ impl Tty7App {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let m = &ev.modifiers;
|
||||
self.set_link_modifier(m.platform, cx);
|
||||
self.set_link_modifier(m.secondary(), cx);
|
||||
|
||||
// Mirror `on_key_down`'s chord test: reject the other platform-ish key
|
||||
// (⌃ on macOS, Win/Super elsewhere), Alt, and Shift, so only the bare
|
||||
@@ -79,7 +79,8 @@ impl Tty7App {
|
||||
.detach();
|
||||
}
|
||||
|
||||
/// Push the platform-modifier state down to every pane's link tracking.
|
||||
/// Push the secondary-modifier state (⌘ on macOS, Ctrl elsewhere — the
|
||||
/// same key that opens a link on click) down to every pane's link tracking.
|
||||
/// Every tab, not just the active one: `on_modifiers_changed` only fires on
|
||||
/// the frontmost window state, so a background tab that saw "⌘ down" but
|
||||
/// never the matching release would keep a stale `true` — and a stale
|
||||
|
||||
+16
-5
@@ -467,7 +467,7 @@ pub(crate) struct SettingsState {
|
||||
pub(crate) shell_args_input: Entity<InputState>,
|
||||
/// Custom working-directory path (used when the strategy is `Custom`).
|
||||
pub(crate) wd_path_input: Entity<InputState>,
|
||||
/// Command template run when ⌘-clicking a file link (Links section). Empty
|
||||
/// Command template run when ⌘/Ctrl-clicking a file link (Links section). Empty
|
||||
/// clears the override, restoring the built-in "open in default app".
|
||||
pub(crate) link_file_command_input: Entity<InputState>,
|
||||
/// Mouse-scroll multiplier slider (Terminal section).
|
||||
@@ -622,6 +622,14 @@ pub(crate) struct Recording {
|
||||
/// unlikely real font name.
|
||||
pub(crate) const FONT_DEFAULT_LABEL: &str = "Default (match primary)";
|
||||
|
||||
/// How the link-click modifier is spelled in the Links copy. It's gpui's
|
||||
/// `secondary` (see `Modifiers::secondary`), so it must read ⌘ on macOS and
|
||||
/// Ctrl on Windows/Linux — same split `key_tokens` uses for keycaps.
|
||||
#[cfg(target_os = "macos")]
|
||||
const LINK_MODIFIER_LABEL: &str = "⌘";
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const LINK_MODIFIER_LABEL: &str = "Ctrl";
|
||||
|
||||
/// Humanize a CamelCase action name for display: "CloseActiveTab" → "Close
|
||||
/// Active Tab".
|
||||
pub(crate) fn humanize_action(action: &str) -> String {
|
||||
@@ -3093,7 +3101,7 @@ impl Tty7App {
|
||||
.child(self.section_header("Links", cx))
|
||||
.child(self.settings_row(
|
||||
"Detect URLs",
|
||||
"Underline links on hover and open them on ⌘-click.",
|
||||
format!("Underline links on hover and open them on {LINK_MODIFIER_LABEL}-click."),
|
||||
link_switch,
|
||||
cx,
|
||||
))
|
||||
@@ -3105,9 +3113,12 @@ impl Tty7App {
|
||||
))
|
||||
.child(self.settings_row(
|
||||
"Open files with",
|
||||
"Command run when ⌘-clicking a file link, instead of the default app. \
|
||||
Use {path}, {line}, {column}; a flag whose value is absent is dropped \
|
||||
(e.g. herdr edit {path} --line={line}). Empty uses the default app.",
|
||||
format!(
|
||||
"Command run when {LINK_MODIFIER_LABEL}-clicking a file link, instead of \
|
||||
the default app. Use {{path}}, {{line}}, {{column}}; a flag whose value \
|
||||
is absent is dropped (e.g. herdr edit {{path}} --line={{line}}). Empty \
|
||||
uses the default app."
|
||||
),
|
||||
link_file_command_control,
|
||||
cx,
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user