Commit graph

357 commits

Author SHA1 Message Date
Daniel Eklöf
2e519ed5b6
render: scrollback indicator: implement 'relative' and 'line' variants
We now implement all combinations of 'scrollback-indicator-style' and
'scrollback-indicator-format'.
2020-07-26 10:18:05 +02:00
Daniel Eklöf
67758a7cb7
render: scrollback indicator: wip: implement 'fixed:percent' indicator
When scrollback indicator has been enabled, and the viewport isn't at
the bottom, we now render a *static* indicator with the position in
percent.

We use the color scheme's blue color as background, and it's white
color as foreground. This is subject to change... Should maybe be
configurable as well.

The Wayland surface + sub-surface are instantiated on-demand, and
automatically destroyed when no longer used.
2020-07-26 10:01:26 +02:00
Daniel Eklöf
c2362c10f1
render: search: fix subpixel argument to fcft_glyph_rasterize() 2020-07-26 10:01:05 +02:00
Daniel Eklöf
c4679e474e
config: rename scrollback-indicator to scrollback-indicator-style
And turn it from a boolean to an enum. It can be set to:

* `none` - disables the indicator
* `static` - always rendered near the top of the window
* `moving` - position reflects the scrollback position
2020-07-25 14:31:45 +02:00
Daniel Eklöf
e945063620
config: rename show-scrollback-position to scrollback-indicator 2020-07-24 18:26:44 +02:00
Daniel Eklöf
2c6f7adc17
config: add 'show-scrollback-position' option to footrc 2020-07-24 18:20:26 +02:00
Daniel Eklöf
b1950ac222
render: add code that calculates current position in scrollback 2020-07-24 17:51:40 +02:00
Daniel Eklöf
3869c7299f
render: bump maximum window title length from 100 to 2048 (bytes)
Apparently, the max is ~8K, but lets stay on the safe side.
2020-07-22 21:07:57 +02:00
Daniel Eklöf
970a42a6dd
term: don't re-render last cursor cell if cursor was hidden 2020-07-15 08:21:41 +02:00
Daniel Eklöf
df2927e088
term: print: write special value CELL_MULT_COL_SPACER to extra cells
When printing a multi-column character, write CELL_MULT_COL_SPACER
instead of '0' to both padding cells (when character doesn't fit at
the end of the line), and to the cells following the actual character.
2020-07-14 16:49:11 +02:00
Daniel Eklöf
5c99e8013b
term: rename COMB_CHARS_LO,HI -> CELL_COMB_CHARS_LO,HI 2020-07-14 16:41:57 +02:00
Daniel Eklöf
3f55cf3d14
render: render_margin: don't damage margins when rendering scroll damage
When applying scroll damage, we may have to re-render the
margins.

This is because when we SHM-scroll, we actually move the entire
surface, and thus we end up overwriting the top margin area with old
window content, and scroll in uninitialized memory in the bottom
margin.

But, we don't have to tell the compositor about this - the last frame
always contains correct margins; i.e. there's no change between the
last frame and current frame being rendered.

TODO: we _could_ micro-optimize and only damage the margins after a
surface resize. We do it slightly more often now, when dealing with
state changes in screen flash or scrollback searching. But I don't
think it's worth the effort.
2020-07-13 14:19:07 +02:00
Daniel Eklöf
96f480b14d
render: doh! flush the last surface damage *outside* of the rendering loop 2020-07-13 14:18:43 +02:00
Daniel Eklöf
ed620f1854
render: render_margin: add 'damage_{top,bottom,left,right}' arguments 2020-07-13 14:06:02 +02:00
Daniel Eklöf
0336f47f05
render: render_margin(): remove top/bottom arguments
All calls to render_margin() set top=true and bottom=true anyway.
2020-07-13 14:03:58 +02:00
Daniel Eklöf
9f21799cb2
render: merge wl surface damage for consecutive dirty rows 2020-07-13 13:44:52 +02:00
Daniel Eklöf
09bdf20aa0
render: keep lock while pushing dirty rows to worker queue
Instead of locking the queue for each dirty row we append, and
signaling a condition variable, just keep the lock while going through
the visible rows.

Release the lock once done.

Since we take the lock *before* posting the 'start' semaphore, all
workers will be waiting for the lock to be released.

Then, one at a time they'll get the lock and pick a row to
render. The queue will never get empty - when all rows have been
rendered, each worker will pick a 'frame done' "job" from the queue,
and break the rendering loop.
2020-07-13 13:27:23 +02:00
Daniel Eklöf
fe6c228b13
render: don't render cursor when it has been explicitly hidden 2020-07-12 13:08:19 +02:00
Daniel Eklöf
2bdd0a7c80
render: remove most of the special handling of cursor rendering
Previously, we had to explicitly render the old cursor cell *before*
applying scrolling damage.

We then rendered all the dirty rows, *without* rendering the cursor -
even if the cursor cell was among the dirty rows.

Finally, when everything else was done, we explicitly rendered the
cursor cell.

This meant a lot of code, and unnecessary render_cell() calls, along
with unnecessary wl_surface_damage_buffer() calls.

This was a necessary in the early design of foot, but not anymore.

We can simply mark both the old cursor cell, and the current one, as
dirty and let the normal rendering framework render it. All we need to
do is pass the cursor column to render_row(), so that it can pass
has_cursor=true in the appropriate call to render_cell(). We pass -1
here for all rows, except the cursor's row, where we pass the actual
cursor column.

With this, there's no need to calculate whether the cursor is visible
or not; just mark it's cell as dirty, and if that row is visible, the
normal rendering will take care of it.

This also simplifies the state needed to be saved between two frames;
we only need a row pointer, and the cursor column index.

Part of https://codeberg.org/dnkl/foot/issues/35
2020-07-12 12:56:10 +02:00
Daniel Eklöf
12a1688ce3
render: use kbd-focus instead of visual focus for hollow block cursor
When determining whether we should render a hollow block cursor,
i.e. to signal that we're unfocused, base the decision on the
terminals current keyboard focus, not visual focus.
2020-07-11 09:06:36 +02:00
Daniel Eklöf
bf62519d83
wayland: read XCURSOR_{THEME,SIZE} in reload_xcursor theme 2020-07-10 12:06:55 +02:00
Daniel Eklöf
4e48d550ef
multi-seat: improve handling of multiple (mouse) pointers
* xcursor always set for all pointers
* xcursor sometimes not updated when it should be
* mouse grabbed state wasn't per seat, but global (i.e. "does at least
  one seat enable mouse grabbing")
* selection enabled state wasn't per seat
2020-07-09 09:52:11 +02:00
Daniel Eklöf
be2490022d
multi-seat: enable xcursor theme support again 2020-07-08 18:08:39 +02:00
Daniel Eklöf
c470825067
wip: multi-seat support
Compiles and runs, but mouse, clipboard and other things have been
disabled.
2020-07-08 16:45:26 +02:00
Daniel Eklöf
c7b2dcc0f4
render: sixel: regression: need to take current offset into account when early-quitting sixel rendering
The sixel images are sorted, that's true. But in order for our row
numer comparisons to actually work, we need to rebase all numbers
against the current scrollback offset (or, the scrollback *end*, to be
precise).
2020-06-28 14:19:43 +02:00
Daniel Eklöf
5158be86d2
render: sixels: break out of loop when we're sure there aren't any more visible images
The sixel list is sorted, with the most recent images *first* in the
list (and thus the "oldest" images are at the back).

This means we can break out of the loop when we see a sixel
that *ends before* the current view starts.

As a minor optimization, we also recognize sixels that *start after*
the current view ends. We can't break out of the loop, but we can skip
trying to render them (they wouldn't have been rendered, but more work
would have been done in render_sixel() to reach this conclusion).
2020-06-28 10:45:30 +02:00
Daniel Eklöf
0969b2ebd7
render: sixel: use pixman_image_composite32() 2020-06-06 14:22:54 +02:00
Daniel Eklöf
fd99b28beb
render: cell: reset clip region also when we're NOT rendering a glyph 2020-06-06 14:22:25 +02:00
Daniel Eklöf
d8a83b500f
render: regression: don't let cell background overflow into the margins
This used to work before because we had a "global" clip region on the
text area, excluding the margins.

When we introduced per-cell clipping, this global clip region was
removed, and the background drawing code could now overflow into the
margins.

This fixes it by setting the cell clip region not just when rendering
a glyph, but before we render the cell background.
2020-06-05 08:10:38 +02:00
Daniel Eklöf
8b320ed296
render: re-write cell clipping to use pixman destination clipping
Our home rolled clip-to-cell code was, obviously, not correct.

The original problem was that we couldn't use pixman clipping since we
have multiple threads writing to the same pixman image, and thus there
would be races between the threads setting clipping.

The fix is actually simple - just instantiate one pixman
image (referencing the same backing image data) for each rendering
thread.
2020-06-04 15:39:19 +02:00
Daniel Eklöf
bddd3fa384
render: do not allow glyphs to overflow into surrounding cells
This would be done cleaner by using destination clipping in pixman,
but since we have multiple threads rendering cells simultaneously,
that is not possible.

We also cannot use source clipping since we need to offset the
destination x,y coordinates with the glyph offsets.

So, roll our own clipping by not allowing the x,y offsets to go
outside the cell boundaries, and adjusting the glyph offset
accordingly.

Closes #21
2020-06-03 17:32:57 +02:00
Daniel Eklöf
8f37c839f3
render: draw hollow block cursor on top of the character, not the opposite 2020-06-02 18:22:55 +02:00
Daniel Eklöf
8fd7c837f7
render: resize: don't try to signal TIOCSWINSZ on a closed ptmx FD 2020-05-27 18:23:35 +02:00
Daniel Eklöf
1a8ccb0ffa
selection/render: sync cells' 'selected' bit before rendering
For performance reasons, we track whether a cell is selected or not
using a bit in a cell's attributes.

This makes it easy for the renderer to determine if the cells should
be rendered as selected or not - it just have to look at the
'selected' bit instead of doing a complex range check against the
current selection.

This works nicely in most cases. But, if the cell is updated, the
'selected' bit is cleared. This results in the renderer rendering the
cell normally, i.e. _not_ selected.

Checking for this, and re-setting the 'selected' bit when the cell is
updated (printed to) is way too expensive as it is in the hot path.

Instead, sync the 'selected' bits just before rendering. This isn't so
bad as it may sound; if there is no selection this is a no-op. Even if
there is a selection, only those cells whose 'selected' bit have been
cleared are dirtied (and thus re-rendered) - these cells would have
been re-rendered anyway.
2020-05-16 21:36:08 +02:00
Daniel Eklöf
b647aa447b
render: only apply transparency to the default background color 2020-05-16 16:26:52 +02:00
Daniel Eklöf
62e0774319
unicode-combining: store seen combining chains "globally" in the term struct
Instead of storing combining data per cell, realize that most
combinations are re-occurring and that there's lots of available space
left in the unicode range, and store seen base+combining combinations
chains in a per-terminal array.

When we encounter a combining character, we first try to pre-compose,
like before. If that fails, we then search for the current
base+combining combo in the list of previously seen combinations. If
not found there either, we allocate a new combo and add it to the
list. Regardless, the result is an index into this array. We store
this index, offsetted by COMB_CHARS_LO=0x40000000ul in the cell.

When rendering, we need to check if the cell character is a plain
character, or if it's a composed character (identified by checking if
the cell character is >= COMB_CHARS_LO).

Then we render the grapheme pretty much like before.
2020-05-03 11:03:22 +02:00
Daniel Eklöf
ef637fb5e8
render: don't re-instantiate the foreground pixman source 2020-05-02 22:14:48 +02:00
Daniel Eklöf
d945b68b73
unicode-combine: remove utf8proc dependency
We only used utf8proc to try to pre-compose a glyph from a base and
combining character.

We can do this ourselves by using a pre-compiled table of valid
pre-compositions. This table isn't _that_ big, and binary searching it
is fast.

That is, for a very small amount of code, and not too much extra RO
data, we can get rid of the utf8proc dependency.
2020-05-02 17:29:00 +02:00
Daniel Eklöf
3b29aa95c9
render: de-indent #if statement 2020-05-01 21:51:40 +02:00
Daniel Eklöf
3474624c2c
unicode-combining: completely remove unicode combining characters when feature is disabled 2020-05-01 12:05:38 +02:00
Daniel Eklöf
76567e9ef0
render: render combining characters
This is basically just a loop that renders additional glyphs on top
off the base glyph.

Since we now need access to the row struct, for the combining
characters, the function prototype for 'render_cell()' has changed.

When rendering the combining characters we also need to deal with
broken fonts; some fonts use positive offsets (as if the combining
character was a regular character), while others use a negative
offset (to be used as if you had already advanced the pen position).

We handle both - a positive offset is rendered just like a regular
glyph. When we see a negative offset we simply add the width of a cell
first.
2020-05-01 11:56:13 +02:00
Daniel Eklöf
69c3e74498
util.h: new header file defining commonly used macros 2020-05-01 11:46:24 +02:00
Daniel Eklöf
74d30dc410
csd: buttons: use default color table as default colors
If the user hasn't configured any CSD button colors, use the color
scheme's default colors for blue/green/red.
2020-04-29 20:06:16 +02:00
Daniel Eklöf
e9ed3025a8
damage: remove 'scroll' sub struct
There is no other types of damage but scroll damage.
2020-04-26 12:47:19 +02:00
Daniel Eklöf
ce280537de
render: make 'glyph' assignment more readable 2020-04-26 12:39:42 +02:00
Daniel Eklöf
f736d467d9
fcft: fcft_glyph_for_wc() has been renamed to fcft_glyph_rasterize() 2020-04-24 10:53:34 +02:00
Daniel Eklöf
7194f65ae9
fcft: adjust to fcft-2.0 API changes
* font_*() -> fcft_*()
* struct font -> struct fcft_font
* struct glyph -> struct fcft_glyph
* enum subpixel_order -> enum fcft_subpixel
2020-04-21 19:29:36 +02:00
Daniel Eklöf
6f83ef81e5
render: use output's subpixel mode when rasterizing glyphs 2020-04-20 18:38:55 +02:00
Daniel Eklöf
b7593897b7
render: search: improve handling of very long search strings 2020-04-19 14:50:48 +02:00
Daniel Eklöf
fa8b0cbd80
csi: implement CSI Ps ; Ps ; Ps t reporting escape sequences
A lot of the escape sequences on the "CSI Ps ; Ps ; Ps t" form are
expected to return a reply. Thus, not having these implemented means
we will hang if the client sends these escapes.

Not all of these escapes can be meaningfully implemented on Wayland,
and thus this implementation is best effort.

We now support the following escapes:

* 11t   - report if window is iconified (always replies "no")
* 13t   - report window position (always replies 0,0)
* 13;2t - report text area position (replies with margins, since we
          cannot get the window's position)
* 14t   - report text area size, in pixels
* 14;2t - report window size, in pixels
* 15t   - report screen size, in pixels
* 16t   - report cell size, in pixels
* 18t   - report text area size, in cells
* 19t   - report screen size, in cells
2020-04-18 11:51:53 +02:00