diff --git a/src/ui/AppShell.tsx b/src/ui/AppShell.tsx index 42a4d91e7..70a43c3a6 100644 --- a/src/ui/AppShell.tsx +++ b/src/ui/AppShell.tsx @@ -641,6 +641,9 @@ export function AppShell({ const v = localStorage.getItem("commandPaletteShortcutEnabled"); return v !== null ? v === "true" : true; }); + const [showTabNumbers, setShowTabNumbers] = useState( + () => localStorage.getItem("showTabNumbers") === "true", + ); const terminalRefs = useRef>>( new Map(), ); @@ -931,6 +934,14 @@ export function AppShell({ ); }, []); + useEffect(() => { + const handler = () => { + setShowTabNumbers(localStorage.getItem("showTabNumbers") === "true"); + }; + window.addEventListener("showTabNumbersChanged", handler); + return () => window.removeEventListener("showTabNumbersChanged", handler); + }, []); + useEffect(() => { const handle = (event: Event) => { const manual = @@ -3081,6 +3092,7 @@ export function AppShell({ onToggleAppFullscreen={toggleAppFullscreen} rightDockOpen={rightRailView !== null} onToggleRightDock={isMobile ? undefined : toggleRightDock} + showTabNumbers={showTabNumbers} />
{/* Split view — always mounted when not mobile, hidden via CSS when inactive */} diff --git a/src/ui/locales/en.json b/src/ui/locales/en.json index b4af34b0f..8c216fbd0 100644 --- a/src/ui/locales/en.json +++ b/src/ui/locales/en.json @@ -4567,6 +4567,8 @@ "reopenTabsOnLoginDesc": "Restore your open tabs when you log in or refresh the page, even from another device", "confirmTabClose": "Confirm Tab Close", "confirmTabCloseDesc": "Ask before closing terminal tabs", + "showTabNumbers": "Show Tab Numbers", + "showTabNumbersDesc": "Display a number on each tab to help tell them apart", "transferConcurrency": "Simultaneous File Transfers", "transferConcurrencyDesc": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels.", "settingsAppRail": "App Rail", diff --git a/src/ui/shell/TabBar.tsx b/src/ui/shell/TabBar.tsx index 2a6a932f6..f67f2d091 100644 --- a/src/ui/shell/TabBar.tsx +++ b/src/ui/shell/TabBar.tsx @@ -62,6 +62,7 @@ export function TabBar({ onToggleAppFullscreen, rightDockOpen, onToggleRightDock, + showTabNumbers, }: { tabs: Tab[]; activeTabId: string; @@ -82,6 +83,7 @@ export function TabBar({ onToggleAppFullscreen: () => void; rightDockOpen?: boolean; onToggleRightDock?: () => void; + showTabNumbers?: boolean; }) { const { t } = useTranslation(); const reduceMotion = useReducedMotion(); @@ -422,6 +424,12 @@ export function TabBar({ {showInPaneIndicator && ( )} + {showTabNumbers && tab.type !== "dashboard" && ( + + {tabs.slice(0, index).filter((t) => t.type !== "dashboard") + .length + 1} + + )} {tabIcon(tab.type)} {tab.type !== "dashboard" && renamingTabId === tab.id ? ( - {tabs.map((tab) => ( + {tabs.map((tab, index) => (
onSetActiveTab(tab.id)} className={`flex items-center justify-between px-2 py-2 text-xs cursor-default hover:bg-accent hover:text-accent-foreground ${tab.id === activeTabId ? "text-foreground" : "text-muted-foreground"}`} >
+ {showTabNumbers && tab.type !== "dashboard" && ( + + {tabs + .slice(0, index) + .filter((t) => t.type !== "dashboard").length + 1} + + )} {tabIcon(tab.type)} {tab.type === "dashboard" diff --git a/src/ui/sidebar/UserProfilePanel.tsx b/src/ui/sidebar/UserProfilePanel.tsx index 612b104bf..905c7f401 100644 --- a/src/ui/sidebar/UserProfilePanel.tsx +++ b/src/ui/sidebar/UserProfilePanel.tsx @@ -768,6 +768,9 @@ export function UserProfilePanel({ const [confirmTabClose, setConfirmTabClose] = useState( () => localStorage.getItem("confirmTabClose") === "true", ); + const [showTabNumbers, setShowTabNumbers] = useState( + () => localStorage.getItem("showTabNumbers") === "true", + ); const [hiddenRailTabs, setHiddenRailTabs] = useState>(() => { try { const stored = localStorage.getItem("hiddenRailTabs"); @@ -2122,6 +2125,19 @@ export function UserProfilePanel({ }} /> + + { + setShowTabNumbers(v); + localStorage.setItem("showTabNumbers", v.toString()); + window.dispatchEvent(new Event("showTabNumbersChanged")); + }} + /> +