Skip to Content

tyndWindow

import { tyndWindow } from "@tynd/core/client";

Every call auto-targets the window it runs in. Each WebView has an injected __TYND_WINDOW_LABEL__ used for routing. The primary window’s label is "main".

State getters

const isMax = await tyndWindow.isMaximized(); const isMin = await tyndWindow.isMinimized(); const isFull = await tyndWindow.isFullscreen(); const isVis = await tyndWindow.isVisible(); const isRes = await tyndWindow.isResizable(); const isCls = await tyndWindow.isClosable(); const isFoc = await tyndWindow.isFocused(); const isDec = await tyndWindow.isDecorated(); const label = tyndWindow.label(); // sync — "main" / "settings" / …

Title

await tyndWindow.setTitle("My App — Unsaved");

Size & position

Logical pixels — divide by scaleFactor() for device pixels.

await tyndWindow.setSize(1400, 900); const innerSize = await tyndWindow.getSize(); // { width, height } — client area const outerSize = await tyndWindow.getOuterSize(); // includes title bar + borders await tyndWindow.setPosition(100, 100); const { x, y } = await tyndWindow.getPosition(); await tyndWindow.setMinSize(400, 300); await tyndWindow.setMaxSize(1920, 1080); const dpi = await tyndWindow.scaleFactor(); // 1.0 / 1.5 / 2.0

Maximize / minimize / fullscreen

await tyndWindow.maximize(); await tyndWindow.unmaximize(); await tyndWindow.toggleMaximize(); await tyndWindow.minimize(); await tyndWindow.unminimize(); await tyndWindow.setFullscreen(true);

Visibility & focus

await tyndWindow.show(); await tyndWindow.hide(); await tyndWindow.setFocus(); // bring to front + keyboard focus await tyndWindow.requestAttention(); // flash taskbar / bounce Dock

Resizable / closable / maximizable / minimizable

await tyndWindow.setResizable(false); await tyndWindow.setClosable(false); await tyndWindow.setMaximizable(false); await tyndWindow.setMinimizable(false);

Decorations & always-on-top

await tyndWindow.setDecorations(false); // no title bar (build your own via CSS) await tyndWindow.setAlwaysOnTop(true); await tyndWindow.center();

WebView ops

await tyndWindow.reload(); await tyndWindow.setZoom(1.25); await tyndWindow.openDevTools(); // debug builds only await tyndWindow.closeDevTools();

Multi-window

interface CreateWindowOptions { label: string; // unique; cannot be "main" url?: string; // defaults to the primary window's entry title?: string; width?: number; height?: number; resizable?: boolean; decorations?: boolean; alwaysOnTop?: boolean; } await tyndWindow.create({ label: "settings", url: "/settings", title: "Settings", width: 600, height: 480, }); const labels = await tyndWindow.all(); // ["main", "settings", …] await tyndWindow.close("settings"); // "main" cannot be closed this way

See the Multi-Window guide.

Events

All on* return unsubscribe(). Events are broadcast to every webview and auto-filtered to the calling window’s label by the client helper — handlers only fire for their own window.

const offResize = tyndWindow.onResized(({ width, height }) => { /* … */ }); const offMove = tyndWindow.onMoved(({ x, y }) => { /* … */ }); const offFocus = tyndWindow.onFocused(() => { /* regained focus */ }); const offBlur = tyndWindow.onBlurred(() => { /* lost focus */ }); const offTheme = tyndWindow.onThemeChanged(({ theme }) => { /* "light" | "dark" */ }); const offDpi = tyndWindow.onDpiChanged(({ scale }) => { /* 1.5 on 150% */ }); // State transitions — fire only on flip, not initial state. const offMin = tyndWindow.onMinimized(() => {}); const offUnmin = tyndWindow.onUnminimized(() => {}); const offMax = tyndWindow.onMaximized(() => {}); const offUnmax = tyndWindow.onUnmaximized(() => {}); const offFull = tyndWindow.onFullscreen(() => {}); const offUnfull = tyndWindow.onUnfullscreen(() => {}); // Broadcast — receive events from every window (not filtered). const offClosed = tyndWindow.onClosed(({ label }) => console.log(label, "closed"));

Preventable close

preventDefault() must be called synchronously in the handler to cancel the close. The close proceeds after 500 ms if nothing cancels it.

interface CloseRequestedEvent { preventDefault(): void; } tyndWindow.onCloseRequested((e) => { if (hasUnsavedChanges()) { e.preventDefault(); // must be synchronous void showSavePromptThenMaybeClose(); } });

For an async confirm flow that exceeds 500 ms:

tyndWindow.onCloseRequested(async (e) => { if (!dirty) return; e.preventDefault(); await tyndWindow.cancelClose(); // explicit halt for async cases const discard = await dialog.confirm("Unsaved changes. Close?"); if (discard) await tyndWindow.close(tyndWindow.label()); });

cancelClose()

Cancel a pending close. Has effect during the 500 ms window after close-requested — after that, the app has already committed to exiting.

await tyndWindow.cancelClose();

CSP

Every HTML response served through tynd:// carries a baseline Content-Security-Policy. Override per-page via <meta http-equiv="Content-Security-Policy">.

Last updated on