mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-07-03 12:27:41 +08:00
refactor(sub-window): rename DetachedWindowManager to SubWindowService
Unify the "window detached from main" concept under the SubWindow name, pairing it with MainWindow. Rename the service class, WindowType enum value, HTML entry, renderer directory, React components, logger contexts, and window-manager docs accordingly. Scope of rename (noun-only): - DetachedWindowManager -> SubWindowService - DetachedWindowState -> SubWindowState - WindowType.DetachedTab -> WindowType.SubWindow (value 'subWindow') - detachedWindow.html / detachedWindow/ -> subWindow.html / subWindow/ - DetachedAppShell -> SubWindowAppShell - DetachedTabApp -> SubWindowApp - DETACHED_DEFAULT_WIDTH/HEIGHT -> SUB_WINDOW_DEFAULT_WIDTH/HEIGHT - Logger contexts / sources and all "detached window" prose Preserved (interaction-specific, not window-type nouns): - IPC channels Tab_Detach / Tab_Attach / Tab_MoveWindow / Tab_TryAttach / Tab_DragEnd and their 'tab:*' literals - these describe the drag-tab interaction, not the SubWindow concept - Component prop isDetached and useTabDrag.detachedCreated state - The DevTools "detached" and Node spawn "detached" unrelated usages
This commit is contained in:
@@ -99,7 +99,7 @@ Runtime setters for the declarative behavior layer live on `wm.behavior` (the {@
|
||||
|
||||
| Mode | Instances | `open()` behavior | `close()` behavior | Use for |
|
||||
|---|---|---|---|---|
|
||||
| `default` | many | fresh create every call | destroys permanently | Windows that appear in parallel (e.g. detached tabs) |
|
||||
| `default` | many | fresh create every call | destroys permanently | Windows that appear in parallel (e.g. sub windows) |
|
||||
| `singleton` | at most one | creates, or shows + focuses the existing one | destroys the sole instance | Unique windows (main, settings) |
|
||||
| `pooled` | many, reusable | pops an idle window, or creates fresh if empty | returns to the idle pool, or destroys if over cap | Frequently opened windows where creation cost matters (selection actions) |
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ These operate on the declarative `behavior` layer per instance and are exposed o
|
||||
|--------|-----------|-------------|
|
||||
| `wm.behavior.setHideOnBlur` | `(windowId: string, enabled: boolean) => void` | Override the declared `behavior.hideOnBlur` at runtime. `enabled: true` keeps auto-hide on; `enabled: false` suppresses (effectively "pinned"). No-op when the window type does not declare `behavior.hideOnBlur` (no listener to override). Override is cleared on window destroy and on pool `releaseToPool`. |
|
||||
| `wm.behavior.setAlwaysOnTop` | `(windowId: string, enabled: boolean) => void` | Toggle always-on-top using `level` / `relativeLevel` from `behavior.alwaysOnTop` (single source of truth). When neither is declared, `setAlwaysOnTop(enabled)` is called with no level — matching Electron's default. |
|
||||
| `wm.behavior.setMacShowInDockByType` | `(type: WindowType, value: boolean) => void` | Override `behavior.macShowInDock` for an entire type at runtime. Use this to express "app is entering / leaving tray mode": `(Main, false)` before `window.hide()` makes the Dock track the transition; `(Main, true)` before `window.show()` lifts the suppression. Keyed by type (not windowId) so it can be set BEFORE the first instance exists (e.g. tray-on-launch path). When multiple window types contribute (e.g. Main + DetachedTab), the Dock stays visible as long as any contributing type is alive — `wm.behavior.setMacShowInDockByType(Main, false)` will not hide the Dock if a DetachedTab window is still present. |
|
||||
| `wm.behavior.setMacShowInDockByType` | `(type: WindowType, value: boolean) => void` | Override `behavior.macShowInDock` for an entire type at runtime. Use this to express "app is entering / leaving tray mode": `(Main, false)` before `window.hide()` makes the Dock track the transition; `(Main, true)` before `window.show()` lifts the suppression. Keyed by type (not windowId) so it can be set BEFORE the first instance exists (e.g. tray-on-launch path). When multiple window types contribute (e.g. Main + SubWindow), the Dock stays visible as long as any contributing type is alive — `wm.behavior.setMacShowInDockByType(Main, false)` will not hide the Dock if a SubWindow is still present. |
|
||||
|
||||
> No WM-level `setVisibleOnAllWorkspaces` is provided: its options differ per call in real usage (e.g. SelectionAction's full-screen show sequence), and WM has no state to maintain. Consumers call `window.setVisibleOnAllWorkspaces(enabled, options)` directly on the `BrowserWindow` instance. See [README → When to Provide a Runtime Setter](./README.md#when-to-provide-a-runtime-setter) for the decision rule.
|
||||
|
||||
|
||||
@@ -50,20 +50,20 @@ WindowManager
|
||||
|
||||
Multi-instance mode. Every `open()` call creates a fresh window. `close()` destroys it permanently.
|
||||
|
||||
**Use for**: windows that appear many times simultaneously (e.g., detached tabs).
|
||||
**Use for**: windows that appear many times simultaneously (e.g., sub windows).
|
||||
|
||||
```typescript
|
||||
// windowRegistry.ts
|
||||
WINDOW_TYPE_REGISTRY[WindowType.DetachedTab] = {
|
||||
type: WindowType.DetachedTab,
|
||||
WINDOW_TYPE_REGISTRY[WindowType.SubWindow] = {
|
||||
type: WindowType.SubWindow,
|
||||
lifecycle: 'default',
|
||||
htmlPath: 'detached-tab.html',
|
||||
htmlPath: 'sub-window.html',
|
||||
windowOptions: { ...DEFAULT_WINDOW_CONFIG },
|
||||
}
|
||||
|
||||
// Usage — each call creates a new window
|
||||
const tab1 = wm.open(WindowType.DetachedTab)
|
||||
const tab2 = wm.open(WindowType.DetachedTab)
|
||||
const tab1 = wm.open(WindowType.SubWindow)
|
||||
const tab2 = wm.open(WindowType.SubWindow)
|
||||
wm.close(tab1) // destroyed
|
||||
```
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ Runtime setters for the behavior layer live on `wm.behavior` (a `BehaviorControl
|
||||
|---|---|
|
||||
| `wm.behavior.setHideOnBlur(id, enabled)` | Override the declared `behavior.hideOnBlur` per instance. Cleared on destroy and on pool `releaseToPool` — pool consumers that need a non-default value must re-apply after `open()` / reuse. No-op when the window does not declare `behavior.hideOnBlur`. |
|
||||
| `wm.behavior.setAlwaysOnTop(id, enabled)` | Toggle always-on-top using the `level` / `relativeLevel` declared in `behavior.alwaysOnTop`. When neither is declared, calls `setAlwaysOnTop(enabled)` with no level. |
|
||||
| `wm.behavior.setMacShowInDockByType(type, value)` | Override `behavior.macShowInDock` for an entire window type (not a single instance). Use for app-level tray-mode transitions: `(Main, false)` then `hide()` pulls the Dock icon down; `(Main, true)` then `show()` brings it back. Keyed by type so it can be set BEFORE the first instance exists (tray-on-launch). Multi-window safe: with `Main + DetachedTab` both contributing, a `wm.behavior.setMacShowInDockByType(Main, false)` alone does NOT hide the Dock while any DetachedTab is alive. |
|
||||
| `wm.behavior.setMacShowInDockByType(type, value)` | Override `behavior.macShowInDock` for an entire window type (not a single instance). Use for app-level tray-mode transitions: `(Main, false)` then `hide()` pulls the Dock icon down; `(Main, true)` then `show()` brings it back. Keyed by type so it can be set BEFORE the first instance exists (tray-on-launch). Multi-window safe: with `Main + SubWindow` both contributing, a `wm.behavior.setMacShowInDockByType(Main, false)` alone does NOT hide the Dock while any SubWindow is alive. |
|
||||
|
||||
`setVisibleOnAllWorkspaces` intentionally has **no** WM-level setter — consumers call it directly on the `BrowserWindow` when needed. See [README → When to Provide a Runtime Setter](./README.md#when-to-provide-a-runtime-setter).
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ export default defineConfig({
|
||||
selectionAction: resolve(__dirname, 'src/renderer/selectionAction.html'),
|
||||
traceWindow: resolve(__dirname, 'src/renderer/traceWindow.html'),
|
||||
migrationV2: resolve(__dirname, 'src/renderer/migrationV2.html'),
|
||||
detachedWindow: resolve(__dirname, 'src/renderer/detachedWindow.html')
|
||||
subWindow: resolve(__dirname, 'src/renderer/subWindow.html')
|
||||
},
|
||||
onwarn(warning, warn) {
|
||||
if (warning.code === 'COMMONJS_VARIABLE_IN_ESM') return
|
||||
|
||||
@@ -9,7 +9,6 @@ import { ApiServerService } from '@main/services/ApiServerService'
|
||||
import { AppMenuService } from '@main/services/AppMenuService'
|
||||
import { AppUpdaterService } from '@main/services/AppUpdaterService'
|
||||
import { CodeCliService } from '@main/services/CodeCliService'
|
||||
import { DetachedWindowManager } from '@main/services/DetachedWindowManager'
|
||||
import { KnowledgeOrchestrationService, KnowledgeRuntimeService } from '@main/services/knowledge'
|
||||
import { KnowledgeVectorStoreService } from '@main/services/knowledge/vectorstore/KnowledgeVectorStoreService'
|
||||
import { LanTransferService } from '@main/services/lanTransfer'
|
||||
@@ -28,6 +27,7 @@ import { SearchService } from '@main/services/SearchService'
|
||||
import { SelectionService } from '@main/services/SelectionService'
|
||||
import { ShortcutService } from '@main/services/ShortcutService'
|
||||
import { SpanCacheService } from '@main/services/SpanCacheService'
|
||||
import { SubWindowService } from '@main/services/SubWindowService'
|
||||
import { ThemeService } from '@main/services/ThemeService'
|
||||
import { TrayService } from '@main/services/TrayService'
|
||||
import { WebviewService } from '@main/services/WebviewService'
|
||||
@@ -62,7 +62,7 @@ export const services = {
|
||||
DbService,
|
||||
CacheService,
|
||||
DataApiService,
|
||||
DetachedWindowManager,
|
||||
SubWindowService,
|
||||
PreferenceService,
|
||||
AnalyticsService,
|
||||
AppMenuService,
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { BrowserWindow, BrowserWindowConstructorOptions, VisibleOnAllWorksp
|
||||
export enum WindowType {
|
||||
Main = 'main',
|
||||
QuickAssistant = 'quickAssistant',
|
||||
DetachedTab = 'detachedTab',
|
||||
SubWindow = 'subWindow',
|
||||
SelectionToolbar = 'selectionToolbar',
|
||||
SelectionAction = 'selectionAction'
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ export class MainWindowService extends BaseService {
|
||||
/**
|
||||
* Resolves the BrowserWindow that originated the IPC call.
|
||||
* Used for window-control channels (minimize/maximize/close) that must operate
|
||||
* on whichever window sent the IPC — main window or a detached tab window.
|
||||
* on whichever window sent the IPC — main window or a sub window.
|
||||
* Throws if the sender cannot be mapped to a live window.
|
||||
*/
|
||||
private resolveIpcSenderWindow(sender: Electron.WebContents): BrowserWindow {
|
||||
@@ -568,7 +568,7 @@ export class MainWindowService extends BaseService {
|
||||
// macOS close-to-tray: opt Main windows out of Dock contribution BEFORE hiding.
|
||||
// This tells WindowManager "the app is now in tray mode" so the Dock icon goes
|
||||
// away too. Unlike the previous hard-coded app.dock?.hide(), this cooperates
|
||||
// with multi-window scenarios: if a DetachedTab (or any other Dock-contributing
|
||||
// with multi-window scenarios: if a SubWindow (or any other Dock-contributing
|
||||
// window) is still alive, it will keep the Dock visible. The override is lifted
|
||||
// in showMainWindow/toggleMainWindow when the user brings Main back.
|
||||
if (isMac && isTrayOnClose) {
|
||||
@@ -666,7 +666,7 @@ export class MainWindowService extends BaseService {
|
||||
if (application.get('PreferenceService').get('app.tray.on_close')) {
|
||||
// Same pattern as the close handler: tell WM to stop counting Main
|
||||
// toward Dock visibility BEFORE hiding, so the Dock coordinates with
|
||||
// whatever else is alive (e.g. a DetachedTab) rather than blindly hiding.
|
||||
// whatever else is alive (e.g. a SubWindow) rather than blindly hiding.
|
||||
if (isMac) {
|
||||
application.get('WindowManager').behavior.setMacShowInDockByType(WindowType.Main, false)
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ import { join } from 'path'
|
||||
|
||||
import icon from '../../../build/icon.png?asset'
|
||||
|
||||
const logger = loggerService.withContext('DetachedWindowManager')
|
||||
const logger = loggerService.withContext('SubWindowService')
|
||||
|
||||
/** Height of the tab bar area used for drag-to-attach detection (must match CSS h-10) */
|
||||
const TAB_BAR_HEIGHT = 40
|
||||
|
||||
/** Must match createWindow BrowserWindow width/height */
|
||||
const DETACHED_DEFAULT_WIDTH = 800
|
||||
const DETACHED_DEFAULT_HEIGHT = 600
|
||||
const SUB_WINDOW_DEFAULT_WIDTH = 800
|
||||
const SUB_WINDOW_DEFAULT_HEIGHT = 600
|
||||
|
||||
/**
|
||||
* After Tab_MoveWindow, ignore `resize` bursts briefly so DPI rounding noise is not written back
|
||||
@@ -27,10 +27,10 @@ const DETACHED_DEFAULT_HEIGHT = 600
|
||||
*/
|
||||
const MOVE_RESIZE_IGNORE_MS = 280
|
||||
|
||||
/** Win/Linux: move detached windows with setContentBounds + cached size (see electron#27651). */
|
||||
/** Win/Linux: move sub windows with setContentBounds + cached size (see electron#27651). */
|
||||
const USE_CONTENT_BOUNDS_MOVE = isWin || isLinux
|
||||
|
||||
type DetachedWindowState = {
|
||||
type SubWindowState = {
|
||||
/** Cached content size to avoid getBounds() round-trips during drag (electron#27651) */
|
||||
width: number
|
||||
height: number
|
||||
@@ -38,12 +38,12 @@ type DetachedWindowState = {
|
||||
lastMoveAt: number
|
||||
}
|
||||
|
||||
@Injectable('DetachedWindowManager')
|
||||
@Injectable('SubWindowService')
|
||||
@ServicePhase(Phase.WhenReady)
|
||||
@DependsOn(['WindowManager'])
|
||||
export class DetachedWindowManager extends BaseService {
|
||||
export class SubWindowService extends BaseService {
|
||||
private windows: Map<string, BrowserWindow> = new Map()
|
||||
private windowState: Map<string, DetachedWindowState> = new Map()
|
||||
private windowState: Map<string, SubWindowState> = new Map()
|
||||
private windowUrls: Map<string, string> = new Map()
|
||||
|
||||
protected async onInit() {
|
||||
@@ -69,16 +69,16 @@ export class DetachedWindowManager extends BaseService {
|
||||
return false
|
||||
}
|
||||
|
||||
// Close sender detached window after successful broadcast. Main-window
|
||||
// senders are skipped because they are not in the DetachedWindowManager
|
||||
// pool (this.windows) and the check below only fires for detached tabs.
|
||||
// Close sender sub window after successful broadcast. Main-window
|
||||
// senders are skipped because they are not in the SubWindowService
|
||||
// pool (this.windows) and the check below only fires for sub windows.
|
||||
const senderWindow = BrowserWindow.fromWebContents(event.sender)
|
||||
const isDetachedTab = senderWindow ? Array.from(this.windows.values()).includes(senderWindow) : false
|
||||
if (senderWindow && isDetachedTab && !senderWindow.isDestroyed()) {
|
||||
const isSubWindow = senderWindow ? Array.from(this.windows.values()).includes(senderWindow) : false
|
||||
if (senderWindow && isSubWindow && !senderWindow.isDestroyed()) {
|
||||
try {
|
||||
senderWindow.close()
|
||||
} catch (err: any) {
|
||||
logger.error('Failed to close detached window after tab attach', err as Error)
|
||||
logger.error('Failed to close sub window after tab attach', err as Error)
|
||||
}
|
||||
}
|
||||
return true
|
||||
@@ -86,7 +86,7 @@ export class DetachedWindowManager extends BaseService {
|
||||
|
||||
this.ipcOn(IpcChannel.Tab_MoveWindow, (event, payload: { tabId: string; x: number; y: number }) => {
|
||||
// Prefer tabId lookup: when the main window sends this IPC, event.sender is the main window,
|
||||
// but we want to move the detached window identified by tabId.
|
||||
// but we want to move the sub window identified by tabId.
|
||||
const win = this.windows.get(payload.tabId) ?? BrowserWindow.fromWebContents(event.sender)
|
||||
if (win && !win.isDestroyed()) {
|
||||
const x = Math.round(payload.x)
|
||||
@@ -95,8 +95,8 @@ export class DetachedWindowManager extends BaseService {
|
||||
if (!win.isVisible()) {
|
||||
win.show()
|
||||
}
|
||||
// Only apply opacity when the detached window is dragging its own tab (preparing to reattach).
|
||||
// When the main window sends Tab_MoveWindow, event.sender differs from the detached window.
|
||||
// Only apply opacity when the sub window is dragging its own tab (preparing to reattach).
|
||||
// When the main window sends Tab_MoveWindow, event.sender differs from the sub window.
|
||||
const senderWindow = BrowserWindow.fromWebContents(event.sender)
|
||||
if (senderWindow === win && win.getOpacity() !== 0.85) {
|
||||
win.setOpacity(0.85)
|
||||
@@ -133,17 +133,17 @@ export class DetachedWindowManager extends BaseService {
|
||||
return false
|
||||
}
|
||||
|
||||
const detachedWin = this.windows.get(payload.tab.id)
|
||||
if (detachedWin && !detachedWin.isDestroyed()) {
|
||||
detachedWin.close()
|
||||
const subWin = this.windows.get(payload.tab.id)
|
||||
if (subWin && !subWin.isDestroyed()) {
|
||||
subWin.close()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Not over tab bar — restore opacity
|
||||
const detachedWin = this.windows.get(payload.tab.id)
|
||||
if (detachedWin && !detachedWin.isDestroyed()) {
|
||||
detachedWin.setOpacity(1)
|
||||
const subWin = this.windows.get(payload.tab.id)
|
||||
if (subWin && !subWin.isDestroyed()) {
|
||||
subWin.setOpacity(1)
|
||||
}
|
||||
|
||||
return false
|
||||
@@ -160,7 +160,7 @@ export class DetachedWindowManager extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a detached window to (x, y).
|
||||
* Moves a sub window to (x, y).
|
||||
* On Win/Linux uses setContentBounds with cached size to avoid electron#27651 outer-bounds creep.
|
||||
* On macOS uses setPosition (no reported creep issue).
|
||||
*/
|
||||
@@ -170,7 +170,7 @@ export class DetachedWindowManager extends BaseService {
|
||||
if (state) {
|
||||
state.lastMoveAt = Date.now()
|
||||
}
|
||||
const { width, height } = state ?? { width: DETACHED_DEFAULT_WIDTH, height: DETACHED_DEFAULT_HEIGHT }
|
||||
const { width, height } = state ?? { width: SUB_WINDOW_DEFAULT_WIDTH, height: SUB_WINDOW_DEFAULT_HEIGHT }
|
||||
// electron#27651: avoid outer getBounds/setBounds round-trips during drag
|
||||
win.setContentBounds({ x, y, width, height })
|
||||
} else {
|
||||
@@ -179,11 +179,11 @@ export class DetachedWindowManager extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks the content size of a detached window, keeping windowState in sync.
|
||||
* Tracks the content size of a sub window, keeping windowState in sync.
|
||||
* Must be called once per created window; cleans up state on close.
|
||||
*/
|
||||
private trackWindowSize(tabId: string, win: BrowserWindow) {
|
||||
this.windowState.set(tabId, { width: DETACHED_DEFAULT_WIDTH, height: DETACHED_DEFAULT_HEIGHT, lastMoveAt: 0 })
|
||||
this.windowState.set(tabId, { width: SUB_WINDOW_DEFAULT_WIDTH, height: SUB_WINDOW_DEFAULT_HEIGHT, lastMoveAt: 0 })
|
||||
|
||||
win.on('ready-to-show', () => {
|
||||
if (!win.isDestroyed() && USE_CONTENT_BOUNDS_MOVE) {
|
||||
@@ -234,8 +234,8 @@ export class DetachedWindowManager extends BaseService {
|
||||
const hasPosition = x !== undefined && y !== undefined
|
||||
|
||||
const win = new BrowserWindow({
|
||||
width: DETACHED_DEFAULT_WIDTH,
|
||||
height: DETACHED_DEFAULT_HEIGHT,
|
||||
width: SUB_WINDOW_DEFAULT_WIDTH,
|
||||
height: SUB_WINDOW_DEFAULT_HEIGHT,
|
||||
minWidth: 400,
|
||||
minHeight: 300,
|
||||
...(hasPosition ? { x, y } : {}),
|
||||
@@ -267,18 +267,18 @@ export class DetachedWindowManager extends BaseService {
|
||||
})
|
||||
|
||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||
win.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/detachedWindow.html?${params.toString()}`).catch((err) => {
|
||||
logger.error(`Failed to load detached window URL for tab ${tabId}`, err)
|
||||
win.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/subWindow.html?${params.toString()}`).catch((err) => {
|
||||
logger.error(`Failed to load sub window URL for tab ${tabId}`, err)
|
||||
this.windows.delete(tabId)
|
||||
if (!win.isDestroyed()) win.close()
|
||||
})
|
||||
} else {
|
||||
win
|
||||
.loadFile(join(__dirname, '../renderer/detachedWindow.html'), {
|
||||
.loadFile(join(__dirname, '../renderer/subWindow.html'), {
|
||||
search: params.toString()
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(`Failed to load detached window file for tab ${tabId}`, err)
|
||||
logger.error(`Failed to load sub window file for tab ${tabId}`, err)
|
||||
this.windows.delete(tabId)
|
||||
if (!win.isDestroyed()) win.close()
|
||||
})
|
||||
@@ -306,7 +306,7 @@ export class DetachedWindowManager extends BaseService {
|
||||
|
||||
this.windows.set(tabId, win)
|
||||
this.windowUrls.set(tabId, url)
|
||||
logger.info(`Created detached window for tab ${tabId}`, payload)
|
||||
logger.info(`Created sub window for tab ${tabId}`, payload)
|
||||
|
||||
return win
|
||||
}
|
||||
@@ -18,7 +18,7 @@ const WebviewContainer = ({ url, isActive }: { url: string; isActive: boolean })
|
||||
</Activity>
|
||||
)
|
||||
|
||||
export const DetachedAppShell = () => {
|
||||
export const SubWindowAppShell = () => {
|
||||
const { tabs, activeTabId, setActiveTab, closeTab, updateTab, addTab, reorderTabs, openTab, pinTab, unpinTab } =
|
||||
useTabs()
|
||||
const initialized = useRef(false)
|
||||
@@ -55,7 +55,7 @@ export const DetachedAppShell = () => {
|
||||
}
|
||||
}, [openTab, setActiveTab])
|
||||
|
||||
// Close tab in detached window. closeTab handles both pinned and normal tabs correctly.
|
||||
// Close tab in sub window. closeTab handles both pinned and normal tabs correctly.
|
||||
// Do NOT call unpinTab before closeTab — unpinTab moves the tab to normalTabs,
|
||||
// then closeTab's closure still sees isPinned=true and filters the wrong list.
|
||||
const handleCloseTab = (id: string) => {
|
||||
@@ -6,7 +6,7 @@ import '@renderer/databases'
|
||||
import { preferenceService } from '@data/PreferenceService'
|
||||
import { loggerService } from '@logger'
|
||||
import store, { persistor } from '@renderer/store'
|
||||
import { DetachedAppShell } from '@renderer/windows/detachedWindow/AppShell'
|
||||
import { SubWindowAppShell } from '@renderer/windows/subWindow/AppShell'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { Provider } from 'react-redux'
|
||||
@@ -21,7 +21,7 @@ import { TabsProvider } from '../../context/TabsContext'
|
||||
import { ThemeProvider } from '../../context/ThemeProvider'
|
||||
|
||||
// Initialize logger for this window
|
||||
loggerService.initWindowSource('DetachedTab')
|
||||
loggerService.initWindowSource('SubWindow')
|
||||
|
||||
void preferenceService.preloadAll()
|
||||
|
||||
@@ -35,7 +35,7 @@ const queryClient = new QueryClient({
|
||||
}
|
||||
})
|
||||
|
||||
function DetachedTabApp(): React.ReactElement {
|
||||
function SubWindowApp(): React.ReactElement {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
@@ -47,7 +47,7 @@ function DetachedTabApp(): React.ReactElement {
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<TabsProvider>
|
||||
<TopViewContainer>
|
||||
<DetachedAppShell />
|
||||
<SubWindowAppShell />
|
||||
</TopViewContainer>
|
||||
</TabsProvider>
|
||||
</PersistGate>
|
||||
@@ -62,4 +62,4 @@ function DetachedTabApp(): React.ReactElement {
|
||||
}
|
||||
|
||||
const root = createRoot(document.getElementById('root') as HTMLElement)
|
||||
root.render(<DetachedTabApp />)
|
||||
root.render(<SubWindowApp />)
|
||||
@@ -19,6 +19,6 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/init.ts"></script>
|
||||
<script type="module" src="/src/windows/detachedWindow/entryPoint.tsx"></script>
|
||||
<script type="module" src="/src/windows/subWindow/entryPoint.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user