diff --git a/src/renderer/src/components/settings/AppearancePane.tsx b/src/renderer/src/components/settings/AppearancePane.tsx index ae8cb643f71..24bb19f278a 100644 --- a/src/renderer/src/components/settings/AppearancePane.tsx +++ b/src/renderer/src/components/settings/AppearancePane.tsx @@ -148,8 +148,7 @@ export function AppearancePane({ const terminalSearchEntries = [ { title: terminalTitle }, ...getTerminalAppearanceSearchEntries({ - showWarpImport: !isWebClient, - showGhosttyImport: !isWebClient + showDesktopThemeImports: !isWebClient }) ] const windowSearchEntries = [ diff --git a/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts b/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts index 59badea2303..b8162992118 100644 --- a/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts +++ b/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts @@ -473,9 +473,7 @@ describe('TerminalAppearanceSection ghostty import wiring', () => { }) expect(findComponentByTypeName(element, 'TerminalFontSizeSetting')).toBeNull() - expect( - findButtons(element).some((button) => button.text === 'Import from Ghostty') - ).toBe(false) + expect(findButtons(element).some((button) => button.text === 'Import from Ghostty')).toBe(false) }) it('shows the Ghostty import button for Ghostty-only searches', () => { @@ -530,6 +528,32 @@ describe('TerminalAppearanceSection ghostty import wiring', () => { expect(findGhosttyImportModal(element)).toBeNull() }) + it.each([false, true])( + 'hides Ghostty search results on web clients with forceVisiblePrimary=%s', + (forceVisiblePrimary) => { + vi.stubGlobal('window', { __ORCA_WEB_CLIENT__: true }) + mockSettingsSearchQuery = 'ghostty' + + const element = TerminalAppearanceSection({ + settings: {} as never, + updateSettings: () => {}, + systemPrefersDark: true, + terminalFontSuggestions: [], + ghostty: ghosttyMock, + warpThemes: warpThemesMock, + forceVisiblePrimary + }) + + expect(findButtons(element).some((button) => button.text === 'Import from Ghostty')).toBe( + false + ) + expect(findGhosttyImportModal(element)).toBeNull() + if (!forceVisiblePrimary) { + expect(findComponentByTypeName(element, 'SettingsSubsectionHeader')).toBeNull() + } + } + ) + it('passes hook state to GhosttyImportModal', () => { const element = TerminalAppearanceSection({ settings: {} as never, diff --git a/src/renderer/src/components/settings/TerminalAppearanceSection.tsx b/src/renderer/src/components/settings/TerminalAppearanceSection.tsx index cafe7d5174d..bf482ed373b 100644 --- a/src/renderer/src/components/settings/TerminalAppearanceSection.tsx +++ b/src/renderer/src/components/settings/TerminalAppearanceSection.tsx @@ -34,7 +34,7 @@ import { GhosttyImportModal } from './GhosttyImportModal' import type { UseGhosttyImportReturn } from './useGhosttyImport' import { WarpThemeImportModal } from './WarpThemeImportModal' import type { UseWarpThemeImportReturn } from './useWarpThemeImport' -import { isWebClientLocation } from '@/hooks/useSettingsNavigationMetadata' +import { isWebClientLocation } from '@/lib/web-client-location' import ghosttyIcon from '../../../../../resources/ghostty.svg' import { translate } from '@/i18n/i18n' diff --git a/src/renderer/src/components/settings/appearance-search.ts b/src/renderer/src/components/settings/appearance-search.ts index de8b742626b..09685358145 100644 --- a/src/renderer/src/components/settings/appearance-search.ts +++ b/src/renderer/src/components/settings/appearance-search.ts @@ -223,14 +223,13 @@ const getAppearanceSectionEntries = createLocalizedCatalog((): SettingsSearchEnt ]) type AppearancePaneSearchOptions = { - showWarpImport?: boolean - showGhosttyImport?: boolean + showDesktopThemeImports?: boolean showSystemTray?: boolean showMenuBarIcon?: boolean } -function buildAppearancePaneSearchEntries( - options: AppearancePaneSearchOptions +export function getAppearancePaneSearchEntries( + options: AppearancePaneSearchOptions = {} ): SettingsSearchEntry[] { return [ ...getAppearanceSectionEntries(), @@ -248,14 +247,3 @@ function buildAppearancePaneSearchEntries( ...getMenuBarIconEntries(options) ] } - -export function getAppearancePaneSearchEntries( - options: AppearancePaneSearchOptions = {} -): SettingsSearchEntry[] { - return buildAppearancePaneSearchEntries({ - showWarpImport: options.showWarpImport ?? true, - showGhosttyImport: options.showGhosttyImport ?? true, - showSystemTray: options.showSystemTray, - showMenuBarIcon: options.showMenuBarIcon - }) -} diff --git a/src/renderer/src/components/settings/terminal-search.test.ts b/src/renderer/src/components/settings/terminal-search.test.ts index 739d1125cd9..f86bcfa3f2c 100644 --- a/src/renderer/src/components/settings/terminal-search.test.ts +++ b/src/renderer/src/components/settings/terminal-search.test.ts @@ -156,17 +156,17 @@ describe('getTerminalPaneSearchEntries', () => { expect(matchesSettingsSearch(query, getAppearancePaneSearchEntries())).toBe(true) }) - it('omits desktop-only import appearance entries when desktop-only controls are hidden', () => { - const desktopEntries = getAppearancePaneSearchEntries({ showWarpImport: true }) - const webEntries = getAppearancePaneSearchEntries({ - showWarpImport: false, - showGhosttyImport: false - }) + it.each(['ghostty', 'warp', 'yaml'])( + 'omits desktop-only %s search results on web clients', + (query) => { + const desktopEntries = getAppearancePaneSearchEntries() + const webEntries = getAppearancePaneSearchEntries({ showDesktopThemeImports: false }) - expect(desktopEntries.some((entry) => entry.title === 'Import from Warp')).toBe(true) - expect(webEntries.some((entry) => entry.title === 'Import from Warp')).toBe(false) - expect(webEntries.some((entry) => entry.title === 'Import from Ghostty')).toBe(false) - }) + expect(matchesSettingsSearch(query, desktopEntries)).toBe(true) + expect(matchesSettingsSearch(query, webEntries)).toBe(false) + expect(matchesSettingsSearch('font size', webEntries)).toBe(true) + } + ) it('includes the system tray appearance entry only when desktop tray controls are shown', () => { const desktopEntries = getAppearancePaneSearchEntries({ showSystemTray: true }) diff --git a/src/renderer/src/components/settings/terminal-search.ts b/src/renderer/src/components/settings/terminal-search.ts index 180d10d9243..39a66d65e51 100644 --- a/src/renderer/src/components/settings/terminal-search.ts +++ b/src/renderer/src/components/settings/terminal-search.ts @@ -63,11 +63,10 @@ export { } from './terminal-window-setup-search' type TerminalAppearanceSearchOptions = { - showWarpImport?: boolean - showGhosttyImport?: boolean + showDesktopThemeImports?: boolean } -const getTerminalAppearanceSearchEntriesCore = createLocalizedCatalog( +const getTerminalAppearanceSearchEntriesWithoutImports = createLocalizedCatalog( (): SettingsSearchEntry[] => [ ...getTerminalTypographySearchEntries(), ...getTerminalCursorSearchEntries(), @@ -79,11 +78,11 @@ const getTerminalAppearanceSearchEntriesCore = createLocalizedCatalog( ] ) -// Why: compose rather than filter — entry titles are localized, so matching on -// an English title would leak the Warp entry back in under non-English locales. -const getTerminalAppearanceSearchEntriesWithWarp = createLocalizedCatalog( +// Compose catalogs because translated titles cannot reliably identify desktop-only entries. +const getTerminalAppearanceSearchEntriesWithImports = createLocalizedCatalog( (): SettingsSearchEntry[] => [ - ...getTerminalAppearanceSearchEntriesCore(), + ...getTerminalAppearanceSearchEntriesWithoutImports(), + ...getTerminalGhosttyImportSearchEntries(), ...getTerminalWarpImportSearchEntries(), ...getTerminalYamlImportSearchEntries() ] @@ -92,12 +91,9 @@ const getTerminalAppearanceSearchEntriesWithWarp = createLocalizedCatalog( export function getTerminalAppearanceSearchEntries( options: TerminalAppearanceSearchOptions = {} ): SettingsSearchEntry[] { - return [ - ...((options.showWarpImport ?? true) - ? getTerminalAppearanceSearchEntriesWithWarp() - : getTerminalAppearanceSearchEntriesCore()), - ...((options.showGhosttyImport ?? true) ? getTerminalGhosttyImportSearchEntries() : []) - ] + return (options.showDesktopThemeImports ?? true) + ? getTerminalAppearanceSearchEntriesWithImports() + : getTerminalAppearanceSearchEntriesWithoutImports() } export function getTerminalPaneSearchEntries(platform: { diff --git a/src/renderer/src/hooks/settings-navigation-interface-sections.ts b/src/renderer/src/hooks/settings-navigation-interface-sections.ts index acbd44333c6..35d51532315 100644 --- a/src/renderer/src/hooks/settings-navigation-interface-sections.ts +++ b/src/renderer/src/hooks/settings-navigation-interface-sections.ts @@ -26,8 +26,7 @@ export function buildInterfaceSettingsSections({ ), icon: Palette, searchEntries: getAppearancePaneSearchEntries({ - showWarpImport: showDesktopOnlySettings, - showGhosttyImport: showDesktopOnlySettings, + showDesktopThemeImports: showDesktopOnlySettings, showSystemTray: showDesktopOnlySettings && isWindows, showMenuBarIcon: showDesktopOnlySettings && isMac }),