Commit graph

67 commits

Author SHA1 Message Date
Daniel Eklöf
abc36d8f09
wayland: wl_display_flush() never blocks
Since it doesn't block, we need to detect EAGAIN failures and ensure
we actually flush everything.

If we don't, we sooner or later end up in a wayland client library
call that aborts due to the socket buffer being full.

Ideally, we'd simply enable POLLOUT in the FDM. However, we cannot
write *anything* to the wayland socket until we've actually managed to
send everything. This means enabling POLLOUT in the FDM wont work
since we may (*will*) end up trying to write more data to it before
we've flushed it.

So, add a wrapper function, wayl_flush(), that acts as a blocking
variant of wl_display_flush(), by detecting EAGAIN failiures and
calling poll() itself, on the wayland socket only, until all data has
been sent.
2020-01-04 21:10:08 +01:00
Daniel Eklöf
1178a7763b
wayland: window: optimize: set opaque region
When background alpha is 1.0 (0xffff), i.e. completely opaque, tell
the compositor this, via wl_surface_set_opaque_region().

This allows it to optimize drawing of surfaces _behind_ our window.
2020-01-03 21:53:38 +01:00
Daniel Eklöf
0ea0323d0f
wayland: don't use wl_display_dispatch()
wl_display_dispatch() calls poll(), which is unnecessary since we
already know the FD is readable.

Use the more lower level wl_display_read_events() +
wl_display_dispatch_pending().

These require wl_display_prepare_read() to have been called.

The idea is to call wl_display_prepare_read() **before** calling
poll().

Thus, we do this more or less last in wayl_init(), and at the **end**
of the FDM handler.

However, having taking this lock also means we no longer can call
wl_display_roundtrip() directly (it will hang).

So, add a wrapper, wayl_roundtrip(), that cancels the read intent,
does the roundtrip, and then re-acquires the read intent.
2020-01-03 21:02:12 +01:00
Daniel Eklöf
a291999f2c
wayland: flush after commit new pointer surface 2020-01-03 19:04:42 +01:00
Daniel Eklöf
c118ed9252
wayland: configure: resize before changing visual focus
This hopefully fixes and issue where the visual focus in/out caused a
render refresh with the *old* size.

This caused the occasional flicker at startup, or when resizing the
window.

By placing the resize call before the visual focus in/out, we ensure
the refresh uses the new size.

This is a temporary workaround. The correct solution is to ensure we
only call refresh() once.
2020-01-03 18:58:26 +01:00
Daniel Eklöf
f7362d381b
render: refresh: ensure window has been configured 2020-01-03 18:55:13 +01:00
Daniel Eklöf
d07fd7de39
render: remove 'refresh' from render_resize() 2020-01-03 13:56:10 +01:00
Daniel Eklöf
46c434d3f1
wayland: window: apply all configure changes after acking the event 2020-01-03 13:54:44 +01:00
Daniel Eklöf
765fe13aff
wayland: remove wayl_terminal_from_xdg_{surface,toplevel} 2020-01-03 13:46:37 +01:00
Daniel Eklöf
b0fbc064dd
wayland: window: pass window pointer to xdg toplevel callbacks 2020-01-03 13:46:15 +01:00
Daniel Eklöf
ea002ad571
wayland: window: pass window pointer to xdg-surface-listener callbacks 2020-01-03 13:41:35 +01:00
Daniel Eklöf
9372fb4166
wayland: window: pass window pointer to wl-surface callbacks 2020-01-03 13:40:37 +01:00
Daniel Eklöf
9a0238bb52
wayland: window now keeps pointer to owning terminal, not wayland 2020-01-03 13:37:03 +01:00
Daniel Eklöf
74aa604904
render: render_resize(): don't do anything if width or height is 0 2020-01-03 12:54:03 +01:00
Daniel Eklöf
11892e8d23
wayland: fix release build 2020-01-03 12:52:18 +01:00
Daniel Eklöf
8494cc808f
wayland: debug log state changes in xdg-toplevel-configure 2020-01-03 12:49:04 +01:00
Daniel Eklöf
c94da979fb
wayland: xdg-surface-configure: refresh terminal
Any changes done in any of the configure events are ignored before
we've ack:ed the configure event.

In particular, this means the resize done in xdg-toplevel-configure
isn't displayed until the next time we call render_refresh().

Unless we do something ourselves, this can take quite some time, since
we're basically need the slave to write something.

So, in xdg-surface-configure, *after* having ack:ed the configure
event, call render_refresh() to make the changes done in
xdg-toplevel-configure visible as soon as possible.
2020-01-03 12:48:54 +01:00
Daniel Eklöf
26c16a9a47
wayland: render_resize() now takes a 'refresh' argument 2020-01-03 12:45:16 +01:00
Daniel Eklöf
aa9e87ffb0
wayland: term_visual_focus_{in,out} handles already being focused/defocused 2020-01-03 11:20:13 +01:00
Daniel Eklöf
304355d8ed
wayland: xdg-toplevel-configure: no need to detect early configure events
We can now lookup terminal instances at all times, making it
unnecessary to detect "early" configure events.

Note that we still need to prevent a resize from happening when
width/height is 0.
2020-01-03 11:18:43 +01:00
Daniel Eklöf
913c684844
term: term_init() calls wl_display_roundtrip()
Instead of having `wayl_win_init()` call
`wl_display_roundtrip()` (which it itself doesn't need), call it from
`term_init()`.

This allows us to add ourselves (the new terminal instance) to the
terminal list in the wayland backend, before triggering the wayland
events caused by `wayl_win_init()`.

This is turn allows the wayland backend to find/lookup the new
terminal when those events occur..
2020-01-03 11:16:06 +01:00
Daniel Eklöf
0e40e1c711
wayland: xdg-top-level-configure: call term_visual_focus_{in,out} 2020-01-02 19:37:01 +01:00
Daniel Eklöf
2192d95fa9
wayland: xdg-toplevel-configure: check for stateless configure calls
Ignore configure calls without state, instead of checking for
width/height == 0.
2020-01-02 17:38:50 +01:00
Daniel Eklöf
4a9f359a6a
wayland: ignore early configure calls
At this point, not everything has been setup and we crash when trying
to convert the surface pointer to a terminal pointer.
2020-01-02 17:25:41 +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
4ecb0ecf4d
wayland: rename focused/moused to kbd_focus/mouse_focus 2020-01-02 15:58:52 +01:00
Daniel Eklöf
403af22061
wayland: warn when presentation timings have been requested but is not supported 2020-01-01 16:09:16 +01:00
Daniel Eklöf
b100a82c2a
wayland: only bind to 'presentation' interface if -p,--presentation-timings 2019-12-31 16:12:48 +01:00
Daniel Eklöf
7fe081600a
wayland: remove empty line 2019-12-31 16:07:05 +01:00
Daniel Eklöf
d8761f31a2
wayland: make zxdg_output_v1_listener struct const 2019-12-31 15:43:15 +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
db1d913ba8
wayland: include more output (monitor) details in the log output 2019-12-05 19:35:34 +01:00
Daniel Eklöf
b5780e735e
Add missing includes 2019-12-01 19:22:45 +01:00
Daniel Eklöf
a87b39f6eb
wayland: track current xcursor, and don't update if same
We may have many windows open, which tries to update/change the
xcursor at various points.

Track which cursor is currently loaded, regardless of which window it
was set by. If someone tries to load that very same xcursor again,
simply skip it.

One example is when we've moused over a window that does *not* have
keyboard focus, and then the user clicks, or by some other mean gives
that window keyboard focus. In many cases it will then try to set the
same cursor again (most of the times, the cursor is the same
regardless of keyboard focus, but not always).
2019-11-30 12:09:57 +01:00
Daniel Eklöf
c8724fe656
wayland: terminal_from_surface: recognize scrollback search surfaces
This fixes an assertion when hovering over the input field for
scrollback searches.
2019-11-29 22:10:28 +01:00
Daniel Eklöf
304ee33fd6
wayland: always flush after dispatching messages
This means we don't have to e.g. roundtrip when setting the cursor.
2019-11-29 22:09: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
204bfa02f4
wayland: calculate output PPI (pixels-per-inch) 2019-11-26 19:02:35 +01:00
Daniel Eklöf
721ac4ab31
wayland: change disconnected log type from err -> warn 2019-11-23 13:56:11 +01:00
Daniel Eklöf
29cccadd1d
tllist: is now an external "library", so use <> includes 2019-11-17 19:19:55 +01:00
Daniel Eklöf
988134717f
wayland: verify xdg-output-manager interface version 2019-11-03 16:14:35 +01:00
Daniel Eklöf
4e93b3a2d8
wayland: verify server implements the required interface versions 2019-11-03 15:39:26 +01:00
Daniel Eklöf
a8cb6c531e
Remove unneeded include 2019-11-03 13:07:19 +01:00
Daniel Eklöf
79c3121aa3
misc: fdm already logs failures 2019-11-03 00:52:24 +01:00
Daniel Eklöf
f28fb6c039
timerfd: read() returns -1 with errno == EAGAIN, not 0
When there hasn't been a timeout (or in our case, there was a timeout,
but we reset the timer before we got to the read()), read() returns,
not 0, but -1 with errno == EAGAIN.
2019-11-02 01:44:01 +01:00
Daniel Eklöf
b27cd9cedf
timerfd: use non-blocking mode, fixes dead lock
Since we cancel the timers every now and then, there's a (small)
chance that one handler cancels a timer that has triggered in the same
epoll() iteration.

When this happens, read() blocks.

Fix by making the timer FDs non-blocking, and simply returning when we
read 0 bytes.
2019-11-02 01:14:40 +01:00
Daniel Eklöf
8b4ef78f7a
wayland: wayl_win_destroy(): looks like we need another roundtrip 2019-11-01 20:45:57 +01:00
Daniel Eklöf
bc815a33db
wayland: wayl_destroy(): destroy any remaining terminals 2019-11-01 20:25:08 +01:00
Daniel Eklöf
2e78dcc5e5
Don't use non-blocking FDs
We use epoll() to determine when we can read/write FDs so there's
absolutely no need for non-blocking.
2019-11-01 20:24:13 +01:00
Daniel Eklöf
95b7c405d4
wayland: wayl_win_destroy(): unmap windows before destroying
This will trigger e.d. keyboard_leave() and wl_pointer_leave() events,
which ensures there aren't any references to the destroyed window from
the global wayland struct.

Call wl_display_roundtrip() to trigger those events *before* we
destroy the window.
2019-11-01 20:19:53 +01:00