Ann: SWI-Prolog 10.1.9

SWI-Prolog Changelog since version 10.1.8

This release is dominated by work on the new SDL3-based xpce backend
and the modernization of the xpce reference manual. The bulk of the
user-visible changes live in xpce; the core Prolog system sees a small
number of bug fixes and ISO-compliance tweaks.

Highlights:

Core Prolog changes:

  • FIXED: a typo in stack shifting that could leave the local stack
    growing in tiny increments, almost grinding the system to a halt.
  • FIXED: mpz_import stack overread in libbf builds when the input
    began with zero bytes (#1497), triggered by seed_from_dev().
  • MODIFIED: current_input/1 and current_output/1 now raise a
    domain error for stream aliases and fail for closed streams, per
    the ISO standard.

GUI (xpce) changes

  • xpce graphics: class transform adds 2D affine transforms, with
    a new transform slot on class figure so children can be
    rotated, scaled, sheared and translated as a group (events,
    bounding boxes, handles, flash and damage propagation are all
    transform-aware). Class graphical gains an opacity slot
    (0.0..1.0) for CSS-style group compositing. Class arc and
    attached arrows now carry sub-pixel precision through to cairo.

  • xpce terminal: support for the xterm-256 colour cube and 24-bit
    truecolor SGR sequences, a configurable link_style and per-link
    armed style for OSC 8 hyperlinks, dotted/dashed underline
    textures, and strikethrough (SGR 9/29).

  • xpce drag-and-drop: SDL3 file/text drop events are surfaced as
    xpce events. PceEmacs opens each dropped file in a new tab;
    Epilog consults all dropped Prolog source files in one
    consult/1 call. A new library(pce_drop_target) makes the
    overlay+callback pattern reusable.

  • Epilog: new XPCE menu exposing the core manpce/0 tools and the
    GUI inspector, and Shift-Ctrl-{V,C} key bindings for copy/paste.

  • xpce reference manual: the legacy .doc card database is
    replaced by markdown sources under man/refmanual/md/, rendered
    via PlDoc (with xpce-specific extensions in ltx2htm and pldoc)
    into both the LaTeX manual and the HTML chunks served by the new
    manpce/0 card viewer. Inline cross-references like
    Class->Sel, Class<-Sel and Class<->Sel resolve to the
    corresponding method anchors.

  • Removed: the public C/C++ embedding API for xpce (class c,
    class c_pointer, the XPCE_* entry points) — xpce now embeds
    only via pl2xpce.so. Legacy dialog_item look-and-feels
    (open_look, motif, gtk) are reduced to {xpce,win}. Five
    long-stub image methods (->invert, ->and, ->or, ->xor,
    ->invert_pixel) are gone.

  • New demos: London tube map (zoom/panning of large graph), interactive opacity, figure transforms, and an arc gallery. Updated several other demos.

Packaging:

  • Windows installer can optionally associate .pl with
    swipl-win.exe.

  • macOS installer file name aligned with the Windows convention:
    swipl-<version>-1.<arch>.pkg.

    Enjoy — Jan

Detailed changes follow.

  • ENHANCED: Windows installer optionally associates .pl with swipl-win.exe
    Adds an “Open .pl files with SWI-Prolog” checkbox to the installer’s
    Install Options page (alongside the desktop icon option). When ticked,
    registers the SWIProlog.SourceFile ProgID so .pl files double-click
    to open in swipl-win.exe. Uninstall removes the association only if
    it still points at our ProgID.

  • MODIFIED: current_input/1 and current_output/1 diagnostics According
    the the ISO standard, these predicates shall raise a domain error
    for stream aliases and shall fail if the argument is a closed stream.

  • FIXED: Ensure shifting stacks properly resizes the local stack.
    Due to a typo, the system could get into a state with many very small
    local stacks enlargements, almost grinding to a halt.

  • ENHANCED: doc2tex --xpce recognises Class->Sel arrow refs Add a CLI
    flag that turns on three extra recogniser clauses for Class->Sel,
    Class<-Sel and Class<->Sel in plain prose; they emit
    \classsend{C}{S} / \classget{C}{S} / \classboth{C}{S}
    respectively. Selectors may start with _ for private slots. The
    - (instance variable) and . (class variable) shapes are
    left alone because they collide with ordinary hyphenation and
    end-of-sentence punctuation in English prose; callers wanting those
    links should write the macro explicitly.

  • TEST: Disable tcmalloc when using ASAN. Can lead to conflicts

  • FIXED: #1497 libbf mpz_import: stack overread when leading bytes
    are zero The byte-count for the import loop was captured before
    the leading-zero strip, so when OP began with zero bytes the loop
    read that many bytes past the end of the input buffer. Triggered by
    seed_from_dev() seeding the random state from /dev/urandom in libbf
    builds.

  • MODIFIED: macOS: name the installer swipl--1..pkg Adds
    the `-1’ package revision before the architecture suffix so the .pkg
    matches the Windows swipl--1.x64.exe naming convention.

Package cpp

  • FIXED: macOS GCC build aborting on std::bad_alloc from over-sized
    new On macOS a foreign extension built with GCC links libstdc++,
    while the process also loads the system libc++/libc++abi via the
    system frameworks. As operator new is a coalesced weak symbol it
    resolves to libc++, so new throws a libc++ std::bad_alloc whose
    type_info differs from the libstdc++ one named in PREDICATE_CATCH’s
    catch(const std::bad_alloc&). That handler misses and, lacking a
    catch-all, the exception reaches std::terminate() and aborts the
    process (e.g. test_cpp.pl cpp:malloc).

Package http

  • TEST: proxy: pick the unused' port from below the ephemeral range The previous fix reserved the unused’ port by holding a socket
    bound but not listening, so that connect() attempts are refused
    while no concurrent ctest job can grab the port via bind(0). On
    Linux/Windows a bound, non-listening socket is refused promptly,
    but on macOS connecting to such a socket blocks for several seconds
    before failing. As several tests connect to the unused port, the
    suite took ~30s on macOS instead of a fraction of a second.

Package ltx2htm

  • ENHANCED: xpce ltx2htm rules for the .md-driven reference manual -
    Add cmd declarations and HTML emitters for \classinstvar and
    \errid (introduced in TeX/xpce.sty for the .md-driven
    reference manual). - Switch the cross-reference anchor scheme for
    \class{X} / \classs{X}
    from “class:X” to “sec:class-X” so the section labels PlDoc emits
    from “# class X {#class-X}” headings resolve as link targets.
    Strip underscores from the link target to match PlDoc’s
    delete_unsafe_label_chars/2 behaviour on the corresponding
    \label{…} statement (so “class foo_bar” links to
    “sec:class-foobar”). - Switch from
    autoload(library(ltx2htm/latex2html)) to
    use_module(latex2html) so sty_xpce.pl loads cleanly when invoked
    outside an installed environment with the matching library path
    alias.

Package pldoc

  • ENHANCED: accept xpce(C, ivar, N) in manindex.db Recognise the new
    “ivar” kind so xpce class instance variables indexed via sty_xpce’s
    classivar emission survive the round-trip through atom_to_object/2.

  • ENHANCED: swi_man_xpce → swi(‘xpce/man/refmanual’) The xpce
    refman HTML is now staged and installed under the xpce home tree
    (swi(‘xpce/man/refmanual’) = /lib/swipl/xpce/man/ refmanual/),
    alongside the rest of the xpce data files (bitmaps, prolog/, appl-help/,
    man/faq/, …). Update the file_search_path so save_man_index/0 picks
    up the .html chunks from the new location and manual_object/5 returns
    file paths that actually exist after install.

  • FIXED: {#anchor} parser accepts `_’ as a token The wiki tokenizer
    breaks {#object-_not_returned} into ['{', '#', w(object), -, '_', w(not_returned), '}'], but the section-label parser’s label_cont
    rule only accepted - and w(Name) tokens, dropping anchors
    that contain a _ immediately after a separator. Add an explicit
    clause for the bare _ token so such anchors are recognised.

  • ENHANCED: index XPCE class-member entries in manindex.db Recognise
    xpce(Class,Kind,Name) compounds emitted by the ltx2htm xpce backend
    (see sty_xpce.pl) so the new XPCE refman HTML lands in the same
    machinery PlDoc uses for the core manual:

  • FIXED: escape < > with \textless / \textgreater instead of math mode
    print_char/2 used to emit $<$ and $>$, which break hyperref’s
    PDF bookmark string generation (“Token not allowed in a PDF string:
    removing ‘math shift’”) and don’t survive any subsequent text-mode
    context cleanly. Switching to the text-mode commands lets hyperref embed
    them in bookmarks unchanged and renders identically in normal text.

  • FIXED: tags environment uses ##1 to escape nested newcommand
    parameter \newenvironment{tags}{…}{…} previously had
    \newcommand{\tag}[1]{\item[#1]} inside the begin body. Modern LaTeX
    interprets the bare #1 as a parameter of the surrounding environment
    (which has none), giving “Illegal parameter number in definition
    of \tags”. Doubling to ##1 lets the inner \newcommand reach its
    own parameter.

  • FIXED: @tag block no longer swallows following section headers
    rest_tag/4 used to read continuation lines for a tag until the next
    @tag or end of input, which meant a following ## section heading became
    part of the last tag’s value. Now also terminates at any section header
    (twiki or markdown atx/setext).

Package utf8proc

  • FIXED: install additional file in tests folder needed for the runtime
    unit tests

Package xpce

  • ADDED: Epilog key bindings Shift-ctrl-{V,C} for copy/paste

  • ENHANCED: Multi-file drop on PceEmacs opens each file in a new tab
    Drop one or more files on a PceEmacs editor to open each as a new tab.
    Show a faint centered hint during the drag.

  • ENHANCED: Multi-file drop on Epilog with overlay feedback Drop one or
    more files on an Epilog terminal to consult all Prolog source files
    in a single consult/1 call. Show a faint centered hint during the
    drag and briefly flag any non-Prolog files in red.

  • ADDED: library(pce_drop_target) for SDL3 drop overlays A small helper
    that turns the SDL3 drop_position / drop_file / drop_complete lifecycle
    delivered to an xpce graphical into a single callback receiving the
    list of dropped OS paths, with a centred bordered hint overlay shown
    on the target’s window during the drag. Transient state lives in
    xpce object attributes, so consumers need no class variables.

  • CLEANUP: misc Smaller, independent cleanups that surfaced during the
    larger work:

  • ADDED: Epilog XPCE menu with the core manpce/0 tools A new “XPCE” popup
    before Help in Epilog’s menu bar covers the File/Demo programs entry,
    all Browsers entries and the first three Tools entries from manpce/0.
    All tool entries route through the existing send(@manual, start_tool,
    Tool) hook, which creates @manual silently (no expose), so users do
    not have to call manpce/0 first. “Inspect GUI hierarchy” moves from
    the Tools menu to the new XPCE menu.

  • ADDED: OS file/text drag-and-drop events via SDL3 Surface SDL3 file/text
    drop events as xpce events. src/sdl/sdlevent.c translates SDL_DROPFILE
    / SDL_DROPTEXT into a pair of new event names that the kernel and
    class event recognise. prolog/demo/dragdrop_file.pl ships a small
    drag-and-drop demo and the pce_demo entry registers it in the demo set.

  • CLEANUP: drop image ->invert, ->invert_pixel, ->and, ->or, ->xor Five
    send-methods on class image were stubs that did nothing. Remove the
    SM entries, the C bodies (invertImage, invertPixelImage, opImage,
    orImage, andImage, xorImage), the matching backend stubs r_op_image
    and r_complement_pixel in sdldraw, and the unused T_image_atADpointD
    type decl. image<-rotate documentation is updated to advertise the
    figure + transform idiom (see the markdown sources commit).

  • CLEANUP: reduce dialog_item look domain to {xpce,win} The look slot
    on class dialog_item used to admit four values: open_look, motif,
    win and gtk. open_look and motif are legacy look-and-feels nobody
    runs anymore; gtk was the working Unix default and is renamed to xpce
    (a neutral name not tied to a host toolkit). The domain narrows to
    {xpce,win}, with xpce default on non-Windows and win on Windows.

  • REMOVED: class c, class c_pointer and the public C/C++ embedding API
    xpce now embeds only via pl2xpce.so; the old C/C++ host classes and
    the XPCE_* embedding API are unused and removed.

  • CHANGED: manpce/0 modernization for the markdown manual The manpce/0
    tool moves from the .doc card database to the markdown-generated HTML
    chunks served by library(pce_html_manual). The main changes:

  • ENHANCED: HTML manual viewer (pbox selection, code blocks, scroll clamp)
    doc_window grows the affordances needed to host the new HTML manual:

  • REMOVED: legacy .doc reference manual sources Drop man/reference/*.doc
    – the old binary-encoded card database that backed the .doc-format
    reference manual. Replaced by the markdown sources under
    man/refmanual/md/ that the new pipeline renders into the manpce/0
    card viewer and the published HTML/PDF manuals.

  • ADDED: markdown reference manual sources Add man/refmanual/md/*.md
    as the new home for the xpce reference manual. Each class, group of
    error codes and special section gets a PlDoc-flavoured markdown file
    with stable {#class-} (and similar) anchors that the new build
    pipeline turns into both the LaTeX manual and the HTML chunks served
    to the manpce/0 card viewer.

  • BUILD: markdown-based reference manual pipeline Introduces a refman
    pipeline that renders the xpce reference manual from markdown sources
    via PlDoc (with xpce-specific extensions) into the existing TeX/HTML
    manual:

  • ADDED: London tube demo Interactive map of the London tube network: zoom
    and pan, search stations, toggle lines on or off, hover to highlight
    every line through a station or segment. Demonstrates figure transforms,
    recognisers, the report system and connection routing via handles.

  • ADDED: library(pan_zoom) Reusable recogniser that handles
    wheel-zoom-around-cursor and left-drag pan by editing the receiver
    figure’s transform. A global @pan_zoom_recogniser is provided for
    class-wide reuse.

  • FIXED: terminal_image: initialise <-armed_link to @off The slot has
    type bool (not bool*), so the implicit @nil left at construction
    tripped the object base check.

  • ENHANCED: demo: interactive opacity demo Adds a pcedemo entry `Opacity’
    that opens a frame with six labelled cells and a single slider driving
    the opacity of every foreground graphical at once. The cells cover:

  • ENHANCED: graphical: composite with alpha when <-opacity < 1.0
    RedrawArea now wraps the per-class redraw in a cairo group when the
    graphical’s opacity is below 1.0, then paints the group onto the parent
    surface with that alpha. For a single primitive this is equivalent
    to using an alpha-bearing colour; for devices and figures it gives
    the correct CSS-style opacity, where overlapping children composite
    fully opaque first and the whole group is then blended.

  • ENHANCED: graphical: add <-opacity slot (Num, 0.0..1.0, default 1.0)
    Per-graphical opacity for compositing. The slot is declared on class
    graphical so it applies uniformly to primitives, dialog items, devices
    and figures. Values outside [0.0, 1.0] are clamped on assignment.
    Rendering itself is wired up in a follow-up commit; this change only
    adds the slot, the accessors and request-redraw on change.

  • FIXED: Image viewer demo.

  • ENHANCED: demo/transform: use figure shortcuts and a single rebuild
    Each slider now sends `->rebuild’ instead of a per-slider callback;
    ->rebuild reads all three slider values from the dialog and composes
    the scene’s transform via the new figure shortcuts (->translate,
    ->scale, ->rotate, ->shear), starting from a fresh identity.

  • ENHANCED: figure: ->translate / ->scale / ->rotate / ->shear
    Composing transform shortcuts on class figure. Each method composes
    the corresponding operation into the figure’s transform, allocating
    an identity transform on demand if the figure currently has none.
    The same `self := self * Op’ rule as on class transform applies,
    so calling these in sequence pre-composes from the inside out.

  • ENHANCED: transform: rotate/scale/shear initialise; ->set for
    coefficients Replaces the 6-coefficient ->initialise with a high-level
    form:

  • BUILD: install demo/transform.pl with the demo data files
    XPCE_DATA_prolog_demo is an explicit list; without this entry
    demo/transform.pl is not copied to the install tree and pcedemo fails
    with `source_sink demo(transform) does not exist’.

  • ENHANCED: pce_demo: register figure->transform demo Adds the Transform
    entry to the XPCE demo browser (pcedemo/0) so the new demo/transform.pl
    shows up in the standard demo list.

  • FIXED: handle.c: drop unused Int x, y from getXYHandle Leftover
    declarations from the pre-transform-aware version; the rewrite uses
    hx/hy and gx/gy only.

  • FIXED: transformed figure: pass children pre-transform area for
    paint RedrawTransformedChildren handed each child the dirty rect
    coming from the parent, which after EnterRedrawAreaDevice is in the
    figure’s POST-transform local coord (where the rotated pixel AABB
    lives). But each child’s gr->area slot is in PRE-transform local
    coord, so the overlap test in RedrawArea mis-clipped: children whose
    pre-transform position fell outside the post-transform AABB (e.g. a
    text label below the bounding box that rotates to above it at 180°,
    or any child past a heavy scale-down) were silently skipped — text
    vanished at rotate ±180° and at scales below 50%.

  • FIXED: figure->transform: always repaint, even on same object The
    setter previously short-circuited when the assigned transform was the
    same object as the current one. That broke the common pattern of
    mutating a single transform in place (e.g. from a slider callback)
    and re-assigning it: the figure kept the cached bounding box and
    skipped the repaint.

  • ENHANCED: demo/transform.pl: live figure->transform demo Opens a
    window with a small scene (yellow box, red diagonal, green circle,
    text label) inside a figure that carries an editable transform.
    Sliders below the picture drive rotation (-180..180), scale (25..250%),
    and horizontal shear (-100..100%) around the scene’s centre; a reset
    button restores identity.

  • ENHANCED: absolute area, handles, flash route through transforms
    graphicalToDeviceCoord / graphicalToDeviceAreaAABB compose the affine
    that maps a graphical’s local coord into any specific ancestor device’s
    children-coord, taking figure->transforms along the chain into account.

  • ENHANCED: damage propagation through transformed figures Adds
    deviceLocalAreaToWindowAABB to coords.c (corner-by-corner walk through
    the device chain producing an outward-rounded integer AABB).

  • ENHANCED: events: route through transform-aware coord mapping
    get_xy_event_device and get_xy_event_graphical now consult the new
    windowToDeviceLocalCoord / windowToGraphicalCoord helpers whenever
    the device chain contains a non-identity figure->transform. An event
    delivered to a child of a rotated or scaled figure now arrives in
    the child’s actual local frame instead of being computed with the
    un-transformed integer offset.

  • ENHANCED: graphical: transform-aware coord mapping Adds src/gra/coords.c
    with a small 2D affine composition that walks the device chain from
    a graphical (or device) up to its window, applying figure->transform
    at each step. Five C-level entry points are exposed:

  • TEST: Add tests/test_figure_transform.pl Plunit-style tests for class
    figure’s transform slot and bounding box semantics: identity fast-path,
    rotation 90/180/270, scale (uniform and non-uniform), translate-only,
    empty figure, multiple children, border interaction, and recompute on
    transform set/clear/replace. Also verifies that <-local_area stays
    in un-transformed children-coords as the transform changes.

  • ENHANCED: figure: parent-coord bounding box follows transform A
    transformed figure’s <-area is now the AABB of the transformed children,
    while a new <-local_area slot keeps the un-transformed children union
    in figure-local coordinates. computeBoundingBoxFigure first lets
    computeBoundingBoxDevice fill area as today, then projects the local box
    through f->transform when present and re-rounds the result to integer.

  • ENHANCED: figure: paint children under f->transform Adds
    r_push_transform / r_pop_transform to the SDL backend. Pushing absorbs
    the current integer pen offset into the cairo transform, then composes
    the figure’s affine matrix and resets the integer offset to zero so
    that r_* primitives feed their coordinates directly into the matrix.

  • ENHANCED: figure: add optional transform slot Adds a transform slot to
    class figure, default @nil, with a setter that requests recompute and
    full repaint when changed. Painting, hit testing and bounding-box
    math will start consulting the transform in the following commits;
    for now any figure without a transform behaves exactly as before.

  • TEST: Add tests/test_transform.pl Plunit-style tests for class
    transform covering construction (defaults, explicit coefficients,
    set/copy/identity), the basic ops (translate, scale, rotate, shear),
    cairo-style composition order, invert/inverse (including singular
    detection and round-trip identity), and <-apply on points and areas.

  • ENHANCED: Add transform class for 2D affine transformations A
    `transform’ instance holds a 2x3 affine matrix (xx, xy, yx, yy, tx,
    ty) stored as Num slots and provides methods to compose translation,
    scale, rotate, shear and matrix multiplication, plus an inverse and
    a <-apply that maps a point or the AABB of an area through the matrix.

  • FIXED: Graphical ->flash: account for window scroll_offset The flash
    overlay was rendered in the window’s logical (client) coordinate
    system, while Cairo draws graphicals translated by sw->scroll_offset
    (see d_window() / Translate()). Windows whose origin is not at (0,0)
    – e.g. a workspace with origin (0, h/2) – made the flash land at the
    wrong screen position. Apply the same scroll_offset before passing
    the rect to flashWindow().

  • FIXED: ws_event_in_subwindow: translate ev->x/ev->y to frame coordinates
    When called with a frame argument, the function descended event_window()
    using ev->x/ev->y as if they were frame-relative. They are relative to
    ev->window though, which during a drag stays on the original receiver
    (the mouse_tracking_window). The position was therefore shifted by
    the tracking window’s offset in the frame, so dragging out of e.g. the
    top-left subwindow into the top-right kept reporting the top-left.

  • FIXED: SDL: stale modifier bit could leak into mouse clicks After
    a Ctrl-Shift- binding (e.g. Ctrl-Shift-O to split an Epilog
    window), the next left click was treated as Shift-click and extended
    the selection instead of starting a new one.

  • ENHANCED: demo/arc: show three arrowed arcs in the arrows cell
    Demonstrates that the wing midpoint lands on the arc across a range
    of curvatures and sweep directions.

  • ENHANCED: arc: align attached arrow wings with the arc’s curvature The
    arc’s first_arrow/second_arrow used to be aimed along the tangent at
    the endpoint, so the wing line — l1 pixels behind the tip — sat on
    a straight line that the arc had already curved away from. The visible
    offset was about l1^2/(2*radius) (≈1.9px for the demo arc).

  • ENHANCED: arrow: accept Num for tip/reference and wing/length
    pointsArrow, ->tip_x/y, ->reference_x/y, ->length, ->wing and the
    corresponding getters now declare and pass Num rather than Int,
    so arrow geometry set programmatically (e.g. from class arc) keeps
    sub-pixel precision end-to-end. Round the bounding area set by
    ->compute with floor/ceil so the area still encloses the triangle
    when the points are non-integer.

  • ENHANCED: arc: carry sub-pixel precision through geometry and rendering
    points_arc, RedrawAreaArc, includeArrowsInAreaArc, computeArc and
    the <-start/<-end getters now use double for the computed sx/sy/ex/ey
    coordinates and pass them to attached arrows via toNum() without an
    integer round-trip. r_arc takes its bounding rectangle and angles as
    double, so drawArcGraphical (->draw_arc) and the arc class no longer
    truncate angles to int before handing them to cairo. The bounding
    area set on the arc is still rounded — out to floor/ceil with the
    existing 1-pixel margin — because Area itself is integer.

  • ENHANCED: demo: add an arc gallery demo Shows the main usage patterns
    of class arc — angles, close modes, ->points, ->connect_angle,
    arrows, elliptic <-size, over-wound sweep, CW vs CCW direction,
    and a tiny pie chart.

  • ENHANCED: arc: use Num for start_angle and size_angle Class arc
    stored its two angle slots as Real. The Num type is a better fit:
    it accepts both integers and floats, returns naturally to Prolog as a
    number, and avoids the heavier Real object identity. The on-the-wire
    behaviour is unchanged.

  • FIXED: r_arc: pass arc size_angle correctly to cairo The 2nd integer
    argument to r_arc has always been size_angle (relative sweep),
    per the X11/xpce convention shared by all callers. The SDL/cairo
    backend treated it as an absolute end angle and ignored that cairo’s
    angle direction is opposite to xpce’s (cairo angles go clockwise on
    screen because cairo’s y axis points down). As a result class arc
    and ->draw_arc drew unrelated arcs.

  • ENHANCED: terminal: strikethrough support (SGR 9 / Style->strikethrough)
    text_char gains a strike bit (from the reserved word in the
    bitfield, no struct growth). SGR 9 sets it, SGR 29 clears it.
    paint_chunks threads the resolved strike+strike_texture pair to a
    new r_strikethrough in sdldraw, drawn through Pango’s strikethrough
    metrics (pango_font_metrics_get_strikethrough_{position,thickness}
    stored on WsFont next to ul_*).

  • ENHANCED: terminal: dotted underline by default for hyperlinks
    (line-texture) Style->underline now accepts a texture_name
    (none/dotted/dashed/dashdot/ dashdotted/longdash) on top of the
    existing Bool|Colour, both in the class declaration and in the
    initialise argument vector. r_underline gains a Name texture
    parameter so the dash pattern survives until the line is drawn
    (previously hard-coded to none). paint_chunks threads the resolved
    texture from effective_style_for through to r_underline.

  • ENHANCED: terminal: per-link armed style (link_armed_style) Add a
    link_armed_style slot on TerminalImage (default: blue + underline, same
    as link_style for now) and wire it into the paint loop. Hover detection
    tracks the specific href node the mouse is over on b-> armed_href;
    effective_style_for(b, flags, armed) overlays the armed style only
    on cells inside that href, falling back to link_style for other links
    on screen. The chunk grouper now splits on the armed boundary, so a
    partially-hovered link renders correctly when adjacent to a second link.

  • ENHANCED: terminal: drive hyperlink rendering from a link_style object
    Add a link_style slot on TerminalImage (default: blue + underline),
    set via ->link_style and class variable link_style, parallel to the
    existing selection_style and nfd_style. Paint resolves per-cell
    fg/bg/underline/ bold through a new effective_style_for() helper that
    overlays link_style on cells whose link bit is set. rlc_put_link no
    longer forces SGR 34/4 into b->sgr_flags — the colour and underline
    come from the style, so applications can carry their own fg/bg through
    the link label.

  • TEST: terminal: visual demo of all SGR attributes the
    xpce terminal renders demo_terminal/0 walks through styles
    (bold/underline/inverse/link), the 16 ANSI colors via fg/bg/hfg/hbg,
    the xterm-256 cube and grayscale ramp, 24-bit channel ramps + HSV
    rainbow, mixed style+color, and an OSC 8 hyperlink. All output goes
    through library(ansi_term) so the same goal also exercises any other
    ANSI terminal.

  • ENHANCED: terminal: support xterm-256 and 24-bit (truecolor) SGR
    sequences CSI ‘m’ now walks its argument list, consuming 38;5;N /
    48;5;N for xterm-256 colors and 38;2;R;G;B / 48;2;R;G;B for 24-bit
    truecolor. Colors land in a per-buffer palette (slots 0..15 still
    alias ti->ansi_colours; 16..4094 are interned via an open-addressed
    COLORRGBA hashtable). On overflow (4095 distinct truecolors), new
    requests fall back to the nearest existing entry by RGB Euclidean
    distance.

  • ENHANCED: terminal: repack per-cell metadata to make room for a
    color palette Restructure text_flags as a 32-bit tagged union (raw +
    bitfield struct): width:2, bold:1, underline:1, inverse:1, link:1,
    reserved:2, fg:12, bg:12. The width byte on text_char is gone;
    text_char stays 64 bits. fg/bg now hold palette indices (sentinel
    PAL_DEFAULT = 4095) instead of 5-bit ANSI codes, opening 4096 slots
    per slot for the upcoming 256-color and truecolor support.

  • FIXED: newdir icon (used by Browse in PceEmacs file prompter)

  • FIXED: Mixup of port and action toolbutton images (fail) for tracer.

3 Likes