Revision history for Notcurses::Native
0.2.6 2026-04-29T23:53:41+01:00
- Bump Github actions to use node 24+
- `Build.rakumod` now garbage-collects sibling staged dirs for
older BINARY_TAGs after each successful install. Without this,
every release accumulated another `binaries-notcurses-*` dir
under `~/.local/share/Notcurses-Native/`, where stale Raku
precomp could load the older libs alongside the new ones —
cf. the Vips::Native r7→r8 incident that revealed this class
of bug. Set `NOTCURSES_NATIVE_KEEP_OLD_STAGES=1` to opt out
(e.g. when intentionally pinning multiple versions for testing).
0.2.5 2026-04-16T03:16:51+01:00
- Native.rakumod: set TERMINFO_DIRS at module load via libc
setenv(3) so ncurses finds terminal definitions on systems
without Homebrew ncurses installed. Our bundled libncursesw
was compiled against Homebrew's ncurses, which bakes the
terminfo search path to the Homebrew cellar — on a fresh
Mac without `brew install ncurses`, that path doesn't exist
and notcurses_core_init fails with "No terminal available"
even though the libraries loaded fine. The fix points
TERMINFO_DIRS at macOS's system /usr/share/terminfo/ (always
present) plus common Linux paths. Uses the same _setenv-c
pattern as Vips-Native (Raku's %*ENV doesn't propagate to C
getenv on macOS). Respects user-set TERMINFO_DIRS.
- test.yml: run prebuilt-path t/ tests before installing
system deps (brew/apt) so the self-contained bundle is
exercised with no system notcurses present. xt/ tests
(terminal-dependent) run after system deps install since
they need terminfo data on macOS. Saves several minutes per
failed run.
0.2.4 2026-04-16T02:58:01+01:00
- Build.rakumod: detect system glibc via `ldd --version` and
fall back to CMake source compile when it's older than the
prebuilt target (currently v2.35, matching the ubuntu-22.04
CI runner). Previously, users on Ubuntu 20.04 / Debian 11 /
RHEL 8 downloaded prebuilt libnotcurses + ffmpeg libs that
loaded but failed at first symbol use with "GLIBC_2.xx not
found". The guard fires before the download so affected users
just see a one-line note and a ~3–5 min source compile
(core-only if their ffmpeg dev packages are missing) instead
of a broken install. NOTCURSES_NATIVE_BINARY_ONLY=1 now
hard-fails with a clear message on old-glibc systems rather
than producing a broken install.
- New CI workflow .github/workflows/glibc-fallback.yml: runs
`zef install .` inside an ubuntu:20.04 container (glibc 2.31)
with apt-installed cmake + ncurses/unistring/deflate dev
packages and asserts both that the fallback message appears
in the build log and that the source-compiled libs load.
0.2.3 2026-04-15T02:52:48+01:00
- CI: rework test.yml to install via zef (which runs Build.rakumod
→ downloads prebuilt → SHA-verifies → stages libs to the XDG
data dir) instead of building notcurses by hand and dropping
libs into resources/lib/. The hand-build step was a vestige of
the pre-XDG-staging layout and stopped working when META6.json
dropped the lib resource entries in 0.2.2 — tests started
failing with "cannot open shared object file" because nothing
was actually staging libs to where Native.rakumod now looks.
Workflow now also re-installs with NOTCURSES_NATIVE_BUILD_FROM_
SOURCE=1 as a second pass to keep the CMake fallback path
covered on every CI run.
0.2.2 2026-04-15T02:46:26+01:00
- Stage native libs to an XDG-style data dir
($XDG_DATA_HOME/Notcurses-Native//lib/, or
$LOCALAPPDATA on Windows, ~/.local/share fallback) instead of
the dist's resources/. Reason: zef hashes every staged resource
filename to a SHA-keyed name, which silently breaks the inter-
dylib references baked into notcurses (libnotcurses.dylib loads
libnotcurses-core.3.0.17.dylib via @loader_path; same on Linux
with $ORIGIN, same on Windows with sibling-DLL search). Hashed
filenames meant the loader couldn't find any sibling lib by its
real name, and `Notcurses::Native` died at first dlopen with a
cryptic "Library not loaded" error post-install. Tests passed at
install time (pre-staging) so the bug only surfaced when
consumers like Selkie tried to actually use the module.
- META6.json no longer lists the 9 dylib/.so/.dll entries; only
checksums.txt and a new BINARY_TAG resource (a tiny text file
immune to the hash-renaming problem, used by Native.rakumod to
locate the staged-libs directory at runtime).
- Native.rakumod resolver: env override
(NOTCURSES_NATIVE_LIB_DIR) → XDG-staged dir → fail with the
staged path in the error message for actionable debug.
- New env knob: NOTCURSES_NATIVE_DATA_DIR to override the XDG base
directory (e.g. for system-wide installs or sandboxed envs).
0.2.1 2026-04-15T02:23:12+01:00
- Build: extract Windows .zip prebuilts via PowerShell's
Expand-Archive instead of `tar`. GNU tar (which is first on
PATH inside MSYS2 install environments) parses `D:\...` as a
remote `host:path` and bombs with "Cannot connect to D:
resolve failed". Expand-Archive ships on every supported
Windows and has no such quirk. macOS / Linux still use `tar`.
0.2.0 2026-04-15T02:17:17+01:00
- Prebuilt-binary-first install path. Build.rakumod now attempts
to download a per-platform archive from the repo's GitHub
Releases containing all three notcurses libs (libnotcurses,
libnotcurses-core, libnotcurses-ffi) plus the ffmpeg sibling
dylibs notcurses dyn-links, before falling back to the existing
CMake source compilation. Saves the 5–15 minute CMake build +
sidesteps the "install these 10 -dev packages first" pain
that the HN thread surfaced.
- ffmpeg sibling bundling with rpath relocation: @loader_path/
on macOS via dylibbundler, $ORIGIN on Linux via patchelf,
sibling-DLL layout on Windows. Archive self-contained — no
system ffmpeg/ncurses/libunistring/libdeflate needed at
runtime.
- SHA256 verification against bundled resources/checksums.txt;
refuses any prebuilt whose hash isn't recorded (hard security
boundary).
- Cache downloaded archives in $XDG_CACHE_HOME/Notcurses-Native-
binaries/ (or $HOME/.cache/ fallback).
- New env knobs: NOTCURSES_NATIVE_BUILD_FROM_SOURCE=1 to skip
prebuilts; NOTCURSES_NATIVE_BINARY_ONLY=1 to refuse fallback;
NOTCURSES_NATIVE_BINARY_URL to override release base URL;
NOTCURSES_NATIVE_CACHE_DIR to override cache dir;
NOTCURSES_NATIVE_LIB_DIR for runtime lib-dir override.
- New BINARY_TAG file at repo root as single source of truth for
the pinned binary release tag (binaries-notcurses--
r), read by both Build.rakumod and the CI
workflow.
- New .github/workflows/build-binaries.yml: builds + publishes
prebuilt archives for five platforms (macOS arm64, Linux
x86_64/aarch64 glibc, Windows x86_64/arm64) on manual dispatch
or binaries-* tag push. macOS uses dylibbundler, Linux uses
recursive ldd walk + patchelf, Windows uses recursive ldd on
MSYS2 + sibling DLL layout.
- macOS is arm64-only for v1. Intel Macs fall through to the
compile fallback; universal builds need cross-arch brew
setup that isn't worth the CI complexity for initial ship.
Can revisit if Intel Mac users complain.
- FFI lookup in Notcurses::Native now respects the
NOTCURSES_NATIVE_LIB_DIR env override before falling back to
%?RESOURCES. Escape hatch for custom notcurses builds.
- Fixed $os.contains('win') bug in FFI lookup: "darwin" matches
"/win/", causing file-extension detection to pick 'dll' on
macOS. Now uses $*DISTRO.is-win.
0.1.5 2026-04-12T21:17:32+01:00
- Build: tighten library-matching regex in Build.rakumod so that
staging `libnotcurses` doesn't accidentally pick up
`libnotcurses-ffi` (only `.` is a valid separator after the
library name, never `-`). The 3.0.16 → 3.0.17 bump surfaced this:
filesystem ordering began handing us the FFI shim first, which
lacks `notcurses_init` and quietly broke every terminal-dependent
test.
- Bump vendored notcurses 3.0.16 → 3.0.17, which upstream describes
as "Fix build problems on Windows and Mac OSX." The public API is
unchanged between these releases (single-character attribute-macro
typo fix in notcurses.h, no ABI impact), so our bindings need no
changes. Drops the Windows termios workaround that would otherwise
have been needed for 3.0.16.
0.1.4 2026-04-12T20:19:12+01:00
- CI: add Windows (MSYS2 UCRT64) to the GitHub Actions test matrix.
Uses OpenImageIO as the multimedia backend (per upstream notcurses
Windows recommendation). Build-only since notcurses-tester is
Unix-only.
- README: document system dependencies with per-OS install commands
for Linux (Debian/Fedora), macOS (Homebrew), and Windows (MSYS2
UCRT64). Added a core-only (no multimedia) note.
0.1.3 2026-04-09T23:56:25+01:00
- Switch library resolution from $?FILE to %?RESOURCES for portable
loading when used as a dependency by other modules
0.1.2 2026-04-09T18:06:28+01:00
- Move terminal-dependent tests to xt/ to avoid prove6 TAP harness
bug during zef install (t/ has pure-Raku tests only)
- CI runs prove6 on t/ and Perl 5 prove on xt/
- Fix NcBlitter enum values (NCBLIT_PIXEL was 6, should be 7)
- Fix visual functions: use $nc-lib (full) not $core-lib for FFmpeg
- Add 130 NCKEY_* key code constants, NcPixelImpl enum, NCBOX_*,
NCMICE_*, NCALPHA_*, NC_BG_* channel bitmasks
- Add NcvisualOptions.set-plane for correct plane compositing
- Add 8 example programs (hello, colors, boxes, input, clock,
image viewer with kitty pixel support, direct mode, progress bars)
- Build.rakumod: search /opt/homebrew/bin for cmake when PATH
is stripped by mi6/zef subprocess
- Windows CI disabled pending upstream notcurses termios fix
0.1.1 2026-04-09T17:23:50+01:00
- Fix TAP harness corruption: redirect stdout/stderr to /dev/null
before notcurses init, reroute $*OUT via /dev/fd/N for TAP output
- Fix Build.rakumod: search /opt/homebrew/bin for cmake when PATH
is stripped by mi6/zef subprocess
- Fix NcBlitter enum values (NCBLIT_PIXEL was 6, should be 7)
- Fix visual functions: use $nc-lib (full) not $core-lib for FFmpeg
- Skip Unicode cell tests on non-UTF-8 environments
- Set LANG/LC_ALL=en_US.UTF-8 in CI for proper UTF-8 detection
- CI uses prove (Perl 5) instead of prove6 to avoid TAP parser bug
- Windows CI disabled pending upstream notcurses termios fix
- Add installation troubleshooting to README
0.1.0 2026-04-09T16:41:32+01:00
- Complete NativeCall wrapper for notcurses 3.0.16 TUI library
- 606 functions bound across 9 modules (100% of bindable symbols)
- Vendored notcurses 3.0.16 built with FFmpeg multimedia + FFI lib
- Build.rakumod: CMake build for macOS, Linux, Windows (MSYS2)
- Modules: Native (core), Types, Plane, Cell, Channel, Context,
Direct, Input, Visual, Widgets
- 25 CStruct types: all notcurses options structs, nccell, ncinput,
ncstats, nccapabilities, ncvgeom, ncvisual_options, timespec,
widget options (selector, menu, tree, tabbed, plot, reader, etc.)
- 19 opaque CPointer handle types for type-safe FFI
- 226 constants: NCKEY_* (130 key codes), NCSTYLE_*, NCOPTION_*,
NCALPHA_*, NCVISUAL_OPTION_*, NCMICE_*, NCBOX_*, NC_BG_* bitmasks
- 7 enums: NcLogLevel, NcAlign, NcBlitter, NcScale, NcInputType,
NcPixelImpl, NcBlitter (with corrected values matching C header)
- CStruct Str field workaround: set-cstruct-str helper + multi
method new constructors for all structs with string fields
- NcvisualOptions.set-plane method for correct plane compositing
- Visual functions use libnotcurses (full) for FFmpeg backend
- Variadic printf bindings (Rakudo 2026.03+)
- 16 test files, 161 subtests, 748+ assertions
- Tests cover: channel math, cell operations, plane lifecycle,
widget lifecycle, input handling, context/capabilities, direct
mode, visual/image loading, rendered output verification
- Render verification tests: exact text, color, style, z-order,
box drawing, erase, merge, and gradient checks via notcurses_at_yx
- 4x4 PNG test fixture for visual pipeline testing
- 8 example programs: hello, colors, boxes, input, clock,
image viewer (with kitty pixel protocol), direct mode, progress bars
- GitHub Actions CI for Linux, macOS, Windows
- Only unbound: 4 vprintf variants (va_list is not FFI-bridgeable)