From 193bc77912bb08b519b808886b869cfa4f6296fc Mon Sep 17 00:00:00 2001 From: Armaan Bhojwani Date: Sun, 6 Jun 2021 23:29:01 -0400 Subject: [PATCH] Revamp downloads manager --- browser.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 16 deletions(-) diff --git a/browser.c b/browser.c index f8ea0f1..ede3ec6 100644 --- a/browser.c +++ b/browser.c @@ -28,8 +28,9 @@ gboolean crashed_web_view(WebKitWebView *, gpointer); gboolean decide_policy(WebKitWebView *, WebKitPolicyDecision *, WebKitPolicyDecisionType, gpointer); gboolean download_handle(WebKitDownload *, gchar *, gpointer); -void download_handle_start(WebKitWebView *, WebKitDownload *, gpointer); -void downloadmanager_cancel(GtkToolButton *, gpointer); +void download_click(GtkToolButton *, gpointer); +void download_start(WebKitWebView *, WebKitDownload *, gpointer); +void download_cancel(GtkMenuItem *, gpointer); gboolean downloadmanager_delete(GtkWidget *, gpointer); void downloadmanager_setup(void); gchar *ensure_uri_scheme(const gchar *); @@ -101,6 +102,12 @@ struct Configuration gint tab_width_chars; } cfg; +struct DownloadItem +{ + GtkToolButton *tb; + WebKitDownload *download; +}; + gint clients = 0, downloads = 0; int cooperative_pipe_fp = 0; gchar *search_text; @@ -494,21 +501,25 @@ decide_policy(WebKitWebView *web_view, WebKitPolicyDecision *decision, } void -download_handle_finished(WebKitDownload *download, gpointer data) +download_finished(WebKitDownload *download, gpointer data) { + if (strcmp(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(data)), + "dialog-error") != 0) + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(data), "emblem-downloads"); downloads--; } void -download_handle_start(WebKitWebView *web_view, WebKitDownload *download, - gpointer data) +download_start(WebKitWebView *web_view, WebKitDownload *download, + gpointer data) { g_signal_connect(G_OBJECT(download), "decide-destination", G_CALLBACK(download_handle), data); } gboolean -download_handle(WebKitDownload *download, gchar *suggested_filename, gpointer data) +download_handle(WebKitDownload *download, gchar *suggested_filename, + gpointer data) { gchar *sug_clean, *path, *path2 = NULL, *uri; GtkToolItem *tb; @@ -538,7 +549,7 @@ download_handle(WebKitDownload *download, gchar *suggested_filename, gpointer da g_free(uri); tb = gtk_tool_button_new(NULL, NULL); - gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(tb), "gtk-delete"); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(tb), "network-receive"); gtk_tool_button_set_label(GTK_TOOL_BUTTON(tb), sug_clean); gtk_toolbar_insert(GTK_TOOLBAR(dm.toolbar), tb, 0); gtk_widget_show_all(dm.win); @@ -548,11 +559,19 @@ download_handle(WebKitDownload *download, gchar *suggested_filename, gpointer da downloads++; g_signal_connect(G_OBJECT(download), "finished", - G_CALLBACK(download_handle_finished), NULL); + G_CALLBACK(download_finished), tb); g_object_ref(download); - g_signal_connect(G_OBJECT(tb), "clicked", - G_CALLBACK(downloadmanager_cancel), download); + + struct DownloadItem *payload = malloc(sizeof(*payload)); + payload->tb = (GtkToolButton *)tb; + payload->download = download; + g_signal_connect(G_OBJECT(tb), "clicked", G_CALLBACK(download_click), + payload); + g_signal_connect(G_OBJECT(tb), "failed", G_CALLBACK(download_cancel), + payload); + g_signal_connect(G_OBJECT(tb), "destroy_event", G_CALLBACK(g_free), + payload); } g_free(sug_clean); @@ -564,14 +583,72 @@ download_handle(WebKitDownload *download, gchar *suggested_filename, gpointer da } void -downloadmanager_cancel(GtkToolButton *tb, gpointer data) +download_cancel(GtkMenuItem *tb, gpointer data) { - WebKitDownload *download = WEBKIT_DOWNLOAD(data); + struct DownloadItem *payload = data; + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(payload->tb), "dialog-error"); + webkit_download_cancel(payload->download); +} - webkit_download_cancel(download); - g_object_unref(download); +void +download_remove(GtkMenuItem *tb, gpointer data) +{ + struct DownloadItem *payload = data; + g_object_unref(payload->download); + gtk_widget_destroy(GTK_WIDGET(payload->tb)); +} - gtk_widget_destroy(GTK_WIDGET(tb)); +void +download_copy_url(GtkMenuItem *tb, gpointer data) +{ + struct DownloadItem *payload = data; + WebKitURIRequest *req = webkit_download_get_request(payload->download); + const gchar *uri = webkit_uri_request_get_uri(req); + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), uri, + strlen(uri)); +} + +void +download_copy_path(GtkMenuItem *tb, gpointer data) +{ + struct DownloadItem *payload = data; + const gchar *path = webkit_download_get_destination(payload->download); + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), path + 7, + strlen(path) - 7); // Offset by 7 to remove "file://" +} + +void +download_click(GtkToolButton *tb, gpointer data) +{ + GtkWidget *pmenu = gtk_menu_new(); + GtkWidget *option; + + if (strcmp(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(tb)), + "network-receive") == 0) { + option = gtk_menu_item_new_with_label("Cancel download"); + g_signal_connect(G_OBJECT(option), "activate", + G_CALLBACK(download_cancel), data); + } else { + option = gtk_menu_item_new_with_label("Remove download"); + g_signal_connect(G_OBJECT(option), "activate", + G_CALLBACK(download_remove), data); + } + gtk_widget_show(option); + gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option); + + option = gtk_menu_item_new_with_label("Copy download URL"); + gtk_widget_show(option); + gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option); + g_signal_connect(G_OBJECT(option), "activate", + G_CALLBACK(download_copy_url), data); + + option = gtk_menu_item_new_with_label("Copy local path"); + gtk_widget_show(option); + gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option); + g_signal_connect(G_OBJECT(option), "activate", + G_CALLBACK(download_copy_path), data); + + gtk_menu_popup_at_pointer(GTK_MENU(pmenu), NULL); } gboolean @@ -833,7 +910,7 @@ init_default_web_context(void) webkit_web_context_set_preferred_languages(wc, cfg.accepted_language); g_signal_connect(G_OBJECT(wc), "download-started", - G_CALLBACK(download_handle_start), NULL); + G_CALLBACK(download_start), NULL); trust_user_certs(wc); -- 2.39.2