But appears to have been allowed in older versions of meson.
Fixes an issue where foot’s version was always reported as the last
stable release, even though it was a git build.
Shift+Tab is an odd bird in XKB; it produces a shifted variant of tab,
ISO_Left_Tab, with Shift being a consumed modifier.
From a terminal perspective, Tab and ISO_Left_Tab are the same key,
with Shift+Tab generating ‘CSI Z’, and all other combos generating a
‘CSI 27;mods;9~’ escape.
Before, when we didn’t filter out consumed modifiers, we could simply
re-use the keymap for Tab when translating ISO_Left_Tab.
This is no longer possible, since shift has been filtered out. As a
result, Shift+Tab no longer generated ‘CSI Z’, but ‘\t’. I.e as if
shift wasn’t being pressed.
This patch adds a separate keymap table for ISO_Left_Tab. It’s MOD_ANY
entry corresponds to Shift+Tab, and emits ‘CSI Z’. All its other
entries *exclude* shift (since it has been consumed), *but*, the
encoded modifier (in the escape sequences) *include* shift.
This requirement is due to the recently added maybe_repair_key_combo()
function, which is making use of xkb_keymap_key_get_mods_for_level().
See also: commit a5b554761a.
Foot has, up until now, used a fixed image size when the application
used DECGRA (Raster Attributes) to “configure” the image size.
This was based on a misunderstanding, that this was how you emitted
sixels where the height was *not* a multiple of 6.
This isn’t the case. The VT340 documentation is actually pretty clear
about this:
Ph and Pv do not limit the size of the image defined by the sixel
data. However, Ph and Pv let you omit background sixel data from the
image definition and still have a color background. They also
provide a concise way for the application or terminal to encode the
size of an image.
This is also how XTerm behaves. Test image:
\EPq
"1;1;1;1
#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0
#1~~@@vv@@~~@@~~$
#2??}}GG}}??}}??-
#1!14@
\E\
This uses DECGRA to set the image size to 1x1. The sixel however
is *not* clipped to 1x1, but is resized to 14x12
The ‘proto_chars’ variable is kind of like a FIFO, where characters
from the grid is pushed to the back of it. I.e. the last <n> bytes are
at the *end* of the array.
This was what the protocol matching logic expected. However, it was
only true after reading ‘max_prot_len’ characters from the
grid. Before that, the last <n> bytes from the grid was in
the *beginning* of ‘proto_chars’.
This meant we did not detect URLs starting in the top left corner of
the viewport. Test case:
foot sh -c "echo http://test.com && sleep 9999"
If a user-provided key combo contains both an explicit modifier, and
the shifted symbol it produces, replace the symbol with its un-shifted
version.
Example: Control+Shift+U contains both ‘Shift’, and ‘U’, where ‘Shift’
is the modifier that shifts ‘u’ to ‘U’.
Such modifiers are “consumed”, i.e. filtered out, when matching key
combos. As such, Control+Shift+U will never trigger since we’ll never
be able to match the consumed modifier ‘Shift’.
The above combo can be written in two ways:
- Control+U
- Control+Shift+u
To be able to detect that Control+Shift+U is an invalid combination,
we need to check all *shifted* symbols for all key *codes*.
Once we’ve detected a shifted symbol (and where it differs from the
un-shifted symbol), we loop all modifier sets that produce the shift
level where our shifted symbol is. For each such set, check if it
intersects with the user-provided key combo’s modifier set.
If there is an intersection, it means the user provided a key combo
containing a modifier and symbol, such that the modifier is consumed
when the symbol is produced.
In this case, we replace the symbol with its un-shifted version.
Bindings are matched in one out of three ways:
* By translated (by XKB) symbols
* By untranslated symbols
* By raw key codes
A translated symbol is affected by pressed modifiers, some of which
can be “consumed”. Consumed modifiers to not partake in the comparison
with the binding’s modifiers. In this mode, ctrl+shift+2 maps to
ctrl+@ on a US layout.
Untranslated symbols, or un-shifted symbols refer to the “base” symbol
of the pressed key, i.e. it’s unaffected by modifiers. In this mode,
consumed modifiers *do* partake in the comparison with the binding’s
modifiers, and ctrl+shift+2 maps to ctrl+shift+2 on a US layout.
More examples: ctrl+shift+u maps to ctrl+U in the translated lookup,
while ctrl+shift+u maps to ctrl+shift+u in the untranslated lookup.
Finally, we also match raw key codes. This allows our bindings to work
using the same physical keys when the user switches between latin and
non-latin layouts.
This means key bindings in foot.ini *must* not include both +shift+
and a *shifted* key. I.e. ctrl+shift+U is not a valid combo as it
cannot be triggered. Unfortunately, this was how you were supposed to
write bindings up until now... so, we try to detect such bindings, log
a deprecation warning and then “fix” the binding for the user.
When specifying bindings in foot.ini, both ctrl+U and ctrl+shift+u are
valid, and will work. The latter is preferred though, since we cannot
detect the raw key code for the former variant. Personally, I also
prefer the latter one because it is more explicit; it’s more obvious
which keys are involved.
However, in some cases it makes more sense to use the other
variant. Typically for non-letter combos.
Fixes log spamming in Sway:
00:54:07.780 [DEBUG] [wlr] [types/wlr_text_input_v3.c:181] Text input commit received without focus
00:54:07.780 [INFO] [sway/input/text_input.c:127] Inactive text input tried to commit an update
Closes#384
In a recent Debian build from master, Lintian complained about a bad
whatis entry for this manual page. The tag description [1] says a NAME
section is required. It is added here.
[1] https://lintian.debian.org/tags/bad-whatis-entry.html
When sixel scrolling is disabled (private mode 80 is off), and scroll
margins have been set, XTerm seems to ignore the top margin (sixel
still begins at (0,0)), but does not go past the bottom margin.
This patch implements the same behavior in foot.
When enabled (the default), sixels behave much like normal output; the
start where the cursor is, and the cursor moves with the
sixel. I.e. after emitting a sixel the cursor is left after the image;
either to the right, if private mode 8452 is enabled, or otherwise on
the next line. Terminal content is scrolled up if the sixel is larger
than the screen.
When disabled, sixels *always* start at (0,0), the cursor never moves,
and the terminal content never scrolls.
In other words, the ‘disabled’ mode is a much simpler mode.
All we need to do to support both modes is re-write the sixel-emitting
loop to:
* break early if we’re “out of rows”, i.e. we’ve reached the bottom of
the screen.
* not linefeed, or move the cursor when scrolling is disabled
This patch also fixes a bug in the (new) implementation of private
mode 8452.
When emitting a sixel, we may break it up into smaller pieces, to
ensure a single sixel (as tracked internally) does not cross the
scrollback wrap-around.
The code that checked if we should do a linefeed or not, would skip
the linefeed on the last row of *each* such sixel piece. The correct
thing to do is to skip it only on the last row of the *last* piece.
I chose not to fix this bug in a separate patch since doing so would
have meant re-writing it again when implementing private mode 80.
Clear scroll damage and damage the entire viewport before entering URL
mode. This will cause us to do a full screen redraw both when entering
URL mode, and later when exiting it.
Clearing the scroll damage is necessary to ensure we don’t apply it
twice (once for the snapshot:ed grid, and later again for the real
grid), as that would result in an incorrect pixmap.
But, since we’ve cleared the scroll damage, we need to damage the
entire view to ensure we redraw the contents correctly.
This ensures the “last cursor” cell is re-drawn (without a cursor, if
the cursor has moved), both in the snapshot:ed grid, and later, when
we switch back to the real grid.
We must also be careful and reset term->render.last_cursor.row
both when *entering* and *leaving* URL mode, to ensure it doesn’t
point to an invalid row.
Previously, we automatically exited URL mode whenever we received data
on the PTY. This was done since we don’t know _what_ has changed on
the screen, and we don’t want to display misleading jump labels.
However, this becomes a problem in curses-like applications that
periodically updates part of the screen. For example, a statusbar with
a clock.
This patch changes this behavior; instead of cancelling URL mode when
receiving PTY data, we snapshot the grid when entering URL mode.
When *rendering*, we use the snapshot:ed grid, while PTY updates
modify the “real” grid.
Snapshot:ing the grid means taking a full/deep copy of the current
grid, including sixel images etc.
Finally, it isn’t necessary to “damage” the entire view
when *entering* URL mode, since we’re at that point the renderer is in
sync with the grid. But we *do* need to damage the entire view when
exiting URL mode, since the grid changes on the “real” grid hasn’t
been tracked by the renderer.