Commit Graph
68 Commits
Author SHA1 Message Date
Elie Gambache 0b7a927e13 feat(examples): add widget-demo, a desktop widget pinned below every window
Counterpart of watermark-demo: the same transparent, undecorated,
taskbar-hidden overlay, stacked below everything instead of above. Holds the
Nucleus atom (copied from nucleus-demo) and a clock, drags itself through the
compositor since an undecorated window has no title bar to grab, and carries a
native context menu to lock its position or close it — no control window.

Linux takes an X11 surface of its own (forceX11), keep_below being an X11
protocol.
2026-08-17 21:37:35 +03:00
Elie G. fcbd9a8c83 feat(examples): watermark-demo — transparent click-through overlay
Animated NUCLEUS watermark in a transparent, undecorated, always-on-top,
click-through, never-focused window pinned to a screen corner, hidden
from the taskbar and controlled entirely from a ComposeNativeTray icon
(corner selection + quit).

The tray icon is fed as image files (iconPath/windowsIconPath as file:
URIs): the composable-icon overloads crash on the skiko shipped with
Compose 1.12 (NoSuchMethodError on Image.encodeToData), and java.net.URI
rejects raw Windows paths.
2026-08-17 17:54:42 +03:00
Elie G. 3b0dcf9792 feat(examples): add rect-stress-demo, the RectManager EDT-escape sentinel
Worst-case shape for the RectManagerEdtGuard on the real Tao backend: a
throttled+debounced onLayoutRectChanged entry moving every frame, a
LazyColumn (mid-pass dispatchCallbacks), >16ms draw and placement
phases, and periodic remounts. The rect callback doubles as a detector:
if a RectManager delayed dispatch ever escapes to the EDT again, the
app prints the proof and exits 55; on an unguarded Compose 1.12 backend
the same shape crashes with 'LayoutNode not found in RectList'.

Also documents in RectManagerEdtGuard why the pin is complete on
1.12.0-rc01 even for debounced rect callbacks: triggerDebounced
early-returns on a pinned (future) deadline, and the mid-pass lowering
branch in ThrottledCallbacks.fireWithUpdatedRect/fire is an upstream
no-op that writes the old deadline back. onScenePulse stays as
defense-in-depth for the day upstream fixes that assignment.

See #555
2026-08-17 15:48:12 +03:00
Elie Gambache 6ff431f442 feat(spellcheck): add Linux Hunspell spellcheck for Compose text fields
Introduce a :spellcheck module (JNI Hunspell via dlopen) and SpellcheckContextMenu
for red-wave underlines plus Cut/Copy/Paste suggestions. Jewel uses ContextMenuDivider
via ProvideJewelSpellcheckMenu. macOS and Windows remain no-ops until implemented.
2026-08-16 14:45:34 +03:00
Elie Gambache f66bbb1d89 build: remove duplicate :system-info include 2026-08-09 08:04:45 +03:00
Elie Gambache ba8da4f3bc test(graalvm): Room-shaped orphan-reflect-smoke for #441 AC
Add a headless smoke app that loads AppDatabase_Impl via
Class.forName(base + "_Impl") with no hand-written reachability entry.
Validates runGraalvmNative succeeds with the orphan detector and fails
with -Pnucleus.orphanDetect=false.
2026-08-06 00:29:09 +03:00
Elie Gambache 83879b1243 feat(examples): AVFoundation/VideoToolbox video into a TextureView on macOS 2026-08-05 19:08:57 +03:00
Elie G. f8274e6a01 feat(examples): Media Foundation video into a TextureView on Windows
The Windows counterpart of the GStreamer sample: IMFSourceReader decoding
through DXVA2, the D3D11 video processor converting NV12 to RGBA, and the
frame published in a shared texture the compositor samples — nothing touches
the CPU.

The video processor is not a shortcut. A DXVA decoder hands out textures
carrying D3D11_BIND_DECODER and nothing else, so they cannot be bound as
shader resources; VideoProcessorBlt is the sanctioned way to read them and it
brings the colour matrix and nominal range along, which is why Chromium's
Windows video path uses it too. Output is R8G8B8A8_UNORM, checked with
CheckVideoProcessorFormat rather than degraded to BGRA, because the consumer
samples premultiplied RGBA and a swapped fallback would be silent. The alpha
fill mode is OPAQUE: a video has no alpha, and drivers are free to leave it
at zero, which composites the frame away.

The shared texture is sized from the first decoded frame, not from the
negotiated type: a decoder only settles its output type once it produces a
sample, and the size it reports then differs from the preroll one. Getting
this wrong is what makes the window come up with no picture. A media-type
change later on is tolerated as long as the frame size holds, since the
consumer has already imported a texture of it.

A source reader has no clock, so the helper paces itself: one sample is read
ahead and held until its presentation time is due against QPC. The Compose
loop ticks once per composited frame and is told "not yet", which plays the
file at its own rate whatever the display does. Software decode is covered as
well — the frames arrive in system memory and go through a staging upload
into the same video processor.

The file is picked with FileKit, or passed as an argument, or named in
NUCLEUS_MF_URL; a pick that cannot be opened leaves the previous one playing.

Verified on this machine (RTX 5060 Ti, ANGLE/D3D11): a 1680x1088 30 fps
recording plays at 30 frames/s with 9 recompositions of the video pane for the
whole run, and a 4K file plays with the same figures — the controls (clip,
alpha, rotation, crop, Compose overlay) apply to the frame, which is the point.

The helper is built by its own build.bat and stays out of CI; everything it
links against ships with Windows, and the sample says so when it is missing.
2026-08-05 18:35:18 +03:00
Elie Gambache 8cc0b1c6fe feat(examples): GStreamer video into a TextureView on Linux
A sample that plays a real video file through TextureView: hardware decode,
GPU colour conversion, and the frame composited in the Compose scene without
ever touching the CPU.

The pipeline is uridecodebin ! glupload ! glcolorconvert ! appsink, asking for
RGBA in GL memory. Converting in the pipeline rather than in the compositor is
not a workaround: it is the same division of labour Flutter's Linux embedder
settled on, whose texture API takes a GL texture and treats it as RGBA. It also
sidesteps the interleaved-chroma formats Skia cannot sample.

Three EGL contexts, one share group: the window's, captured from inside a draw
pass because that is where it is current; one handed to GStreamer, which creates
its own sharing context from it — it has to activate what it is given, so it
must not be the window's, and its GL info has to be filled in first or the EGL
backend reaches for GLES and EGL refuses the share; and one for the puller, so a
producer loop on a background dispatcher never touches the render thread.

Each frame is copied into a texture of ours and handed over as the EGLImage that
aliases it, which keeps the source stable for the whole playback: one import, and
no recomposition per frame — the pane's recomposition counter is on screen next
to the frame rate to show it. The controls (clip, alpha, rotation, crop, Compose
overlay) are there to show the frame is a composable and not a hole punched
through the window.

Verified on this machine (NVIDIA 5060 Ti, Wayland): 1280x720 H.264 decoded with
nvh264dec, looping, ~1100 frames composited per run with no import failure, and
no crash on termination — the pipeline is stopped from a shutdown hook, because
its GL thread otherwise outlives the toolkit's context.

The helper is built by its own build.sh against the GStreamer development files
and stays out of CI, which has no GStreamer; the sample says so when it is
missing.
2026-08-05 17:22:01 +03:00
Elie Gambache d8c9e73fec feat(tao): window scaffold, glass regions and chrome APIs (#129)
Adds an alternative to the fixed TitleBar layout so Compose content can
extend under the title bar, plus the primitives design systems need to
build their own chrome. All additive: existing DecoratedWindow/TitleBar
call sites are untouched.

- WindowScaffold: Docked (current behaviour) or Overlay placement, the
  latter letting content fill the window while the bar floats above and
  the measured bar height flows back as content padding.
- LocalWindowChromeInsets: reserved control zones (macOS traffic lights,
  KDE edge padding) exposed to custom chrome.
- Modifier.windowDragArea: standalone drag region with double-click
  maximize, extracted from TitleBar's implicit handler.
- Modifier.windowGlassRegion: Apple's wallpaper-tinted material behind a
  Compose region, backed by a hosted NSSplitViewController so AppKit
  applies the same desktop-tinted backdrop as System Settings.
- WindowBackdrop: full-window behind-window glass (NSGlassEffectView on
  macOS 26, NSVisualEffectView fallback).
- WindowAppearance: forces NSWindow.appearance so native surfaces follow
  the app theme rather than the OS setting.

Also honours Modifier.macOSLargeCornerRadius from WindowScaffold, and
routes nativeSetWindowBackgroundColor through the stored-background path
so the themed colour is applied according to the transparency mode.
2026-07-27 14:28:40 +03:00
Elie G. b19ee58cd8 feat: upgrade Jewel to 0.39 and IntelliJ icons to 262
- Bump jewel 0.37.0-262.4852.51 -> 0.39.0-262.9437.21 and icons 261 -> 262
- Add intellij-icons-api/impl deps (Jewel 0.39 IntUiTheme needs IconManager/DefaultIconManager)
- Add intellij-repository snapshots maven repo
- GraalVM: initialize-at-build-time for Jewel UnsafeAccessing/MacPlatformServicesDefaultImpl
  to avoid Method.invoke segfault under SVM object layout
- Refactor demo-project detection to path.startsWith(":examples:")
- system-info-demo: enable AOT cache + aotTraining, drop AWT --add-opens, SerialGC
- Register java.lang.Module#implAddOpens for reflection
2026-07-23 21:10:09 +03:00
Elie Gambache b69fb5b303 test(tao): GraalVM native test pyramid + native accessibility CI protocol
GraalVM native-image testing (examples/tao-native-test):
- New runner app (nucleus plugin, graalvm enabled) that compiles the whole
  Tao test pyramid into a native binary and RUNS it — the first place a
  produced native image is actually executed in CI (test-graalvm.yaml only
  compiled nucleus-demo before). Consumes decorated-window-tao's compiled
  test classes via a taoTestArtifacts configuration.
- TaoSceneTestBattery: generated reflection-free registry of the stage-1
  offscreen suite (60 cases) — JUnit discovery needs reflection metadata,
  direct calls need none.
- Two process modes (battery / headful): the offscreen battery's global
  Compose runtime state prevents the Tao loop from starting in the same
  process, so CI compiles once and runs the binary once per mode.
- New tao-native-tests job in test-graalvm.yaml (3-OS matrix, Xvfb+openbox
  on Linux). Local macOS: battery 60/60 and headful 6/6 with native=true.

Native accessibility protocol (scripts/ci/ + tao-a11y job in pre-merge.yaml):
- Verifies the OS-level a11y projection from the OUTSIDE, via the same
  client APIs assistive tech uses, against tao-demo's A11y tab
  (NUCLEUS_DEMO_TAB env added to tao-demo for direct navigation):
  - Windows (hard gate): verify-uia.ps1 — UIA tree exposure, InvokePattern
    round-trip (Increment -> 'click counter 1'), TogglePattern, RangeValue.
    Derived from scripts/dump-uia-tree.ps1 / uia-action.ps1.
  - Linux (hard gate): verify-atspi.py — pyatspi walk over the AT-SPI bus
    (org.a11y.Status.IsEnabled flipped like scripts/a11y-linux-iter.sh),
    element exposure + doAction round-trip.
  - macOS: verify-ax.swift — AX client dump (axdump/axtool derived);
    self-skips on runners without the TCC Accessibility permission.
    Verified locally: 4/4 elements exposed, 53 named accessibles.
2026-07-19 09:22:02 +03:00
Elie GambacheandClaude Fable 5 d750987e5f feat(examples): add cross-runtime benchmark suite (benchmark-demo)
Geekbench-style shootout across 5 desktop runtimes — JVM (C2 & GraalVM JIT),
GraalVM Native Image (-Os/-O2/-O3/PGO via -Popt/-Ppgo), SwiftUI, Tauri/Rust
and Flutter/Dart — running byte-identical workloads defined in BENCHMARK-SPEC.md.

- 13 CPU kernels (mandelbrot, n-body, raytracer, SGEMM, gaussian blur,
  sha256, sieve, fft, pi 10k digits + 4 multithreaded variants)
- 3 render torture ramps (particles, vector stars, text) with warmup window,
  double-failure confirmation and geometric growth; anchored graphics score
- list-load bench + auto-run + results JSON in ~/nucleus-benchmarks/
- cross-port self-checks (prime count, SHA-256 digest sum, pi digits)
- measurement-trap defenses documented in spec/README: dead-code elimination,
  pure-function hoisting, async canvas submission, render-loop allocation,
  macOS sandbox, Dart isolate sendability
- recorded GraalVM PGO profile (GUI-trained): +31% composite vs ML-inferred,
  image size 135->89 MB; march=native for platform parity with Swift/Rust
- run-all.sh: sequential 9-variant matrix with peak-RSS and thermal logging
- AGENTS.md: operator playbook for agents

The flagship app dogfoods nucleus-application DSL + decorated-window-tao.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 20:28:57 +03:00
Elie Gambache eea7d3505e feat(examples): add swing-tao-demo — pure Swing on the Tao event loop
A plain Swing JFrame driven by TaoApplication.run (native Tao/winit event
loop on the main thread), with no Compose. Demonstrates AWT EDT + Tao loop
cohabiting in one process: buttons cross from the EDT into the Tao loop to
open/close a native Tao window. Forces exitProcess(0) after the loop stops
since AWT's non-daemon EDT would otherwise keep the JVM alive.
2026-07-13 12:14:55 +03:00
Elie Gambache f0e0209b55 feat(examples): zstd-demo — file/folder compression via zstd-kmp
End-to-end host for the issue #317 sandbox pipeline: a Compose desktop app
that picks a file or folder (FileKit) and compresses it with zstd-kmp
(Zstandard). zstd-kmp loads its native library through the extract-and-load
pattern, so pairing it with TargetFormat.Pkg exercises the marker + bytecode
rewrite + runtime shim redirect in a signed store bundle.

- Pure-Kotlin streaming compressor (no upstream library changes).
- GraalVM native-image config: JNI reachability metadata for zstd-kmp's
  native methods and result fields, plus -H:IncludeResources for the bundled
  jni/<arch>/libzstd-kmp.* payloads.
- Drop the redundant local val + non-null assertion in the sandbox manifest
  wiring.
2026-07-12 23:12:23 +03:00
Elie G. 9a853ab209 refactor(examples): consolidate demos under examples/ + add compose-demo
Move all top-level demo/sample modules into a single examples/ directory with
uniform <topic>-demo naming (example → nucleus-demo, sample-tao → tao-demo,
jewel-sample → jewel-demo, etc.), and update every CI workflow, script, and doc
that referenced the old Gradle paths.

Add examples/compose-demo: a port of bitsycore/compose-desktop-native's demo
running on the Tao backend with Material 3 decorated windows, FileKit file
dialogs, Navigation 3, and GraalVM native-image config. Screens relying on
Material 3 Expressive (Compose 1.12) are omitted to stay on the repo's 1.11.x.
2026-07-12 21:50:45 +03:00
Elie Gambache d74feb9aa1 Merge pull request #290 from amir1376/feat/additional-launchers
Support Additional Launchers
2026-07-10 12:50:43 +03:00
RavenLiao 7179d8134d test: add fs-watcher smokeNative task and JSON report 2026-07-08 21:47:40 +08:00
RavenLiao f8a5df191f feat(fs-watcher): add native watcher module 2026-07-08 14:45:37 +08:00
AmirHossein Abdolmotallebi 617a3221c6 support additional launchers 2026-07-08 01:50:34 +03:30
Elie Gambache eaab2fa156 Merge origin/main into nucleus-2.0
- Port TitleBarLayoutPolicy (fill-center) feature (#245) to the 2.0 API
- Thread layoutPolicy through BasicTitleBar in Tao backend
- Thread layoutPolicy through MaterialTitleBar (material3)
- Rewrite FillCenterDemoWindow on NucleusApplicationScope using nucleusWindow
- Drop unused window: Window param from TitleBarLayoutPolicy
2026-05-24 20:39:11 +03:00
Sean Proctor 2b218af59f update and alphabetize dependency versions (#242) 2026-05-13 16:22:52 +03:00
Elie Gambache f03f9f7b19 Merge main into nucleus-2.0 2026-05-11 18:06:26 +03:00
Sean Proctor c82b0bd5a0 add foojay resolver 2026-05-11 03:43:03 -04:00
Elie G. c42d0e7ced feat(taskbar-progress-tao): implement Tao backend support with unified NucleusWindow API
New taskbar-progress-tao adapter module providing Tao-backed window support. Adds NucleusTaskbarProgress facade that transparently dispatches to correct backend (AWT or Tao) via runtime window type checking. All operations offloaded to daemon thread to prevent shutdown deadlocks. Refactored example to use backend-agnostic NucleusWindow API.

- New module: taskbar-progress-tao with TaoTaskbarProgress and NucleusTaskbarProgress
- Unified API: extension functions on NucleusWindow (transparent to callers)
- Threading: all native calls offloaded to executor (non-blocking, prevents freeze-on-close)
- Platform support: Windows ITaskbarList3 via HWND, macOS/Linux delegates to existing implementations
- Example refactored: removes backend-specific dispatch logic
2026-05-10 22:17:02 +03:00