Commit graph

69 commits

Author SHA1 Message Date
Daniel Eklöf
129deaffa8
wayland: optionally disable pointer input on subsurfaces
We have a number of sub-surfaces for which we are *not* interrested in
pointer (or touch) input.

Up until now, we’ve manually dealt with these, by recognizing these
surfaces in all pointer events, and ignoring them.

But, lo and behold, there are better ways of doing this. By clearing
the subsurface’s input region, the compositor will do this for us -
when a pointer is outside a surface’s input region, the event is
passed to the next surface underneath it.

This is exactly what we want! Do this for all subsurfaces, *except*
the CSDs.
2022-04-16 17:41:14 +02:00
Merlin Büge
5539eac590
fix some small typos 2022-04-13 09:41:10 +02:00
Daniel Eklöf
5b1f1602bc
refactor: add a ‘range’ struct, grouping a start and end coord together 2022-04-09 15:09:02 +02:00
Daniel Eklöf
1e63dddb89
input: don’t allow non-significant modifiers when matching untranslated symbols
When matching “untranslated” bindings (by matching the base symbol of
the key, e.g. ctrl+shift+2 in US layout), require that no
non-significant modifiers are active.

This fixes an issue where AltGr was “ignored”, and would cause certain
combinations to match a key binding.

Example: ctrl+altgr+0, on many European layouts matched against the
default ctrl+0 (reset the font size), instead of emitting ^]

To make this work, we now need to filter out “locked”
modifiers (e.g. NumLock and CapsLock). Otherwise having e.g. NumLock
active would prevent *all* untranslated matching to fail.

Closes #983
2022-03-20 13:29:29 +01:00
Daniel Eklöf
fed90646d3
input/search/url: pass pointer-to key-binding struct to execute() 2022-02-09 17:51:05 +01:00
Daniel Eklöf
dcd79065c8
wayland: unify key- and mouse-binding structs 2022-02-09 17:51:04 +01:00
Daniel Eklöf
e0227266ca
fcft: adapt to API changes in fcft-3.x
Fcft no longer uses wchar_t, but plain uint32_t to represent
codepoints.

Since we do a fair amount of string operations in foot, it still makes
sense to use something that actually _is_ a string (or character),
rather than an array of uint32_t.

For this reason, we switch out all wchar_t usage in foot to
char32_t. We also verify, at compile-time, that char32_t used
UTF-32 (which is what fcft expects).

Unfortunately, there are no string functions for char32_t. To avoid
having to re-implement all wcs*() functions, we add a small wrapper
layer of c32*() functions.

These wrapper functions take char32_t arguments, but then simply call
the corresponding wcs*() function.

For this to work, wcs*() must _also_ be UTF-32 compatible. We can
check for the presence of the  __STDC_ISO_10646__ macro. If set,
wchar_t is at least 4 bytes and its internal representation is UTF-32.

FreeBSD does *not* define this macro, because its internal wchar_t
representation depends on the current locale. It _does_ use UTF-32
_if_ the current locale is UTF-8.

Since foot enforces UTF-8, we simply need to check if __FreeBSD__ is
defined.

Other fcft API changes:

* fcft_glyph_rasterize() -> fcft_codepoint_rasterize()
* font.space_advance has been removed
* ‘tags’ have been removed from fcft_grapheme_rasterize()
* ‘fcft_log_init()’ removed
* ‘fcft_init()’ and ‘fcft_fini()’ must be explicitly called
2022-02-05 17:00:54 +01:00
Daniel Eklöf
ccee08a393
osc8: uri ranges: use a dynamically re-sizable array instead of a tllist 2021-11-26 20:09:15 +01:00
Daniel Eklöf
0c03e9a766
config: add url.uri-characters
This option specifies the characters allowed in the auto-detected
URLs.

Any character not in this set constitutes an URL delimiter, and will
never be included in auto-detected URLs.

This option does not affect OSC-8 URLs.

Closes #654
2021-08-09 18:25:36 +02:00
Daniel Eklöf
31fad58465
url-mode: use shm_get_many()
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.
2021-07-15 18:39:41 +02:00
Daniel Eklöf
f030c87ee6
url-mode: abort when running into un-allocated scrollback memory
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.
2021-07-11 11:31:11 +02:00
Daniel Eklöf
cf6d04f9f2
url-mode: fix crash when removing duplicate and/or overlapping URLs
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
2021-07-11 10:06:12 +02:00
Daniel Eklöf
0a6e7e6167
url-mode: purge SHM pixmaps when destroying URLs
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.
2021-07-11 09:59:17 +02:00
Daniel Eklöf
974c3acd78
url-mode: off-by-one error in end-point column of auto-detected URLs
When an auto-detected URL ended *on* the right-most column, the URL
endpoint was off by one, resulting in the underline in URL mode being
one character short.
2021-06-02 08:11:14 +02:00
Daniel Eklöf
a9e8ba0932
url-mode: codespell 2021-05-22 17:08:14 +02:00
Daniel Eklöf
5605eb9040
url-mode: remove overlapping URLs, not just duplicates
echo -e '\e]8;;https://www.foo.bar\e\\https://www.foo\e]8;;\e\\.bar'

will produce an OSC-8 URL (https://www.foo) that is slightly shorter
than the auto-detected one (https://www.foo.bar).

This produces strange results in URL mode. For example, if
url.osc8-underline=always, the OSC8 underline will be removed when
url-mode is exited.

This patch changes the behavior so that auto-detected URLs that
overlap OSC-8 URLs are removed.

Note that OSC-8 URLs cannot overlap with each other, and that
auto-detected URLs also cannot overlap with each other.
2021-05-22 16:42:43 +02:00
Daniel Eklöf
53516aceec
config: add url.protocols
This makes the protocols recognized by auto-detected URLs
configurable.

Closes #531
2021-05-22 14:50:47 +02:00
Daniel Eklöf
0f483d65ce
config: move url-mode related options to a dedicated section, ‘url’ 2021-05-22 14:50:47 +02:00
Daniel Eklöf
be980a6282
url-mode: fix auto-detection of URLs in the top corner of the viewport
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"
2021-03-06 13:06:54 +01:00
Daniel Eklöf
93b02cf2b8
url-mode: ignore keys with modifiers 2021-03-04 09:43:44 +01:00
Daniel Eklöf
5e64e06a55
input: rewrite of how we match foot’s own key bindings
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.
2021-03-04 09:43:43 +01:00
Daniel Eklöf
b87b8f1170
Revert "url-mode: ignore keys with modifiers"
This reverts commit e5cd09bf3f.

This needs to be applied on the consume-modifiers-for-key-bindings
branch.
2021-03-04 09:34:37 +01:00
Daniel Eklöf
e5cd09bf3f
url-mode: ignore keys with modifiers 2021-03-04 08:54:38 +01:00
Daniel Eklöf
ae0f20a536
url-mode: damage current view before entering URL mode
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.
2021-02-26 09:15:46 +01:00
Daniel Eklöf
bc71e06d5f
url-mode: dirty the “last cursor” cell before taking the snapshot
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.
2021-02-26 09:15:45 +01:00
Daniel Eklöf
aa10cd54ea
url-mode: no need to damage the entire view when exiting URL mode
The renderer will simply apply *all* accumulated damage at once, when
we render the real grid.
2021-02-26 09:15:45 +01:00
Daniel Eklöf
54b5ae95c1
url-mode: snapshot screen state when entering URL mode
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.
2021-02-26 09:15:45 +01:00
Daniel Eklöf
8365fde980
url-mode: redirect stdin/stdout/stderr to /dev/null when opening an URL
This fixex an issue where TUI programs started in the parent
terminal (when running nested terminals).
2021-02-24 21:30:58 +01:00
Daniel Eklöf
7ee5247525
url-mode: disable debug logging 2021-02-23 14:59:54 +01:00
Daniel Eklöf
11464a65de
url-mode: use the same key combo for all occurrences of an URL 2021-02-21 20:15:33 +01:00
Daniel Eklöf
2074f8b656
urls: OSC-8 URLs can now optionally be underlined outside of url-mode
This patch adds a new configuration option,
‘osc8-underline=url-mode|always’.

When set to ‘url-mode’, OSC-8 URLs are only
highlighted (i.e. underlined) in url-mode, just like auto-detected
URLs.

When set to ‘always’, they are always underlined, regardless of mode,
and regardless of their other attributes.

This is implemented by tagging collected URLs with a boolean,
instructing urls_render() and urls_reset() whether they should update
the cells’ ‘url’ attribute or not.

The OSC-8 collecter sets this based on the value of ‘osc8-underline’.

Finally, when closing an OSC-8 URL, the cells are immediately tagged
with the ‘url’ attribute if ‘osc8-underline’ is set to ‘always’.
2021-02-21 20:15:32 +01:00
Daniel Eklöf
06a9ffa763
urls: add key binding that toggles whether URLs are displayed on jump-label
By default, the URL isn’t shown on the jump-label. For auto-detect
URLs, doing so is virtually always useless, as the URL is already
visible in the grid.

For OSC-8 URLs however, the URL is often _not_ visible in the
grid. Many times, seeing the URL is still not needed (if you’re doing
‘ls --hyperlink’, you already know what the URIs are).

But it is still useful to have a way to show the URLs.

This patch adds a new key binding action that can be used in url-mode
to toggle the URL on and off in the jump label.

It is bound to ctrl+t by default.
2021-02-21 20:15:31 +01:00
Daniel Eklöf
cc43c1b704
urls: remove free-form ‘text’ member from URL struct 2021-02-21 20:15:31 +01:00
Daniel Eklöf
cf651d361f
url-mode: remove duplicate URLs
Remove URLs with the same start and end coordinates. Such duplicate
URLs can be created by emitting an OSC-8 URL with matching grid
content:

  \E]8;;http://foo\E\\http://foo\E]8;;\E\\
2021-02-21 20:15:31 +01:00
Daniel Eklöf
a99f9c9341
url-mode: activate_url(): ensure ‘scheme’, ‘host’ and ‘path’ are free:d
uri_parse() may succeed. But if the scheme isn’t “file”, or if the
hostname isn’t localhost, then we failed to free ‘scheme’, ‘host’ and
‘path’.
2021-02-21 20:15:31 +01:00
Daniel Eklöf
fb9e9513a5
url-mode: multiple URL (parts) with the same ID is assigned a single key sequence
In case an URL is split up into multiple parts, those parts are now
treated as a single URL when it comes to key assignment.

Only the *first* URL part is actually assigned a key combo. The other
parts are ignored.

We still highlight them, but for all other purposes they are ignored.
2021-02-21 20:15:29 +01:00
Daniel Eklöf
39c5057d49
url-mode: initial support for OSC-8 URLs
Things left to do: since OSC-8 URLs are stored as ranges in the
per-row ‘extra’ data member, we currently do not handle line-wrapping
URLs very well; they will be considered two separate URLs, and
assigned two different key sequences.
2021-02-21 20:14:51 +01:00
Daniel Eklöf
3339915d20
url-mode: store URL in UTF-8, not UTF-32
The only time the URL is actually in UTF-32 is when we’re collecting
it (auto-detecting it) from the grid, since cells store their
character(s) in UTF-32.

Everything *after* that prefers the URL in UTF-8. So, do the
conversion while collecting the URL.

This patch also changes the URL activation code to strip the
‘file://user@host/’ prefix from file URIs that refer to files
on the *local* computer.
2021-02-21 20:14:51 +01:00
Daniel Eklöf
9d362158e3
url-mode: convert struct wl_url to use wayl_win_subsurface_new() 2021-02-17 21:48:07 +01:00
Daniel Eklöf
c7006661f5
url-mode: use ‘jump-label-letters’ as the alphabet for key sequences
Instead of hard coding the alphabet to “sadfjklewcmpgh”, use the
letters from ‘jump-label-letters’.

Closes #355
2021-02-13 11:43:28 +01:00
Daniel Eklöf
b09606e343
url-mode: do case insensitive comparison when matching key sequence 2021-02-13 11:41:04 +01:00
Daniel Eklöf
79e054faff
Merge branch 'refactor-key-bindings' 2021-02-08 18:57:17 +01:00
Daniel Eklöf
1710c1452a
url-mode: ‘%’ is a valid URI character (but don’t allow it at the end)
Closes #338
2021-02-08 16:02:07 +01:00
Daniel Eklöf
4bad85b593
misc: when free:ing tll lists, prefer tll_remove() over tll_free()
In many places we have the following pattern:

  tll_foreach(list, it)
     free(it->item.thing);
  tll_free(list);

Since all tll functions are macros, and thus inlined, and since
tll_free in itself expands to a tll_foreach(), the above pattern
expands to more native code than necessary.

This is somewhat smaller:

  tll_foreach(list, it) {
      free(it->item.thing);
      tll_remove(list, it);
  }
2021-02-08 10:09:59 +01:00
Daniel Eklöf
03bac9dada
key-bindings: refactor: use a single type for all key bindings
Up until now, the various key binding modes (“normal”, “search” and
“url”) have used their own struct definitions for their key bindings.

The only reason for this was to have a properly typed “action” (using
the appropriate “action” enum).

This caused lots of duplicated code. This patch refactors this to use
a single struct definition for the “unparsed” key bindings handled by
the configuration, and another single definition for “parsed” bindings
used while handling input.

This allows us to implement configuration parsing, keymap translation
and so on using one set of functions, regardless of key binding mode.
2021-02-08 10:09:14 +01:00
Daniel Eklöf
24263412dc
url-mode: urls_render(): early exit when URL list is empty 2021-02-07 16:33:35 +01:00
Daniel Eklöf
9ee392dc8c
url-mode: generate-key-combos: minor efficiency tweaks
* Use a do..while loop; this lets us drop the second half of the loop
  condition.

* Call wcslen(prefix) once, *before* iterating the alphabet
  characters.

* Step through the alphabet characters using a  pointer, as this
  avoids an indexed load (with possibly an imul instruction in
  e.g. -Os builds).
2021-02-07 16:33:35 +01:00
Daniel Eklöf
c84e379767
url-mode: be consistent; use xmalloc() + xrealloc() 2021-02-07 16:33:35 +01:00
Daniel Eklöf
9066ba87df
url-mode: early exit when assigning key combos to empty list 2021-02-07 16:33:35 +01:00
Daniel Eklöf
1aec534b37
url-mode: input: backspace reverts the last key 2021-02-07 16:33:35 +01:00