Instead of passing a raw wl_surface pointer, pass a wayl_surface
pointer.
This is needed later, when using fractional scaling to scale the
surface (since then we need the surface’s viewport object).
And add a viewport object to accompany the surface (to be used when
scaling the surface).
Also rename the wl_surf_subsurf struct to wayl_sub_surface, and add a
wayl_surface object to it, rather than a plain wl_surface pointer (to
also get the viewport pointer).
* Bind the wp-viewporter and wp-fractional-scale-manager globals.
* Create a viewport and fractional-scale when instantiating a window.
* Add fractional-scale listener (that does nothing at the moment).
* Destroy everything on teardown.
When emitting a sixel, we need to:
a) scroll terminal content to ensure the new image fits
b) position the text cursor
Recent changes in the cursor positioning logic meant we reduced the
number of linefeeds, to ensure 1) sixels could be printed to the
bottom row without scrolling the terminal contents, and 2) the cursor
was positioned on the last sixel row.
Except, we’re not actually positioning the cursor on the last sixel
row. We’re positioning it on the text row that maps to the *upper*
pixel of the last sixel.
In most cases, this _is_ the last row of the sixel. But for certain
combinations of font and image sizes, it may be higher up.
This patch fixes a regression, where the terminal contents weren’t
scrolled up enough for certain images, causing a crash when trying to
dirty a not-yet scrolled in row.
The fix is this:
* Always scroll by the number of rows occupied by the image, minus
one. This ensures the image "fits".
* Adjust the cursor position, if necessary.
* 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