mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 16:02:32 +00:00
Update titlebar app name controls (#1644)
This commit is contained in:
@@ -66,7 +66,7 @@ function createSettings(overrides: Partial<GlobalSettings> = {}): GlobalSettings
|
||||
terminalScrollbackBytes: 10_000_000,
|
||||
openLinksInApp: false,
|
||||
rightSidebarOpenByDefault: true,
|
||||
showTitlebarAgentActivity: true,
|
||||
showTitlebarAppName: true,
|
||||
showTasksButton: true,
|
||||
diffDefaultView: 'inline',
|
||||
notifications: {
|
||||
|
||||
@@ -60,7 +60,7 @@ function createSettings(overrides: Partial<GlobalSettings> = {}): GlobalSettings
|
||||
terminalScrollbackBytes: 10_000_000,
|
||||
openLinksInApp: false,
|
||||
rightSidebarOpenByDefault: true,
|
||||
showTitlebarAgentActivity: true,
|
||||
showTitlebarAppName: true,
|
||||
showTasksButton: true,
|
||||
diffDefaultView: 'inline',
|
||||
notifications: {
|
||||
|
||||
+1
-1
@@ -550,7 +550,7 @@ app.whenReady().then(async () => {
|
||||
const ui = store?.getUI()
|
||||
return {
|
||||
showTasksButton: settings?.showTasksButton !== false,
|
||||
showTitlebarAgentActivity: settings?.showTitlebarAgentActivity !== false,
|
||||
showTitlebarAppName: settings?.showTitlebarAppName !== false,
|
||||
statusBarVisible: ui?.statusBarVisible !== false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const SETTINGS_CHANGED_WHITELIST_SET = new Set<string>(SETTINGS_CHANGED_WHITELIS
|
||||
// items when the backing state changes.
|
||||
const APPEARANCE_MENU_KEYS: readonly (keyof GlobalSettings)[] = [
|
||||
'showTasksButton',
|
||||
'showTitlebarAgentActivity'
|
||||
'showTitlebarAppName'
|
||||
]
|
||||
|
||||
export function registerSettingsHandlers(store: Store): void {
|
||||
|
||||
@@ -35,7 +35,7 @@ function buildMenuOptions() {
|
||||
onToggleAppearance: vi.fn(),
|
||||
getAppearanceState: vi.fn(() => ({
|
||||
showTasksButton: true,
|
||||
showTitlebarAgentActivity: true,
|
||||
showTitlebarAppName: true,
|
||||
statusBarVisible: true
|
||||
}))
|
||||
}
|
||||
@@ -194,7 +194,7 @@ describe('registerAppMenu', () => {
|
||||
const options = buildMenuOptions()
|
||||
options.getAppearanceState.mockReturnValue({
|
||||
showTasksButton: false,
|
||||
showTitlebarAgentActivity: true,
|
||||
showTitlebarAppName: true,
|
||||
statusBarVisible: true
|
||||
})
|
||||
registerAppMenu(options)
|
||||
@@ -209,9 +209,7 @@ describe('registerAppMenu', () => {
|
||||
expect(tasksItem?.type).toBe('checkbox')
|
||||
expect(tasksItem?.checked).toBe(false)
|
||||
|
||||
const titlebarItem = appearanceSubmenu.find(
|
||||
(item) => item.label === 'Show Titlebar Agent Activity'
|
||||
)
|
||||
const titlebarItem = appearanceSubmenu.find((item) => item.label === 'Show Titlebar App Name')
|
||||
expect(titlebarItem?.checked).toBe(true)
|
||||
|
||||
const statusBarItem = appearanceSubmenu.find((item) => item.label === 'Show Status Bar')
|
||||
@@ -229,8 +227,12 @@ describe('registerAppMenu', () => {
|
||||
appearanceSubmenu
|
||||
.find((item) => item.label === 'Show Tasks Button')
|
||||
?.click?.({} as never, {} as never, {} as never)
|
||||
appearanceSubmenu
|
||||
.find((item) => item.label === 'Show Titlebar App Name')
|
||||
?.click?.({} as never, {} as never, {} as never)
|
||||
|
||||
expect(options.onToggleAppearance).toHaveBeenCalledWith('showTasksButton')
|
||||
expect(options.onToggleAppearance).toHaveBeenCalledWith('showTitlebarAppName')
|
||||
})
|
||||
|
||||
it('routes sidebar toggle items through their callbacks', () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { BrowserWindow, Menu, app } from 'electron'
|
||||
|
||||
export type AppearanceMenuState = {
|
||||
showTasksButton: boolean
|
||||
showTitlebarAgentActivity: boolean
|
||||
showTitlebarAppName: boolean
|
||||
statusBarVisible: boolean
|
||||
}
|
||||
|
||||
@@ -181,10 +181,10 @@ function buildAndApplyMenu(options: RegisterAppMenuOptions): void {
|
||||
click: () => onToggleAppearance('showTasksButton')
|
||||
},
|
||||
{
|
||||
label: 'Show Titlebar Agent Activity',
|
||||
label: 'Show Titlebar App Name',
|
||||
type: 'checkbox',
|
||||
checked: appearance.showTitlebarAgentActivity,
|
||||
click: () => onToggleAppearance('showTitlebarAgentActivity')
|
||||
checked: appearance.showTitlebarAppName,
|
||||
click: () => onToggleAppearance('showTitlebarAppName')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+30
-123
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { lazy, Suspense, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
|
||||
import { lazy, Suspense, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { getDefaultUIState } from '../../shared/constants'
|
||||
|
||||
import {
|
||||
@@ -14,10 +14,14 @@ import logo from '../../../resources/logo.svg'
|
||||
import { SYNC_FIT_PANES_EVENT, TOGGLE_TERMINAL_PANE_EXPAND_EVENT } from '@/constants/terminal'
|
||||
import { syncZoomCSSVar } from '@/lib/ui-zoom'
|
||||
import { buildAppFontFamily } from '@/lib/app-font-family'
|
||||
import { activateTabAndFocusPane } from '@/lib/activate-tab-and-focus-pane'
|
||||
import { toast } from 'sonner'
|
||||
import { Toaster } from '@/components/ui/sonner'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuTrigger
|
||||
} from '@/components/ui/context-menu'
|
||||
import { useAppStore } from './store'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useIpcEvents } from './hooks/useIpcEvents'
|
||||
@@ -44,12 +48,8 @@ import {
|
||||
import { useGlobalFileDrop } from './hooks/useGlobalFileDrop'
|
||||
import { registerUpdaterBeforeUnloadBypass } from './lib/updater-beforeunload'
|
||||
import { buildWorkspaceSessionPayload } from './lib/workspace-session'
|
||||
import { countWorkingAgents, getWorkingAgentsPerWorktree } from './lib/agent-status'
|
||||
import { activateAndRevealWorktree } from './lib/worktree-activation'
|
||||
import { applyDocumentTheme } from './lib/document-theme'
|
||||
import { isEditableTarget } from './lib/editable-target'
|
||||
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'
|
||||
import { findWorktreeById, getRepoIdFromWorktreeId } from '@/store/slices/worktree-helpers'
|
||||
import {
|
||||
canGoBackWorktreeHistory,
|
||||
canGoForwardWorktreeHistory
|
||||
@@ -179,19 +179,6 @@ function App(): React.JSX.Element {
|
||||
const activeWorktreeId = useAppStore((s) => s.activeWorktreeId)
|
||||
const tabsByWorktree = useAppStore((s) => s.tabsByWorktree)
|
||||
const activeTabId = useAppStore((s) => s.activeTabId)
|
||||
const worktreesByRepo = useAppStore((s) => s.worktreesByRepo)
|
||||
const agentInputs = useAppStore(
|
||||
useShallow((s) => ({
|
||||
tabsByWorktree: s.tabsByWorktree,
|
||||
runtimePaneTitlesByTabId: s.runtimePaneTitlesByTabId,
|
||||
worktreesByRepo: s.worktreesByRepo
|
||||
}))
|
||||
)
|
||||
const activeAgentCount = useMemo(() => countWorkingAgents(agentInputs), [agentInputs])
|
||||
const workingAgentsPerWorktree = useMemo(
|
||||
() => getWorkingAgentsPerWorktree(agentInputs),
|
||||
[agentInputs]
|
||||
)
|
||||
const expandedPaneByTabId = useAppStore((s) => s.expandedPaneByTabId)
|
||||
const canExpandPaneByTabId = useAppStore((s) => s.canExpandPaneByTabId)
|
||||
const workspaceSessionReady = useAppStore((s) => s.workspaceSessionReady)
|
||||
@@ -739,14 +726,7 @@ function App(): React.JSX.Element {
|
||||
})
|
||||
observer.observe(controls)
|
||||
return () => observer.disconnect()
|
||||
}, [
|
||||
activeAgentCount,
|
||||
isFullScreen,
|
||||
settings?.showTitlebarAgentActivity,
|
||||
showSidebar,
|
||||
workspaceActive,
|
||||
sidebarOpen
|
||||
])
|
||||
}, [isFullScreen, settings?.showTitlebarAppName, showSidebar, workspaceActive, sidebarOpen])
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
@@ -807,6 +787,28 @@ function App(): React.JSX.Element {
|
||||
) : (
|
||||
<div className="pl-2" />
|
||||
)}
|
||||
{showSidebar && (
|
||||
<>
|
||||
{settings?.showTitlebarAppName !== false && (
|
||||
<ContextMenu>
|
||||
<ContextMenuTrigger asChild>
|
||||
<div className="titlebar-app-name" aria-label="Orca">
|
||||
Orca
|
||||
</div>
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent>
|
||||
<ContextMenuItem
|
||||
onSelect={() => {
|
||||
void actions.updateSettings({ showTitlebarAppName: false })
|
||||
}}
|
||||
>
|
||||
Hide App Name
|
||||
</ContextMenuItem>
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{showSidebar && (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
@@ -823,101 +825,6 @@ function App(): React.JSX.Element {
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
)}
|
||||
{settings?.showTitlebarAgentActivity !== false ? (
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
className={`titlebar-agent-badge${activeAgentCount === 0 ? ' titlebar-agent-badge-idle' : ''}`}
|
||||
aria-label={`${activeAgentCount} ${activeAgentCount === 1 ? 'agent' : 'agents'} active`}
|
||||
>
|
||||
<span
|
||||
className={`titlebar-agent-badge-dot${activeAgentCount === 0 ? ' titlebar-agent-badge-dot-idle' : ''}`}
|
||||
aria-hidden
|
||||
/>
|
||||
<span className="titlebar-agent-badge-count">{activeAgentCount}</span>
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent side="bottom" sideOffset={6} className="titlebar-agent-hovercard">
|
||||
<div
|
||||
className={`titlebar-agent-hovercard-header${activeAgentCount > 0 ? ' titlebar-agent-hovercard-header-with-list' : ''}`}
|
||||
>
|
||||
{activeAgentCount === 0
|
||||
? 'No agents active'
|
||||
: `${activeAgentCount} ${activeAgentCount === 1 ? 'agent' : 'agents'} active`}
|
||||
</div>
|
||||
{activeAgentCount > 0 && (
|
||||
<div className="titlebar-agent-hovercard-list">
|
||||
{Object.entries(workingAgentsPerWorktree).map(([worktreeId, { agents }]) => {
|
||||
const wt = findWorktreeById(worktreesByRepo, worktreeId)
|
||||
// Why: when a transient git error causes worktreesByRepo to
|
||||
// lose a worktree, the raw worktreeId (uuid::path) is not
|
||||
// useful. Extract a cross-platform path basename as a
|
||||
// readable fallback.
|
||||
const sepIdx = worktreeId.indexOf('::')
|
||||
const pathPart = sepIdx !== -1 ? worktreeId.slice(sepIdx + 2) : worktreeId
|
||||
const fallbackName = pathPart.split(/[\\/]/).pop() || pathPart
|
||||
return (
|
||||
<div key={worktreeId}>
|
||||
<button
|
||||
className="titlebar-agent-hovercard-worktree"
|
||||
onClick={() => {
|
||||
// Why: if the worktree is missing from worktreesByRepo
|
||||
// (transient git error cleared the list), refresh the
|
||||
// repo's worktrees before navigating so the activation
|
||||
// lookup succeeds instead of silently failing.
|
||||
if (!wt) {
|
||||
const repoId = getRepoIdFromWorktreeId(worktreeId)
|
||||
void useAppStore
|
||||
.getState()
|
||||
.fetchWorktrees(repoId)
|
||||
.then(() => {
|
||||
activateAndRevealWorktree(worktreeId)
|
||||
})
|
||||
return
|
||||
}
|
||||
activateAndRevealWorktree(worktreeId)
|
||||
}}
|
||||
>
|
||||
<span className="titlebar-agent-hovercard-name">
|
||||
{wt?.displayName ?? fallbackName}
|
||||
</span>
|
||||
</button>
|
||||
{agents.map((agent) => (
|
||||
<button
|
||||
key={`${agent.tabId}:${agent.paneId ?? 'none'}:${agent.label}`}
|
||||
className="titlebar-agent-hovercard-agent"
|
||||
onClick={() => {
|
||||
activateAndRevealWorktree(worktreeId)
|
||||
activateTabAndFocusPane(agent.tabId, agent.paneId)
|
||||
}}
|
||||
>
|
||||
<span className="titlebar-agent-hovercard-agent-label">
|
||||
{agent.label}
|
||||
</span>
|
||||
<span className="titlebar-agent-hovercard-agent-dot" />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
className="titlebar-agent-hovercard-hide"
|
||||
onClick={() => {
|
||||
void actions.updateSettings({ showTitlebarAgentActivity: false })
|
||||
toast('Agent activity badge hidden', {
|
||||
description: 'You can turn it back on in Settings → Appearance.',
|
||||
duration: Infinity,
|
||||
dismissible: true
|
||||
})
|
||||
}}
|
||||
>
|
||||
Hide from titlebar
|
||||
</button>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
) : null}
|
||||
</div>
|
||||
{/* Why: Back/Forward traverse mixed worktree + Tasks history, so the
|
||||
cluster is shown wherever the history shortcut is live (terminal or
|
||||
|
||||
@@ -528,192 +528,23 @@
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.titlebar-agent-badge {
|
||||
.titlebar-app-name {
|
||||
-webkit-app-region: no-drag;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-left: 4px;
|
||||
margin-right: 8px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid color-mix(in srgb, var(--border) 78%, transparent);
|
||||
background: color-mix(in srgb, var(--accent) 80%, transparent);
|
||||
color: var(--foreground);
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Why: the titlebar is a drag region, and descendant elements inherit that
|
||||
region unless they opt out. Without this, hovering the dot/count spans
|
||||
inside the badge showed the default cursor instead of pointer because the
|
||||
drag region overrode the button's cursor. pointer-events: none forwards
|
||||
hover/click hit-testing to the button, which already has no-drag set. */
|
||||
.titlebar-agent-badge > * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.titlebar-agent-badge:hover {
|
||||
background: var(--accent);
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
.titlebar-agent-badge-idle {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.titlebar-agent-badge-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 999px;
|
||||
flex-shrink: 0;
|
||||
background: #16a34a;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, #16a34a 18%, transparent);
|
||||
}
|
||||
|
||||
.titlebar-agent-badge-dot-idle {
|
||||
background: var(--muted-foreground);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.titlebar-agent-badge-count {
|
||||
min-width: 1ch;
|
||||
}
|
||||
|
||||
.titlebar-agent-badge-label {
|
||||
height: 24px;
|
||||
margin-left: 2px;
|
||||
margin-right: 4px;
|
||||
padding: 0 6px;
|
||||
border-radius: 4px;
|
||||
color: var(--muted-foreground);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ─── Agent hover card (titlebar badge popover) ───────────────────── */
|
||||
|
||||
.titlebar-agent-hovercard {
|
||||
width: auto;
|
||||
min-width: 180px;
|
||||
max-width: 280px;
|
||||
padding: 8px 0 0;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-header {
|
||||
padding: 0 12px 6px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-header-with-list {
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-hide {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 5px 12px 8px;
|
||||
margin-top: 4px;
|
||||
border-top: 1px solid var(--border);
|
||||
background: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
color: var(--muted-foreground);
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-hide:hover {
|
||||
color: var(--foreground);
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-worktree {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 5px 12px;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--foreground);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-worktree:hover {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-agent {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 3px 12px 3px 24px;
|
||||
font-size: 12px;
|
||||
color: var(--muted-foreground);
|
||||
background: none;
|
||||
border: none;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-agent:hover {
|
||||
background: var(--accent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-agent-label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-agent-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 999px;
|
||||
flex-shrink: 0;
|
||||
background: #16a34a;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-count {
|
||||
flex-shrink: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 11px;
|
||||
color: var(--muted-foreground);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.titlebar-agent-hovercard-dot {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 999px;
|
||||
background: #16a34a;
|
||||
}
|
||||
|
||||
.titlebar-icon-button {
|
||||
-webkit-app-region: no-drag;
|
||||
background: none;
|
||||
|
||||
@@ -114,9 +114,9 @@ const LAYOUT_ENTRIES: SettingsSearchEntry[] = [
|
||||
|
||||
const TITLEBAR_ENTRIES: SettingsSearchEntry[] = [
|
||||
{
|
||||
title: 'Titlebar Agent Activity',
|
||||
description: 'Show the number of active agents in the titlebar.',
|
||||
keywords: ['titlebar', 'agent', 'badge', 'active', 'count', 'status']
|
||||
title: 'Titlebar App Name',
|
||||
description: 'Show Orca in the titlebar.',
|
||||
keywords: ['titlebar', 'orca', 'app', 'name', 'brand']
|
||||
}
|
||||
]
|
||||
|
||||
@@ -289,32 +289,30 @@ export function AppearancePane({
|
||||
</div>
|
||||
|
||||
<SearchableSetting
|
||||
title="Titlebar Agent Activity"
|
||||
description="Show the number of active agents in the titlebar."
|
||||
keywords={['titlebar', 'agent', 'badge', 'active', 'count', 'status']}
|
||||
title="Titlebar App Name"
|
||||
description="Show Orca in the titlebar."
|
||||
keywords={['titlebar', 'orca', 'app', 'name', 'brand']}
|
||||
className="flex items-center justify-between gap-4 px-1 py-2"
|
||||
>
|
||||
<div className="space-y-0.5">
|
||||
<Label>Titlebar Agent Activity</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Show the number of active agents in the titlebar.
|
||||
</p>
|
||||
<Label>Titlebar App Name</Label>
|
||||
<p className="text-xs text-muted-foreground">Show Orca in the titlebar.</p>
|
||||
</div>
|
||||
<button
|
||||
role="switch"
|
||||
aria-checked={settings.showTitlebarAgentActivity}
|
||||
aria-checked={settings.showTitlebarAppName}
|
||||
onClick={() =>
|
||||
updateSettings({
|
||||
showTitlebarAgentActivity: !settings.showTitlebarAgentActivity
|
||||
showTitlebarAppName: !settings.showTitlebarAppName
|
||||
})
|
||||
}
|
||||
className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-transparent transition-colors ${
|
||||
settings.showTitlebarAgentActivity ? 'bg-foreground' : 'bg-muted-foreground/30'
|
||||
settings.showTitlebarAppName ? 'bg-foreground' : 'bg-muted-foreground/30'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`pointer-events-none block size-3.5 rounded-full bg-background shadow-sm transition-transform ${
|
||||
settings.showTitlebarAgentActivity ? 'translate-x-4' : 'translate-x-0.5'
|
||||
settings.showTitlebarAppName ? 'translate-x-4' : 'translate-x-0.5'
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
|
||||
@@ -196,7 +196,7 @@ export function getDefaultSettings(homedir: string): GlobalSettings {
|
||||
terminalScrollbackBytes: 10_000_000,
|
||||
openLinksInApp: true,
|
||||
rightSidebarOpenByDefault: true,
|
||||
showTitlebarAgentActivity: true,
|
||||
showTitlebarAppName: true,
|
||||
showTasksButton: true,
|
||||
notifications: getDefaultNotificationSettings(),
|
||||
diffDefaultView: 'inline',
|
||||
|
||||
+2
-2
@@ -1145,8 +1145,8 @@ export type GlobalSettings = {
|
||||
* until the user explicitly wants worktree-scoped in-app browsing. */
|
||||
openLinksInApp: boolean
|
||||
rightSidebarOpenByDefault: boolean
|
||||
/** Whether to show the live agent activity count badge in the titlebar. */
|
||||
showTitlebarAgentActivity: boolean
|
||||
/** Whether to show the Orca app name in the titlebar. */
|
||||
showTitlebarAppName: boolean
|
||||
/** Why: some users do not use the Tasks feature and prefer to keep the
|
||||
* left sidebar free of its button entirely. Hiding the button here also
|
||||
* removes it from keyboard navigation. */
|
||||
|
||||
Reference in New Issue
Block a user