Skip to content

widgetWindow ​

Create and manage desktop widget windows. Each window hosts a UI script and supports drag, snap, transparency, background images, animations, context menus, and events. UI scripts communicate via IPC.

javascript
import { widgetWindow } from "novadesk";

Availability

Available in the Main script only.

Table of Contents ​

Constructor ​

new widgetWindow(options) #
widgetWindow

Creates and shows a new desktop widget window.

If id is provided and a widget with the same id already exists, the existing widget is silently removed before the new one is created. If id matches a previously saved widget, the saved position and size are loaded as defaults (explicitly provided x, y, width, height override them). If no saved state exists yet, the initial position is automatically saved after the first successful creation.

Options:

Option Type Default Description
id string "" Unique identifier. Saved position/size are loaded by this ID on creation.
width number — Window width in pixels.
height number — Window height in pixels.
x number — Horizontal screen position in pixels.
y number — Vertical screen position in pixels.
script string — Path to the UI script. Must end with .ui.js (e.g. "ui/clock.ui.js"). Relative paths resolve from the entry script directory.
backgroundColor string "rgba(0,0,0,0)" Window background color or gradient. Supports rgb(), rgba(), linearGradient(), radialGradient().
opacity number | string 1 Master window opacity. Accepts 0.0–1.0, 0–100, 0–255, or a percentage string like "75%". Scales the entire window including all drawn elements.
draggable boolean true Allow the user to drag the window.
resizable boolean false Allow the user to resize the window by dragging its edges.
minWidth number 0 Minimum window width in pixels when resizing.
minHeight number 0 Minimum window height in pixels when resizing.
clickThrough boolean false Mouse events pass through the window to whatever is behind it.
keepOnScreen boolean false Prevent dragging the window off-screen.
snapEdges boolean true Snap to screen edges and other widgets while dragging.
show boolean true Show the window immediately after creation. Pass false to create it hidden and call win.show() later.
showInToolbar boolean false Show in the Windows taskbar.
toolbarIcon string "" Path to the taskbar icon.
toolbarTitle string "" Title shown in the Windows taskbar.
backgroundImage string "" Path to a background image. Supports local files and HTTP/HTTPS URLs.
backgroundImageFallback string "" Fallback image shown while the main image loads (or if it fails).
backgroundImageFallbackAspectRatio string "stretch" How the fallback background image is scaled. Values: "stretch", "preserve" / "fit" / "contain", "crop" / "cover". Also accepted as backgroundImageFallbackSize.
backgroundImageSize string | object "cover" How the image fits. String: "cover", "contain", "stretch". Object: { width, height } for explicit sizing.
backgroundImagePosition string | object "center" Image position. String: "top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right". Object: { x, y } for pixel offset.
zPos string "normal" Z-order position. See values below.

zPos values (case-insensitive):

Value Behavior
"ontopmost" Always on top of everything, including other topmost windows.
"ontop" Above normal windows.
"normal" Normal stacking order (default).
"onbottom" Behind all app windows. Hidden when "Show Desktop" is triggered.
"ondesktop" Sits over the desktop. Ideal for wallpaper-style widgets.

Script must end with .ui.js

If script does not end with .ui.js, the window is created but the script is not executed. The UI will be blank. Valid examples: "script.ui.js", "ui/clock.ui.js".

opacity vs backgroundColor alpha

opacity sets the Win32 layered window opacity — it scales the entire window including all UI elements. The alpha component of backgroundColor only affects the background fill. Setting opacity: 0 makes everything invisible. Setting backgroundColor: "rgba(0,0,0,0)" only makes the background transparent while UI elements remain visible.

PARAMETERS

options object
Window configuration object. See options table below.
javascript
import { widgetWindow } from "novadesk";

const win = new widgetWindow({
  id: "my-widget",
  width: 400,
  height: 300,
  script: "script.ui.js",
  backgroundColor: "rgb(10,10,10)",
  draggable: true,
  resizable: true,
  snapEdges: true,
  showInToolbar: true,
  toolbarTitle: "My Widget"
});

Window State ​

win.show() #
widgetWindow

Shows the widget window. Fires the show event.

RETURNS: widgetWindow The widget instance (chainable).
javascript
win.show();
win.hide() #
widgetWindow

Hides the widget window. Fires the hide event.

RETURNS: widgetWindow The widget instance (chainable).
javascript
win.hide();
win.close() #
widgetWindow

Destroys the widget window and releases all resources. Fires the close and closed events.

javascript
win.close();
win.destroy() #
widgetWindow

Destroys the widget window immediately without firing the close event. Use close() for normal shutdown; use destroy() when you need to remove the window silently.

javascript
win.destroy();
win.isVisible() #
widgetWindow

Returns whether the window is visible.

RETURNS: boolean true if the window is currently visible.
javascript
if (!win.isVisible()) win.show();
win.isFocused() #
widgetWindow

Returns whether the window has keyboard focus.

RETURNS: boolean true if the window currently has keyboard focus.
javascript
console.log("Focused:", win.isFocused());
win.isDestroyed() #
widgetWindow

Returns whether the window has been destroyed. Safe to call even after the window is closed. Check this before calling other methods on a window that may have been closed elsewhere.

RETURNS: boolean true if the window has been destroyed.
javascript
if (!win.isDestroyed()) {
  win.setProperties({ width: 500 });
}
win.setResizable(enable) #
widgetWindow

Enables or disables window resizing by the user dragging the window edges. When enabled, a thin resize border appears around the window.

Not persisted

The resizable state is not saved to disk. The window will revert to resizable: false on the next launch unless you set it again in the constructor or via setResizable().

PARAMETERS

enable boolean
true to allow the user to resize by dragging edges. false to disable.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setResizable(true);   // user can now drag edges to resize
win.setResizable(false);  // lock the size
win.isResizable() #
widgetWindow

Returns whether the user can resize the window by dragging its edges.

RETURNS: boolean true if the window is currently resizable.
javascript
console.log("Resizable:", win.isResizable());
win.isResizing() #
widgetWindow

Returns whether the window is in the process of being resized (user is dragging an edge).

RETURNS: boolean true if the window is currently being resized by the user.
javascript
win.on("resize", () => {
  if (win.isResizing()) {
    console.log("User is resizing...");
  }
});
win.setMinWidth(width) #
widgetWindow

Sets the minimum width the window can be resized to.

PARAMETERS

width number
Minimum width in pixels.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setMinWidth(200);
win.getMinWidth() #
widgetWindow

Returns the current minimum width.

RETURNS: number The minimum width in pixels.
javascript
console.log("Min width:", win.getMinWidth());
win.setMinHeight(height) #
widgetWindow

Sets the minimum height the window can be resized to.

PARAMETERS

height number
Minimum height in pixels.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setMinHeight(150);
win.getMinHeight() #
widgetWindow

Returns the current minimum height.

RETURNS: number The minimum height in pixels.
javascript
console.log("Min height:", win.getMinHeight());
win.setMinSize(width, height) #
widgetWindow

Sets both minimum width and height in one call.

PARAMETERS

width number
Minimum width in pixels.
height number
Minimum height in pixels.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setMinSize(200, 150);
win.getMinSize() #
widgetWindow

Returns the current minimum size.

RETURNS: object An object with width and height.
javascript
const min = win.getMinSize();
console.log("Min size:", min.width, "x", min.height);
win.minimize() #
widgetWindow

Minimizes the widget window. Fires the minimize event.

javascript
win.minimize();
win.unMinimize() #
widgetWindow

Restores a minimized widget window. Fires the unMinimize event.

javascript
win.unMinimize();
win.isMinimized() #
widgetWindow

Returns whether the window is minimized.

RETURNS: boolean true if the window is currently minimized.
javascript
if (win.isMinimized()) {
  win.unMinimize();
}
win.maximize() #
widgetWindow

Maximizes the widget window to fill the work area.

javascript
win.maximize();
win.restore() #
widgetWindow

Restores a maximized window to its previous size and position.

javascript
win.restore();
win.toggleMaximize() #
widgetWindow

Toggles between maximized and normal window state.

javascript
win.toggleMaximize();
win.isMaximized() #
widgetWindow

Returns whether the window is maximized.

RETURNS: boolean true if the window is currently maximized.
javascript
if (!win.isMaximized()) {
  win.maximize();
}
win.setFocus() #
widgetWindow

Gives keyboard focus to the widget window.

javascript
win.setFocus();
win.unFocus() #
widgetWindow

Removes keyboard focus from the widget window.

javascript
win.unFocus();
win.refresh() #
widgetWindow

Clears all UI elements and re-executes the widget's UI script. Stale ipcRenderer listeners from the previous run are automatically cleaned up before the new script executes.

javascript
win.refresh();

Background Image ​

win.setBackgroundImage(path, size, position) #
widgetWindow

Sets the window background image. The image is drawn behind all UI elements but on top of backgroundColor.

Size modes:

Mode Behavior
"cover" Image fills the window, cropping if needed to maintain aspect ratio (default).
"contain" Image fits inside the window, letterboxing if needed to maintain aspect ratio.
"stretch" Image stretches to fill the window exactly, ignoring aspect ratio.
{ width, height } Explicit pixel size. Omit one dimension to auto-scale while maintaining aspect ratio.

Position keywords:

"top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right"

PARAMETERS

path string
Path to the image file. Supports local files and HTTP/HTTPS URLs.
size string | object OPTIONAL
Image fit mode: cover (default), contain, stretch, or { width, height } for explicit sizing.
position string | object OPTIONAL
Image position: center (default), or a keyword / { x, y } offset.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setBackgroundImage("./assets/wallpaper.jpg");
win.setBackgroundImage("./assets/bg.png", "contain");
win.setBackgroundImage("./assets/bg.png", "cover", "top-left");
win.setBackgroundImage("./assets/bg.png", { width: 200 }, "center");
win.getBackgroundImage() #
widgetWindow

Returns the current background image path.

RETURNS: string The current background image path, or empty string if none.
javascript
console.log("BG image:", win.getBackgroundImage());
win.setBackgroundImageFallback(path) #
widgetWindow

Sets a fallback image that displays while the main backgroundImage is loading (or if it fails to load).

PARAMETERS

path string
Fallback image path. Shown while the main image loads or if it fails to load.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setBackgroundImageFallback("./assets/placeholder.png");
win.setBackgroundImage("https://example.com/wallpaper.jpg");
win.setBackgroundImageFallbackAspectRatio(mode) #
widgetWindow

Sets the aspect ratio mode for the fallback background image. This controls how the fallback is scaled independently of the main background image size setting.

PARAMETERS

mode string
How the fallback image is scaled. Accepted values: "stretch" (default), "preserve" / "fit" / "contain", "crop" / "cover".
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setBackgroundImageFallback("./assets/placeholder.jpg");
win.setBackgroundImageFallbackAspectRatio("preserve"); // show full fallback, letterboxed
win.setBackgroundImage("https://example.com/wallpaper.jpg", "cover");

Window Animation ​

win.animate(options) #
widgetWindow

Animates the window's position, size, and opacity using either a simple A-to-B tween or a multi-stop keyframe timeline.

Every call is fire-and-forget — there is no callback when the animation completes. Calling animate() on a window that is already animating immediately replaces the running animation.

Options:

Property Type Required Default Description
duration number No 250 Duration in milliseconds.
easing string No "linear" Easing function name. See easing reference.
iterationCount number / "infinite" No 1 How many times to play. Must be ≥ 1 or "infinite".
to object Tween only — Target values. See animatable properties below.
from object No Current state Starting values. Omit to start from current state. Accepts the same properties as to.
keyframes array / object Keyframe only — Multi-stop timeline. Cannot be combined with to/from.

Animatable properties (in from, to, and each keyframe):

Property Type Description
x number / string Horizontal position in pixels, or a screen keyword expression (see below).
y number / string Vertical position in pixels, or a screen keyword expression (see below).
width number Window width in pixels. Alias: w.
height number Window height in pixels. Alias: h.
opacity number Window opacity 0.0–1.0. Alias: alpha.
backgroundColor string Background color to animate to. Alias: bgColor.
position string Screen position preset (see below). Alias: align.
offsetX number Pixel offset applied after resolving position.
offsetY number Pixel offset applied after resolving position.

Screen position presets (position / align):

Preset Aliases Resolves to
"top-left" "topleft" Top-left corner of the work area.
"top-center" "top" Top center of the work area.
"top-right" "topright" Top-right corner of the work area.
"center-left" "left" Left edge, vertically centered.
"center" "middle" Dead center of the work area.
"center-right" "right" Right edge, vertically centered.
"bottom-left" "bottomleft" Bottom-left corner of the work area.
"bottom-center" "bottom" Bottom center of the work area.
"bottom-right" "bottomright" Bottom-right corner of the work area.

Work area

The "work area" is the portion of the screen excluding the taskbar. Position presets align the window's top-left corner to that screen location.

String expressions for x and y:

Instead of a number, x and y accept a string keyword with an optional pixel offset:

Keyword X resolves to Y resolves to
"left" Left edge of work area —
"center" / "middle" Horizontally centered Vertically centered
"right" Right edge minus window width —
"top" — Top edge of work area
"bottom" — Bottom edge minus window height
"offscreen-left" Left edge minus window width (hidden) —
"offscreen-right" Right edge (hidden) —
"offscreen-top" — Top edge minus window height (hidden)
"offscreen-bottom" — Bottom edge (hidden)

PARAMETERS

options object
Animation configuration object.
RETURNS: widgetWindow The widget instance (chainable).
javascript
// Slide the window in from off-screen
win.animate({
  duration: 500,
  easing: "easeOutCubic",
  from: { x: -400 },
  to: { x: 100 }
});

// Fade in
win.animate({
  duration: 300,
  from: { opacity: 0 },
  to: { opacity: 1 }
});

// Infinite bounce
win.animate({
  duration: 700,
  iterationCount: "infinite",
  from: { y: 100 },
  to: { y: 80 }
});

// Keyframe: slide in then settle
win.animate({
  duration: 800,
  keyframes: [
    { offset: 0, x: -400 },
    { offset: 0.6, x: 120, easing: "easeOutBack" },
    { offset: 1, x: 100 }
  ]
});

// Animate to a screen position
win.animate({
  duration: 400,
  easing: "easeOutCubic",
  to: { position: "bottom-center" }
});

// Use position with an offset
win.animate({
  duration: 300,
  to: { position: "top-right", offsetX: -20, offsetY: 20 }
});

// String expression for x/y
win.animate({
  duration: 500,
  from: { x: "offscreen-left" },
  to: { x: "left", y: "center" }
});

// Animate background color
win.animate({
  duration: 600,
  from: { backgroundColor: "rgb(0,0,0)" },
  to: { backgroundColor: "rgb(30,30,60)" }
});
win.stopAnimation() #
widgetWindow

Stops all running window animations. The window stays at its current position/size/opacity.

RETURNS: widgetWindow The widget instance (chainable).
javascript
win.stopAnimation();

Properties ​

win.setProperties(options) #
widgetWindow

Updates one or more window properties at runtime.

PARAMETERS

options object
Partial options object. Accepts the same keys as the constructor. Only the provided keys are changed.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setProperties({ width: 600, height: 400 });
win.setProperties({ backgroundColor: "rgb(30,30,30)", draggable: false });
win.setProperties({ show: false }); // equivalent to win.hide()
win.getProperties() #
widgetWindow

Returns the current state of all window properties. Note: zPos is returned as a number (-2 to 2), not a string.

RETURNS: object An object with id, x, y, width, height, draggable, clickThrough, keepOnScreen, snapEdges, showInToolbar, toolbarIcon, toolbarTitle, show (live visibility), windowOpacity (0–255), backgroundColor, zPos (as a number), and script.
javascript
const props = win.getProperties();
console.log("Position:", props.x, props.y);
console.log("Size:", props.width, "x", props.height);

Position and Size ​

win.setBounds(bounds) #
widgetWindow

Sets the position and/or size of the window in one call. Throws TypeError if the argument is not an object.

PARAMETERS

bounds object
Object with optional x, y, width, height properties. Omitted keys are left unchanged.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setBounds({ x: 100, y: 100, width: 500, height: 400 });
win.setBounds({ width: 600 }); // change only width
win.getBounds() #
widgetWindow

Returns the current position and size of the window using screen coordinates.

RETURNS: object An object with x, y, width, and height in screen coordinates. Returns null if the window handle is not available.
javascript
const b = win.getBounds();
console.log("At:", b.x, b.y, "Size:", b.width, "x", b.height);
win.setSize(width, height) #
widgetWindow

Sets the window size without changing its position. Throws TypeError if fewer than two number arguments are provided.

PARAMETERS

width number
New width in pixels.
height number
New height in pixels.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setSize(800, 600);
win.getSize() #
widgetWindow

Returns the current window size.

RETURNS: object An object with width and height. Returns null if the window handle is not available.
javascript
const { width, height } = win.getSize();
console.log(width, "x", height);

Color and Opacity ​

win.setBackgroundColor(color) #
widgetWindow

Sets the window background color or gradient.

PARAMETERS

color string
Color string. Supports rgb(), rgba(), linearGradient(), radialGradient().
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setBackgroundColor("rgba(20,20,30,0.95)");
win.getBackgroundColor() #
widgetWindow

Returns the current background color.

RETURNS: string The current background color string.
javascript
console.log("BG:", win.getBackgroundColor());
win.setOpacity(value) #
widgetWindow

Sets the master window opacity. Scales the entire window including all UI elements. Throws TypeError if the argument is not a number.

Range Interpretation
0.0–1.0 Fractional opacity (e.g. 0.75 = 75%)
1.0–100.0 Percentage (e.g. 75 = 75%)
100.0–255.0 Raw byte (e.g. 191 = 75%)

PARAMETERS

value number
Opacity as 0.0–1.0, 0–100, or 0–255. Auto-detected and normalized.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setOpacity(0.75); // 75% opacity
win.setOpacity(128);  // ~50% opacity

Context Menu ​

win.setContextMenu(items) #
widgetWindow

Sets the right-click context menu. Replaces any previous menu and clears all previous action callbacks.

Menu item properties:

Property Type Description
text string Label text.
action function Callback invoked when the item is clicked.
type string "separator" inserts a horizontal divider. Separator items ignore all other properties.
checked boolean Shows a checkmark when true.
items object[] Nested sub-menu items (recursively supports the same schema).

PARAMETERS

items object[]
Array of menu item definitions. Replaces the entire existing menu. Throws TypeError if not an array.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.setContextMenu([
  { text: "Refresh", action: () => win.refresh() },
  {
    text: "Tools",
    items: [
      { text: "Debug", checked: false, action: () => app.enableDebugging(true) }
    ]
  },
  { type: "separator" },
  { text: "Close", action: () => win.close() }
]);
win.clearContextMenu() #
widgetWindow

Removes all custom context menu items and clears their registered callbacks.

RETURNS: widgetWindow The widget instance (chainable).
javascript
win.clearContextMenu();
win.disableContextMenu(disable) #
widgetWindow

Enables or disables the right-click context menu.

PARAMETERS

disable boolean
true to disable the right-click menu entirely. false to re-enable it. Defaults to true if omitted.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.disableContextMenu(true);   // no right-click menu
win.disableContextMenu(false);  // restore menu
win.showDefaultContextMenuItems(show) #
widgetWindow

Controls whether built-in Novadesk context menu entries (e.g. Refresh, Close) are shown alongside custom items.

PARAMETERS

show boolean
true to include the built-in Novadesk default menu items. false to hide them.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.showDefaultContextMenuItems(false); // custom items only

Events ​

win.on(event, callback) #
widgetWindow

Registers an event listener on the widget window. Mouse events pass a Mouse Event Object to the callback. Throws TypeError if the callback is not a function or the event name is empty.

Supported events:

Event Trigger
show Window became visible
hide Window was hidden
focus Window gained keyboard focus
unFocus Window lost keyboard focus
minimize Window was minimized
unMinimize Window was restored from minimized state
move Window position changed
resize Window was resized (width or height changed)
resizeStart Window resize operation started (user began dragging an edge). Alias: resize-start
resizeEnd Window resize operation ended (user released the edge). Alias: resize-end
refresh UI script was refreshed
close Window is about to close (fired by close(), not by destroy())
closed Window has been fully destroyed
mouseOver Mouse entered the window area
mouseLeave Mouse left the window area
mouseMove Mouse moved over the window
mouseDown Any mouse button was pressed
mouseUp Any mouse button was released
click Left click released on the window
right-click Right click released on the window
double-click Left button double-clicked
scroll-up Mouse wheel scrolled up
scroll-down Mouse wheel scrolled down

PARAMETERS

event string
Event name. See supported events below.
callback function
Handler. Mouse events receive a Mouse Event Object.
RETURNS: widgetWindow The widget instance (chainable).
javascript
win.on("click", (e) => {
  console.log("Clicked at:", e.__clientX, e.__clientY);
});

win.on("mouseMove", (e) => {
  console.log("Mouse:", e.__clientX, e.__clientY);
});

win.on("close", () => {
  console.log("Window closing");
  cleanup();
});

win.on("resize", () => {
  const { width, height } = win.getSize();
  console.log("New size:", width, "x", height);
});

win.on("resizeStart", () => {
  console.log("User started resizing");
});

win.on("resizeEnd", () => {
  console.log("User finished resizing");
  const { width, height } = win.getSize();
  console.log("Final size:", width, "x", height);
});

Native Interop ​

win.getHandle() #
widgetWindow

Returns the native window handle. Useful when passing to a native addon that needs a parent window.

RETURNS: number The native Windows HWND as a number.
javascript
const hwnd = win.getHandle();
win.getInternalPointer() #
widgetWindow

Returns the raw Widget pointer. Useful when passing the widget reference to a native addon.

RETURNS: number The internal native Widget pointer as a number.
javascript
const ptr = win.getInternalPointer();
win.getTitle() #
widgetWindow

Returns the current window title.

RETURNS: string The window title string.
javascript
console.log("Title:", win.getTitle());

Runtime Overrides ​

When the Ctrl key is held down, the runtime temporarily overrides some interaction settings:

  • Dragging works even when draggable: false
  • Click-through widgets become interactable
  • Snap behavior can be bypassed for precise placement

Practical Examples ​

Basic widget with tray and context menu

javascript
import { widgetWindow, tray, app } from "novadesk";

const win = new widgetWindow({
  id: "demo",
  width: 400,
  height: 300,
  script: "script.ui.js",
  backgroundColor: "rgb(10,10,10)",
  snapEdges: true
});

const appTray = new tray(path.join(__dirname, "assets", "icon.ico"));
appTray.setToolTip("My Widget");
appTray.on("click", () => win.show());

win.setContextMenu([
  { text: "Refresh", action: () => win.refresh() },
  { type: "separator" },
  { text: "Exit", action: () => app.exit() }
]);

Hidden window revealed on demand

javascript
const win = new widgetWindow({
  id: "popup",
  width: 300,
  height: 200,
  script: "popup.ui.js",
  show: false   // start hidden
});

ipcMain.on("show-popup", () => win.show());
ipcMain.on("hide-popup", () => win.hide());

Resize window based on content

javascript
const win = new widgetWindow({
  id: "dynamic",
  width: 300,
  height: 100,
  script: "dynamic.ui.js"
});

ipcMain.on("content-changed", (event, payload) => {
  const newHeight = 60 + payload.itemCount * 30;
  win.setSize(300, newHeight);
});

Dynamic opacity on hover

javascript
const win = new widgetWindow({
  id: "fade",
  width: 300,
  height: 200,
  script: "fade.ui.js",
  opacity: 0.4
});

win.on("mouseOver", () => win.setOpacity(1.0));
win.on("mouseLeave", () => win.setOpacity(0.4));