Commit graph

694 commits

Author SHA1 Message Date
Daniel Eklöf
1fec0cf5ea
Revert "term: append zero-width grapheme breaking characters to previous cell"
This reverts commit 76503fb86a.
2025-04-24 18:22:37 +02:00
Daniel Eklöf
1b15cc5f3d
Revert "term: ignore LTR+RTL markers (U+200E + U+200F)"
This reverts commit 70b324b24c.
2025-04-24 18:20:18 +02:00
Daniel Eklöf
70b324b24c
term: ignore LTR+RTL markers (U+200E + U+200F)
Foot doesn't implement RTL, and explicit LTR markers is neither
needed, nor used in anyway. In fact, they cause issues with font
lookup, as fcft often fails to find the marker codepoint in the
primary font, causing a fallback font to be used instead.

Closes #2049
2025-04-24 08:23:56 +02:00
Daniel Eklöf
7f11ba59ef
fcft: require fcft >= 3.3.0, add support for new scaling-filters
Update tweak.scaling-filter to recognize the new scaling filters added
in fcft-3.3.0.

Since fcft_set_scaling_filter() is deprecated in 3.3.0, don't use it
anymore, and set the scaling filter via fcft_font_options instead.
2025-03-12 10:03:06 +01:00
Daniel Eklöf
7b6efcf19a
grid: change default value of linebreak to true
This way, all lines are treated as having a hard linebreak, until it's
cleared when we do an auto-wrap.

This change alone causes issues when reflowing text, as now all
trailing lines in an otherwise empty window are treated as hard
linebreaks, causing the new grid to insert lots of unwanted, empty
lines.

Fix by doing two things:

* *clear* the linebreak flag when we pull in new lines for the new
  grid. We only want to set it explicitly, when an old row has its
  linebreak flag set.
* Coalesce empty lines with linebreak=true, and only "emit" them as
  new liens in the new grid if they are followed by non-empty lines.
2025-03-05 18:55:01 +01:00
Daniel Eklöf
a80b32d006
term: tweak linebreaking
Don't set linebreak on linefeed. Instead, rely on the default value of
true, and that it is only cleared when a character is printed while
LCF=1.

Note that printing to a row that has linebreak cleared, will set the
linebreak flag again.
2025-03-05 18:55:00 +01:00
Daniel Eklöf
ccf625b991
render: gamma-correct blending
This implements gamma-correct blending, which mainly affects font
rendering.

The implementation requires compile-time availability of the new
color-management protocol (available in wayland-protocols >= 1.41),
and run-time support for the same in the compositor (specifically, the
EXT_LINEAR TF function and sRGB primaries).

How it works: all colors are decoded from sRGB to linear (using a
lookup table, generated in the exact same way pixman generates it's
internal conversion tables) before being used by pixman. The resulting
image buffer is thus in decoded/linear format. We use the
color-management protocol to inform the compositor of this, by tagging
the wayland surfaces with the 'ext_linear' image attribute.

Sixes: all colors are sRGB internally, and decoded to linear before
being used in any sixels. Thus, the image buffers will contain linear
colors. This is important, since otherwise there would be a
decode/encode penalty every time a sixel is blended to the grid.

Emojis: we require fcft >= 3.2, which adds support for sRGB decoding
color glyphs. Meaning, the emoji pixman surfaces can be blended
directly to the grid, just like sixels.

Gamma-correct blending is enabled by default *when the compositor
supports it*. There's a new option to explicitly enable/disable it:
gamma-correct-blending=no|yes. If set to 'yes', and the compositor
does not implement the required color-management features, warning
logs are emitted.

There's a loss of precision when storing linear pixels in 8-bit
channels. For this reason, this patch also adds supports for 10-bit
surfaces. For now, this is disabled by default since such surfaces
only have 2 bits for alpha. It can be enabled with
tweak.surface-bit-depth=10-bit.

Perhaps, in the future, we can enable it by default if:

* gamma-correct blending is enabled
* the user has not enabled a transparent background
2025-03-05 18:45:01 +01:00
Daniel Eklöf
9e6d334bd8
term: reset the grapheme clustering state on cursor movements 2025-03-04 07:50:03 +01:00
Daniel Eklöf
9f9ffa9434
term: set_app_id(): app_id may be NULL, in which case we can't do strlen()
Closes #1963
2025-02-18 15:09:23 +01:00
Daniel Eklöf
76503fb86a
term: append zero-width grapheme breaking characters to previous cell
When compiled with grapheme clustering support, zero-width characters
that also are grapheme breaks, were ignored (not stored in the
grid).

When utf8proc says the character is a grapheme break, we try to print
the character to the current cell. But this is only done when width >
0. As a result, zero width grapheme breaks were simply discarded.

This only happens when grapheme clustering is enabled; when disabled,
all zero width characters are appended.

Fix this by also requiring the width to be non-zero when if we should
append the character or not.

Closes #1960
2025-02-16 09:13:13 +01:00
Daniel Eklöf
9840204097
term: print-non-ascii: propagate existing forced-width
When appending to an existing composed character, "inherit" its forced
width, if set.

Also make sure to actually _use_ the forced width, if set, rather than
the calculated width.

This fixes an issue when appending zero-width codepoints to a
forced-width combining character.
2025-02-06 14:02:38 +01:00
Daniel Eklöf
d3f692990e
term+vt: refactor: move "utf8" char processing to term_process_and_print_non_ascii()
This function "prints" any non-ascii character (i.e. any character
that ends up in the action_utf8_print() function in vt.c) to the
grid. This includes grapheme cluster processing etc.

action_utf8_print() now simply calls this function.

This allows us to re-use the same functionality from other
places (like the text-sizing protocol).
2025-02-06 07:45:20 +01:00
Daniel Eklöf
1111f7e918
grid: reflow: handle composed characters longer than 2 cells
The logic that tries to ensure we don't break a line in the middle of
a multi-cell character was flawed when the number of cells were larger
than 2.

In particular, if the number of cells to copy were limited by the
number of cells left on the current (new) line, and were less than the
length of the multi-cell character, then we failed to insert the
correct number of spacers, and also ended up misplacing the multi-cell
character; instead of pushing it to the next line, it was inserted on
the current line, even though it doesn't fit.

Also change how trailing SPACER cells are rendered (cells that are
"fillers" at then end of a line, when a multi-column character was
pushed over to the next line): don't copy the previous cell's
attributes (which may be wrong anyway), use default attributes
instead.
2025-02-06 07:42:38 +01:00
Daniel Eklöf
88dcde3ed8
term: insert-mode: handle combining characters correctly
When the client application emits combining characters, for example
multi-codepoint emojis, in insert-mode, we ended up pushing partial
graphemes to the right, for each codepoint, resulting in too many
cells (and with the wrong content) being inserted.

The fix is fairly simple; don't "insert" when appending characters to
an existing grapheme cluster.

This isn't something we can detect easily in print_insert() (it would
require us to do grapheme clustering again). Fortunately, we do have
the required information in action_utf8_print(). So, pass this
information as a boolean to term_print().

Closes #1947
2025-02-06 07:37:55 +01:00
Daniel Eklöf
2fe72effa9
term: ptmx pause/resume: don't modify the FDM if ptmx has been closed
This fixes error message spam when resizing a terminal window executed
with --hold, and where the client application has terminated.
2025-02-05 11:39:06 +01:00
Daniel Eklöf
2a07a2e6b9
Add support for the new Wayland protocol xdg-system-bell
From the release notes:

    system bell - allowing e.g. terminal emulators to hand off system
    bell alerts to the compositor for among other things accessibility
    purposes

The new protocol is used when the new config option
bell.system=yes (and the compositor implements the protocol,
obviously).

The system bell is rung independent of whether the foot window has
keyboard focus or not (thus relying on compositor configuration to
determine whether anything should be done or not in response to the
bell).

The new option is enabled by default.
2025-01-17 10:21:50 +01:00
Daniel Eklöf
2c309227f1
term: cursor_refresh(): don't try to dirty the grid if we don't have one
If the compositor sends a keyboard enter event before our window has
been mapped, foot crashes; the enter event triggers a cursor
refresh (hollow -> non-hollow block cursor), which crashes since we
haven't yet allocated a grid.

Fix by no-op:ing the refresh if the window hasn't been configured yet.

Closes #1910
2025-01-09 07:56:57 +01:00
Alexander Orzechowski
c2add346ad
terminal: Refresh only overlay when flash expires
If we call render_refresh, that will wait for a callback to the main
surface. In the case of a flash, the main surface might not get callbacks
if the compositor implements fancy culling optimizations like wlroots
wlr_scene compositors such as sway version >=1.10.
2025-01-09 07:53:50 +01:00
Daniel Eklöf
c7ab7b3539
term: limit app-id to 2048 characters
Unsure if the protocol imposes a limit (haven't found any
documentation), or if the issue is in the libwayland implementation,
or wlroots (triggers in at least sway+river).

The issue is that setting a too long app-id causes the
compositor (river at least) to peg the CPU at 100%, and stop sending
e.g. frame callbacks to foot.

Closes #1897
2025-01-02 08:58:48 +01:00
Daniel Eklöf
d523e7a676
term: set_app_id() + set_window_title(): only allow printable characters 2024-12-17 11:01:17 +01:00
Daniel Eklöf
9a1b59adae
box-drawings: implement octants 2024-12-08 12:55:57 +01:00
Daniel Eklöf
256749c6d0
term: get_font_dpi(): remove invalid assertion
Closes #1874
2024-11-24 08:01:31 +01:00
Daniel Eklöf
7984f08925
osc: OSC-1 does not set the icon, it sets the icon _label_
In fact, there appears there *is* no escape sequence to set the icon.

Keep most of the logic in place, but in practice, we'll always set the
icon to the app-id. That is, at startup, we set it to the configured
app-id (either from config, or the command line).

OSC-176, which sets the app-id, also updates the icon (to the app-id).
2024-09-13 09:04:18 +02:00
Daniel Eklöf
97ec375c67
toplevel-icon: implement OSC-1, CSI 20/21/22/23 t
* The toplevel icon is now set to the app-id, unless "overridden" by
  OSC-1 or OSC-0.
* Implemented OSC-1
* OSC-0 extended to also set the icon
* Implemented CSI 20 t - report window icon
* Implemented CSI 21 t - report window title
* Implemented CSI 22 ; 1 t - push window icon
* Implemented CS 23 ; 1 t - pop window icon
* Extended CSI 22/23 ; 0 t to also push/pop the icon
* Verify app-id set by OSC-176 is valid UTF-8
* Verify icon set by OSC-0/1 is valid UTF-8
2024-09-13 09:04:17 +02:00
Craig Barnes
d4a1283797
xsnprintf: various improvements related to xvsnprintf() and xsnprintf()
Summary of changes:

* Make xvsnprintf() static
* restrict-qualify pointer arguments (as done by the libc equivalents)
* Make comments and spec references more thorough
* Remove pointless `n <= INT_MAX` assertion (see comment)
* Use FATAL_ERROR() instead of xassert() (since the assertion is inside
  a shared util function but the caller is responsible for ensuring the
  condition holds true)
* Change some callers to use size_t instead of int for the return value
  (negative returns are impossible and all subsequent uses are size_t)

The updated comments and code were taken (and adapted) from:

49260bb154/src/util/xsnprintf.c (L6-50)

This work was entirely authored by me and I hereby license this
contribution under the MIT license (stated explicitly, so that
there's no ambiguity w.r.t. the original license).
2024-09-13 09:01:15 +02:00
Daniel Eklöf
c5bb1fb2ed
notifications: BEL and OSC-777 now focuses the window on notification activation
Or put more propertly; if the notification daemon, and the
notification helper used by foot has been configured
properly (i.e. they both support XDG activation tokens), notifications
generated by BEL and OSC-777 will now raise/focus the window when the
default action of the notification is activated - typically by
clicking the notification.

Closes #1822
2024-09-05 07:16:15 +02:00
Daniel Eklöf
8f9f3dbd9d
term_set_window_title(): fix bad check for invalid UTF-8
mbsntoc32() returns (size_t)-1 on failure, not (char32_t)-1.
2024-08-20 07:15:22 +02:00
Andrew J. Hesford
1969717527
feature: add resize-keep-grid to allow text reflow on font changes 2024-08-20 07:07:29 +02:00
Daniel Eklöf
96c30cd410
term: thrd_join() returns thrd_success on success, not 0
Closes #1812
2024-08-15 17:20:12 +02:00
Daniel Eklöf
a3a35f2c8c
term: reload_fonts(): don't ignore return value of thrd_join()
This should fix the

    ‘ret’ may be used uninitialized

warning

Closes #1789
2024-08-04 11:55:25 +02:00
Craig Barnes
f87c9bb9f7 xmalloc: remove delim param from xstrjoin() and add separate xstrjoin3()
This avoids the need for an unused third argument for most xstrjoin()
calls and replaces the cases where it's needed with a more flexible
function. Code generation is the same in both cases, when there are 2
string params and a compile-time known delimiter.

This commit also converts 4 uses of xasprintf() to use xstrjoin*().

See also: https://godbolt.org/z/xsjrhv9b6
2024-08-03 08:51:06 +01:00
Daniel Eklöf
ea2f0e7c3f
osc: kitty notifications: cleanup and update to latest version of spec
* Don't store a list of unfinished notifications. Use a single one. If
  the notification ID of the 'current' notification doesn't match the
  previous, unfinished one, the 'current' notification replaces the
  previous one, instead of updating it.

* Update xstrjoin() to take an optional delimiter (for example ','),
  and use that when joining categories and 'alive IDs'.

* Rename ${action-arg} to ${action-argument}

* Update handling of the 'n' parameter (symbolic icon name); the spec
  allows it to be used multiple times, and the terminal is supposed to
  pick the first one it can resolve. Foot can't resolve icons at all,
  neither can 'notify-send' or 'fyi' (which is what foot typically
  executes to display a notification); it's the notification daemon that
  resolves icons.

  The spec _could_ be interpreted to mean the terminal should lookup
  .desktop files, and use the value of the 'Icon' key from the first
  matching .desktop files. But foot doesn't read .desktop files, and I
  don't intend to implement XDG directory scanning and parsing of
  .desktop files just to figure out which icon to use.

  Instead, use a simple heuristics; use the *shortest* symbolic
  names. The idea is pretty simple: plain icon names are typically
  shorter than .desktop file IDs.
2024-08-02 08:07:13 +02:00
Daniel Eklöf
76ac910b11
osc: kitty notifications: buttons, icons, app-name, categories etc
First, icons have been finalized in the specification. There were only
three things we needed to adjust:

* symbolic names are base64 encoded
* there are a couple of OSC-99 defined symbolic names that need to be
  translated to the corresponding XDG icon name.
* allow in-band icons without a cache ID (that is, allow applications
  to use p=icon without having to cache the icon first).

Second, add support for the following new additions to the protocol:

* 'f': custom app-name, overrides the terminal's app-id
* 't': categories
* 'p=alive': lets applications poll for currently active notifications
* 'id' is now 'unset' by default, rather than "0"
* 'w': expire time (i.e. notification timeout)
* "buttons": aka actions. This lets applications add additional (to
  the terminal defined "default" action) actions. The 'activated' event
  has been updated to report which button/action was used to activate
  the notification.

To support button/actions, desktop-notifications.command had to be
reworked a bit.

There's now a new config option:
desktop-notifications.command-action-arg. It has two template
arguments ${action-name} and ${action-label}.

command-action-arg gets expanded for *each* action.

${action-name} and ${action-label} has been replaced by ${action-arg}
in command. This is a somewhat special template, in that it gets
replaced by *all* instances of the expanded actions.
2024-07-31 16:22:17 +02:00
Daniel Eklöf
0a5ba708e4
notify: don't close FD 0
This fixes a regression where closing a terminal instance, or hard- or
soft-resetting a terminal caused FD 0 to be closed.

This meant it became re-usable. Usually, by memfd_create() when
allocating a new surface buffer. So far nothing _really_ bad has
happened.

But what if FD 0 is now used by a memfd, and we close _another_
terminal instance?

This causes our memfd to be closed. And then, when e.g. trying to
scroll the terminal content: fallocate() fails with bad FD.
2024-07-30 16:33:19 +02:00
Daniel Eklöf
b3108e1ad2
notify: separate active notifications from unfinished kitty notifications
This fixes an issue where it wasn't possible to trigger multiple
notifications with the same kitty notification ID. This is something
that works in kitty, and there's no reason why it shouldn't work.

The issue was that we track stdout, and the notification helper's PID
in the notification struct. Thus, when a notification is being
displayed, we can't re-use the same notification struct instance for
another notification.

This patch fixes this by adding a new notification list,
'active_notifications'. Whenever we detect that we need to track the
helper (notification want's to either focus the window on activation,
or send an event to the application), we add a copy of the
notification to the 'active' list.

The notification can then be removed from the 'kitty' list, allowing
kitty notifications to re-use the same ID over and over again, even if
old notifications are still being displayed.
2024-07-23 11:53:30 +02:00
Daniel Eklöf
ccb184ae64
osc: kitty notifications: updated support for icons
This implements the suggested protocol discussed in
https://github.com/kovidgoyal/kitty/issues/7657.

Icons are handled by loading a cache. Both in-band PNG data, and
symbolic names are allowed.

Applications use a graphical ID to reference the icon both when
loading the cache, and when showing a notification.

* 'g' is the graphical ID
* 'n' is optional, and assigns a symbolic name to the icon
* 'p=icon' - the payload is icon PNG data. It needs to be base64
  encoded, but this is *not* implied. I.e. the application *must* use
  e=1 explicitly.

To load an icon (in-band PNG data):

    printf '\e]99;g=123:p=icon;<base64-encoded-png-data>\e\\'

or (symbolic name)

    printf '\e]99;g=123:n=firefox:p=icon;\e\\'

Of course, we can combine the two, assigning *both* a symbolic
name, *and* PNG data:

    printf '\e]99;g=123:n=firefox:p=icon;<base64-encoded-png>\e\\'

Then, to use the icon in a notification:

    printf '\e]99;g=123;this is a notification\e\\'

Foot also allows a *symbolic* icon to be defined and used at the same
time:

    printf '\e]99;g=123:n=firefox;this is a notification\e\\'

This obviously won't work with PNG data, since it uses the payload
portion of the escape sequence.
2024-07-23 11:29:05 +02:00
Daniel Eklöf
5905ea0d84
osc: kitty notifications: implement focus|report
This patch adds support for window focusing, and sending events back
to the client application when a notification is closed.

* Refactor notification related configuration options:
    - add desktop-notifications sub-section
    - deprecate 'notify' in favor of 'desktop-notifications.command'
    - deprecate 'notify-focus-inhibit' in favor of
      'desktop-notifications.inhibit-when-focused'
* Refactor: rename 'struct kitty_notification' to 'struct
  notification'
* Pass a 'struct notification' to notify_notify(), instead of many
  arguments.
* notify_notify() now registers a reaper callback. When the notifier
  process has terminated, the notification is considered closed, and we
  either try to focus (activate) the window, or send an event to the
  client application, depending on the notification setting.
* For the window activation, we need an XDG activation token. For now,
  assume *everything* written on stdout is part of the token.
* Refactor: remove much of the warnings from OSC-99; we don't
  typically log anything when an OSC/CSI has invalid values.
* Add icon support to OSC-99. This isn't part of the upstream
  spec. Foot's implementation:
    - uses the 'I' parameter
    - the value is expected to be a symbolic icon name
    - a quick check for absolute paths is done, and such icon requests
      are ignored.
* Added ${icon} to the 'desktop-notifications.command' template. Uses
  the icon specified in the notification, or ${app-id} if not set.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
a42f990818
spawn: add optional reaper callback, return pid_t
This will allow spawn() callers to do things when the spawned process
has terminated.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
b0bf8ca5f7
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:

* 'a': action to perform on notification activation. Since we don't
  trigger the notification ourselves (over D-Bus), we don't know a)
  which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported

To be explicit, we *do* support:

* Chunked notifications (d=0|1), allowing the application to append
  data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
  the following quirks:
    - we don't know when the window is invisible, thus it's treated as
      'unfocused'.
    - the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)

[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-23 07:17:21 +02:00
Daniel Eklöf
45c7cd3f74
input: allow mouse selections to start inside the margins
Before this, margins were special cased:

* The mouse cursor was always a pointer, and never an I-beam (thus
  signaling selections cannot be made).
* The internal mouse coords where set to -1 when the cursor was inside
  the margins, causing:
    - text selections from being made
    - mouse events being passed to mouse grabbing applications

In particular, even with a one-pixel margin, making selections was
unnecessarily hard in e.g. fullscreen mode, where you'd expect to be
able to throw the cursor into the corner of the screen and then start
a selection.

With this patch, the cursor is treated as if it was in the first/last
column/row, when inside the margin(s).

An unintended side-effect of this, initially, was that auto-scrolling
selections where way too easy to trigger, since part of its logic is
checking if the cursor is inside the margins.

That problem has been reduced by two things:

* auto-scrolling does not occur unless a selection has been
  started. That is, just holding down the mouse in the margins and
  moving up/down doesn't cause scrolling. You have to first select at
  least one cell in the visible viewport.
* A selection isn't fully started (i.e. a cell is actually selected)
  unless the cursor is inside the actual grid, and *not* in the
  margins.

What does the last point mean? We now allow a selection to be
_started_ when clicking in the margin. What this means internally is
we set a start coordinate for a selection, but *not* and end
coordinate. At this point, we don't have an actual selection. Nothing
is selected, and no cells are highlighted, graphically.

This happens when we set an end coordinate. Without the last bullet
point, that would happen as soon as the cursor was _moved_, even if
still inside the margins. Now, we require the cursor to leave the
margins and touch an actual cell before we set an end coordinate.

Closes #1702
2024-07-19 06:55:28 +02:00
Daniel Eklöf
38461eef6f
csi: in-band window resize notifications, private mode 2048
This implements
https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83,
in-band window resize notifications.

When user enables private mode 2048 (in-band resize
notifications), *always* send current size, even if the mode is
already active.

This ensures applications can rely on getting a reply from the
terminal.
2024-07-19 06:54:32 +02:00
Daniel Eklöf
1136108c97
input: don't map wheel events to BTN_{BACK,FORWARD}
BTN_BACK and BTN_FORWARD are separate buttons. The scroll wheel don't
have any button mappings in libinput/wayland, so make up our own
defines.

This allows us to map them in mouse bindings.

Also expose BTN_WHEEL_{LEFT,RIGHT}. These were already defined, and
used, internally, to handle wheel tilt events. With this, they can
also be used in mouse bindings.

Finally, fix encoding used for BTN_{BACK,FORWARD} when sending mouse
button events to the client application. Before this, they were mapped
to buttons 4/5. But, button 4/5 are for the scroll wheel, and as
mentioned above, BTN_{BACK,FORWARD} are not the same as scroll wheel
"buttons".

Closes #1763
2024-07-13 10:41:10 +02:00
Daniel Eklöf
22c8637610
osc: extend damage-cells-by-color to default fg/bg as well
When changing part of the color palette, through either OSC-4, or
OSC-10 and OSC-11 (and the corresponding reset OSCs: 104, 110 and
111), only dirty affected cells.

We've always done this, but only for OSC-4.

This patch breaks out that logic, and extends it to handle default
fg/bg too.

It also fixes a bug where cells with colored underlines were not
dirtied if the underline was the only part of the cell that was
affected by a OSC-4 change.
2024-07-03 10:53:33 +02:00
Daniel Eklöf
dd6fc99ae1
csi: implement XTPUSHCOLORS+XTPOPCOLORS+XTREPORTCOLORS
The documentation of these sequences are vague and lacking, as is
often the case with XTerm invented control sequences.

I've tried to replicate what XTerm does (as of xterm-392).

The stack represents *stashed/stored* palettes. The currently active
palette is *not* stored on the stack.

The stack is dynamically allocated, and starts out with zero elements.

Now, XTerm has a somewhat weird definition of "pushing" and "popping"
in this context, and the documentation is somewhat misleading.

What a push does is this: it stores the current palette to the stack
at the specified slot. If the specified slot number (Pm) is 0, the
slot used is the current slot index incremented by 1.

The "current" slot index is then set to the specified slot (which is
current slot + 1 if Pm == 0).

Thus, "push" (i.e. when Pm == 0 is used) means store to the "next"
slot. This is true even if the current slot index points into the
middle of stack.

Pop works in a similar way. The palette is restored from the specified
slot index. If the specified slot number is 0, we use the current slot
index.

The "current" slot index is then set to the specified slot -
1 (current slot - 1 if Pm == 0).

XTREPORTCOLORS return the current slot index, and the number of
palettes stored on the stack, on the format

    CSI ? <slot index> ; <palette count> # Q

When XTPUSHCOLORS grows the stack with more than one element (i.e. via
a 'CSI N # P' sequence), make sure *all* new slots are initialized (to
the current color palette). This avoids uninitialized slots, that
could then be popped with XTPOPCOLORS.

Closes #856
2024-07-03 09:47:30 +02:00
Daniel Eklöf
5d4a002413
osc: merge OSC 10/11/12/17/19 handling
10/11/17/19 were already merged, so this patch just stops special
casing 12 (cursor color).

In preparation for XTPUSHCOLORS/XTPOPCOLORS, the cursor colors are
moved from their own struct, into the 'colors' struct.

Also fix a bug where OSC 17/19 queries returned OSC-11 data.
2024-07-03 09:47:30 +02:00
Craig Barnes
674a535fc3 Rename various uses of "curly" in the source code with "underline"
Since "curly" could make it seem as if all underline styles are curled
(to people unfamiliar with the codebase), whereas in reality only 1 is.
2024-07-01 20:00:16 +01:00
Daniel Eklöf
48cf57818d
term: performance: use a bitfield to track which ascii printer to use
The things affecting which ASCII printer we use have grown...

Instead of checking everything inside term_update_ascii_printer(), use
a bitfield.

Anything affecting the printer used, must now set a bit in this
bitfield. This makes term_update_ascii_printer() much faster, since
all it needs to do is check if the bitfield is zero or not.
2024-06-26 18:39:24 +02:00
Daniel Eklöf
22302d8bcc
term: term_fill(): only set OSC-8 + styled hyperlinks when use_sgr_attrs is set 2024-06-26 18:39:24 +02:00
Daniel Eklöf
3b738c6e68
terminal: term_fill(): fix osc8 erase bug + handle styled underlines
Only clear OSC-8 hyperlinks at the target columns if we don't have an
active OSC-8 URI. This corresponds to normal VT attributes; the
currently active attributes are set, and all others are cleared.

Handle styled underlines in the same way
2024-06-26 18:39:24 +02:00
Daniel Eklöf
32effc6657
csi: wip: styled underlines
This is work in progress, and fairly untested.

This adds initial tracking of styled underlines. Setting attributes
seems to work (both color and underline style). Grid reflow has *not*
been tested.

When rendering, style is currently ignored (all styles are rendered as
a plain, legacy underline).

Color however, *is* applied.
2024-06-26 18:39:23 +02:00