When calculating where in the scrollback history we are, we previously
did this against the total number of scrollback lines. I.e. the
`scrollback.lines` setting in `footrc`.
Now, we count only the used/allocated scrollback lines.
Note that the initial indicator position might still seem to start a
bit high up, if the number of used scrollback lines is low. This is
because we use the *top* of the screen for the current position. Thus,
we'll never be at the bottom (except for the special case when
we're *really* at the bottom).
This can be set to 'none' (the default), 'osd', 'log' or 'both'.
When 'osd' is enabled, we'll render the frame rendering time to a
sub-surface after each frame.
When 'log' is enabled, the frame rendering time is logged on stderr.
The default is still to inverse the regular foreground/background
colors.
If the user sets *both* of the new options, selection-foreground and
selection-background, those colors will *always* be used for selected
cells, instead of inverting the regular foreground/background colors.
When enabled, the mouse cursor is hidden when the user types in the
terminal. It is un-hidden when the user moves the mouse, or when the
window loses keyboard focus.
Compiler, in release builds, complains about 'cell_count' "may be used
uninitialized". This isn't true, as it is initialized in every
possible switch case below.
But, make the compiler happy and zero-initialize it before the switch
statement.
When scrollback indicator has been enabled, and the viewport isn't at
the bottom, we now render a *static* indicator with the position in
percent.
We use the color scheme's blue color as background, and it's white
color as foreground. This is subject to change... Should maybe be
configurable as well.
The Wayland surface + sub-surface are instantiated on-demand, and
automatically destroyed when no longer used.
And turn it from a boolean to an enum. It can be set to:
* `none` - disables the indicator
* `static` - always rendered near the top of the window
* `moving` - position reflects the scrollback position
When printing a multi-column character, write CELL_MULT_COL_SPACER
instead of '0' to both padding cells (when character doesn't fit at
the end of the line), and to the cells following the actual character.
When applying scroll damage, we may have to re-render the
margins.
This is because when we SHM-scroll, we actually move the entire
surface, and thus we end up overwriting the top margin area with old
window content, and scroll in uninitialized memory in the bottom
margin.
But, we don't have to tell the compositor about this - the last frame
always contains correct margins; i.e. there's no change between the
last frame and current frame being rendered.
TODO: we _could_ micro-optimize and only damage the margins after a
surface resize. We do it slightly more often now, when dealing with
state changes in screen flash or scrollback searching. But I don't
think it's worth the effort.
Instead of locking the queue for each dirty row we append, and
signaling a condition variable, just keep the lock while going through
the visible rows.
Release the lock once done.
Since we take the lock *before* posting the 'start' semaphore, all
workers will be waiting for the lock to be released.
Then, one at a time they'll get the lock and pick a row to
render. The queue will never get empty - when all rows have been
rendered, each worker will pick a 'frame done' "job" from the queue,
and break the rendering loop.
Previously, we had to explicitly render the old cursor cell *before*
applying scrolling damage.
We then rendered all the dirty rows, *without* rendering the cursor -
even if the cursor cell was among the dirty rows.
Finally, when everything else was done, we explicitly rendered the
cursor cell.
This meant a lot of code, and unnecessary render_cell() calls, along
with unnecessary wl_surface_damage_buffer() calls.
This was a necessary in the early design of foot, but not anymore.
We can simply mark both the old cursor cell, and the current one, as
dirty and let the normal rendering framework render it. All we need to
do is pass the cursor column to render_row(), so that it can pass
has_cursor=true in the appropriate call to render_cell(). We pass -1
here for all rows, except the cursor's row, where we pass the actual
cursor column.
With this, there's no need to calculate whether the cursor is visible
or not; just mark it's cell as dirty, and if that row is visible, the
normal rendering will take care of it.
This also simplifies the state needed to be saved between two frames;
we only need a row pointer, and the cursor column index.
Part of https://codeberg.org/dnkl/foot/issues/35
When determining whether we should render a hollow block cursor,
i.e. to signal that we're unfocused, base the decision on the
terminals current keyboard focus, not visual focus.
* xcursor always set for all pointers
* xcursor sometimes not updated when it should be
* mouse grabbed state wasn't per seat, but global (i.e. "does at least
one seat enable mouse grabbing")
* selection enabled state wasn't per seat
The sixel images are sorted, that's true. But in order for our row
numer comparisons to actually work, we need to rebase all numbers
against the current scrollback offset (or, the scrollback *end*, to be
precise).
The sixel list is sorted, with the most recent images *first* in the
list (and thus the "oldest" images are at the back).
This means we can break out of the loop when we see a sixel
that *ends before* the current view starts.
As a minor optimization, we also recognize sixels that *start after*
the current view ends. We can't break out of the loop, but we can skip
trying to render them (they wouldn't have been rendered, but more work
would have been done in render_sixel() to reach this conclusion).
This used to work before because we had a "global" clip region on the
text area, excluding the margins.
When we introduced per-cell clipping, this global clip region was
removed, and the background drawing code could now overflow into the
margins.
This fixes it by setting the cell clip region not just when rendering
a glyph, but before we render the cell background.