Commit graph

185 commits

Author SHA1 Message Date
Daniel Eklöf
5a6cbb8c3e
dcs: initial handling of DCS in general
Add data structure to term->vt. This structure tracks the free-form
data that is passed-through, and the handler to call at the end.

Intermediates and parameters are collected by the normal VT
parser. Then, when we enter the passthrough state, we call dcs_hook().

This function checks the intermediate(s) and parameters, and selects
the appropriate unhook handler (and optionally does some execution
already).

In passthrough mode, we simply append strings to an internal
buffer. This might have to be changed in the future, if we need to
support a DCS that needs to execute as we go.

In unhook (i.e. when the DCS is terminated), we execute the unhook
handler.

As a proof-of-concept, handlers for BSU/ESU (Begin/End Synchronized
Update) has been added (but are left unimplemented).
2020-01-12 11:55:22 +01:00
Daniel Eklöf
457eb573c4
selection: update: don't dirty cells that don't change state
Previously when updating a selection, we would unmark *all* cells in
the old selection, and then mark all cells in the new selection.

This caused *all* cells to be dirtied and thus re-rendered.

Avoid this, by adding a temporary state to the cells' selected state.

Before unmarking the old selection, pre-mark the new selection using a
temporary state.

When unmarking the old selection, ignore cells in this temporary state.
When marking the new selection, ignore cells in this temporary
state (except clearing the temporary state).
2020-01-06 11:56:18 +01:00
Daniel Eklöf
7e178d6337
search: rename render.search_offset -> render.search_glyph_offset 2020-01-05 15:25:24 +01:00
Daniel Eklöf
5a89520274
render: ensure cursor is always visible in the search box
Maintain a view 'offset' (which glyph from the search string to start
rendering at).

This defines the start of the viewable area. The end is the offset +
the search box size (which is limited to the window size).

Adjust this offset whenever the cursor moves outside the viewable
area. For now, this is always done in the same way: set the offset to
the cursor position.

This means that when we're entering text at the end of the search
criteria (i.e. the normal case; we're simply typing), and the search
box reaches the window size, the cursor will jump to the start of the
search box, which will be empty. This could be confusing, but let's go
with for now.
2020-01-05 15:16:40 +01:00
Daniel Eklöf
1060a4250b
term: more comments in the 'render' sub-struct 2020-01-04 19:56:59 +01:00
Daniel Eklöf
99f471d738
render: trigger terminal refreshes in an FDM hook
In some cases, we end up calling render_refresh() multiple times in
the same FDM iteration. This means will render the first update
immediately, and then set the 'pending' flag, causing the updated
content to be rendered in the next frame.

This can cause flicker, or flashes, since we're presenting one or more
intermediate frames until the final content is shown.

Not to mention that it is inefficient to render multiple frames like
this.

Fix by:

* render_refresh() only sets a flag in the terminal

* install an FDM hook; this hook loops all terminals and executes what
  render_refresh() _used_ to do (that is, render immediately if we're
  not waiting for a frame callback, otherwise set 'pending' flag). for
  all terminals that have the 'refresh_needed' flag set.
2020-01-04 19:49:26 +01:00
Daniel Eklöf
2a531327dd
selection: selection_cancel() now sets 'kind' to SELECTION_NONE 2020-01-04 12:09:09 +01:00
Daniel Eklöf
f12b1473fd
selection: store cell 'selected' state in the cells' attributes
Instead of having the renderer calculate, for each cell, whether that
cell is currently selected or not, make selection_update() mark/unmark
the selected cells.

The renderer now only has to look at the cells' 'selected'
attribute. This makes the renderer both smaller and faster.
2020-01-04 12:03:04 +01:00
Daniel Eklöf
d706e68280
selection: track selection type; normal or block selection 2020-01-03 23:29:45 +01:00
Daniel Eklöf
ce4e99ebe2
term: background alpha is not a floating point number 2020-01-03 21:53:16 +01:00
Daniel Eklöf
6f281cebfb
term: add term_visual_focus_{in,out}
These functions should be called when the terminal gets or loses
visual focus.

Note that this isn't necessarily the same as having keyboard focus.
2020-01-02 19:35:32 +01:00
Daniel Eklöf
e9325b958f
term: rename term_focus_{in,out} -> term_kbd_focus_{in,out} 2020-01-02 19:29:42 +01:00
Daniel Eklöf
eb1ea2d80d
term: add visually focused attribute to terminal struct 2020-01-02 16:06:35 +01:00
Daniel Eklöf
5a07419096
wayland: optionally use the presentation time protocol to measure input lag
This adds a flag, -p,--presentation-timings, that enables input lag
measuring using the presentation time Wayland protocol.

When enabled, we store a timestamp when we *send* a key to the
slave. Then, when we commit a frame for rendering to the compositor,
we request presentation feedback. We also store a timestamp for when
the frame was committed.

The 'presented' callback then looks at the input and commit
timestamps, and compares it with the presented timestamp.

The delay is logged at INFO when the delay was less than one frame
interval, at WARN when it was one frame interval, and at ERR when it
was two or more frame intervals.

We also update statistic counters that we log when foot is shut down.
2019-12-31 15:39:40 +01:00
Daniel Eklöf
39146fac5c
term: term_init: add 'cwd' argument
This is used when spawning the slave, to set its current working
directory just before we exec() the client.

In a regular foot instance, we set the cwd from getcwd().

In a foot server instance, each connecting client sends its cwd to the
server, and we use that.
2019-12-21 19:57:28 +01:00
Daniel Eklöf
016bde1bd4
term: wip: track current working directory
This sets the initial current working directory, as it is when the
terminal is instantiated.

We chdir() to it just before spawning a new terminal.
2019-12-21 15:35:54 +01:00
Daniel Eklöf
57de9feaa5
term: term_spawn_new(): new function, spawns a new foot/footclient process
Bind ctrl+shift+return to it
2019-12-21 15:27:17 +01:00
Daniel Eklöf
c22ae98729
render: get rid of 'all-clean' detection
Instead of trying to figure out if we had to render
something (i.e. something in the grid was dirty), and using that to
determine whether to post a callback or not, we now let
render_refresh() set a flag indication we need to render another
frame.

This simplifies render_grid(), which now _always_ renders, and pushes
it to the compositor.

The callback handler checks the pending flag and simply doesn't call
render_grid() when there's no more pending state to render.

This ends up reducing the number of wakeups when e.g. having a
blinking cursor.
2019-12-17 19:14:56 +01:00
Daniel Eklöf
418ff5bcd9
render: move blink timer handling to term.c 2019-12-17 19:14:55 +01:00
Daniel Eklöf
d490cc84c0
term: cursor blink: cursor refresh now dirties the cursor cell
Normally we don't dirty the cell on cursor movement. But, since a
blinking cursor isn't a cursor that has moved, our normal cursor
rendering wont work.

Dirty the cursor cell to force a redraw of it.
2019-12-16 21:31:40 +01:00
Daniel Eklöf
7d29435d86
term: implement cursor blinking
Blinking can be enabled either by setting the cursor style with

 CSI Ps SP q

and selecting a blinking style.

Or, with 'CSI ? 12 h'

Note that both affect the same internal state. I.e. you can disable
blinking with CSI ? 12l after having selected a blinking cursor
style. This is consistent with XTerm behavior.
2019-12-15 15:07:56 +01:00
Daniel Eklöf
30335ef32a
fcft: include <fcft/fcft.h>, and use fcft/stride.h instead of local copy 2019-12-01 14:03:24 +01:00
Daniel Eklöf
fd9c28464d
fcft: use fcft instead of local copy of font.c/font.h 2019-12-01 13:43:51 +01:00
Daniel Eklöf
fbeb1e9610
term: mouse reporting functions no longer take modifier state
The mouse reporting functions are called from input when we receive
Wayland mouse events.

We used to pass the current keyboard modifier (shift, alt, ctrl, etc)
to the terminal functions.

This however is wrong, since we may receive Wayland mouse events
without having keyboard focus. When we don't have keyboard focus, the
modifier state doesn't apply to us.

Remove the modifier arguments from the terminal mouse reporting
functions. These functions now read this state directly instead, but
only when the terminal instance in question has keyboard focus.
2019-11-30 17:11:00 +01:00
Daniel Eklöf
2208f4304b
term: add term_mouse_grabbed()
When this returns true, it means we have keyboard focus and are
grabbing the mouse (for e.g. selections), regardless of whether the
client has enabled mouse tracking or not.
2019-11-30 17:06:15 +01:00
Daniel Eklöf
bf9a9e7b90
term: xcursor: use 'hand2' instead of 'left_ptr' when mouse tracking
Mouse tracking always reports clicks, so using a cursor that suggests
you can click makes sense I think.
2019-11-29 22:30:56 +01:00
Daniel Eklöf
0dd37f0a36
terminal: use the 'text' xcursor pointer whenever selection is possible 2019-11-28 19:35:47 +01:00
Daniel Eklöf
bc86cd61c7
font: move metrics from terminal struct to font struct 2019-11-26 19:02:35 +01:00
Daniel Eklöf
9902a5732f
term: try to improve on a performance regression
When support was added for DECOM (absolute/relative row addressing), a
small but noticeable (~3.5%) performance regression was introduced.

Try to improve the situation by simplifying the relative-to-absolute
conversion; only the row needs to be transformed.
2019-11-17 18:52:27 +01:00
Daniel Eklöf
cf75528e86
Revert "term: new function: term_autowrap()"
This reverts commit 686405b703.
2019-11-17 17:22:34 +01:00
Daniel Eklöf
686405b703
term: new function: term_autowrap()
Adds a linebreak (+ scroll if necessary) if we're in a deferred wrap
and auto-margins are enabled.

Return true when we wrapped, false otherwise.
2019-11-17 12:13:36 +01:00
Daniel Eklöf
c9ebd527cf
term: save/restore charsets on save/restore cursor+attributes 2019-11-17 10:02:46 +01:00
Daniel Eklöf
3f3feedde2
term: convert anonymous 'charsets' struct to a named struct 2019-11-17 10:00:30 +01:00
Daniel Eklöf
ce544776ab
term: move charset variables into an anonymous struct 2019-11-17 09:59:12 +01:00
Daniel Eklöf
a70fe1f5d7
term: move lcf flag into 'cursor' struct 2019-11-17 09:46:20 +01:00
Daniel Eklöf
d637b8c9ba
term: add struct cursor 2019-11-17 09:44:31 +01:00
Daniel Eklöf
c1088d77ac
term: rename: print_needs_wrap -> lcf (Last Column Flag) 2019-11-17 09:39:43 +01:00
Daniel Eklöf
f91073c362
term: add tab-stop list to terminal struct
This list is intended to store tab stop columns
2019-11-16 10:54:21 +01:00
Daniel Eklöf
95eaad7ce4
csi: implement DECOM - switch cursor origin between absolute and relative
The default is absolute mode, where 0,0 is the upper left corner of
the screen.

In relative mode, the origin is relative the top scroll margin.

Internally, we always track the current cursor position in absolute
mode. Every time we the client *sets* or *queries* the cursor position
in relative mode, we translate it to absolute.
2019-11-05 13:27:37 +01:00
Daniel Eklöf
f00c5fdac6
term: asynchronous writes to slave
Make ptmx non-blocking. Then, when writing data to the slave would
have blocked, use the FDM to asynchronously write the remaining data.

This is done by enabling EPOLLOUT on ptmx, and enqueueing all outgoing
data. The FDM handler will go through the enqueued data, and once all
of it has been written, we turn off EPOLLOUT again (thus switching
back to synchronous writes)
2019-11-03 01:03:52 +01:00
Daniel Eklöf
9f1525aef7
Rename: vt_to_slave() -> term_to_slave() 2019-11-03 00:52:24 +01:00
Daniel Eklöf
bf9aff056a
Revert "render: last_buf may point to a free:d buffer"
This reverts commit 4d3251a93b.
2019-11-02 01:28:29 +01:00
Daniel Eklöf
4d3251a93b
render: last_buf may point to a free:d buffer
So, store last buf's width/height separately
2019-11-02 00:48:07 +01:00
Daniel Eklöf
0bd2ddd8ad
term_init(): initialize slave TERM from term_init() argument 2019-11-01 21:03:08 +01:00
Daniel Eklöf
1e41a25f00
terminal: call user-defined callback when destroying terminal
main uses this to get the exit code of the terminal.
2019-11-01 20:34:32 +01:00
Daniel Eklöf
9d5926ce12
term: add term_shutdown()
This function unmaps the terminal window, removes itself from the
wayland list of terminals and then finally destroys itself.

We ensure we don't get any callbacks/events referring to a free:d
terminal struct, we close all terminal related FDs and unmap the
wayland window.

Then, to be really really sure there aren't any (by the FDM) queued up
events, we delay the self-destruction to the next FDM poll iteration,
by opening an event FD and adding it to the FDM.

The callback for the event FD removes the FD from the FDM again, and
closes it. And then proceeds to destroy the terminal.
2019-10-30 20:03:11 +01:00
Daniel Eklöf
ad0f8a02d5
Merge branch 'fdm' 2019-10-30 17:31:44 +01:00
Daniel Eklöf
a42df2434b
scrollback: regression: fix rendering of scrollback diffs less than a screen
When doing "small" scrolls (typically done via mouse wheel or
similar), we render the scrolling by emitting a "scroll damage".

A recent commit changed how scroll damage is rendered; only when the
view is at the bottom ("following" the screen output) do we render the
damage.

To fix this, add a new type of scroll damage,
SCROLL_DAMAGE_IN_VIEW and SCROLL_DAMAGE_REVERSE_IN_VIEW.

These signal to the renderer that it should always render the damage.
2019-10-29 21:09:37 +01:00
Daniel Eklöf
0979a0e2e5
terminal: implement term_init() and term_destroy() 2019-10-28 18:25:19 +01:00
Daniel Eklöf
61cc8c3c55
wayland: implement wayl_init()
Wayland instantiation is now done by the wayland backend, not in main.
2019-10-27 19:08:48 +01:00