From b622cdf534a74053692356da1aea493c1f1882ac Mon Sep 17 00:00:00 2001 From: Robert Timm Date: Sun, 23 Apr 2017 21:10:37 +0200 Subject: [PATCH] Reject window manager quit if downloading Rejects a window manager initiated quit signal if there are downloads in progress. This closes #375. --- src/main.c | 22 +++++++++++++++++++--- src/main.h | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 8a13d57..e58200e 100644 --- a/src/main.c +++ b/src/main.c @@ -80,6 +80,7 @@ static void on_webview_notify_uri(WebKitWebView *webview, GParamSpec *pspec, Client *c); static void on_webview_ready_to_show(WebKitWebView *webview, Client *c); static gboolean on_webview_web_process_crashed(WebKitWebView *webview, Client *c); +static gboolean on_window_delete_event(GtkWidget *window, GdkEvent *event, Client *c); static void on_window_destroy(GtkWidget *window, Client *c); static gboolean quit(Client *c); static void read_from_stdin(Client *c); @@ -447,17 +448,19 @@ void vb_modelabel_update(Client *c, const char *label) /** * Close the given client instances window. */ -void vb_quit(Client *c, gboolean force) +gboolean vb_quit(Client *c, gboolean force) { /* if not forced quit - don't quit if there are still running downloads */ if (!force && c->state.downloads) { - vb_echo_force(c, MSG_ERROR, TRUE, "Can't quit: there are running downloads"); - return; + vb_echo_force(c, MSG_ERROR, TRUE, "Can't quit: there are running downloads. Use :q! to force quit"); + return FALSE; } /* Don't run the quit synchronously, because this could lead to access of * no more existing widget where some command response is written. */ g_idle_add((GSourceFunc)quit, c); + + return TRUE; } /** @@ -673,6 +676,7 @@ static Client *client_new(WebKitWebView *webview, gboolean show) g_object_connect( G_OBJECT(c->window), "signal::destroy", G_CALLBACK(on_window_destroy), c, + "signal::delete-event", G_CALLBACK(on_window_delete_event), c, "signal::key-press-event", G_CALLBACK(on_map_keypress), c, NULL); @@ -1309,6 +1313,18 @@ static gboolean on_webview_web_process_crashed(WebKitWebView *webview, Client *c return TRUE; } +/** + * Callback for window ::delete-event signal which is emitted if a user + * requests that a toplevel window is closed. The default handler for this + * signal destroys the window. Returns TRUE to stop other handlers from being + * invoked for the event. FALSE to propagate the event further. + */ +static gboolean on_window_delete_event(GtkWidget *window, GdkEvent *event, Client *c) +{ + /* if vb_quit fails, do not propagate event further, keep window open */ + return !vb_quit(c, FALSE); +} + /** * Callback for the window destroy signal. * Destroys the client that is associated to the window. diff --git a/src/main.h b/src/main.h index 6ff37f4..38f8808 100644 --- a/src/main.h +++ b/src/main.h @@ -279,7 +279,7 @@ void vb_mode_add(char id, ModeTransitionFunc enter, ModeTransitionFunc leave, ModeKeyFunc keypress, ModeInputChangedFunc input_changed); VbResult vb_mode_handle_key(Client *c, int key); void vb_modelabel_update(Client *c, const char *label); -void vb_quit(Client *c, gboolean force); +gboolean vb_quit(Client *c, gboolean force); void vb_register_add(Client *c, char buf, const char *value); const char *vb_register_get(Client *c, char buf); void vb_statusbar_update(Client *c); -- 2.20.1