Appearance
Window
Programmatic window controls from JavaScript and an opt-in CSS-driven window drag listener.
| Config key | window |
| JS namespace | Window |
| Core | No |
| Phases | Bindable · WebviewInject |
| Hard deps | — |
| Platforms | macOS · Linux · Windows |
The Window plugin exposes runtime window controls to JavaScript — minimize, maximize, center, resize, retitle — and a CSS-driven drag listener for custom title bars. For initial window size, title, and macOS chrome options, see Window Configuration.
JavaScript API
js
import { lune } from "../lunejs/runtime/runtime.js";
await lune.Window.minimize();
await lune.Window.maximize();
await lune.Window.center();
await lune.Window.setTitle("My App — Unsaved");
await lune.Window.setSize(1440, 900);| Method | Signature | Returns |
|---|---|---|
minimize | minimize() | Promise<void> |
maximize | maximize() | Promise<void> |
center | center() | Promise<void> |
setTitle | setTitle(title) | Promise<void> |
setSize | setSize(width, height) | Promise<void> |
lune.Window.startDrag is also exposed but is invoked by the auto-injected mousedown listener — application code rarely calls it directly.
Window drag (macOS + Windows)
Tag DOM elements with a CSS custom property and mousedown on them initiates a native window drag. Essential when using a custom title bar without the OS chrome.
crystal
Lune.run(app) do |opts|
opts.window.drag_zone = "--lune-draggable"
end| Option | Type | Default | Description |
|---|---|---|---|
drag_zone | String | "" | CSS custom property name that marks drag handles. Empty means no listener is installed. |
Mark an element as a drag handle with an inline style. Any non-empty value on the configured property activates the drag — write true for clarity:
html
<div style="--lune-draggable: true">Title bar</div>Inline style required. Detection reads
style.getPropertyValuedirectly and walks up the DOM, so marking a container makes all children draggable too.
When drag_zone is empty (the default), no mousedown listener is installed and the start_drag binding is unused — the plugin behaves exactly like before the drag feature existed. To "disable" drag, leave drag_zone unset.
Notes
setSizesets the content area in logical pixels (independent of screen DPI).- For initial size and position constraints (
min_width,max_width, etc.) use the Window Configuration options.
Platform notes
- macOS — Verified. Programmatic controls + drag both work.
- Linux — Untested. Programmatic controls only —
drag_zonehas no effect (drag needs_NET_WM_MOVERESIZE; tracked in ROADMAP.md). - Windows — Verified. Programmatic controls +
drag_zone(mousedown →ReleaseCapture+SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0)). Window state opt-in viaremember_frame = true(liveGetWindowRecttracker since HWND is destroyed before save). Chrome opts are macOS-only.
Disabling
yaml
plugins:
disabled:
- windowThis turns off everything — the JS bindings AND the drag listener. To keep the programmatic controls but turn off drag, leave opts.window.drag_zone empty (the default).