Changelog
Release history and notable changes for each version of Koya.
0.7.0 #
Adds direct display output with role: 'raw'. Applications can create full-screen windows on physical displays without a Wayland compositor. See Koya/Compositor for options and examples.
- Multiple outputs on one GPU, explicit desktop layout, focus controls and input-device/output mappings.
- Keyboard, pointer and touch through libinput/xkbcommon and the existing Helix UI input system; bundled software cursors.
- VT handling and output disconnect/reconnect suspension that retains windows and UI; raw lifecycle events and a runnable input demo.
0.6.1 #
Fix touchpad flicks ending with an interrupted cancellation: zero axis deltas no longer interrupt native inertia. Wayland delivers a frame’s final scroll values before its axis stops, preserving both-axis momentum.
0.6.0 #
Koya 0.6.0 replaces raw mouse/touch callbacks with virtual interactions. This is a breaking input API release; migrate scripts and rebuild native integrations using the 0.5.0 → 0.6.0 migration guide.
Added #
- Named virtual handlers:
onPress,onActivate,onHover,onDrag,onScroll,onLongPress,onDoubleActivate, andonTransform, with matching element setters and typed event objects. - Window input registration:
Helix/Input.setHandlers(windowId, handlers)andsetOptions(windowId, options)provide scoped handlers and recognition defaults. Elements can override thresholds, accepted buttons, drag axis, and input blocking. - Gesture recognition: ancestor takeover, long press, immediate single activations plus double activation on the second qualified activation, and two-contact pan/pinch/rotation.
- Input metadata: opaque interaction/contact IDs, semantic buttons, modifiers, logical-window/UI/local coordinates, two-axis scroll units and source, and available touch pressure or contact geometry.
- Native scroll containers:
scroll: trueor axis/options configuration clips and moves children, supports touch inertia and Wayland finger-axis stops, and emits start/change/end/cancel notifications. Includes programmatic scroll/stop methods and a native scrolling guide. - ScrollView standard control: native kinetic viewport/content composition, content resizing, lifecycle observers, scroll/stop methods, and a runnable standard-library example. See standard controls.
Changed #
- Breaking removal: element
onMouse*options,setOnMouse*methods, and nativekoya_ui_set_on_mouse_*callbacks are replaced without compatibility adapters. Each new callback receives one event object. - Ownership and routing: started presses/drags retain their owner and finish with
endorcancel; UI recognition runs before window/game fallback. Handler return values do not decide consumption. - Standard controls and examples: buttons, text inputs, and bundled input examples use virtual interactions.
- Breaking removal: compositor
pointerDown/pointerUpevents and native pointer callback fields are replaced by window virtual input handlers.
Fixed #
- Lost releases: moving outside an element no longer loses the interaction terminal event. Capture loss, focus/device/window loss, handler changes, owner teardown, and native drag handoff explicitly cancel active interactions.
- Multi-contact state: independent contacts and buttons retain separate lifecycles; hover is independent of held state. Cancellation cannot trigger activation.
- Wayland input normalization: fractional coordinates, source-specific pointer/touch frames, high-resolution wheel steps, touch shape/orientation, and device cancellation are preserved through the shared recognizer.
Upgrading #
Replace raw callbacks by intent and handle cancellation alongside release. See the migration guide and Helix/Input reference. Keyboard, text input, custom Helix/Event events, and OS data drag/drop retain their separate APIs.
0.5.0 #
Native plugin, windowing, and rendering lifecycle release. Koya 0.5.0 adds per-window GPU selection and animation pose controls, replaces the native plugin ABI, and improves multi-window behaviour, rendering synchronisation, and UI correctness. These changes build on the rendering and asset work documented under 0.3.0 and 0.3.1.
Added #
- Per-window Vulkan device selection through
deviceSelectorinCompositor.createWindowand the standard UI window helper. Select a GPU synchronously or asynchronously from surface-specific candidates, including device properties, memory, queues, features, and suitability reasons. Without a callback, Koya prefers a suitable discrete GPU. - Deterministic animation poses through
UI.setAnimationTimeandUI.clearAnimationTime. Hold an element at an authored clip-local time, clamp to the clip endpoints, and sample procedural noise consistently without starting playback, looping, or firing completion callbacks. - Helix native plugin ABI with a C-compatible header, per-runtime plugin instances, and discoverable
helix.script,helix.assets, andhelix.rendercapabilities. The eight bundled plugins have been migrated: DBus, FFmpeg, HTTP, Hyprland IPC, PAM, Process, SQLite, and WebSocket. - Product-specific version reporting through
koya --version, showing the Koya version and build separately from the Helix engine version and source revision, without starting the compositor.
Changed #
- Shared Wayland session owns the display connection, input devices, keyboard state, cursor resources, and event pump. Individual windows own their surfaces and route pointer, keyboard, and touch input through the session registry.
- Renderer resource ownership is separated into window, frame, offscreen, and post-processing backends. Swapchain replacement is constructed and committed as a unit, with cleanup for partially built replacements.
- GPU submission and resource retirement use a shared timeline. Texture replacement, mesh uploads, offscreen rendering, and readback retain resources until their submissions complete; targeted waits replace queue-wide and device-wide idle waits in these paths.
- Polyline updates avoid rebuilding local-width geometry for translation or clip-transform changes, upload only changed vertex/index data, and handle duplicate-point runs with linear work.
- Native plugin distribution uses
helix-plugin-*packages andlibhx-*.solibraries. JavaScript imports retain theModule/<name>form.
Fixed #
- UI scaling and hit areas: Koya windows retain logical-unit sizing by default, avoiding a second reference-resolution scale on top of Wayland scaling. Explicit scaling policies survive window resizing, and layout/cache calculations account for canvas and output changes.
- Scaled composite rendering and fonts: offscreen composites cover the scaled canvas instead of only part of the window, and glyph rasterisation accounts for UI scale. Font-atlas revisions remain distinct when changing character sizes.
- Text publication and opacity: text rebuilt after model contention becomes visible to composite caches, and replacement glyph geometry no longer inherits stale opacity state that can leave text blank or incorrectly faded.
- Colour changes in cached UI: changing renderable colours or opacity refreshes the affected vertex data and invalidates composite content, preventing stale colours in boxes, circles, panels, sprites, and text.
- UI tree integrity: attaching an ancestor as a child is rejected before modifying the existing tree, preventing cycles.
- Cross-thread task timeouts: queued synchronous work is cancelled if it has not started; work already running finishes before its caller returns, avoiding access to expired caller-owned data.
- Window teardown and input routing: destroying a window removes its surface and focus registrations before releasing the surface, without destroying the shared display or input resources used by other windows.
- Renderer failure cleanup: offscreen allocations, swapchain replacement, and presentation failures have explicit cleanup and retry/fatal outcomes. Enabling post-processing after scaled-only rendering rebuilds the required render targets.
- Native plugin shutdown: script callbacks run on the owning QuickJS thread; shutdown revokes scheduled work, separates script and engine cleanup, and destroys each instance once. One runtime can shut down while another continues using its own instance of the same plugin.
- QuickJS teardown: event callback values are released before the context and runtime are destroyed.
- Particle gradient parsing: gradient keys accept
{time, value}as well as{time, colour}and{time, color}. Dynamic polyline point colours also accept byte-valued colour objects instead of losing their colour/opacity gradients. - Polyline publication under contention: prepared geometry is retained and published when a model slot becomes writable, instead of losing an update.
Upgrading #
- Rebuild native plugins for the new ABI. Replace
libsm-<name>.sowithlibhx-<name>.soandintegrateV1withhelix_plugin_integrate. Named hooks become callbacks onHelixPluginInstance; mutable state belongs to each instance. There is no legacy ABI or filename fallback. - Plugin lookup order: explicit
-ndirectories are searched first, followed by the executable directory and system library paths. Module names must be a single component containing ASCII letters, digits, underscores, or hyphens. - Vulkan requirements: device selection requires Vulkan 1.3, timeline semaphores,
synchronization2,VK_KHR_present_id, andVK_KHR_present_wait, plus suitable surface/queue support and particle resource limits. A selector must return a suitable candidate ID within five seconds; a rejected, invalid, or timed-out selection rejects window creation and releases pending resources.
0.3.1 #
Asset packaging and virtual-filesystem maintenance release shared by Koya and Syncromesh.
Added #
- Self-discovering application archives automatically mount an ordinary ZIP appended to a Koya or Syncromesh executable at
/rom. - Bootstrap-time asset mounting through asynchronous
mountandmountAdjacentAPIs, allowing applications to load replaceable plugin and game-data ZIPs distributed beside the executable. - Bounded archive mounting through
Helix::Assets::mountArchiveRangefor ZIP payloads stored at a known offset and length inside a larger file. - Asset regression coverage for prefixed and bounded archives, ZIP64, empty and long-name entries, concurrent reads, failed mounts, and unsafe archive paths.
Changed #
- Archive backend now uses miniz 3.1.2 instead of the legacy assetsys/miniz 1.15 implementation.
- Virtual filesystem indexing now supports ZIP64, long member paths, deterministic recursive listings, case-insensitive lookup, and thread-safe archive reads.
- Ambient default mounts are disabled for reproducible application startup. The former platform, XDG, user configuration, and
./assetslocations are available only with--default-mounts.
Fixed #
- Invalid ZIP mounts no longer leave allocator state that can abort during cleanup.
- Empty archive members no longer risk invalid buffer access.
- Unsafe absolute, drive-qualified, backslash-separated, and parent-traversal archive paths are rejected.
0.3.0 #
Major rendering and core-architecture release. Koya 0.3.0 adds GPU particles, programmable post-processing, explicit blend and texture semantics, profiling, and a substantially more resilient dynamic-mesh path while moving the reusable engine into Helix.
Added #
- GPU particle renderable with compute-shader simulation, emitter controls, colour and size interpolation, JavaScript and C APIs, examples, tests, and embedded shaders.
- Programmable post-processing pipeline with multiple effect passes, runtime parameters, per-pass enable controls, and separate
scene_onlyandscene_and_uiapplication modes. - Explicit render blend modes — premultiplied alpha, straight alpha, additive, and opaque — for built-in and custom-shader renderables.
- Texture semantics distinguish premultiplied sRGB colour textures from unmodified linear data textures across asset loading, live uploads, C APIs, and plugin renderer hooks.
- Runtime profiling tools with scoped engine, scripting, and rendering counters plus current and high-water gauges.
- Generic Helix asset and image services shared by Koya and downstream runtimes, including live texture content revisions so render-to-texture consumers notice pixel updates.
- Runtime circle controls for arc angles, fill, border, radius, colour, and related circle-renderable properties.
- Mutable animation definitions through
updateAnimation, retaining animation IDs and completion callbacks while allowing keyframes, timing, easing, and looping to be replaced after creation. - Text colour areas paint Unicode character ranges without markup, with stable IDs and newest-first precedence for overlapping sections across Koya and Syncromesh.
- Native-module script dispatch hook for safely scheduling plugin callbacks on the owning scripting thread.
Changed #
- Reusable Helix core now owns the renderer, UI graph, renderables, scripting services, assets, and shared C APIs; Koya provides the Wayland platform shell and Koya-specific modules.
- Dynamic mesh rendering now uses shared growable vertex/index allocators, batched staging uploads, deferred buffer retirement, and double-buffered model publication for high-churn or multithreaded producers.
- Renderer plugin ABI now carries blend mode and texture semantic information and exposes the expanded render services to native modules.
- Wayland and Vulkan setup are decoupled, allowing surface/platform initialization to be managed independently from Vulkan instance creation.
- JavaScript API spelling aliases support both British and American forms without breaking existing scripts.
- Version generation now derives Meson build headers from the project version, keeping the executable, APIs, and release metadata in sync.
Fixed #
- Vulkan mesh uploads now reserve staging capacity before recording and retain replaced staging buffers until the submission fence signals, preventing command buffers from being invalidated by destroyed buffers.
- Dynamic mesh allocation and publication no longer fail under heavy geometry churn or concurrent model updates.
- Live texture reuploads now invalidate dependent renderable content correctly, including offscreen and plugin-produced textures.
- Post-processing and scripting lifecycle cleanup prevents stale renderer state during startup, shutdown, and resource rebuilds.
- Box inset controls are now applied when changed at runtime.
- Wayland
xdg_surfaceconfigure acknowledgements and initial commits now follow the compositor handshake without committing content against unacknowledged configuration. - Window geometry is synchronized with the logical extent of the presented buffer, including fractional scaling and viewport changes.
- Mapped surfaces retain their received configure state instead of clearing it after the initial Wayland roundtrip.
- Native-module
updatehooks now run on QuickJS's owning scripting thread, preventing promise completion callbacks from corrupting the garbage collector under concurrent workloads. - Closing a window now releases its UI text and font-atlas listeners before destroying renderer-owned font and texture resources.
0.2.2 #
Stability and runtime architecture release focused on scripting thread safety, input reliability, and text/renderable correctness.
Added #
- Command-line bootstrap arguments for startup configuration.
- Text
metricsBasisoption for more predictable measurement and layout behavior. - Script lifecycle hooks routed on the script thread for safer module callback execution.
Changed #
- Scripting runtime architecture now runs with a dedicated scripting engine thread.
- Documentation refresh for updated compositor behavior, including clipboard mechanism details.
Fixed #
- Crash that could occur during mouse event handling.
- Use-after-free issue involving JavaScript intervals.
- Renderable AABB/layout interaction bug that could force incorrect layout shaping.
0.2.1 #
Standard library, text rendering improvements, and new engine features.
Added #
- Standard library —
koya-ui.js(object-orientedWindowandElementwrappers),koya-controls.js(InputTextandButtoncontrols with focus management and tab navigation), andstore.js(reactive data store with deep proxy observation). - Word-wrap and justify modes for text renderables.
- Text measurement APIs —
measureText,getTextCaretPosition,hitTestTextfor building text input controls. - Clipboard support —
Compositor.getClipboardText/setClipboardTextfor copy and paste. - Gradient generator in the image module.
- Improved promise error handling — better stack traces and error reporting for rejected Koya promises.
Changed #
- Text renderer improved for crisp edges under normal (non-subpixel) rendering.
Helix/RandomandHelix/Geometryare synchronous — reverted to synchronous calls; these helpers no longer requireawait.- Documentation rewritten with improved layout and structure.
Fixed #
- Segfault on
engine.quit(). - Arc positions on circle renderable were unstable.
- Layout type
nonewas not sizing children to the parent bounds.
0.2.0 #
Major architecture overhaul. Introduced a C API layer between the scripting engine and the core, split JS and engine calls through task queues, and migrated to a thread-safe runtime model.
Added #
- C API layer — Full C API for engine and all modules, decoupling the scripting runtime from the core.
- Task queue system — JS and engine calls are routed through task queues for thread safety.
- Better promise error handling — Improved error reporting and stack traces for rejected promises.
- Vulkan screenshot API — Offscreen rendering for automated testing and screenshot capture.
- Offscreen composite rendering — Supports blend modes on elements through offscreen render targets.
- Scissor clipping —
UIElementclipping via Vulkan scissor rects. - Circle renderable — New
circlerenderable type with AABB-based hit detection. - Mesh renderable — Programmable mesh geometry with vertex/index buffer support.
- Touch events — Touch input support for surfaces.
- Background layer windows — Support for
exclusiveZoneoverride on background-role surfaces. - Dynamic framerate — Frame rate adjusts to compositor-requested rendering; gated rendering reduces idle GPU usage.
- Opacity on animations — Opacity property on animation keyframes, correctly applied to children.
- Render-to-texture — Surfaces can render into textures for composition effects.
- Shader inputs — User-defined shader uniforms (
User0,User1,Time).
Changed #
- Engine time uses
doubleeverywhere — Eliminated precision loss from mixed float/double time sources. - All clock sources use simulation time — Consistent timing model across the engine instead of mixed wall/engine time.
- Refactored
Module.UserInterface— Consistent style and structure across all UI module bindings. - Refactored
createWindowAPI — Now usesrole: bar | overlay | lock | windowinstead of separate calls. - Layout engine rewrite — Flexbox-inspired layout with correct tree propagation.
- Alpha blending standardised — Premultiplied alpha across all pipelines for consistent blending.
- Debug output channels —
KOYA_COUTrebuilt with named channels for structured logging. - FastNoise replaced with FastNoiseLite — More modern, less hacky noise generation.
Fixed #
- Rendering issues caused by C layer migration.
- Segfault on termination caused by early compositor cleanup.
- Segfault on
SIGINTduring shutdown. - Colour updates not propagating into mesh renderables.
- Renderable origin bug — centred renderables now render outside of parent bounds correctly.
- Colour animation not applying to text renderables.
- Rotation on animation keys not factoring falsy inputs.
- Layout not recalculating when
enabledflag changed. - Font rendering softness — text renderable now respects
bufferScale. - Origin and rotation faults on framed renderables.
- Hit detection bounds vs renderable mismatch.
- Texture lifecycle issues with font atlas causing stale white boxes.
- UIElement leak on destroy.
0.1.0 #
Initial release. Vulkan-rendered UI engine for Wayland compositors with QuickJS scripting, core renderables (box, panel, sprite, text), animation system, layout engine, and plugin architecture.
Core #
- Vulkan rendering pipeline with multi-surface support (bar, overlay, background).
- QuickJS scripting runtime with module-based API (
Helix/*,Koya/*,Module/*). - Promise-based async API model.
- Animation system with keyframe interpolation and callbacks.
- Flexbox-inspired layout engine for
UIElementtrees. - Image loading and GPU texture management.
- Asset loading from filesystem with fallback paths.
- Event system for input, compositor, and lifecycle events.
Renderables #
- Box — Rounded rectangle with per-corner radius, fill, and border.
- Panel — 9-slice sprite rendering for scalable UI elements.
- Sprite — Texture-mapped quad with atlas/crop support.
- Text — GPU-rendered text with font loading, alignment, and wrapping.
Plugins #
- HTTP — HTTP client for API requests.
- SQLite — Embedded database for persistent storage.
- D-Bus — System and session bus communication.
- Process — Child process spawning and management.
- WebSocket — WebSocket client connections.
- Hypr — Hyprland IPC integration for workspace/window events.
- FFmpeg — Media decoding for audio and video.
- PAM — Pluggable Authentication Module support for lock screens.