Apparently, a frame callback for the cursor surface is *never*
triggered if we get a pointer-leave event *before* the callback is
triggered. At least on Sway 1.4.
This caused the cursor being stuck, and never updating once this state
was reached.
Fix by destroying the cursor frame callback on pointer-leave.
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.
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.
When we receive a keyboard_key or pointer_motion event without first
having received a keyboard_enter or pointer_enter event (that being
the "sway bugs" part), we generally don't know _which_ terminal window
the event was intended for.
However, if we only have *one* window open (always the case for a
regular 'foot' process, or when there's a single footclient connected
to a foot server process), then obviously we can "guess" which window
the event was intended for... so do that.
Now, the only time the event is ignored is when we're a server process
with more than one window open (= more than one footclient connected).
I.e. what we're effectively doing is *not* repeating modifier
keys.
Besides being the "right" thing to do, this also works around another
Sway 1.2 bug, where being in a focused foot window and then switching
to a vt and back would cause us to be stuck in an endless key repeat
loop that would only stop when unfocusing, focusing back and then
unfocusing once again.
Sway 1.2 has been seen sending keyboard_key() events without first
sending a keyboard_enter() event.
This can be triggered by:
1. start a foot terminal
2. unfocus it (move focus to another window)
3. switch to a vt
4. switch back to sway
5. focus the foot terminal
At this point, Sway will *not* send the keyboard_enter() event, but
instead send a keyboard_key() event.
(furthermore, if you now unfocus the window again, sway will send a
keyboard_leave() event, still without having sent a keyboard_enter()
event).
Sway has _also_ been seen crashing in wl_pointer_motion(). Though this
was in a build without proper debug information, everything points to
a similar issue - i.e. sway is sending a motion event without first
having sent an enter event.
Workaround this by detecting this and logging a warning the first time
it happens. The event is then ignored.
This fixes an assertion when holding in ctrl+shift+c (copy to
clipboard); subsequent "presses" would set the clipboard serial to 0,
which we would then assert on in the next iteration when we tried to
cancel the previous copy.
This happens on Sway when exiting a screen locker. Or at least that's
when we see the problem; it's unclear if the event occurs when
starting the screen locker, or when exiting it. Or maybe its both.
Anyway, don't try to unfocus a NULL-terminal.
This reverts commit 739c5cf7f0.
The original commit stated:
Not sure why these were added here; they don't appear to be
needed (we're writing to the client - it's up to the client to echo
stuff, in which case we redraw as usual).
But, client output doesn't cause a scrollback/view reset.
Not sure why these were added here; they don't appear to be
needed (we're writing to the client - it's up to the client to echo
stuff, in which case we redraw as usual).