Commit graph

320 commits

Author SHA1 Message Date
Daniel Eklöf
d48a1c53f5
meson: require wayland-protocols >= 1.41 2025-03-13 13:28:34 +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
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
c6208a98c8
main: include toplevel-icon support in --version output 2024-09-13 09:04:18 +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
0cb07027f2
wayland: set toplevel icon
If the xdg-toplevel-icon-v1 protocol is available, and we have the
corresponding manager global, set the toplevel icon to "foot".

Note: we do *not* provide any pixel data. This is by design; we want
to keep things simple.

To be able to provide pixel data, we would have to either:

* embed the raw pixel data in the foot binary
* link against either libpng or/and e.g. nanosvg, locate, at run-time,
  the paths to our own icons, and load them at run-time.
* link against either libpng or/and e.g. nanosvg, and, at run-time, do
  a full icon lookup. This would also require us to add a config option
  for which icon theme to use.

Of the two, I would prefer the first option. But, let's skip this
completely for now.

By providing the icon as a name, the compositor will have to lookup
the icon itself. Compositors supporting icons is likely to already
support this.

So what do we gain by implementing this protocol? Compositors no
longer has to parse .desktop files and map our app-id to find the icon
to use.

There's one question remaining. With this patch, the icon name is
hardcoded to "foot", just like our .desktop files. But, perhaps we
should use the app-id instead? And if so, should we also change the
icon when the app-id changes?

My gut feeling is, yes, we should use the app-id instead, and yes, we
should update the icon when the app-id is changed at run-time.
2024-09-13 09:04:17 +02:00
Daniel Eklöf
28a1c67dd5
wayland: bind the xdg-toplevel-icon manager global 2024-09-13 09:04:17 +02:00
Daniel Eklöf
69f56b86b7
wayland: add wayl_activate()
wayl_activate() takes an XDG activation token and does an XDG
activation request.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
e11a4ab6af
wayland: #ifdef guard code related to wl_shm_release() 2024-07-18 14:27:40 +02:00
Daniel Eklöf
4f25e1ba9f
wayland: use wl_shm v2 if available 2024-07-18 08:23:25 +02:00
Daniel Eklöf
c45231ef89
input: don't reset the XKB compose state in keymap()
When the compositor sends a new keymap, don't reset the XKB compose
state.

This is done by initializing the XKB context, along with the compose
state, when binding the seat, instead of in keymap().

Then, in keymap(), simply stop destroying the old xkb state. Only
destroy, and re-create the keymap state.

Closes #1744
2024-06-22 08:00:13 +02:00
Daniel Eklöf
aea16ba5d2
input: implement wl_pointer::axis_value120()
This implements high resolution mouse wheel scroll events. A "normal"
scroll step corresponds to the value 120. Anything less than that is a
partial scroll step.

This event replaces axis_discrete(), when we bind wl_seat v8 (which we
now do, when available).

We calculate the number of degrees that is required to scroll a single
line, based off of the scrollback.multiplier value.

Each high-res event accumulates, until we have at least the number of
degress required to scroll one, or more lines.

The remaining degrees are kept, and added to in the next scroll event.

Closes #1738
2024-06-18 14:09:03 +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
e753bb953b
wayland: remove has_wl_compositor_v6
We deviate slightly from the specification, in that we don't assume a
preferred buffer scale of 1. Instead, we "guess" the scale *until we
receive a surface_preferred_buffer_scale event.

Because of this, we don't need the has_wl_compositor_v6 member, as
it's enough to check if we have a non-zero 'preferred buffer scale'.
2024-04-12 15:35:25 +02:00
Daniel Eklöf
88a3b54ca3
wayland: only use the surface preferred scale if set by the compositor
Before this patch, we would, in some cases, fallback to the surface
preferred (not fractional) scaling, even though the compositor hadn't
actually published a preferred buffer scale; the presence of a v6
compositor interface doesn't mean we've actually received a preferred
scale yet.
2024-04-05 16:19:47 +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
67f97cbca1
shm: use XRGB surfaces when we know we wont be using transparency 2024-02-21 16:29:10 +01:00
Daniel Eklöf
bc8c2e0112
wayland: regression: use correct scaling factor when calling render_resize()
When an output property (such as scaling factor) has changed, we need
to call render_resize() to ensure the window surface is correct (for
example, we may have to change its scale).

The width/height parameters are in *logical* pixels (i.e. already
scaled). For render_resize() to work correctly when the scale is being
changed, it needs to be called with *current* logical size. This means
we need to scale our current width/height using the *old* scaling
factor.
2024-02-07 16:22:33 +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
Daniel Eklöf
43e27a8843
wayland: 'mode' is unused when LOG_ENABLE_DBG is not set 2024-01-24 20:00:18 +01:00
Leonardo Hernández Hernández
7e3da3007b
wayland: use wl_compositor version 6 when available 2024-01-24 20:00:18 +01:00
Daniel Eklöf
a2283c8229
wayland: surface_scale_explicit_width_height(): dont assert width/height are valid for scale, take 2
764248bb0d modified
wayl_surface_scale_explicit_width_height() to not assert the surface
size is valid for the given scaling factor. This, since that function
is only used when scaling a mouse pointer surface.

However, that commit only updated the code path run when fractional
scaling is available (i.e. when the compositor implements the
fractional-scale-v1 protocol).

The legacy code path, that does integer scaling, was still asserting
the surface width/height were divisible with the scaling factor.

For the same reasons this isn't true with fractional scaling
available, it's not true with integer scaling. Fix by skipping the
assertions.

This patch also converts the assertions to more verbose BUG() calls,
that prints more information on the numbers involved.

Closes #1573
2024-01-09 16:47:41 +01:00
Daniel Eklöf
883368572f
wayland: debug: log wm-capabilities as human-readable strings 2023-10-02 16:34:54 +02:00
Daniel Eklöf
b2963bbf80
changelog: crash when xdg token is set, but compositor does not support activation 2023-09-21 18:31:46 +02:00
Alyssa Ross
9257273d84
wayland: check activation supported before activating
It's possible for token to be set when the compositor doesn't support
activation, and this caused a segfault.  For example, this can happen
when overriding WAYLAND_DISPLAY to point to a compositor that doesn't
support activation, in a terminal running under one that does, and so
has set XDG_ACTIVATION_TOKEN.
2023-09-21 06:59:48 +00:00
CismonX
f0f0d02bf7
input: improve touch handling on pointer presense
No longer inhibits touch event handling when terminal window
has pointer focus.  Instead, inhibit touch event when at least
one pointer button is held down.

This change improves user experience when using foot with both
a mouse and a touchscreen.

Closes #1428.
2023-08-24 00:45:20 +08:00
Daniel Eklöf
698c5b54f3
wayland: cursor-shape-v1 is now always available
Since we're requiring wayland-protocols >= 1.32
2023-08-07 16:53:19 +02:00
Daniel Eklöf
7eee415b75
wayland: fractional-scale-v1 is now always available
Since we're requiring wayland-protocols >= 1.32
2023-08-07 16:53:19 +02:00
Daniel Eklöf
d59a4e7a77
wayland: xdg-activation is now always available
Since we're requiring wayland-protocols >= 1.32
2023-08-07 16:53:19 +02:00
Daniel Eklöf
764248bb0d
wayl_surface_scale_explicit_width_height(): don’t assert width/height are valid for scale
This function is only called directly when scaling the mouse
pointer. The mouse pointer is never guaranteed to have a valid width
and height, so skip the width/height assertions for it.
2023-07-29 08:18:00 +02:00
Daniel Eklöf
1782474481
fractional scaling: another round(!) of rounding fixes
* Ensure buffer sizes are valid. That is, ensure that
  size / scale * scale == size.
* Do size calculation of the window geometry in the same way we
  calculate the CSD offsets.
2023-07-28 16:03:13 +02:00
Daniel Eklöf
9d75c55146
wayland: don't try to use a non-existing viewporter interface
When instantiating the viewport for a pointer surface, we didn't first
check if the compositor implements the viewporter interface.

This triggered a crash when a) foot was compiled with fractional
scaling, and b) the compositor did not implement the viewporter
interface.

Closes #1444
2023-07-28 15:42:28 +02:00
Daniel Eklöf
613c61abb4
scaling: always round the scaling factor when converting to int
* In all calls to wl_subsurface_set_position()
* (wp_viewport_set_destination() already does this)
* Whenever we use the scale to calculate margins (search box,
  scrollback indicator etc)
* Since the scaling factor is stored as a float (and not a double),
  use roundf() instead of round()
2023-07-25 16:48:50 +02:00
Daniel Eklöf
0a61cfc3be
wayland: update terminals (fonts etc) on xdg_output_handle_done()
Monitor DPI depends on information from both the wl_output and the
xdg_output interfaces.

Before this patch, terminals were only updated after changes to the
wl_output interfaces (thus depending on xdg output changes being
pushed by the compositor before wl_output changes).

That assumption (xdg_output happening before wl_output) isn’t always
true.

This patch fixes the issue by updating the terminals in the
xdg_output’s “done” event.

Closes #1431
2023-07-23 20:12:13 +02:00
xdavidwu
0b8791d1c5
wayland: fix pointer cap lost handling
Before this, on compositor without cursor-shape support, a pointer
capability lost of the seat makes foot crash.
2023-07-18 16:09:31 +02:00
Daniel Eklöf
21d99f8dce
terminal: break out scaling factor updating, and reduce number of calls to render_resize()
Break out the logic that updates the terminal’s scaling factor value,
from render_resize(), to a new function, term_update_scale(). This
allows us to update the scaling factor without a full grid resize.

We also change how we pick the scaling factor (when fractional scaling
is not in use). Before, we’d use the highest scaling factor from all
monitors we were mapped on. Now, we use the scaling factor from the
monitor we were *last* mapped on.

Then, add a boolean parameter to term_set_fonts(), and when
false, *don’t* call render_resize_force().

Also change term_font_dpi_changed() to only return true if the font
was changed in any way.

Finally, rewrite update_term_for_output_change() to:

* Call term_update_scale() before doing anything else
* Call render_resize{,_force} *last*, and *only* if either the scale
  or the fonts were updated.

This fixes several things:

* A bug where we failed to update the fonts when fractional scaling
  was in use, and we guessed the initial scale/DPI wrong. The bug
  happened because updated the internal "preferred" scale value, and a
  later call to render_resize() updated the terminal’s scale value,
  but since that code path didn’t call term_font_dpi_changed() (and it
  shouldn’t), the fonts weren’t resized properly.

* It ensures we only resize the grid *once* when the scaling factor,
  or DPI is changed. Before this, we’d resize it twice. And this
  happened when e.g. dragging the window between monitors.
2023-07-18 05:48:01 +02:00
Daniel Eklöf
c96863b188
wayland: error out if there aren’t any monitors available 2023-07-18 05:48:01 +02:00
Daniel Eklöf
b2a29280cb
wayland: use physical DPI on fractional-scale capable compositors
With legacy scaling, we need to use a "scaled", or "logical" DPI
value, that is basically the real DPI value scaled by the monitor’s
scaling factor.

This is necessary to compensate for the compositor downscaling the
surface, for "fake" fractional scaling.

But with true fractional scaling, *we* scale the surface to the final
size. This means we should *not* use the scaled DPI, but the monitor’s
actual DPI.

To facilitate this, store both the scaled and the unscaled DPI value
in the monitor struct.

This patch also changes how we pick the DPI value. Before, we would
use the highest DPI value from all the monitors we were mapped
on. Now, we use the DPI value from the monitor we were *last* mapped
on (typically the window we’re dragging the window *to*).
2023-07-18 05:48:01 +02:00
Daniel Eklöf
59f0a721c4
wayland: fractional_scale_preferred_scale(): only push update if scale has changed
Also, drop wl_window::have_preferred_scale. Check for scale > 0 instead.
2023-07-18 05:48:01 +02:00
Ronan Pigott
b7100d5716 render: use rounding for fractional scale
If we truncate the buffer dimensions we may accidentally submit a
buffer with inappropriate size.
2023-07-15 20:03:16 -07:00
CismonX
d2fcb5343f
input: add basic support for touchscreen input
Closes #517
2023-07-05 16:22:28 +02:00
Daniel Eklöf
c2baaff3c1
cursor-shape: use server-side cursors for custom (OSC-22), if possible
Using a lookup table, try to map the user-provided xcursor string to a
cursor-shape-v1 known shape.

If we succeed, set the user’s custom cursor using server side
cursors (i.e. using cursor-shape-v1).

If not, fallback to trying to load the image ourselves (using
wl_cursor_theme_get_cursor()), and set it using the legacy
wl_pointer_set_cursor().
2023-07-03 14:36:32 +02:00
Daniel Eklöf
c8e13ad393
cursor-shape: add support for server side cursor shapes
This implements support for the new cursor-shape-v1 protocol. When
available, we use it, instead of client-side cursor surfaces, to
select the xcursor shape.

Note that we still need to keep client side pointers, for:

* backward compatibility
* to be able to "hide" the cursor

Closes #1379
2023-07-03 14:36:32 +02:00
Daniel Eklöf
72bc0acfbd
wayland: handle enum value XDG_TOPLEVEL_STATE_SUSPENDED
Added in wayland-protocols-1.32
2023-07-03 14:36:03 +02:00
Daniel Eklöf
5e305fa854
wayland: typo: ‘.’ -> ‘;’
Closes #1392
2023-06-30 08:24:02 +02:00
Daniel Eklöf
ce31cc518a
wayland: surface_scale(): reset buffer scale when using fractional scaling
Since the first frame uses legacy scaling, the surface may have a
buffer scale > 1, which isn’t allowed.
2023-06-29 15:38:24 +02:00
Daniel Eklöf
c61247f317
wayland: surface_scale(): improve debug logging 2023-06-29 15:38:24 +02:00
Daniel Eklöf
8f74b1090a
wayland: use legacy scaling until fractional_scale::preferred_scale() has been called
This way, the initial frame is more likely to get scaled correctly;
foot will guess the initial (integer) scale from the available
monitors, and use that. By using legacy scaling, we force the
compositor to down-scale the image to the correct scale factor.

If we use the new fraction scaling method with an integer scaling
factor, the initial frame gets rendered way too big.
2023-06-29 15:38:24 +02:00