From a6f2fee4ff23ca3c89ff8a75bc5ead990d9423e1 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Mon, 27 Jul 2026 16:17:47 -0700 Subject: [PATCH] fix(browser): make link-routing modifier copy true in every state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review follow-ups on the Shift-inverts-routing change. - The nested row promised "⇧⌘+click opens one in Orca" in the present tense while its own toggle was off, so the out-of-box state described behavior the user did not have. Phrase it as enabled-state copy, matching sibling rows. - The parent Link Routing description gained "opens a link the other way", which is false in the default state and contradicts the child row when inverting is on. No fixed sentence there is true in every state, so the child row — which knows the live destination — now owns the claim. That leaves getBrowserLinkRoutingShortcutLabel unused, so drop it. - The rich markdown editor still forced the system browser while the preview of the same file honored the modifier, so one link routed two ways depending on which view it was clicked in. - A remote runtime pins every link to the system browser, so the hover hint could promise Orca for a click that lands elsewhere. Gate the hint on the same condition openHttpLink uses. - Index both modifier titles: the search entry is built with openLinksInApp false, so the row was unfindable by the title it renders when routing is on. - Drop the ariaLabel that shared no words with the visible label (WCAG 2.5.3) and add the four missing settings-search keyword keys to all five catalogs. --- .../rich-markdown-editor-click-routing.ts | 7 ++- .../BrowserLinkRoutingModifierSetting.tsx | 5 -- .../src/components/settings/BrowserPane.tsx | 2 +- .../browser-link-routing-modifier-copy.ts | 7 ++- .../settings/browser-search.test.ts | 49 +++++++++++-------- .../src/components/settings/browser-search.ts | 21 ++++---- .../terminal-link-open-hints.test.ts | 44 ++++++++++++++++- .../terminal-pane/terminal-link-open-hints.ts | 20 ++++++++ .../use-terminal-pane-lifecycle.ts | 6 +-- src/renderer/src/i18n/locales/en.json | 9 +++- src/renderer/src/i18n/locales/es.json | 9 +++- src/renderer/src/i18n/locales/ja.json | 9 +++- src/renderer/src/i18n/locales/ko.json | 9 +++- src/renderer/src/i18n/locales/zh.json | 9 +++- .../pane-manager/pane-dom-creation.test.ts | 23 +++++++++ 15 files changed, 174 insertions(+), 55 deletions(-) diff --git a/src/renderer/src/components/editor/rich-markdown-editor-click-routing.ts b/src/renderer/src/components/editor/rich-markdown-editor-click-routing.ts index 4c0f0ca967c..87289fbdbbd 100644 --- a/src/renderer/src/components/editor/rich-markdown-editor-click-routing.ts +++ b/src/renderer/src/components/editor/rich-markdown-editor-click-routing.ts @@ -129,6 +129,7 @@ export function handleRichMarkdownEditorClick({ runtimeEnvironmentId, sourceOwner, settings, + worktreeId, worktreeRoot }) return true @@ -184,6 +185,7 @@ function getClickedLinkHref(view: EditorView, pos: number): string { function openMarkdownLinkInClientOs({ href, filePath, + worktreeId, worktreeRoot, runtimeEnvironmentId, sourceOwner, @@ -191,6 +193,7 @@ function openMarkdownLinkInClientOs({ }: { href: string filePath: string + worktreeId: string worktreeRoot: string | null runtimeEnvironmentId?: string | null sourceOwner: HttpLinkSourceOwner @@ -204,7 +207,9 @@ function openMarkdownLinkInClientOs({ return } if (classified.kind === 'external') { - openHttpLink(classified.url, { forceSystemBrowser: true, sourceOwner }) + // Why: same escape hatch as the markdown preview of this very file — routing must + // not depend on which of the two views the link was clicked in. + openHttpLink(classified.url, { worktreeId, modifierHeld: true, sourceOwner }) return } if (classified.kind === 'anchor') { diff --git a/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx b/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx index 106054a9d6a..aeb8f4151d8 100644 --- a/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx +++ b/src/renderer/src/components/settings/BrowserLinkRoutingModifierSetting.tsx @@ -1,5 +1,4 @@ import type { GlobalSettings } from '../../../../shared/types' -import { translate } from '@/i18n/i18n' import { SearchableSetting } from './SearchableSetting' import { SettingsSwitchRow } from './SettingsFormControls' import { @@ -48,10 +47,6 @@ export function BrowserLinkRoutingModifierSetting({ openLinksInAppModifierInverts: settings.openLinksInAppModifierInverts !== true }) } - ariaLabel={translate( - 'auto.components.settings.BrowserLinkRoutingModifierSetting.toggleLabel', - 'Toggle inverted link routing modifier' - )} /> diff --git a/src/renderer/src/components/settings/BrowserPane.tsx b/src/renderer/src/components/settings/BrowserPane.tsx index c030cffd912..716393a4953 100644 --- a/src/renderer/src/components/settings/BrowserPane.tsx +++ b/src/renderer/src/components/settings/BrowserPane.tsx @@ -107,7 +107,7 @@ export function BrowserPane({ const showCookies = matchesSettingsSearch(searchQuery, [getBrowserPaneSearchEntries()[6]]) const showBrowserUse = matchesSettingsSearch(searchQuery, getBrowserUsePaneSearchEntries()) const isMac = isMacUserAgent() - const linkRoutingDescription = getBrowserLinkRoutingDescription({ isMac }) + const linkRoutingDescription = getBrowserLinkRoutingDescription() const hostLabelOverrides = useMemo(() => getHostDisplayLabelOverrides(settings), [settings]) const browserSessionHostOptions = useMemo( () => diff --git a/src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts b/src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts index b8f6e188c48..1151d3e70e1 100644 --- a/src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts +++ b/src/renderer/src/components/settings/browser-link-routing-modifier-copy.ts @@ -3,7 +3,8 @@ import { translate } from '@/i18n/i18n' /** * Title and description both name the destination the modifier reaches, which is * the opposite of wherever Link Routing points. Kept out of the component so the - * settings-search index and the component render identical strings. + * settings-search index can reuse the same strings; the index pins openLinksInApp + * to false, so it also indexes the other title as a keyword. */ export function getLinkRoutingModifierTitle(openLinksInApp: boolean): string { return openLinksInApp @@ -17,6 +18,8 @@ export function getLinkRoutingModifierTitle(openLinksInApp: boolean): string { ) } +// Why: the Orca branch is enabled-state copy — with the toggle off the chord +// still lands on the system browser, so it must not promise Orca in present tense. export function getLinkRoutingModifierDescription({ openLinksInApp, isMac @@ -33,7 +36,7 @@ export function getLinkRoutingModifierDescription({ ) : translate( 'auto.components.settings.BrowserLinkRoutingModifierSetting.descriptionOrca', - "Links open in your system browser, so {{chord}}+click opens one in Orca's built-in browser instead.", + "Links open in your system browser. When enabled, {{chord}}+click opens one in Orca's built-in browser instead.", { chord } ) } diff --git a/src/renderer/src/components/settings/browser-search.test.ts b/src/renderer/src/components/settings/browser-search.test.ts index 6eaa408e93b..cd53de69030 100644 --- a/src/renderer/src/components/settings/browser-search.test.ts +++ b/src/renderer/src/components/settings/browser-search.test.ts @@ -1,26 +1,16 @@ import { describe, expect, it } from 'vitest' -import { - getBrowserLinkRoutingDescription, - getBrowserLinkRoutingShortcutLabel, - getBrowserPaneSearchEntries -} from './browser-search' +import { getBrowserLinkRoutingDescription, getBrowserPaneSearchEntries } from './browser-search' import { getLinkRoutingModifierDescription, getLinkRoutingModifierTitle } from './browser-link-routing-modifier-copy' describe('browser settings search copy', () => { - it('uses macOS shortcut symbols for Link Routing copy and search metadata', () => { - expect(getBrowserLinkRoutingShortcutLabel({ isMac: true })).toBe('⇧⌘-click') - - const description = getBrowserLinkRoutingDescription({ isMac: true }) - expect(description).toContain('⇧⌘-click') - expect(description).not.toContain('Cmd/Ctrl') - + it('uses macOS shortcut keywords for Link Routing search metadata', () => { const linkRoutingEntry = getBrowserPaneSearchEntries({ isMac: true }).find( (entry) => entry.title === 'Link Routing' ) - expect(linkRoutingEntry?.description).toBe(description) + expect(linkRoutingEntry?.description).toBe(getBrowserLinkRoutingDescription()) expect(linkRoutingEntry?.keywords).toContain('cmd') expect(linkRoutingEntry?.keywords).not.toContain('ctrl') @@ -30,20 +20,22 @@ describe('browser settings search copy', () => { expect(defaultZoomEntry?.keywords).toContain('zoom') }) - it('uses Ctrl shortcut text for Link Routing copy and search metadata off macOS', () => { - expect(getBrowserLinkRoutingShortcutLabel({ isMac: false })).toBe('Shift+Ctrl+click') - - const description = getBrowserLinkRoutingDescription({ isMac: false }) - expect(description).toContain('Shift+Ctrl+click') - expect(description).not.toContain('Cmd/Ctrl') - + it('uses Ctrl shortcut keywords for Link Routing search metadata off macOS', () => { const linkRoutingEntry = getBrowserPaneSearchEntries({ isMac: false }).find( (entry) => entry.title === 'Link Routing' ) - expect(linkRoutingEntry?.description).toBe(description) + expect(linkRoutingEntry?.description).toBe(getBrowserLinkRoutingDescription()) expect(linkRoutingEntry?.keywords).toContain('ctrl') expect(linkRoutingEntry?.keywords).not.toContain('cmd') }) + + // Why: the modifier can now invert, so no fixed sentence here is true in every + // state — the nested row owns that claim and states the live destination. + it('leaves the modifier claim to the nested row', () => { + const description = getBrowserLinkRoutingDescription() + expect(description).not.toContain('click') + expect(description).not.toContain('system browser') + }) }) describe('browser link routing modifier copy', () => { @@ -83,4 +75,19 @@ describe('browser link routing modifier copy', () => { 'system browser' ) }) + + // Why: the toggle is off by default, so present-tense "opens one in Orca" would + // describe behavior the user does not have yet. + it('phrases the Orca branch as enabled-state copy', () => { + expect(getLinkRoutingModifierDescription({ openLinksInApp: false, isMac: true })).toContain( + 'When enabled' + ) + }) + + // Why: the entry is built with openLinksInApp false, so without this the row is + // unfindable by the title it actually renders when Link Routing is on. + it('indexes both titles so the row is findable in either routing state', () => { + const entry = getBrowserPaneSearchEntries({ isMac: true })[4] + expect(entry?.keywords).toContain(getLinkRoutingModifierTitle(true)) + }) }) diff --git a/src/renderer/src/components/settings/browser-search.ts b/src/renderer/src/components/settings/browser-search.ts index f34fdb8a6de..8e656ca3cbb 100644 --- a/src/renderer/src/components/settings/browser-search.ts +++ b/src/renderer/src/components/settings/browser-search.ts @@ -16,15 +16,13 @@ function getDefaultBrowserShortcutPlatform(): BrowserShortcutPlatform { } } -export function getBrowserLinkRoutingShortcutLabel(platform: BrowserShortcutPlatform): string { - return platform.isMac ? '⇧⌘-click' : 'Shift+Ctrl+click' -} - -// Why: the modifier sentence moved to the nested "Hold Shift to open in …" row — -// once that row can invert the routing, "always uses your system browser" is no -// longer true, and the child row states the live destination instead. -export function getBrowserLinkRoutingDescription(platform: BrowserShortcutPlatform): string { - return `Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor. ${getBrowserLinkRoutingShortcutLabel(platform)} opens a link the other way.` +// Why: the modifier sentence moved to the nested "Hold Shift to open in …" row. +// Once that row can invert the routing, no single sentence here is true in every +// state — "always uses your system browser" breaks when inverting is on, and +// "opens a link the other way" breaks in the default state where it is off. The +// chord is now stated only by the child row, which knows the live destination. +export function getBrowserLinkRoutingDescription(): string { + return "Open http(s) links in Orca's built-in browser — from the terminal, markdown, and the editor." } export function getBrowserPaneSearchEntries( @@ -99,7 +97,7 @@ export function getBrowserPaneSearchEntries( }, { title: translate('auto.components.settings.browser.search.5cb082b3e3', 'Link Routing'), - description: getBrowserLinkRoutingDescription(platform), + description: getBrowserLinkRoutingDescription(), keywords: [ ...translateSearchKeyword('auto.components.settings.browser.search.2d2d995c58', 'browser'), ...translateSearchKeyword('auto.components.settings.browser.search.44d14df30d', 'preview'), @@ -142,6 +140,9 @@ export function getBrowserPaneSearchEntries( 'auto.components.settings.browser.search.linkRoutingModifier.opposite', 'opposite' ), + // Why: the row renders live copy but this entry is built with openLinksInApp + // false, so index the other title too or the row is unfindable by its own text. + getLinkRoutingModifierTitle(true), platform.isMac ? 'cmd' : 'ctrl' ] }, diff --git a/src/renderer/src/components/terminal-pane/terminal-link-open-hints.test.ts b/src/renderer/src/components/terminal-pane/terminal-link-open-hints.test.ts index 4d802efed52..656db8d4bfd 100644 --- a/src/renderer/src/components/terminal-pane/terminal-link-open-hints.test.ts +++ b/src/renderer/src/components/terminal-pane/terminal-link-open-hints.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { getTerminalUrlOpenHint } from './terminal-link-open-hints' +import { getTerminalUrlOpenHint, terminalUrlOpenHintOptionsFor } from './terminal-link-open-hints' function stubPlatform(isMac: boolean): void { vi.stubGlobal('navigator', { userAgent: isMac ? 'Mac OS X' : 'Windows NT 10.0' }) @@ -45,3 +45,45 @@ describe('getTerminalUrlOpenHint', () => { ) }) }) + +describe('terminalUrlOpenHintOptionsFor', () => { + it('reports inversion when links open externally on a local runtime', () => { + expect( + terminalUrlOpenHintOptionsFor({ + openLinksInApp: false, + openLinksInAppModifierInverts: true + }) + ).toEqual({ openLinksInApp: false, modifierInverts: true }) + }) + + // Why: openHttpLink refuses to route a remote-owned URL into Orca, so promising + // "open in Orca" there would advertise a click that lands somewhere else. + it('drops inversion while a remote runtime is active', () => { + stubPlatform(true) + const options = terminalUrlOpenHintOptionsFor({ + openLinksInApp: false, + openLinksInAppModifierInverts: true, + activeRuntimeEnvironmentId: 'remote-1' + }) + + expect(options.modifierInverts).toBe(false) + expect(getTerminalUrlOpenHint(options)).toContain('for system browser') + }) + + it('ignores a blank runtime id', () => { + expect( + terminalUrlOpenHintOptionsFor({ + openLinksInApp: false, + openLinksInAppModifierInverts: true, + activeRuntimeEnvironmentId: ' ' + }).modifierInverts + ).toBe(true) + }) + + it('tolerates missing settings', () => { + expect(terminalUrlOpenHintOptionsFor(null)).toEqual({ + openLinksInApp: false, + modifierInverts: false + }) + }) +}) diff --git a/src/renderer/src/components/terminal-pane/terminal-link-open-hints.ts b/src/renderer/src/components/terminal-pane/terminal-link-open-hints.ts index 3ecb4f9dbb4..6316b4b7c26 100644 --- a/src/renderer/src/components/terminal-pane/terminal-link-open-hints.ts +++ b/src/renderer/src/components/terminal-pane/terminal-link-open-hints.ts @@ -25,6 +25,26 @@ export type TerminalUrlOpenHintOptions = { modifierInverts?: boolean } +// Why: openHttpLink only routes to Orca when the source is local, so a remote runtime +// pins every link to the system browser and inverting cannot reach Orca there. +export function terminalUrlOpenHintOptionsFor( + settings: + | { + openLinksInApp?: boolean + openLinksInAppModifierInverts?: boolean + activeRuntimeEnvironmentId?: string | null + } + | null + | undefined +): TerminalUrlOpenHintOptions { + return { + openLinksInApp: settings?.openLinksInApp === true, + modifierInverts: + settings?.openLinksInAppModifierInverts === true && + !settings?.activeRuntimeEnvironmentId?.trim() + } +} + // Why: with modifierInverts on, Shift no longer always means "system browser" — // it means "the other one" — so the hint has to name the actual destination. export function getTerminalUrlOpenHint(options: TerminalUrlOpenHintOptions = {}): string { diff --git a/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts b/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts index dce481daec7..810a69dfe56 100644 --- a/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts +++ b/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts @@ -31,6 +31,7 @@ import { getTerminalUrlOpenHint, installFilePathLinkClickFallback } from './terminal-link-handlers' +import { terminalUrlOpenHintOptionsFor } from './terminal-link-open-hints' import { createTerminalHandleLinkProvider } from './terminal-handle-links' import type { LinkHandlerDeps } from './terminal-link-handlers' import { handleOscLink } from './terminal-osc-link-routing' @@ -780,10 +781,7 @@ export function useTerminalPaneLifecycle({ const fileOpenLinkHint = getTerminalFileOpenHint() // Why: read settingsRef at fire time so toggling link routing applies without recreating panes. const getUrlOpenLinkHint = (): string => - getTerminalUrlOpenHint({ - openLinksInApp: settingsRef.current?.openLinksInApp === true, - modifierInverts: settingsRef.current?.openLinksInAppModifierInverts === true - }) + getTerminalUrlOpenHint(terminalUrlOpenHintOptionsFor(settingsRef.current)) const osc7UncHost = extractUncHost(startupCwd) let releaseWebviewDragPassthrough: (() => void) | null = null diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 54d17a4b09e..c5a8248af14 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -7603,6 +7603,12 @@ "8dd4805991": "file", "68d1db8929": "markdown", "90425d313c": "shift", + "linkRoutingModifier": { + "routing": "routing", + "modifier": "modifier", + "invert": "invert", + "opposite": "opposite" + }, "72c58f7792": "webview", "82ba1c80ea": "localhost", "bea27bac4b": "links", @@ -9747,11 +9753,10 @@ "legacyHelp": "Update this server manually once to enable remote updates." }, "BrowserLinkRoutingModifierSetting": { - "toggleLabel": "Toggle inverted link routing modifier", "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", "descriptionSystem": "Links open in Orca, so {{chord}}+click sends one to your system browser instead.", - "descriptionOrca": "Links open in your system browser, so {{chord}}+click opens one in Orca's built-in browser instead." + "descriptionOrca": "Links open in your system browser. When enabled, {{chord}}+click opens one in Orca's built-in browser instead." } }, "right": { diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 7b050ab634b..90da0f05c3b 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -7543,6 +7543,12 @@ "8dd4805991": "archivo", "68d1db8929": "markdown", "90425d313c": "cambio", + "linkRoutingModifier": { + "routing": "enrutamiento", + "modifier": "modificador", + "invert": "invertir", + "opposite": "opuesto" + }, "72c58f7792": "vista web", "82ba1c80ea": "localhost", "bea27bac4b": "enlaces", @@ -9724,11 +9730,10 @@ "legacyHelp": "Update this server manually once to enable remote updates." }, "BrowserLinkRoutingModifierSetting": { - "toggleLabel": "Toggle inverted link routing modifier", "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", "descriptionSystem": "Links open in Orca, so {{chord}}+click sends one to your system browser instead.", - "descriptionOrca": "Links open in your system browser, so {{chord}}+click opens one in Orca's built-in browser instead." + "descriptionOrca": "Links open in your system browser. When enabled, {{chord}}+click opens one in Orca's built-in browser instead." } }, "right": { diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 0ddc7a69638..1a8bab0a15a 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -7565,6 +7565,12 @@ "8dd4805991": "ファイル", "68d1db8929": "markdown", "90425d313c": "シフト", + "linkRoutingModifier": { + "routing": "ルーティング", + "modifier": "修飾キー", + "invert": "反転", + "opposite": "逆" + }, "72c58f7792": "ウェブビュー", "82ba1c80ea": "ローカルホスト", "bea27bac4b": "リンク", @@ -9724,11 +9730,10 @@ "legacyHelp": "Update this server manually once to enable remote updates." }, "BrowserLinkRoutingModifierSetting": { - "toggleLabel": "Toggle inverted link routing modifier", "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", "descriptionSystem": "Links open in Orca, so {{chord}}+click sends one to your system browser instead.", - "descriptionOrca": "Links open in your system browser, so {{chord}}+click opens one in Orca's built-in browser instead." + "descriptionOrca": "Links open in your system browser. When enabled, {{chord}}+click opens one in Orca's built-in browser instead." } }, "right": { diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index 60583855af3..4039c4fd403 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -7528,6 +7528,12 @@ "8dd4805991": "파일", "68d1db8929": "markdown", "90425d313c": "Shift", + "linkRoutingModifier": { + "routing": "라우팅", + "modifier": "수정자", + "invert": "반전", + "opposite": "반대" + }, "72c58f7792": "웹뷰", "82ba1c80ea": "로컬호스트", "bea27bac4b": "링크", @@ -9724,11 +9730,10 @@ "legacyHelp": "Update this server manually once to enable remote updates." }, "BrowserLinkRoutingModifierSetting": { - "toggleLabel": "Toggle inverted link routing modifier", "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", "descriptionSystem": "Links open in Orca, so {{chord}}+click sends one to your system browser instead.", - "descriptionOrca": "Links open in your system browser, so {{chord}}+click opens one in Orca's built-in browser instead." + "descriptionOrca": "Links open in your system browser. When enabled, {{chord}}+click opens one in Orca's built-in browser instead." } }, "right": { diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index 706ae0f3483..192b53fccb8 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -7528,6 +7528,12 @@ "8dd4805991": "文件", "68d1db8929": "markdown", "90425d313c": "转移", + "linkRoutingModifier": { + "routing": "路由", + "modifier": "修饰键", + "invert": "反转", + "opposite": "相反" + }, "72c58f7792": "网页视图", "82ba1c80ea": "本地主机", "bea27bac4b": "链接", @@ -9724,11 +9730,10 @@ "legacyHelp": "Update this server manually once to enable remote updates." }, "BrowserLinkRoutingModifierSetting": { - "toggleLabel": "Toggle inverted link routing modifier", "titleSystem": "Hold Shift to open in your web browser", "titleOrca": "Hold Shift to open in Orca", "descriptionSystem": "Links open in Orca, so {{chord}}+click sends one to your system browser instead.", - "descriptionOrca": "Links open in your system browser, so {{chord}}+click opens one in Orca's built-in browser instead." + "descriptionOrca": "Links open in your system browser. When enabled, {{chord}}+click opens one in Orca's built-in browser instead." } }, "right": { diff --git a/src/renderer/src/lib/pane-manager/pane-dom-creation.test.ts b/src/renderer/src/lib/pane-manager/pane-dom-creation.test.ts index d4aa34759bd..4c57b61d1bb 100644 --- a/src/renderer/src/lib/pane-manager/pane-dom-creation.test.ts +++ b/src/renderer/src/lib/pane-manager/pane-dom-creation.test.ts @@ -111,6 +111,29 @@ describe('createPaneDOM link tooltips', () => { ) }) + // Why: the only PaneManager consumer passes linkOpenHint, so the hardcoded fallback + // is unreachable in production — without this, dropping the option stays green. + it('re-resolves the caller hint on every hover so setting changes apply live', () => { + const leafId = '11111111-1111-4111-8111-111111111111' as TerminalLeafId + let hint = 'first hint' + const pane = createPaneDOM( + 1, + leafId, + { linkOpenHint: () => hint }, + { active: null } as never, + {} as never, + vi.fn(), + vi.fn() + ) + + webLinksAddonMock.options?.hover?.({} as MouseEvent, 'http://localhost:5180/') + expect(pane.linkTooltip.textContent).toBe('http://localhost:5180/ (first hint)') + + hint = 'second hint' + webLinksAddonMock.options?.hover?.({} as MouseEvent, 'http://localhost:5180/') + expect(pane.linkTooltip.textContent).toBe('http://localhost:5180/ (second hint)') + }) + it('lets callers replace WebLinks hover text for display-only labels', async () => { const labeledText = 'http://main.orca.localhost:60016/ (localhost:5180; click to open)' const leafId = '11111111-1111-4111-8111-111111111111' as TerminalLeafId