Incorrect kitty kbd escape emitted for some dead key combinations #1120

Closed
opened 4 months ago by dnkl · 1 comments
dnkl commented 4 months ago
Owner
See https://github.com/neovim/neovim/issues/19517 for details.
dnkl added the
bug
label 4 months ago
Poster
Owner

The issue is how foot handles composed characters when the kitty keyboard protocol is enabled.

We have this:

        if (composed && is_text)
            key = utf32;
        else {
            key = xkb_keysym_to_utf32(sym_to_use);
            if (key == 0)
                return false;

            /* The *shifted* key. May be the same as the unshifted
             * key - if so, this is filtered out below, when
             * emitting the CSI */
            alternate = xkb_keysym_to_utf32(sym);
        }

which basically says that composed characterse are to be emitted as-is, while "regular" characters go through a symbol-to-key conversion related to shifted vs. unshifted keys.

As extra security, we also require is_text to be true. This variable may be false in some composed-character cases, resulting in the else clause being executed. For many dead-key combinations, the end result is the same (matches kitty). But not all.

In the example from https://github.com/neovim/neovim/issues/19517, " is a dead key. When it's followed by shift+space, space is not treated as text, and we execute the else clause. In this particular case, the result is different from kitty.

So, why is is_text false in this case? We have this:

    const bool is_text = iswprint(utf32) && (effective & ~caps_num) == 0;

This says that the character is text (is printable) if it's, well, printable, and there aren't any non-consumed modifiers active. What's a consumed modifier? Take shift+a as an example. This combination produces an upper case A, and shift is considered consumed.

But with shift+space, shift isn't always (not in all XKB keyboard layouts) considered consumed, leading to is_text being set to false.

I think the correct solution is to always consider composed characters to be printable, but we should try to test this for other regressions.

The issue is how foot handles composed characters when the kitty keyboard protocol is enabled. We have this: ```c if (composed && is_text) key = utf32; else { key = xkb_keysym_to_utf32(sym_to_use); if (key == 0) return false; /* The *shifted* key. May be the same as the unshifted * key - if so, this is filtered out below, when * emitting the CSI */ alternate = xkb_keysym_to_utf32(sym); } ``` which basically says that composed characterse are to be emitted as-is, while "regular" characters go through a symbol-to-key conversion related to shifted vs. unshifted keys. As extra security, we also require `is_text` to be true. This variable may be false in some composed-character cases, resulting in the `else` clause being executed. For many dead-key combinations, the end result is the same (matches kitty). But not all. In the example from https://github.com/neovim/neovim/issues/19517, <kbd>"</kbd> is a dead key. When it's followed by <kbd>shift</kbd>+<kbd>space</kbd>, space is **not** treated as text, and we execute the `else` clause. In this particular case, the result is different from kitty. So, why is `is_text` false in this case? We have this: ```c const bool is_text = iswprint(utf32) && (effective & ~caps_num) == 0; ``` This says that the character is text (is printable) if it's, well, printable, **and** there aren't any non-consumed modifiers active. What's a consumed modifier? Take <kbd>shift</kbd>+<kbd>a</kbd> as an example. This combination produces an upper case `A`, and <kbd>shift</kbd> is considered consumed. But with <kbd>shift</kbd>+<kbd>space</kbd>, <kbd>shift</kbd> isn't always (not in all XKB keyboard layouts) considered consumed, leading to `is_text` being set to `false`. I _think_ the correct solution is to always consider composed characters to be printable, but we should try to test this for other regressions.
dnkl closed this issue 4 months ago
Sign in to join this conversation.
No Milestone
No Assignees
1 Participants
Notifications
Due Date

No due date set.

Dependencies

No dependencies set.

Reference: dnkl/foot#1120
Loading…
There is no content yet.