There were two errors:
* We subtracted half the line width instead of adding it to the
baseline
* We rounded the line positioning and thickness before the positioning
calculation. In particular, rounding the thickness before using it
to adjust the position was wrong. Now we round just before the
pixman call.
This is what we used as baseline for regular glyphs anyway. Thus, we
can update that code to call font_baseline() now. This makes it easier
to change how we define the baseline in the future.
When the user had configured the cursor color, we failed to
invert (reverse) the foreground and background color when the cursor
was on a cell with the 'reverse' attribute set.
When doing "small" scrolls (typically done via mouse wheel or
similar), we render the scrolling by emitting a "scroll damage".
A recent commit changed how scroll damage is rendered; only when the
view is at the bottom ("following" the screen output) do we render the
damage.
To fix this, add a new type of scroll damage,
SCROLL_DAMAGE_IN_VIEW and SCROLL_DAMAGE_REVERSE_IN_VIEW.
These signal to the renderer that it should always render the damage.
Since we now initialize the worker threads from term_init(), which
returns before the threads terminate, we can no longer use
stack-allocated worker contexts.
We _could_ put them in the terminal struct. But a simpler solution is
to allocate them in term_init(), and let the threads free them when
they don't need them anymore.
When user has scrolled back in the output history, new output should
not trigger scrolling.
This was true for normal cell rendering, which renders the cells *in
view*, not caring where the "front" of the output is.
However, we still applied scroll damage. I.e. we memmoved part of the
screen.
The fix is simple; only apply scroll damage when the view is at the
front of the output.
We do however need access to it, so provide a pointer. The difference
is that now we can have a *single* wayland instance, but multiple
terminal instances.
Short term, we want to break out the wayland backend from the terminal
struct. Long term, we might want to support multiple windows.
One step towards both the above is separating global wayland objects
from per-window objects.
Not all compositors support buffer re-use. I.e. they will call the
frame callback *before* the previous buffer has been
released. Effectively causing us to swap between two buffers.
Previously, this made us enter an infinite re-render loop, since we
considered the window 'dirty' (and in need of re-draw) when the buffer
is different from last redraw.
Now, we detect the buffer swapping case; size must match, and we must
not have any other condition that require a full repaint.
In this case, we can memcpy() the old buffer to the new one, without
dirtying the entire grid. We then update only the dirty cells (and
scroll damage).
Note that there was a bug here, where we erased the old
cursor *before* checking for a new buffer. This worked when the buffer
had *not* changed.
Now that we need to handle the case where it *has* changed, we must do
the memcpy() *before* we erase the cursor, or the re-painted cell is
lost.
This makes foot work on Plasma, without burning CPU. The memcpy() does
incur a performance penalty, but we're still (much) faster than
e.g. konsole. In fact, we're still mostly on par with Alacritty.
This ensures we always have a valid (but possibly incorrect) scaling
value. This allows us to simplify code that uses the scale - it
doesn't have to verify the scale if valid.
Furthermore, since render_resize() is the function that actually
updates term->scale, make sure to call it *before* updating the
cursor (otherwise, the cursor will use the old scaling value).
Use the 'yellow' color from the 'regular' range of colors (SGR 33) for
background when we have a match, or 'red' from the 'regular' range of
colors (SGR 31) when we don't have a match.
Foreground uses the 'black' color from the regular range of
colors (SGR 30).
The old baseline calculation was copy-pasted to a couple of places,
and also assumed that the font's height was equal to ascent+descent.
While this is typically true, it isn't necessarily so.
Now, we assume that height >= ascent+descent, and then position the
baseline in "center" (but adjusted for the descent).
This adds a new state, 'is_searching'. While active, input is
re-directed, and stored in a search buffer. In the future, we'll use
this buffer and search for its content in the scrollback buffer, and
move the view and create a selection on matches.
When rendering in 'is_searching', everything is dimmed. In the future,
we'll render the current search buffer on-top of the dimmed "regular"
terminal output.
With this assumption, we can replace 'a % b' with 'a & (b - 1)'. In
terms of instructions, this means a fast 'and' instead of a slow
'div'.
Further optimize scrolling by:
* not double-initializing empty rows. Previously, grid_row_alloc()
called calloc(), which was then followed by a memset() when
scrolling. This is of course unnecessary.
* Don't loop the entire set of visible rows (this was done to ensure
all visible rows had been allocated, and to prefetch the cell
contents).
This isn't necessary; only newly pulled in rows can be NULL. For
now, don't prefetch at all.