Commit graph

743 commits

Author SHA1 Message Date
Alexander Orzechowski
de3becef96
Revert "config: don't allow colors.flash-alpha to be 1.0"
This reverts commit 56d2c3e990.
2025-01-18 09:23:41 +01:00
Alexander Orzechowski
881eb28134
render: Expose render_overlay
This function updates the overlay that foot uses. It will be used to
update the overlay when the flash effect ends.
2025-01-18 09:23:39 +01:00
Daniel Eklöf
f5c10a2452
render: fix order we're checking custom codepoints
Fixes a crash when trying to print a "Legacy Computing"
symbol (U+1FB00-U+1FB9B).

Closes #1901
2025-01-03 07:33:14 +01:00
Daniel Eklöf
56d2c3e990
config: don't allow colors.flash-alpha to be 1.0
A compositor will not send a frame callback for our main window if it
is fully occluded (for example, by a fully opaque overlay...). This
causes the overlay to stuck.

For regular buffers, it _should_ be enough to *not* hint the
compositor it's opaque. But at least some compositor special cases
single-pixel buffers, and actually look at their pixel value.

Thus, we have two options: implement frame callback handling for the
overlay sub-surface, or ensure we don't use a fully opaque
surface. Since no overlays are fully opaque by default, and the flash
surface is the only one that can be configured to be
opaque (colors.flash-alpha), and since adding frame callback handling
adds a lot of boilerplate code... let's go with the simpler solution
of
2025-01-02 09:10:51 +01:00
Daniel Eklöf
9a1b59adae
box-drawings: implement octants 2024-12-08 12:55:57 +01:00
Daniel Eklöf
e891abdd6a
render: remove unnecessary call to wl_surface_damage_buffer()
The damage region(s) are translated to wl_surface_damage_buffer()
calls after the entire frame has been rendered.
2024-10-06 11:26:35 +02:00
Daniel Eklöf
ce38f5b413
render: sixels: update damage region when rendering sixels
This fixes flickering when foot is forced to double-buffer (e.g when
running under KDE, or smithay based compositors).

Since the damage region isn't updated, the sixel images aren't
included in the memcpy that is done to transfer the last frame's
updated regions to the next frame.

As a result, every other frame will have the sixels, while the others
don't.

Closes #1851
2024-10-05 08:55:48 +02:00
Daniel Eklöf
6ad84dab2d
render: do dirty/clean consistency check before rendering sixels
Since the sixels may render some of the cells, we want the check to
happen before the sixels.
2024-09-21 09:11:28 +02:00
Daniel Eklöf
798b44934f
render: double-buffer: optimization: skip clean rows
When scanning the grid for all-dirty rows (that we can remove from the
damage region we're about to memcpy from the old frame), check the
row->dirty bit, and skip scanning the cells of that row altogether.

We're only looking for rows where all cells are dirty - those rows can
be removed from the region we copy from the old frame, since the
entire row will be re-rendered anyway.

If a row is clean, it *must* be copied from the old frame.
2024-09-21 09:11:07 +02:00
Daniel Eklöf
a9fefcf58b
render: (debug): assert row->dirty vs. cell->attrs.clean consistency 2024-09-21 09:11:07 +02:00
Daniel Eklöf
e2aeb7f336
render: xcursor_is_valid(): don't crash when there's no theme loaded
When trying to set a custom cursor shape, we first validate it. This
is done by checking against known server-side names, and then trying
to load the cursor from the client side cursor theme.

But, if we're using server side names, there is no theme loaded, and
foot crashed.

Fix by checking if we have a theme loaded, and if not, fail the cursor
shape name validation.
2024-09-21 09:10:48 +02:00
Daniel Eklöf
297cb370aa
render: add missing include, limits.h 2024-09-15 09:56:41 +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
Daniel Eklöf
b34137dde3
toplevel-icon: set to app-id, instead of hardcoding to "foot"
And, special case "footclient", and map it to "foot".
2024-09-13 09:04:17 +02:00
Daniel Eklöf
1925593a37
render: resize(): don't overflow the number of scrollback lines
The config system allows setting the scrollback lines to
2**32-1.

However, the total number of grid lines is the scrollback lines plus
the window size, and then rounded *up* to the nearest power of two.

Furthermore, the number of rows is represented with a plain 'int'
throughout the code base.

The largest positive integer that fits in an int is 2**31-1. That
however, is not a power of two.

The largest positive integer, that also is a power of two, that fits
in an int is 2**30, or 1073741824.

Ideally, we'd just cast the line count to a 64-bit integer, and call
__builtin_clzl{,l}() on it, and then take the smallest value of that,
or 2**30. But, for some reason, __builtin_clzl(), and
__builtin_clzll() appears to ignore bits above 32, despite they being
typed to long and long long. Bug?

Instead, ensure we never call __builtin_clz() on anything larger than
2**30.

Closes #1828
2024-09-09 06:58:52 +02:00
Oleh Hushchenkov
b47a4dd255
add setting for strikeout thickness 2024-08-26 19:34:47 +02:00
tokyo4j
a2fc2a986e
render: follow cursor.unfocused-style regardless of cursor.style
Before this commit, cursor.unfocused-style was effective only with
cursor.style=block
2024-08-20 06:59:33 +02:00
Daniel Eklöf
bef613e656
csd: track pointer when rendering and handling CSD button clicks
* Render button as highlighted only when pointer is above them
* Releasing the mouse button while *not* on the button does *not*
  activate the button

When pressing, and holding, a mouse button, the compositor keeps
sending motion events for the surface where the button was pressed,
even if the mouse has moved outside it.

We also don't get any surface leave/enter events.

This meant that the button was rendered as highlighted, and a click
registered, if the user pressed the mouse button while on the button,
and then moved the cursor away from the button before releasing the
button.

This patch fixes it, by checking if the current cursor coordinates
fall within the button surface.
2024-08-09 08:20:59 +02:00
Daniel Eklöf
a9e462d952
Remove a number of unused includes 2024-08-02 08:28:13 +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
56556e5f23
render: hollow-cursor: use correct cursor color 2024-07-13 10:37:21 +02:00
Daniel Eklöf
c46c124363
render: cursor: use default fg/bg if cell fg/bg are the same
When deciding which colors to use for the cursor, and the cursor text
and background colors are the same, use the default fg/bg instead.

Closes #1761
2024-07-13 10:30:23 +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
970b95509c render: fix "maybe-uninitialized" error in draw_styled_underline()
Reproducer:

    CFLAGS='-Og -g' meson setup --buildtype=debug bld
    ninja -C bld

Error message:

    ../render.c: In function ‘draw_styled_underline’:
    ../render.c:490:19: error: ‘y_ofs’ may be used uninitialized
    [-Werror=maybe-uninitialized]
      490 |         const int top = y + y_ofs;
          |                   ^~~
    ../render.c:405:9: note: ‘y_ofs’ was declared here
      405 |     int y_ofs;
          |         ^~~~~
2024-07-03 06:55:01 +01: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
7341ba5ee3
render: cursor color: remove assertion that both cursor fg/bg be set
Before this patch, we asserted both the cursor foreground, and
background colors had been set. This is true in most cases; the config
system enforces it.

It is however possible to set only the cursor background color, while
leaving the foreground (text) color unset:

* Use a foot config that does *not* configure the cursor colors. This
  means foot will invert the default fg/bg colors when rendering the
  cursor.
* Override the cursor color using an OSC-12 sequence. OSC-12 only sets
  the background color of the cursor, and there is no other OSC sequence
  to set the cursor's text color.

To handle this, remove the assertion, and simply split the logic for
the cursor backgound and foreground colors:

* Use the configured background color if set (either through config or
  OSC-12), otherwise use the default foreground color.
* Use the configured foreground color if set (through config),
  otherwise use the default background color.
2024-07-01 10:53:21 +02:00
Daniel Eklöf
0c7725217a
render: draw_styled_underline(): respect main.underline-thickness
Also refactor a bit, and break out early to draw_underline() for
legacy underlines.
2024-06-27 19:21:23 +02:00
Daniel Eklöf
19bf558e6c
render: underlines: improve the appearance of the 'dotted' style
Try to make the 'dotted' style appear more even, and less like each
cell is rendered separately (even though they are).

Algorithm:

Each dot is a square; it's sides are that of the font's line
thickness.

The spacing (gaps) between the dots is initially the same width as the
dots themselves.

This means the number of dots per cell is the cell width divided by
the dots' length/width, divided by two.

At this point, there may be "left-over" pixels.I.e. the widths of the
dots and the gaps between them may not add up to the width of the
cell.

These pixels are evenly (as possible) across the gaps.

There are still visual inaccuracies at small font sizes. This is
impossible to fix without changing the way underlines are rendered, to
render an entire line in one go. This is not something we want to do,
since it'll make styled underlines, for a specific cell/character,
look differently, depending on the surrounding context.
2024-06-27 18:36:17 +02:00
Daniel Eklöf
08138e9546
render: underlines: minor perf-tweak: early break out
When looking up the extender underline range, break out early if we
see that there can't possibly be any ranges matching the current column.
2024-06-26 18:39:24 +02:00
Daniel Eklöf
963ce45f3f
render: resize: copy styled underlines to temporary grid
When doing an interactive resize, we create a small grid copy of the
current viewport, and then do a non-reflow resize.

When the interactive resize is done, we do a proper reflow. This is
for performance reasons.

When creating the viewport copy, we also need to copy the styled
underlines. Otherwise, styled underlines will be rendered as plain
underlines *while resizing*.
2024-06-26 18:39:23 +02:00
Daniel Eklöf
8e2402605e
render: styled underlines
This was originally contributed by @kraftwerk28 in
https://codeberg.org/dnkl/foot/pulls/1099

Here, we re-use the rendering logic only, as attribute tracking has
been completely rewritten.
2024-06-26 18:39:23 +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
Daniel Eklöf
708ca3d650
render: single-pixel: minor optimization
Don't re-create the single-pixel buffer, unless necessary.

The buffer itself doesn't have a size. That means we can re-use the
buffer if the last frame's overlay style matches the current frame's
style.

What we *do not* know is whether the current frame's size is the same
as the last frame's.

This means we still have to set the viewport destination, and commit
the surface.
2024-05-22 13:48:46 +02:00
Daniel Eklöf
3c96d0b68e
render: use single-pixel buffers for overlays, when possible
The unicode-mode, and flash overlays are single color buffers. This
means we can use the single-pixel buffer protocol.

It's undefined whether the compositor will release the buffer or not;
to make things easier, simply destroy the buffer as soon as we've
committed it.

Note that since compositors don't necessarily release single-pixel
buffers, we can't plug them into our own buffer interface. This means
we can't use buffer pointers to check if we can re-use the previous
buffer (i.e. we can skip comitting a new buffer), or if we have to
create a new one.

It's _almost_ enough to just check if the last overlay style is the
same as the current one. Except that that doesn't take window resizes
into account...
2024-05-22 13:48:46 +02:00
Daniel Eklöf
18b702b249
unicode-mode: move state from seat to term
This fixes an issue where entering unicode-mode in one foot client,
also enabled unicode-mode on other foot clients. Both
visually (although glitchy), and in effect.

The reason the state was originally in the seat objects, was to fully
support multi-seat. That is, one seat/keyboard entering unicode-mode
should not affect other seats/keyboards.

The issue with this is that seat objects are Wayland global. Thus, in
server mode, all seat objects are shared between the foot clients.

There is a similarity with IME, which also keeps state in the
seat. There's one big difference, however, and that is IME has Wayland
native enter/leave events, that the compositor emits when windows are
focused/unfocused. These events allow us to reset IME state. For our
own Unicode mode, there is nothing similar.

This patch moves the Unicode state from seats, to the terminal
struct. This does mean that if one seat/keyboard enters Unicode mode,
then *all* seats/keyboards will affect the unicode state. This
potential downside is outweighed by the fact that different foot
clients no longer affect each other.

Closes #1717
2024-05-21 08:36:56 +02:00
Daniel Eklöf
e5a2ac4b57
config: add cursor.unfocused-style
This option controls how we render the cursor when the terminal window
is unfocused.

Possible values are:

* hollow: the default, and how we rendered the cursor before this
  patch.
* unchanged: render the cursor exactly the same way as when the window
  is focused.
* none: do not render any cursor at all

Closes #1582
2024-04-10 16:24:10 +02:00
Daniel Eklöf
578765ad83
wayland: skip loading cursor theme when using server side cursors
We don't need the client side cursor theme when using server side
cursors.
2024-03-16 15:36:44 +01:00
Daniel Eklöf
d3b348a5b1
cursor-shape: improve xcursor fallback support, and prefer CSS names
Before this patch, we used legacy X11 xcursor names, and didn't really
have any fallback handling in place (we only tried to fallback to
"xterm", regardless of which cursor shape we were trying to load).

This patch changes two things:

1. Improved fallback support. cursor_shape_to_string() now returns a
   list of strings. This allows us to have per-shape fallbacks, and any
   number of fallbacks.

2. We prefer CSS xcursor names over legacy X11 names.
2024-03-01 07:04:48 +01:00
Daniel Eklöf
6fd533ce13
render: don't try to set a NULL xcursor image
render_xcursor_update() is called when we've loaded a new xcursor
image, and needs to display it. The reason it's not pushed to the
compositor immediately is to ensure we don't flood the Wayland socket
with xcursor updates.

Normally, it's only called when we *succeed* to load a new xcursor
image. I.e. if we try to load a non-existing xcursor image, we never
schedule an update.

However, we _can_ still end up in render_xcursor_update() without a
valid xcursor image. For example, we have loaded a valid xcursor
image, and scheduled an update. But before the update runs, the user
moves the cursor, and we try to load a new xcursor image. If it fails,
we crash when the previously scheduled update finally runs.

Closes #1624
2024-02-29 08:16:20 +01:00
Daniel Eklöf
67f97cbca1
shm: use XRGB surfaces when we know we wont be using transparency 2024-02-21 16:29:10 +01:00
Daniel Eklöf
c114afadbd
render: always center grid when fullscreened or maximized 2024-02-15 16:54:01 +01:00
delthas
6c56b04b3f
osc: add support for osc 176 (app ID)
This adds support for a new OSC escape sequence: OSC 176, that lets
terminal programs tell the terminal the name of the app that is
running. foot then sets the app ID of the toplevel to that ID,
which lets the compositor know which app is running, and typically
sets the appropriate icon, window grouping, ...

See: https://gist.github.com/delthas/d451e2cc1573bb2364839849c7117239
2024-02-06 13:50:09 +01:00
Daniel Eklöf
4801d3a305
term: drop term->render.title.is_armed
This boolean isn't needed. The idea was probably to not re-program the
timer unnecessarily, or even to prevent it from being moved forward in
time indefinitely.

However, the logic has (probably) gone through some changes, that now
makes it irrelevant.

The timer isn't moved forward indefinitely; it is always set to 8ms
from the last title update. The closer we get to that point in time,
the smaller the timeout we set.

Now, is_armed _did_ prevent the timer from being re-programmed. But
that tiny performance tweak isn't really necessary, as the title
should, in normal cases, not be set that often anyway.
2024-02-06 13:41:09 +01:00
Daniel Eklöf
7999975016
Don't use fancy Unicode quotes, stick to ASCII 2024-02-06 12:36:45 +01:00
Andrew J. Hesford
21a8d832ce
feature: add resize-by-cells option to constrain window sizes...
...to multiples of the cell size, and preserve grid size when changing
fonts or display scales in floating windows.
2024-02-05 12:14:53 +01:00
Craig Barnes
e0f3703ae6
util: add streq() function and use in place of strcmp(...) == 0 2024-02-05 12:09:52 +01:00
Craig Barnes
91b22ae21a Replace unchecked allocations with calls to xmalloc.h functions 2024-01-25 07:03:50 +00:00
Daniel Eklöf
3dbb86914c
render: sixel: regression: wrong cell color behind opaque sixels
An opaque sixel that isn't a multiple of the cell size will have some
cells partially visible (either the entire last row, the entire last
column, or both).

These must be rendered before blitting the sixel.

f5f2f5a954 introduced a regression,
where all such cells were rendered as if the cursor was there, giving
them the wrong appearance.

Closes #1520
2023-10-13 18:44:44 +02:00
Daniel Eklöf
f5f2f5a954
render: fix surface damage when rendering sixels.
Pass a damage region to render_row()/render_cell() when rendering
partially visible cells underneath a sixel.

This ensures the affected regions are later reported as 'damaged' to
the Wayland compositor.

Closes #1515
2023-10-12 16:32:00 +02:00
Daniel Eklöf
4449177517
term: cache font baseline
No need to redo the calculation for every single cell we render,
every frame...
2023-10-10 14:23:33 +02:00