# Ann: SWI-Prolog 10.1.19

**URL:** <https://swi-prolog.discourse.group/t/ann-swi-prolog-10-1-19/9874>\
**Category:** Releases\
**Created:** [October 21, 2026, 2:37pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-10-1-19/9874 "2026-10-21T14:37:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 21, 2026, 2:37pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-10-1-19/9874/1 "2026-10-21T14:37:03Z")

</div>

Dear SWI-Prolog user,

SWI-Prolog 10.1.19 is ready for download. The core has a faster virtual  
machine and much faster tabling. XPCE can now handle sound, cameras,  
video, gamepads, pens and touch screens, draw using the GPU and draw  
vector graphics. Highlights:

**Core**

- The virtual machine instructions can be compiled as functions that  
continue using guaranteed tail calls. This is now the default for  
GCC \>= 15 and Apple Clang. Together with keeping the hot code  
together and avoiding several stalls, this makes the VM faster.
- Tabling is much faster: cheaper creation, completion and resumption  
of tables, a compact trie representation, lazily compiled answer  
tries (Prolog flag `table_compile_threshold`) and the experimental  
flag `table_drop_intermediate` to drop tables that are no longer  
needed. Monotonic tabling and trie\_gen/2,3 index better.
- Fixed monotonic tabling not propagating to calls answered from  
subsumptive or abstract tables and several trie bugs: trie\_gen/2,3  
crashing on an emptied trie or missing attributed variables and  
trie\_update/3 corrupting stored compound values.
- Fixed JIT indexing dropping a single remaining candidate argument,  
deleted clauses of a static predicate remaining visible after  
reloading, #1552 (crash on a stack overflow in debug mode) and  
term\_minimal/2 and friends copying attributed variables.
- profile\_data/1 counts the self ticks of recursive predicates  
correctly.
- check\_installation/0 reports the image, sound and video formats xpce  
supports.
- The macOS release is a universal binary built using Apple Clang and  
there is a Windows installer for ARM64.

**XPCE (GUI)**

- Input devices: pens, touch screens, trackpad pinch and smooth  
scrolling, gamepads (including rumble and LED), keyboard polling and  
key\_up events. Events have a device and device specific details.
- Media: classes sound, audio\_recorder and audio\_stream play and record  
sound (MP3, Ogg, FLAC, … using SDL3\_sound), camera delivers video  
from a camera and video and video\_writer play, record and stream  
video with sound. display-\>bell can play a sound.
- Images: class animation plays and saves animated PNG, GIF and WebP,  
image-\>save writes many formats, animated cursors, copy and paste  
of images and graphicals and a tray\_icon in the system tray.
- GPU drawing: classes sdl\_texture, sdl\_layer, sdl\_window, sdl\_mesh  
and sdl\_canvas draw sprites, video and particles using the SDL  
renderer.
- Vector graphics: class canvas, path with Bezier curves, arcs and SVG  
path data, line styles, image fills, nested clipping, blend modes  
and saving graphicals and windows as SVG.
- Pango markup: classes markup and markup\_text and markup in labels,  
menu items and list\_browser items.
- Font aliases are theme fonts that can be edited in the preferences  
editor.
- IDE: a key bindings browser, keyboard control of panes and tabs,  
PceEmacs grep results in a filterable hit list. MODIFIED: PceEmacs  
loads its init file from user\_app\_config(‘xpce/emacs/init’).
- New demos, including the games Asteroids and Pong and demos for  
sound, the camera, video, particles, animations and graphics.
- The XPCE User Guide is updated for version 9, with new chapters on  
input devices and media and on paths, paint and text.
- Many fixes, notably crashes and hangs after a process terminated,  
the profiler call graph and several Epilog terminal issues.

**Platform notes**

- **MacOS:** Compiling the VM to tail-call functions causes AppleClang  
to produce faster code than GCC15. This simplifies a lot, expecially  
for those using Macports, Homebrew or build from source.
- **Windows:** Building using MSVC or MSYS2 has not been tested. Only  
the cross-compiled release build has been tested. Claude enabled  
the VM tail-call functions for MSVC. If this works it might -as for  
Clang- close the performance gap.
- **WASM:** Unfortunately enabling VM tail-call functions makes things  
worse using Emscripten’s Clang compiler. This is related to how WASM  
optimizes as well as the address validation when jumping to a function  
pointer.

**Build dependencies**

- Unfortunately the release only works with **SDL \>= 3.4.0**. Users of  
older SDL versions should use the GIT sources for building ☹

- Add **SDL3\_sound** as dependency if you want sound with anything but  
`.wav` files.

- Add **ffmpeg** as dependency if you want video on Linux and streaming  
video on MacOS or Windows. On these systems basic video decoding  
falls back to the native API. The MacOS and Windows binaries include  
a stripped down version of ffmpeg. The default install for Macports  
or Homebrew is big. Building withput `ffmpeg` uses the native video  
API of the OS. This does not support most streaming options.

# SWI-Prolog Changelog since version 10.1.18

- FIXED: waiting on a queue or thread\_wait/2 spun with a pending signal  
in sig\_atomic/1 Inside sig\_atomic/1 or a cleanup handler, signals  
cannot be handled. cv\_timedwait() nevertheless reported a pending  
signal as an interrupt, PL\_handle\_signals() did nothing and the wait  
was retried immediately. As a result, e.g., thread\_get\_message/3 with  
timeout(0) never returned. Waits now only stop for signals that can  
be handled and time out normally otherwise.

- BUILD: scripts/configure: add `deps’ to build against ~/deps for macOS  
10.15 build.deps builds what scripts/make-distribution builds for the  
bundle, using the dependencies from scripts/macos-deps.sh, but for  
this machine’s CPU and without the bundle. MACOS\_DEPS overrides ~/deps.

- BUILD: macOS deps: add a small LGPL ffmpeg and, with WITH\_SRT=yes,  
libsrt ffmpeg 8.1.3 with only libavformat, libavcodec and libavutil,  
encoding through VideoToolbox/AudioToolbox and using the bundled  
OpenSSL for TLS. xpce uses it if SWI-Prolog is configured with  
-DXPCE\_VIDEO=ffmpeg. Not yet built on a Mac.

- BUILD: MinGW: also copy DLLs named -.dll for an import  
library lib.dll.a, as ffmpeg’s Co-Authored-By: Claude Opus  
5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ENHANCED: check\_installation/0 reports the video codecs xpce can play  
and write Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- FIXED: macOS: only use dependencies from one of Macports,  
Homebrew or a directory Macports builds picked up packages from  
Homebrew, e.g., SDL3\_sound, which then loads Homebrew’s libSDL3  
next to the one from Macports. find\_package() derives prefixes  
from $PATH, which CMAKE\_IGNORE\_PATH does not stop. Now also use  
CMAKE\_IGNORE\_PREFIX\_PATH and ignore the other package managers in  
all modes. If MACOSX\_DEPENDENCIES\_FROM is a directory, add it to  
CMAKE\_PREFIX\_PATH and limit pkg-config to its .pc files.

- FIXED: profile\_data/1: ticks\_self ignored nested calls of the same  
predicate If a predicate is called (indirectly) recursively, only  
the self ticks of its outermost nodes in the call tree were counted.  
The ticks of the nested nodes are now added to the self ticks and  
removed from the sibling ticks, such that the self ticks of all  
predicates plus the accounting ticks add up to the total ticks.

- ENHANCED: check\_installation/0 reports the image formats xpce can  
save and the sound files it can load Both depend on how SDL\_image  
and SDL3\_sound were built. Nothing is reported if xpce cannot tell,  
e.g., without a display or with an older xpce.

- FIXED: macOS: allow the app to use the camera and microphone  
swipl-win was killed by TCC when XPCE opened the camera because  
Info.plist lacked NSCameraUsageDescription. The sound recorder  
needs NSMicrophoneUsageDescription for the same reason. Also add  
the camera and audio-input entitlements: under the hardened runtime,  
access is silently denied without them.

- BUILD: macOS deps: add SDL3\_sound, use libpng for SDL3\_image, update  
versions SDL3\_sound 3.2.0 (icculus/SDL\_sound) is a CMake project  
built universal next to SDL3 and SDL3\_image. All its decoders are  
built in; MIDI stays off as it needs patch files. 3.2.0 never sets  
SDLSOUND\_VERSION, which sdl3-sound.pc.in uses, so we pass it.

- TEST: cleanup of tests only removes what the test added retractall/1  
on user:file\_search\_path/2 and user:message\_property/2 also removed  
the clauses with a variable head, destroying the library search path.  
The settings test removed all settings and loaded settings files.  
Erase the asserted clauses by reference and restrict the settings  
reset to the test module.

- TEST: removed search path setup for the library alias Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- BUILD: Build the MacOS release using Apple Clang in a single pass The  
MacOS release is now a universal (arm64 + x86\_64) Release build using  
Apple Clang with CMAKE\_OSX\_ARCHITECTURES, on both Apple Silicon and  
Intel hosts. This replaces the two GCC PGO builds that were merged  
using lipo. `build --no-sign` creates an unsigned .pkg.

- WASM: default to the switch-based VM again The 19% gain of tail-calling  
VMI functions measured with Node 22 was an artifact of V8’s tiering:  
wasm functions start in the baseline compiler and V8 has no on-stack  
replacement for wasm, so the single large PL\_next\_solution() may  
run as baseline code for an entire benchmark while the small VMI  
functions are optimized quickly. With all code optimized, bench/  
takes for tail calls relative to the switch:

- DOC: src/wasm/README.md describes tiered compilation and the VM  
variants, and fixes the commands to create a self-contained .qlf  
of bench/.

- WASM: use tail-calling VMI functions by default Clang reports  
musttail for WebAssembly, but the backend can only emit tail calls  
with the tail-call feature (-mtail-call). VMI\_TAILCALL now requires  
**wasm\_tail\_call** on WebAssembly.

- PORT: Enable VMI functions by default when using AppleClang

- TEST: only test AGC reclaiming trie atoms if  
SWIPL\_TEST\_FAIL\_ON\_UNLIKELY=y Atom-GC may find stale references to  
the atoms on the stacks, making the test fail depending on the build  
(e.g., VMI\_FUNCTIONS).

- FIXED: term\_minimal/2 and friends copied attributed variables  
term\_minimal/2, term\_factorized/3,4, term\_automaton/2 and  
automaton\_minimal/2,3 copied the cell of an attributed variable in  
the input into the answer rather than referencing it. That made a  
second attributed variable that is not on the attvar chain: binding the  
original did not show in the answer, and GC could corrupt the stacks.  
In the WASM version this showed as test\_bisim failing and crashing.

- TEST: tabling tests failed without threads (WASM) Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- BUILD: GCC PGO -Wstringop-overflow false positive in trie\_gen\_raw()  
trie\_gen() passed a NULL trie when retrying. With profile data, GCC  
(MinGW 16) cloned trie\_gen\_raw() for that constant and warned about  
the first-call branch that dereferences it, though a retry never  
takes that branch.

- BUILD: compile without O\_PROFILE (WASM) Co-Authored-By: Claude Opus  
5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- BUILD: GCC PGO build failed on inconsistent profiles of the VMI  
functions With VMI\_FUNCTIONS using musttail, GCC finds the profile  
of most VMI functions not flow-consistent and refuses to use it.  
Add -fprofile-correction. The resulting build is 2-4% faster on bench/  
than a PGO build using computed goto.

- FIXED: Windows (MinGW GCC): crash compiling the boot file with VMI  
tail calls MinGW GCC accepts preserve\_none for the VMI functions,  
but the result enters a VMI with LD == NULL. Do not use preserve\_none  
for MinGW GCC.

- ENHANCED: HOT and hot VMI functions for tabling Mark trie\_insert\_flat(),  
trie\_lookup\_flat() and push\_continuation\_list() HOT and add S\_TABLED  
to src/pl-vmi-hot.h.

- ENHANCED: tabling: cheaper insertion of variant answers  
trie\_insert\_flat() dereferences the arguments once and looks up children  
inline; TRIE\_STAT\_INC() is a relaxed non-atomic increment. Variant  
answers are added without a foreign frame: tbl\_reset\_add\_answer()  
calls trie\_insert\_flat() itself and only for a new or conditional  
answer continues in tbl\_add\_answer\_found(). 500pDoubleFirst about 72%.

- ENHANCED: tabling: resume suspended goals cheaply I\_RESET pushes  
all environments of a continuation at once instead of meta-calling  
call\_continuation/1 (which remains for reset/3), the answer is unified  
directly into the skeleton of the suspension, ‘$tbl\_reset’/6 prunes  
and fails on an answer that completes the table and is no longer  
a meta-predicate.

- ENHANCED: compiled tries: save the trie VM state only at choice  
points The trie VM trails its frame slots at most once per choice  
point; T\_TRY\_\* saves TrieOffset in the CHP\_JUMP choice point instead  
of trailing it (setJumpChoice()). accManyComp 78%, accOneComp 63%,  
accManyAtom 88%.

- ENHANCED: tabling: add answers on exit of the worker Answers are added  
by I\_EXITRESET when the worker of ‘$tbl\_reset’/6 exits rather than by a  
Prolog call. Unconditional answers without delay information are added  
inline and tries no longer keep reference counts for built-in atoms.

- ENHANCED: tabling: cheaper creation and completion of tables Call  
internal deterministic foreign setup and cleanup goals directly, cheaper  
creation of a private table, run the leader using ‘$tbl\_leader’/5  
with a C cleanup and in fewer steps, return zero or one answer of a  
leader directly and reuse freed components, worklists and clusters.

- ADDED: Prolog flag table\_drop\_intermediate (experimental) If non-zero,  
abolish tables of completed child components that merely served the  
outermost tabled goal when this goal completes. Tables are kept  
if they are small, called again after completion or expensive to  
recompute (in inferences, including the dropped tables below them).  
Trie node chunks count their live nodes and empty chunks are freed,  
so pruning many variants releases memory. Deleting a node in a full  
chunk only locks if atom-GC may register the chunk.

- ENHANCED: tries: allocate nodes from chunks and avoid atomic counters  
Trie nodes are allocated from chunks. Atom-GC marks the atom keys  
of the chunks and registers the keys of full chunks.

- ENHANCED: tabling: compile answer tries lazily and discard their  
nodes Answer tries are compiled when called often enough (Prolog flag  
table\_compile\_threshold, default 32) and their nodes are discarded.  
trie\_gen/2,3 use a compact path for deep tries. table\_statistics/0  
handles answer tries with discarded nodes.

- ENHANCED: tries: compact children representation with optional striped  
write locks Trie node children are now a tagged word: no children, a  
single child or a block of {key,child} entries. Blocks up to 8 entries  
are searched linearly; larger blocks have an open addressing index.  
This replaces the lock-free hash tables, making a hashed child lookup  
about 3 times cheaper and reducing memory usage of tries.

- ENHANCED: tabling: add flat answers to the answer trie without the  
generic term walk trie\_insert\_flat() adds an atom or a compound whose  
arguments are atomic or plain variables, creating the same keys as  
trie\_lookup\_abstract(). ‘$tbl\_wkl\_add\_answer’/4 uses it first and  
falls back to trie\_lookup\_abstract() for other answers. This reduces  
the cost of an answer insertion (mostly duplicate checks) by about 25%.

- ENHANCED: tabling: S\_TABLED supervisor calls complete tables directly  
The S\_TABLED supervisor looks up the variant of a call directly from the  
frame arguments (flat calls, cached start node of the predicate in the  
variant table) and calls a complete table without going through Prolog.  
S\_INCR\_DYNAMIC uses put\_supervisor\_goal().

- FIXED: ‘$tbl\_variant\_table’/6 crashed if the first argument is  
not a closure start\_tabling/3 documents that the closure may be  
passed as 0, in which case the predicate is found from the wrapper.  
‘$tbl\_variant\_table’/6 then used a NULL predicate. Resolve the  
predicate from the variant if there is no closure.

- FIXED: calling a complete shared moded table raised a type error For  
a shared table, ‘$tbl\_variant\_table’/6 returned the compiled answer  
trie clause if the table is complete. start\_moded\_tabling/5 passes  
this to trie\_gen/2, which requires the trie. Moded tabling does not  
use the compiled answer trie, so do not request it.

- MODIFIED: GCC defaults to VMI\_FUNCTIONS if it supports musttail With  
musttail (GCC \>= 15) the VMI functions use guaranteed tail calls,  
which is faster than the single function using computed goto (GCC 16:  
bench/ 97%, tabling 91-101%). Older GCC keeps computed goto.

- ENHANCED: keep the hot VMI and C functions of the VM together  
src/pl-vmi-hot.h lists the 80 VMI/VMH functions with the most cycles  
on bench/ and the tabling benchmarks (doc/tabling/tools/vmi-hot.sh).  
pl-wam.c redeclares these with **attribute** ((hot)) when using  
tail-calling VMI functions, which groups them in .text.hot (33.5Kb  
contiguous instead of spread over 94Kb). HOT marks the hottest C  
functions of the VM (clause selection, unify, tries, continuations,  
fastheap terms), so they are placed next to these: the instruction  
cache behaviour of the hot code then no longer depends on the placement  
of unrelated code.

- ENHANCED: tail-calling VMI functions With VMI\_FUNCTIONS and a compiler  
supporting musttail (GCC \>= 15, Clang \>= 13), VMI and VMH functions  
continue with a guaranteed tail call of the next instruction instead  
of returning to the dispatch loop. Helper arguments are passed  
in the register file so all functions have the same signature.  
With preserve\_none the hot registers LD, PC, FR, the register file  
(r15) and ARGP are arguments. VMI functions are noinline (GCC 16 drops  
musttail in inlined VMIs). VMCODE\_IS\_ADDRESS is used for Clang too.  
VMI\_TAILCALL=0 and VMI\_CC= select the fallbacks.

- ENHANCED: mark slow-path functions COLD Add COLD ( **attribute** ((cold)))  
and apply it to functions that are only called on slow paths: stack  
overflows and growing the stacks, errors, the debugger, tracing,  
coverage, profiling, etc. GCC moves the blocks calling these  
into the .cold part of the caller, which shrinks the hot part of  
PL\_next\_solution() from 92.9Kb to 74.2Kb.

- ENHANCED: put\_fastheap(): relocate by tag in a single pass Drop the  
relocation array from fastheap records: the term part holds only tagged  
cells, so a cell is relocated iff it has STG\_GLOBAL storage and is  
not a functor (mask table). Restoring is a single branch-free pass  
with post-passes for attvars and atoms only if needed. Records are  
about 40% smaller.

- ENHANCED: avoid store-to-load forwarding stalls in arithmetic and clause  
choice points A struct copy or memcpy() of data just written by narrower  
stores compiles to wide loads that cannot be store-forwarded and stall  
until the stores retired. moveNumber() copies small integers and floats  
by field; clause choices and moved choice points are copied using scalar  
moves (copyWordsScalarUp()/copyWordsScalarDown(), copyClauseChoice()).

- ENHANCED: use non-atomic updates for the flags of local frames set()  
and clear() use atomic operations. Local frames are only accessed by  
their own thread, so the VM can update their flags with plain stores.  
The locked instructions were paid on every non-deterministic exit,  
SSU commit, cut, etc. Adds setLocal() and clearLocal().

- ENHANCED: per-thread cache for looking up modules by name Meta calls  
look up the module of M:Goal by name. Each thread now caches the  
most recent lookups in a direct-mapped cache of 8 entries, which is  
flushed when a module is destroyed. Calling a qualified goal takes  
10% fewer instructions.

- ENHANCED: do not validate term\_t for internal PL\_get\_blob() and  
PL\_get\_pointer\_ex() As for the other PL\_\*() functions, the exported  
functions validate their arguments and internal callers use the \_\_\_LD  
version without validation. These two are used by the tabling and  
trie predicates for each table.

- ENHANCED: dark theme: colours for the CPU gauges of the thread monitor  
and the code ranges of the symbol picker Co-Authored-By: Claude Opus  
5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ENHANCED: dark theme: colours for error and warning reports, the failing  
part of an incremental search and code in running text Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ENHANCED: dark theme: colour for filter matches in PceEmacs hit lists  
Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com) Claude-Session:  
[https://claude.ai/code/session\_01UgGX2Hqkp4kavsXYTKX8Sf](https://claude.ai/code/session_01UgGX2Hqkp4kavsXYTKX8Sf)

- FIXED: #1552 crash when unwinding a stack overflow in debug mode If  
there is no space to start the tracer, b\_throw\_unwind\_debug retries  
while unwinding using dbg\_except\_start\_tracer(). This runs GC, trims  
the stacks and prints the message, which may move the local stack.  
The VM registers were not saved and reloaded around this call,  
leaving FR pointing at the old stack.

- FIXED: JIT indexing: a single remaining candidate argument was dropped  
candidate\_indexes() only merged the remaining single-argument candidates  
inside the block that builds two-argument combinations, which requires  
at least two assessments. If exactly one poor but useful argument  
remained (e.g., the parent argument of bintree(Parent,Child) with the  
child argument as good index), it was silently discarded. As static  
predicates have fixed candidate indexes, calls on that argument then  
scanned all clauses. This made the bintree18 tabling benchmark about  
60 times slower.

- BUILD: macOS deps: build libpng so that cairo has the SVG surface  
cairo builds its SVG surface only along with the PNG functions,  
so XPCE’s -\>svg was unavailable in the bundle.

- TEST: monotonic propagation to reused tables and trie value/delete cases  
test\_mono\_reuse.pl covers several binding patterns on one subsumptive  
table, a subsumed call on a recursive table, a dependency created  
during propagation, incremental+monotonic subsumptive tables, indirect  
keys in abstracted calls and reevaluation of an invalidated incremental  
abstract table. test\_trie.pl adds an emptied root that held a variable  
key and balanced atom references over repeated trie\_update/3 calls.

- DOC: trie\_gen/3: do not claim the cost only depends on matching paths  
A variable in Key still visits every stored subterm at its place.  
Also state that the enumeration order is undefined and that a choice  
point may be left after the last answer.

- FIXED: monotonic dependency index left a foreign frame open on errors  
mono\_index\_find(), mono\_index\_insert() and mono\_index\_build() returned  
on an error without closing the foreign frame they opened. Close it,  
keeping the exception. Also update the comment on cluster.sindex,  
which now indexes on several key paths.

- ENHANCED: trie\_gen/2,3 keep pruning on bound arguments after a variable  
trie\_gen/2,3 followed the bound arguments of Key only up to the  
first variable, in Key or in a stored key. From there it enumerated  
the whole subtrie and left it to unification to reject the paths,  
so looking up p(a, 25000) in a trie of p(\_, I) keys walked every I.  
dyn\_affected/2 in boot/tabling.pl makes such a lookup on the variant  
table of an incremental predicate for every fact the predicate gains  
or loses.

- ENHANCED: tabling: index suspensions on key paths during completion  
During completion ‘$tbl\_wkl\_work’/6 offers every answer of an answer  
cluster to every suspension of the suspension cluster it is paired with.  
A suspension of a call answered from a more general table carries the  
call as an instance. The scan rejects it cheaply only when a key of  
an argument of that instance differs from the answer’s, and otherwise  
copies the instance from the fastheap and unifies it with the answer.

- ENHANCED: monotonic tabling: index a table’s dependencies by skeleton  
Calls answered from an abstract or more general table each record  
a monotonic dependency on that table with their own skeleton.  
The dependencies of one (source, consumer) edge form a chain:  
find\_dep() walks it to find a duplicate of each new dependency, and  
propagating an answer copies and unifies every dependency of the source.  
One consumer making N bound calls to one abstracted table cost 2.1 s  
to evaluate for N = 32000, against 0.40 s through N variant tables,  
and each later answer 6.6 ms to propagate, against 8 us.

- FIXED: monotonic tabling: propagate to calls answered from subsumptive  
and abstract tables A call to a monotonic tabled predicate that is  
answered from a table other than a new variant table of its own did  
not record its dependency on that table: a subsumed call reading a  
more general table, a call reusing an existing variant table of a  
subsumptive predicate, and a call abstracted by subgoal\_abstract(N).  
Answers that monotonic propagation later added to that table never  
reached the caller. For example, with

- FIXED: trie\_gen/2,3 crashed on a trie emptied by trie\_delete/3  
When trie\_delete/3 removes the last key below a root whose children  
are hashed, prune\_node() stops at the root and leaves it the empty  
table. add\_choice() enumerated that table without testing whether  
advanceTableEnum() produced a child and used the undefined key  
and child:

- FIXED: trie\_gen/2,3 missed a stored attvar in a hashed trie node  
When the children of a trie node are hashed and the query is bound at  
that position, add\_choice() looks up the query’s own key and then the  
variable keys recorded in the node’s var\_mask. update\_var\_mask() only  
records plain variables (TAG\_VAR), so the key of a stored attributed  
variable, (N\<\<LMASK\_BITS)|TAG\_ATTVAR|STG\_STATIC, was never tried and  
the answer was lost. With a single child (TN\_KEY) the attributed  
variable was found:

- FIXED: trie\_update/3 and trie\_insert/3 corrupted a stored compound  
value variantRecords(), which equal\_value() uses to compare the value  
stored at a trie node with a new one, called memcpy() where memcmp()  
was meant. For two records of the same size it copied the new record  
over the old one and, as memcpy() returns its destination, reported  
them as different.

- FIXED: clause\_info/4 failed on optimised clauses using dicts in  
maplist/N or debug/3 library(apply\_macros) reorders the arguments  
of maplist/N, which changes the order of the ‘.’/3 calls that  
evaluate dicts. Decompiled ‘.’/3 goals may now match any goal in a  
run of ‘.’/3 calls. Also skip the ‘.’/3 calls of a goal removed by  
optimisation such as debug/3.

- FIXED: clause\_info/4 failed on clauses with `Var is Int + Var` The  
compiler turns this into A\_ADD\_FC, which decompiles as `Var is Var

- FIXED: reloading a file that deletes clauses from an indexed  
static predicate left the deleted clauses reachable through the  
index reconsultFinalizePredicate() only updated the clause indexes  
for dynamic predicates. Since the static code fast path skips the  
visibility check, the erased clauses remained visible through the  
JIT indexes after make/0.

- FIXED: with optimise, var/1 and nonvar/1 on a fresh variable did  
not mark the variable as initialised. As 7dba157ea, this could  
leave the variable uninitialised after + inside a branch of ;/2.  
Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ADDED: Build the ARM64 Windows installer in the release workflow Turn  
the single x64 job into a matrix over {x64, arm64}. The ARM64 leg runs  
on a native aarch64 runner (ubuntu-24.04-arm), as the ARM64 host tools  
execute under Wine and need a 4K-page aarch64 kernel. It uses the  
swipl-mingw-build-arm64 image and --winarm64-from-git. fail-fast is  
disabled so a failure on one architecture does not cancel the other.

## Package RDF

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package chr

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package clib

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package cpp

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package http

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package inclpr

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package jpl

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package odbc

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package pengines

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package pldoc

- CLEANUP: declare latex//1 and print\_latex/3 public They are called  
by xpce’s gen\_refman.pl.

## Package protobufs

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package semweb

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package ssl

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package xpce

- MODIFIED: xdot demo only lists the installed graphviz layout engines  
Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- FIXED: clicking a menu bar moved the keyboard focus of the frame If  
the window holding the menu bar wants the keyboard, e.g., a dialog  
with a text\_item, a click on the menu bar made it the keyboard focus  
of the frame. After the menu, or a dialog opened from it, such as  
PceEmacs Edit/Replace, closed, the keys no longer went to the window  
the user was working in. A click on a menu bar now leaves the focus  
alone. Keyboard operation of the menu is not affected: while open,  
the menu bar grabs the keyboard.

- FIXED: closing a transient frame could leave its owner without the  
keyboard Window managers are supposed to give the keyboard back to the  
window a dialog is transient for when the dialog closes. GNOME with  
focus-follows-mouse does not always do so, leaving the owner visible but  
without a caret or keys. If the transient had the keyboard and nothing  
took it over, raise the transient\_for frame ourselves, on all platforms.

- DOC: Versioned userguide upload

- BUILD: take the xpce version from the VERSION file CMake, the C kernel  
(via config.h) and the User Guide’s version.tex now all get PCE\_VERSION  
from VERSION. Removed the stale fallback definition from h/interface.h.

- DOC: User Guide: SDL’s PipeWire camera driver does not work  
Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- FIXED: demo video player: loading a file raised `@nil \<-duration’ -\>open  
reports the status synchronously for a local file, so -\>video\_status  
ran -\>prepare before -\>load had set the video slot.

- FIXED: SDL timer: a tick queued before -\>stop still ran the message  
Closing the Asteroids or Pong window stops its timer in -\>unlink,  
but a tick that was already in the event queue then sent -\>tick to  
the freed window.

- DOC: User Guide section “Drawing with the GPU” with mesh and canvas  
examples; refman links to sdl\_mesh and sdl\_canvas The User Guide  
documents pce\_sdl\_mesh\_set/3. The anchors of the sdl\_mesh and  
sdl\_canvas pages used hyphens, which broke links to them.

- ADDED: demo Particles; demos Asteroids, Pong and Camera use the new  
GPU drawing Particles draws thousands of glowing particles using a  
single sdl\_mesh. Asteroids has glowing sparks, drifting tiled dust  
and an exhaust trail drawn into an sdl\_canvas, Pong glowing sparks  
and a net of one tiled layer and Camera ripple and fisheye effects  
that warp the video using an sdl\_mesh.

- ADDED: class sdl\_canvas draws sdl\_layer objects into a texture that a  
layer shows Moves many sprites as one, shows the same layers again,  
e.g., as a minimap, and leaves trails with sdl\_canvas\<-\>clear @off.  
The renderer draws a canvas before the frame and only after it changed.

- MODIFIED: sdl\_layer\<-window is now sdl\_layer\<-device, as  
graphical\<-device This prepares for layers shown on an off-screen  
sdl\_canvas.

- ADDED: class sdl\_mesh: triangles with coloured corners that an sdl\_layer  
draws, mapping its texture onto them sdl\_layer\<-\>mesh makes a layer  
draw the triangles of a mesh using SDL\_RenderGeometry(). This draws  
gradients, warps a texture and draws many particles in one layer.  
pce\_sdl\_mesh\_set/3 replaces all triangles of a mesh in one call.

- FIXED: translucent sdl\_layer textures drawn with a shear replaced  
what is below on the software renderer SDL’s software renderer draws  
triangles without the premultiplied blend modes. It now gets textures  
with straight alpha.

- ADDED: sdl\_layer blend modes, tint, scale mode, tiling and 9-slice  
scaling sdl\_layer\<-\>blend selects SDL’s blend modes (blend, add,  
mod, mul, none), \<-\>tint multiplies the colours of the texture  
and \<-\>scale\_mode selects linear, nearest or pixelart sampling.  
Scale `tile` repeats the texture over \<-area, shifted by \<-\>offset,  
and \<-\>slices scales it as nine parts that keep the size of the corners.

- FIXED: sdl\_layer\<-alpha was too bright for images and ignored for  
camera and video frames SDL does not scale the RGB of premultiplied  
textures by the alpha mod, and textures without an alpha channel were  
drawn without blending.

- DOC: xpce refman: fix links to classes whose name contains an  
underscore Several newer class pages used hyphens in their anchor  
(e.g. {#class-sdl-layer}), giving the label sec:class-sdl-layer,  
while \class{sdl\_layer} links to sec:class-sdllayer (PlDoc strips the  
`_`). Links to these classes were therefore missing.

- DOC: User Guide: video backends, sprite stacking, cursor none and  
class summary entries for SDL and video classes Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ADDED: demo Pong: the good old game for one or two players Play against  
the computer or with two players using the keyboard or gamepads.  
Like the Asteroids demo, the paddles, ball, trail, sparks and net  
are GPU sprites driven by a timer, the controls are polled and the  
beeps are generated sound. Before the first game the computer plays  
against itself.

- ENHANCED: demos Camera and Sound: tidier controls with tooltips,  
split buttons and a REC/LIVE/PLAY indicator Start/Stop, Record/Stop  
and Play/Stop are single buttons whose label changes. Snapshot,  
Record and Open are split buttons whose menu holds the other actions,  
e.g., saving a snapshot, streaming to a URL or recording to a WAV file.

- ADDED: classes video and video\_writer play, record and stream encoded  
video with sound A video plays a file, a URL (http, HLS, RTSP,  
UDP, …) or encoded data written to it, e.g., using pce\_open/3.  
Its frames go into an sdl\_texture, so an sdl\_layer shows them in an  
sdl\_window without Cairo, and its sound sets the time. It can play,  
pause, seek and loop, gives thumbnails and keeps up with live streams.  
A video\_writer encodes images, textures, frames, windows, cameras  
and the microphone into a file, streams them to a URL (RTMP, SRT,  
UDP, TCP, RTP, HLS) or gives the data to code. The backends are  
ffmpeg (Linux, and Windows and macOS with -DXPCE\_VIDEO=ffmpeg), Media  
Foundation (Windows) and AVFoundation (macOS); streaming needs ffmpeg.  
library(pce\_video) writes video to a Prolog stream. Demos: Video  
player, Camera records and streams.

- FIXED: A slider without label or values was too high and its bar was  
not aligned with the items in its row Without a label, the reference  
point of a slider is the baseline of its values or, without these,  
such that its bar is at the middle of the text of the other items.  
The height only includes the label and the values if they are shown.

- FIXED: Compile with SDL \< 3.4.16, where pen proximity events have no  
pen\_state Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- FIXED: Crash decoding data SDL\_sound does not recognise on macOS  
SDL3\_sound’s CoreAudio decoder crashes if no file extension is given,  
which happens for an audio\_stream with encoded data and when loading a  
file whose name has no extension. Pass “” instead, which also makes  
SDL\_sound try all decoders.

- TEST: sdl\_keyboard:text\_input only checks the key events Dispatching  
events for 0.2 seconds also delivers the events of the real pointer,  
e.g., area\_enter and loc\_move on Windows if the pointer is over the  
new window.

- ENHANCED: Asteroids demo draws its objects as GPU sprites, has buttons  
to play, edit the settings and show the controls, and hides the pointer  
while playing The field is an sdl\_window and the ship, rocks, bullets,  
particles and stars are sdl\_layer subclasses with a texture drawn  
once from a figure. The buttons appear on start-up, after the game  
is over and while it is paused. Settings opens the class variable  
editor on the preferences of the game. F1 shows the controls.

- ADDED: predefined cursor none hides the pointer Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ADDED: classes sdl\_texture, sdl\_layer and sdl\_window draw pixels with  
the SDL renderer instead of Cairo An sdl\_texture keeps its pixels in  
their own format. An sdl\_layer places it in an sdl\_window, scaled  
to an area or as a sprite that is moved, rotated and scaled using a  
transform around the texture’s hot spot. The layers are drawn below  
the graphicals of the window, so these can annotate, e.g., video.  
camera-\>texture delivers frames to a texture without converting them,  
which the Camera demo uses. Textures are made from an image or a  
graphical, image-\>copy converts them back and sdl\_texture-\>draw\_in  
draws on them.

- ENHANCED: The class variable editor serves applications: Control-comma  
opens it and it shows the class variables of application classes  
Control-comma (Command-comma on MacOS) opens the class variable editor  
on the object below the pointer in any xpce window, or shows that object  
in the editor that is open. Without a preferences specification,  
the editor shows the class variables the manual classifies as basic.  
The manual does not know the classes of an application, so all class  
variables of these classes are now basic.

- ENHANCED: Asteroids demo: game objects are graphicals that hold their  
own state The ship, asteroids, bullets, particles, stars and scoreboard  
texts are now classes that keep their position, velocity and timers  
in slots and update themselves in a -\>tick method. The window holds  
the state of the game as a whole and ticks everything using

- ADDED: display\_manager\<-audio\_output tells whether there is a device to  
play sound on The first request starts the audio subsystem. From then  
on the value follows the playback devices that are added and removed.  
This allows an application to make sound optional: playing a sound  
or audio\_stream without an audio device prints an error.

- ENHANCED: The event viewer shows the button, click, rotation, device  
and event\<-detail of an event; event\_node\<-\>summary describes each event  
type All types of @event\_tree have a summary, including those of pens,  
touch screens, pinches, gamepads, devices, drag-and-drop and key\_up.  
The event viewer shows it; a key that types a character shows the  
summary of its kind. Fixed the description of cursor\_down and the  
function keys.

- ADDED: key\_up event for releasing a key and event\<-repeat for  
auto-repeated key-downs A key\_up is not a keyboard event, so key  
bindings and text editing do not see it. It goes to the keyboard focus  
and its event\<-key is that of the key-down it releases. Both carry  
a new event\_detail, key\_data. frame-\>sdl\_test\_event accepts text\_input.

- FIXED: A window without text input did not get the keys of plain  
characters Without text input, as in a plain window without a focused  
text\_item or editor, SDL sends no text input event. The key-down now  
gives the character, shifted as the keymap says, without waiting  
for text. Dead keys and input methods still need text input.  
frame-\>sdl\_test\_event accepts key\_down and key\_up.

- FIXED: A read-only text\_item that has the keyboard focus showed an  
active caret A read-only item still takes the focus when clicked,  
so text can be selected with Shift-cursor and copied with C-c, but  
it shows no caret.

- ENHANCED: file\_item has a browse icon; library(find\_file) uses the  
file dialog of the desktop unless display.native\_file\_dialog is @off  
text\_item\<-\>icon and \<-\>icon\_message show a clickable image right  
of the field. file\_item uses it to run -\>browse (class variable  
browse\_image), replacing the separate “Browse …” buttons of the  
PceEmacs prompter and the class variable editor. file\_item\<-\>filter  
sets the extensions offered. @finder uses frame\<-open\_file, \<-save\_file  
and the new \<-open\_directory if display.native\_file\_dialog is @on and  
a frame is shown. The sound demo uses a file\_item for the location  
it streams.

- ADDED: class audio\_stream plays audio while it is written;  
audio\_recorder-\>record(to=[source\_sink]) writes while recording An  
audio\_stream is a source\_sink that plays raw samples or encoded data  
(WAV, MP3, FLAC, …; not Ogg Vorbis) while Prolog writes it using  
pce\_open/3 or -\>append. \<-low\_water\_message asks for more data,  
closing the stream ends the data and \<-message runs when everything  
is played. audio\_recorder-\>record(to=File) writes a WAV file while  
recording; any other source\_sink gets the raw samples.

- ENHANCED: pce\_open/3: binary streams on a source\_sink with encoding  
octet; -\>close\_as\_file pce\_open/3 opens a binary stream on a source\_sink  
whose encoding is octet, so -\>write\_as\_file gets the bytes unchanged.  
Closing a stream opened for writing sends -\>close\_as\_file to the  
object, a new virtual method of source\_sink.

- ADDED: variable\<-types, as method\<-types The argument types of the send  
method: \<-type if the variable can be set, none if it can only be read.  
Fails if the variable is not accessible. Fixes M-x comment-column  
in PceEmacs language modes, where comment\_column is a slot.

- FIXED: PceEmacs grep: report a failing command in PceEmacs and show  
the outcome of the next grep A failing grep reported its exit status  
on the console, and its error message stayed on the PceEmacs status  
bar, hiding the outcome of later greps.

- ENHANCED: Theme preferences edit display.bell\_sound The bell sound  
is edited using a file\_item with a Browse button that starts in the  
desktop’s sound directory. Bell pitch and duration are inactive if  
a bell sound file is set.

- ENHANCED: display-\>bell plays a sound: display.bell\_sound or a tone  
made by the new sound-\>tone display\<-bell\_sound returns the sound -\>bell  
plays. The class variable display.bell\_sound names a sound file to play  
instead of the tone of display.bell\_pitch and display.bell\_duration.  
The tone now fades in and out, so it no longer clicks.

- FIXED: PlDoc warning on -\>goto\_history in pce\_html\_manual.pl xpce  
member comments take a bare header; the signature is derived from  
the method definition.

- TEST: frame-\>sdl\_test\_event lost negative device ids on ARM64 (macOS)  
It converted the float field value directly to the unsigned id type,  
which is undefined for negative values: ARM64 gives 0 instead of,  
e.g., SDL\_PEN\_MOUSEID. The tests sdl\_emulation:pen\_mouse\_ignored  
and touch\_mouse\_ignored failed on macOS.

- DOC: no “PlDoc: unknown tag @cursors” warning when building the  
reference manual `@see @cursors` makes PlDoc read @cursors as a tag.  
Added it, and the other globals that follow an @see (@completer,  
@errors and @key\_bindings), to the globals for which pldoc\_xpce  
suppresses this warning.

- ENHANCED: demos ImageViewer and Juggler use class animation ImageViewer  
plays animated PNG, GIF, WebP and AVIF files and shows WebP, AVIF,  
BMP, ICO, CUR and ANI files. Juggler plays an animation made from  
its SVG images; its speed sets the delays of the frames. Also fixed  
the spelling of the Juggler’s description in the demo browser.

- FIXED: image-\>copy painted the copy over the old pixels, losing  
transparency As a result, animation-\>append also made the transparent  
parts of a frame, e.g., of an SVG image, opaque white.

- FIXED: semi-transparent pixels were too dark when saved, copied or  
used in a cursor, and image-\>pixel ignored premultiplied alpha Images  
are Cairo surfaces with premultiplied alpha. Converting them for SDL  
(saving, the clipboard, cursors) now unpremultiplies, and image-\>pixel  
and image\<-pixel convert between the straight alpha of colours and  
the premultiplied pixels.

- ADDED: animated cursors: cursor(Name, Animation), e.g., from a  
Windows .ani file Images keep the hot spot of CUR and ANI files in  
image\<-hot\_spot and save it, so cursor/2 uses the hot spot of the  
file by default.

- ADDED: animation-\>append, -\>record and -\>save: make and save animated  
PNG, GIF and WebP files, with their loop count and metadata An  
animation can now be made from images (-\>append) or by recording a  
frame or window (-\>record, -\>stop), and saved as an animated image file  
(-\>save). -\>save writes \<-\>loop\_count and the new \<-\>title, \<-\>author,  
\<-\>description and \<-\>copyright, as far as the format can hold them.  
Loading finds the format from the data rather than the file name.

- ENHANCED: image-\>save writes JPEG, WebP, AVIF, GIF, BMP, TGA, ICO  
and CUR The format defaults to the one the file extension selects,  
PNG if the extension is not one of these. A new third argument sets  
the quality of JPEG, WebP and AVIF. display\<-image\_save\_formats lists  
the formats SDL\_image can write.

- MODIFIED: PceEmacs loads its init file from  
user\_app\_config(‘xpce/emacs/init’) On all platforms, PceEmacs now  
loads xpce/emacs/init.pl from the user’s configuration directory  
(e.g., ~/.config/swi-prolog) instead of ~/.pceemacsrc or, on Windows,  
pceemacs.ini. If only the old file exists, PceEmacs prints a warning  
asking to move it.

- ADDED: demo Animated images: play animated PNG, GIF and WebP files  
Plays an animation in a bitmap, with controls to play, stop, step  
and select a frame, and a film strip of all frames. The default  
animation is the public domain bouncing beach ball APNG by Holger  
Will from Wikimedia Commons.

- ADDED: class animation holds the frames of animated PNG, GIF,  
WebP and AVIF files; a bitmap plays it animation(File) decodes all  
frames using SDL\_image, with \<-delays per frame and \<-loop\_count.  
bitmap(Animation) shows its first frame; bitmap-\>play, -\>stop and  
-\>frame play it or show a frame, and \<-playing tells whether it plays.

- FIXED: Windows: class sound only loaded WAV files although SDL3\_sound  
was found Windows did not use the config.h that CMake generates, but the  
hand-written src/md/md-win64.h, so HAVE\_SDL3\_SOUND was never defined.  
All platforms now use config.h. src/md/md-windows.h is reduced to  
what CMake cannot know about Windows or finds although it does not  
work for xpce on Windows, such as select() and mkstemp().

- FIXED: Windows: the drop shadow of popups was black SDL’s transparent  
windows show black where they should be transparent, both on Windows  
11 and on Wine. Popups on Windows are now opaque and drawn without  
a shadow, as on X11 without a compositor. Windows 11 rounds their  
corners.

- ENHANCED: Epilog: a pane whose shell waits for a command closes  
without asking An interactive shell is the foreground process group  
of its terminal while it waits for input, so closing the pane asked  
for confirmation because “a program is running”. Epilog now remembers  
the pid of the shell it starts and only asks if another process group,  
i.e., a command run by the shell, holds the terminal.

- ENHANCED: demo browser shows the demos in groups with headings The  
demos are grouped as Applications and tools, Dialogs and windows,  
Graphics, Media and devices and Games and animation, followed by the  
contributions. Demos that are not in a group appear under Other demos.

- ADDED: demo Asteroids: a game using keyboard polling, gamepads and  
sound Fly a ship through an asteroid field and shoot the asteroids,  
which break up into smaller ones. The game polls the keyboard  
(keyboard\<-key\_down) and a gamepad on each tick of a timer, moves  
and rotates figures using figure-\>transform and plays sound effects  
that it generates as WAV data. The asteroids are shaded using radial  
gradients and glow, and explosions fade out using opacity.

- ADDED: class keyboard; @keyboard\_device\<-key\_down polls whether a  
key is held @keyboard\_device is now an instance of class keyboard, a  
subclass of input\_device, like class gamepad. There are no events for  
releasing a key, so applications such as games can poll the keyboard,  
e.g., get(@keyboard\_device, key\_down, cursor\_left, @on).

- ADDED: demo Sound: record, replay, load and save sound Records from  
the microphone while showing the input level and the growing waveform,  
plays the sound back, loads sound files (MP3, Ogg, FLAC, … if xpce  
has SDL3\_sound) and saves the sound as WAV.

- ENHANCED: class sound loads MP3, Ogg Vorbis, FLAC, … using SDL3\_sound  
If SDL3\_sound is available, sound-\>load decodes WAV, MP3, Ogg Vorbis,  
FLAC, AIFF, AU, VOC and module files. @pce then has the feature  
sound\_decoders. display\<-sound\_file\_extensions lists the extensions  
that can be loaded. Added sound\<-peaks to draw a waveform.

- ENHANCED: camera decodes Motion JPEG frames; camera-\>open accepts a  
size Most webcams deliver Motion JPEG frames without Huffman tables,  
which SDL cannot convert. The frames are now decoded using SDL\_image.  
camera-\>open(Size) uses the supported frame size that is closest, with  
the highest frame rate, and camera\<-sizes lists the supported sizes.  
The Camera demo lets the user choose the size.

- ADDED: demo Camera: show the video of a camera and take snapshots The  
demo shows the video of the camera selected in a menu, the status of  
the camera, the frame size and the frame rate. Snapshot copies the  
current frame, which can be saved as PNG or copied to the clipboard.

- DOC: User Guide chapter “Input devices and media” Describes  
event\<-device and event\<-detail, sub-pixel positions and smooth  
scrolling, pens, touch screens and pinch gestures, gamepads, sound,  
cameras, images on the clipboard, the system tray, power and locale  
and how to test input without the devices. The examples are in  
examples/devices.pl. Other chapters refer to it.

- ADDED: class tray\_icon shows an icon with a menu in the system tray  
tray\_icon(Image, Tooltip, Popup) shows Image in the system tray  
(notification area). Its menu is built from the popup: selecting an  
entry executes the popup with the tray\_icon as context. Sub-popups  
become submenus. On Linux this requires libayatana-appindicator.

- ADDED: display\<-power\_state, \<-battery\_percent,  
\<-battery\_seconds and \<-preferred\_locales Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com) Claude-Session:  
[https://claude.ai/code/session\_01R86ZKx3ZMkfQcXM87545Tt](https://claude.ai/code/session_01R86ZKx3ZMkfQcXM87545Tt)

- ADDED: copy and paste images and graphicals using the clipboard  
display-\>copy and display-\>selection accept an image (offered as  
PNG) or a graphical (offered as SVG and PNG). display\<-selection  
with target `image` returns an image from PNG, JPEG or another  
image format on the clipboard and with target `svg` the SVG text.  
display\<-selection\_targets lists the MIME types on the clipboard.

- ADDED: class camera delivers video from a camera as an image  
camera-\>open starts the camera. Each frame is copied into the same  
camera\<-image, so a bitmap showing this image shows the video, and  
camera\<-message is executed. \<-status tells whether the user gave  
permission (waiting, open, denied); \<-status\_message reports changes.  
display\<-cameras lists the available cameras.

- ADDED: class sound to play WAV files and class audio\_recorder  
sound(File) loads a WAV file. -\>play plays it, possibly several  
times at once, -\>stop stops it and \<-message is executed when a play  
is finished. -\>save writes a WAV file. An audio\_recorder records  
from the default input (-\>record, -\>stop) into its \<-sound and executes  
its \<-level\_message with the input level while recording.

- ADDED: gamepads: events, hot-plug, polling, rumble and LED  
display\<-gamepads enables gamepads and returns the connected ones.  
Their buttons and axes generate gamepad\_button\_down, gamepad\_button\_up  
and gamepad\_axis events for the window with the keyboard focus,  
whose \<-detail is a gamepad\_input (event\<-control, event\<-value).  
Controls are named by position (south, east, dpad\_up, left\_x, …).  
A gamepad can be polled (\<-button, \<-axis) and may -\>rumble and show a  
colour (-\>led). When a device is added or removed, the keyboard-focus  
window of each frame receives a device\_added or device\_removed event.

- ADDED: pen, touch screen and trackpad pinch input A pen and the  
first finger on a touch screen act as the mouse, so mouse-only  
applications work. Their events carry the device and its data:  
event\<-pressure, \<-xtilt, \<-eraser, … (class pen\_state) and  
event\<-finger (class touch\_point). Other fingers generate touch\_\*  
events. A trackpad zoom gesture generates pinch\_begin, pinch\_update  
and pinch\_end with event\<-scale; library(pan\_zoom) zooms on a pinch.  
frame-\>sdl\_test\_event allows testing this input without the devices.

- ADDED: precise and smooth scrolling for trackpads Wheel events  
report the precise scroll distance of trackpads and high resolution  
wheels as event\<-dx and \<-dy (class wheel\_data). In a window with  
window\<-\>smooth\_scroll @on, every scroll step generates a wheel event  
whose \<-rotation may be a fraction of a notch. The built-in handlers  
add up the fractions: a window scrolls by whole pixels, an editor or  
list\_browser by whole lines.

- ENHANCED: each input device has its own event state The defaults  
for a new event, the multiclick detection, the implicit grab from a  
button-down to its up and the window holding the pointer are kept  
per input\_device. Interleaved events from the mouse and a pen or  
touch screen thus no longer disturb each other. Keyboard events use  
the state of the last pointer device, as before.

- MODIFIED: drop events answer \<-path and \<-text instead of attributes  
The detail of a drop\_\* event is a drop\_data, and class event delegates  
to its \<-detail. So the dropped file and text are now available as  
event\<-path and event\<-text, and event\<-source gives the application  
that sent the drop. Use get(Ev, path, Path) instead of get(Ev,  
attribute, path, Path).

- ADDED: event\<-device and event\<-detail, classes input\_device and  
event\_detail Each event refers to the input\_device that generated  
it: @mouse\_device, @keyboard\_device or, later, a pen, touch  
screen or gamepad. display\<-input\_devices lists the known devices.  
event\<-detail will hold device specific data such as pen pressure; it  
is @nil for now. event-\>initialise accepts the device as an optional  
7th argument. If omitted, keyboard events use @keyboard\_device and  
other events use the device of the last pointer event.

- ADDED: window\<-\>subpixel\_events: events keep the fractional position  
Events now store the position the window system reports, including  
the fraction. The position getters (event\<-x, \<-y, \<-position, …)  
return it for a window with subpixel\_events @on. Otherwise they  
return whole pixels, rounded down, as before. This prepares for pen  
and touch input.

- FIXED: terminal: an erase to the end of the line that starts beyond  
the text of the line used the default background Whiptail dialogs  
(e.g., raspi-config) draw the shadow of their window this way, so  
the shadow was missing. Cells that are added to a line to reach the  
caret now also keep the colour of an earlier erase.

- TEST: test cleanup only removes the search paths the test added  
retractall/1 on user:file\_search\_path/2 also removed the clauses  
with a variable head, destroying the library search path. Erase the  
asserted clauses by reference. The tracer configuration sandbox  
moved to xpce\_test\_sandbox.pl and is removed after the tests.

- ENHANCED: font alias label for the labels of the user interface The  
label\_font of dialog items, dialog groups, list browsers, editors,  
window decorations and the display defaults to the new alias `label`  
rather than `bold`. It is bold, so nothing changes by default, but  
labels can now use a normal font without affecting bold text, e.g.,  
using font.system\_fonts: [label := font(sans, normal, 12)].

- ENHANCED: menu items and dialog labels can be markup The label of a  
menu\_item, dialog item, dialog group or tab may be a markup object,  
which is displayed with its fonts, colours, etc. The mnemonic is  
chosen from the text without the markup and underlined. A cycle menu  
that is too narrow ellipsizes the markup.

- ENHANCED: font\_item offers the installed Pango families The family  
menu lists the generic families sans, serif and mono, followed by the  
installed families, shown in their own font. Items for a mono\_font  
and the monospaced font aliases only offer the monospaced families.  
The list that opens from the family menu shows 15 lines.

- FIXED: the list of a cycle menu did not show the selection The list  
was scrolled before its frame had its final size, so it always opened  
at the top.

- ENHANCED: menu-\>max\_value\_width ellipsizes the value of a cycle menu  
A cycle menu with many long values, such as font families, no longer  
needs to be as wide as its longest value. A selection that does not  
fit ends in an ellipsis and menu\<-ellipsized\_label provides the full  
label, which library(help\_message) shows as tooltip. The list that  
opens from the menu is as wide as its labels.

- FIXED: class variable help window could not be resized The help window  
is -\>transient\_for the editor, which makes it a frame of kind transient  
that cannot be resized.

- MODIFIED: font alias fixed is now an old name for tt `fixed` and `tt`  
were two aliases for the same font. `fixed` is no longer an alias  
of its own: converting it to a font yields the theme font `tt`, and  
`fixed := Font` in font.system\_fonts defines `tt`. As a result,  
@font\_aliases no longer has an entry `fixed`. All code now uses `tt`.

- FIXED: class variable editor: help window failed without the IDE  
The help window uses class tool\_bar, which was only available if  
library(toolbar) was already loaded, e.g., by the IDE.

- ENHANCED: preferences editor: edit the font aliases in the Text  
tab The Text tab of the GUI preferences editor shows a family,  
style and size per font alias, followed by a sample text in the  
font and a tooltip that describes the role of the alias. If “Same  
size for related fonts” is on, changing the size of an alias also  
changes the aliases that only differ by style. Class font\_item has  
a Theme… button to select a theme font. Documented font.scale,  
font.system\_fonts and font.pango\_families for users and added the  
manual page of class theme\_font.

- FIXED: tab labels were not laid out again after fonts\_changed If  
a font changed in place, e.g., after changing font.scale or a font  
alias, the tab labels kept their old size and overlapped.

- ENHANCED: font aliases are theme fonts that can be changed in place  
Font aliases such as `normal` and `bold` are now instances of the  
new class theme\_font, a font whose properties are copied from the  
font it is derived from. Changing that font using -\>derived\_from  
or by changing font.system\_fonts changes the theme font in place,  
so all users follow after `display_manager ->fonts_changed`.

- TEST: key\_binding\_browser: expect macOS key symbols on macOS  
Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- FIXED: thread monitor failed to open if the font descent is fractional  
On Windows, font\<-descent is a float, making the icon size a float  
and between/3 in thread\_browser-\>icon\_styles raise a type error.

- BUILD: avoid clang -Wabsolute-value warning in failing isearch report  
Co-Authored-By: Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- FIXED: profiler: call graph and browser issues reported on Discourse  
Sorted on the time of the children, the browser showed ticks. In the  
call graph, recursive calls are summed over all cycles and shown for  
every node, edges into a cycle no longer show inflated times but the  
number of calls, tooltips show the fail count if ports were recorded  
and the graph is redrawn when its preferences change.

- ENHANCED: thread monitor, theme colour chooser and symbol picker  
follow the theme; icons of list browsers use the icon gap The CPU  
gauges of the thread monitor use the theme colours thread\_cpu\_idle and  
thread\_cpu\_busy and are drawn again if the theme or the font changes.  
All thread status icons have the size of the gauge, so the names  
line up. The swatches of the theme colour chooser follow a change  
of theme. The code ranges of the symbol picker use the theme colours  
symbol\_picker\_user and symbol\_picker\_prolog.

- ENHANCED: markup in list\_browser items and the labels of list\_browser,  
editor and decorated windows A dict\_item whose label is a markup shows  
its text using the fonts, colours and underlining of the markup on  
top of the item’s style; selection and search feedback stay on top.  
Searching and sorting a dict ignore the markup. The labels of  
list\_browser, editor and window\_decorator are displayed by a  
markup\_text, so they accept a markup:

- TEST: terminal rows: use the whole-pixel cell metrics of the terminal  
The terminal truncates the metrics of its font, which are fractional  
on Windows.

- TEST: emacs grep: only run grep if it is installed Co-Authored-By:  
Claude Opus 5.5 [noreply@anthropic.com](mailto:noreply@anthropic.com)

- ENHANCED: key bindings browser: summaries next to the keys, choose  
functions from a list of commands, moved to the Settings menu The  
list of keys shows the summary of the function, which is the tooltip  
of the row. Changing the function of a key shows the commands with  
their summaries, a filter and a menu of classes; selecting one shows  
its documentation. Only commands are offered: built-in methods  
in a group of commands, such as `caret` or `search`, and methods  
defined in Prolog that are bound to a key or refine such a method.  
The browser moved from the Help to the Settings menu of the IDE.

- ENHANCED: Pango markup: shows code in xpce’s fixed-width font  
on a faint background and font\_family use xpce’s font families,  
so uses the same font as fixed-width text elsewhere in xpce.  
The background is the new theme colour ui\_code\_background.

- FIXED: markup in a clipped label read past the end of its text A clipped  
label draws a one-line copy of its text that is not 0-terminated,  
while the markup code assumed it was. This showed as a failing  
isearch in PceEmacs that printed the raw markup and a Pango warning  
about invalid UTF-8.

- ENHANCED: a failing incremental search shows which part of the target  
was found The warning shows the part of the search string that was  
found on the background of the isearch hit, `ui_isearch_background`,  
and the part that cannot be found on the new theme colour  
`ui_isearch_failed_background`.

- FIXED: xpce format: incomplete and unknown %-sequences and `*`  
widths An incomplete or unknown conversion is copied verbatim.  
A `%` at the end of the format was written as `\`, a format ending  
in a flag or width, such as “%-” or “%5”, read past the end of the  
format and wrote a NUL character, and an unknown conversion such as  
“-5z" lost its flags and width. A `*` width, as in "\*d” and “%-\*s”,  
consumed its argument but printed the directive literally.

- ENHANCED: reporter shows errors and warnings in the theme  
colours ui\_error and ui\_warning Co-Authored-By: Claude Opus 5.5  
[noreply@anthropic.com](mailto:noreply@anthropic.com)

- ADDED: class markup, a string holding Pango markup; formatting it  
escapes the arguments, and a label renders it, also for -\>report  
messages send(Window, report, warning,  
markup(“Cannot open **%s** ”, File))

- MODIFIED: keyboard control of the panes and tabs of IDE windows;  
panes agree to be closed using -\>can\_close. Control-Page-Down/Up  
show the next or previous tab, F6, Shift-F6 and Control-X o move  
between the panes of a tab, Control-X 1 closes the other panes of  
the tab and Control-X 0 the current one. These work from any pane,  
including tools. Control-X 1 moves panes that do not agree to be  
closed, such as a terminal running a query or the console showing  
the messages of Prolog, to a new tab. `<-can_close: bool` is now  
`->can_close(Ask:[bool])`.

- FIXED: a window of the IDE that was not open kept its dropped status  
bar in its layout. Laying out the window then sent -\>geometry to  
the freed bar, e.g., when an editor was moved to the tab beside it.  
frame-\>delete keeps the tile of a window if the frame is not created,  
as tab\_frame relies on that.

- FIXED: a key after a prefix that no table binds ran the default  
function. For example, Control-X 1 in Epilog inserted “1”. Such a  
sequence is now reported as undefined.

- ENHANCED: key bindings browser for PceEmacs (Ctrl-H b) and any window  
of the IDE (Help/Key bindings). The browser is a tool pane that  
lists the keys per table, with a filter that works as you type and  
the manual entry of the method a key invokes. Keys can be bound to  
another function or key, unbound, and added to a table by selecting  
its header. Changes apply at once; Save writes them to the Defaults  
file as `key_binding.<table>: [Key := Function, ...]`, one binding  
per line. Functions are completed from the commands of the target,  
which PceEmacs modes declare with `Name = command`; M-x completes  
the same commands.

- FIXED: Preferences editor saved values with a backslash so they did  
not read back Prolog writes the atom \C-x as ‘\C-x’, which xpce reads  
with two backslashes: xpce reads quoted text as is. Such atoms are  
now written as xpce reads them.

- FIXED: goal stack of xpce warnings lost the arguments of Prolog methods  
The arguments of a goal handled by Prolog were written to the current  
output instead of user\_output, where xpce writes the rest of the line.  
In swipl-win they were missing from the warning and appeared on the  
terminal when the program halted.

- CLEANUP: Delete PceEmacs C++ support for defining xpce classes in C++.

- TEST: terminal: the first attribute shot painted on the input background  
out/2 writes to the terminal directly, bypassing the line editor, whose  
input decoration is still on at the prompt. Start each shot with SGR 0.

- FIXED: Epilog windows were one row short of the rows asked for Since  
the terminal leaves room below the last row for the caret, a window  
sized as rows times the font height fits one row less, so the default  
Epilog window had 24 rows rather than 25. Added terminal\_image  
\<-cells\_size, the inverse of how the terminal derives its rows and  
columns from its size, and size Epilog windows with it.

- FIXED: Epilog on Windows: libedit assumed 80 columns until the window  
was resized Discourse 9090/232: editing a wrapped input line in a fresh  
window climbed up the screen, deleting characters from the rows above.

- FIXED: terminal: italic fonts ignored after changing the font size  
If the user changed terminal\_image.font (and bold\_font), the italic  
variants still named the default size and were dropped with a “pitch  
differs” warning. A variant that does not fit is now derived from  
\<-font.

- FIXED: frame \<-open\_file and \<-save\_file: Cancel returned ‘’ SDL 3.2’s  
zenity file dialog reports a cancel as a single empty file name.  
Treat that as a cancel. Reported for File/Edit in swipl-win on  
Debian Trixie.

- ENHANCED: PceEmacs hit list: filter as you type The bookmark pane used  
for grep, git grep and find-references has a filter field. It shows  
only the hits whose line or file name matches the (case insensitive)  
regular expression and highlights what the filter matches using the  
new theme colour `emacs_bookmark_filter`.

- FIXED: terminal: the caret on the last row could be truncated The  
rows of the terminal now leave room below the last row for the part  
of the caret that reaches below its cell, such as the triangle of  
the default xpce caret style.

- ENHANCED: PceEmacs grep and git grep show their hits in a hit list  
The hits appear in the same reusable pane as find-references instead  
of a compilation buffer. The commands run with --color=always, so  
the colour tells where the match is, which is highlighted in the hit  
list and the editor. Output that is not a hit is reported when the  
command is done.

- TEST: check the reference manual card signatures against the classes  
xpce:refman\_signatures compares the signature line of each card  
in man/refmanual/md with the live behaviour. Updated the cards it  
found stale, removed cards for figure-\>shadow, figure\<-shadow and  
figure-\>convert\_old\_slot, and fixed the argument declarations of  
frame-\>y (named x) and pen-\>initialise.

- ENHANCED: regex\<-\>newline\_sensitive; PceEmacs search/replace do  
not match newlines with . or [^…] Class regex compiles with  
REG\_NLANCH only, so `.` and `[^...]` match a newline and `.*` in  
PceEmacs query-replace-regex ran to the end of the buffer. The new  
option adds REG\_NLSTOP. It defaults to @off, as library patterns  
rely on spanning lines. PceEmacs query-replace-regex and the find  
dialog switch it on for the pattern typed by the user.

- ENHANCED: manual browsers adapt the name column to the window width  
The name column of the class, module, group and search browsers is  
as wide as the widest name, but at most half the window, and follows  
the window when it is resized. Longer names are truncated with an  
ellipsis and show the full name as tooltip.

- ADDED: @pce has the feature svg if -\>svg can write SVG images Cairo  
may be built without the SVG surface, as by MacPorts. Test using  
send(@pce, has\_feature, svg). The demo galleries only offer to save  
as SVG if it is supported.

- FIXED: graphical-\>graphics\_state used a freed stroke\_style A  
stroke\_style created for the texture argument is not referenced, so  
it was freed when the send returned while the drawing context still  
used it. -\>restore\_graphics\_state then crashed on macOS.

- ADDED: graphics demos and the XPCE userguide chapter “Paths, paint  
and text” Demos Path gallery, Paint gallery, Text gallery and Canvas  
show paths, gradients, line styles, markup text, clipping, blending  
and the canvas.

- ADDED: class canvas for Cairo-style vector drawing; graphical-\>svg  
and window-\>svg A canvas is drawn on using paths, stroke, fill,  
clip, transformations, text and images, recorded as vectors.  
graphical-\>draw\_path draws a path object from a ‘\_redraw\_area’ method.  
graphical-\>svg and window-\>svg write the graphical or window contents  
as an SVG image.

- ENHANCED: clipping regions nest; added figure-\>clip\_path and  
figure-\>blend -\>clip intersects with the enclosing region and -\>unclip  
restores it. figure-\>clip\_path clips the contents of a figure to  
a path and figure-\>blend composites a figure onto what is below it  
using a blend mode such as multiply, screen or difference.

- FIXED: colour(‘#RRGGBB’) created through new/2 or as a term argument  
was not parsed as hexadecimal Only conversion of a name such as  
‘#RRGGBB’ parsed the hexadecimal notation; creating the colour  
explicitly, e.g. send(Box, fill, colour(‘#ff8000’)), produced an  
unknown named colour. The parsing is now shared by both.

- FIXED: a colour with an unknown name was black instead of the grey50  
the warning announces The fallback stored the RGBA value untagged.

- FIXED: a rounded box with an elevation lifted the clip of its window,  
painting outside the area being redrawn r\_3d\_box() reset the clip after  
drawing each half of the box rather than restoring the enclosing one.

- ADDED: class markup\_text displays text formatted using Pango markup,  
with Pango wrapping, alignment, justification, ellipsizing and line  
spacing; graphical-\>draw\_markup draws markup from a ‘\_redraw\_area’  
method Markup can mix fonts, sizes, styles and colours, e.g.  
“Some **bold** and red text”.  
Unlike class text, a markup\_text is read-only. It uses a layout  
of its own from the same Pango context as the fonts, so its metrics  
match those of plain text.

- ADDED: line styles, image fills and gradient extend and units Class  
stroke\_style provides line caps, joins, miter limit, arbitrary dash  
patterns and gradient lines, usable as graphical -\>texture. Graphicals  
can be filled with a repeated image. gradient\<-extend selects what  
is painted beyond the stops and gradient\<-units: bounding\_box makes  
a gradient relative to the shape it fills.

- FIXED: the arrows of a path were never drawn The arrow heads of a  
path were positioned but not marked as displayed, so RedrawArea()  
skipped them. Line, arc and bezier\_curve already did this.

- ADDED: class path supports Bezier curves, elliptical arcs, sub-paths, a  
fill rule, rounded corners and SVG path data Curves, arcs and sub-paths  
use the new point subclasses curve\_point, arc\_point and move\_point.  
path-\>svg\_data and path\<-svg\_data set and get the points as SVG  
path data.

- FIXED: graphical-\>draw\_poly filled after stroking, painting the  
fill over the inner half of the outline Also removes a transparent  
cairo\_paint() from r\_fill\_polygon() that had no effect.

- FIXED: r\_pixel() and r\_get\_pixel() accepted x == width and y == height  
The callers in image.c check bounds with inImage(), so this could not be  
reached from Prolog; there is therefore no regression test. The bounds  
check and address computation are now shared in target\_pixel().

- FIXED: -\>draw\_fill drew nothing unless the fill was @default, and  
r\_fill() rejected gradients graphical-\>draw\_fill now fills with any  
colour or gradient, and a figure with a gradient background draws it.

- FIXED: gradient colour stops were scaled by 1/256, so no stop reached  
its full colour A red stop rendered as ffff0101 instead of ffff0000.  
Adds tests/test\_cairo\_render.pl, which checks drawn pixels via  
image-\>draw\_in.

- FIXED: graphical -\>graphics\_state used a freed colour A colour converted  
from a name is not referenced, so it was freed when the send returned  
while the drawing context still used it. Depending on the reuse  
of the memory, lines were drawn in a random colour or not at all.  
This made the graphics\_state test fail on Windows.

- FIXED: a process was reported to exit with status 0 at the end of its  
output End of file on the output of a process was taken as -\>exited 0,  
losing the real exit status or signal and leaving the child unreaped.  
On Unix the termination is now only reported when the child is reaped,  
after handling the output it wrote. process-\>wait also waits for  
the process to terminate, such that \<-status and \<-code are known.  
On Windows the end of the output still means normal termination.

- FIXED: crashes and hangs after a process (e.g., PceEmacs grep)  
terminated The SIGCHLD handler reaped the children and sent -\>exited  
or -\>killed, running the terminate message (Prolog, frame labels, the  
window system) inside the signal handler, interrupting whatever the  
main thread was doing. This crashed in GTK (libdecor on Wayland),  
corrupted the Prolog VM or crashed on halt. The handler now only  
writes to a pipe that is watched by the fd watcher thread, so the  
children are reaped from the main thread’s event loop.

- FIXED: X11 with SDL 3.2: clicking a menu\_bar did not keep the popup  
open With SDL 3.2 under a window manager such as xfwm4, the up-event of  
the click that opens a popup is reported for the popup window as that  
takes the focus. It is redirected to the window of the down-event,  
but the translation used SDL\_GetWindowPosition(), which is relative to  
the parent for a popup. The menu\_bar saw the up far from the down, so  
it did not keep the popup open and the popup closed without a selection.  
Compute screen positions through the parents of popup windows.

- FIXED: possible crash on pressing Alt when a freed popup frame is  
still listed by the display acceleratorCuesFrame() walks the popup  
frames of the display to update their accelerator underlines. A freed  
frame keeps its \<-kind (names are not reset) while its \<-members is  
@nil, which crashed. Skip freed frames there and in wsid\_to\_frame().  
Reported on Debian/Xfce with 10.1.18.

- TEST: theme:colour\_trace failed on systems without a GNOME or KDE  
desktop There, sys\_window\_background uses xpce’s default, so the  
trace source is `default` rather than `desktop`.

- FIXED: various issues found while updating the userguide - Interface:  
new(X, 3.5) crashed on an assertion. A float is not an  
object and now raises a type error, as for integers. - Interface:  
prolog(Float) did not pass the float. - Interface: calling Prolog  
from xpce while a Prolog exception is pending,  
e.g., reporting the type error after an unknown @Ref, printed  
“did not clear exception” and lost the exception. The pending  
exception is now saved and restored around the call. - Arithmetic  
objects truncated float arguments: 3+2.5 evaluated to 5. - Class  
compiler: unquoted range types such as Vol:[0..130] did not  
expand. - A frame larger than its display, e.g., from `view ->size` in  
characters, could crash the graphics driver. Frames are now limited  
to the size of their display. - program\_object \<-dflags is an  
alien slot. It held raw flag bits in  
an `int` slot, which showed as a garbage float. - bezier\_curve term  
names were those of box. - \<-man\_summary warned about -\>has\_help if  
the manual is not loaded. - toc\_tree -\>selection selected a graphical  
used as node identifier  
rather than the node. - Visual hierarchy: show anonymous object  
arguments as rather  
than their long and varying reference.

- DOC: XPCE userguide: recreate the screenshots Added  
screenshots/screenshots.pl to create the screenshots in figs from the  
code in the guide, using `make screenshots`. screenshots/shoot.sh  
runs it against a private headless mutter display at scale 2, or  
Xvfb if mutter is not available. A logical pixel is printed as 0.6  
point, such that the text has about the size of the running text.  
Recreated all screenshots of the guide and removed the explicit widths  
that scaled them.

- DOC: XPCE userguide: update the content for version 9 Revised all  
chapters for the SDL/Cairo/Pango based version. Removed material  
on features and systems that no longer exist (X11 resources,  
PostScript, ProWindows, other Prolog systems, old Windows versions,  
removed classes and methods), described themes, the flat dialog look,  
keyboard operation, OS drag and drop, image formats and the IDE tools  
as panes, and fixed code examples that no longer work. The class  
summary has entries for new classes such as bool\_item, theme\_colour,  
gradient and shadow.

- DOC: XPCE userguide: automatic version, title page and build fixes -  
The Makefile creates version.tex with \productversion from PCE\_VERSION  
in CMakeLists.txt and \productdate and \productyear from the date.

- FIXED: graphical -\>restore\_graphics\_state raised “Unknown texture”  
g\_save() no longer recorded the pen, texture and colours because  
graphstate.c was included in sdldraw.c before the drawing context  
was declared. The initial dash of a context is now `none` rather than  
NULL, so it can be restored. Also fixed g\_level(), which tested the  
inverse condition.

## Package yaml

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

## Package zlib

- TEST: removed search path setup for the library and foreign aliases  
src/swipl in the build tree already finds the libraries and foreign  
modules of all packages.

---

<div class="post-metadata">

**Author:** ![alanbur](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/alanbur/32/7166_2.png) [@alanbur](https://swi-prolog.discourse.group/u/alanbur)\
**Post date:** [October 21, 2026, 9:50pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-10-1-19/9874/2 "2026-10-21T21:50:48Z")

</div>

No longer builds on Debian with the OS-provided SDL packages, but builds OK with locally built versions,

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [October 21, 2026, 10:07pm UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-10-1-19/9874/3 "2026-10-21T22:07:01Z")

</div>

Prior to the version release, it didn’t build for me on Debian, but now it does with gcc (with a few, probably incorrect, warnings about possibly initialized variables). I had to do a clean build.

However, I get some errors from the XPCE tests (I’ve sent the output separately).

---

<div class="post-metadata">

**Author:** ![mgondan1](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/mgondan1/32/803_2.png) [@mgondan1](https://swi-prolog.discourse.group/u/mgondan1)\
**Post date:** [October 22, 2026, 5:14am UTC](https://swi-prolog.discourse.group/t/ann-swi-prolog-10-1-19/9874/4 "2026-10-22T05:14:26Z")

</div>

Msys: builds with gcc, but clang fails:

```prolog
Building C object packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/ker/gc.c.obj
2026-10-22T04:55:58.0383072Z FAILED: [code=1] packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/ker/gc.c.obj 
2026-10-22T04:55:58.0575611Z C:\M\msys64\clangarm64\bin\clang.exe -Dplugin_pl2xpce_EXPORTS -IC:/_/B/src/build-CLANGARM64/packages/xpce -IC:/_/B/src/swipl-10.1.19/packages/xpce/src -IC:/_/B/src/swipl-10.1.19/src/win32/console -IC:/_/B/src/swipl-10.1.19/src/os/windows -IC:/_/B/src/swipl-10.1.19/src/os -IC:/_/B/src/swipl-10.1.19/src -isystem C:/M/msys64/clangarm64/include/cairo -isystem C:/M/msys64/clangarm64/include/freetype2 -isystem C:/M/msys64/clangarm64/include/libpng16 -isystem C:/M/msys64/clangarm64/include/harfbuzz -isystem C:/M/msys64/clangarm64/include/glib-2.0 -isystem C:/M/msys64/clangarm64/lib/glib-2.0/include -isystem C:/M/msys64/clangarm64/include/pixman-1 -isystem C:/M/msys64/clangarm64/include/pango-1.0 -isystem C:/M/msys64/clangarm64/include/fribidi -march=armv8.1-a -O2 -pipe -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector-strong -Wp,-D __USE_MINGW_ANSI_STDIO=1 -O2 -std=gnu11 -fvisibility=hidden -D__ WINDOWS __-D_WIN32_WINNT=0x0600 -DWIN64 -Wall -DHAVE_CONFIG_H -D__ SWI_PROLOG__ -MD -MT packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/ker/gc.c.obj -MF packages\xpce\CMakeFiles\plugin_pl2xpce.dir\src\ker\gc.c.obj.d -o packages/xpce/CMakeFiles/plugin_pl2xpce.dir/src/ker/gc.c.obj -c C:/_/B/src/swipl-10.1.19/packages/xpce/src/ker/gc.c
2026-10-22T04:55:58.0738459Z C:/_/B/src/swipl-10.1.19/packages/xpce/src/ker/gc.c:224:1: error: hidden visibility cannot be applied to 'dllexport' declaration
2026-10-22T04:55:58.0758528Z 224 | _rewindAnswerStack(AnswerMark *mark, Any obj)
2026-10-22T04:55:58.0759338Z | ^
2026-10-22T04:55:58.0759850Z 1 error generated.
2026-10-22T04:55:58.0760692Z [1803/2300] 

```
