Understanding the Window Management System in TUUI: Splash, Main, and Error Windows
TUUI orchestrates splash, main, and error windows using Electron's BrowserWindow API through centralized factories in src/main/MainRunner.ts, ensuring graceful startup transitions and crash recovery.
The window management system in TUUI (part of the ai-ql/tuui repository) handles the complete lifecycle of application windows using Electron's native APIs. This architecture separates concerns between a lightweight splash screen, the primary application interface, and a dedicated error recovery window, all coordinated through the main process entry point at src/main/index.ts.
Splash Window Creation in TUUI
Purpose and Configuration
The splash window provides immediate visual feedback while the main application UI initializes. According to the source code in src/main/MainRunner.ts, the createSplashWindow() function constructs a small, frameless window (400 × 300 px) that stays always-on-top with a transparent background.
Implementation Details
The factory function handles environment-specific resource loading through constants defined in src/main/utils/Constants.ts:
export const createSplashWindow = async (): Promise<BrowserWindow> => {
const splashWindow = new BrowserWindow({
width: 400,
height: 300,
frame: false,
alwaysOnTop: true,
resizable: false,
show: true,
skipTaskbar: true,
transparent: true
})
// Load dev or prod splash HTML
if (Constants.IS_DEV_ENV) {
await splashWindow.loadURL(Constants.APP_SPLASH_URL_DEV)
} else {
await splashWindow.loadFile(Constants.APP_SPLASH_URL_PROD)
}
return splashWindow
}
In development mode, the window loads from VITE_DEV_SERVER_URL/splash.html, while production builds use the bundled ../splash.html file.
Main Window Management
Window Configuration and OS-Specific Features
The main window hosts the full TUUI application UI built with Vue. The createMainWindow() function in src/main/MainRunner.ts configures a resizable window with minimum dimensions and platform-specific title bar styling.
For Windows, Linux, and macOS, the implementation applies a hidden title bar with custom overlay colors:
export const createMainWindow = async (): Promise<BrowserWindow> => {
let opt: BrowserWindowConstructorOptions = {
title: Constants.APP_NAME,
show: false,
width: options.width,
height: options.height,
minWidth: options.minWidth,
minHeight: options.minHeight,
useContentSize: true,
webPreferences: Constants.DEFAULT_WEB_PREFERENCES,
frame: true,
...(process.platform === 'win32' || process.platform === 'linux' || process.platform === 'darwin'
? {
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#344767',
symbolColor: 'white',
height: 36
}
}
: {})
}
const mainWindow = new BrowserWindow(opt)
mainWindow.setMenu(null) // disables native menu and dev-tools shortcut
// …event handlers, tray creation, IPC init, then load UI
if (Constants.IS_DEV_ENV) {
await mainWindow.loadURL(Constants.APP_INDEX_URL_DEV)
} else {
await mainWindow.loadFile(Constants.APP_INDEX_URL_PROD)
}
return mainWindow
}
Lifecycle and Event Handling
The main window remains hidden until the ready-to-show event fires, preventing visual flicker during initialization. At that point, the window is shown, focused, and temporarily set to alwaysOnTop to ensure it appears above the splash screen before the splash is destroyed.
Closing the main window triggers a custom exitApp() sequence that hides the window, destroys the instance, and calls app.exit() to ensure clean termination.
Error Window Handling
Trigger Conditions
TUUI implements a dedicated error window to handle renderer crashes gracefully. The system monitors two critical failure points in src/main/index.ts:
render-process-gone: Fires when the renderer process crashes or is killeduncaughtException: Catches unhandled exceptions in the main process
Both events invoke createErrorWindow() from src/main/MainRunner.ts to present a user-friendly fallback UI.
Error Window Implementation
The error window factory accepts the existing main window instance and crash details, then constructs a replacement interface:
export const createErrorWindow = async (
errorWindow: BrowserWindow,
mainWindow: BrowserWindow,
_details?: RenderProcessGoneDetails
): Promise<BrowserWindow> => {
if (!Constants.IS_DEV_ENV) {
mainWindow?.hide()
}
errorWindow = new BrowserWindow({
title: Constants.APP_NAME,
show: false,
resizable: Constants.IS_DEV_ENV,
webPreferences: Constants.DEFAULT_WEB_PREFERENCES
})
errorWindow.setMenu(null)
if (Constants.IS_DEV_ENV) {
await errorWindow.loadURL(`${Constants.APP_INDEX_URL_DEV}#/error`)
} else {
await errorWindow.loadFile(Constants.APP_INDEX_URL_PROD, { hash: 'error' })
}
errorWindow.on('ready-to-show', () => {
if (!Constants.IS_DEV_ENV && mainWindow && !mainWindow.isDestroyed()) {
mainWindow.destroy()
}
errorWindow.show()
errorWindow.focus()
})
return errorWindow
}
In production, the main window is hidden before the error window appears, then destroyed once the error UI is ready. The error window loads the #/error route, displaying a dedicated Vue component for crash recovery.
Window Orchestration Flow
The complete window management system in TUUI follows this coordinated sequence:
- Application startup –
src/main/index.tscallscreateSplashWindow()to display the loading screen immediately - Main window preparation – While the splash is visible,
createMainWindow()constructs the primary UI (hidden initially) - Transition – Once the main window fires
ready-to-show, the splash window closes and the main window appears with temporaryalwaysOnTopfocus - Normal operation – The main window handles all user interactions until closure triggers
exitApp() - Error recovery – If
render-process-goneoruncaughtExceptionoccurs,createErrorWindow()hides the main window and presents the error UI, ensuring the application fails gracefully rather than crashing silently
Summary
- TUUI's window management system centralizes creation logic in
src/main/MainRunner.ts, exporting three factory functions:createSplashWindow(),createMainWindow(), andcreateErrorWindow() - Environment awareness drives resource loading through
src/main/utils/Constants.ts, distinguishing between development URLs and production file paths - Splash window provides immediate visual feedback as a frameless, transparent 400×300px overlay that loads before the main UI
- Main window implements platform-specific title bar styling with hidden overlays and manages lifecycle through
ready-to-showand customexitApp()handlers - Error window intercepts renderer crashes via
render-process-goneanduncaughtExceptionevents, gracefully replacing the main UI with a dedicated error route
Frequently Asked Questions
How does TUUI's window management system handle development versus production environments?
The system uses the Constants.IS_DEV_ENV flag defined in src/main/utils/Constants.ts to branch resource loading logic. In development, windows load from VITE_DEV_SERVER_URL endpoints (e.g., http://localhost:3000/splash.html), while production builds use loadFile() with relative paths to the bundled HTML files. This dual-mode approach ensures developers see live-reloaded changes while production users receive optimized static assets.
What triggers the error window to appear in TUUI?
The error window activates through two specific event listeners in src/main/index.ts. First, the render-process-gone event fires when the Chromium renderer process crashes or is terminated unexpectedly. Second, the uncaughtException event catches unhandled JavaScript errors in the main Node.js process. Both handlers invoke createErrorWindow() from src/main/MainRunner.ts, passing the crash details and main window reference to initiate the recovery UI.
How are the splash and main windows coordinated during application startup?
The orchestration occurs sequentially in src/main/index.ts. First, createSplashWindow() returns immediately and displays the loading screen. Then createMainWindow() constructs the primary window in a hidden state while the splash remains visible. Once the main window emits the ready-to-show event, the application calls splashWindow.close() to destroy the loading screen, then shows and focuses the main window with a temporary alwaysOnTop flag to prevent visual flicker during the transition.
Where are window configuration constants defined in the TUUI codebase?
All environment-specific URLs, dimension defaults, and web preferences are centralized in src/main/utils/Constants.ts. This file exports APP_SPLASH_URL_DEV, APP_SPLASH_URL_PROD, APP_INDEX_URL_DEV, APP_INDEX_URL_PROD, and DEFAULT_WEB_PREFERENCES used by the factory functions in src/main/MainRunner.ts. Centralizing these values ensures consistent window behavior across development and production builds while simplifying configuration maintenance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →