Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package foot for openSUSE:Factory checked in 
at 2021-12-09 19:45:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/foot (Old)
 and      /work/SRC/openSUSE:Factory/.foot.new.2520 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "foot"

Thu Dec  9 19:45:41 2021 rev:12 rq:937364 version:1.10.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/foot/foot.changes        2021-12-05 
22:47:07.505443900 +0100
+++ /work/SRC/openSUSE:Factory/.foot.new.2520/foot.changes      2021-12-09 
19:46:20.213154271 +0100
@@ -1,0 +2,8 @@
+Wed Dec  8 19:48:49 UTC 2021 - Arnav Singh <opens...@arnavion.dev>
+
+- Update to 1.10.3:
+  * Implemented support for all other modes of the Kitty keyboard protocol.
+    See Kitty keyboard protocol docs for more details.
+  * See https://codeberg.org/dnkl/foot/releases/tag/1.10.3 for more details.
+
+-------------------------------------------------------------------

Old:
----
  foot-1.10.2.tar.gz

New:
----
  foot-1.10.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ foot.spec ++++++
--- /var/tmp/diff_new_pack.S2QVNT/_old  2021-12-09 19:46:21.121154708 +0100
+++ /var/tmp/diff_new_pack.S2QVNT/_new  2021-12-09 19:46:21.125154710 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           foot
-Version:        1.10.2
+Version:        1.10.3
 Release:        0
 Summary:        A Wayland terminal emulator
 License:        MIT

++++++ foot-1.10.2.tar.gz -> foot-1.10.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/CHANGELOG.md new/foot/CHANGELOG.md
--- old/foot/CHANGELOG.md       2021-12-02 20:26:59.000000000 +0100
+++ new/foot/CHANGELOG.md       2021-12-08 18:09:50.000000000 +0100
@@ -1,5 +1,6 @@
 # Changelog
 
+* [1.10.3](#1-10-3)
 * [1.10.2](#1-10-2)
 * [1.10.1](#1-10-1)
 * [1.10.0](#1-10-0)
@@ -34,6 +35,29 @@
 * [1.2.0](#1-2-0)
 
 
+## 1.10.3
+
+### Added
+
+* Kitty keyboard protocol:
+  - [Report event 
types](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-events)
+    (mode `0b10`)
+  - [Report alternate 
keys](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-alternates)
+    (mode `0b100`, but not that only the _shifted_ key is reported,
+    not the _base layout key_)
+  - [Report all keys as escape 
codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-all-keys)
+    (mode `0b1000`)
+  - [Report associated 
text](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#report-text)
+    (mode `0b10000`)
+
+
+### Fixed
+
+* Crash when bitmap fonts are scaled down to very small font sizes
+  (https://codeberg.org/dnkl/foot/issues/830).
+* Crash when overwriting/erasing an OSC-8 URL.
+
+
 ## 1.10.2
 
 ### Added
@@ -41,7 +65,7 @@
 * New value, `max`, for `[tweak].grapheme-width-method`.
 * Initial support for the [Kitty keyboard 
protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/).
   Modes supported:
-  - [Disambiguate escape 
codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate)
+  - [Disambiguate escape 
codes](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate) (mode 
`0b1`)
 * ???Window menu??? (compositor provided) on right clicks on the CSD title
   bar.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/INSTALL.md new/foot/INSTALL.md
--- old/foot/INSTALL.md 2021-12-02 20:26:59.000000000 +0100
+++ new/foot/INSTALL.md 2021-12-08 18:09:50.000000000 +0100
@@ -39,6 +39,7 @@
 
 ### Running
 
+* UTF-8 locale
 * fontconfig
 * freetype
 * pixman
@@ -449,19 +450,14 @@
 ```
 
 Where _???output-directory???_ **must** match the value passed to
-`-Dcustom-terminfo-install-location` in the foot build.
-
-To compile and install directly (assuming the default
-`-Dcustom-terminfo-install-location`):
-
-```sh
-sudo tic -o /usr/share/foot/terminfo ...
-```
+`-Dcustom-terminfo-install-location` in the foot build. If
+`-Dcustom-terminfo-install-location` has not been set, `-o
+<output-directoty>` can simply be omitted.
 
 Or, if packaging:
 
 ```sh
-tic -o ${DESTDIR}/usr/share/foot/terminfo ...
+tic -o ${DESTDIR}/usr/share/terminfo ...
 ```
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/grid.c new/foot/grid.c
--- old/foot/grid.c     2021-12-02 20:26:59.000000000 +0100
+++ new/foot/grid.c     2021-12-08 18:09:50.000000000 +0100
@@ -69,10 +69,10 @@
 }
 
 static void
-uri_range_ensure_size(struct row_data *extra, size_t count_to_add)
+uri_range_ensure_size(struct row_data *extra, uint32_t count_to_add)
 {
     if (extra->uri_ranges.count + count_to_add > extra->uri_ranges.size) {
-        extra->uri_ranges.size += count_to_add + count_to_add;
+        extra->uri_ranges.size = extra->uri_ranges.count + count_to_add;
         extra->uri_ranges.v = xrealloc(
             extra->uri_ranges.v,
             extra->uri_ranges.size * sizeof(extra->uri_ranges.v[0]));
@@ -81,6 +81,10 @@
     xassert(extra->uri_ranges.count + count_to_add <= extra->uri_ranges.size);
 }
 
+/*
+ * Be careful! This function may xrealloc() the URI range vector, thus
+ * invalidating pointers into it.
+ */
 static void
 uri_range_insert(struct row_data *extra, size_t idx, int start, int end,
                  uint64_t id, const char *uri)
@@ -1028,6 +1032,9 @@
 
                 uri_range_insert(extra, i + 1, col + 1, r->end, r->id, r->uri);
 
+                /* The insertion may xrealloc() the vector, making our
+                 * ???old??? pointer invalid */
+                r = &extra->uri_ranges.v[i];
                 r->end = col - 1;
                 xassert(r->start <= r->end);
 
@@ -1161,6 +1168,10 @@
             /* Erase range erases a part in the middle of the URI */
             uri_range_insert(
                 extra, i + 1, end + 1, old->end, old->id, old->uri);
+
+            /* The insertion may xrealloc() the vector, making our
+             * ???old??? pointer invalid */
+            old = &extra->uri_ranges.v[i];
             old->end = start - 1;
             return;  /* There can be no more URIs affected by the erase range 
*/
         }
@@ -1231,6 +1242,33 @@
     verify_no_overlapping_uris(&row_data);
     verify_uris_are_sorted(&row_data);
 
+    grid_row_uri_range_destroy(&row_data.uri_ranges.v[0]);
+    grid_row_uri_range_destroy(&row_data.uri_ranges.v[1]);
+    row_data.uri_ranges.count = 0;
+
+    /*
+     * Regression test: erasing the middle part of an URI causes us to
+     * insert a new URI (we split the partly erased URI into two).
+     *
+     * The insertion logic typically triggers an xrealloc(), which, in
+     * some cases, *moves* the entire URI vector to a new base
+     * address. grid_row_uri_range_erase() did not account for this,
+     * and tried to update the ???end??? member in the URI range we just
+     * split. This causes foot to crash when the xrealloc() has moved
+     * the URI range vector.
+     *
+     * (note: we???re only verifying we don???t crash here, hence the lack
+     * of assertions).
+     */
+    free(row_data.uri_ranges.v);
+    row_data.uri_ranges.v = NULL;
+    row_data.uri_ranges.size = 0;
+    uri_range_append(&row_data, 1, 10, 0, "dummy");
+    xassert(row_data.uri_ranges.size == 1);
+
+    grid_row_uri_range_erase(&row, 5, 7);
+    xassert(row_data.uri_ranges.count == 2);
+
     for (size_t i = 0; i < row_data.uri_ranges.count; i++)
         grid_row_uri_range_destroy(&row_data.uri_ranges.v[i]);
     free(row_data.uri_ranges.v);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/input.c new/foot/input.c
--- old/foot/input.c    2021-12-02 20:26:59.000000000 +0100
+++ new/foot/input.c    2021-12-08 18:09:50.000000000 +0100
@@ -1026,6 +1026,11 @@
 legacy_kbd_protocol(struct seat *seat, struct terminal *term,
                     const struct kbd_ctx *ctx)
 {
+    if (ctx->key_state != WL_KEYBOARD_KEY_STATE_PRESSED)
+        return false;
+    if (ctx->compose_status == XKB_COMPOSE_COMPOSING)
+        return false;
+
     enum modifier keymap_mods = MOD_NONE;
     keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE;
     keymap_mods |= seat->kbd.alt ? MOD_ALT : MOD_NONE;
@@ -1140,6 +1145,30 @@
 kitty_kbd_protocol(struct seat *seat, struct terminal *term,
                    const struct kbd_ctx *ctx)
 {
+    const bool repeating = seat->kbd.repeat.dont_re_repeat;
+    const bool pressed = ctx->key_state == WL_KEYBOARD_KEY_STATE_PRESSED && 
!repeating;
+    const bool released = ctx->key_state == WL_KEYBOARD_KEY_STATE_RELEASED;
+    const bool composing = ctx->compose_status == XKB_COMPOSE_COMPOSING;
+    const bool composed = ctx->compose_status == XKB_COMPOSE_COMPOSED;
+
+    const enum kitty_kbd_flags flags =
+        term->grid->kitty_kbd.flags[term->grid->kitty_kbd.idx];
+
+    const bool disambiguate = flags & KITTY_KBD_DISAMBIGUATE;
+    const bool report_events = flags & KITTY_KBD_REPORT_EVENT;
+    const bool report_alternate = flags & KITTY_KBD_REPORT_ALTERNATE;
+    const bool report_all_as_escapes = flags & KITTY_KBD_REPORT_ALL;
+
+    if (!report_events && released)
+        return false;
+
+    if (composed && released)
+        return false;
+
+    /* TODO: should we even bother with this, or just say it???s not 
supported? */
+    if (!disambiguate && !report_all_as_escapes && pressed)
+        return legacy_kbd_protocol(seat, term, ctx);
+
     const xkb_mod_mask_t mods = ctx->mods & seat->kbd.kitty_significant;
     const xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2(
         seat->kbd.xkb_state, ctx->key, XKB_CONSUMED_MODE_GTK) & 
seat->kbd.kitty_significant;
@@ -1147,16 +1176,47 @@
     const xkb_mod_mask_t caps_num =
         (seat->kbd.mod_caps != XKB_MOD_INVALID ? 1 << seat->kbd.mod_caps : 0) |
         (seat->kbd.mod_num != XKB_MOD_INVALID ? 1 << seat->kbd.mod_num : 0);
+
     const xkb_keysym_t sym = ctx->sym;
     const uint32_t utf32 = ctx->utf32;
     const uint8_t *const utf8 = ctx->utf8.buf;
+
+    const bool is_text = iswprint(utf32) && (effective & ~caps_num) == 0;
     const size_t count = ctx->utf8.count;
 
-    if (ctx->compose_status == XKB_COMPOSE_COMPOSED) {
-        term_to_slave(term, utf8, count);
-        return true;
+    const bool report_associated_text =
+        (flags & KITTY_KBD_REPORT_ASSOCIATED) && is_text && !released;
+
+    if (composing) {
+        /* We never emit anything while composing, *except* modifiers
+         * (and only in report-all-keys-as-escape-codes mode) */
+        switch (sym) {
+        case XKB_KEY_Caps_Lock:
+        case XKB_KEY_Num_Lock:
+        case XKB_KEY_Shift_L:
+        case XKB_KEY_Control_L:
+        case XKB_KEY_Alt_L:
+        case XKB_KEY_Super_L:
+        case XKB_KEY_Hyper_L:
+        case XKB_KEY_Meta_L:
+        case XKB_KEY_Shift_R:
+        case XKB_KEY_Control_R:
+        case XKB_KEY_Alt_R:
+        case XKB_KEY_Super_R:
+        case XKB_KEY_Hyper_R:
+        case XKB_KEY_Meta_R:
+        case XKB_KEY_ISO_Level3_Shift:
+        case XKB_KEY_ISO_Level5_Shift:
+            goto emit_escapes;
+
+        default:
+            return false;
+        }
     }
 
+    if (report_all_as_escapes)
+        goto emit_escapes;
+
     if (effective == 0) {
         switch (sym) {
         case XKB_KEY_Return:    term_to_slave(term, "\r", 1); return  true;
@@ -1165,20 +1225,14 @@
         }
     }
 
-    /*
-     * Printables without any modifiers are printed as is.
-     *
-     * TODO: plain text keys (a-z, 0-9 etc) are still printed as text,
-     * even when NumLock is active, despite NumLock being a
-     * significant modifier, *and* despite NumLock affecting other
-     * keys, like Return and Backspace; figure out if there???s some
-     * better magic than filtering out Caps- and Num-Lock here..
-     */
-    if (iswprint(utf32) && (effective & ~caps_num) == 0) {
+    /* Plain-text without modifiers, or commposed text, is emitted as-is */
+    if (is_text && !released) {
         term_to_slave(term, utf8, count);
         return true;
     }
 
+emit_escapes:
+    ;
     unsigned int encoded_mods = 0;
     if (seat->kbd.mod_shift != XKB_MOD_INVALID)
         encoded_mods |= mods & (1 << seat->kbd.mod_shift) ? (1 << 0) : 0;
@@ -1194,7 +1248,7 @@
         encoded_mods |= mods & (1 << seat->kbd.mod_num)   ? (1 << 7) : 0;
     encoded_mods++;
 
-    int key = -1;
+    int key = -1, alternate = -1, base = -1;
     char final;
 
     switch (sym) {
@@ -1296,113 +1350,172 @@
     case XKB_KEY_XF86AudioRaiseVolume: key = 57439; final = 'u'; break;
     case XKB_KEY_XF86AudioMute:        key = 57440; final = 'u'; break;
 
-#if 0  /* TODO: enable when ???Report all keys as escape codes??? is enabled */
-    case XKB_KEY_Caps_Lock: key = 57358; final = 'u'; break;
-    case XKB_KEY_Num_Lock:  key = 57360; final = 'u'; break;
-
-    case XKB_KEY_Shift_L:   key = 57441; final = 'u'; break;
-    case XKB_KEY_Control_L: key = 57442; final = 'u'; break;
-    case XKB_KEY_Alt_L:     key = 57443; final = 'u'; break;
-    case XKB_KEY_Super_L:   key = 57444; final = 'u'; break;
-    case XKB_KEY_Hyper_L:   key = 57445; final = 'u'; break;
-    case XKB_KEY_Meta_L:    key = 57446; final = 'u'; break;
-    case XKB_KEY_Shift_R:   key = 57447; final = 'u'; break;
-    case XKB_KEY_Control_R: key = 57448; final = 'u'; break;
-    case XKB_KEY_Alt_R:     key = 57449; final = 'u'; break;
-    case XKB_KEY_Super_R:   key = 57450; final = 'u'; break;
-    case XKB_KEY_Hyper_R:   key = 57451; final = 'u'; break;
-    case XKB_KEY_Meta_R:    key = 57452; final = 'u'; break;
-#endif
+    case XKB_KEY_Caps_Lock: if (report_all_as_escapes) {key = 57358; final = 
'u';} break;
+    case XKB_KEY_Num_Lock:  if (report_all_as_escapes) {key = 57360; final = 
'u';} break;
 
-    default:
-        if (count > 0) {
-            if (effective == 0) {
-                term_to_slave(term, utf8, count);
-                return true;
-            }
+    case XKB_KEY_Shift_L:   if (report_all_as_escapes) {key = 57441; final = 
'u';} break;
+    case XKB_KEY_Control_L: if (report_all_as_escapes) {key = 57442; final = 
'u';} break;
+    case XKB_KEY_Alt_L:     if (report_all_as_escapes) {key = 57443; final = 
'u';} break;
+    case XKB_KEY_Super_L:   if (report_all_as_escapes) {key = 57444; final = 
'u';} break;
+    case XKB_KEY_Hyper_L:   if (report_all_as_escapes) {key = 57445; final = 
'u';} break;
+    case XKB_KEY_Meta_L:    if (report_all_as_escapes) {key = 57446; final = 
'u';} break;
+    case XKB_KEY_Shift_R:   if (report_all_as_escapes) {key = 57447; final = 
'u';} break;
+    case XKB_KEY_Control_R: if (report_all_as_escapes) {key = 57448; final = 
'u';} break;
+    case XKB_KEY_Alt_R:     if (report_all_as_escapes) {key = 57449; final = 
'u';} break;
+    case XKB_KEY_Super_R:   if (report_all_as_escapes) {key = 57450; final = 
'u';} break;
+    case XKB_KEY_Hyper_R:   if (report_all_as_escapes) {key = 57451; final = 
'u';} break;
+    case XKB_KEY_Meta_R:    if (report_all_as_escapes) {key = 57452; final = 
'u';} break;
+    case XKB_KEY_ISO_Level3_Shift: if (report_all_as_escapes) {key = 57453; 
final = 'u';} break;
+    case XKB_KEY_ISO_Level5_Shift: if (report_all_as_escapes) {key = 57454; 
final = 'u';} break;
 
-            /*
-             * Use keysym (typically its Unicode codepoint value).
-             *
-             * If the keysym is shifted, use its unshifted codepoint
-             * instead. In other words, ctrl+a and ctrl+shift+a should
-             * both use the same value for ???key??? (97 - i.a. ???a???).
-             *
-             * However, if a non-significant modifier was used to
-             * generate the symbol. This is needed since we cannot
-             * encode non-significant modifiers, and thus the ???extra???
-             * modifier(s) would get lost.
-             *
-             * Example:
-             *
-             * the Swedish layout has ???2???, QUOTATION MARK (???double
-             * quote???), ???@???, and ???????? on the same key. ???2??? is 
the base
-             * symbol.
-             *
-             * Shift+2 results in QUOTATION MARK
-             * AltGr+2 results in ???@???
-             * AltGr+Shift+2 results in ????????
-             *
-             * The kitty kbd protocol can???t encode AltGr. So, if we
-             * always used the base symbol (???2???), Alt+Shift+2 would
-             * result in the same escape sequence as
-             * AltGr+Alt+Shift+2.
-             *
-             * (yes, this matches what kitty does, as of 0.23.1)
-             */
-
-            /* Get the key???s shift level */
-            xkb_level_index_t lvl = xkb_state_key_get_level(
-                seat->kbd.xkb_state, ctx->key, ctx->layout);
-
-            /* And get all modifier combinations that, combined with
-             * the pressed key, results in the current shift level */
-            xkb_mod_mask_t masks[32];
-            size_t mask_count = xkb_keymap_key_get_mods_for_level(
-                seat->kbd.xkb_keymap, ctx->key, ctx->layout, lvl,
-                masks, ALEN(masks));
-
-            /* Check modifier combinations - if a combination has
-             * modifiers not in our set of ???significant??? modifiers,
-             * use key sym as-is */
-            bool use_level0_sym = true;
-            for (size_t i = 0; i < mask_count; i++) {
-                if ((masks[i] & ~seat->kbd.kitty_significant) > 0) {
-                    use_level0_sym = false;
-                    break;
-                }
+    default: {
+        /*
+         * Use keysym (typically its Unicode codepoint value).
+         *
+         * If the keysym is shifted, use its unshifted codepoint
+         * instead. In other words, ctrl+a and ctrl+shift+a should
+         * both use the same value for ???key??? (97 - i.a. ???a???).
+         *
+         * However, if a non-significant modifier was used to
+         * generate the symbol. This is needed since we cannot
+         * encode non-significant modifiers, and thus the ???extra???
+         * modifier(s) would get lost.
+         *
+         * Example:
+         *
+         * the Swedish layout has ???2???, QUOTATION MARK (???double
+         * quote???), ???@???, and ???????? on the same key. ???2??? is the 
base
+         * symbol.
+         *
+         * Shift+2 results in QUOTATION MARK
+         * AltGr+2 results in ???@???
+         * AltGr+Shift+2 results in ????????
+         *
+         * The kitty kbd protocol can???t encode AltGr. So, if we
+         * always used the base symbol (???2???), Alt+Shift+2 would
+         * result in the same escape sequence as
+         * AltGr+Alt+Shift+2.
+         *
+         * (yes, this matches what kitty does, as of 0.23.1)
+         */
+
+        /* Get the key???s shift level */
+        xkb_level_index_t lvl = xkb_state_key_get_level(
+            seat->kbd.xkb_state, ctx->key, ctx->layout);
+
+        /* And get all modifier combinations that, combined with
+         * the pressed key, results in the current shift level */
+        xkb_mod_mask_t masks[32];
+        size_t mask_count = xkb_keymap_key_get_mods_for_level(
+            seat->kbd.xkb_keymap, ctx->key, ctx->layout, lvl,
+            masks, ALEN(masks));
+
+        /* Check modifier combinations - if a combination has
+         * modifiers not in our set of ???significant??? modifiers,
+         * use key sym as-is */
+        bool use_level0_sym = true;
+        for (size_t i = 0; i < mask_count; i++) {
+            if ((masks[i] & ~seat->kbd.kitty_significant) > 0) {
+                use_level0_sym = false;
+                break;
             }
+        }
 
-            key = use_level0_sym && ctx->level0_syms.count > 0
-                ? ctx->level0_syms.syms[0]
-                : sym;
-            final = 'u';
+        xkb_keysym_t sym_to_use = use_level0_sym && ctx->level0_syms.count > 0
+            ? ctx->level0_syms.syms[0]
+            : sym;
+
+        if (composed && is_text)
+            key = utf32;
+        else {
+            key = xkb_keysym_to_utf32(sym_to_use);
+            if (key == 0)
+                key = sym_to_use;
+
+            /* 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);
         }
+
+        /* Base layout key. I.e the symbol the pressed key produces in
+         * the base/default layout (layout idx 0) */
+        const xkb_keysym_t *base_syms;
+        int base_sym_count = xkb_keymap_key_get_syms_by_level(
+            seat->kbd.xkb_keymap, ctx->key, 0, 0, &base_syms);
+
+        if (base_sym_count > 0)
+            base = xkb_keysym_to_utf32(base_syms[0]);
+
+        final = 'u';
         break;
     }
+    }
 
     xassert(encoded_mods >= 1);
 
-    char buf[16];
-    int bytes;
+    char event[4];
+    if (report_events /*&& !pressed*/) {
+        /* Note: this deviates slightly from Kitty, which omits the
+         * ???:1??? subparameter for key press events */
+        event[0] = ':';
+        event[1] = '0' + (pressed ? 1 : repeating ? 2 : 3);
+        event[2] = '\0';
+    } else
+        event[0] = '\0';
+
+    char buf[64], *p = buf;
+    size_t left = sizeof(buf);
+    size_t bytes;
 
     if (key < 0)
         return false;
 
     if (final == 'u' || final == '~') {
-        if (encoded_mods > 1)
-            bytes = snprintf(buf, sizeof(buf), "\x1b[%u;%u%c",
-                             key, encoded_mods, final);
-        else
-            bytes = snprintf(buf, sizeof(buf), "\x1b[%u%c", key, final);
+        bytes = snprintf(p, left, "\x1b[%u", key);
+        p += bytes; left -= bytes;
+
+        if (report_alternate) {
+            bool emit_alternate = alternate > 0 && alternate != key;
+            bool emit_base = base > 0 && base != key && base != alternate;
+
+            if (emit_alternate) {
+                bytes = snprintf(p, left, ":%u", alternate);
+                p += bytes; left -= bytes;
+            }
+
+            if (emit_base) {
+                bytes = snprintf(
+                    p, left, "%s:%u", !emit_alternate ? ":" : "", base);
+                p += bytes; left -= bytes;
+            }
+        }
+
+        bool emit_mods = encoded_mods > 1 || event[0] != '\0';
+
+        if (emit_mods) {
+            bytes = snprintf(p, left, ";%u%s", encoded_mods, event);
+            p += bytes; left -= bytes;
+        }
+
+        if (report_associated_text) {
+            bytes = snprintf(p, left, "%s;%u", !emit_mods ? ";" : "", utf32);
+            p += bytes; left -= bytes;
+        }
+
+        bytes = snprintf(p, left, "%c", final);
+        p += bytes; left -= bytes;
     } else {
-        if (encoded_mods > 1)
-            bytes = snprintf(buf, sizeof(buf), "\x1b[1;%u%c", encoded_mods, 
final);
-        else
-            bytes = snprintf(buf, sizeof(buf), "\x1b[%c", final);
+        if (encoded_mods > 1 || event[0] != '\0') {
+            bytes = snprintf(p, left, "\x1b[1;%u%s%c", encoded_mods, event, 
final);
+            p += bytes; left -= bytes;
+        } else {
+            bytes = snprintf(p, left, "\x1b[%c", final);
+            p += bytes; left -= bytes;
+        }
     }
 
-    term_to_slave(term, buf, bytes);
+    term_to_slave(term, buf, sizeof(buf) - left);
     return true;
 }
 
@@ -1418,15 +1531,20 @@
         return;
     }
 
-    if (state == XKB_KEY_UP) {
+    const bool pressed = state == WL_KEYBOARD_KEY_STATE_PRESSED;
+    //const bool repeated = pressed && seat->kbd.repeat.dont_re_repeat;
+    const bool released = state == WL_KEYBOARD_KEY_STATE_RELEASED;
+
+    if (released)
         stop_repeater(seat, key);
-        return;
-    }
 
-    bool should_repeat = xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key);
+    bool should_repeat =
+        pressed && xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key);
+
     xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->kbd.xkb_state, key);
 
-    if (state == XKB_KEY_DOWN && term->conf->mouse.hide_when_typing &&
+    if (pressed && term->conf->mouse.hide_when_typing &&
+
         /* TODO: better way to detect modifiers */
         sym != XKB_KEY_Shift_L && sym != XKB_KEY_Shift_R &&
         sym != XKB_KEY_Control_L && sym != XKB_KEY_Control_R &&
@@ -1443,13 +1561,13 @@
     enum xkb_compose_status compose_status = XKB_COMPOSE_NOTHING;
 
     if (seat->kbd.xkb_compose_state != NULL) {
-        xkb_compose_state_feed(seat->kbd.xkb_compose_state, sym);
+        if (pressed)
+            xkb_compose_state_feed(seat->kbd.xkb_compose_state, sym);
         compose_status = xkb_compose_state_get_status(
             seat->kbd.xkb_compose_state);
     }
 
-    if (compose_status == XKB_COMPOSE_COMPOSING)
-        goto maybe_repeat;
+    const bool composed = compose_status == XKB_COMPOSE_COMPOSED;
 
     xkb_mod_mask_t mods, consumed;
     get_current_modifiers(seat, &mods, &consumed, key);
@@ -1464,18 +1582,26 @@
     size_t raw_count = xkb_keymap_key_get_syms_by_level(
         seat->kbd.xkb_keymap, key, layout_idx, 0, &raw_syms);
 
-    if (term->is_searching) {
-        if (should_repeat)
-            start_repeater(seat, key);
-        search_input(
-            seat, term, key, sym, bind_mods, bind_consumed, raw_syms, 
raw_count, serial);
-        return;
-    } else  if (urls_mode_is_active(term)) {
-        if (should_repeat)
-            start_repeater(seat, key);
-        urls_input(
-            seat, term, key, sym, bind_mods, bind_consumed, raw_syms, 
raw_count, serial);
-        return;
+    if (pressed) {
+        if (term->is_searching) {
+            if (should_repeat)
+                start_repeater(seat, key);
+
+            search_input(
+                seat, term, key, sym, bind_mods, bind_consumed,
+                raw_syms, raw_count, serial);
+            return;
+        }
+
+        else  if (urls_mode_is_active(term)) {
+            if (should_repeat)
+                start_repeater(seat, key);
+
+            urls_input(
+                seat, term, key, sym, bind_mods, bind_consumed,
+                raw_syms, raw_count, serial);
+            return;
+        }
     }
 
 #if 0
@@ -1499,36 +1625,38 @@
     /*
      * User configurable bindings
      */
-    tll_foreach(seat->kbd.bindings.key, it) {
-        const struct key_binding *bind = &it->item;
-
-        /* Match translated symbol */
-        if (bind->sym == sym &&
-            bind->mods == (bind_mods & ~bind_consumed) &&
-            execute_binding(
-                seat, term, bind->action, bind->pipe_argv, serial))
-        {
-            goto maybe_repeat;
-        }
-
-        if (bind->mods != bind_mods)
-            continue;
-
-        /* Match untranslated symbols */
-        for (size_t i = 0; i < raw_count; i++) {
-            if (bind->sym == raw_syms[i] && execute_binding(
+    if (pressed) {
+        tll_foreach(seat->kbd.bindings.key, it) {
+            const struct key_binding *bind = &it->item;
+
+            /* Match translated symbol */
+            if (bind->sym == sym &&
+                bind->mods == (bind_mods & ~bind_consumed) &&
+                execute_binding(
                     seat, term, bind->action, bind->pipe_argv, serial))
             {
                 goto maybe_repeat;
             }
-        }
 
-        /* Match raw key code */
-        tll_foreach(bind->key_codes, code) {
-            if (code->item == key && execute_binding(
-                    seat, term, bind->action, bind->pipe_argv, serial))
-            {
-                goto maybe_repeat;
+            if (bind->mods != bind_mods)
+                continue;
+
+            /* Match untranslated symbols */
+            for (size_t i = 0; i < raw_count; i++) {
+                if (bind->sym == raw_syms[i] && execute_binding(
+                        seat, term, bind->action, bind->pipe_argv, serial))
+                {
+                    goto maybe_repeat;
+                }
+            }
+
+            /* Match raw key code */
+            tll_foreach(bind->key_codes, code) {
+                if (code->item == key && execute_binding(
+                        seat, term, bind->action, bind->pipe_argv, serial))
+                {
+                    goto maybe_repeat;
+                }
             }
         }
     }
@@ -1542,13 +1670,12 @@
      * Compose, and maybe emit "normal" character
      */
 
-    xassert(seat->kbd.xkb_compose_state != NULL ||
-           compose_status != XKB_COMPOSE_COMPOSED);
+    xassert(seat->kbd.xkb_compose_state != NULL || !composed);
 
     if (compose_status == XKB_COMPOSE_CANCELLED)
         goto maybe_repeat;
 
-    int count = compose_status == XKB_COMPOSE_COMPOSED
+    int count = composed
         ? xkb_compose_state_get_utf8(seat->kbd.xkb_compose_state, NULL, 0)
         : xkb_state_key_get_utf8(seat->kbd.xkb_state, key, NULL, 0);
 
@@ -1558,9 +1685,13 @@
     uint8_t *utf8 = count < sizeof(buf) ? buf : xmalloc(count + 1);
     uint32_t utf32 = (uint32_t)-1;
 
-    if (compose_status == XKB_COMPOSE_COMPOSED) {
+    if (composed) {
         xkb_compose_state_get_utf8(
             seat->kbd.xkb_compose_state, (char *)utf8, count + 1);
+
+        wchar_t wc;
+        if (mbtowc(&wc, (const char *)utf8, count) == count)
+            utf32 = wc;
     } else {
         xkb_state_key_get_utf8(
             seat->kbd.xkb_state, key, (char *)utf8, count + 1);
@@ -1590,7 +1721,7 @@
         ? kitty_kbd_protocol(seat, term, &ctx)
         : legacy_kbd_protocol(seat, term, &ctx);
 
-    if (seat->kbd.xkb_compose_state != NULL)
+    if (composed && released)
         xkb_compose_state_reset(seat->kbd.xkb_compose_state);
 
     if (utf8 != buf)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/meson.build new/foot/meson.build
--- old/foot/meson.build        2021-12-02 20:26:59.000000000 +0100
+++ new/foot/meson.build        2021-12-08 18:09:50.000000000 +0100
@@ -1,5 +1,5 @@
 project('foot', 'c',
-        version: '1.10.2',
+        version: '1.10.3',
         license: 'MIT',
         meson_version: '>=0.54.0',
         default_options: [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/terminal.c new/foot/terminal.c
--- old/foot/terminal.c 2021-12-02 20:26:59.000000000 +0100
+++ new/foot/terminal.c 2021-12-08 18:09:50.000000000 +0100
@@ -688,6 +688,11 @@
         : max(term->fonts[0]->height,
               term->fonts[0]->ascent + term->fonts[0]->descent);
 
+    if (term->cell_width <= 0)
+        term->cell_width = 1;
+    if (term->cell_height <= 0)
+        term->cell_height = 1;
+
     term->font_x_ofs = term_pt_or_px_as_pixels(term, 
&conf->horizontal_letter_offset);
     term->font_y_ofs = term_pt_or_px_as_pixels(term, 
&conf->vertical_letter_offset);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/foot/terminal.h new/foot/terminal.h
--- old/foot/terminal.h 2021-12-02 20:26:59.000000000 +0100
+++ new/foot/terminal.h 2021-12-08 18:09:50.000000000 +0100
@@ -133,7 +133,11 @@
     KITTY_KBD_REPORT_ALTERNATE = 0x04,
     KITTY_KBD_REPORT_ALL = 0x08,
     KITTY_KBD_REPORT_ASSOCIATED = 0x10,
-    KITTY_KBD_SUPPORTED = KITTY_KBD_DISAMBIGUATE,
+    KITTY_KBD_SUPPORTED = (KITTY_KBD_DISAMBIGUATE |
+                           KITTY_KBD_REPORT_EVENT |
+                           KITTY_KBD_REPORT_ALTERNATE |
+                           KITTY_KBD_REPORT_ALL |
+                           KITTY_KBD_REPORT_ASSOCIATED),
 };
 
 struct grid {

Reply via email to