Commit graph

907 commits

Author SHA1 Message Date
Daniel Eklöf
8967dd9cfe
input: add new Unicode input mode
This mode is activated through the new key-bindings.unicode-input and
search-bindings.unicode-input key bindings.

When active, the user can “build” a Unicode codepoint by typing its
hexadecimal value.

Note that there’s no visual feedback in this mode. This is
intentional. This mode is intended to be a fallback for users that
don’t use an IME.

Closes #1116
2022-07-29 09:26:31 +02:00
Daniel Eklöf
fa2d9f8699
selection: rework how we update a selection
Before this patch, each selection update would result in grid covered
by the selection being walked *three* times. First to “premark” the
area that *will* be selected after the update, then again to unmark
the previous selection (excluding the cells that were premarked - but
the cells are still iterated), and then one more time to finalize the
selection state in the grid.

Furthermore, each time a frame is rendered, the entire selection were
iterated again, to ensure all the cells have their ‘selected’ bit
set.

This quickly gets *very* slow.

This patch takes a completely different approach. Instead of looking
at the selection as a range of cells to iterate, we view it as an
area, or region. Thus, on each update, we have to regions: the region
representing the previous selection, and the region representing the
to-be selection.

By diffing these two regions, we get two new regions: one that
represents the cells that were selected, but aren’t any more, and one
that represents the cells that previously were not selected, but now
will be.

We implement the regions using pixman regions. By subtracting the
current selection from the previous selection, we get the region
representing the cells that are no longer selected, and that should be
unmarked.

By subtracting the previous selection from the current, we get the
region representing the cells that was added to the selection in this
update, and that should be marked.

selection_dirty_cells() is rewritten in a similar manner. We create
pixman regions for the selection, and the current scrollback view. The
intersection represents the (selected) cells that are visible. These
need to iterated and marked as being selected.

Closes #1114
2022-07-28 21:06:58 +02:00
Daniel Eklöf
b8506bbea0
selection: extend: use scrollback relative coordinates
When extending a selection, we determine *how* to extend it (which
endpoint to move, and whether to grow or shrink the selection) by
comparing the extension point with the old start and end coordinates.

For this to work correctly, we need to use scrollback relative
coordinates.

This fixes an issue where extending a very large selection (covering
many pages) sometimes shrunk the selection instead of growing it, or
just misbehaving in general.
2022-07-28 21:06:58 +02:00
Daniel Eklöf
a05eaf28bd
selection: selection_on_rows(): use scrollback relative coords
When checking if the current selection intersects with the
region (passed as parameter to the function), use scrollback relative
coordinates.

This fixes an issue where selections crossing the scrollback
wrap-around being misdetected, resulting in either the selection being
canceled while scrolling, even though it wasn’t scrolled out, or the
selection _not_ being canceled, when it _was_ scrolled out.
2022-07-28 21:06:57 +02:00
Daniel Eklöf
632c4839cd
search: find_next(): handle trailing SPACER cells
Make sure to increment match_end_col to account for trailing SPACER
cells after a match.

This fixes an issue where search matches weren’t highlighted correctly
when the match *ends* with a double-width character.
2022-07-28 21:05:06 +02:00
Daniel Eklöf
d79a3b9350
config: add colors.search-box-{no-,}match
Closes #1112
2022-07-28 19:02:56 +02:00
Daniel Eklöf
801970aa33
input: kitty: always treat composed characters as ‘printable’
Certain dead key combinations results different escape sequences in
foot, compared to kitty, when the kitty keyboard protocol is used.

        if (composed && is_text)
            key = utf32;
        else {
            key = xkb_keysym_to_utf32(sym_to_use);
            if (key == 0)
                return false;

            /* The *shifted* key. May be the same as the unshifted
             * key - if so, this is filtered out below, when
             * emitting the CSI */
            alternate = xkb_keysym_to_utf32(sym);
        }

If is_text=false, we’ll fall through to the non-composed
logic. is_text is set to true if the character is printable *and*
there aren’t any non-consumed modifiers enabled.

shift+space is one example where shift is *not* consumed (typically -
may be layouts where it is).

As a result, pressing ", followed by shift+space with the
international english keyboard layout (where " is a dead key) results
in different sequences in foot and kitty.

This patch fixes this by always treating composed characters as
printable.

Closes #1120
2022-07-28 19:02:25 +02:00
Daniel Eklöf
4abf46955f
keymap: change alt+escape to emit \E\E instead of a CSI 27 sequence
Closes #1105
2022-07-28 19:02:05 +02:00
Daniel Eklöf
87e4004960
csi: clamp color index for ‘CSI 38/48 ; 5 ; idx m’ sequences
Indexed color values are stored in the cell attributes as color
indices (into the 256-color table). However, the index from the CSI
was not validated in any way, meaning you can do something like this:

  echo -e ‘\e[38:5:1024m CRASH \e[m’

and foot will crash on an out-of-bounds access.

Fix by clamping the color index.

Closes #1111
2022-07-22 10:44:33 +02:00
Daniel Eklöf
d58290ea12
input: don’t ignore keyboard enter/leave events when there’s no keymap
The compositor _usually_ sends the keymap event *before* the enter
event. But not always.

Not (yet) having a keymap is not a reason to ignore the enter
event (now, on the other hand, getting a key press/release event
without a keymap is a compositor bug).

Closes #1097
2022-06-28 20:57:48 +02:00
Daniel Eklöf
2e4da6fbf6
selection: ignore drag-and-drops with unsupported mime-types
Specifically, make sure we do *not* call wl_data_offer_receive() with
a NULL mime-type, as this causes libwayland to error out, which in
turn causes foot to exit.

Closes #1092
2022-06-20 20:56:11 +02:00
Daniel Eklöf
bdb79e8b9f
osc: add support for OSC 133;A (prompt markers)
This patch adds support for the OSC-133;A sequence, introduced by
FinalTerm and implemented by iTerm2, Kitty and more. See
https://iterm2.com/documentation-one-page.html#documentation-escape-codes.html.

The shell emits the OSC just before printing the prompt. This lets the
terminal know where, in the scrollback, there are prompts.

We implement this using a simple boolean in the row struct ("this row
has a prompt"). The prompt marker must be reflowed along with the text
on window resizes.

In an ideal world, erasing, or overwriting the cell where the OSC was
emitted, would remove the prompt mark. Since we don't store this
information in the cell struct, we can't do that. The best we can do
is reset it in erase_line(). This works well enough in the "normal"
screen, when used with a "normal" shell. It doesn't really work in
fullscreen apps, on the alt screen. But that doesn't matter since we
don't support jumping between prompts on the alt screen anyway.

To be able to jump between prompts, two new key bindings have been
added: prompt-prev and prompt-next, bound to ctrl+shift+z and
ctrl+shift+x respectively.

prompt-prev will jump to the previous, not currently visible, prompt,
by moving the viewport, ensuring the prompt is at the top of the
screen.

prompt-next jumps to the next prompt, visible or not. Again, by moving
the viewport to ensure the prompt is at the top of the screen. If
we're at the bottom of the scrollback, the viewport is instead moved
as far down as possible.

Closes #30
2022-06-16 19:02:10 +02:00
Daniel Eklöf
96f23b4c64
ime: track IME focus independently from keyboard focus
Replace the seat->ime.focused boolean with a terminal instace pointer,
seat->ime_focus.

Set and reset this on ime::enter() and ime::leave() events, and use
this instead of seat->kbd_focus on all other IME events.

This fixes two issues:

a) buggy compositors that sometimes sends an IME enter event without
  first having sent a keyboard enter event.

b) seats may be IME capable while still lacking the keyboard
  capability. Such seats will *always* see IME enter events without a
  corresponding keyboard enter event.
2022-06-15 19:25:33 +02:00
Daniel Eklöf
dbe2c0a068
selection: allow HT, VT and FF, disallow NUL in non-bracketed paste mode
This syncs foot with more recent versions of XTerm, where it’s
“disallowedPasteControls” resource has changed its default value to

  BS,DEL,ENQ,EOT,ESC,NULL

Note that we’re already stripping out ENQ,EOT,ESC in all modes.

What does it mean for foot:

* HT, VT and FF are now allowed, regardless of paste mode
* NUL is now stripped in non-bracketed paste mode

Closes #1084
2022-06-15 19:09:40 +02:00
Daniel Eklöf
604a3cdd84
changelog: new ‘environment’ section in foot.ini 2022-06-13 11:55:24 +02:00
Daniel Eklöf
9567694bab
grid: reflow: don’t trim trailing empty cells from logical lines
When a line in the old grid (the one being reflowed) doesn’t have a
hard linebreak, don’t trim trailing empty cells.

Doing so means we’ll “compress” (remove) empty cells between text
if/when we revert to a larger window size.

The output from neofetch suffers from this; it prints a logo to the
left, and system information to the right. The logo and the system
info column is separated by empty cells (i.e. *not* spaces).

If the window is reduced in size such that the system info is pushed
to a new line, each logo line ends with a number of empty cells. The
next time the window is resized, these empty cells were
ignored (i.e. removed).

That meant that once the window was enlarged again, the system info
column was a) no longer aligned, and b) had been pulled closer to the
logo.

This patch doesn’t special case trailing empty cells when the line
being reflowed doesn’t have a hard linebreak. This means e.g. ‘ls’
output is unaffected.

Closes #1055
2022-06-11 12:02:20 +02:00
Daniel Eklöf
bc7214cd88
config: use $HOME instead of getpwuid() to retrieve users’s home dir
When searching for foot.ini, use $HOME instead of getpwuid() to
retrieve the user’s home directory.
2022-05-25 17:02:41 +02:00
Daniel Eklöf
62fe452cc2
meson: add -Dsystemd-units-dir=<path> meson command line option
This allows package maintainers to override the location to which our
systemd service files are installed.

It’s value is an *absolute* path, and *not* relative ${prefix}.

The default is ${systemduserunitdir}.
2022-05-12 13:45:53 +02:00
Daniel Eklöf
fc67bff9c0
terminal: move viewport when part of it is scrolled out
If the viewport is at the top of the scrollback, and a program is
scrolling (e.g. by emitting newlines), the viewport needs to be
moved. Otherwise, the top of the viewport will show the *bottom* of
the scrollback (i.e. the newly emitted lines), and the bottom of the
viewport shows the top of the scrollback.

How do we detect if the viewport needs to be moved?

We convert its absolute row number to a scrollback relative row. This
number is also the maximum number of rows we can scroll without the
viewport being scrolled out.

In other words, if the number of rows to scroll is larger than the
viewports scrollback relative row number, the viewport needs to
moved.

How much do we need to move it? The difference between the number of
rows to scroll, and the viewports scrollback relative row number.

Example:

if the viewport is at the very top of the scrollback, its scrollback
relative row number is 0. In this case, it needs to be moved the same
number of rows as is being scrolled.
2022-05-11 17:58:18 +02:00
Daniel Eklöf
ea1aac88db
url-mode: add support for XDG activation when opening URLs
First, add a ‘token’ argument to spawn(). When non-NULL, spawn() will
set the ‘XDG_ACTIVATION_TOKEN’ environment variable in the forked
process. If DISPLAY is non-NULL, we also set DESKTOP_STARTUP_ID, for
compatibility with X11 applications. Note that failing to set either
of these environment variables are considered non-fatal - i.e. we
ignore failures.

Next, add a helper function, wayl_get_activation_token(), to generate
an XDG activation token, and call a user-provided callback when it’s
‘done (since token generation is asynchronous). This function takes an
optional ‘seat’ and ‘serial’ arguments - when both are non-NULL/zero,
we set the serial on the token. ‘win’ is a required argument, used to
set the surface on the token.

Re-write wayl_win_set_urgent() to use the new helper function.

Finally, rewrite activate_url() to first try to get an activation
token (and spawn the URL launcher in the token callback). If that
fails, or if we don’t have XDG activation support, spawn the URL
launcher immediately (like before this patch).

Closes #1058
2022-05-05 10:02:28 +02:00
Daniel Eklöf
bd8dd9ff7e
changelog: fix URL in #1047 issue link 2022-04-28 19:29:06 +02:00
Daniel Eklöf
de201ead2e
changelog: add new ‘unreleased’ section 2022-04-27 20:09:16 +02:00
Daniel Eklöf
225f8e659e
changelog: prepare for 1.12.1 2022-04-27 20:05:51 +02:00
Daniel Eklöf
5308b8cdb8
changelog: changed behavior of “extend-to-word-boundary” 2022-04-27 18:52:08 +02:00
Daniel Eklöf
32d9895697
term: reset sixel options when hard resetting the terminal state 2022-04-26 21:05:17 +02:00
Daniel Eklöf
aa4c7c5a30
config: add ctrl+shift+v and XF86 paste to SEARCH_CLIPBOARD_PASTE
We now bind ctrl+v, ctrl+shift+v, ctrl+y and XF86Paste to pasting from
the clipboard into the scrollback search buffer.

Why all these? Because we can, and because all are common shortcuts
for pasting:

* ctrl+v: “normal” apps use this by default
* ctrl+shift+v: used in terminals (including foot)
* ctrl+y: Emacs
* XF86Paste: special keyboard key, for pasting
2022-04-26 20:37:30 +02:00
Daniel Eklöf
0e9ebf433b
search: fix infinite loop when highlighting all matches
find_next() did not always terminate correctly, causing
search_matches_next() to never terminate, which finally leads to an
infinite loop when rendering the search overlay surface, while finding
all matches to highlight.

The problem is that find_next(), after having found the initial
matching characters, enters a nested while loop that tries to match
the rest of the search criteria. This inner while loop did not check
if we’ve reached the last cell, and happily continued past
it (eventually wrappping around the scrollback buffer).

Closes #1047
2022-04-26 20:36:28 +02:00
Daniel Eklöf
93dcb7dc9c
changelog: typo: space on the wrong side of the parenthesis 2022-04-26 17:52:00 +02:00
Daniel Eklöf
3abb23c81c
changelog: workaround for Sway bug #6960 2022-04-26 17:42:46 +02:00
Daniel Eklöf
b94f540113
changelog: search mode not always highlighting all matches correctly 2022-04-26 17:40:20 +02:00
Daniel Eklöf
1b5b1d5d92
changelog: crash when extending selection in search mode 2022-04-26 17:40:00 +02:00
Daniel Eklöf
312f0dbcfd
changelog: scrollback mode freezing, with 100% CPU 2022-04-24 20:18:49 +02:00
Daniel Eklöf
47d1ba58e5
changelog: UI not refreshing when pasting into the scrollback search box 2022-04-24 12:08:23 +02:00
Daniel Eklöf
1913fb6efd
changelog: hyperlink lists under their corresponding sub-section 2022-04-23 11:13:25 +02:00
Daniel Eklöf
9483a3a7c0
changelog: pgo helper binary build fix (missing key-binding stubs) 2022-04-23 00:49:52 +02:00
Daniel Eklöf
1383def2a0
changelog: convert all issue links to reference links in the 1.12.0 release 2022-04-22 20:05:33 +02:00
Daniel Eklöf
61446df895
Revert "changelog: convert all issue links to reference links in the 1.12.0 release"
This reverts commit 6652a836ad.

We only added the actual links to the 1.12.0 release, meaning all
other issue hyperlinks broke.
2022-04-22 20:02:15 +02:00
Daniel Eklöf
6652a836ad
changelog: convert all issue links to reference links in the 1.12.0 release 2022-04-22 18:54:49 +02:00
Daniel Eklöf
e284c764b7
changelog: replace all bug refs with markdown hyperlinks 2022-04-22 18:36:28 +02:00
Daniel Eklöf
2d4d919687
changelog: add new ‘unreleased’ section 2022-04-22 17:19:04 +02:00
Daniel Eklöf
0cdd32043e
changelog: prepare for 1.12.0 2022-04-22 17:14:00 +02:00
Daniel Eklöf
c7248cf763
meson: add -Dtests=false|true option
When set to false, no test binaries are neither built, nor
executed (with “ninja test”).

Closes #919
2022-04-22 17:05:25 +02:00
Daniel Eklöf
9907d7bbe9
search: don't modify search.start coord *before* finding next match
The match logic uses the last start coordinate to determine which end
points in the selection to update. This sometimes fails when the start
coordinate has been changed by e.g. a key binding - the new start
coordinate is incorrectly matched against the old-but-modified start
coordinate, causing foot to e.g. *not* upate the selection start
coordinate.

Example:

  $ echo 'test\n\test\ntest'

Then do a scrollback search for 'test. The first match is found
correctly (the last 'test'), but searching for the previous match
(ctrl+r) does not select the middle 'test'.

Fix by passing the search direction to search_find_next(), and have
_it_ calculate the coordinate to start search. There are three possibilities:

* forward
* backward
* "backward", but at the same position

The first two are used when searching for next/prev match with ctrl+s
and ctrl+r. The last one is used when the search criteria is
updated. In this case, we don't want to move to the previous match,
*unless* the current match no longer matches.
2022-04-21 18:54:27 +02:00
Daniel Eklöf
6ed9a31007
changelog: move “re-mapping input” from “changed” to “added” 2022-04-20 20:56:04 +02:00
Daniel Eklöf
8485cdaaaa
csi: implement CSI > 4n (reset modifyOtherKeys) 2022-04-19 17:25:06 +02:00
Daniel Eklöf
c5519e2aa6
search: fix next/prev not updating selection correctly when matches overlap
When the new match overlapped with the old match, the selection wasn’t
updated correctly.
2022-04-17 19:16:47 +02:00
Daniel Eklöf
8046e5560a
changelog: key binding overrides having no effect with footclient 2022-04-17 16:01:30 +02:00
Daniel Eklöf
e95bc9283e
meson: install foot.ini to /etc/xdg/foot/foot.ini
Closes #1001
2022-04-17 11:27:53 +02:00
Daniel Eklöf
501a9fbb5e
url-mode: add a key binding that enables “persistent” URL mode
This is an alternative to ‘show-urls-launch’, where we stay in URL
mode after activating an URL.

Closes #964
2022-04-17 11:24:27 +02:00
Daniel Eklöf
0062f4e133
changelog: scrollback search mode highlights all matches 2022-04-17 11:05:14 +02:00