Did you know ... Search Documentation:
Title for pldoc(default)
Branch: development (switch to stable),
version to version

SWI-Prolog Changelog from version 10.1.17 to 10.1.18

[Oct 12 2026]

  • FIXED: Windows: format/2 with code points above 0xffff in the format On Windows such a code point is a UTF-16 surrogate pair. format/2 wrote the halves of a pair in the format text one by one, raising an I/O error, and truncated a ~`c column fill character to 16 bits.
  • FIXED: Windows: writing variable names and numbers with code points above 0xffff On Windows such a code point is a UTF-16 surrogate pair. The check whether an atom is a valid variable name looked at the halves, so print('$VAR'('X\U0001D431')) and variable_names(['X\U0001D431'=V]) wrote the name quoted. Whether a number needs a space before it used the first half of a float_format/integer_format starting with such a character.
  • FIXED: Windows: split_string/4, string_code/3 and get_string_code/3 on code points above 0xffff On Windows, where wchar_t is 16 bits, such a code point is a UTF-16 surrogate pair. These predicates indexed the text by wchar_t units while their indexes and PL_unify_text_range() count code points, so split_string("a\t\U0001F4D6\tb", "\t", "", L) put the separator in the wrong substring. text_chr() could not find a separator or padding character above 0xffff.
  • FIXED: ==/2 and \==/2 on a fresh variable did not mark the variable as initialised. This could cause \+ inside a branch of ;/2 to leave the variable uninitialised on the success path, while the code after the disjunction assumes it is initialised. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • ADDED: dark theme values for the xpce ui_danger colours Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • TEST: theme_hook:thread requires threads Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • FIXED: #1545 incremental WFS re-evaluation leaving tnot/1 undefined Answers of the previous evaluation that are not re-derived remain in the trie until re-evaluation of the component completes. These made simplify_component() believe the table had answers, so a tnot/1 delay on a table that re-evaluated to false was never resolved and the depending answer remained undefined.

[Oct 11 2026]

  • ADDED: dark theme: values for ui_tile_gap, ui_tile_border and ui_tile_separator Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • FIXED: profiler/2 did not sample a thread that never ran profile/1,2 The sample period was only set by profile/1,2. Starting the profiler using profiler/2, as the IDE thread monitor does, used a period of 0, which disables the timer. The call graph was collected, but no time.
  • ADDED: prolog:theme_base/2 to base a theme on another theme A theme uses the console colours (prolog:console_color/3) and online help styles (pldoc_style:theme/4) of its base theme that it does not define itself. This allows for a theme that is a small variation of, e.g., the dark theme. Setting the flag theme no longer loads library(theme/Theme) if prolog:theme(Theme) is true, so a theme editor can define a theme in memory while editing it.
  • FIXED: fatal error raising an occurs_check error with a full global stack failed_unify_with_occurs_check() calls PL_error() with GC and stack shifts blocked. If the global stack had no room for the error term, f_ensureStackSpace() did not use the spare stack and PL_error() died with "Cannot report error: no memory". As growLocalSpace() and makeMoreStackSpace(), f_ensureStackSpace() now uses the spare stacks while processing an exception.
  • FIXED: syntax error context for EOF in a leading block comment If the input ends in a block comment before anything was read, the error context showed the first byte of the read buffer, which was not written by this read. Now the context text is empty.
  • FIXED: str_number(): 0' at the end of the text read past the end For the text "0'", str_number() decoded the terminator as character and returned an end pointer beyond the text. atom_number/2 then inspected the byte after the text. Now raise a syntax error.
  • FIXED: read_term/2,3: cycles(Bool) option could reset dotlists(true) The options cycles and dotlists were declared OPT_BOOL, which writes an int, while the targets are bool fields. Writing cycles cleared the adjacent dotlists field. Use OPT_STDBOOL.
  • FIXED: double unlock of L_FILE when using an unbound standard alias Accessing a standard stream alias that is not bound, e.g. protocol if protocol/1 is not active, unlocked L_FILE twice, causing an assertion failure rather than an existence error.
  • ENHANCED: select the theme using the Prolog flag theme The flag theme is now always defined and shared between threads. Setting it loads library(theme/Theme) through theme_hook/1, e.g., :- set_prolog_flag(theme, dark). in the init file. The hooks prolog:console_color/3 and pldoc_style:theme/4 take the theme as first argument, which removes active/0 from the theme files.

[Oct 10 2026]

  • ADDED: create_prolog_flag/3 option shared(true) and hook theme_hook/1 A shared flag has one value for all threads: set_prolog_flag/2 never makes a thread-local copy. -Dtheme=Name creates the flag theme as a shared flag. Changing its value first calls all solutions of the multifile hook theme_hook/1 in the calling thread. If the hook raises an exception the flag keeps its old value and set_prolog_flag/2 raises the exception.

[Oct 11 2026]

  • FIXED: set_prolog_flag/2 with flag user_flags = warning With user_flags set to warning, setting an unknown flag crashed because the warning lacked the arity of its message term. Also, there was no message text, and the flag was not created as documented.

[Oct 10 2026]

  • CLEANUP: dark theme: remove setting the colours of the old Windows console win_window_color/2 belonged to the old Windows console and no longer exists, so this code was never loaded.

[Oct 11 2026]

  • FIXED: #1543 writeq('[]'(a)) wrote [a] and writeq('()'(a)) wrote (a) Only Unicode bracket pairs are read as '<open><close>'(Arg). Do not write the ASCII pairs [] and () this way.
  • FIXED: #1542 writing Latin-1 atoms used signed characters On platforms where char is signed, characters 128-255 of ISO Latin-1 atoms were passed as negative values to PutOpenToken(), omitting the space after a prefix operator such as in "dynamic é", and to code_requires_quoted(), ignoring quote_non_ascii(true). The first character of an identifier atom was never subject to quote_non_ascii(true).
  • FIXED: #1541 syntax errors mis-encoded non-ASCII characters The arguments of end_of_file_in_quoted/1 and undefined_char_escape/1 were created from UTF-8 resp. a truncated code point using PL_CHARS (ISO Latin-1). Both now use UTF-8.
  • FIXED: #1540 clause/2 could return a clause that is not equivalent After moving X = Term into the head, the decompiler restores the unification only if X is used later in the body. Detection of such use only considered a few instructions (B_VAR*, B_ARGVAR, H_VAR and var-var B_UNIFY_*), missing e.g. ==/2, unification against a constant, type tests and arithmetic. The clause is now flagged CL_HEAD_TERMS whenever a unification is moved and mark_bvar_access() uses the VM operand types to find all read access to argument variables.
  • FIXED: #1539 optimise_unify moved X = Term past a variable goal A variable at a goal position is a call/1, but did not clear head_unify, so a subsequent X = Term against a head argument was moved into the head, before the call.
  • FIXED: #1538 variant_hash/2 ignored the tail of long atoms and strings hash_compile() did not advance the data pointer when splitting input over multiple hash blocks, so data that crossed a block boundary was replaced by its own prefix. Note that this changes the hash values for such terms.
  • FIXED: #1537 JIT indexing ignored an argument right after H_VOID_N When skipArgs() ended exactly at the end of a run of void arguments it returned the H_VOID_N instruction rather than the next one, so argKey() considered the target argument a void. In multi-argument assessments the remaining arguments were mis-read as well, and the result was cached, so e.g. p(_,_,a) was never indexed on argument 3.
  • FIXED: #1544 Illegal locale string warning for fi_FI.UTF-8 The default locale was created using newlocale() with only LC_NUMERIC, leaving LC_CTYPE at "C". As a result, mbsrtowcs() failed to decode non-ASCII separators such as U+202F (NARROW NO-BREAK SPACE) used as thousands separator by fi_FI.UTF-8.

[Oct 9 2026]

  • MODIFIED: dark theme: scroll bar trough is the dialog background Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • FIXED: Stop acceptiong Ctrl-L as a trace command. This was skipped due to isBlank().

[Oct 8 2026]

  • MODIFIED: comment_hook/3 is now prolog:comment_hook/4 The additional argument is the list Name=Var of the variables of the term if read_clause/3 is called with variable_names(Bindings), so the hook can relate a comment to the argument names of the term. The cross-referencer stores object comments and signatures created by the PlDoc hook prolog:doc_compile_comment/6 (xref_object_comment/4, xref_object_signature/3) and only uses `<module>` sections as module comment.
  • MODIFIED: dark theme: the margin background follows the window background On a dark desktop this makes the margin of the editor use the desktop window background, as in the light theme, rather than a fixed grey20.

[Oct 7 2026]

  • ENHANCED: dark theme colours for the cross-referencer and thread monitor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

[Oct 6 2026]

  • FIXED: #1535 classify resource_error(_) exceptions as EXCEPT_RESOURCE classify_exception_p() tested for error(resource_error, _), which is never raised. As a result, resource errors such as stack overflows were ranked as ordinary errors and could be replaced by a subsequent ordinary error.
  • FIXED: assertion failure for a static predicate with two clauses whose first argument is a rational number arg1Key() did not handle H_MPQ, causing an assertion failure when checking for the list supervisor. Reported by Shivaji Gadde.

[Oct 5 2026]

  • FIXED: unsetenv under Windows unsetenv was not redirected to GetEnvironmentVariable to test if the variable actually existed. Also, setting the variable to "" does not delete it on Windows. Added _xos_unsetenv(), which calls SetEnvironmentVariable() with a NULL value, and use it as unsetenv().

[Oct 4 2026]

  • PORT: Cross-compile for Windows on ARM64 - New toolchain file cmake/cross/linux_win_arm64.cmake for llvm-mingw (aarch64-w64-mingw32-clang) with dependencies from MSYS2 CLANGARM64 in $MINGW_ROOT and Wine as emulator. - Use SWIPL_ARCH arm64-win64 for ARM64 Windows. - Use the toolchain's objdump to find indirect DLL dependencies rather than x86_64-w64-mingw32-objdump. - With clang, ship libc++.dll and libunwind.dll instead of libstdc++. - C stack backtrace: add ARM64 support.
  • ENHANCED: MinGW cross builds: install_dll() also copies indirect DLL dependencies DLLs found in MINGW_ROOT may depend on further DLLs from there. For example, MSYS2's libarchive needs liblzma, libzstd, liblz4 and libb2. These must be next to the plugin, both in the build tree and in the installation.
  • TEST: Only run compare_cyclic:flag_thread if threads are supported Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • FIXED: Missing <errno.h> include in pl-cstack.c Broke the single threaded build.

Package clib

[Oct 5 2026]

  • FIXED: alarm/4 remove(true): using the Id after the alarm fired accessed freed memory Calling remove_alarm/1 (or install/uninstall) on the Id of a remove(true) alarm that had fired used freed memory, often silently acting on another alarm such as the one of call_with_time_limit/2, leading to crashes, hangs or 100% CPU. Alarm Ids are now blobs and the event memory is reclaimed by atom-GC. remove_alarm/1 on a removed alarm succeeds silently; install and uninstall raise an existence error.

Package cpp

[Oct 11 2026]

  • ADDED: synchronized C++ API with changes to SWI-Prolog.h

Package libedit

[Oct 9 2026]

  • FIXED: Windows: slow paste in swipl-win due to the electric caret The electric caret shows the matching open bracket until input arrives or its time out ends. Waiting for input used WaitForSingleObject() and PeekConsoleInput(), which only work for a console. The input of swipl-win (Epilog) is a pipe, so every closing bracket of a paste waited the full time out. For a pipe we now poll PeekNamedPipe().

Package pldoc

[Oct 8 2026]

  • ADDED: PlDoc hooks to document and show non-predicate objects The hook prolog:doc_compile_comment/6 is tried before the default processing of a structured comment. It gets the term that follows the comment and its variable names (passed by prolog:comment_hook/4) and may compile the comment into object(Object, Summary, Comment) and signature(Object, Signature) terms. The hook prolog:doc_object//3 emits such objects on file pages, which used to skip them, also when the file is documented using the cross-referencer. Used for the members of xpce classes. Added doc_signature/2, process_comments/5, parse_comment/5 and the xpce object kind class.

Package xpce

[Oct 12 2026]

  • TEST: chain_list: library(thread) only exists with threads Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • ENHANCED: error browser filters as you type and explains its Kind menu The search field is a filter_item, so the list updates on every key; the apply and help buttons are removed. The Kind menu, which changes how the selected error is reported, e.g., to raise a warning as an error while debugging, comes after the search field, has a tooltip and says on the status bar what it changed. The tab stops of the list are computed from the widest error id.
  • FIXED: error browser passed the input focus to the selected error It kept the selected error in a slot current, which hid `tabbed_window <-current`, the window of its tab. tabbed_window ->input_focus hands the focus to that window. The slot is now current_error. Also removed the unused man_class_hierarchy ->focus, which hid window ->focus.
  • FIXED: visual hierarchy, card viewer and inspector showed a blank report bar These tools had a report_dialog of their own from the time they were frames. As panes of the IDE they report on the status bar of the window they are in, so their own bar stayed blank and a report added a second bar.
  • FIXED: manual summary browsers no longer suggest their entries can be dragged A mouse-down showed the drag cursor, but nothing in the manual accepts a dropped entry since the card editor of the .doc era was removed.
  • FIXED: manual: class variables and methods without their own entry use the instance variable A class variable that is not documented itself had no manual entry, although the instance variable with the same name, which it provides the default for, is documented. It now falls back to this variable, as methods already did. The card says that the description is that of the variable.
  • ENHANCED: manual summary lists show a book for documented entries ->has_help still looked for descriptions on the manual cards of the .doc era, which are no longer loaded, so the (+) tag after a documented summary no longer appeared. It now uses the index of the markdown manual through man_documented/1 from library(pce_html_manual). The tag is replaced by a column with an open book just before the summary.
  • ENHANCED: class browser always shows the class itself at the top The class used to be hidden if the filter does not classify it, e.g., bool_item is not basic, or if the search does not match it. The self item of the Display menu is removed and Display gets an all item that works as the one of the Filter menu.
  • FIXED: crash freeing a frame, display, text_buffer, prolog_term or class whose ->initialise failed If ->initialise fails, e.g., because an argument has the wrong type, the object is freed while its slots are not filled. The ->unlink of these classes assumed they were. Found by creating every class with arguments of the wrong type.
  • ADDED: button->danger for buttons that start a destructive action A danger button has a border and label in button.danger_colour (theme colour ui_danger) or, if it is also the default button, is filled with it, using button.danger_foreground for the label. pane_frame ->confirm_danger asks for such an action with a danger button labelled with the action and cancel as default button. It is used to confirm closing several tabs or a tab that ends the application.
  • FIXED: the main Epilog console was not called main epilog_name/3 only recognised @on, while boot/toplevel.pl asks for the main console using main(true).
  • ENHANCED: confirm closing a tab if that ends Prolog When Epilog runs as the main program, Prolog halts as soon as no window keeps the application alive. Closing the tab holding the last terminal therefore ended Prolog, even if other tabs held, e.g., an editor, and the tab label may name another pane than the console it holds. Closing such a tab now asks for confirmation.
  • BUILD: rebuild the xpce INDEX.pl and CLASSINDEX.pl when a library changes The targets only depended on other targets, which orders the build but does not make them out of date, so a new or changed export in an xpce library was not picked up by the autoloader until the index was removed by hand. They now depend on the files MKINDEX.pl scans.
  • ENHANCED: chain_list/2 is thread-safe; ADDED: member_chain/2 chain_list/2 takes a snapshot of the chain in a single foreign call. member_chain/2 enumerates a snapshot on backtracking, skipping elements freed in the meantime. The host interface has pceSnapshotChain(), pceSnapshotNext() and pceFreeSnapshot() for this. The libraries use member_chain/2 instead of chain_list/2 and member/2.
  • ENHANCED: cursor demo shows SDL, X11 and image cursors A marked menu selects the standard (SDL) cursors, the X11 compatibility cursors or an image cursor made from @pce_image. The browser uses the selected cursor, which follows the arrow keys, and shows the cursor <-summary as a tooltip.
  • ADDED: cursor <-kind and <-summary `cursor <-kind` tells whether a cursor is a standard (SDL) cursor, an x11 cursor kept for compatibility or an image cursor. `cursor <-summary` describes the standard cursors. @cursor_names lists the standard names first. cursor_item uses <-kind, and the manual no longer refers to the removed display<-cursors.
  • FIXED: list_browser ->cursor was only shown while holding a button The text image that covers the list kept its own (arrow) cursor, which hid the cursor of the list_browser except while it had the focus. ->cursor now also sets the cursor of the text image; browser ->cursor uses it.
  • FIXED: clicking a list_browser in a dialog did not give it the keyboard focus The focus stayed on another item, so the arrow keys did not move the selection of the list_browser. It now takes the focus on a button press, as other dialog items do.
  • ADDED: list_browser ->selection_changed hook The method is called once after an operation that changed the selection, whether by the mouse, the keyboard (e.g., the arrow keys) or a method such as ->selection or ->change_selection. It is sent to the browser if the list_browser is part of one, so subclasses of either class can redefine it to act on any change of the selection.
  • FIXED: gap in the selection highlight between a text run and a tab When a highlighted text run was followed by a run with the same fill, such as the tab after a selected browser item, the fill stopped at the Pango advance of the text, which may be less than the stored start of the next run, leaving a thin unfilled bar.
  • FIXED: class_variable_editor->show_path was defined by two clauses XPCE methods are a single clause; loading reported the second as a redefinition. Merge them using if-then-else.
  • FIXED: tab_frame: window leaving a tab kept the destroyed tab as tile manager Taking the last window out of a tab destroys the tab, but the root tile of that window still named the tab as <-manager, which checkpce/0 reported and which made window <-tile_manager answer a freed object.
  • FIXED: theme checking and the cross-referencer without threads check_theme/1 and load_theme_libraries/0 tried to load the profiler and thread monitor, which are only installed if Prolog has threads. The cross-referencer's ->update always created a thread; it now runs in the foreground without threads. Tests that need threads are conditional.
  • TEST: profiler pane tests use a stored profile The tests profiled real code, so whether a callee survived pruning of the call graph depended on where the samples landed. This made the_graph_walks_past_methods fail occasionally. The tests are about the windows, so they now show a small stored profile.

[Oct 11 2026]

  • FIXED: library(pce_theme_samples): keep the clauses of build/2 together Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • BUILD: bump the name database version for NAME_slice Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • ADDED: theme colours ui_tile_gap, ui_tile_border and ui_tile_separator The class variables gap_colour and separator_colour of class tile default to new theme colours, and the new `tile <-border_colour` gives the border around the windows of a frame its own colour, which used to be the gap colour. The defaults are ui_dialog_background and ui_window_foreground, so a theme can set the gaps, the border and the separator lines apart from the dialog and window colours.
  • MODIFIED: editor and list_browser incremental search styles The class variables isearch_style of editor and list_browser default to style(background := ui_isearch_background), as for terminal_image. The editor's isearch_style and isearch_other_style are of type style*, where @nil for isearch_style shows the hit as the selection, as for a terminal_image. The global @_isearch_style is removed. A Defaults file that refers to it must use style(background := ui_isearch_background) instead.
  • TEST: keep the xpce tests out of the user's configuration The tests emacs_split, prolog_mode, mixed_panes and tool_panes wrote the PceEmacs bookmarks of the user running them. They now use a temporary configuration, as the theme and class variable editor tests did. The new module tests/xpce_test_sandbox.pl provides this and removes the temporary directories after xpce has saved its state on exit.
  • ADDED: theme editor, library(pce_theme_editor) Settings/Theme/Edit theme… creates a theme as a variation of another theme or edits a theme of the user. It edits the theme colours, the console colours and the online help styles. The theme is applied while editing, so each change is visible immediately. The editor shows how a colour gets its value and samples of the user interface that use it. Themes are saved to <user_app_config>/lib/theme/<Name>.pl by the new library(pce_theme_file), which updates an existing file in place.
  • ENHANCED: colour editor: colour wheel, live changes and a palette The colour editor shows a colour wheel for hue and saturation. If it has a message, every change calls it, so the colour can be seen in place. OK keeps the colour; Cancel restores the initial colour or calls the new end message with cancel. The Apply button is gone. The editor can show a palette of colours, passing the index of a selected colour as second argument of the message. Clicking a named colour close to the current colour uses it.
  • ADDED: chain<-slice and vector<-slice <-slice(Start, Length) returns a new chain or vector with Length elements from Start, where Start is a 1-based chain index or an index of the vector. Length defaults to the remainder. The part of the range outside the receiver is left out. The result is of the class of the receiver; a vector slice is indexed from 1.
  • FIXED: manual search tool: word list out of step after a rejected key The search tool passed the keys typed in its search field to the word list. After a character for which no word exists, which the list rejects, a backspace removed a character from both, so the list searched for a different word than the one in the field. The list now searches for the last word of the field after every change.
  • FIXED: a click in a pane repeated its last warning on the status bar Every click sets the keyboard focus, which made the window clear the status bar and put back what the pane said last, repeating an old warning. The window now only does so if the current pane changed.
  • FIXED: thread monitor: profiling wall time used CPU time The test for wall time support checked for '$profile'/2, which became '$profile'/4, so wall time profiling fell back to CPU time.
  • FIXED: profiler: call graph raised a type error for xpce methods Walking the call graph looks up the data of each callee by comparing it with the predicates of the profile. For a callee that is an xpce method and a predicate in module user, this called pi_head/2 with the method as head, raising "Type error: callable expected".
  • FIXED: terminal_image painted outside its area if not at the top Clearing the part of the terminal below the text computed the height from the terminal height and a window coordinate. If the terminal was not at the top of its window, this cleared upwards, over the text and other graphicals. The terminal now also clips its drawing to its area and restores the background colour.
  • ENHANCED: HTML renderer computes fonts from their properties Class vfont used to map to a few predefined fonts, so fixed-width text was always the 14pt fixed font, larger than the text around it and never bold, italic or of another size. The font is now computed from the family, slant, weight and size, relative to the size of the normal font. font_map/7 can still map a virtual font.
  • FIXED: HTML renderer lost the blank after an inline element If a paragraph started with an inline element such as <code> or a link, the blank after it was dropped, e.g., `<p><code>a</code> = b</p>` was rendered as "a= b".
  • ENHANCED: xpce themes use the Prolog flag theme apply_theme/1 sets the flag theme and a theme_hook/1 clause applies the colours, so the console and xpce share the theme. A theme selected before xpce is loaded, e.g., using -Dtheme=dark, is kept as the user's selection.

[Oct 10 2026]

  • FIXED: Epilog: a click ending a terminal search scrolled back to the end A left click during an incremental search (Shift-Ctrl-F) ended it as ^G does, giving back the view the search started from. It now ends it as ESC does, so the user can select and copy from the page the search found.
  • ENHANCED: dialog gallery: keyboard notes, labelled list browser, cancel The gallery documents how it is operated from the keyboard, has a `cancel' button run by Escape, a labelled list browser and a float_item that steps by 0.1.
  • FIXED: help balloon freed when its window closed; hide it on a key Closing the window under a help balloon, e.g. from the keyboard, freed the balloon, after which every mouse event raised "pce(object) <pce>(freed) does not exist". As other tooltips, a balloon now also hides when a key is pressed.
  • ADDED: keyboard control of sliders, combo boxes, number items and tabs Sliders, cycle menus (combo boxes), int_item and float_item and the tabs of a tab_stack can be operated from the keyboard, as on Windows, Gnome and MacOS.
  • FIXED: real numbers lost precision in xpce Text such as 0.123 was converted inexactly, xpce printed a non-integral number as its integer part (0.6 as 0) and passed 0.6 to Prolog as 0.5999999999999999.
  • FIXED: password_item did not show its selection and could copy the password The password is edited in a hidden shadow item, so Control-A (select all) or Shift with a cursor key selected text that was never shown. The bullets now show the selection of the shadow. Copy and cut, which put the password on the clipboard in clear text, are refused, as by native password fields.
  • ADDED: keyboard operation of dialogs, menus and popups Dialogs, menu bars and popups can be fully operated from the keyboard, following the conventions of Windows, Gnome and MacOS: Alt-<letter> accelerators that are underlined while Alt is held, F10 for the menu bar, the cursor keys, Return, Escape and Space in menus, submenus and on buttons.
  • FIXED: Epilog: clicking and selection editing in multi-line input Clicking to position the caret only worked on the logical line of the caret, and deleting or typing over a selection only worked for a selection inside that line. An input with embedded newlines, such as a pasted or recalled multi-line query, spans several logical lines. With OSC 133 prompt marks, the input now runs from the input mark to the end of the text in the buffer (rlc_input_range()). Moving the caret counts a hard line break as one step, as the line editor moves over the newline with a single cursor key. <-input keeps the newlines.
  • BUILD: silence compiler and PlDoc warnings Initialise c in insert_editor() and insertSelfFillEditor() to avoid a -Wmaybe-uninitialized false positive and terminate the mode lines of set_keybinding_style/1,2.
  • ADDED: native key bindings for text entry in dialogs, over Emacs The new class variable key_binding.dialog_style sets the style of the text_item, text_item_view and text tables: `apple' on MacOS, `cua' on Windows and Unix. Keys a style does not bind keep their Emacs function. `cua' adds Control-A (select all), Control-X, Control-Left and Control-Right (by word) and Control-Backspace and Control-Delete; `apple' adds Command-C/X/V/A, Command-Left and Command-Right (line) and Option-Left and Option-Right (word). Use `emacs' for Emacs keys only; @pce->dialog_key_binding_style switches at runtime. PceEmacs and the other tables keep following key_binding.style, and switching one style no longer resets the tables of the other.
  • FIXED: Tab and Shift-Tab move the keyboard focus through a dialog SDL names the Tab key `TAB', but dialog items only advanced on code 9, so Tab did nothing on buttons, menus and the like. Shift-Tab now moves backwards; text_item and list_browser have ->previous for it.
  • FIXED: PceEmacs: Spy and listing to resolve to the implementing module.

[Oct 9 2026]

  • ADDED: bitmaps/pce.svg, a colourful vector version of the XPCE logo It replaces pce.png: the window, arrow and blob in blue and green, and the three St Andrew's crosses of Amsterdam in red, carrying P, C and E, in the U of the University of Amsterdam. The dialog gallery shows it.
  • MODIFIED: popups have a flat outline, rounded corners and a drop shadow A popup no longer draws a 3D elevation. It has a flat outline in the new class variable popup.border_colour (ui_separator) with corners rounded by the new class variable popup.radius (6 on Unix, 8 on Windows, 10 on MacOS), and the drop shadow of the new class variable popup.shadow (@nil on MacOS, which adds its own). The popup window is made larger for the shadow and is transparent outside the popup. That needs a compositor: MacOS, Windows and Wayland always have one; on X11 we check for a compositing manager and otherwise use square corners and no shadow, as transparent pixels would show black. popup.elevation is deleted.
  • MODIFIED: CSS-like drop shadows: class shadow for box, ellipse, circle, figure The new class shadow describes a drop shadow as CSS `box-shadow' does: x and y offset, blur, spread and colour, which normally has an alpha. The ->shadow of a box, ellipse, circle (new) and figure takes one. The shadow is drawn outside the area of the graphical, which keeps its size, and not under the graphical itself. The blur is a Gaussian approximated by three box blurs of an alpha mask.
  • FIXED: classes with instances could be left unrealised after boot At the end of the boot, the classes that have instances are realised by scanning the class table. Realising a class may define new classes and thus resize the table, which made the scan skip some. Adding a single built-in class made it skip class class itself. We now scan until a scan realises nothing.
  • FIXED: colours were drawn with at most 255/256 of their intensity and alpha pce_cairo_set_source_color() divided the 0..255 components by 256, so white was not quite white and no colour was fully opaque, which shows in a transparent popup window.
  • ENHANCED: tab labels: tab<->icon, narrower closable tabs, larger new-tab button A tab can show an image left of the text of its label, scaled to the height of the text and dimmed with the label of a hidden tab. It sits in the half circle at the left end of the pill, and the close button now sits in the one at the right end, which makes a closable label narrower. The new-tab button of a tabbed_window is a pill with a plus, as high as the labels and as far from the last one as the labels are from each other.
  • MODIFIED: list_browser scrolling stops with the last item at the bottom A list_browser could be scrolled until only its last item was left at the top, and ->scroll_to with @default (the end) did just that. Now scrolling in any way stops when the last item is on the bottom line, as for the terminal.
  • ADDED: terminal_image->scroll_past_end to scroll the last line to the top With ->scroll_past_end @on (class variable scroll_past_end, default @off), the terminal can be scrolled down until the last line is at the top of the window, leaving the rest of it empty for the output that follows, which some people like while tracing. Output fills the window downwards and scrolls as usual once it reaches the bottom. The scroll bar includes the room below the last line. The option is in the Epilog preferences.
  • FIXED: Manual File/Demo programs menu item It called pcedemo/0, which no longer exists. It now starts the demo browser as a manual tool, as the GUI menu of the IDE does.
  • FIXED: the grip of a browser or view pane was drawn over its scroll bar A split_handle places itself in the corner of the window's <-content_area, which is what is visible less the scroll bars the window displays itself. The scroll bar of a view or browser belongs to the editor or list_browser that fills it, so the grip went on top of it, e.g., in the demo browser. <-content_area now also subtracts that scroll bar; emacs_view no longer needs to do so itself.
  • ADDED: demo dialog_gallery: a gallery of the dialog items Tabs with buttons (a split button and a menu button), text items and a labelled editor, the kinds of menu, bool_item and tick_box, sliders and a list browser, the colour, font, style and cursor items, and dialog groups. The status line shows the value each item's message or popup receives.
  • MODIFIED: menu layout in dialogs: vertical labels and choice widths The label of a vertical menu is now left of its first item, as for a horizontal menu, instead of on top, so a dialog puts it in the label column and the items in the value column. A choice menu no longer takes the value width of the menus above it, which stretched its segments; its segments keep the width of their own labels.
  • MODIFIED: dialog items have a flat, themed look instead of 3D Buttons, cycle menus, entry fields, dialog groups, editors, list browsers, tabs and scroll bars no longer draw 3D elevations. They use flat, anti-aliased rounded boxes in the theme colours, show the keyboard focus by an accent border and ignore ->look. Elevation class variables that selected the 3D style are deleted.
  • FIXED: frame<-position of a top-level frame could be 0,0 The position was only recorded when the window system reports that the window moved. A frame centred by xpce when its window is created gets no such event without a window manager that moves it, e.g., on a bare X server. The position is now read when the window is shown. Popups and other transient windows keep their position relative to the parent.
  • FIXED: password_item: crash on a click, Return and the clear icon Mouse events went to the invisible shadow text_item that holds the password, which cannot locate them and crashed. Return also went to the shadow, which inserted it, so the message was never sent, and the clear icon cleared only the visible text. Now keys that edit the text go to the shadow and the visible item handles the mouse, Return, Tab and ->clear. The message belongs to the visible item, so a dialog with an apply button handles it as any other item. The password shows as bullets (U+25CF) instead of stars.
  • FIXED: dialog items in tabs and dialog groups had no accelerators A dialog only assigned accelerators to its direct members. It now also assigns them to the items in dialog groups and tabs. Each tab gets its own set, which avoids the accelerators of the items around the tab stack, so tabs may reuse each other's letters. Dialog groups pass an accelerator key to their items, a tab only while it is on top.
  • MODIFIED: a dialog laid out taller than its contents no longer spreads its rows Only rows holding an item with <-ver_stretch grow; otherwise the spare height is left below the last row. This applies to the tabs of a tab_stack and to dialogs, dialog groups and label boxes laid out to a given size.
  • FIXED: accelerator underlines in nested devices were drawn at the wrong place str_label() translates the coordinates of the text lines, and the underline went through r_line(), which translated them again. Inside e.g. a tab, the underlines showed up as stray dashes away from their labels.
  • CLEANUP: delete images, defaults and the system Defaults file made redundant by the menu redesign Deleted @mark_image and @nomark_image, the unused bitmaps mark, nomark, on_marked, off_marked, on_toggle, off_toggle, toggle_on, toggle_off, ol_cycle, ol_pulldown, ol_pullright and ms_*_arrow, and the system Defaults file, whose only entry duplicated the built-in font.system_fonts. <pcehome>/Defaults is still read if a site administrator creates it. Class variable defaults no longer test the always-true @colour_display, and pce.initialise no longer defines the unused @_mark_elevation.
  • FIXED: themes added as library(theme/Name) were not offered The theme menu of the IDE and the preferences editor only offered a theme if its file was a .pl file whose text mentions pce_theme:colour. Now every Prolog source in a library(theme) directory is a theme, except auto, which chooses between light and dark. Each theme is listed once; the themes after light are sorted by name.
  • FIXED: font<-domain ignored fallback fonts after the 64th With many fonts installed, a font late in the fallback chain may cover characters beyond the reported domain, so font->member succeeded for characters outside font<-domain. The envelope is now extended font by font, only examining code points outside it, which is also faster.
  • TEST: class variable editor: * scope is only offered where it makes sense Since 09d25fec3, colour has no * scope. Test that, and test the * scope on a class variable that two test classes declare.
  • DOC: class menu: ->kind and ->multiple_selection, theme class variables, keyboard Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • ENHANCED: marked and choice menus can be operated from the keyboard Such menus accept the keyboard focus. The arrow keys move the selection of a single selection menu. In a multiple selection menu they move the new menu->focus_item, which Space or Return toggles. At the first or last item, Left and Right move to the previous or next dialog item. The focus item is shown with a ring in the accent colour.
  • MODIFIED: menus have one themed look: radio buttons, check boxes and segmented choices A marked menu draws radio buttons, or check boxes if it has multiple selection; a choice menu is a segmented control. The indicators are vector drawings in the theme colours and scale with the value font. Menus ignore ->look, so toggle menus now show check boxes on all platforms. Popups highlight the previewed item with the selection colour and mark selected items with a check mark. New class variables: accent_colour, indicator_size, indicator_border, indicator_background, segment_background, segment_border and segment_pressed. Deleted: item_elevation, mark_elevation and preview_elevation.
  • MODIFIED: menu->kind sets only the presentation; selection is ->multiple_selection ->kind is cycle, marked, choice or popup and resets ->multiple_selection to @off. toggle remains as the name for a marked menu with multiple selection, and <-kind answers toggle for such a menu. ->feedback maps to ->kind. A cycle menu is always a combo box: the class variable cycle_indicator and the internal kind cycle_popup are deleted.
  • CLEANUP: share pill drawing and input-focus test between dialog items; add r_smooth_box() r_smooth_box() draws an anti-aliased box with rounded corners, for controls with a modern look.

[Oct 8 2026]

  • ENHANCED: preferences editor: only offer * scope where it makes sense The * scope is offered only if several classes declare the class variable and it has a common meaning (not for e.g., colour or background). Its tooltip lists the classes it applies to.
  • FIXED: tooltips of the items in the drop-down list of cycle menus Moving over the list passes the focus of the window to the gesture of the list_browser, after which the inspect handlers no longer looked at the completer. Now use the completer if its client is in the window.
  • ADDED: PlDoc comments for the members of Prolog defined classes A structured comment starting with `->Sel`, `<-Sel`, `<->Var`, -Var or `.Var` documents the member of the class being compiled and a block comment starting with `<class> Title` documents the class. They become PlDoc objects xpce(Class, Kind, Name) with a signature derived from the definition. The new library(pce_class_doc) finds this documentation from the PlDoc database or by cross-referencing the class source. It is shown by the manual card for objects without a manual entry, by the preferences editor ("?" help, value tooltips and the tooltip of class variables without a summary) and on the PlDoc web pages. Documented the class variables of the PceEmacs and Epilog preferences.
  • ENHANCED: horizontal scrolling with the wheel: Shift+wheel and horizontal_wheel events Shift with the wheel scrolls horizontally, as does the wheel on a horizontal scroll_bar. Horizontal scrolling of a trackpad or tilt wheel is reported as a horizontal_wheel event. If the receiver cannot scroll horizontally, Shift with the wheel scrolls one line as before.
  • FIXED: navigator: edit callees defined elsewhere and do not hang showing help A predicate that is not defined in the analysed file, such as a built-in or library predicate, can now be edited. Showing its manual used help/1 in the GUI thread, which could block on the console pager; it now uses class prolog_predicate, which shows the manual in a window.
  • FIXED: navigator: loading files no longer scrolls the tree away Expanding a file often loads files, which are added to the tree. This moved the expanded node or scrolled to the directory of the new file. The node the user expanded last, or else the top node of the window, now keeps its position in the window.
  • FIXED: Wayland: tooltip of browser and menu items did not follow the item Moving the pointer to another item changed the text of the tooltip, but not its position. The tooltip is now reopened at the new position.
  • ENHANCED: theme colour chooser shows where each colour gets its value A column shows whether the colour comes from the desktop, the theme or a default, and the tooltip traces the value step by step, e.g., from ui_margin_background through ui_window_background to the GNOME desktop setting for sys_window_background. Adds theme_colour_origin/2 to library(pce_theme) and @system_colour_origins, which tells whether a sys_* colour comes from the desktop or is an xpce default.
  • MODIFIED: the xpce Prolog libraries use num rather than real Methods and slots typed real, int|real, etc. now use num. A num arrives in Prolog as an integer if it is integral. float_item keeps returning floats. Also fixes integer division on a font ascent in the colour item, scaled_bitmap with a numeric scale and float_item->increment beyond the upper bound.
  • FIXED: saving a num that is not a 32-bit integer, e.g., a pen of 1.5 Such values were saved as a (truncated) integer or raised an assertion. They are now saved as a double using the new 'F' tag.
  • ENHANCED: preferences editor: edit a class variable with a set of values using a cycle menu E.g., text_cursor.fixed_font_style is now edited using a cycle menu rather than a text item. The descriptions of the values from the manual are shown as tooltips of the menu items.
  • FIXED: pane_frame: keep a tool's status message when it moves and activate a pane on a click A tool remembers its last inform, warning or error message and shows it again when it becomes the current pane, also after moving to another window. A window drops its status bar only if none of its panes uses it. Clicking a window that does not want the keyboard, such as the graph of the thread monitor, now makes its pane current through the new frame hook ->window_clicked.
  • ENHANCED: string(Obj) creates a string holding a copy of the text of a char_array Obj may be an object reference or a term that converts to a char_array, e.g., string(string(foo)). The text is copied as is, i.e., it is not used as a format.

[Oct 7 2026]

  • MODIFIED: real ranges and most methods that took a real use num A real range type such as `0.0..1.0` translates to a num rather than a real object, as do the arguments of ->resize, ->layout, ->draw_arc, <-angle, date<->posix_value, pce<-cpu_time, stream<-read_line and the colour factors of <-hilite, <-reduce, <-fade and <-mix. The dispatch timeout is a num in seconds rather than an int in milliseconds or a real in seconds.
  • ENHANCED: class variable editor: general preferences and preferences of the IDE tools The Text tab sets `*.selection_style` for all classes. The Theme tab (was Colours) holds the theme and, under the heading Bell, the visual and audible bell, edited using sliders that are only active if the setting is used. The profiler, cross-referencer, debugger, thread monitor and navigator declare their preferences, so the editor shows them. The settings of the cross-referencer and debugger are now class variables saved in the Defaults file; an existing config('Tracer.cnf') is migrated once. Colours of these tools are theme colours.
  • FIXED: prolog_thread_monitor->update_interval did not store the value.
  • MODIFIED: graphical<->pen is a num, so lines can be drawn with a fractional width This matches Cairo. The slot type is `num' rather than `0.0..', as a real range converts the class variable default to a `real' object, which the C code read as a pen of 0, so nothing was drawn. Negative values are mapped to 0. line->pen accepts a num as well.
  • MODIFIED: an inactive slider fades, as an inactive bool_item Using the inherited graphical.inactive_colour, the track was painted in the background colour, leaving only a grey knob.
  • ENHANCED: the bell: pitch and duration are class variables; times are in seconds display.bell_pitch and display.bell_duration define the tone of display ->bell. graphical.visual_bell_duration and the time of ->flash are in seconds, as all times in SWI-Prolog. BEL in a terminal_image calls ->alert, so it respects graphical.visual_bell.
  • DOC: no longer describe xpce in terms of X-windows Class and method summaries, comments and the reference manual refer to the window system rather than X-windows. Class window is summarised as a "Scrollable device with its own coordinate system".
  • BUILD: install the reference manual Markdown files and rebuild manindex.db Combines:
  • FIXED: persistent_frame: destroying a frame that was never opened wiped the saved geometry of all other frames Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011Ee9zPKoGDiUDoBz6rrguv
  • FIXED: the debugger saved its settings in every process that loaded it Only save Tracer.cnf if a setting was changed. The tests that load the debugger use a configuration file of their own.
  • MODIFIED: debugger settings are in Settings/Debugger The debugger adds this item to the Settings menu of the window it is in. The dialog uses bool_item, int_item and a cycle menu.
  • DELETED: display<->dpi and library(print_text) The DPI of a display was no longer used. Printing text (PceEmacs Print and Print selection) no longer worked.
  • MODIFIED: types, comments and classification of class variables Numeric class variables with natural bounds use range types, class variables have comments and are classified as basic or advanced for the class variable editor. On Windows, PceEmacs saves files that cannot be represented in the default encoding as UTF-8.
  • MODIFIED: class browser applies changes immediately The Apply button is gone and search works as you type. Also fixes the class field and the "All" filter.
  • ADDED: library(pce_class_variable_editor): edit GUI preferences Pick a GUI object on the screen and edit the class variables of its component, as declared by library(pce_preferences), or general preferences in the tabs Text, Colours, Layout and IDE. Values are applied immediately and can be saved to the Defaults file. Opened from Settings/Edit GUI preferences of the IDE and from the manual. Also adds config_item/4 to library(pce_configeditor) and `visual<-contained`.
  • MODIFIED: tile appearance: separators, gap colour and borders The class variables tile.separator_pen, tile.separator_colour and tile.gap_colour define the space between the windows of frames and tab_frames. tile.fixed_border is the width of gaps that cannot be resized. `frame<->background` is removed; use `tile<->gap_colour` of the root tile. Also fixes tile layout if space is short, a new root tile taking over the appearance and loading library(tab_frame) after subclassing tabbed_window.
  • ENHANCED: change fonts at runtime display_manager->fonts_changed applies changes to font.scale and font.pango_families to the existing fonts and windows. font.pango_families only maps mono, sans and serif. New type mono_font, `font<-font_families` filters on monospace and the characters covered and `list_browser<-drop_unrenderable` drops items whose font cannot show them, so combo boxes can show font families in their own font. Adds pango_families_item and fixes `font<-fixed_width`.
  • MODIFIED: text carets: styles bar, block, underline and xpce; blinking The caret of editors, text items and terminals has the styles bar, block, underline and xpce (the default), selected by text_cursor.fixed_font_style and text_cursor.proportional_font_style. The active caret blinks (text_cursor.blink).
  • ENHANCED: combo boxes, menus and list browsers Combo boxes show tooltips for their values, work from the keyboard (up, down, return, escape, search) and close on a click outside, also for cycle menus. Items of a list_browser can have tooltips. Alt-click or double-click selects only one item of a toggle menu. Also fixes sliders with real bounds, scrolling back to the origin of a restricted window and the frame of a loc_still event.
  • ADDED: dialog items to edit colours, cursors and styles New are colour_editor, colour_item (a compact item to select a theme colour or edit a colour), ansi_colours_item, cursor_item, style_item and line_decoration_item. The old colour_item is renamed to colour_palette_item. Compound dialog items record ->active.
  • ADDED: class bool_item: a switch to edit a boolean value library(pce_config) uses it to edit booleans.
  • ADDED: text->style, strikethrough and textured underlines A style overrules the font, colour, etc. of a text object. Styles support strikethrough and textured (wavy, dotted, ...) underlines. Also fixes the position of underlines, underlines of multi-line text, style grey in editors and the background of selected text in a translated window.
  • MODIFIED: colours no longer accept images (pixmaps) Colours and backgrounds are colours. The remaining support for images as colours is removed and graphical.inactive_colour is of type colour*. Also fixes colour<-saturation (was misspelled as <-saturnation), adds theme_colour<-summary describing the role of a theme colour and fixes a crash after freeing @colour_names or @colour_list.
  • FIXED: class variables: subclass entries, inherited values and summaries A Defaults entry for a subclass of the class that declares a class variable is now used, class->class_variable_value on an inherited class variable no longer changes the super class, `class_variable<-summary` falls back to the instance variable, #RRGGBB colours in Defaults are accepted without a warning and use_class_template/1 keeps the summary of the class.

[Oct 5 2026]

  • FIXED: xpce SDL: synthesize a lost mouse up-event If a motion event shows that the button pressed in an xpce window is no longer held, but no up-event was seen, the motion is turned into the missing up-event. This terminates the gesture that handled the down.
  • FIXED: xpce SDL: deliver drag and up events to the window of the down If SDL reported a drag or up event for another frame than the one that received the down event, the event went to the window under the pointer in that frame, leaving the gesture that handled the down active.
  • FIXED: xpce drag-scroll: vertical scrolling tested y against the width The vertical cases compared the y coordinate instead of x against the width, so dragging diagonally beyond the right edge scrolled vertically.
  • FIXED: xpce gestures: drag-scroll only while the gesture's button is held If a gesture remained active after missing its up-event, the pointer leaving the window generated an area_exit just outside the client, which started the drag-scroll timer. PceEmacs then kept scrolling although no button was pressed.

[Oct 4 2026]

  • FIXED: terminal: send NUL for Ctrl+Space, as xterm does SDL reports Ctrl+Space as a space with Control held, which the terminal passed on as a plain space, so e.g. emacs -nw never saw set-mark. Alt+Ctrl+Space now sends ESC NUL rather than a lone ESC.