Changelog
[0.9.13.0-beta] - 2026-09-28
📅 28th September, 2026
Changed & Improved
- Manage Novadesk UI & Widget List:
- Double-clicking any widget in the Manage Novadesk widget list now toggles its loaded state (load/unload).
- Maintained item selection and view scroll position across list refreshes when toggling or refreshing widgets.
- Added
LVS_SHOWSELALWAYSstyle so the selected widget remains highlighted when focus shifts to other controls. - Optimized list rebuilds with
WM_SETREDRAWsuppression to eliminate visual flicker during updates.
- Script Path Handling & Engine Stability:
- Improved script path comparisons throughout
JSEngine(destruction, timers, IPC listeners/handlers, trays, webFetch) using case-insensitive normalization to prevent duplicate script instances and stale listener leaks on Windows. - Switched script evaluation revision tracking to an atomic global revision counter for reliable module re-evaluation.
- Improved script path comparisons throughout
[0.9.12.0-beta] - 2026-09-27
📅 27th September, 2026
Added
- Added
app.beginWindowBatch()andapp.endWindowBatch()— batches window show and hide operations to eliminate visual flicker when toggling multiple windows simultaneously. - Added
widgetWindowconstructor optionbackgroundImageFallbackAspectRatio(and aliasbackgroundImageFallbackSize) and methodwin.setBackgroundImageFallbackAspectRatio(mode). - Added
fallbackAspectRatiooption to image elements (ui.addImage()and general image options) supporting"stretch","preserve"/"fit"/"contain", and"crop"/"cover". - Enhanced gradient parser:
- Supported CSS-style aliases
linear-gradient(...)andradial-gradient(...). - Supported direction keywords (
to top,to bottom,to right,to left,to top right,to bottom right,to top left,to bottom left). - Supported angle unit specifiers (
deg,rad,turn) and raw numbers. - Supported explicit stop positions (percentages or decimals) with automatic linear interpolation for omitted stops.
- Supported CSS-style aliases
- Upgraded Native Addon Host API to Version 2 (
NOVADESK_ADDON_API_VERSION 2):- Added
novadesk::Apphelper class providing read-only access to host versions, paths, portable mode, and first-run state. - Added automatic
NovadeskAddonApiVersion()DLL export inNOVADESK_ADDON_INITfor host compatibility verification.
- Added
- Added
minimumNovadeskVersionmetadata field support inmeta.jsonfor widget package installer compatibility checks. - Added immediate saving of first-run widget position and state when created with an
id. - Added colored console logging output for errors, warnings, and info messages.
Changed & Improved
- Updated default installer setup name to
{NAME}_Setupin template and widget packaging. - Changed log level of background application and tray icon events from Info to Debug to reduce console noise.
- Switched InputBox text antialiasing to grayscale rendering for improved clarity on transparent layered window surfaces.
- Preserved authored element positions for text elements during animation queries rather than calculated layout bounds.
Fixed
- Fixed widget window position updates for
m_Options.xandm_Options.yto eliminate position flickering. - Fixed mouse message handling and click dispatch order to prioritize frontmost interactive controls over transparent display-only overlays.
- Fixed drag gesture initiation on draggable controls during left mouse button down.
- Fixed input box focus and caret positioning during programmatic and mouse click interactions.
- Fixed element destruction ordering to ensure child controls are cleanly detached without invalid container references.
- Fixed widget instance cleanup in event bindings ensuring proper deregistration from global tracking upon deletion.
[0.9.11.0-beta] - 2026-09-09
📅 09th September, 2026
Added
- Added
ipcMain.removeListener(channel, listener)— removes a specific previously-registeredipcMain.on()listener.ipcMain.off()is an alias. - Added
ipcMain.removeAllListeners([channel])— removes allipcMain.on()listeners, optionally scoped to a channel. - Added
ipcMain.removeHandler(channel)— unregisters the handler set byipcMain.handle()for a specific channel. - Added
ipcRenderer.removeListener(channel, listener)— removes a specific previously-registeredipcRenderer.on()listener.ipcRenderer.off()is an alias. - Added
ipcRenderer.removeAllListeners([channel])— removes allipcRenderer.on()listeners, optionally scoped to a channel. - Added
widgetWindow.minimize()— minimizes the widget window. Fires theminimizeevent. - Added
widgetWindow.unMinimize()— restores a minimized widget window. Fires theunMinimizeevent. - Added
widgetWindow.isMinimized()— returnstrueif the window is currently minimized. - Added
widgetWindow.maximize()— maximizes the widget window to fill the work area. - Added
widgetWindow.restore()— restores a maximized window to its previous size and position. - Added
widgetWindow.toggleMaximize()— toggles between maximized and normal state. - Added
widgetWindow.isMaximized()— returnstrueif the window is currently maximized. - Added
widgetWindow.setMinWidth(width),widgetWindow.getMinWidth()— set/get minimum resize width. - Added
widgetWindow.setMinHeight(height),widgetWindow.getMinHeight()— set/get minimum resize height. - Added
widgetWindow.setMinSize(width, height),widgetWindow.getMinSize()— set/get both minimum dimensions at once. - Added
widgetWindow.isResizing()— returnstruewhile the user is dragging a window edge. - Added
widgetWindow.getHandle()— returns the native Win32HWNDas a number. - Added
widgetWindow.getInternalPointer()— returns the raw internal Widget pointer as a number. - Added
widgetWindow.getTitle()— returns the current window title string. - Added
widgetWindow.stopAnimation()— stops all running window animations at the current frame. - Added
widgetWindow.isDestroyed()— returnstrueif the window has been destroyed; safe to call afterclose(). - Added
resizeStart/resize-startevent — fires when the user begins dragging a window edge. - Added
resizeEnd/resize-endevent — fires when the user releases the window edge after resizing. - Added
dialog.showOpenDialog(options)— native Windows file open dialog; supports filters and multi-select. - Added
dialog.showSaveDialog(options)— native Windows file save dialog; supports filters anddefaultExtension. - Added
dialog.openDirectory(options)— native Windows folder picker dialog. - Added
dialog.showFileExplorerDialog(options)/dialog.showFileExplorer(options)— unified file explorer dialog supporting"open","save","directory", and"folder"modes. - Added
dialog.openFile(options)— shorthand forshowOpenDialog. - Added
dialog.saveFile(options)— shorthand forshowSaveDialog. - Added
app.argv— array of filtered command-line arguments (internal Novadesk flags removed). Contains executable path, entry script, and user arguments. - Added
app.rawArgv— array of all raw command-line arguments including internal flags. - Added
system.colorsmodule for reading Windows system and accent colors:colors.get()— returns a full object of all system theme colors.colors.isDarkMode()— returnstruewhen Windows is using a dark color scheme.colors.getAccent()— returns the current Windows accent color object.colors.getColor(name)— returns a specific named system color.
[0.9.10.0-beta] - 2026-08-13
📅 13th August, 2026
Added
- Added
dialog.show(options)API for displaying native Windows modal dialogs from JavaScript scripts.- Supports
title,message,type, andbuttonsoptions. typeaccepts"info"/"information","warning"/"warn","error", and"question".buttonsaccepts"ok","ok-cancel","yes-no","yes-no-cancel","retry-cancel", and"abort-retry-ignore". Hyphenated and non-hyphenated forms are both supported (e.g."ok-cancel"and"okcancel").- Returns the clicked button as a lowercase string:
"ok","cancel","yes","no","retry","abort", or"ignore". - Defaults to
type: "info"andbuttons: "ok"when not specified. Empty strings also fall back to defaults. - Both
typeandbuttonsare case-insensitive.
- Supports
- Added
toastAPI for sending Windows toast notifications from JavaScript scripts.toast.show(options)— displays a notification and returns a numeric toast ID, ornullon failure.toast.hide(id)— programmatically dismisses a notification by ID.toast.clear()— dismisses all active notifications from the current widget session.toast.initialize([options])— explicitly initializes the notification system with custom app identity (appName,companyName,productName,aumi). Called automatically bytoast.show()if not already initialized.toast.isCompatible()— checks whether Windows toast notifications are supported on the current system.toast.isInitialized()— returns whether the notification system is ready.toast.getLastError()— returns the error message from the last failedtoast.show()call.toast.show()supports:title,message/body,thirdLine,attribution,image/imagePath,heroImage/heroImagePath,inlineHeroImage,crop,actions,input,duration,scenario,audio,audioPath,silent,loop, andexpiration.- Callback support:
onActivated/onActivate/onClick,onAction,onInput,onDismissed/onDismiss,onFailed/onFail. durationaccepts"short","long", and"system".scenarioaccepts"default","alarm","incomingCall"/"incoming-call", and"reminder".audioaccepts"default","im","mail","reminder","sms","alarm", and"call".cropaccepts"square"(default) and"circle".- Relative paths for
image,heroImage, andaudioPathresolve from the current script directory.
- Added online font support for Text and InputBox elements.
- Font URLs can be passed to
fontPathto download and use remote fonts. - Fonts are loaded asynchronously so the UI does not block while a font downloads.
- Downloaded fonts are cached in memory to avoid repeated network requests.
- Added WOFF2 / Brotli decompression support for downloaded fonts.
- Font URLs can be passed to
- Added URL support for widget UI scripts — UI scripts can now be loaded from remote locations in addition to local file paths.
- Added URL support for image element sources —
image,Bitmap,Button, andRotatorelements can now load images directly from HTTP/HTTPS URLs.- A built-in fallback image is displayed while a remote image is loading or if it fails.
- Custom fallback paths can be set via
SetFallbackPath().
Improved
- Improved
AreaGraphElementdimension calculations. Rendering dimensions now consistently use the element's calculated width and height, with padding properly taken into account for the drawable area. - Improved asynchronous font downloading — the widget window handle is now guaranteed to be available before any async font operation begins.
- Improved in-memory font loading and caching through
FontManager. Fonts no longer rely on persistent temporary files, improving font lifetime and reuse. - Reduced unnecessary log output from
ButtonElementby disabling the informational render log generated after each successful render pass.
Fixed
- Fixed
TIMER_ANIMATIONandkTimerIdto use timer ID6, keeping timer identifiers consistent between animation and widget code.
[0.9.9.0-beta] - 2026-07-04
📅 04th July, 2026
Added
- Added text selection support for Text elements with
textSelection,selectionBackgroundColor, andselectionTextColor. - Added the Direct2D-rendered
InputBoxUI element viaui.addInputBox. - Added
hiddenanddashedsupport toLayoutBoxborderStyle.
[0.9.8.0-beta] - 2026-06-17
📅 17th June, 2026
Added
- Added support for
"double"border style toLayoutBoxborder system. - Added
flexDirectionproperty ("row","rowreverse","column","columnreverse") toLayoutBoxto configure modern flexbox flow layouts. - Added
displayproperty ("flex","none","list-item") toLayoutBoxto manage layout and visibility. - Added support for hyphenated CSS-like formats (e.g.
"left-top","center-center") and"middle"aliases fortextAlignproperty on Text elements.
Removed
- Removed
minWidthandminHeightproperties fromLayoutBoxelements.
[0.9.7.0-beta] - 2026-06-02
📅 2nd June, 2026
Added
- Added new
app.storagepersistent JSON storage API:app.storage.get(key[, defaultValue])- retrieves stored values or returns default fallbackapp.storage.set(key, value)- stores key-value pairs persistently instorage.jsonapp.storage.remove(key)- deletes key-value pairs from persistent storage
- Added
LayoutBoxcontainer element (ui.addLayoutBoxandui.layoutBox) supporting layout direction (row/column), alignment, padding, gaps, and nested composition of children. - Enhanced
LayoutBoxborder system with support for CSS-likeborderStyleproperties, allowing"solid","none","inset","outset","groove","ridge", and"dotted"borders, customized globally or per-side. - Introduced
ui.animate(options)API for animating UI element properties:- Keyframe timeline animations via
keyframesproperty (supports array syntax and percentage-key object syntax). - Tween animations supporting starting states via
fromproperty. - Loop control using
iterationCount(can be a number or"infinite"). - Typography property animation (
fontSize,fontWeight,letterSpacing,fontColor) on Text elements inside keyframe timelines.
- Keyframe timeline animations via
[0.9.6.0-beta] - 2026-05-21
21st May, 2026
Added
- Added
system.cpu.getUpTime(...)to thesystemmodule CPU API.
Improved
- Improved
isTrackedElementwith recursive search to support safer validation for nested child elements. - Updated InputBox addon to support small width and height values.
Fixed
- Fixed a critical engine crash in
HandleMouseMessagecaused by dangling element pointers when elements were deleted during JS event callbacks. - Fixed Manage Novadesk window lifecycle so it exits automatically when Novadesk closes.
- Fixed QuickJS UI IPC listener ownership by binding
ipcRenderer.oncallbacks to the active__filenamescript path, ensuring stale widget listeners are cleared on refresh and preventing duplicate update flicker.
[0.9.5.0-beta] - 2026-05-15
📅 15th May, 2026
Improved
- Optimized widget engine script loading (
AddScript) to be non-destructive. Adding new scripts no longer triggers a global runtime reset, ensuring existing active widgets remain stable. - Optimized
diskmodule performance by initializing PDH disk IO counters asynchronously. - Miscellaneous tweaks and stabilization for the widget Context Menu API.
Fixed
- Fixed UI flickering during
Widget::Refresh()by implementing nested batch updates (BeginUpdate/EndUpdate). UI redraws are now deferred until all nested element modifications are complete. - Fixed
TextElementfont face resetting during partial updates. - Fixed
fontShadowproperty not applying correctly to UI elements. - Protected critical UI properties (containers, alignment, tooltips) from being overwritten during partial state updates.
[0.9.4.0-beta] - 2026-05-08
📅 8th May, 2026
Added
- Added
system.timeAPI module. - Added
ui.removeElementById(id)binding. - Added new CLI command for Manage window close request:
manage_novadesk.exe --request-close
Fixed
- Fixed widget refresh lifecycle so stale
ipcRendererUI listeners are cleared before reloading.ui.js. - Improved
.ndpkginstaller admin-close behavior by adding elevated fallback.
[0.9.3.0-beta] - 2026-05-01
📅 1st May, 2026
Added
- Added
InputBoxaddon to the default plugin list in NWM (no longer requires separate packaging). - Added new JS bindings for widget window control and properties:
win.show()/win.hide()win.setBounds()/win.getBounds()win.setSize()/win.getSize()win.setOpacity()/win.setBackgroundColor()/win.getBackgroundColor()win.isFocused()/win.isVisible()/win.isDestroyed()win.destroy()(destroys without firing close event)
- Added new UI element methods:
ui.setElementProperty(id, key, value)- update a single propertyui.isElementExist(id)- check if an element exists
- Added disk I/O metrics with PDH to the
diskmodule:disk.readSpeed()- returns read speed in bytes/secdisk.writeSpeed()- returns write speed in bytes/sec
- Added drag events for UI elements:
onDragStart- fired when drag beginsonDrag- fired continuously during dragonDragEnd- fired when drag ends
Fixed
- Fixed
RoundLineelement to use effective dimensions for positioning and drawing calculations.
[0.9.2.0-beta] - 2026-04-24
📅 24th April, 2026
Added
- Added
excludeItemssupport for widget packaging (nwm build). - Added additional widget events:
clickright-clickdouble-clickscroll-upscroll-down
- Added Ctrl-based runtime overrides for widgets.
- Added
system.recycleBinAPI:openBin()emptyBin()emptyBinSilent()getStats()
- Added async Promise-based
webFetch(...). - Added
pixelHitTestproperty for UI elements.
Fixed
- Fixed hit testing behavior for:
- Rotator element
- Histogram element
- Area Graph element
- Fixed UI font property handling.
Removed
- Removed InputBox addon options:
messageplaceholder
[0.9.1.0-beta] - 2026-04-21
📅 21st April, 2026
Added
- Added Manage submenu and widget settings entries.
- Added tray events:
double-clickscroll-upscroll-down
- Added widget toolbar options:
showInToolbartoolbarIcontoolbarTitle
- Added
widgetWindowmethods:win.minimize()win.unMinimize()
- Added widget
.on(...)events:minimizeunMinimize
- Added global variable:
__mainScriptDirPath.
Changed
- Simplified
TextElementhit testing. - Refactored tooltip handling to manual tracking for more stable hover/tooltip behavior.
[0.9.0.0-beta] - 2026-04-16
📅 16th April, 2026
Added
New InputBox add-on
Support for named CSS colors
New Image properties:
imageFlipimageCropuseExifOrientation
New Image element property:
scaleMargins
New elements:
- Line
- Button
- Bitmap
- Histogram
- Rotator
Improved
- Enhanced
getAddonsPathfunction
[0.8.0.0-beta] - 2026-04-07
📅 7th April, 2026
Added
- Introduced manage_novadesk GUI for managing widgets.
- Added restart_novadesk.exe to restart the Novadesk application.
- Added support for .ndpkg files for widget distribution.
- Introduced a .ndpkg installer for widgets.
- Added a new global variable:
__addonsPath. - novadesk.exe now supports executing multiple scripts.
- novadesk.exe now supports several CLI arguments.
Changed
- Updated nwm for improved compatibility with .ndpkg files.
- Modified the output structure of distributions generated by nwm.
- nwm now generates .zip archives for widget distribution instead of raw files.
[0.7.0.0-beta] - 2026-03-24
📅 24th March, 2026
Added
- Added support for
meta.json.maininnwm run, allowing widgets to define a custom entry script path instead of always usingindex.js.
Changed
- Updated engine IPC: main-to-UI messages now use Electron-style
ipcRenderer.on(channel, (event, payload) => ...)instead of the old payload-first callback order. - Renamed
clipStringalias totextClip.
Fixed
- Fixed TextElement hit testing to use the actual rendered text ink alpha instead of the layout box, preventing false hover detection above/below glyphs.
- Fixed unstable button hover handling by preserving the currently hovered element, preventing repeated
onMouseOver/onMouseLeavetriggers. - Fixed an issue where setting a property on a text element would clear the text.
Removed
- Removed
appVolume,audioLevel,brightness,hotkey, andnowPlayingsystem objects (can now be replaced by external official addons). - Removed deprecated
app.tray*methods, replaced with the newtrayobject from Novadesk.
[0.6.0.0-beta] - 2026-03-06
📅 6th March, 2026
Added
- Integrated QuickJS for ECMAScript 2020 (ES11) support.
- Added new modules: novadesk, system, and fs.
Changed
- UI scripts now require the .ui.js suffix at the end of the script filename.
- Renamed the win object to the ui object (alias updated accordingly).
- Replaced the IPC method with a new implementation.
Removed
- Removed include() and require() methods.
- Removed all previous system and app objects.
[0.5.0.0-beta] - 2026-02-19
📅 19th February, 2026
Added
JSON API
- Added fixture for comment preservation.
- Booleans now persist as
true/falseinstead of1/0. - Suppresses merge-failure warnings for empty or whitespace-only files while keeping warnings for real merge failures.
App Object API
- Added
app.isPortable(). - Added
app.isFirstRun().
Engine & Module System
- Implemented module-aware path resolution by propagating module directory context into exported function calls.
Element & Widget System
- Added element grouping with dedicated
groupproperty. - Added
win.removeElementsByGroup(). - Added
win.setElementPropertyByGroup().
Cursor System
- Added
CursorManagerfor element mouse cursors. - Added
mouseEventCursor,mouseEventCursorName, andcursorsDiroptions. - Added support for built-in and custom
.curand.anicursors.
System APIs
- Added
setWallpaperAPI to change desktop wallpaper. - Added brightness control API for Windows.
- Added application volume control and mute APIs.
File & Icon APIs
- Added file icon extraction.
- Added ICO export functionality.
Global Variables
- Added
__widgetsDir - Added
__offsetX - Added
__offsetY - Added
__offsetXPercent - Added
__offsetYPercent - Added
__clientX - Added
__clientY - Added
__screenX - Added
__screenY
Widget Events
- Added widget mouse events:
mouseDownmouseUpmouseMovemouseOvermouseLeave
Installer
- Installer now includes Standard/Portable mode page, blocks Portable installs in system-protected paths, and skips uninstaller/registry/PATH changes when Portable is selected.
Fixed
Module System
- Fixed
js_requirecache writeback so modules that replacemodule.exportsare cached correctly.
Text Rendering
- Fixed
TextElementpartial update state loss. - Preserved
fontGradientand related text style fields inPreFillTextOptions. - Prevented gradient text from resetting to black on
setElementProperties.
Widget Lifecycle
- Fixed widget recreation crash.
- Removed old widget from global widget list before deletion.
- Prevented double-erase invalid iterator during
WM_DESTROY.
Input & Interaction
- Fixed mouse routing for non-interactive overlays.
- Text or overlays no longer steal hover, click, cursor, wheel, or tooltip events from underlying interactive elements.
Engine & JS API
- Fixed engine event callback context restoration to prevent win/Duktape stack corruption.
Installer Stub
- Fixed installer stub uninstall cleanup now removes all child folders/files in install directory (including unknown generated system API caches) before final root deletion, with existing cmd fallback retained.
[0.4.0.0-beta] - 2026-02-11
📅 11th February, 2026
Added
Window & Lifecycle
- Added new
.oncallbacks forwidgetWindowfocus and unfocus events. - Added new
widgetWindowmethods:setFocus()andunFocus(). - Added new
widgetWindowmethods:getHandle(),getInternalPointer(), andgetTitle(). - Added support for gradient backgrounds in
widgetWindow.
Elements
- Added new element type
roundLine. - Added new element type
shapeswith multiple shape variants. - Added gradient color support for elements.
- Added automatic width and height calculation for
barelement. - Added new element property
showto control element visibility.
System & Runtime
- Added new system monitor for
audioLevel. - Added system to detect and verify portable environment support.
- Added
requiremethod for loading modules.
Performance & Updates
- Added
win.startUpdate()andwin.endUpdate()methods for batch updating element properties.
Installation
- Added self-installation support for widgets using the new tool
installer_stub.
Fixed
- Fixed issue where images were not displayed when width or height was not explicitly set.
Removed
- Removed deprecated element properties like
solidColor2andgradientAngle, replaced by the new gradient support system.
[0.3.0.0-beta] - 2026-02-05
📅 5th February, 2026
Added
Extended fontWeight support with string and numeric values.
- String values: thin, extralight or ultralight, light, regular, medium, semibold or semi-bold, bold, extrabold or ultrabold, black
- Numeric values: 100, 200, 300, 400, 500, 600, 700, 800, 900
Added fontPath property for loading custom fonts in the text element
Added inline style tag support for the text element
Added fontColor support for gradient colors
Added fontShadow support for text
Added letterSpacing property for the text element
Added case property for the text element
Added underline property for the text element
Added strikethrough property for the text element
Supported Inline Tags
<b>: Bold text<i>: Italic text<u>: Underlined text<s>: Strikethrough text<color=value>: Changes text color or applies a gradient
Example:<color=#f00>Red Text</color>
Example:<color=linearGradient(0,#f00,#0f0)>Gradient Text</color><size=value>: Changes font size in pixels
Example:<size=24>Large Text</size><font=name>: Changes font face
Example:<font=Consolas>Monospaced Text</font><case=value>: Changes text case
Valid values:normal: Maintains original casingupper: Converts all text to uppercaselower: Converts all text to lowercasecapitalize: Capitalizes the first letter of each wordsentence: Capitalizes the first letter of the first word
Example:<case=upper>this will be uppercase</case>
[0.2.0.0-beta] - 2026-01-30
📅 30th January, 2026
Added
- New JavaScript APIs on the
appobject:getAppDataPath(),getSettingsFilePath(), andgetLogPath(). - Dynamic product name retrieval from executable resources for consistent directory naming.
Fixed
- Single Instance Enforcement: Resolved an issue where multiple instances could run if one was started as Administrator (by the installer) and another as a Standard User.
- Changelog Sorting: Standardized versioning to 3-part Semver to ensure "Latest" version labeling works correctly.
Changed
- Branding Consistency: Refactored
GetAppTitle()to usePathUtils::GetProductName(), ensuring the product name is consistently pulled from executable resources across the entire application (including the tray menu). - Redirected
settings.json,config.json, andlogs.logto the user's%APPDATA%directory. - Updated the installer and uninstaller to handle user data cleanup in AppData.
- Consolidated resource extraction logic across the codebase for improved performance (caching).
[0.1.0.0-beta] - 2026-01-30
📅 30th January, 2026
Added
- Initial beta release...