Commit graph

6151 commits

Author SHA1 Message Date
Daniel Eklöf
9fcf5977c0
sixel: fix cursor positioning when image is split up into several 2024-03-18 17:12:11 +01:00
Daniel Eklöf
bce1d7313d
sixel: hopefully handle image height correctly when trimming
When trimming trailing empty rows from the final image, handle the RA
region correctly:

* If image is transparent, trim down to the last non-empty pixel row,
  regardless of whether it is inside or outside the RA region.

* If image is opaque, trim down to either the last non-empty pixel
  row, or the RA region, whatever is the largest height.
2024-03-18 17:11:27 +01: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
Daniel Eklöf
282c55aa4a
sixel: place cursor on the last character row touched by the sixel
After emitting a sixel, place the cursor on the character row touched
by the last sixel. The last sixel _may_ not be a multiple of 6
pixels, *if* the sixel had an explicit width/height set via raster
attributes.

This is an intended deviation from the DEC cursor placement algorithm,
where the cursor is placed on the character row touched by the last
sixel's *upper* pixel.

The adjusted algorithm implemented here makes it much easier for
applications to handle text-after-sixels, since they can now simply
assume a single text newline is required to move the cursor to a
character row not touched by the sixel.
2024-03-18 16:58:54 +01:00
Craig Barnes
5f41eb798b base64: simplify lookup table initializer 2024-03-17 15:27:22 +00:00
Craig Barnes
e8b04e0e2c
xmalloc: add xmemdup() and use to replace some uses of xmalloc+memcpy 2024-03-17 12:31:02 +01:00
Craig Barnes
853be450bb main/config: replace some uses of xasprintf() with xstrjoin() 2024-03-16 20:17:53 +00: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
Craig Barnes
27330a5dd6
csi: indicate "permanently reset" for DECRQM queries of mode 67 (DECBKM)
This allows dynamic querying for the equivalent of terminfo's "kbs"
capability.
2024-03-16 15:36:00 +01:00
Daniel Eklöf
f17b989650
sixel: disable debug logging 2024-03-16 08:57:15 +01:00
Daniel Eklöf
60fd4a262c
sixel: initialize the color table to colors used by the VT340 2024-03-15 15:19:43 +01:00
Daniel Eklöf
dd3bb13d97
completions: fish: fix path completion for --pty 2024-03-14 07:37:57 +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
712bc95db3
csi: the CSI-t family of queries now report unscaled pixel values
Before this patch, we reported scaled pixel values. This was rather
useless, since applications have no way of getting the scaling factor,
to "scale up" e.g. images.

Furthermore, the most common use of these queries are probably to
calculate the dimensions to use when emitting sixels.

Closes #1643
2024-03-14 07:26:37 +01:00
Daniel Eklöf
f72555f29a
Merge branch 'rectangular-edit'
Closes #1633
2024-03-14 07:25:49 +01:00
Daniel Eklöf
e2b3eb91dd
csi: params_to_rectangular_area(): ensure left/right is within bounds 2024-03-10 17:37:11 +01:00
Daniel Eklöf
4ea4e5da4e
changelog: rectangular functions: add bug ref 2024-03-07 16:29:39 +01:00
Daniel Eklöf
cbf55ccacf
changeloge: move DECERA to the 'unreleased' section 2024-03-07 16:28:59 +01:00
Daniel Eklöf
6ff307b3b5
doc: ctlseq: DECCARA, DECRARA, DECCRA, DECFRA and DECERA 2024-03-07 16:26:11 +01:00
Daniel Eklöf
8d7ab86182
term_fill(): no need to set attrs.clean = 0
The VT state’s attribute is always 0
2024-03-07 16:25:04 +01:00
Daniel Eklöf
6a01642a6f
csi: DECCARA+DECRARA: dirty cells 2024-03-07 16:25:04 +01:00
Daniel Eklöf
aac24bfa1b
foot.info: add non-standard capability ‘Rect’ (used by tmux)
This tells tmux it can use DECFRA to erase rectangular regions.
2024-03-07 16:25:02 +01:00
Daniel Eklöf
60c5d889ec
vt: DECALN: erase sixels, reset margins, home the cursor
https://vt100.net/docs/vt510-rm/DECALN.html:

  Notes on DECALN

  DECALN sets the margins to the extremes of the page, and moves the
  cursor to the home position.
2024-03-07 16:24:34 +01:00
Daniel Eklöf
d6c5bc3262
csi: DECRARA: fix comment: DECCARA -> DECRARA 2024-03-07 16:24:33 +01:00
Daniel Eklöf
f5c574cd94
csi: DECCRA: no need for a counter here 2024-03-07 16:24:33 +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
1b13deff04
term_fill(): make sure the filled cells have their ‘clean’ bit reset 2024-03-07 16:24:33 +01:00
Daniel Eklöf
74a1fa9e00
vt: update DECALN to use term_fill() 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
1b66c6a3ac
csi: rectangular: add helper function params_to_rectangular_area()
This functions reads the four top/left/bottom/right parameters,
validates them, and converts relative row numbers to absolute.

Returns true if the params are valid, otherwise false.
2024-03-07 16:24:33 +01:00
Daniel Eklöf
df5dd94789
term: codespell: limitiations -> limitations 2024-03-07 16:24:33 +01:00
Daniel Eklöf
4b4fe9d493
changelog: rectangular edit functions 2024-03-07 16:24:33 +01:00
Daniel Eklöf
95293f142a
csi: add ‘28’ (rectangular edit) to primary DA response 2024-03-07 16:24:33 +01:00
Daniel Eklöf
926d88fd30
csi: implement rectangular edit escapes
* DECCARA - change attributes in rectangular area
* DECRARA - reverse attributes in rectangular area
* DECCRA - copy rectangular area
* DECFRA - fill rectangular area
* DECERA - erase rectangular area

Not implemented:

* DECSERA - selective erase rectangular area
2024-03-07 16:24:33 +01:00
Daniel Eklöf
b30b8a2944
put_char fixup 2024-03-07 16:24:32 +01:00
Daniel Eklöf
b4dbfb58b8
grid: remove prototype for non-existing function 2024-03-07 16:24:32 +01:00
Daniel Eklöf
e6c372b14f
term: print: spacers may be printed all the way up to the last column 2024-03-07 16:24:32 +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
3e6f0e63f3
sixel: don't try to emit a sixel if we're outside the image's boundaries
Closes #1634
2024-03-07 16:21:06 +01:00
Daniel Eklöf
75fd59df3f
sixel: debug: sixel image _may_ be zero-sized
For example, and single GNL (Graphical New Line) will result in a
sixel with a non-zero height, but a zero width.
2024-03-07 16:20:29 +01:00
Daniel Eklöf
a2fa667f45
sixel: we no longer need the extra newline
Since we never place the cursor *under* the sixel anymore.
2024-03-07 16:19:56 +01:00
Daniel Eklöf
1421ba504d
sixel: debug: fix logged width/height values when emitting sixel
image.width and image.height are the scaled dimensions, and these
haven't been set when the log message is printed.
2024-03-07 16:18:35 +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
Daniel Eklöf
8ff8ec5b70
sixel: fix row height calculation in resize_vertically()
In resize_vertically(), we assumed a sixel is 6 pixels tall. This is
mostly true, but not for non-1:1 sixels. Or, to be more precise, not
for sixels where 'pan' != 1.

This caused us to allocate too little backing memory, resulting in a
crash when we later tried to write to the image.
2024-03-06 16:36:30 +01:00
Daniel Eklöf
702d3ae6ca
kitty kbd: update handling of locked modifiers
The kitty keyboard specification has been updated/clarified yet
again. Locked modifiers are to be ignored if the key event would
result in plain text without the locked modifier being enabled.

In short, locked modifiers are included in the set of modifiers
reported in a key event. But having a locked modifier enabled doesn't
turn all key events into CSIu sequences.

For example, with only the disambiguate mode enabled, pressing 'a', or
'shift+a' results in a/A regardless of the state of Caps- or NumLock.

But 'ctrl+a', which always results in a CSIu, will have a different
modifier list, depending on whether Caps- or NumLock are enabled.
2024-03-06 16:33:24 +01:00
Daniel Eklöf
ec73e4d10d
kitty kbd: switch from GTK to XKB mode for 'consumed' modifiers
This fixes an issue where some key combinations resulted in different
output (e.g. escape code vs. plain text) depending on the state of
e.g. the NumLock key. One such example is Shift+space. Another example
is Shift+BackSpace.

This patch also removes the hardcoded CapsLock filter, when
determining whether a key combo produces text or not, and instead uses
the locked modifiers as reported by XKB.
2024-03-02 10:28:25 +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