logo

badwolf

Minimalist and privacy-oriented WebKitGTK+ browser
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:

MMakefile4++--
Mbadwolf.c72+++++++++++++++++++++++++++++++++---------------------------------------
Mbadwolf.h1+
Mconfig.h3+++
Adownloads.c160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adownloads.h28++++++++++++++++++++++++++++
Mpo/messages.pot76++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mversion.sh5+++--
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