The line break flag is used by the text reflow and text
extraction (i.e. copy-paste) logic, to determine whether or not to
insert a newline between two lines.
There’s some amount of heuristics involved in this. For example, the
client application could emit a newline, move the cursor back up, and
print text. What does that mean for us?
Foot’s behavior up until now has been this:
The line break flag is set on the row, when the application emits an
explicit linefeed. The flag is cleared when the line is erased. But
otherwise not.
This meant that emitting a linefeed and then moving the cursor back up
and printing text, did not clear the line break flag. This in turn
meant that text copied always had newlines inserted, even though that
was not the client applications intention.
By clearing the line break flag whenever _anything_ is printed to a
row, the new behavior is, in practice, that the line break flag is
only set on a row if a linefeed was that *last* thing printed to that
row.
Closes#410
When the user has set a custom line-height, we now adjust it when
increasing/decreasing (“zooming”) the font size at run-time.
Previously, the line-height was fixed at the size specified in
foot.ini.
When detecting, and repairing, “broken” key bindings (where the key
binding itself explicitly lists a modifier that is consumed by the
final symbol - e.g “Shift+W”), don’t just look for an intersection
between the set of modifiers needed to produce the final symbol, and
the modifiers listed in the key combo. Instead, check if the key combo
has *all* the required modifiers.
Example: Shift+AltGr+w produces Page_Down. I.e. Page_Down is the
_shifted_ symbol, ‘w’ is the un-shifted symbol, and Shift+AltGr are
the modifiers required to shift ‘w’ to Page_Down.
If we have the key combo Shift+Page_Down, foot would, correctly,
determine that Page_Down is a shifted symbol. It would find the
Shift+AltGr modifier set, and since the intersection of “Shift+AltGr”
and “Shift” (from our key combo) is non-empty, foot
would (incorrectly) determine that we can, and should, replace
Page_Down with its un-shifted symbol ‘w’.
This is completely wrong, since Shift+w does _not_ produce Page_Down.
Closes#407
* use toe for terminfo, thanks Craig.
* adds optional dependency on bash-completion for positional arguments
Co-authored-by: Craig Barnes <craigbarnes@protonmail.com>
term_print() is called whenever the client application “prints”
something to the grid. It is called for both ASCII and UTF-8
characters, and needs to handle sixels, insert mode and ASCII
vs. graphical charsets.
Since it’s on the hot path, this becomes unnecessarily slow.
This patch adds a “fast” version of term_print(), tailored for the
common case: ASCII characters in non-insert mode, without any sixels
and non-graphical charsets.
A new function, term_update_ascii_printer(), has been added, and must
be called whenever:
* The currently selected charset *index* changes
* The currently selected charset changes (from ASCII to graphical, or
vice verse)
* Sixels are added to the grid
* Sixels are removed from the grid
* Insert mode is enabled/disabled
This avoids a call to sixel_overwrite_by_row() (where we also exit
early if the image list is empty).
This saves a couple of instructions to set up the arguments for
sixel_overwrite_by_row().
“current geometry” will report whatever value is the smallest; the max
geometry or the current window size.
But “max geometry” always returns the configured max geometry.
This aligns foot’s behavior with XTerm.
After emitting multiple color bands for each sixel row, the increased
amount of sixel data shifted the balance in the profiling data,
causing a performance regression in regular ASCII handling.
Closing it as soon as we detect that the client has died, means we may
not have drained it completely.
The PTY is either closed _by_ the client application, or by us when we
shutdown the terminal. Thus, leaving it open (until we call
term_shutdown()) is fine.
When P2=1, empty pixels are transparent.
This patch also changes the behavior of P2=0|2, from setting empty
pixels to the default background color, to instead use the *current*
background color.
To implement this, a couple of changes are needed:
* Sixel pixels always use alpha=1.0, except for *empty* cells when
P2=1 (i.e. transparent pixels).
* The renderer draws sixels with the OVER operator, instead of the SRC
operator.
* The renderer *must* now render the cells beneath the sixel. As an
optimization, this is only done for sixels where P2=1. I.e. for
fully opaque sixels, there’s no need to render the cells beneath.
The sixel renderer isn’t yet hooked into the multi-threaded
renderer. This means *rows* (not just the cells) beneath
maybe-transparent sixels are rendered single-threaded.
Closes#391.
This ensures we don’t trim off bottom rows in unhook().
This could happen either because the application used “Set Raster
Attributes” to configure an image size larger than the sixels later
emitted.
Or, the last sixel row contains empty pixel rows.
In either case, the size set with “Set Raster Attributes” defines
the *minimum* image size; the image may still end up being larger.