Commit graph

545 commits

Author SHA1 Message Date
Daniel Eklöf
24ee3dcc10
wayland: refactor: remove ‘struct config’ pointer from wayland struct
The global config doesn’t necessarily reflect the correct
configuration to use - we should *always* use the current terminal
instance’s conf pointer.

* Move selection override modifier mask to the key_binding_set struct
* Always warn if XDG activation is unavailable, not just if
  bell.urgent is set (we no longer have access to this information)
* Pass ‘bool presentation_timings’ as a parameter to wayl_init()
* Remove ‘presentation_timings’ member from the ‘terminal’ struct

Closes #932
2022-04-17 16:34:04 +02:00
Daniel Eklöf
90a2ca966f
key-binding: new API, for handling sets of key bindings
Up until now, our Wayland seats have been tracking key bindings. This
makes sense, since the seat’s keymap determines how the key bindings
are resolved.

However, tying bindings to the seat/keymap alone isn’t enough, since
we also depend on the current configuration (i.e. user settings) when
resolving a key binding.

This means configurations that doesn’t match the wayland object’s
configuration, currently don’t resolve key bindings correctly. This
applies to footclients where the user has overridden key bindings on
the command line (e.g. --override key-bindings.foo=bar).

Thus, to correctly resolve key bindings, each set of key bindings must
be tied *both* to a seat/keymap, *and* a configuration.

This patch introduces a key-binding manager, with an API to
add/remove/lookup, and load/unload keymaps from sets of key bindings.

In the API, sets are tied to a seat and terminal instance, since this
makes the most sense (we need to instantiate, or incref a set whenever
a new terminal instance is created). Internally, the set is tied to a
seat and the terminal’s configuration.

Sets are *added* when a new seat is added, and when a new terminal
instance is created. Since there can only be one instance of each
seat, sets are always removed when a seat is removed.

Terminals on the other hand can re-use the same configuration (and
typically do). Thus, sets ref-count the configuration. In other words,
when instantiating a new terminal, we may not have to instantiate a
new set of key bindings, but can often be incref:ed instead.

Whenever the keymap changes on a seat, all key bindings sets
associated with that seat reloads (re-resolves) their key bindings.

Closes #931
2022-04-17 15:39:51 +02:00
Daniel Eklöf
78fcdc5787
render: implement ‘flash’ and search mode’s ‘dimming’ with a sub-surface
Search mode and ‘flash’ (OSC-555) both achieves similar visual
effects: flash tints the entire window yellow, and search mode dims
it (except the search match).

But, they do so in completely different ways. Search mode is detected
in render_cell(), and the colors are then dimmed there.

Flash is implemented by blending a yellow, semi-transparent color on
top of the rendered grid.

This patch replaces those two implementations with a single one. We
add a new sub-surface, called the ‘overlay’. In normal mode, it’s
unmapped.

When either search mode, or flash, is enabled, we enable it, and
fill it with a semi-transparent color. Yellow for ‘flash’, and
“black” (i.e. no color) for search mode.

The compositor then blends it with the grid. Hopefully on the GPU,
meaning it’ll be faster than if we blend in software.

There are more performance benefits however. By using a separate
surface, we can do much better damage tracking.

The normal grid rendering code no longer have to care about neither
search mode, nor flash. Thus, we get rid of a couple of ‘if’
statements in render_cell(), which is nice. But more importantly, we
can drop full grid repaints in a couple of circumstances:

* Entering/exiting search mode
* Every frame while flash is active

Now, when rendering the search mode overlay, we do want to do some
damage tracking, also of the overlay.

This, since search mode doesn’t dim the *entire* window. The search
match is *not* dimmed. This is implemented by punching a hole in the
overlay sub-surface. That is, we make part of it *fully*
transparent. The basic idea is to set a clip region that excludes the
search match, and then dim the rest of the overlay.

It’s slightly more complicated than that however, if we want to reuse
the last frame’s overlay buffer (i.e we don’t want to re-render
the *entire* overlay every frame).

In short, we need to:

* Clear (punch hole) in areas that are part of this frame’s search
  match, but not the last frame’s (since those parts are _already_
  cleared).
* Dim the areas that were part of the last frame’s search match, but
  aren’t anymore (the rest of the overlay should already be dimmed).

To do this, we save the last frame’s “holes” (as a pixman
region). Then, when rendering the next frame, we first calculate the
new frame’s “holes” region.

The region to clear is “this frame’s holes minus last frame’s holes”
The region to dim is “last frame’s holes minus this frames holes”.

Finally, we compute the bounding box of all modified cells by taking
the union of the two diff regions mentioned above. This allows us to
limit the buffer damage sent to the compositor.
2022-04-16 18:31:02 +02:00
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
Daniel Eklöf
d02124902b
client: add -E,--client-environment
When this option is used, the child process in the new terminal
instance will inherit its environment from the footclient process,
instead of the foot server’s.

Implemented by sending (yet another) dynamic string list as part of
the client -> server setup packet. When the new option is *not* used,
the setup packet is now 2 bytes larger than before.

On the server side, the slave process now uses execvpe() instead of
execvp(). There’s plumbing to propagate a new ‘envp’ argument from
term_init() all the way down to slave_exec(). If ‘envp’ is NULL, we
use ‘environ’ instead (thus matching the old behavior of execvp()).

Closes #1004
2022-04-12 15:07:40 +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
Craig Barnes
23cf80667a Explicitly initialize sigaction::sa_mask members with sigemptyset(3)
Not doing so before calling sigaction(3) is "undefined" according to
POSIX[1]:

> Applications shall call either sigemptyset() or sigfillset() at least
> once for each object of type sigset_t prior to any other use of that
> object. If such an object is not initialized in this way, but is
> nonetheless supplied as an argument to any of pthread_sigmask(),
> sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(),
> sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or
> sigwaitinfo(), the results are undefined.

The use of designated initializers means that sa_mask members were
still being initialized, but sigset_t is an opaque type and implicit
initialization doesn't necessarily produce the same results as using
sigemptyset(3) (although it typically does on most implementations).

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html
2022-02-12 12:26:42 +00:00
Craig Barnes
e32707ffc0 csi/input: remove private mode 27127
This effectively reverts commit 31c73f0cf0.
2022-02-09 20:50:20 +00:00
Ashish SHUKLA
4df73585e7
Specify a fallback mouse cursor
`text' cursor is not available in lots of cursor themes, but `xterm'
is, so specify `xterm' as a fallback cursor name.
2022-02-07 22:15:47 +05:30
Daniel Eklöf
0bf92fff05
term: add term_set_user_mouse_cursor()
This function allows setting a custom mouse cursor.

This is done by adding a ‘char*’ member to the term struct. When it is
non-NULL, we *always* use that pointer (the exception being when the
pointer is hidden), while the pointer is over the grid. This is
instead of the hand/beam pointers we otherwise would use.
2022-02-07 17:28:37 +01:00
Daniel Eklöf
631c63d5a4
term: scrollback-to-text: crash when trying to extract the entire scrollback
We calculated the ‘start’ row by adding the number of screen rows to
the current grid offset. This works in most cases. But not when the
offset is close to the wrap-around.

This triggered a crash when we tried to access a row number larger
than the number of available grid rows.

Fix by bounding the start row to the number of grid rows.

This unearthed a second bug, where trying to extract the scrollback
resulted in nothing getting copied.

The extraction logic did:

   for (r = start; r != (end + 1); r++)
       ....

This works, as long as end isn’t start-1. When we try to extract the
entire scrollback, it _is_ start-1.

Fix by rewriting the loop logic to check for r==end *after* copying
the row contents, but *before* incrementing r.

Closes #926
2022-02-07 15:12:38 +01:00
Daniel Eklöf
b4027118e6
term: init: initialize selection pivot point coords to -1,-1
While this _shouldn’t_ be necessary (pivot points are only used while
a selection is ongoing). But it doesn’t hurt to initialize them
anyway.
2022-02-07 10:36:59 +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
739e7d76b4
search: remember last searched-for string between searches
Regardless of how we exit search mode (commit or cancel), the search
string is remembered.

The next time we enter search mode, the last searched-for string will
be used when searching for the next/prev match (ctrl+r, ctrl+s), and
the search query is empty.
2022-01-29 17:50:42 +01:00
Pranjal Kole
0da19a81bc replace gettimeofday with clock_gettime
POSIX.1-2008 has marked gettimeofday(2) as obsolete, recommending the
use of clock_gettime(2) instead.

CLOCK_MONOTONIC has been used instead of CLOCK_REALTIME because it is
unaffected by manual changes in the system clock. This makes it better
for our purposes, namely, measuring the difference between two points in
time.

tv_sec has been casted to long in most places since POSIX does not
define the actual type of time_t.
2022-01-15 21:35:45 +05:30
Érico Nogueira
5af65d897c terminal: use CLOCK_MONOTONIC instead of literal.
CLOCK_MONOTONIC isn't guaranteed to have the same value on all
platforms, and this makes the code more readable.
2022-01-14 11:39:27 -03:00
Autumn Lamonte
d72ba4a062
SGR-Pixels mouse mode, closes #762 2022-01-01 11:02:30 +01:00
Daniel Eklöf
a835436537
term_mouse_grabbed(): make ‘seat’ argument const 2021-12-28 17:10:03 +01:00
Daniel Eklöf
3f10ee87b1
term: print: erase existing OSC-8 URI
If we have an “active” OSC-8 URI, term_print() would correctly replace
an existing URI with the new one.

But, if we don’t have an active URI, an existing URI was not
erased. This can be reproduced with e.g

  echo -e '\e]8;;http://foo.bar\e\\foobar\e]8;;\e\\\b\b\b\b\b😀\n'
2021-12-26 14:51:26 +01:00
Daniel Eklöf
39bb6be8bf
term_erase(): replace coord-typed arguments with regular ints 2021-12-26 12:39:34 +01:00
Daniel Eklöf
a098fad004
term: font_size_adjust: use DPI=96 when font is *not* scaled by DPI
Closes #842
2021-12-14 17:45:12 +01:00
Daniel Eklöf
06c72fc8c3
term: ensure cell dimensions are non-zero
Closes #830
2021-12-04 18:41:36 +01:00
feeptr@codeberg.org
a4d53bdf88 config, input: allow configuring select-override modifiers 2021-12-02 18:44:08 -05:00
Daniel Eklöf
b3029234af
term: xcursor_update_for_seat(): BUG on xcursor == NULL 2021-11-30 22:25:32 +01:00
Daniel Eklöf
59e6285037
term: xcursor_update_for_seat(): remove duplicate check for term->is_searching 2021-11-30 22:14:05 +01:00
Daniel Eklöf
bfbb4b0830
term: xcursor_update_for_seat(): remove switch default case
Let the compiler catch missing enum values
2021-11-30 22:12:56 +01:00
Daniel Eklöf
90cfdcf1a5
Merge branch 'window-menu' 2021-11-30 22:10:27 +01:00
Jonas Ådahl
5c2557b421 terminal: Make seat xcursor update focus aware
When term_xcursor_update_for_seat() was called on e.g. keyboard focus
loss, it'd update the curret xcursor to 'text' even if it was e.g. on
top of the window title, or resize areas. This makes the function a bit
more focus aware, and will not be so eager to set the text xcursor.
2021-11-29 16:26:40 +01:00
Daniel Eklöf
66171f1045
input: rename ‘meta’ to ‘super’ 2021-11-28 15:14:54 +01:00
Daniel Eklöf
fec42e5941
kitty kbd: add flag state, implement push/pop/update/query 2021-11-28 15:14:40 +01:00
Daniel Eklöf
8c50a7afd4
osc8: update URI ranges as we print data, *not* when the URI is closed
At first, an OSC-8 URI range was added when we received the closing
OSC-8 escape (i.e. with an empty URI).

But, this meant that cursor movements while the OSC-8 escape was in
effect wasn’t handled correctly, since we’d add a range that spanned
the cursor movements.

Attempts were made to handle this in the cursor movement functions, by
closing and re-opening the URI.

However, there are too many corner cases to make this a viable
approach. Scrolling is one such example, line-wrapping another.

This patch takes a different approach; emit, or update the URI range
when we print to the grid. This models the intended behavior much more
closely, where an active OSC-8 URI act like any other SGR attribute -
it is applied to all cells printed to, but otherwise have no effect.

To avoid killing performance, this is only done in the “generic”
printer. This means OSC-8 open/close calls must now “switch” the ASCII
printer.

Note that the “fast” printer still needs to *erase* pre-existing OSC-8
URIs.

Closes #816
2021-11-25 19:31:03 +01:00
Daniel Eklöf
5b176dd5d6
term: print: reset ‘col’ after padding the right margin 2021-11-21 18:09:40 +01:00
Daniel Eklöf
315769b50b
Revert "term: print: erase URI range when printing right-margin padding"
This reverts commit bb967fd2f927d90e881ed2b05db1fa6946033580.
2021-11-21 18:09:40 +01:00
Daniel Eklöf
65944906bf
term: print: erase URI range when printing right-margin padding 2021-11-21 18:09:40 +01:00
Daniel Eklöf
3c6239c66f
term: print: re-order col/row/cell assigments 2021-11-21 18:09:39 +01:00
Daniel Eklöf
0be55ef74c
term: erase_cell_range(): check if row->extra != NULL 2021-11-21 18:09:27 +01:00
Daniel Eklöf
53fc1a1cb1
term: tail-call optimize calls to grid_row_uri_range_erase() 2021-11-21 18:09:27 +01:00
Daniel Eklöf
09a331857a
term: call grid_row_uri_range_erase() when printing cells 2021-11-21 18:09:26 +01:00
Daniel Eklöf
1a0de0017f
grid: add grid_row_uri_range_erase()
This function handles erasing of an URI range. That is, a range of the
row is being either erased, or overwritten (from the URI perspective,
these two are the same thing).

We handle both partial overwrites (split up, or truncate URI), as well
as complete overwrites (remove URI).
2021-11-21 18:09:26 +01:00
Daniel Eklöf
d46af6bd7a
term: track cell color source
Each cell now tracks it’s current color source:

* default fg/bg
* base16 fg/bg (maps to *both* the regular and bright colors)
* base256 fg/bg
* RGB

Note that we don’t have enough bits to separate the regular from the
bright colors. These _shouldn’t_ be the same, so we ought to be
fine...
2021-11-20 16:46:38 +01:00
Daniel Eklöf
c01904a2c7
config: add [colors].dim0-7
This allows you to configure custom colors to be used when colors are
being dimmed (`\E[2m`).

It is implemented by color matching (just like
bold-text-in-bright=palette-based); the color-to-be-dimmed is matched
against the current color palette.

If it matches one of the regular colors (colors 0-7), the
corresponding “dim” color will be used.

If it matches one of the bright colors (colors 8-15), the
corresponding “regular” color will be used (but *only* if the “dim”
color has been set).

Otherwise, the color is dimmed by reducing its luminance.

The default behavior, i.e. when dim0-7 hasn’t been configured, is to
dim by reducing luminance for *all* colors. I.e. we don’t do any color
matching at all. In particular, this means that dimming a bright color
will *not* result in the corresponding “regular” color.

Closes #776
2021-11-13 17:39:08 +01:00
Daniel Eklöf
d29c3cf7b7
config: add {str,value}_to_uint{16,32}()
This allows us to pass the final pointer directly to the conversion
functions, as well as allowing us to print outside-range errors.
2021-11-13 11:04:29 +01:00
Ronan Pigott
99d5bf64bc foot/client: implement xdga client activation
This is an application of the xdg activation protocol that will allow
compositors to associate new foot toplevels with the command that
launched them.

footclient receives an activation token from the launcher which the
compositor can use to track application startup. It passes the token
to the foot server, which then activates the new window with the token
to complete the startup sequence.
2021-10-31 18:52:29 -07:00
Daniel Eklöf
db2529159c
term: bell: simplify if-statement - we don’t need two nested levels 2021-10-22 20:04:23 +02:00
Daniel Eklöf
2fbc336eb9
term: ignore window title updates if title is un-changed 2021-10-22 18:01:53 +02:00
Mitja Horvat
729f7466ae notify: add the notify-focus-inhibit config option
foot doesn't show desktop notifications (via OSC777) if the current
terminal has keyboard focus.

This is probably a sane default, but there are use cases where showing
a notification regardless of the focus status may be desired. For
example, a completion notification of a long running task inside a
non-focused tmux window.

This PR adds the notify-focus-inhibit option which can be used to
disable inhibition of notifications when the window has focus.

The default value is `yes`, which retains the old behavior.
2021-10-06 23:33:17 +02:00
Daniel Eklöf
fb77637eb9
term: only scale using DPI if *all* monitors have a scaling factor or one
With dpi-aware=auto (the default), scale fonts using DPI *only*
if *all* available monitors have a scaling factor of one.

The idea is this: if a user, with multiple monitors, have enabled
scaling on *at least* one monitor, he/she has most likely done so to
match the size of his/hers other monitors.

For example, if the user has one monitor with a scaling factor of one,
and another one with a scaling factor of two, he/she expects things to
be twice as large on the second monitor.

If we (foot) scale using DPI on the first monitor, and using the
scaling factor on the second monitor, foot will *not* look twice as
big on the second monitor (this was the old behavior of
dpi-aware=auto).

Part of #714
2021-09-24 22:07:47 +02:00
Daniel Eklöf
37b15adcd8
term: turn ‘box-drawings’ array into three dynamically allocated arrays
The box_drawings array is now quite large, and uses up ~4K
when *empty*.

This patch splits it up into three separate, dynamically allocated
arrays; one for the traditional box+line drawing and block elements
glyphs, one for braille, and one for the legacy computing symbols.

When we need to render a glyph, the *entire* array (that it belongs
to) is allocated.

I.e this is one step closer to a dynamic glyph cache (like the one
fcft uses), but doesn’t go all the way.

This is especially nice for people with
‘box-drawings-uses-font-glyphs=yes’; for them, the custom glyphs now
uses 3*8 bytes (for the three array pointers), instead of 4K.
2021-09-14 09:50:49 +02:00
Daniel Eklöf
d126662560
term: reduce scope of variable 2021-09-05 12:39:25 +02:00
Daniel Eklöf
bb948d03e1
terminal: prefer the advance width of ‘M’ over that of a space
This makes some non-monospaced fonts more readable, allowing users to
read errors and warnings printed in the window.

Furthermore, fcft-3.0 will remove the space_advance member, so once we
upgrade, we’ll have to rasterize a glyph ourselves anyway.
2021-08-31 19:56:59 +02:00