From b1ffc750a229a03d6f7e9e413a4a3a7d70e38279 Mon Sep 17 00:00:00 2001 From: "jabber.developer2" Date: Fri, 29 May 2026 08:48:51 +0300 Subject: [PATCH] fix(ui): iterate main context inside synchronous input loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit inp_get_line() / inp_get_password() loop `while (!x) { inp_readline(); ui_update(); }` with no g_main_context_iteration call. If such a prompt is raised from a network handler during an editor session — realistic triggers are TLS-cert verification on a reconnect (sv_ev_certfail -> ui_get_line() in src/event/server_events.c) and PGP passphrase on an incoming encrypted message (ui_ask_pgp_passphrase() in src/pgp/gpg.c) — the main thread is parked in this loop. inp_readline returns NULL (suspended), ui_update returns (ui_suspended), and the editor child watch never dispatches because the main loop never reaches its own g_main_context_iteration. is_suspended stays TRUE forever, the loop never receives input, and the app deadlocks until killed externally. Run the GLib iteration inside the loop body so the child watch can dispatch, _editor_exit_cb fires, ui_resume clears suspension, and the next inp_readline reads from the terminal — letting the user answer the deferred prompt once the editor is closed. --- src/ui/inputwin.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index 6e98af02..fd8a8835 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -325,6 +325,10 @@ inp_get_line(void) while (!line) { line = inp_readline(); ui_update(); + // Let GLib sources (notably the editor child watch) dispatch so + // ui_resume can run if the prompt was raised mid-editor-session. + while (g_main_context_iteration(NULL, FALSE)) + ; } status_bar_clear_prompt(); return line; @@ -356,6 +360,10 @@ inp_get_password(void) while (!password) { password = inp_readline(); ui_update(); + // Let GLib sources (notably the editor child watch) dispatch so + // ui_resume can run if the prompt was raised mid-editor-session. + while (g_main_context_iteration(NULL, FALSE)) + ; } get_password = FALSE; status_bar_clear_prompt();