From 0f128a46b3901e7cbc14cd753c161539e3af1c4d Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Mon, 17 Aug 2026 23:25:53 +0900 Subject: [PATCH] wl: another frontend's picture is not ours to show e64e4ea took the picture out of the owner poll and argued a later take could not show a stale one: "either our own key replaced it, or the engine suppressed the send because our snapshot is that same picture". The second half is the hole. redraw() returns before it drains when the picture has not changed, and under Wayland wl is drawc's only reader, so every IBus interaction leaves its last picture sitting there -- the mode mark after Ctrl+T, a hanja list, whatever was up. Press a bare modifier in a text-input-v3 window while IBus owns the engine: keymeaningful(0) is false, the engine changes nothing, the send is suppressed, and grabkey's takedraw puts the other window's candidates on our popup surface. I could not make it visible. checkowner() runs later in the same loop iteration, finds we are not the owner and hides it, and both commits leave in one wl_display_flush, so the compositor renders nothing between them. What is wrong is the rule: README says an IBus client under Wayland "shows no candidates, because the popup belongs to the Wayland frontend", and that is now true by construction rather than by luck. leave() and flushpending() already take only while engaged, so the guard costs nothing where it is and covers all three callers. The drain still happens either way, which is what keeps drawc and lastdraw in step. Phases A-G under headless sway at both scales; the phase E hanja popup is unchanged. Co-Authored-By: Claude Opus 5 (1M context) --- wl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wl.c b/wl.c index 28ea693..aef2f47 100644 --- a/wl.c +++ b/wl.c @@ -314,14 +314,15 @@ popup(Drawcmd *dc) /* * drawc is empty or holds exactly what the engine last published, so one * take is enough. lastdraw follows the engine and not our surface, so - * take it wherever the two can part. + * take it wherever the two can part -- but show it only while the engine + * is ours: what it drew for another frontend is not ours to put up. */ static void takedraw(void) { Drawcmd dc; - if(channbrecv(drawc, &dc) > 0) + if(channbrecv(drawc, &dc) > 0 && engaged) popup(&dc); }