From 40fd4ab551dcb9fac6e229d5fefa60eb1aafe34c Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Mon, 17 Aug 2026 21:21:07 +0900 Subject: [PATCH] wl: a deactivate hands the pending text back Two things arrive as a deactivate. When the focus moved, the compositor sent the text input its leave first, and sway's handle_im_commit finds no focused text input and drops the whole commit -- which is what the old comment described. But a client that merely disabled its text input still holds the focus: sway relays that deactivate only in that case (handle_text_input_disable returns early once the surface is unfocused), so the commit would have been delivered, and half a syllable was thrown away instead. A GtkEntry losing the focus to a button in its own window is that case. XIM and IBus both hand the text back there and drop it only when the client itself is gone -- ibus.c keeps the two apart as flushcontext and releasecontext. This gives the Wayland frontend the same halves. The commit that goes nowhere costs one empty request. Co-Authored-By: Claude Opus 5 (1M context) --- wl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/wl.c b/wl.c index dd57216..0cd9d26 100644 --- a/wl.c +++ b/wl.c @@ -352,10 +352,11 @@ releasegrab(void) } /* - * The context is going: give the client its keys back. The engine's - * pending text goes nowhere, because the compositor sends the text input - * its leave before it sends us the deactivate, and a commit with nothing - * focused to take it is dropped whatever serial it carries. + * The context is going: give the client its keys back and the pending + * text, as a lost focus does everywhere else. A client that only + * disabled its text input still holds the focus and takes the commit; + * when the focus itself moved, the compositor sent the text input its + * leave first and drops the commit whatever serial it carries. */ static void leave(void) @@ -365,6 +366,7 @@ leave(void) releasekeys(); if(engaged){ sendrequest(Keyrelease, 0, 0, &res); + answer(&res, ""); engaged = 0; takedraw(); }