The row numbers in the tracking points are in absolute
numbers. However, when we walk the old grid, we do so starting in the
beginning of the scrollback history.
We must ensure the tracking points are sorted such that the *first*
one we see is the “oldest” one. I.e. the one furthest back in the
scrollback history.
Instead of iterating a linked list of tracking points, for *each and
every* cell in the old grid, use a sorted array.
This allows us to step through the array of tracking points as we walk
the old grid; each time we match a tracking point, we move to the next
one.
This means we only have to check a single tracking point for each cell.
Calling wcwidth() on every character in the entire scrollback history
is slow.
We already have the character width encoded in the grid; it’s in the
CELL_SPACERs following a multi-column character.
Thus, when we see a non-SPACER character, that isn’t in the last
column, peek the next character. If it’s a SPACER, get the current
characters width from it.
The only thing we need the width for, is to be able to print padding
SPACERS in the right margin, if the there isn’t enough space on the
current row for the current character.
Instead of using CELL_SPACER for *all* cells that previously used
CELL_MULT_COL_SPACER, include the remaining number of spacers
following, and including, itself. This is encoded by adding to the
CELL_SPACER value.
So, a double width character will now store the character itself in
the first cell (just like before), and CELL_SPACER+1 in the second
cell.
A three-cell character would store the character itself, then
CELL_SPACER+2, and finally CELL_SPACER+1.
In other words, the last spacer is always CELL_SPACER+1.
CELL_SPACER+0 is used when padding at the right margin. I.e. when
writing e.g. a double width character in the last column, we insert a
CELL_SPACER+0 pad character, and then write the double width character
in the first column on the next row.
Only enable XDG activation when compiling against wayland-protocols
1.21. Older versions don’t have this protocol.
When available, define HAVE_XDG_ACTIVATION.
Make all usages of xdg_activation_v1 and xdg_activation_token_v1
conditional.
While skimming this doc, I noticed that "-Dterminfo" wasn't rendering
properly as it was lacking its closing backquote.
While at it, tweak the Arch wiki link, as it redirects to replace
/index.php with /title.
In some cases, the underline position (typically provided by the font,
mind you), end up below the cell, making it visible.
Note that below the cell here means below the line. I.e. the font
provided underline position is below the font provided line height...
Oh well.
Doing this in foot rather than fcft, since other applications
typically don’t have to clip the rendered text.
Closes#503
Older version of Plasma/KWin had an issue where buffer damage recorded
before the buffer was attached were ignored. This appears to have been
fixed now.
* Break out cursor cell dirtying to separate functions
* Break out handling of double buffering
* Handle buffers with age > 1 (we’re swapping between more than 2
buffers)
* Detect full screen repaints, and skip re-applying old frame’s damage
* Use an allocated array insted of a tll list for old frame’s scroll damage
* When logging frame rendering time, including the amount used for
double buffering.
When re-applying the previous frame’s damage (due to us being forced
to double buffer), subtract the current frame’s damage from the
region-to-copy when there’s no scroll damage on the current frame.
When the current frame doesn’t have any scroll damage, the current
frame’s damage is in the same coordinate system as the previous
frame’s damage, and we can safely remove it from the region we copy
from.
When we are forced to swap between two buffers, re-apply the old
frame’s damage to the current buffer, before applying the current
frame’s damage.
First, while applying this frame’s scroll damage, copy it to the
buffer’s scroll damage list (so that we can access it via
term->render.last_buf).
Also, when iterating and rendering the grid, build a pixman region of
the damaged regions. This is currently done on a per-row basis. This
is also stored in the buffer.
Now, when being forced to double buffer, first iterate the old
buffer’s damage, and re-apply it to the current buffer. Then,
composite the old buffer on top of the current buffer, using the old
frame’s damage region as clip region. This effectively copies
everything that was rendered to the last frame. Remember, this is on a
per-row basis.
Then we go on and render the frame as usual.
Note that it would be _really_ nice if we could subtract the current
frame’s damage region from the clip region (no point in copying areas
we’re going to overwrite anyway). Unfortunately, that’s harder than it
looks; the current frame’s damage region is only valid *after* this
frame’s scroll damage have been applied, while the last frame’s damage
region is only valid *before* it’s been applied.
Translating one to the other isn’t easy, since scroll damage isn’t
just about counting lines - there may be multiple scroll damage
records, each with its own scrolling region. This creates very complex
scenarios.
By default, age all matching buffers that are busy (i.e. in use by the
compositor).
This allows us to detect whether we can apply the current frame’s
damage directly, or if we need to prepare the buffer first (e.g. copy
old buffer, or re-apply last frame’s damage etc).
1. Free buffers and strings
2. memset() the vt struct
3. re-initialize members that must not be zero
We _could_ replace the memset() with explicit zeroing of all the
members. It’s just that there’s a lot of arrays, so this is much
easier.
Closes#495