When enabled, PUA (Private Usage Area) codepoints are always treated
as double-width glyphs, regardless of the actual glyph width.
Requires allow-overflowing-double-width-glyphs=yes
Works in pretty much the same way as ‘beam-thickness’, except that the
default value is “the font’s underline thickness”.
This means, that when unset, the cursor underline thickness scales
with the font size.
But, when explicitly set, either to a point size value, or a pixel
size, it remains fixed at that size.
Closes#524
It _may_ be acceptable in e.g. tiling WMs, where windows are seldom
resized interactively.
But in a stacking WM where the typical way of resizing windows is by
interactive resizes, this spams way too much.
Instead of using CELL_SPACER for *all* cells that previously used
CELL_MULT_COL_SPACER, include the remaining number of spacers
following, and including, itself. This is encoded by adding to the
CELL_SPACER value.
So, a double width character will now store the character itself in
the first cell (just like before), and CELL_SPACER+1 in the second
cell.
A three-cell character would store the character itself, then
CELL_SPACER+2, and finally CELL_SPACER+1.
In other words, the last spacer is always CELL_SPACER+1.
CELL_SPACER+0 is used when padding at the right margin. I.e. when
writing e.g. a double width character in the last column, we insert a
CELL_SPACER+0 pad character, and then write the double width character
in the first column on the next row.
In some cases, the underline position (typically provided by the font,
mind you), end up below the cell, making it visible.
Note that below the cell here means below the line. I.e. the font
provided underline position is below the font provided line height...
Oh well.
Doing this in foot rather than fcft, since other applications
typically don’t have to clip the rendered text.
Closes#503
Older version of Plasma/KWin had an issue where buffer damage recorded
before the buffer was attached were ignored. This appears to have been
fixed now.
* Break out cursor cell dirtying to separate functions
* Break out handling of double buffering
* Handle buffers with age > 1 (we’re swapping between more than 2
buffers)
* Detect full screen repaints, and skip re-applying old frame’s damage
* Use an allocated array insted of a tll list for old frame’s scroll damage
* When logging frame rendering time, including the amount used for
double buffering.
When re-applying the previous frame’s damage (due to us being forced
to double buffer), subtract the current frame’s damage from the
region-to-copy when there’s no scroll damage on the current frame.
When the current frame doesn’t have any scroll damage, the current
frame’s damage is in the same coordinate system as the previous
frame’s damage, and we can safely remove it from the region we copy
from.
When we are forced to swap between two buffers, re-apply the old
frame’s damage to the current buffer, before applying the current
frame’s damage.
First, while applying this frame’s scroll damage, copy it to the
buffer’s scroll damage list (so that we can access it via
term->render.last_buf).
Also, when iterating and rendering the grid, build a pixman region of
the damaged regions. This is currently done on a per-row basis. This
is also stored in the buffer.
Now, when being forced to double buffer, first iterate the old
buffer’s damage, and re-apply it to the current buffer. Then,
composite the old buffer on top of the current buffer, using the old
frame’s damage region as clip region. This effectively copies
everything that was rendered to the last frame. Remember, this is on a
per-row basis.
Then we go on and render the frame as usual.
Note that it would be _really_ nice if we could subtract the current
frame’s damage region from the clip region (no point in copying areas
we’re going to overwrite anyway). Unfortunately, that’s harder than it
looks; the current frame’s damage region is only valid *after* this
frame’s scroll damage have been applied, while the last frame’s damage
region is only valid *before* it’s been applied.
Translating one to the other isn’t easy, since scroll damage isn’t
just about counting lines - there may be multiple scroll damage
records, each with its own scrolling region. This creates very complex
scenarios.
By default, age all matching buffers that are busy (i.e. in use by the
compositor).
This allows us to detect whether we can apply the current frame’s
damage directly, or if we need to prepare the buffer first (e.g. copy
old buffer, or re-apply last frame’s damage etc).
In all other cases, alpha is disabled. This includes:
* Palette- or RGB-colors matching the default background color
* When any kind of reverse video is enabled (e.g. DECSCNM, or ANSI
reverse)
* Rename cursor.style value ‘bar’ to ‘beam’. ‘bar’ remains recognized,
but should eventually be deprecated and then removed.
* Add ‘cursor.beam-thickness’ option, a pt-or-px value specifying the
thickness of the beam cursor. Defaults to 1.5pt.
* Rename (and export) pt_or_px_as_pixels() to
term_pt_or_px_as_pixels()
* Change term_pt_or_px_as_pixels() to round point values instead of
truncating them.
When rendering a selected/highlighted cell where the foreground and
background colors are the same, invert the background color to make
the selected text legible.
Closes#455
When ‘bold-text-in-bright’ is set ‘to palette-based’, colors matching
one of the 8 regular palette colors are brightened by using the
corresponding bright palette color.
Other colors, or all colors if ‘bold-text-in-bright’ is set to
‘yes|true’, are brightened by increasing the luminance.
We have no guarantee that sub-surfaces extending outside the window
geometry are rendered correctly (if at all).
For example, both Sway and River will render the window border on top
of the sub-surface.
Future versions of Sway may clip the sub-surface.
Since jump-labels are positioned slightly above, and to the left of
the URLs first character, having a label on either the top row, or on
the first column, will likely position it outside the window. This is
handled by simply setting x/y to 0 (or, to -margin, since the label
coordinate is later offsetted with the window margins).
Second, if the label is very long, it may extend outside the
window. This is very unusual for labels only showing the key, and not
the URL itself, but could happen in this case too, if e.g. the user
has configured double-width key characters.
This is handled by calculating its maximum width, and then truncating
the label.
Although very unlikely, it is possible for a label to also extend
outside the window’s vertical size. This could happen for very small
font sizes, where the label’s own margins are large, relative to the
font size. This case is currently not handled.
Closes#443
When disabled, we render box drawing characters ourselves. This is the
default.
When enabled, we instead use font glyphs. I.e. no special treatment.
Closes#430
The buffer attached to a surface with wl_surface_attach() must have a
width and height that both are a multiple of the scale configured for
that buffer:
The new size of the surface is calculated based on the buffer
size transformed by the inverse buffer_transform and the
inverse buffer_scale. This means that at commit time the supplied
buffer size must be an integer multiple of the buffer_scale. If
that's not the case, an invalid_size error is sent.
Due to a libwayland bug[^1], this is currently *not* being reported as an
error. However, recent versions of Sway have started enforcing this,
and is e.g. dropping (not rendering) sub-surfaces that does not adhere
to this.
[^1]: https://gitlab.freedesktop.org/wayland/wayland/-/issues/194Closes#409
All uses of render_osd() passes buf->width/buf->height as
width/height. Thus, we can simply remove the width/height parameters
and have render_osd() use buf->width and buf->height directly.
This fixes a possible deadlock; render_sixels_images() may call
render_cell(), which may need to take the worker lock (when rendering
either a blinking cell, or a box drawing glyph that isn’t yet in the
glyph cache).
In all instances where we call ime_update_cursor_rect(), the ‘term’
argument is the same as seat->kbd_focus.
So, let ime_update_cursor_rect() use that directly instead.
Also make ime_send_cursor_rect() static (i.e. local to ime.c).
This ensures different seat’s don’t step on each others IME pre-edit
state.
It also removes most dependencies on having a valid term pointer for
many IME operations.
We’re still not all the way, since we support disabling IME with a
private mode, which is per terminal, not seat.
Thus, we still require the seat to have keyboard focus on one of our
windows.
Closes#324. But note that *rendering* of multiple seat’s IME pre-edit
strings is still broken.
When P2=1, empty pixels are transparent.
This patch also changes the behavior of P2=0|2, from setting empty
pixels to the default background color, to instead use the *current*
background color.
To implement this, a couple of changes are needed:
* Sixel pixels always use alpha=1.0, except for *empty* cells when
P2=1 (i.e. transparent pixels).
* The renderer draws sixels with the OVER operator, instead of the SRC
operator.
* The renderer *must* now render the cells beneath the sixel. As an
optimization, this is only done for sixels where P2=1. I.e. for
fully opaque sixels, there’s no need to render the cells beneath.
The sixel renderer isn’t yet hooked into the multi-threaded
renderer. This means *rows* (not just the cells) beneath
maybe-transparent sixels are rendered single-threaded.
Closes#391.
Previously, we automatically exited URL mode whenever we received data
on the PTY. This was done since we don’t know _what_ has changed on
the screen, and we don’t want to display misleading jump labels.
However, this becomes a problem in curses-like applications that
periodically updates part of the screen. For example, a statusbar with
a clock.
This patch changes this behavior; instead of cancelling URL mode when
receiving PTY data, we snapshot the grid when entering URL mode.
When *rendering*, we use the snapshot:ed grid, while PTY updates
modify the “real” grid.
Snapshot:ing the grid means taking a full/deep copy of the current
grid, including sixel images etc.
Finally, it isn’t necessary to “damage” the entire view
when *entering* URL mode, since we’re at that point the renderer is in
sync with the grid. But we *do* need to damage the entire view when
exiting URL mode, since the grid changes on the “real” grid hasn’t
been tracked by the renderer.
By default, the URL isn’t shown on the jump-label. For auto-detect
URLs, doing so is virtually always useless, as the URL is already
visible in the grid.
For OSC-8 URLs however, the URL is often _not_ visible in the
grid. Many times, seeing the URL is still not needed (if you’re doing
‘ls --hyperlink’, you already know what the URIs are).
But it is still useful to have a way to show the URLs.
This patch adds a new key binding action that can be used in url-mode
to toggle the URL on and off in the jump label.
It is bound to ctrl+t by default.
In case an URL is split up into multiple parts, those parts are now
treated as a single URL when it comes to key assignment.
Only the *first* URL part is actually assigned a key combo. The other
parts are ignored.
We still highlight them, but for all other purposes they are ignored.