commit: a5a058cad154d188170bc5ae5a8e4eb6200f6288
parent: e64d606e233e320d8df20958ee9e964fd95dca6a
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 3 May 2020 00:43:09 +0200
Merge branch 'features/download-progress' into develop
Diffstat:
8 files changed, 278 insertions(+), 71 deletions(-)
diff --git a/Makefile b/Makefile
@@ -21,8 +21,8 @@ PKGCONFIG ?= pkg-config
MSGFMT ?= msgfmt
DEPS = gtk+-3.0 webkit2gtk-4.0 libsoup-2.4
-SRCS = uri.c uri_test.c keybindings.c badwolf.c
-OBJS = uri.o keybindings.o badwolf.o
+SRCS = uri.c uri_test.c keybindings.c downloads.c badwolf.c
+OBJS = uri.o keybindings.o downloads.o badwolf.o
OBJS_test = uri_test.o
EXE = badwolf
EXE_test = uri_test
diff --git a/badwolf.c b/badwolf.c
@@ -5,6 +5,7 @@
#include "badwolf.h"
#include "config.h"
+#include "downloads.h"
#include "keybindings.h"
#include "uri.h"
@@ -50,9 +51,6 @@ static gboolean WebViewCb_decide_policy(WebKitWebView *web_view,
static void web_contextCb_download_started(WebKitWebContext *web_context,
WebKitDownload *download,
gpointer user_data);
-static gboolean downloadCb_decide_destination(WebKitDownload *download,
- gchar *suggested_filename,
- gpointer user_data);
static gboolean locationCb_activate(GtkEntry *location, gpointer user_data);
static gboolean javascriptCb_toggled(GtkButton *javascript, gpointer user_data);
static gboolean SearchEntryCb_next__match(GtkSearchEntry *search, gpointer user_data);
@@ -408,47 +406,37 @@ WebViewCb_load_failed_with_tls_errors(WebKitWebView *web_view,
static void
web_contextCb_download_started(WebKitWebContext *web_context,
- WebKitDownload *download,
+ WebKitDownload *webkit_download,
gpointer user_data)
{
(void)web_context;
+ struct Client *browser = (struct Client *)user_data;
+ struct Download *download = malloc(sizeof(struct Client));
- g_signal_connect(G_OBJECT(download),
+ if(download != NULL)
+ {
+ download->window = browser->window;
+
+ download_new_entry(webkit_download, download);
+
+ g_signal_connect(
+ G_OBJECT(webkit_download), "received-data", G_CALLBACK(downloadCb_received_data), download);
+ g_signal_connect(G_OBJECT(webkit_download),
+ "created-destination",
+ G_CALLBACK(downloadCb_created_destination),
+ download);
+ g_signal_connect(G_OBJECT(webkit_download), "failed", G_CALLBACK(downloadCb_failed), download);
+ g_signal_connect(
+ G_OBJECT(webkit_download), "finished", G_CALLBACK(downloadCb_finished), download);
+ }
+
+ g_signal_connect(G_OBJECT(webkit_download),
"decide-destination",
G_CALLBACK(downloadCb_decide_destination),
user_data);
}
static gboolean
-downloadCb_decide_destination(WebKitDownload *download,
- gchar *suggested_filename,
- gpointer user_data)
-{
- struct Client *browser = (struct Client *)user_data;
- gint chooser_response;
- GtkWindow *parent_window = GTK_WINDOW(browser->window->main_window);
-
- GtkFileChooserNative *file_dialog =
- gtk_file_chooser_native_new(NULL, parent_window, GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
- GtkFileChooser *file_chooser = GTK_FILE_CHOOSER(file_dialog);
-
- gtk_file_chooser_set_current_name(file_chooser, suggested_filename);
- gtk_file_chooser_set_do_overwrite_confirmation(file_chooser, TRUE);
- webkit_download_set_allow_overwrite(download, TRUE);
-
- chooser_response = gtk_native_dialog_run(GTK_NATIVE_DIALOG(file_dialog));
-
- if(chooser_response == GTK_RESPONSE_ACCEPT)
- webkit_download_set_destination(download, gtk_file_chooser_get_uri(file_chooser));
- else
- webkit_download_cancel(download);
-
- g_object_unref(file_dialog);
-
- return FALSE; /* Let it propagate */
-}
-
-static gboolean
locationCb_activate(GtkEntry *location, gpointer user_data)
{
struct Client *browser = (struct Client *)user_data;
@@ -786,6 +774,7 @@ main(int argc, char *argv[])
window->main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
window->notebook = gtk_notebook_new();
window->new_tab = gtk_button_new_from_icon_name("tab-new-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ window->downloads_tab = badwolf_downloads_tab_new();
gtk_window_set_default_size(
GTK_WINDOW(window->main_window), BADWOLF_DEFAULT_WIDTH, BADWOLF_DEFAULT_HEIGHT);
@@ -824,12 +813,9 @@ main(int argc, char *argv[])
gtk_notebook_popup_enable(GTK_NOTEBOOK(window->notebook));
gtk_container_add(GTK_CONTAINER(window->main_window), window->notebook);
+ gtk_widget_queue_draw(window->notebook);
- if(argc == 1)
- badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, NULL, NULL));
- else
- for(int i = 1; i < argc; ++i)
- badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, argv[i], NULL));
+ badwolf_downloads_tab_attach(window);
g_signal_connect(
window->main_window, "key-press-event", G_CALLBACK(main_windowCb_key_press_event), window);
@@ -841,6 +827,14 @@ main(int argc, char *argv[])
gtk_widget_show(window->new_tab);
gtk_widget_show_all(window->main_window);
+ if(argc == 1)
+ badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, NULL, NULL));
+ else
+ for(int i = 1; i < argc; ++i)
+ badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, argv[i], NULL));
+
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), 1);
+
gtk_main();
#if 0
diff --git a/badwolf.h b/badwolf.h
@@ -12,6 +12,7 @@ struct Window
GtkWidget *main_window;
GtkWidget *notebook;
GtkWidget *new_tab;
+ GtkWidget *downloads_tab;
};
struct Client
diff --git a/config.h b/config.h
@@ -42,6 +42,9 @@
// BADWOLF_STATUSBAR_PADDING: Amount of padding between statusbar elements
#define BADWOLF_STATUSBAR_PADDING 0
+// BADWOLF_DOWNLOAD_PADDING: Amount of padding between download list row-elements
+#define BADWOLF_DOWNLOAD_PADDING 5
+
/* BADWOLF_DEFAULT_WIDTH / BADWOLF_DEFAULT_HEIGHT:
* Used to define the default width/height of the window,
* useful for floating Window Managers, probably useless in tiling ones
diff --git a/downloads.c b/downloads.c
@@ -0,0 +1,160 @@
+// BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser
+// Copyright © 2019 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include "downloads.h"
+
+#include "badwolf.h"
+#include "config.h"
+
+#include <glib/gi18n.h> /* _() and other internationalization/localization helpers */
+
+static void
+download_stop_iconCb_clicked(GtkButton *stop_icon, gpointer user_data)
+{
+ (void)stop_icon;
+ WebKitDownload *webkit_download = (WebKitDownload *)user_data;
+
+ webkit_download_cancel(webkit_download);
+}
+
+void
+download_new_entry(WebKitDownload *webkit_download, struct Download *download)
+{
+ download->error = 0;
+ download->container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BADWOLF_DOWNLOAD_PADDING);
+ download->progress = gtk_progress_bar_new();
+ download->file_path = gtk_label_new(NULL);
+ download->status = gtk_label_new(_("Download starting…"));
+ download->icon =
+ gtk_image_new_from_icon_name("network-idle-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ download->stop_icon = gtk_button_new_from_icon_name("process-stop", GTK_ICON_SIZE_SMALL_TOOLBAR);
+
+ g_signal_connect(
+ download->stop_icon, "clicked", G_CALLBACK(download_stop_iconCb_clicked), webkit_download);
+
+ gtk_box_pack_start(GTK_BOX(download->container), download->icon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(download->container), download->progress, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(download->container), download->stop_icon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(download->container), download->status, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(download->container), download->file_path, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(
+ GTK_BOX(download->window->downloads_tab), download->container, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(download->container);
+}
+
+void
+downloadCb_created_destination(WebKitDownload *webkit_download,
+ gchar *destination,
+ gpointer user_data)
+{
+ (void)webkit_download;
+ struct Download *download = (struct Download *)user_data;
+
+ gtk_label_set_text(GTK_LABEL(download->file_path), destination);
+}
+
+gboolean
+downloadCb_decide_destination(WebKitDownload *webkit_download,
+ gchar *suggested_filename,
+ gpointer user_data)
+{
+ struct Client *browser = (struct Client *)user_data;
+ gint chooser_response;
+ GtkWindow *parent_window = GTK_WINDOW(browser->window->main_window);
+
+ GtkFileChooserNative *file_dialog =
+ gtk_file_chooser_native_new(NULL, parent_window, GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
+ GtkFileChooser *file_chooser = GTK_FILE_CHOOSER(file_dialog);
+
+ gtk_file_chooser_set_current_name(file_chooser, suggested_filename);
+ gtk_file_chooser_set_do_overwrite_confirmation(file_chooser, TRUE);
+ webkit_download_set_allow_overwrite(webkit_download, TRUE);
+
+ chooser_response = gtk_native_dialog_run(GTK_NATIVE_DIALOG(file_dialog));
+
+ if(chooser_response == GTK_RESPONSE_ACCEPT)
+ webkit_download_set_destination(webkit_download, gtk_file_chooser_get_uri(file_chooser));
+ else
+ webkit_download_cancel(webkit_download);
+
+ g_object_unref(file_dialog);
+
+ return FALSE; /* Let it propagate */
+}
+
+void
+downloadCb_failed(WebKitDownload *webkit_download, GError *error, gpointer user_data)
+{
+ (void)webkit_download;
+ (void)error;
+ struct Download *download = (struct Download *)user_data;
+
+ download->error = error;
+
+ if(g_error_matches(error, WEBKIT_DOWNLOAD_ERROR, WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER))
+ gtk_label_set_text(GTK_LABEL(download->status), _("Download cancelled"));
+ else
+ gtk_label_set_text(GTK_LABEL(download->status), _("Download error"));
+
+ gtk_image_set_from_icon_name(
+ GTK_IMAGE(download->icon), "network-error-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
+}
+
+void
+downloadCb_finished(WebKitDownload *webkit_download, gpointer user_data)
+{
+ (void)webkit_download;
+ struct Download *download = (struct Download *)user_data;
+
+ // gtk_button_set_image(GTK_BUTTON(download->stop_icon), NULL);
+ gtk_widget_destroy(download->stop_icon);
+
+ if(download->error == 0)
+ {
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(download->progress), 1);
+ gtk_label_set_text(GTK_LABEL(download->status), _("Download finished"));
+ gtk_image_set_from_icon_name(
+ GTK_IMAGE(download->icon), "network-idle-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ }
+
+ // TODO: Send notification
+}
+
+void
+downloadCb_received_data(WebKitDownload *webkit_download, guint64 data_lenght, gpointer user_data)
+{
+ (void)data_lenght;
+ struct Download *download = (struct Download *)user_data;
+ gchar *format_size = g_format_size(data_lenght);
+
+ gtk_image_set_from_icon_name(
+ GTK_IMAGE(download->icon), "network-receive-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_label_set_text(GTK_LABEL(download->status), format_size);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(download->progress),
+ webkit_download_get_estimated_progress(webkit_download));
+
+ g_free(format_size);
+}
+
+GtkWidget *
+badwolf_downloads_tab_new()
+{
+ return gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+}
+
+void
+badwolf_downloads_tab_attach(struct Window *window)
+{
+ gtk_notebook_insert_page(GTK_NOTEBOOK(window->notebook), window->downloads_tab, NULL, 0);
+ gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(window->notebook), window->downloads_tab, FALSE);
+ GtkWidget *downloads_tab_label =
+ gtk_image_new_from_icon_name("emblem-downloads", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_widget_set_tooltip_text(downloads_tab_label, _("Badwolf Downloads"));
+ gtk_notebook_set_tab_label(
+ GTK_NOTEBOOK(window->notebook), window->downloads_tab, downloads_tab_label);
+ gtk_notebook_set_menu_label_text(
+ GTK_NOTEBOOK(window->notebook), window->downloads_tab, _("Badwolf Downloads"));
+}
diff --git a/downloads.h b/downloads.h
@@ -0,0 +1,28 @@
+#include "badwolf.h"
+
+#include <gtk/gtk.h>
+
+struct Download
+{
+ struct Window *window;
+
+ GtkWidget *container;
+ GtkWidget *icon;
+ GtkWidget *stop_icon;
+ GtkWidget *file_path;
+ GtkWidget *progress;
+ GtkWidget *status;
+ GError *error;
+};
+
+void download_new_entry(WebKitDownload *webkit_download, struct Download *download);
+void
+downloadCb_created_destination(WebKitDownload *download, gchar *destination, gpointer user_data);
+gboolean downloadCb_decide_destination(WebKitDownload *download,
+ gchar *suggested_filename,
+ gpointer user_data);
+void downloadCb_failed(WebKitDownload *webkit_download, GError *error, gpointer user_data);
+void downloadCb_finished(WebKitDownload *download, gpointer user_data);
+void downloadCb_received_data(WebKitDownload *download, guint64 data_lenght, gpointer user_data);
+GtkWidget *badwolf_downloads_tab_new();
+void badwolf_downloads_tab_attach(struct Window *window);
diff --git a/po/messages.pot b/po/messages.pot
@@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Badwolf 0.5.1+ga60529e\n"
+"Project-Id-Version: Badwolf 0.5.1+gb1ff239.download-progress\n"
"Report-Msgid-Bugs-To: contact+badwolf-msgid@hacktivis.me\n"
-"POT-Creation-Date: 2020-04-02 06:58+0200\n"
+"POT-Creation-Date: 2020-05-01 00:20+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,51 +17,71 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: badwolf.c:772
+#: downloads.c:155 downloads.c:159
+msgid "Badwolf Downloads"
+msgstr ""
+
+#: badwolf.c:760
#, c-format
msgid "Buildtime WebKit version: %d.%d.%d\n"
msgstr ""
-#: badwolf.c:389
+#: badwolf.c:387
msgid "Continue"
msgstr ""
-#: badwolf.c:339
+#: badwolf.c:337
msgid ""
"Couldn't verify the TLS certificate to ensure a better security of the "
"connection. You might want to verify your machine and network.\n"
"\n"
msgstr ""
-#: badwolf.c:96
+#: badwolf.c:94
msgid "Crashed"
msgstr ""
-#: badwolf.c:362
+#: downloads.c:98
+msgid "Download cancelled"
+msgstr ""
+
+#: downloads.c:100
+msgid "Download error"
+msgstr ""
+
+#: downloads.c:118
+msgid "Download finished"
+msgstr ""
+
+#: downloads.c:28
+msgid "Download starting…"
+msgstr ""
+
+#: badwolf.c:360
msgid "Error: Some unknown error occurred validating the certificate.\n"
msgstr ""
-#: badwolf.c:343
+#: badwolf.c:341
msgid "Error: The X509 Certificate Authority is unknown.\n"
msgstr ""
-#: badwolf.c:356
+#: badwolf.c:354
msgid "Error: The certificate has been revoked.\n"
msgstr ""
-#: badwolf.c:353
+#: badwolf.c:351
msgid "Error: The certificate has expired. Check your system's clock.\n"
msgstr ""
-#: badwolf.c:359
+#: badwolf.c:357
msgid "Error: The certificate is considered to be insecure.\n"
msgstr ""
-#: badwolf.c:350
+#: badwolf.c:348
msgid "Error: The certificate isn't valid yet. Check your system's clock.\n"
msgstr ""
-#: badwolf.c:346
+#: badwolf.c:344
msgid "Error: The given identity doesn't match the expected one.\n"
msgstr ""
@@ -72,67 +92,67 @@ msgid ""
"Runtime WebKit version: %d.%d.%d"
msgstr ""
-#: badwolf.c:701
+#: badwolf.c:689
msgid "New tab"
msgstr ""
-#: badwolf.c:819
+#: badwolf.c:808
msgid "Open new tab"
msgstr ""
-#: badwolf.c:100
+#: badwolf.c:98
msgid "Out of Memory"
msgstr ""
-#: badwolf.c:770
+#: badwolf.c:758
#, c-format
msgid "Running Badwolf version: %s\n"
msgstr ""
-#: badwolf.c:777
+#: badwolf.c:765
#, c-format
msgid "Runtime WebKit version: %d.%d.%d\n"
msgstr ""
-#: badwolf.c:386
+#: badwolf.c:384
#, c-format
msgid "TLS Error for %s."
msgstr ""
-#: badwolf.c:389
+#: badwolf.c:387
msgid "Temporarly Add Exception"
msgstr ""
-#: badwolf.c:586
+#: badwolf.c:574
msgid "Toggle javascript"
msgstr ""
-#: badwolf.c:104
+#: badwolf.c:102
msgid "Unknown Crash"
msgstr ""
-#: badwolf.c:627
+#: badwolf.c:615
msgid "search in current page"
msgstr ""
-#: badwolf.c:95
+#: badwolf.c:93
msgid "the web process crashed.\n"
msgstr ""
-#: badwolf.c:99
+#: badwolf.c:97
msgid "the web process exceeded the memory limit.\n"
msgstr ""
-#: badwolf.c:103
+#: badwolf.c:101
msgid "the web process terminated for an unknown reason.\n"
msgstr ""
-#: badwolf.c:784
+#: badwolf.c:772
#, c-format
msgid "webkit-web-extension directory set to: %s\n"
msgstr ""
#. TRANSLATOR Ignore this entry. Done for forcing Unicode in xgettext.
-#: badwolf.c:848
+#: badwolf.c:842
msgid "ø"
msgstr ""
diff --git a/version.sh b/version.sh
@@ -1,8 +1,9 @@
#!/bin/sh
hash=$(git --git-dir="$(dirname $0)/.git" rev-parse --short HEAD 2>/dev/null)
+branch=$(git --git-dir="$(dirname $0)/.git" rev-parse --abbrev-ref HEAD | sed -r 's/.*[^0-9A-Za-z-]([0-9A-Za-z-]*)$/\1/g')
-if [ -n "$hash" ]
+if [ -n "$hash" ] || [ -n "$branch" ]
then
- printf '+g%s' "$hash"
+ printf '+g%s.%s' "$hash" "$branch"
fi
echo