When enabled (the default), sixels use private color registers. That
is, the color palette from the last sixel is *not* re-used.
When disabled, sixels share (i.e. re-use) the same color palette.
Closes#362
This patch adds a new configuration option,
‘osc8-underline=url-mode|always’.
When set to ‘url-mode’, OSC-8 URLs are only
highlighted (i.e. underlined) in url-mode, just like auto-detected
URLs.
When set to ‘always’, they are always underlined, regardless of mode,
and regardless of their other attributes.
This is implemented by tagging collected URLs with a boolean,
instructing urls_render() and urls_reset() whether they should update
the cells’ ‘url’ attribute or not.
The OSC-8 collecter sets this based on the value of ‘osc8-underline’.
Finally, when closing an OSC-8 URL, the cells are immediately tagged
with the ‘url’ attribute if ‘osc8-underline’ is set to ‘always’.
If the client application emitted e.g:
\E]8;;http://foo\E\\\E]8;;\E\\
i.e. an anchor without content, then we ended up with an ‘end’
coordinate that lied *before* the ‘start’ coordinate, since we
subtract one (column) from the end point to make it inclusive.
These functions update the OSC-8 URI state in the terminal.
term_osc8_open() tracks the beginning of an URL, by storing the start
coordinate (i.e. the current cursor location), along with the URL
itself.
Note that term_osc8_open() may not be called with an empty URL. This
is important to notice, since the way OSC-8 works, applications close
an URL by “opening” a new, empty one:
\E]8;;https://foo.bar\e\\this is an OSC-8 URL\E]8;;\e\\
It is up to the caller to check for this, and call term_osc8_close()
instead of term_osc8_open() when the URL is empty.
However, it is *also* valid to switch directly from one URL to
another:
\E]8;;http://123\e\\First URL\E]8;;http//456\e\\Second URL\E]8;;\e\\
This use-case *is* handled by term_osc8_open().
term_osc8_close() uses the information from term_osc8_open() to add
per-row URL data (using the new ‘extra’ row data).
This patch adds an ‘extra’ member to the row struct. It is a pointer
to a struct containing extra data to be associated with this row.
Initially, this struct contains a list of URL ranges. These
define (OSC-8) URLs on this row.
The ‘extra’ data is allocated on-demand. I.e. the pointer is NULL by
default; it is *not* allocated by grid_row_alloc().
In addition to letting the FDM do the low-level signal watching, this
patch also fixes a bug; multiple SIGCHLDs, be it delivered either through a
signal, or via a signalfd, can be coalesced, like all signals.
This means we need to loop on waitpid() with WNOHANG until there are
no more processes to reap.
This in turn requires a small change to the way reaper callbacks are
implemented.
Previously, the callback was allowed to do the wait(). This was
signalled back to the reaper through the callback’s return value.
Now, since we’ve already wait():ed, the process’ exit status is passed
as an argument to the reaper callback.
The callback for the client application has been updated accordingly;
it sets a flag in the terminal struct, telling term_destroy() that the
process has already been wait():ed on, and also stores the exit
status.
In many places we have the following pattern:
tll_foreach(list, it)
free(it->item.thing);
tll_free(list);
Since all tll functions are macros, and thus inlined, and since
tll_free in itself expands to a tll_foreach(), the above pattern
expands to more native code than necessary.
This is somewhat smaller:
tll_foreach(list, it) {
free(it->item.thing);
tll_remove(list, it);
}
This is implemented by allocating one of the (few!) remaining bits in
the cells’ attribute struct to indicate the cell should be “URL
highlighted”.
render_cell() looks at this bit and draws an underline using the color
from colors.urls (defaults to regular3 - i.e. yellow).
A new function, url_tag_cells(), iterates the currently detected URLs
and sets the new ‘url’ attribute flag on the affected cells.
Note: this is done in a separate function to keep urls_collect() free
from as many dependencies as possible.
urls_reset() is updated to *clear* the ‘url’ flag (and thus implicitly
also results in a grid refresh, _if_ there were any URLs).
We now exit URL mode on *any* client application input. This needs to
be so since we can’t know if the URLs we previously detected are still
valid.
These two buttons were encoded using the *exact* same numbers as
button 4 and 5 (scroll wheel up/down), making it impossible to
distinguish them.
The relevant section from XTerm’s control sequences documentation is:
Some wheel mice can send additional button events, e.g., by tilting the
scroll wheel left and right.
Additional buttons are encoded like the wheel mice,
o by adding 64 (for buttons 6 and 7), or
o by adding 128 (for buttons 8 through 11).
terminal.c:3:10: fatal error: 'malloc.h' file not found
#include <malloc.h>
^~~~~~~~~~
terminal.c:1512:9: error: implicit declaration of function 'sigaction' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
sigaction(SIGALRM, &(const struct sigaction){.sa_handler = &sig_alarm}, NULL);
^
terminal.c:1532:21: error: implicit declaration of function 'kill' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
kill(term->slave, kill_signal);
^
When we are shutting down the terminal, we explicitly wait for the
child application to terminate (with a timeout, after which the child
process is killed).
I.e. there’s no need to let the reaper handle it. In fact, doing so
leads to a crash since we will have destroyed (and thus free:d) the
terminal instance when the reaper callback is called.
If the value is specified without a unit, then the value is assumed to
be in points, subject to DPI scaling.
The value can optionally have a ‘px’ suffix, in which case the value
is treated as a raw pixel count.
0, the default, means no additional spacing; the cell width is defined
by the font metrics.
A positive value *adds* to the width from the font metrics, while a
negative value *subtracts*.
* ‘term’ struct contains an array of 160 fcft glyph pointers
* the glyph pointers are lazily allocated when we need to draw a box
drawings character
* Filtering out box drawings characters is easy - they are (except
unicode 13, which isn’t handled yet )all in a single range.
Shutdown the terminal when the client process terminates, not when the
ptmx file descriptor is closed.
This fixes an issue where the terminal remains running after the
client process has terminated, if it spawned child processes that
inherited the ptmx file descriptor.
This extends the new ‘dpi-aware’ option with a new default value,
‘auto’.
When set to ‘auto’, fonts are sized using monitors’ DPI when output
scaling is disabled. When output scaling is enabled, fonts are instead
sized using the scaling factor.
The reasoning here is that a user that has enabled output scaling is
obviously *not* relying on DPI scaling.
Output scaling can also be a way to compensate for different viewing
distances, in which case we do *not* want to break that by using DPI
scaling.
Users can still force DPI-only font sizing by setting ‘dpi-aware=yes’,
or disable it completely by setting ‘dpi-aware=no’.
This fixes issues with de-synchronized frames being rendered; we may
have scheduled a redraw earlier, that hasn’t yet triggered (probably
because we’re waiting for a frame callback), when we enable
application synchronized updates.
This means we risk rendering a partially updated state when the frame
callback finally arrives, if the application hasn’t yet ended its
synchronized update.