diff options
| author | Albert Cervin <albert@acervin.com> | 2024-05-06 22:42:39 +0200 |
|---|---|---|
| committer | Albert Cervin <albert@acervin.com> | 2024-05-06 22:42:39 +0200 |
| commit | ad0cd5c036f0080ee8d97db2e67b8d54186d1e33 (patch) | |
| tree | b85cc21acac6e1383dfa3b78494ce09c409b2f30 /src/dged/keyboard.c | |
| parent | c42412e1643c88c81cf5b38404cc010881437fe9 (diff) | |
| download | dged-ad0cd5c036f0080ee8d97db2e67b8d54186d1e33.tar.gz dged-ad0cd5c036f0080ee8d97db2e67b8d54186d1e33.tar.xz dged-ad0cd5c036f0080ee8d97db2e67b8d54186d1e33.zip | |
Fix slow buffer paste
Was caused by updating all buffer hooks on every char insert.
Particularily, the syntax update takes a little bit too long to
call on every char. Now the keyboard parsing routine compresses
all consecutive self-inserting chars into one "key press".
Also fix some small issues with timers and update them with a min
and max.
Diffstat (limited to 'src/dged/keyboard.c')
| -rw-r--r-- | src/dged/keyboard.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/src/dged/keyboard.c b/src/dged/keyboard.c index 1e28066..26eb308 100644 --- a/src/dged/keyboard.c +++ b/src/dged/keyboard.c @@ -31,15 +31,19 @@ struct keyboard keyboard_create_fd(struct reactor *reactor, int fd) { void parse_keys(uint8_t *bytes, uint32_t nbytes, struct key *out_keys, uint32_t *out_nkeys) { - // TODO: can be optimized if "bytes" contains no special chars uint32_t nkps = 0; for (uint32_t bytei = 0; bytei < nbytes; ++bytei) { uint8_t b = bytes[bytei]; bool has_more = bytei + 1 < nbytes; uint8_t next = has_more ? bytes[bytei + 1] : 0; + struct key *prev_kp = nkps > 0 ? &out_keys[nkps - 1] : NULL; struct key *kp = &out_keys[nkps]; if (b == 0x1b) { // meta + // meta key is special since it records as its own + // key press so only set some state of the key press + // and do not advance to the next since it is + // not done yet kp->start = bytei; kp->mod = Meta; } else if (has_more && isalnum(next) && kp->mod & Meta && @@ -47,6 +51,7 @@ void parse_keys(uint8_t *bytes, uint32_t nbytes, struct key *out_keys, b == '0')) { // special char (function keys, pgdn, etc) kp->mod = Spec; } else if (b == 0x7f) { // ? + // For some reason, delete is not a control char kp->mod |= Ctrl; kp->key = '?'; kp->start = bytei; @@ -59,31 +64,35 @@ void parse_keys(uint8_t *bytes, uint32_t nbytes, struct key *out_keys, kp->end = bytei + 1; ++nkps; } else { - if (kp->mod & Spec && b == '~') { + if ((kp->mod & Spec) && b == '~') { // skip tilde in special chars kp->end = bytei + 1; ++nkps; - } else if (kp->mod & Meta || kp->mod & Spec) { + } else if ((kp->mod & Meta) || (kp->mod & Spec)) { + // handle the key press following meta or spec. kp->key = b; kp->end = bytei + 1; - if (kp->mod & Meta || (kp->mod & Spec && next != '~')) { ++nkps; } } else if (utf8_byte_is_unicode_continuation(b)) { // do nothing for these - } else if (utf8_byte_is_unicode_start(b)) { // unicode char - kp->mod = None; - kp->key = 0; - kp->start = bytei; - kp->end = bytei + utf8_nbytes(bytes + bytei, nbytes - bytei, 1); - ++nkps; - } else { // normal ASCII char - kp->mod = None; - kp->key = b; - kp->start = bytei; - kp->end = bytei + 1; - ++nkps; + } else { // ascii char or unicode start byte (self-inserting) + uint32_t nb = utf8_byte_is_unicode_start(b) + ? utf8_nbytes(bytes + bytei, nbytes - bytei, 1) + : 1; + + // "compress" number of keys if previous key was also a + // "simple" key + if (prev_kp != NULL && prev_kp->mod == None) { + prev_kp->end += nb; + } else { + kp->mod = None; + kp->key = b; + kp->start = bytei; + kp->end = bytei + nb; + ++nkps; + } } } } |
