mirror of
https://github.com/stablyai/orca.git
synced 2026-10-12 16:03:03 +00:00
Revert "Polish floating terminal native window"
This reverts commit c7e4bdf4d4.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { app, BrowserWindow, ipcMain, nativeTheme } from 'electron'
|
||||
import { app, BrowserWindow, nativeTheme } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { is } from '@electron-toolkit/utils'
|
||||
import icon from '../../../resources/icon.png?asset'
|
||||
@@ -12,55 +12,6 @@ const FLOATING_TERMINAL_MIN_HEIGHT = 280
|
||||
let floatingTerminalWindow: BrowserWindow | null = null
|
||||
let appQuitting = false
|
||||
|
||||
function isFloatingTerminalSender(
|
||||
event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent
|
||||
): boolean {
|
||||
return floatingTerminalWindow?.webContents.id === event.sender.id
|
||||
}
|
||||
|
||||
function sendWindowState(window: BrowserWindow): void {
|
||||
if (window.isDestroyed()) {
|
||||
return
|
||||
}
|
||||
window.webContents.send('floating-terminal-window:maximize-changed', window.isMaximized())
|
||||
window.webContents.send('floating-terminal-window:pinned-changed', window.isAlwaysOnTop())
|
||||
}
|
||||
|
||||
ipcMain.handle('floating-terminal-window:isMaximized', (event): boolean => {
|
||||
return isFloatingTerminalSender(event) && floatingTerminalWindow?.isMaximized() === true
|
||||
})
|
||||
|
||||
ipcMain.handle('floating-terminal-window:isPinned', (event): boolean => {
|
||||
return isFloatingTerminalSender(event) && floatingTerminalWindow?.isAlwaysOnTop() === true
|
||||
})
|
||||
|
||||
ipcMain.on('floating-terminal-window:hide', (event) => {
|
||||
if (isFloatingTerminalSender(event)) {
|
||||
floatingTerminalWindow?.hide()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('floating-terminal-window:toggleMaximized', (event) => {
|
||||
const window = floatingTerminalWindow
|
||||
if (!window || window.isDestroyed() || !isFloatingTerminalSender(event)) {
|
||||
return
|
||||
}
|
||||
if (window.isMaximized()) {
|
||||
window.unmaximize()
|
||||
} else {
|
||||
window.maximize()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('floating-terminal-window:togglePinned', (event) => {
|
||||
const window = floatingTerminalWindow
|
||||
if (!window || window.isDestroyed() || !isFloatingTerminalSender(event)) {
|
||||
return
|
||||
}
|
||||
window.setAlwaysOnTop(!window.isAlwaysOnTop(), 'floating')
|
||||
sendWindowState(window)
|
||||
})
|
||||
|
||||
app.on('before-quit', () => {
|
||||
appQuitting = true
|
||||
})
|
||||
@@ -92,7 +43,6 @@ export function showFloatingTerminalWindow(): void {
|
||||
minWidth: FLOATING_TERMINAL_MIN_WIDTH,
|
||||
minHeight: FLOATING_TERMINAL_MIN_HEIGHT,
|
||||
title: 'Floating Terminal',
|
||||
frame: false,
|
||||
show: false,
|
||||
autoHideMenuBar: true,
|
||||
backgroundColor: nativeTheme.shouldUseDarkColors ? '#0a0a0a' : '#ffffff',
|
||||
@@ -105,7 +55,6 @@ export function showFloatingTerminalWindow(): void {
|
||||
})
|
||||
|
||||
floatingTerminalWindow = window
|
||||
window.setAlwaysOnTop(true, 'floating')
|
||||
window.webContents.setBackgroundThrottling(false)
|
||||
window.once('ready-to-show', () => {
|
||||
if (!window.isDestroyed()) {
|
||||
@@ -126,8 +75,6 @@ export function showFloatingTerminalWindow(): void {
|
||||
floatingTerminalWindow = null
|
||||
}
|
||||
})
|
||||
window.on('maximize', () => sendWindowState(window))
|
||||
window.on('unmaximize', () => sendWindowState(window))
|
||||
window.webContents.on('before-input-event', (event, input) => {
|
||||
if (input.type !== 'keyDown') {
|
||||
return
|
||||
|
||||
@@ -1178,15 +1178,6 @@ export type PreloadApi = {
|
||||
onMaximizeChanged: (callback: (isMaximized: boolean) => void) => () => void
|
||||
requestClose: () => void
|
||||
popupMenu: () => void
|
||||
floatingTerminal: {
|
||||
hide: () => void
|
||||
toggleMaximized: () => void
|
||||
isMaximized: () => Promise<boolean>
|
||||
onMaximizeChanged: (callback: (isMaximized: boolean) => void) => () => void
|
||||
togglePinned: () => void
|
||||
isPinned: () => Promise<boolean>
|
||||
onPinnedChanged: (callback: (pinned: boolean) => void) => () => void
|
||||
}
|
||||
onWindowCloseRequested: (callback: (data: { isQuitting: boolean }) => void) => () => void
|
||||
confirmWindowClose: () => void
|
||||
}
|
||||
|
||||
@@ -2103,32 +2103,6 @@ const api = {
|
||||
popupMenu: (): void => {
|
||||
ipcRenderer.send('menu:popup')
|
||||
},
|
||||
floatingTerminal: {
|
||||
hide: (): void => {
|
||||
ipcRenderer.send('floating-terminal-window:hide')
|
||||
},
|
||||
toggleMaximized: (): void => {
|
||||
ipcRenderer.send('floating-terminal-window:toggleMaximized')
|
||||
},
|
||||
isMaximized: (): Promise<boolean> =>
|
||||
ipcRenderer.invoke('floating-terminal-window:isMaximized'),
|
||||
onMaximizeChanged: (callback: (isMaximized: boolean) => void): (() => void) => {
|
||||
const listener = (_event: Electron.IpcRendererEvent, isMaximized: boolean) =>
|
||||
callback(isMaximized)
|
||||
ipcRenderer.on('floating-terminal-window:maximize-changed', listener)
|
||||
return () =>
|
||||
ipcRenderer.removeListener('floating-terminal-window:maximize-changed', listener)
|
||||
},
|
||||
togglePinned: (): void => {
|
||||
ipcRenderer.send('floating-terminal-window:togglePinned')
|
||||
},
|
||||
isPinned: (): Promise<boolean> => ipcRenderer.invoke('floating-terminal-window:isPinned'),
|
||||
onPinnedChanged: (callback: (pinned: boolean) => void): (() => void) => {
|
||||
const listener = (_event: Electron.IpcRendererEvent, pinned: boolean) => callback(pinned)
|
||||
ipcRenderer.on('floating-terminal-window:pinned-changed', listener)
|
||||
return () => ipcRenderer.removeListener('floating-terminal-window:pinned-changed', listener)
|
||||
}
|
||||
},
|
||||
/** Fired by the main process when the user tries to close the window
|
||||
* (X button, Cmd+Q, etc.). Renderer should show a confirmation dialog
|
||||
* if terminals are still running, then call confirmWindowClose().
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { Maximize2, Minimize2, Pin, PinOff, X } from 'lucide-react'
|
||||
import TabBar from '@/components/tab-bar/TabBar'
|
||||
import TerminalPane from '@/components/terminal-pane/TerminalPane'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Toaster } from '@/components/ui/sonner'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { TooltipProvider } from '@/components/ui/tooltip'
|
||||
import { FLOATING_TERMINAL_WORKTREE_ID } from '@/lib/floating-terminal'
|
||||
import { focusTerminalTabSurface } from '@/lib/focus-terminal-tab-surface'
|
||||
import { createSessionWriteSubscriber } from '@/lib/session-write-subscriber'
|
||||
@@ -35,8 +33,6 @@ export function FloatingTerminalWindowApp(): React.JSX.Element {
|
||||
const tabBarOrder = useAppStore((s) => s.tabBarOrderByWorktree[FLOATING_TERMINAL_WORKTREE_ID])
|
||||
const floatingTerminalCwd = useAppStore((s) => s.settings?.floatingTerminalCwd ?? '~')
|
||||
const [cwd, setCwd] = useState<string | null>(null)
|
||||
const [pinned, setPinned] = useState(true)
|
||||
const [maximized, setMaximized] = useState(false)
|
||||
|
||||
const tabs = tabsByWorktree[FLOATING_TERMINAL_WORKTREE_ID] ?? EMPTY_TERMINAL_TABS
|
||||
const activeTabId = activeTabIdByWorktree[FLOATING_TERMINAL_WORKTREE_ID] ?? tabs[0]?.id ?? null
|
||||
@@ -82,27 +78,6 @@ export function FloatingTerminalWindowApp(): React.JSX.Element {
|
||||
[]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
void window.api.ui.floatingTerminal.isPinned().then((value) => {
|
||||
if (!cancelled) {
|
||||
setPinned(value)
|
||||
}
|
||||
})
|
||||
void window.api.ui.floatingTerminal.isMaximized().then((value) => {
|
||||
if (!cancelled) {
|
||||
setMaximized(value)
|
||||
}
|
||||
})
|
||||
const offPinned = window.api.ui.floatingTerminal.onPinnedChanged(setPinned)
|
||||
const offMaximized = window.api.ui.floatingTerminal.onMaximizeChanged(setMaximized)
|
||||
return () => {
|
||||
cancelled = true
|
||||
offPinned()
|
||||
offMaximized()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const createFloatingTab = useCallback(() => {
|
||||
const tab = createTab(FLOATING_TERMINAL_WORKTREE_ID, undefined, undefined, { activate: false })
|
||||
setActiveTabForWorktree(FLOATING_TERMINAL_WORKTREE_ID, tab.id)
|
||||
@@ -136,94 +111,26 @@ export function FloatingTerminalWindowApp(): React.JSX.Element {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<div className="flex h-screen min-h-0 flex-col bg-background text-foreground">
|
||||
<div
|
||||
className="flex h-9 shrink-0 items-center border-b border-border bg-[var(--bg-titlebar,var(--card))]"
|
||||
style={{ WebkitAppRegion: 'drag' } as React.CSSProperties}
|
||||
>
|
||||
<div className="flex h-full min-w-0 flex-1">
|
||||
<TabBar
|
||||
tabs={tabs}
|
||||
activeTabId={activeTab?.id ?? null}
|
||||
worktreeId={FLOATING_TERMINAL_WORKTREE_ID}
|
||||
expandedPaneByTabId={expandedPaneByTabId}
|
||||
onActivate={(tabId) => setActiveTabForWorktree(FLOATING_TERMINAL_WORKTREE_ID, tabId)}
|
||||
onClose={closeTab}
|
||||
onCloseOthers={closeOthers}
|
||||
onCloseToRight={closeToRight}
|
||||
onNewTerminalTab={createFloatingTab}
|
||||
onNewBrowserTab={() => {}}
|
||||
terminalOnly
|
||||
onSetCustomTitle={setTabCustomTitle}
|
||||
onSetTabColor={setTabColor}
|
||||
onTogglePaneExpand={(tabId) =>
|
||||
setTabPaneExpanded(tabId, expandedPaneByTabId[tabId] !== true)
|
||||
}
|
||||
activeTabType="terminal"
|
||||
tabBarOrder={tabBarOrder}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center gap-1 px-2"
|
||||
style={{ WebkitAppRegion: 'no-drag' } as React.CSSProperties}
|
||||
>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon-xs"
|
||||
aria-label={pinned ? 'Unpin floating terminal' : 'Pin floating terminal'}
|
||||
aria-pressed={pinned}
|
||||
onClick={() => window.api.ui.floatingTerminal.togglePinned()}
|
||||
>
|
||||
{pinned ? <PinOff className="size-3.5" /> : <Pin className="size-3.5" />}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom" sideOffset={6}>
|
||||
{pinned ? 'Unpin floating terminal' : 'Pin floating terminal'}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon-xs"
|
||||
aria-label={
|
||||
maximized ? 'Restore floating terminal' : 'Maximize floating terminal'
|
||||
}
|
||||
aria-pressed={maximized}
|
||||
onClick={() => window.api.ui.floatingTerminal.toggleMaximized()}
|
||||
>
|
||||
{maximized ? (
|
||||
<Minimize2 className="size-3.5" />
|
||||
) : (
|
||||
<Maximize2 className="size-3.5" />
|
||||
)}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom" sideOffset={6}>
|
||||
{maximized ? 'Restore' : 'Maximize'}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon-xs"
|
||||
aria-label="Hide floating terminal"
|
||||
onClick={() => window.api.ui.floatingTerminal.hide()}
|
||||
>
|
||||
<X className="size-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom" sideOffset={6}>
|
||||
Hide floating terminal
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<TabBar
|
||||
tabs={tabs}
|
||||
activeTabId={activeTab?.id ?? null}
|
||||
worktreeId={FLOATING_TERMINAL_WORKTREE_ID}
|
||||
expandedPaneByTabId={expandedPaneByTabId}
|
||||
onActivate={(tabId) => setActiveTabForWorktree(FLOATING_TERMINAL_WORKTREE_ID, tabId)}
|
||||
onClose={closeTab}
|
||||
onCloseOthers={closeOthers}
|
||||
onCloseToRight={closeToRight}
|
||||
onNewTerminalTab={createFloatingTab}
|
||||
onNewBrowserTab={() => {}}
|
||||
terminalOnly
|
||||
onSetCustomTitle={setTabCustomTitle}
|
||||
onSetTabColor={setTabColor}
|
||||
onTogglePaneExpand={(tabId) =>
|
||||
setTabPaneExpanded(tabId, expandedPaneByTabId[tabId] !== true)
|
||||
}
|
||||
activeTabType="terminal"
|
||||
tabBarOrder={tabBarOrder}
|
||||
/>
|
||||
<div className="relative min-h-0 flex-1 overflow-hidden bg-background">
|
||||
{cwd
|
||||
? tabs.map((tab) => (
|
||||
|
||||
Reference in New Issue
Block a user