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.0Maximize / 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 DockResizable / 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 waySee 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">.
Related
- monitors — multi-display enumeration.
- menu — app menu bar click handling.
- Multi-Window guide.