• Stable 1.8.0 bc6b4d7b8a


    dnkl released this 4 months ago | 359 commits to master since this release

    Grapheme shaping

    (rest of changelog after this)

    This release adds experimental, opt-in support for grapheme cluster segmentation and grapheme shaping.

    (note: several of the examples below may not render correctly in your browser, viewer or editor).

    Grapheme cluster segmentation is the art of splitting up text into grapheme clusters, where a cluster may consist of more than one Unicode codepoint. For example, 🙂 is a single codepoint, while 👩🏽‍🚀 consists of 4 codepoints (Woman + Medium skin tone + Zero width joiner + Rocket). The goal is to cluster codepoints belonging to the same grapheme in the same cell in the terminal.

    Previous versions of foot implemented a simple grapheme cluster segmentation technique that only handled zero-width codepoints. This allowed us to cluster combining characters, like q́ (q + COMBINING ACUTE ACCENT).

    Once we have a grapheme cluster, we need to shape it.

    Combining characters are simple: they are typically rendered as multiple glyphs layered on top of each other. This is why previous versions of foot got away with it without any actual text shaping support.

    Beyond that, support from the font library is needed. Foot now depends on fcft-2.4, which added support for grapheme and text shaping. When rendering a cell, we ask the font library: give us the glyph(s) for this sequence of codepoints.

    Fancy emoji sequences aside, using libutf8proc for grapheme cluster segmentation means improved correctness.

    For full support, the following is required:

    • fcft compiled with HarfBuzz support
    • foot compiled with libutf8proc support
    • tweak.grapheme-shaping=yes in foot.ini

    If tweak.grapheme-shaping has not been enabled, foot will neither use libutf8proc to do grapheme cluster segmentation, nor will it use fcft’s grapheme shaping capabilities to shape combining characters.

    This feature is experimental mostly due to the “wcwidth” problem; how many cells should foot allocate for a grapheme cluster? While the answer may seem simple, the problem is that, whatever the answer is, the client application must come up with the same answer. Otherwise we get cursor synchronization issues.

    In this release, foot simply adds together the wcwidth() of all codepoints in the grapheme cluster. This is equivalent to running wcswidth() on the entire cluster. This is likely to change in the future.

    Finally, note that grapheme shaping is not the same thing as text (or text run) shaping. In this version, foot only shapes individual graphemes, not entire text runs. That means e.g. ligatures are not supported.


    • Support for DECSET/DECRST 2026, as an alternative to the existing "synchronized updates" DCS sequences (#459).
    • cursor.beam-thickness option to foot.ini (#464).
    • cursor.underline-thickness option to foot.ini (#524).
    • Unicode 13 characters U+1FB70 - U+1FB8B to list of box drawing characters rendered by foot itself (rather than using font glyphs) (#471).
    • Dedicated [bell] section to config, supporting multiple actions and a new command action to run an arbitrary command. (#483)
    • Dedicated [url] section to config.
    • [url].protocols option to foot.ini (#531).
    • Support for setting the full 256 color palette in foot.ini (#489)
    • XDG activation support, will be used by [bell].urgent when available (falling back to coloring the window margins red when unavailable) (#487).
    • ctrl+c as a default key binding; to cancel search/url mode.
    • ${window-title} to notify.
    • Support for including files in foot.ini (#555).
    • ENVIRONMENT section in foot(1) and footclient(1) man pages (#556).
    • tweak.pua-double-width option to foot.ini, letting you force Private Usage Area codepoints to be treated as double-width characters.
    • OSC 9 desktop notifications (iTerm2 compatible).
    • Support for LS2 and LS3 (locking shift) escape sequences (#581).
    • Support for overriding configuration options on the command line (#554, #600).
    • underline-offset option to foot.ini (#490).
    • csd.button-color option to foot.ini.
    • -Dterminfo-install-location=disabled|<custom-path> meson command line option (#569).


    • fcft: required version bumped from 2.3.x to 2.4.x.
    • generate-alt-random-writes.py --sixel: width and height of emitted sixels has been adjusted.
    • Concealed text (\E[8m) is now revealed when highlighted.
    • The background color of highlighted text is now adjusted, when the foreground and background colors are the same, making the highlighted text legible (#455).
    • cursor.style=bar to cursor.style=beam. bar remains a recognized value, but will eventually be deprecated, and removed.
    • Point values in line-height, letter-spacing, horizontal-letter-offset and vertical-letter-offset are now rounded, not truncated, when translated to pixel values.
    • Foot’s exit code is now -26/230 when foot itself failed to launch (due to invalid command line options, client application/shell not found etc). Footclient’s exit code is -36/220 when it itself fails to launch (e.g. bad command line option) and -26/230 when the foot server failed to instantiate a new window (#466).
    • Background alpha no longer applied to palette or RGB colors that matches the background color.
    • Improved performance on compositors that does not release shm buffers immediately, e.g. KWin (#478).
    • ctrl + w (extend-to-word-boundary) can now be used across lines (#421).
    • Ignore auto-detected URLs that overlap with OSC-8 URLs.
    • Default value for the notify option to use -a ${app-id} -i ${app-id} ... instead of -a foot -i foot ....
    • scrollback-*+pipe-scrollback key bindings are now passed through to the client application when the alt screen is active (#573).
    • Reverse video (\E[?5h) now only swaps the default foreground and background colors. Cells with explicit foreground and/or background colors remain unchanged.
    • Tabs (\t) are now preserved when the window is resized, and when copying text (#508).
    • Writing a sixel on top of another sixel no longer erases the first sixel, but the two are instead blended (#562).
    • Running foot without a configuration file is no longer an error; it has been demoted to a warning, and is no longer presented as a notification in the terminal window, but only logged on stderr.


    • bell option in foot.ini; set actions in the [bell] section instead.
    • url-launch option in foot.ini; use launch in the [url] section instead.
    • jump-label-letters option in foot.ini; use label-letters in the [url] section instead.
    • osc8-underline option in foot.ini; use osc8-underline in the [url] section instead.


    • Buffer damage quirk for Plasma/KWin.


    • generate-alt-random-writes.py --sixel sometimes crashing, resulting in PGO build failures.
    • Wrong colors in the 256-color cube (#479).
    • Memory leak triggered by “opening” an OSC-8 URI and then resetting the terminal without closing the URI (#495).
    • Assertion when emitting a sixel occupying the entire scrollback history (#494).
    • Font underlines being positioned below the cell (and thus being invisible) for certain combinations of fonts and font sizes (#503).
    • Sixels with transparent bottom border being resized below the size specified in ”Set Raster Attributes”.
    • Fonts sometimes not being reloaded with the correct scaling factor when dpi-aware=no, or dpi-aware=auto with monitor(s) with a scaling factor > 1 (#509).
    • Crash caused by certain CSI sequences with very large parameter values (#522).
    • Rare occurrences where the window did not close when the shell exited. Only seen on FreeBSD (#534)
    • Foot process(es) sometimes remaining, using 100% CPU, when closing multiple foot windows at the same time (#542).
    • Regression where <mod>+shift+tab always produced \E[Z instead of the correct \E[27;<mod>;9~ sequence (#547).
    • Crash when a line wrapping OSC-8 URI crossed the scrollback wrap around (#552).
    • Selection incorrectly wrapping rows ending with an explicit newline (#565).
    • Off-by-one error in markup of auto-detected URLs when the URL ends in the right-most column.
    • Multi-column characters being cut in half when resizing the alternate screen.
    • Restore SIGHUP in spawned processes.
    • Text reflow performance (#504).
    • IL+DL (CSI Ps L + CSI Ps M) now moves the cursor to column 0.
    • SS2 and SS3 (single shift) escape sequences behaving like locking shifts (#580).
    • TEXT+STRING+UTF8_STRING mime types not being recognized in clipboard offers (#583).
    • Memory leak caused by custom box drawing glyphs not being completely freed when destroying a foot window instance (#586).
    • Crash in scrollback search when current XKB layout is missing compose definitions.
    • Window title not being updated while window is hidden (#591).
    • Crash on badly formatted URIs in e.g. OSC-8 URLs.
    • Window being incorrectly resized on CSD/SSD run-time changes.