* Lazy initialize image height. This is necessary to prevent garbage
from being rendered for "empty" sixels.
* Fix plotting of non-1:1 pixels
* Fix calculation of height in resize(), for non-1:1 aspect ratios
That is, parse P1 when initializing a new sixel, and don’t ignore
pad/pad in the raster attributes command.
The default aspect ratio is 2:1, but most sixels will override it in
the raster attributes command (to 1:1).
This adjusts the logic that positions the text cursor after emitting a
sixel, when sixel scrolling mode is *enabled*.
We’ve always mimicked XTerm’s behavior. However, XTerm recently
changed its behavior, to better match that of an VT382.
Now, the cursor is placed *on* the last row of the sixel, instead of
on a new row after the sixel.
This allows applications to print sixels to the bottom row of the
terminal, without causing the content to scroll.
Finally, there was a bug in the horizontal positioning of the cursor;
it was placed on the *first* column of the row, instead of on the
first column of the sixel.
We don’t need to record scroll damage if the viewport isn’t at the
bottom, since in this case, the renderer ignores the scroll damage
anyway.
This fixes a performance corner case, when the viewport is at the top
of the scrollback history.
When application scrolls the terminal contents, and the scrollback
history is full, and the viewport is at top of the history, then the
viewport needs to be moved (the scrollback history is a circular
buffer, and thus the top of the history “moves” when we’re scrolling
in new contents).
Moving the viewport typically results in another type of scroll
damage (DAMAGE_SCROLL_IN_VIEW, instead of the “normal” DAMAGE_SCROLL).
Thus, each application triggered scroll, will result in two scroll
damage records: one DAMAGE_SCROLL, and one
DAMAGE_SCROLL_IN_VIEW. These two are incompatible, meaning they can’t
be merged. What’s worse, it also means the DAMAGE_SCROLL records from
two application triggered scrolls cannot be merged (since there’s a
DAMAGE_SCROLL_IN_VIEW in between).
As a result, the renderer will not see one, or “a few” scroll damage
events, but a *ton*. _Each_ one typically a single line, or so. And
each one resulting in lots of traffic on the wayland socket, as we
create and destroy new buffer pools, when doing “shm scrolling”.
This eventually leads to the socket not being able to keep up, and the
socket is closed on us, forcing us to exit.
The fix is really simple: don’t record “normal” scroll damage when
scrolling, _unless_ the viewport is at the bottom (and thus “follows”
the application output).
As soon as the user scrolls up in the history, we’ll stop emitting
normal scroll damage records. This is just fine, since, as mentioned
above, the renderer ignores them when the viewport isn’t at the
bottom.
What if the viewport is moved back down again, before the next frame
has been rendered? Wont there be “missing” scroll damage records? No,
because moving the viewport results in scroll damage records by
itself.
Closes#1380
When doing an interactive resize, and `resize-delay-ms` > 0 (the
default), we would crash if the original screen size (i.e. the size
before the interactive resize started) was larger than the last window
size.
For example, if we interactively go from 85 rows to 75, and then
non-interactively went from 75 to 80, we’d crash.
The resizes had to be made in a single go. One way to trigger this was
to start an interactive resize on a floating window, and then *while
resizing* toggle the window’s floating mode.
Closes#1377
Set cursor column, absolute.
term_cursor_to() needs to reload the current row pointer, and is thus
not very effective when we only need to modify the column.
We’re already switching on the next VT input byte in the state
machine; no need to if...else if in action_param() too.
That is, split up action_param() into three:
* action_param_new()
* action_param_new_subparam()
* action_param()
This makes the code cleaner, and hopefully slightly faster.
Next, to improve performance further, only check for (sub)parameter
overflow in action_param_new() and action_param_subparam().
Add pointers to the VT struct that points to the currently active
parameter and sub-parameter.
When the number of parameters (or sub-parameters) overflow, warn, and
then point the parameter pointer to a "dummy" value in the VT struct.
This way, we don’t have to check anything in action_param().
This is a new ‘extended’ capability. ‘TS’ has been around for a while,
but was originally not part of foot’s terminfo. Not sure when it was
added to ncurses’ foot terminfo.
In any case, ncurses has this to say about TS:
These building-blocks allow access to the X titlebar and icon name as a
status line. There are a few problems in using them in entries:
a) tsl should have a parameter to denote the column on which to transfer to
the status line.
...
But that issue regarding the parameter for tsl means that applications may
not rely on it. The SVr4 documentation says tsl will "move to status line,
column #1". At the point in time when ESR added DJM's "pseudo-color" entry
with the split-up escape sequence for tsl/fsl, there were 65 entries using
tsl:
32 used a parameter, matching the documentation (including x10term).
21 used a parameterless control, exiting from the status line on ^M.
6 used parameterless controls for tsl and fsl
6 used a split-up escape sequence, e.g., the same approach.
The extension "TS" is preferable, because it does not accept a parameter.
However, if you are using a non-extended terminfo, "TS" is not visible.
If the locale isn't UTF-8, foot tries to fall back to C.UTF-8 and
prints a warning. The warning was garbled because the name of the
original locale is no longer valid after calling setlocale() a
second time. Use strdup to stash the original string.
Closes#1362
When background alpha is changed at runtime (using OSC-11), we (may)
have to update the opaque hint we send to the compositor.
We must also update the subpixel mode used when rendering font
glyphs.
Why?
When the window is fully opaque, we use wl_surface_set_opaque_region()
on the entire surface, to hint to the compositor that it doesn’t have
to blend the window content with whatever is behind the
window. Obviously, if alpha is changed from opaque, to transparent (or
semi-transparent), that hint must be removed.
Sub-pixel mode is harder to explain, but in short, we can’t do
subpixel hinting with a (semi-)transparent background. Thus, similar
to the opaque hint, subpixel antialiasing must be enabled/disabled
when background alpha is changed.
For this to work, the default app-id of footclient has been changed
from ‘foot’ to ‘footclient’.
By using distinct StartupWMClasses, the compositor can connect a
running foot/footclient instance to the correct .desktop-file. This
ensures the correct icon is being used in e.g. docks, and that actions
like “open another window” works correctly.
Note that the user can override the app-id, either by setting app-id
in foot.ini, or with the -a,--app-id command line option.
Closes#1355
This patch generalizes the utmp support, to not only support
libutempter, but also ulog (and in the future, even more interfaces).
* Rename config option main.utempter to main.utmp-helper
* Add meson option -Dutmp-backend=none|libutempter|ulog|auto
* Rename meson option -Ddefault-utempter-path to -Dutmp-default-helper-path
* utmp is no longer detected at compile time, but at runtime instead.
Meson will configure the following pre-processor macros, based on the
selected utmp backend:
* UTMP_ADD - argument to pass to utmp helper when adding a record (starting foot)
* UTMP_DEL - argument to pass to utmp helper when removing a record (exiting foot)
* UTMP_DEL_HAVE_ARGUMENT - if defined, UTMP_DEL expects an extra argument ($WAYLAND_DISPLAY)
* UTMP_DEFAULT_HELPER_PATH - path to the default utmp helper binary
The documentation has been updated to mention which arguments are
passed to the helper binary.
Closes#1314
Foot’s policy is to not set environment variables that identifies
it (except the well-known and established `TERM` variable).
We encourage applications to use terminfo to determine capabilities,
or terminal queries, when available. Or, at least use terminal queries
to detect the terminal and its version.
Setting environment variables is a bad idea since they are inherited
by all applications started by the terminal (which is the whole
point). But, this includes other terminal emulators, making it very
possible a terminal emulator gets mis-detected just because it was
started from another terminal.
Since there are a couple of terminal emulators that _do_ set
TERM_PROGRAM and TERM_PROGRAM_VERSION, unset these environment
variables to avoid being misdetected.
Closes#1349
3b41379be4 introduced a regression,
where canceling a scrollback search didn’t refresh the viewport
correctly; the viewport was changed, but the screen content was not
refreshed.
This worked before, because the workaround for
https://github.com/swaywm/sway/issues/6960 always called
term_damage_view() when exiting scrollback search mode.
3b41379be4 removed that call since it’s
no longer required. *Except* when executing the
BIND_ACTION_SEARCH_CANCEL binding, since then the viewport may be
moved.
Note that this regression affected *all* compositors, not just Sway.
Closes#1354
When unmapping a sub-surface, Sway <= 1.8 does not damage the surface
beneath the sub-surface.
https://github.com/swaywm/sway/issues/6960
The workaround is to manually damage the main surface. Previously,
this was done when exiting scrollback search, and after the ‘flash’
OSC. But other sub-surfaces, that may also be unmapped, did not.
This patch adds a quirk handler that does this, and calls it when:
* Exiting scrollback search
* Ending the ‘flash’ OSC
* Exiting unicode input mode
* Clearing URL labels
* Removing the scrollback position indicator
Closes#1335
The original kitty keyboard specification allowed F3 to emit either
CSI R, or CSI 13~.
Support for CSI R was removed in later revisions of the protocol,
since it collides with "Cursor Position Report" sequences.
If we had a non-empty bottom scroll region, and the window was resized
to a smaller size, the scroll region was not reset correctly.
This led to a crash when scrolling the screen content.
Fix by making sure the scroll region’s endpoint is within range.
At least Gnome needs this in order to link running instances of foot
to their corresponding .desktop file, used e.g. when determining which
icon to display for running applications.
Closes#1317
We’ve never supported neither 132-column mode, nor smooth
scrolling. But we _did_ recognize the escape sequences.
We don’t, anymore. Thus it makes very little sense to include these
escapes in any of our terminfo capabilities. So, remove them.
We don’t support neither 132 column mode, nor smooth scrolling. Thus
it makes little sense to recognize these control condes.
Note that while XTerm does support 132 columns, it is disabled by
default. In this mode, XTerm also doesn’t trigger the
side-effects (i.e. clearing the screen).
Closes#1265
Some of the config options we’re testing result in calls to FontConfig
APIs. Without calling FcIni()+FcFini(), we leak memory:
Direct leak of 768 byte(s) in 3 object(s) allocated from:
#0 0x7f7e95cbfa89 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x7f7e95bd1fe5 (/usr/lib/libfontconfig.so.1+0x20fe5)
Indirect leak of 96 byte(s) in 3 object(s) allocated from:
#0 0x7f7e95cbf411 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7f7e95bd63fd (/usr/lib/libfontconfig.so.1+0x253fd)
Indirect leak of 19 byte(s) in 2 object(s) allocated from:
#0 0x7f7e95c72faa in __interceptor_strdup /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:439
#1 0x7f7e95bd1898 in FcValueSave (/usr/lib/libfontconfig.so.1+0x20898)
When accumulating scroll damage, we check if the last scroll damage’s
scrolling region, and type, matches the new/current scroll damage. If
so, the number of lines in the last scroll damage is increased,
instead of adding a new scroll damage instance to the list.
If the scroll damage list isn’t consumed, this build up of scroll
damage would eventually overflow.
And, even if it didn’t overflow, it could become large enough, that
when later used to calculate e.g. the affected surface area, while
rendering a frame, would cause an overflow there instead.
This patch fixes both issues by:
a) do an overflow check before increasing the line count
b) limit the line count to UINT16_MAX
When applying scroll damage, we calculate the affected region’s
height (in pixels), by subtracting the number of rows to scroll, from
the scrolling region, and finally multiply by the cell height.
If the number of rows to scroll is very large, the subtraction may
underflow, resulting in a very large height value instead of a
negative one.
This caused the check for "scrolling too many lines" to fail. That in
turn resulted in an integer overflow when calculating the source
offset into the rendered surface buffer, which typically triggered a
segfault.
This bug happened when there was continuous output in the terminal
without any new frames being rendered. This caused a buildup of scroll
damage, that triggered the underflow+overflow when we finally did
render a new frame.
For example, a compositor that doesn’t send any frame callbacks (for
example because the terminal window is minimized, or on a different
workspace/tag) would cause this.
Closes#1305
When this happened (for example, by specifying a custom compose
sequence), the kitty keyboard protocol didn’t emit any text at all.
This was caused by the utf32 codepoint being -1. This in turned was
caused by us trying to convert the utf8 sequence to a *single* utf32
codepoint.
This patch replaces the use of mbrtoc32() with a call to
ambstoc32(), and the utf32 codepoint with an utf32 string.
The kitty keyboard protocol is updated:
* When determining if we’re dealing with text, check *all* codepoints
in the utf32 string.
* Add support for multiple codepoints when reporting "associated
text". The first codepoint is the actual parameter in the emitted
sequence, and the remaining codepoints are sub-parameters. I.e. the
codepoints are colon separated.
Closes#1288