As of 2021-07-31, ncurses ships its own version of foot’s terminfo.
Since:
* It doesn’t have the non-standard Sync,Tc,setrgbf,setrgbb
capabilities.
* It doesn’t set hs,fsl,dsl (statusbar).
* We want to be able to update our termminfo without waiting for an
ncurses release.
* Foot should be installable and usable on Linux systems that doesn’t
have the latest ncurses.
we still want to ship our own version. We can however not install it
to the default terminfo location (e.g. /usr/share/terminfo), since it
will collide with the ncurses provided files.
Our options are to either rename our terminfo to something else, or to
keep the name, but install our terminfo files somewhere else.
The first option would be the easy one. However, I think it makes
sense to use the same name. For example, a user that SSH’s into a
remote system that does *not* have our own version installed,
but *does* have the ncurses one, will gracefully fall back to that
one, which is better than manually having to set
e.g. TERM=xterm-256color.
Now, if we want to use the same name, we need to install it somewhere
else. But where? And how do we ensure our version is preferred over
the ncurses one?
I opted to $datadir/foot/terminfo (e.g. /usr/share/foot/terminfo) by
default. It makes it namespaced to foot (i.e. we’re not introducing a
new “standard” terminfo location), thus guaranteeing it wont collide
with ncurses.
To enable applications to find it, we export TERMINFO_DIRS. This is a
list of *additional* directories to search for terminfo files. If it’s
already defined, we *append* to it.
The nice thing with this is, if there’s no terminfo in that
location (e.g. when you SSH into a remote), the default terminfo
location is *also* searched. But only *after* having searched through
TERMINFO_DIRS.
In short: our version is preferred, but the ncurses one (or an older
version of our terminfo package!) will be used if ours cannot be
found.
To enable packagers full control over the new behavior, the existing
meson command line options have been modified, and a new option added:
-Dterminfo=disabled|enabled|auto: *build* and *install* the terminfo
files.
-Dcustom-terminfo-install-location=<path>: *where* the terminfo files
are expected to be found.
This *needs* to be set *even* if -Dterminfo=disabled. For example, if
the packaging script builds and packages the terminfo files separate
from the regular foot build. The path is *relative to $prefix*, and
defaults to $datadir/foot/terminfo.
This is the value that will be appended to TERMINFO_DIRS. Note that
you can set it to ‘no’, in which case foot will *not* set/modify
TERMINFO_DIRS. Only do this if you don’t intend to package foot’s
terminfo files at all (i.e. you plan on using the ncurses ones only).
-Ddefault-terminfo=foot. Allows overriding the default TERM
value. This should only be changed if the target platform doesn’t
support terminfo files.
Closes#671
term_cursor_blink_update() is called when the visual focus changes
state (i.e. when our top-level surface is activated de-activated).
Checking keyboard focus worked on Sway, but on e.g. GNOME, the order
in which keyboard focus and visual focus are updated is different, and
we ended up either making the cursor invisible, or visible, but not
blinking, when changing focus back to the window.
Closes#686
Before this patch, pt-or-px values, like letter-spacing, were *always*
scaled using the current DPI value.
This is wrong; if the fonts are scaled using the output’s scaling
factor, then so should all other point values.
This also fixes an issue where e.g. letter-spacing would use one DPI
value at startup, but then when increasing/decreasing or resetting the
font size, would be re-calculated using a different DPI value, leading
to completely different spacing.
This happened when there were multiple monitors, with different DPI
values, and foot guessed the initial DPI value wrong. Normally, foot
would correct itself as soon as the window was mapped, and the
“correct” DPI value known. But if the fonts were scaled using the
scaling factor, it was possible that the font reload never happened.
This patch also updates the thickness calculation (for LIGHT and HEAVY
box drawing characters) to use the scaling factor when appropriate.
Closes#680
This fixes an issue where the left-most column of a sixel was
“overwritten” by the cell content.
This patch also rewrites the prepass logic, to try to reduce the
number of loads performed.
The new logic loops each row from left to right, looking for dirty
cells. When a dirty cell is found, we first scan backwards, until we
find a non-overflowing cell. That cell is unaffected by the
overflowing cell we’re currently dealing with.
We can also stop as soon as we see a dirty cell, since that cell will
already have been dealt with.
Then, we scan forward, dirtying cells until we see a non-overflowing
cell. That first non-overflowing cell is also dirtied, but after that
we break.
The last loop, that scans forward, advances the same cell pointer used
in the outer loop.
We now emit button 6/7 events (when the client application grabs the
mouse). This buttons map to mouse wheel horizontal scroll events. Or, left/right
tilting, if you like.
Wayland report these as ‘axis’ events (just like regular scroll wheel events),
and thus we need to translate those scroll events to button events.
libinput does not define any mouse buttons for wheel tilts, so we add our own
defitions. These are added last in the BTN_* range, just before the BTN_JOYSTICK
events.
ncurses has had a bug where mouse support is completely disabled if the terminfo
didn’t have kmous=\E[M, *or*, the terminfo *name* contained ‘xterm’.
This appears to have been fixed.
Thus, change kmous to \E[<, and set xm/XM accordingly. With this, ncurses
application will use the SGR mouse reporting mode, instead of the legacy
reporting mode.
If the call to fdm_wayl() with EPOLLHUP was followed by calls to
wayl_roundtrip(), foot would hang.
The reason for this is that the EPOLLHUP handler in fdm_wayl() would
call wl_display_cancel_read().
wayl_roundtrip() also calls wl_display_cancel_read() (since we
normally have called wl_display_prepare_read()), before calling
wl_display_roundtrip().
When calling wl_display_cancel_read() two times in a row, without a
wl_display_prepare_read() in between, wl_display_roundtrip() hangs.
Fix by not calling wl_display_cancel_read() in fdm_wayl(). This
ensures our invariant holds: wl_display_prepare_read() is *always* in
effect outside of fdm_wayl().
Closes#651
While we’re in scrollback search mode, the selection may be
cancelled (for example, if the application is scrolling out the
selected text). Trying to e.g. extend the search selection after this
has happened triggered a crash.
This fixes it by simply resetting the search match state when the
selection is cancelled.
Closes#644
Add stubs for shm_chain_new(), shm_chain_free() and shm_unref(). This
fixes ‘pgo’ linking failures in the ‘generate’ phase when doing a PGO
build with clang.
Closes#642
This patch adds a `confined` flag to each cell to track if the last
rendered glyph bled into it's right neighbor. To keep things simple,
bleeding into any other neighbor cell than the immediate right one is
not allowed. This should cover most use cases.
Before rendering a row we now do a prepass and mark all cells unclean
that are affected by a bleeding neighbor. If there are consecutive
bleeding cells, the whole group must be re-rendered even if only a
single cell has changed.
The patch also deprecates both old overflowing glyph options
*allow-overflowing-double-width-glyphs* and *pua-double-width* in favor
of a single new one named *overflowing-glyphs*.
If we have lots of URLs, we use up a *lot* of SHM buffers (and thus
pools). Each and every one is a single mmap(), of at least 4K.
Since all URL labels are created and destroyed at the same time, it
makes sense to use a single pool for all buffers.
To do this, we must now do two passes; first one to generate the
actual string (label content), and to calculate the label sizes.
Then we use this information to allocate all SHM buffers at once, from
the same pool.
Finally, we iterate the URLs again, this time to actually render them.
There has been some confusion whether enabling DECSDM (private mode
80) enables or disables sixel scrolling.
Foot currently enables scrolling when DECSDM is set, and this patch
changes this, such that setting DECSDM now *disables* scrolling.
The confusion is apparently due to a documentation error in the VT340
manual, as described in
https://github.com/dankamongmen/notcurses/issues/1782#issuecomment-863603641.
And that makes sense, in a way: the SDM in DECSDM stands for Sixel
Display Mode. I.e. it stands to reason that enabling that disables
scrolling.
Anyway, this lead to https://github.com/hackerb9/lsix/issues/41, where
it was eventually proven (by testing on a real VT340), that foot, and
a large number of other terminals (including XTerm) has it wrong:
https://github.com/hackerb9/lsix/issues/41#issuecomment-873269599.
When tagging URL cells (in preparation for rendering URL mode), we
loop the URL’s entire range, setting the `url` attribute of all cells,
and dirtying the rows.
It is possible to create URLs that are invalid, and wrap around the
scrollback, even though the scrollback hasn’t yet been filled. For
example, by starting an OSC-8 URL, moving the cursor, and then closing
the OSC-8 URL.
These URLs are invalid, but are still rendered just fine. “Fine” being
relative - they will typically fill the entire screen. But at least
that’s a very clear indication for the user that’s something is wrong.
The problem is when we hit un-allocated scrollback rows. We didn’t
check for NULL rows, and crashed.
This has now been fixed.
Removing overlaping and duplicated URLs is done by running two nested
loops, that both iterate the same URL list.
When a duplicate is found, one of the URLs is destroyed and removed
from the list.
Deleting and removing an item *is* safe, but only as long as _no
other_ iterator has references to it.
In this case, if we remove an item from e.g. the inner iterator, we’ll
crash if the outer iterator’s *next* item is the item being removed.
Closes#627
Unlike other surface types, the SHM cookie depends on the address of
each URL instance. This means if we enable, disable, and then enable
URL mode again (thus showing exactly the same URLs as the first time),
the URLs will have new addresses, and thus the old SHM pixmaps will
not get purged automatically.
So, manually purge them when destroying the URLs.
That is, instead of requiring a ‘\n’ to be printed, non-empty lines
are now treated as having a hard linebreak by default.
The linebreak is cleared on an explicit wrap.
A narrow, but offset:ed glyph should still be considered double
width.
This patch also fixes a crash, when the maybe-double width glyph is in
the last column. This is a regression.