feat: implement asynchronous external editor support

Move from blocking fork/wait logic to nonblocking fork and
g_child_watch_add.

This ensures that the Profanity main loop continues to run while an
external editor is open. So we don't loose connection and react to
pings.

We change editor handling also in vcard and muc subject editing.
In the new implementation we are launching the editor and passing a
callback which we will use once the editor exited.

We use the recently added ui_susped() and ui_resume().

To not clutter the UI we need to check whether Profanity UI is suspended
and omit drawing in this case.

Fixes: https://github.com/profanity-im/profanity/issues/1888
Ref: 9b112904a9bc7250dc013d901187ca8622580d98
Signed-off-by: Michael Vetter <jubalh@iodoru.org>
This commit is contained in:
Michael Vetter
2026-04-02 21:30:31 +02:00
parent fc66ddc2c1
commit 36ec2b0ae1
5 changed files with 178 additions and 89 deletions

View File

@@ -171,6 +171,12 @@ _inp_slashguard_check(void)
char*
inp_readline(void)
{
// UI is suspended
if (isendwin()) {
g_usleep(100000); // 100ms
return NULL;
}
p_rl_timeout.tv_sec = inp_timeout / 1000;
p_rl_timeout.tv_usec = inp_timeout % 1000 * 1000;
FD_ZERO(&fds);
@@ -996,6 +1002,16 @@ _inp_rl_down_arrow_handler(int count, int key)
return 0;
}
static void
_editor_finished_cb(gchar* message, void* user_data)
{
if (message) {
rl_replace_line(message, 0);
rl_point = rl_end;
rl_forced_update_display();
}
}
static int
_inp_rl_send_to_editor(int count, int key)
{
@@ -1003,16 +1019,7 @@ _inp_rl_send_to_editor(int count, int key)
return 0;
}
auto_gchar gchar* message = NULL;
if (get_message_from_editor(rl_line_buffer, &message)) {
return 0;
}
rl_replace_line(message, 0);
ui_resize();
rl_point = rl_end;
rl_forced_update_display();
launch_editor(rl_line_buffer, _editor_finished_cb, NULL);
return 0;
}