Commit graph

327 commits

Author SHA1 Message Date
Daniel Eklöf
b934969b85
term: add ‘id’ parameter to term_osc8_open()
The current OSC-8 URL’s ID is now tracked along with the URI itself,
and its starting point.
2021-02-21 20:14:52 +01:00
Daniel Eklöf
682494d45a
terminal: add term_osc8_{open,close} functions
These functions update the OSC-8 URI state in the terminal.

term_osc8_open() tracks the beginning of an URL, by storing the start
coordinate (i.e. the current cursor location), along with the URL
itself.

Note that term_osc8_open() may not be called with an empty URL. This
is important to notice, since the way OSC-8 works, applications close
an URL by “opening” a new, empty one:

  \E]8;;https://foo.bar\e\\this is an OSC-8 URL\E]8;;\e\\

It is up to the caller to check for this, and call term_osc8_close()
instead of term_osc8_open() when the URL is empty.

However, it is *also* valid to switch directly from one URL to
another:

  \E]8;;http://123\e\\First URL\E]8;;http//456\e\\Second URL\E]8;;\e\\

This use-case *is* handled by term_osc8_open().

term_osc8_close() uses the information from term_osc8_open() to add
per-row URL data (using the new ‘extra’ row data).
2021-02-21 20:14:51 +01:00
Daniel Eklöf
841e5f0e50
terminal: add OSC-8 state tracking to the VT sub-struct 2021-02-21 20:14:51 +01:00
Daniel Eklöf
fd87bca102
grid: enable rows to have ‘extra’ data associated with them
This patch adds an ‘extra’ member to the row struct. It is a pointer
to a struct containing extra data to be associated with this row.

Initially, this struct contains a list of URL ranges. These
define (OSC-8) URLs on this row.

The ‘extra’ data is allocated on-demand. I.e. the pointer is NULL by
default; it is *not* allocated by grid_row_alloc().
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
23bc3b2179
reaper: monitor SIGCHLD using the FDM instead of via a signalfd
In addition to letting the FDM do the low-level signal watching, this
patch also fixes a bug; multiple SIGCHLDs, be it delivered either through a
signal, or via a signalfd, can be coalesced, like all signals.

This means we need to loop on waitpid() with WNOHANG until there are
no more processes to reap.

This in turn requires a small change to the way reaper callbacks are
implemented.

Previously, the callback was allowed to do the wait(). This was
signalled back to the reaper through the callback’s return value.

Now, since we’ve already wait():ed, the process’ exit status is passed
as an argument to the reaper callback.

The callback for the client application has been updated accordingly;
it sets a flag in the terminal struct, telling term_destroy() that the
process has already been wait():ed on, and also stores the exit
status.
2021-02-11 18:55:30 +01:00
Daniel Eklöf
ddd6f1d944
url-mode: fix key sequence generation
* We were using the ‘back’ element of the list as prefix for the next
  iteration of sequences, instead of the element at index ‘offset’

* ALEN() on a wchar_t[] includes the NULL terminator. We don’t want
  that.
2021-02-07 16:33:34 +01:00
Daniel Eklöf
a988138492
url-mode: urls_collect(): URL list pointer as an argument 2021-02-07 16:33:34 +01:00
Daniel Eklöf
2c10a147ea
url-mode: underline URLs using the color from colors.urls
This is implemented by allocating one of the (few!) remaining bits in
the cells’ attribute struct to indicate the cell should be “URL
highlighted”.

render_cell() looks at this bit and draws an underline using the color
from colors.urls (defaults to regular3 - i.e. yellow).

A new function, url_tag_cells(), iterates the currently detected URLs
and sets the new ‘url’ attribute flag on the affected cells.

Note: this is done in a separate function to keep urls_collect() free
from as many dependencies as possible.

urls_reset() is updated to *clear* the ‘url’ flag (and thus implicitly
also results in a grid refresh, _if_ there were any URLs).

We now exit URL mode on *any* client application input. This needs to
be so since we can’t know if the URLs we previously detected are still
valid.
2021-02-07 16:33:34 +01:00
Daniel Eklöf
69706546c8
term: surface-kind: add TERM_SURF_JUMP_LABEL 2021-02-07 16:33:33 +01:00
Daniel Eklöf
93181649b3
config: add show-urls-copy action
This works just like show-urls-launch, except that instead of opening
the URL (typically using xdg-open), it is placed in the clipboard when
activated.
2021-02-07 16:33:32 +01:00
Daniel Eklöf
2cc84db979
urls: initial support for detecting URLs and rendering jump-labels
The jump labels work, but is currently hardcoded to use xdg-open
2021-02-07 16:33:31 +01:00
Tadeo Kondrak
95c0c89cac
Send text_input_rectangle requests for text-input 2021-01-28 22:22:01 -07:00
Craig Barnes
22f25a9e4f Print stack trace on assert() failure or when calling fatal_error()
Note: this uses the __sanitizer_print_stack_trace() function from the
AddressSanitizer runtime, so it only works when AddressSanitizer is
in use.
2021-01-16 19:56:33 +00:00
Daniel Eklöf
2a012f86d8
term: keep cursor state in grid, for now, but document that it _could_ be moved 2021-01-15 18:02:17 +01:00
Daniel Eklöf
bae3c871bb
term/vt/csi: break out cursor save/restore to dedicated functions 2021-01-15 17:08:30 +01:00
Daniel Eklöf
a6fc8b5da4
config: line-height, letter-spacing: values are in pt by default, but we allow px
If the value is specified without a unit, then the value is assumed to
be in points, subject to DPI scaling.

The value can optionally have a ‘px’ suffix, in which case the value
is treated as a raw pixel count.
2021-01-11 09:31:08 +01:00
Daniel Eklöf
3a9172342f
selection: combine enum selection_kind with selection_semantic 2021-01-06 10:53:27 +01:00
Daniel Eklöf
2fd7b2fbd4
selection: allow selections to pivot around a range instead of a point
Extend selection pivoting to allow selections to pivot around a
range.

Use this in word- and row-based selections to pivot around the initial
word/row that was selected.

This mimics the behavior of at least urxvt and xterm.
2021-01-04 19:48:42 +01:00
Daniel Eklöf
bef69cb961
selection: remember whether word-wise selection uses spaces only for delimiters 2021-01-04 19:48:41 +01:00
Daniel Eklöf
55ecf29a36
selection: wip: update selection row-wise when initial selection was by row 2021-01-04 19:48:40 +01:00
Daniel Eklöf
30de262d29
selection: wip: update selection word-wise when initial selection was by word 2021-01-04 19:48:26 +01:00
Daniel Eklöf
25d2b03a5c
box-drawing: SEXTANTS, U+1fb00-1fb3b 2021-01-01 21:09:37 +01:00
Daniel Eklöf
7acdb3a0dd
box-drawing: add infrastructure for rendering box drawing characters ourselves
* ‘term’ struct contains an array of 160 fcft glyph pointers
* the glyph pointers are lazily allocated when we need to draw a box
  drawings character
* Filtering out box drawings characters is easy - they are (except
  unicode 13, which isn’t handled yet )all in a single range.
2021-01-01 21:09:31 +01:00
Daniel Eklöf
2e137c0a7e
vt: don’t ignore extra private/intermediate characters
Take ‘\E(#0’ for example - this is *not* the same as ‘\E(0’.

Up until now, foot has however treated them as the same escape,
because the handler for ‘\E(0’ didn’t verify there weren’t any _other_
private characters present.

Fix this by turning the ‘private’ array into a single 4-byte
integer. This allows us to match *all* privates with a single
comparison.

Private characters are added to the LSB first, and MSB last. This
means we can check for single privates in pretty much the same way as
before:

  switch (term->vt.private) {
  case ‘?’:
      ...
      break;
  }

Checking for two (or more) is much uglier, but foot only supports
a *single* escape with two privates, and no escapes with three or
more:

  switch (term->vt.private) {
  case 0x243f:  /* ‘?$’ */
      ...
      break;
  }

The ‘clear’ action remains simple (and fast), with a single write
operation.

Collecting privates is potentially _slightly_ more complex than
before; we now need mask and compare, instead of simply comparing,
when checking how many privates we already have.

We _could_ add a counter, which would make collecting privates easier,
but this would add an additional write to the ‘clean’ action which is
really bad since it’s in the hot path.
2020-12-16 14:30:49 +01:00
Daniel Eklöf
6c8b034aff
term: enabling application synchronized updates clear pending grid refresh
This fixes issues with de-synchronized frames being rendered; we may
have scheduled a redraw earlier, that hasn’t yet triggered (probably
because we’re waiting for a frame callback), when we enable
application synchronized updates.

This means we risk rendering a partially updated state when the frame
callback finally arrives, if the application hasn’t yet ended its
synchronized update.
2020-12-14 19:05:54 +01:00
Daniel Eklöf
15d20af2a2
config: add ‘notify’ to possible values for ‘bell’ in foot.ini
When `bell=notify`, foot will trigger a desktop notification when it
receives a BEL in an unfocused window.
2020-12-10 18:22:48 +01:00
Daniel Eklöf
194fbff883
ime: store wchar version of pre-edit string in terminal struct 2020-12-07 20:44:14 +01:00
Daniel Eklöf
0536bc41f4
csi: add DECSET 737769 - enables/disables IME input
73 77 69 = I M E
2020-12-07 20:44:12 +01:00
Daniel Eklöf
b59d695b2b
ime: add functions to enable/disable IME, simplify code that enables IME
We may want to be able to enable/disable IME run-time, even though we
have received an ‘enter’ IME event.

This enables us to do that.

Also add functions to enable/disable IME on a per-terminal instance
basis.

A terminal may have multiple seats focusing it, and enabling/disabling
IME in a terminal instance enables/disables IME on all those seats.

Finally, the code to enable IME is simplified; the *only* surface that
can ever receive ‘enter’ IME events is the main grid. All other
surfaces are sub-surfaces, without their own keyboard focus.
2020-12-07 20:44:11 +01:00
Daniel Eklöf
05083110c3
ime: make IME compile-time optional 2020-12-07 20:44:10 +01:00
Daniel Eklöf
8c3d48c5cd
ime: render pre-edit text
This is done by allocating cells for the pre-edit text when receiving
the text-input::done() call, and populating them by converting the
utf-8 formatted pre-edit text to wchars.

We also convert the pre-edit cursor position to cell positions (it can
cover multiple cells).

When rendering, we simply render the pre-edit cells on-top off the
regular grid. While doing so, we also mark the underlying, “real”,
cells as dirty, to ensure they are re-rendered when the pre-edit text
is modified or removed.
2020-12-07 20:44:10 +01:00
Craig Barnes
31c73f0cf0 csi: add new private mode that makes the Escape key emit "\E[27;1;27~"
This mode can be set by client programs with the DECSET, DECRST,
XTSAVE and XTRESTORE sequences by using 27127 as the parameter.

The sequence "\E[27;1;27~" is encoded in the same way as is done by
xterm's "modifyOtherKeys" mode. Even though xterm itself never emits
such a sequence for the Escape key, many programs already have
support for parsing this style of key sequence.
2020-11-29 04:04:57 +00:00
Daniel Eklöf
cb2f496269
term: split cursor blink state into two
There are two different escape sequences that can be used to set the
cursor blink state: ‘CSI ? 12 h/l’ and ‘CSI Ps SP q’.

Up until now, they both modified the same internal state in foot. This
meant you could enable a blinking cursor with e.g. ‘CSI ? 12 h’ and
then disable it with ‘CSI 2 SP q’.

Since the ‘CSI ? 12’ escapes are used in the civis/cnorm/cvvis
terminfo entries, applications often ended up disabling the blink
state on exit (typically be emitting ‘cnorm’), requiring users to
manually re-enable blinking.

By splitting the internal state into two separate states, we can
improve the situation.

The cursor will blink if at least one of the two have been enabled.

The setting in foot.ini sets the default state of the ‘CSI Ps SP q’
escape.

This means if the user has enabled blinking in the configuration, the
cursor will blink regardless of civis/cnorm/cvvis. Which probably is
what the user wants.

If the user has NOT enabled blinking, civis/cnorm/cvvis act as
intended: cvvis blink, civis and cnorm do not.

If an application overrides the cursor blink/style with ‘CSI Ps SP q’,
that will override the user’s setting in foot.ini. But most likely
that too is intended (for example, the user may have configured the
application to use a different cursor style). And, a well written
application will emit the ‘Se’ terminfo sequence on exit, which in
foot is defined to ‘CSI SP q’, which will reset both the style and
blink state to the user configured style/state.

Closes #218
2020-11-26 18:09:32 +01:00
Daniel Eklöf
360cc8e6de
term: remove read-only properties copied from the config
Use the config directly instead.
2020-11-26 18:08:28 +01:00
Daniel Eklöf
22c354c8fd
term: place frequently accessed members first in term struct
To hopefully use the cache better.
2020-11-24 20:55:41 +01:00
Daniel Eklöf
8e7658a135
config: add ‘dpi-aware’ option, defaulting to enabled
When disabled, foot no longers uses outputs’ DPI to scale the
font. Instead, it uses the outputs’ scaling factor.

That is, instead of appending “:dpi=123” to the fontconfig string,
modify the “:pixelsize” or “:size” attribute.

Closes #206
2020-11-19 19:25:48 +01:00
Daniel Eklöf
2382d6b448
csi: implement “CSI ? 1035” - toggle Num Lock override
This adds a num_lock_modifier state to the terminal, and hooks up
“CSI?1035h/l” to toggle it.
2020-11-11 18:26:47 +01:00
Daniel Eklöf
2c101a21ee
config: add font-bold, font-italic and font-bold-italic options
These options lets the user configure custom fonts and styles, to use
with the bold and italic cell attributes.

By default, they are unset, meaning we use the bold/italic variants of
the regular font.

Closes #169.
2020-10-20 21:04:47 +02:00
Daniel Eklöf
f928c1fa68
wayland: properly restore window size when being un-tiled
Bind to xdg-shell version 2 if available, as this enables us to
track our window’s ‘tiled’ state in the ‘configure’ events.

This in turn allows us to stash the ‘old’ window size when being
tiled, to be used again when restoring the window size when un-tiled.
2020-10-20 20:58:03 +02:00
Daniel Eklöf
1f650a7fdf
term: remove unneeded blink.active field
We now use the timer FD instead; if it is -1, blinking is not active.
2020-10-13 19:28:05 +02:00
Daniel Eklöf
d75e50230e
Merge branch 'scroll-up-down-while-selecting' into master
Closes #149
2020-10-12 20:20:26 +02:00
Daniel Eklöf
4ad7fdc19c
selection: auto-scroll: add SELECTION_SCROLL_NOT as a scroll ‘direction’ 2020-10-11 18:18:18 +02:00
Daniel Eklöf
17761dce63
csi: implement ‘CSI ? 1042 h/l’ - enable/disable bell-is-urgent 2020-10-11 17:44:29 +02:00
Daniel Eklöf
7fedf2f801
selection: auto-scroll: selection keeps scrolling while mouse is outside grid
Moving the mouse outside the grid while we have an on-going selection
now starts a timer. The interval of this timer depends on the mouse’s
distance from the grid - the further away the mouse is, the shorter
interval.

On each timer timeout, we scroll one line, and update the
selection. Thus, the shorter the interval, the faster we scroll.

The timer is canceled as soon as the mouse enters the grid again, or
the selection is either canceled or finalized.

The timer FD is created and destroyed on-demand.

Most of the logic is now in selection.c. The exception is the
calculation of the timer interval, which depends on the mouse’s
position. Thus, this is done in input.c.

The scroll+selection update logic needs to know a) which direction
we’re scrolling in, and b) which *column* the selection should be
updated with.

If the mouse is outside the grid’s left or right margins, the stored
mouse column will be -1. I.e. we don’t know whether the mouse is on
the left or right side of the grid. This is why the caller, that
starts the timer, must provide this value.

The same applies to top and bottom margins, but since we already have
the scroll *direction*, which row value to use can be derived from this.
2020-10-11 15:44:20 +02:00
Daniel Eklöf
1f9ca7715f
term: remove unused bit in xtsave struct 2020-10-09 18:52:05 +02:00
Daniel Eklöf
7c6686221f
bell: optionally render margins in red when receiving BEL
Add anew config option, ‘bell=none|set-urgency’. When set to
‘set-urgency’, the margins will be painted in red (if the window did
not have keyboard focus).

This is intended as a cheap replacement for the ‘urgency’ hint, that
doesn’t (yet) exist on Wayland.

Closes #157
2020-10-08 19:55:32 +02:00
Daniel Eklöf
060be30803
term: add private mode flag ‘’reverse-wrap’ 2020-10-02 21:29:56 +02:00
Daniel Eklöf
7ffd31e13a
render: remove render_refresh_margins() 2020-09-29 10:08:59 +02:00
Daniel Eklöf
5116e40581
term: add term_damage_cursor() and term_damage_margins()
term_damage_cursor() damages the cell where the cursor is currently
at. This can be used to ensure the cursor is re-drawn, if there aren’t
any other pending updates.

term_damage_margins() requests the margins be redrawn the next time we
render the grid.
2020-09-29 10:04:18 +02:00