fix(wayland): the first key repeat lands at the delay, not as a burst of the periods since the press
keyboard_key set lastFireTime to the press and TickKeyRepeats caught up on every period since it, so the first tick past the compositor's delay fired floor(delay / period) repeats at once: with rate 25 and delay 600 a held Backspace deleted sixteen characters at the delay mark and a held letter put fifteen copies in the field, from a hardware keyboard and from an on-screen keyboard that sends Backspace as key events. A rate above 1000 made the period zero and the loop endless. The first repeat now lands at the delay, as wl_keyboard.repeat_info promises (one after `delay`, then `rate` a second): the first tick past the delay sets lastFireTime to pressTime + delay - period. The period is at least a millisecond, and the catch-up after a stalled frame is capped (kKeyRepeatCatchUp, three) with the rest of the stall dropped, so a held key is never a burst of edits. TickKeyRepeats takes the clock as a parameter for the tests; the frame path's call is unchanged. tests/KeyRepeat drives TickKeyRepeats with an injected clock on a default-constructed Window: nothing before the delay, one at it, one per period after, a capped catch-up, a key without text, a rate above 1000, a released key, rate 0.
This commit is contained in:
parent
8c9a588083
commit
3f646ec42b
4 changed files with 145 additions and 11 deletions
|
|
@ -34,7 +34,11 @@ export namespace Crafter {
|
|||
std::string utf8; // UTF-8 to re-emit as onTextInput, if any
|
||||
std::chrono::time_point<std::chrono::steady_clock> pressTime;
|
||||
std::chrono::time_point<std::chrono::steady_clock> lastFireTime;
|
||||
bool fired = false; // a repeat has fired since the press: before it, lastFireTime is the press itself
|
||||
};
|
||||
// Repeats one tick may emit at once when frames stalled; the rest of the
|
||||
// stall is dropped, so a held key is never a burst of edits.
|
||||
inline constexpr int kKeyRepeatCatchUp = 3;
|
||||
#endif
|
||||
|
||||
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
|
||||
|
|
@ -564,6 +568,7 @@ export namespace Crafter {
|
|||
#ifdef CRAFTER_GRAPHICS_WINDOW_WAYLAND
|
||||
inline static KeyRepeatState keyRepeat;
|
||||
static void TickKeyRepeats();
|
||||
static void TickKeyRepeats(std::chrono::steady_clock::time_point now); // the clock injected, for the tests
|
||||
#else
|
||||
static void TickKeyRepeats() {}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue