Commit graph

483 commits

Author SHA1 Message Date
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
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
051cd6ecfc
config+url: add support for user-defined regex patterns
Users can now define their own regex patterns, and use them via key
bindings:

    [regex:foo]
    regex=foo(bar)?
    launch=path-to-script-or-application {match}

    [key-bindings]
    regex-launch=[foo] Control+Shift+q
    regex-copy=[foo] Control+Mod1+Shift+q

That is, add a section called 'regex:', followed by an
identifier. Define a regex and a launcher command line.

Add a key-binding, regex-launch and/or regex-copy (similar to
show-urls-launch and show-urls-copy), and connect them to the regex
with the "[regex-name]" syntax (similar to how the pipe-* bindings
work).
2025-02-05 13:35:17 +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
9a1b59adae
box-drawings: implement octants 2024-12-08 12:55:57 +01:00
Daniel Eklöf
511aad419b
config: add color.sixelN options
These options allows you to configure the default sixel color palette.
2024-10-23 08:35:30 +02: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
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
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
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
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
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
45f4eb48fb
grid: refactor: remove union range_data_for_insertion
This union is identical to row_range_data, except the URI char pointer
is const. Let's ignore that, and re-use row_range_data, casting the
URI pointer when necessary.

Also remove uri_range_insert() and curly_range_insert(), and use the
generic version of range_insert() everywhere.
2024-06-26 18:39:24 +02: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
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
20923bb2e8
grid: refactor: first step towards a more generic range handling 2024-06-26 18:39:23 +02:00
Daniel Eklöf
8716ca5784
url-mode: disable IME mode while URL-mode is active
This prevents the IME from stealing "our" key-presses, and thus
preventing the user from opening URLs.

Closes #1718, hopefully.
2024-05-21 08:37:39 +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
7c20fb247c
term: stash last known DPI, and use after a unmapped/mapped sequence
A compositor may unmap, and then remap the window, for example when
the window is minimized, or if the user switches workspace.

With DPI aware rendering, we *need* to know on which output we're
mapped, in order to use the correct DPI. This means the first frame we
render, before being mapped, always guesses the DPI.

In an unmap/map sequence, guessing the wrong DPI means the window will
flicker.

Fix by stashing the last used DPI value, and use that instead of
guessing.

This means the *only* time we _actually_ guess the DPI, is the very
first frame, when starting up foot.
2024-04-17 09:14:52 +02:00
Daniel Eklöf
7f4328e0b1
term: send SIGHUP before SIGTERM when shutting down
If we're the ones initiating shutdown, start by sending SIGHUP. Only
if the client application does not terminate, send SIGTERM (and if it
still refuses to terminate, send SIGKILL).

Also reduce the timeout between the signals from 60s to 30s.
2024-04-05 19:34:17 +02:00
Daniel Eklöf
cb820a498b
sixel: RA region does not affect the text cursor position
The raster attributes is, really, just a way to erase an area. And, if
the sixel is transparent, it's a nop.

The final text cursor position depends, not on our image size (which
is based on RA), but on the final graphical cursor position.

However, we do want to continue using it as a hint of the final image
size, to be able to pre-allocate the backing buffer.

So, here's what we do:

* When trimming trailing transparent rows, only trim the *image*, if
  the graphical cursor is positioned on the last sixel row, *and* the
  sixel is transparent.
* Opaque sixels aren't trimmed at all, since RA in this acts as an
  erase that fills the RA region with the background color.
* The graphical cursor position is always adjusted (i.e. trimmed),
  since it affects the text cursor position.
* The text cursor position is now calculated from the graphical cursor
  position, instead of the image height.
2024-03-18 17:11:26 +01:00
Daniel Eklöf
cc660bc7c1
sixel: trim trailing, fully transparent sixel rows
See https://github.com/hpjansson/chafa/issues/192
2024-03-18 17:09:20 +01:00
Alyssa Ross
86894a1cd2
Add support for opening an existing PTY
Virtual machine monitor programs (e.g. QEMU, Cloud Hypervisor) expose
guest consoles as PTYs.  With this patch, foot can access these guest
consoles.

Usually, the program used for accessing these PTYs is screen, but
screen is barely developed, doesn't support resizing, and has a bunch
of other unrelated stuff going on.  It would be nice to have a
terminal emulator that properly supported opening an existing PTY.
The VMM controls the master end of the PTY, so to the other end (in
this case foot), it just behaves like any application running in a
directly-opened PTY, and all that's needed is to change foot's code to
support opening an existing PTY rather than creating one.

Co-authored-by: tanto <tanto@ccc.ac>
2024-03-14 07:31:03 +01:00
Daniel Eklöf
23908d9277
term_fill(): change ‘character’ parameter from char -> uint8_t 2024-03-07 16:24:33 +01:00
Daniel Eklöf
b3a84ba71b
term: modify term_fill() to optionally reset the SGR attributes 2024-03-07 16:24:33 +01:00
Daniel Eklöf
189cfd717f
term: replace term_put_char() with term_fill() 2024-03-07 16:24:33 +01:00
Daniel Eklöf
ea851962c1
term: add term_put_char()
This function prints a single, non-double width, character to the
grid. It handles OSC-8 hyperlinks, but does not:

* update the cursor location
* erase sixels
2024-03-07 16:24:32 +01:00
Daniel Eklöf
1568518ab3
sixel: performance improvements
* Store pointer to current pixel (i.e. pixel we're about to write to),
  instead of a row-byte-offset. This way, we don't have to calculate the
  offset into the backing image every time we emit a sixel band.

* Pass data pointer directly to sixel_add_*(), to avoid having to
  calculate an offset into the backing image.

* Special case adding a single 1:1 sixel. This removes a for loop, and
  simplifies state (position) updates. It is likely LTO does this for
  us, but this way, we get it optimized in non-LTO builds as well.
2024-03-06 16:37:54 +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
Daniel Eklöf
1c70a84fde
config: add pipe-command-output key-binding 2024-02-06 12:12:57 +01:00
Daniel Eklöf
e9607de5ae
osc: store column of FTCS_COMMAND_{EXECUTED,FINISHED} in row struct 2024-02-06 12:12:57 +01:00
Daniel Eklöf
f8e875a7cd
term: move row->prompt_marker into new struct, row->shell_integration 2024-02-06 12:12:56 +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
9da7152f83
slave: don't skip setting environment variables when using a custom environment
When launching footclient with -E,--client-environment the environment
variables that should be set by foot, wasn't.

Those variables are:

* TERM
* COLORTERM
* PWD
* SHELL

and all variables defined by the user in the [environment] section in
foot.ini.

In the same way, we did not *unset* TERM_PROGRAM and
TERM_PROGRAM_VERSION.

This patch fixes it by "cloning" the custom environment, making it
mutable, and then adding/removing the variables above from it.

Instead of calling setenv()/unsetenv() directly, we add the wrapper
functions add_to_env() and del_from_env().

When *not* using a custom environment, they simply call
setenv()/unsetenv().

When we *are* using a custom environment, add_to_env() first loops all
existing variables, looking for a match. If a match is found, it's
updated with the new value. If it's not found, a new entry is added.

del_from_env() loops all entries, and removes it when a match is
found. If no match is found, nothing is done.

The mutable environment is allocated on the heap, but never free:d. We
don't need to free it, since it's only allocated after forking, in the
child process.

Closes #1568
2024-01-11 16:37:17 +01: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
Daniel Eklöf
4eef001d58
csi: implement DECSET/DECRST/DECRQM 2027 - grapheme cluster processing
This implements private mode 2027 - grapheme cluster processing, as
defined in the "Terminal Unicode Core"[1] specification.

Internally, we just flip the already existing option "grapheme
shaping". Since it's now runtime changeable, we need a copy of it in
the terminal struct, rather than referencing the conf object.

[1]: 13fc5a8993/spec/terminal-unicode-core.tex (L50-L53)
2023-09-25 16:50:44 +02:00
Daniel Eklöf
1719ff93a7
selection: add support for selecting the contents of a quote
This patch changes the default of triple clicking, from selecting the
current logical row, to first trying to select the contents of the
quote under the cursor, and if failing to find a quote, selecting the
current row (like before).

This is implemented by adding a new key binding, 'select-quote'.

It will search for surrounding quote characters, and if one is found
on each side of the cursor, the quote is selected. If not, the entire
row is selected instead.

Subsequent selection operations will behave as if the selection is
either a word selection (a quote was found), or a row selection (no
quote found).

Escaped quote characters are not supported: "foo \" bar" will match
'foo \', and not 'foo " bar'.

Mismatched quotes are not custom handled. They will simply not match.

Nested quotes ("123 'abc def' 456") are supported.

Closes #1364
2023-09-19 16:23:34 +02:00
Daniel Eklöf
86ef638102
term: improve fallback logic when selecting scaling factor while unmapped
The foot window may, for various reasons, become completely
unmapped (that is, being removed from all outputs) at run time.

One example is wlroots based compositors; they unmap all other windows
when an opaque window is fullscreened.

21d99f8dce introduced a regression,
where instead of picking the scaling factor from one of the available
outputs (at random), we started falling back to '1' as soon as we were
unmapped.

This patch restores the original logic, but also improves upon it.

As soon as a scaling factor has been assigned to the window, we store
a copy of it in the term struct ('scale_before_unmap').

When unmapped, we check if it has a valid value (the only time it
doesn't is before the initial map). If so, we use it.

Only if it hasn't been set do we fall back to picking an output at
random, and using its scaling factor.

Closes #1464
2023-08-18 16:48:18 +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
a36f67cbe3
render: apply new baseline calculation everywhere
* URL jump labels
* Scrollback position indicator
* Line/box drawings characters

Closes #1430
2023-07-25 15:53:29 +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
829353a5da
term: font_dpi_changed: scale (and old_scale) are floating point
This should fix an issue where the font size wasn’t updated when
moving the window between outputs whose scaling factors match when
truncated.
2023-07-18 05:48:01 +02:00