fix(editor): Ctrl-Z aborts editor and returns to profanity
Some checks failed
CI Code / Check spelling (pull_request) Successful in 16s
CI Code / Check coding style (pull_request) Failing after 34s
CI Code / Code Coverage (pull_request) Successful in 3m1s
CI Code / Linux (debian) (pull_request) Successful in 4m43s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m55s
CI Code / Linux (arch) (pull_request) Successful in 6m55s
Some checks failed
CI Code / Check spelling (pull_request) Successful in 16s
CI Code / Check coding style (pull_request) Failing after 34s
CI Code / Code Coverage (pull_request) Successful in 3m1s
CI Code / Linux (debian) (pull_request) Successful in 4m43s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m55s
CI Code / Linux (arch) (pull_request) Successful in 6m55s
Replaces the SIGTSTP=SIG_IGN inheritance approach (was commit 8) with a detect-and-abort design that matches user expectation: Ctrl-Z inside the editor brings you back to profanity instead of leaving the session suspended. - src/tools/editor.c: SIGTSTP reset back to SIG_DFL in the child so vim's :stop / Ctrl-Z actually stop the editor (revert previous SIG_IGN inheritance). - src/tools/editor.c: new editor_check_stopped() — non-reaping waitpid poll for WIFSTOPPED. Lets prof_run detect Ctrl-Z / :stop / gdb-attach on the editor child. - src/tools/editor.c: editor_emergency_kill() now sends SIGCONT before SIGTERM so the abort works on a STOPPED child too. - src/tools/editor.c: _editor_exit_cb handles WIFSIGNALED cleanly with "Editor session cancelled." instead of printing garbage via WEXITSTATUS on a signaled child. - src/profanity.c: SIGTSTP / SIGCONT signal handlers set flags consumed by the main loop. Editor STOPPED -> editor_emergency_kill (returns to the chat with the pre-alt+c readline buffer intact). Plain Ctrl-Z with no editor -> mutt-style drop the process group to the shell. SIGCONT -> refresh curses with clearok + ui_resize. While editor is active, swallow suspend_requested (race: vim's kill(0,SIGTSTP) beats waitpid seeing STOPPED — next poll catches it). - src/tools/editor.h: declare editor_check_stopped and editor_is_active. Verbose comment blocks across the branch tightened to one to two lines.
This commit is contained in:
@@ -64,10 +64,8 @@ static Display* display;
|
||||
|
||||
static void _ui_draw_term_title(void);
|
||||
|
||||
// Skip drawing while an external editor is active (ui_suspended) or after the
|
||||
// screen has been closed (endwin). The flag is authoritative and does not rely
|
||||
// on isendwin() staying TRUE, which a stray doupdate() during the session could
|
||||
// otherwise clear.
|
||||
// Fail-safe gate: authoritative flag (doesn't depend on isendwin staying
|
||||
// TRUE), plus the regular endwin check for shutdown.
|
||||
static gboolean
|
||||
_ui_redraw_suspended(void)
|
||||
{
|
||||
|
||||
@@ -182,10 +182,8 @@ inp_readline(void)
|
||||
{
|
||||
// UI is suspended
|
||||
if (is_suspended || isendwin()) {
|
||||
// Mirror the normal-path unlock/sleep/lock so worker threads
|
||||
// (http_upload / http_download / ai_client) can acquire `lock`
|
||||
// during the editor session — otherwise the main thread holds
|
||||
// it continuously and every in-flight transfer freezes.
|
||||
// Mirror the normal-path unlock so workers aren't starved
|
||||
// for the whole editor session.
|
||||
pthread_mutex_unlock(&lock);
|
||||
g_usleep(100000); // 100ms
|
||||
pthread_mutex_lock(&lock);
|
||||
@@ -322,8 +320,8 @@ 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.
|
||||
// Let the editor child watch dispatch — otherwise a prompt raised
|
||||
// mid-editor-session deadlocks here.
|
||||
while (g_main_context_iteration(NULL, FALSE))
|
||||
;
|
||||
}
|
||||
@@ -354,8 +352,8 @@ 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.
|
||||
// Let the editor child watch dispatch — otherwise a prompt raised
|
||||
// mid-editor-session deadlocks here.
|
||||
while (g_main_context_iteration(NULL, FALSE))
|
||||
;
|
||||
}
|
||||
|
||||
@@ -43,9 +43,8 @@ void ui_load_colours(void);
|
||||
void ui_update(void);
|
||||
void ui_redraw(void);
|
||||
void ui_resize(void);
|
||||
// Centralised physical-paint primitive: flushes the virtual screen unless the
|
||||
// UI is suspended (external editor active) or the screen has been closed. Use
|
||||
// this instead of raw doupdate() in any path reachable while suspended.
|
||||
// doupdate() wrapper that skips when the UI is suspended. Use this instead
|
||||
// of raw doupdate() to avoid the per-site whitelist class of bug.
|
||||
void prof_doupdate(void);
|
||||
void ui_focus_win(ProfWin* window);
|
||||
void ui_sigwinch_handler(int sig);
|
||||
|
||||
Reference in New Issue
Block a user