fix(ui): stop status bar / chat bleed-through over the external editor #131

Closed
jabber.developer2 wants to merge 11 commits from fix/editor-ui-suspend-redraw into master
11 changed files with 187 additions and 21 deletions
Showing only changes of commit 62d9c57925 - Show all commits

View File

@@ -70,12 +70,38 @@ static void _connect_default(const char* const account);
pthread_mutex_t lock;
static gboolean force_quit = FALSE;
// Signal-driven flags consumed by the main loop. SIGTSTP and a STOPPED editor
// child → drop the process group to the shell (mutt-style). SIGCONT →
// refresh curses on return.
static volatile sig_atomic_t suspend_requested = FALSE;
static volatile sig_atomic_t cont_requested = FALSE;
static void
jabber.developer marked this conversation as resolved Outdated

comments are still too verbose. Let's keep implementation details within commit messages.

comments are still too verbose. Let's keep implementation details within commit messages.

corrected

corrected
_handle_suspend_signals(void)
{
if (cont_requested) {
cont_requested = FALSE;
if (!editor_is_active()) {
clearok(stdscr, TRUE);
ui_resize();
}
}
if (editor_check_stopped()) {
log_info("[Editor] stopped; aborting back to profanity");
suspend_requested = FALSE;
editor_emergency_kill();
} else if (suspend_requested) {
suspend_requested = FALSE;
if (editor_is_active()) {
log_info("[Editor] SIGTSTP from vim group; deferring to next poll");
} else {
log_info("[Suspend] dropping to shell");
if (!isendwin()) {
endwin();
}
kill(0, SIGSTOP);
}
}
}
void
jabber.developer marked this conversation as resolved Outdated

Please extract this functionality to a different method if possible. Let's keep main loop minimal.

Please extract this functionality to a different method if possible. Let's keep main loop minimal.

corrected

corrected
prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_file, gchar* theme_name, gchar** commands)
{
@@ -99,36 +125,7 @@ prof_run(gchar* log_level, gchar* account_name, gchar* config_file, gchar* log_f
int waittime = 0;
while (cont && !force_quit) {
log_stderr_handler();
// Resume from fg after SIGSTOP. Vim handles its own refresh.
if (cont_requested) {
cont_requested = FALSE;
if (!editor_is_active()) {
clearok(stdscr, TRUE);
ui_resize();
}
}
// Editor STOPPED → abort. Plain Ctrl-Z → drop to shell. While editor
// is active, swallow suspend_requested (race: vim's kill(0,SIGTSTP)
// beats waitpid seeing STOPPED) — next poll catches it.
if (editor_check_stopped()) {
log_info("[Editor] stopped; aborting back to profanity");
suspend_requested = FALSE;
editor_emergency_kill();
} else if (suspend_requested) {
suspend_requested = FALSE;
if (editor_is_active()) {
log_info("[Editor] SIGTSTP from vim group; deferring to next poll");
} else {
log_info("[Suspend] dropping to shell");
if (!isendwin()) {
endwin();
}
kill(0, SIGSTOP);
}
}
_handle_suspend_signals();
session_check_autoaway();
line = commands ? *commands : inp_readline();

View File

@@ -32,9 +32,7 @@ typedef struct EditorContext
void* user_data;
} EditorContext;
// Re-entrancy guard (lost in the async-editor rewrite). Prevents a plugin
// from spawning a second editor that would fight the first for the terminal.
static gboolean editor_active = FALSE;
static gboolean editor_active = FALSE; // re-entrancy guard
static pid_t editor_pid = 0;
static void

View File

@@ -320,9 +320,7 @@ inp_get_line(void)
while (!line) {
line = inp_readline();
ui_update();
// Let the editor child watch dispatch — otherwise a prompt raised
// mid-editor-session deadlocks here.
while (g_main_context_iteration(NULL, FALSE))
while (g_main_context_iteration(NULL, FALSE)) // non-blocking; bounded by ready sources
;
}
status_bar_clear_prompt();
@@ -352,9 +350,7 @@ inp_get_password(void)
while (!password) {
password = inp_readline();
ui_update();
// Let the editor child watch dispatch — otherwise a prompt raised
// mid-editor-session deadlocks here.
while (g_main_context_iteration(NULL, FALSE))
while (g_main_context_iteration(NULL, FALSE)) // non-blocking; bounded by ready sources
;
}
get_password = FALSE;