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
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
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
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
If the user didn’t explicitly set the font size (e.g. font=monospace,
instead of font=monospace:size=12), our initial attempt to read the
FC_SIZE and FC_PIXEL_SIZE attributes will fail, and we used to
fallback to setting the size to 8pt.
Change this slightly, so that when we fail to read the FC_*_SIZE
attributes, apply the fontconfig rules, but *without expanding*
them (i.e. without calling FcDefaultSubstitute()).
Then try reading FC_*_SIZE again.
If that too fails, _then_ set size to 8pt. This allows us to pick up
rules that set a default {pixel}size:
<fontconfig>
<match>
<edit name="pixelsize" mode="append"><double>14</double></edit>
</fontconfig>
Closes#1287
Sort bindings such that bindings with the same symbol are sorted with
the binding having the most modifiers comes first.
This fixes an issue where the “wrong” key binding are triggered when
used with “consumed” modifiers.
For example: if Control+BackSpace is bound before
Control+Shift+BackSpace, then the latter binding is never triggered.
Why? Because Shift is a consumed modifier. This means
Control+BackSpace is “the same” as Control+Shift+BackSpace.
By sorting bindings with more modifiers first, we work around the
problem. But note that it is *just* a workaround, and I’m not
confident there aren’t cases where it doesn’t work.
Closes#1280
Closes#1249
Note that it is still unclear whether ack:ing a configure event for an
unmapped surface is a protocol violation, or something that should be
handled by the compositor.
According to
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/108,
Kwin, Mutter and Weston handles it, while wlroots does not.
If cells overflowed (for example, by using an italic font that isn’t
truly monospaced) into a double-width glyph (that itself is *not*
overflowing), then the double-width glyph would glitch when being
rendered; typically the second half of it would occasionally
disappear.
This happened because we tried to rasterize the second cell of the
double-width glyph. This cell contains a special “spacer”
value. Rasterizing that typically results the font’s “not available”
glyph.
If _that_ glyph overflows, things broke; we’d later end up forcing a
re-render of it (thus erasing half the double-width glyph). But since
the double-width glyph _itself_ doesn’t overflow, _it_ wouldn’t be
re-rendered, leaving it half erased.
Fix by recognizing spacer cells, and not trying to rasterize them (set
glyph count to 0, and cell count to 1).
Closes#1256
Key bindings with multiple key mappings share auxiliary data (e.g. the
command to execute in pipe-* bindings, or the escape sequence in
text-bindings).
The first one is the designated “master” copy. Only that one should be
freed.
This fixed a double-free on exit, with e.g.
[text-bindings]
\x1b\x23=Mod4+space Mod4+equal
Closes#1259
Ncurses added these in 2022-12-24, but they have been used/supported
by vim since 2017.
* BE - Bracketed paste Enable
* BD - Bracketed paste Disable
* PE - Paste Enable (i.e. "begin")
* PD - Paste Disable (i.e. "end")
The old default, wcswidth, simply calls wcswidth() on the grapheme
cluster. This was supposedly the implementation with the highest
application compatibility. Except we never even tried to measure
it. It was just assumed.
A lot of modern applications have better implementations. Let’s try to
push support for better emoji support by changing our default method
from wcswith to double-width.
While far from correct (it’s not based on the Unicode tables), the
‘double-width’ method produces accurate results anyway.
double-width is like wcswidth(), in that it adds together the
individual wcwidths of all codepoints in the grapheme cluster. But, it
limits the maximum width to 2.
This patch adds a new config option, font-size-adjustment.
It lets you configure how much the font size should be
incremented/decremented when zooming in or out (ctrl-+, ctrl+-).
Values can be specified in points, pixels or percent.
Closes#1188
* Both double and single quotes are recognized. There’s no difference
in how they are handled.
* The entire string must be quoted:
- “a quoted string” - OK
- quotes “in the middle” of a string - NOT ok
* Two escape characters are regonized:
- Backslash
- The quote character itself
Before this patch, hyperlinked cells were tagged with the “URL”
attribute (thus instructing the renderer to draw an
underline) *before* the grid was snapshot.
When exiting URL mode, the cells were once again updated, this time
removing the URL attribute.
But what if an escape sequence had modified the grid _while we were in
URL mode_? Depending on the sequence, it could move cells around in
such a way, that when exiting URL mode, the affected cells weren’t
updated correctly. I.e. we left some cells with the URL attribute
still set.
The fix is simple: tag cells in the snapshot:ed grid only (which isn’t
affected by any escape sequence received while in URL mode). Not in
the *actual* grid (which _is_ affected).
This fixes an issue where selections in the scroll margins were not
detected correctly. This meant they weren’t canceled as they should
have been, which in turn caused a visual glitch where text appeared to
be selected, but were in fact not.
The default foot output looks like this, in Debian testing "bookworm"
at the time of writing:
anarcat@angela:pubpaste$ foot true
info: main.c:421: version: 1.13.1 +pgo +ime +graphemes -assertions
info: main.c:428: arch: Linux x86_64/64-bit
info: main.c:440: locale: fr_CA.UTF-8
info: config.c:3003: loading configuration from /home/anarcat/.config/foot/foot.ini
info: fcft.c:338: fcft: 3.1.5 +graphemes -runs +svg(nanosvg) -assertions
info: fcft.c:377: fontconfig: 2.13.1, freetype: 2.12.1, harfbuzz: 5.2.0
info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Regular.otf: size=8.00pt/8px, dpi=75.00
info: wayland.c:1353: eDP-1: 2256x1504+0x0@60Hz 0x095F 13.32" scale=2 PPI=205x214 (physical) PPI=136x143 (logical), DPI=271.31
info: wayland.c:1509: requesting SSD decorations
info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Bold.otf: size=24.00pt/32px, dpi=96.00
info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Regular.otf: size=24.00pt/32px, dpi=96.00
info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Bold.otf: size=24.00pt/32px, dpi=96.00
info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Regular.otf: size=24.00pt/32px, dpi=96.00
info: terminal.c:700: cell width=19, height=39
info: terminal.c:588: using 16 rendering threads
info: wayland.c:859: using SSD decorations
info: main.c:680: goodbye
anarcat@angela:pubpaste$
That's 17 lines of output that are *mostly* useless for most use
cases. I might understand having this output during the project's
startup, when it's helpful for diagnostics, but now Foot just mostly
works everywhere, and I've never had a use for any of that stuff in
the (arguably short) time I've been using Foot so far.
And if I do, there's the `--log-level` commandline option to tweak
this. At first, I looked at tweaking the log level through the config
file. But as explained in this issue:
https://codeberg.org/dnkl/foot/issues/1142
... there's a chicken and egg problem there that makes it hard to
implement and possibly confusing for users as well.
There's also the possibility for users to change the shortcut with
which they start foot, for example a `.desktop` file so that menu
systems that support those start foot properly. But that only works in
that environment, and not through the so many things that will just
call `foot` and hope it will do the right thing.
In my case, I have `foot` hardcoded in a lot of places now, between
sway and waybar, and this is only going to grow. Others have suggested
adding the flag to a $TERMINAL global variable, but that won't help
.desktop users.
So, instead of playing whack-a-mole with the log levels, just make it
so that, by default, foot is silent. This is actually one of the
[basics of UNIX philosophy][1]:
> Rule of Silence: When a program has nothing surprising to say, it
> should say nothing.
And yes, I am aware I am severely violating that principle by writing
a way too long commit log for a one-line patch, but there you go, I
figured it was good to document the why of this properly.
[1]: https://web.archive.org/web/20031102053334/http://www.faqs.org/docs/artu/ch01s06.html
If an output has a bogus physical width or height, the DPI can become
so high that the cell width/height is too large for
pixman_image_fill_rectangles(), resulting in a crash in pixman_fill().
Since it doesn’t make any sense to use a DPI that is obviously bogus,
don’t. Force it 96 instead.
When drawing a block cursor using inversed fg/bg colors, we didn’t
strip the alpha from the background color. This meant that the text
"behind" the cursor was rendered with transparency. If alpha was set
to 0, the text was completely invisible.
We should never apply alpha to the text color. So, detect this, and
force alpha to 1.0.
Normally, when selecting the cursor’s color, we don’t really know
_where_ the background color is coming from (or more accurately,
_what_ it is).
However, the *only* background color that can have a non-1.0 alpha is
the *default* background color.
This is why we can ignore the bg parameter, and use term->colors.fg/bg
instead.
Closes#1205