Summary Files Commits Branches @commit @diff @stats
path: root / badwolf.c
diff options
context:
space:
mode:
Commit762114dcc99d4e70a0472813ff41f77e44277bb8 (patch)
Author
 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
2021-04-19 22:31:58 +0200
Committer
 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
2021-04-19 22:31:58 +0200
Files57387ef745ab5022bb34c74d304e9c32dbd7331d /badwolf.c
goodwolf-1.1.0.tar
goodwolf-1.1.0.tar.gz
goodwolf-1.1.0.zip
Parent680ca3102df72264022babbea5003fb98d8e5189 (diff)
Parent4abd7044fda92b4d3dcb4774ff8d5f7772987b6a (diff)
Merge branch 'release-1.1' into missy for 1.1.0 v1.1.0
1 files changed, 184 insertions, 30 deletions
-rw-r--r--badwolf.c214
diff --git a/badwolf.c b/badwolf.c
index 5bac0a6..aea2bbc 100644
--- a/badwolf.c
+++ b/badwolf.c
@@ -1,25 +1,30 @@
// BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser
-// Copyright © 2019-2020 Badwolf Authors <https://hacktivis.me/projects/badwolf>
+// Copyright © 2019-2021 Badwolf Authors <https://hacktivis.me/projects/badwolf>
// SPDX-License-Identifier: BSD-3-Clause
#include "badwolf.h"
+#include "bookmarks.h"
#include "config.h"
#include "downloads.h"
#include "keybindings.h"
#include "uri.h"
+#include <assert.h>
#include <glib/gi18n.h> /* _() and other internationalization/localization helpers */
#include <libsoup/soup.h> /* soup* */
#include <locale.h> /* LC_* */
-#include <stdio.h> /* perror(), fprintf() */
+#include <stdio.h> /* perror(), fprintf(), snprintf() */
#include <stdlib.h> /* malloc() */
#include <unistd.h> /* access() */
-gchar *web_extensions_directory;
const gchar *homepage = "https://hacktivis.me/projects/badwolf";
const gchar *version = VERSION;
+static gchar *web_extensions_directory;
+static uint64_t context_id_counter = 0;
+GtkTreeModel *bookmarks_completion_model;
+
static gboolean WebViewCb_close(WebKitWebView *webView, gpointer user_data);
static gboolean WebViewCb_web_process_terminated(WebKitWebView *webView,
WebKitWebProcessTerminationReason reason,
@@ -66,6 +71,7 @@ static void new_tabCb_clicked(GtkButton *new_tab, gpointer user_data);
static void closeCb_clicked(GtkButton *close, gpointer user_data);
static void
notebookCb_switch__page(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data);
+void content_managerCb_ready(GObject *store, GAsyncResult *result, gpointer user_data);
static gboolean
WebViewCb_close(WebKitWebView *webView, gpointer user_data)
@@ -126,10 +132,37 @@ WebViewCb_notify__uri(WebKitWebView *webView, GParamSpec *pspec, gpointer user_d
return TRUE;
}
+static char *
+fmt_context_id(uint64_t num, char *out)
+{
+ const char alpha_digits[27] = {" ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
+ char buf[66] = {'\0'};
+ int i, len = 0;
+
+ // Get 0 = 'A' instead of 0 = '' and 1 = 'A'
+ num++;
+
+ buf[len++] = ' ';
+ buf[len++] = ':';
+ do
+ {
+ buf[len++] = alpha_digits[num % 26];
+ } while(num /= 26);
+
+ for(i = 0; len > 0; i++)
+ out[i] = buf[--len];
+
+ return out;
+}
+
GtkWidget *
badwolf_new_tab_box(const gchar *title, struct Client *browser)
{
(void)browser;
+ char context_id_str[7] = "";
+
+ fmt_context_id(browser->context_id, context_id_str);
+
GtkWidget *tab_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_name(tab_box, "browser__tabbox");
GtkWidget *close =
@@ -137,6 +170,8 @@ badwolf_new_tab_box(const gchar *title, struct Client *browser)
gtk_widget_set_name(close, "browser__tabbox__close");
GtkWidget *label = gtk_label_new(title);
gtk_widget_set_name(label, "browser__tabbox__label");
+ GtkWidget *context_label = gtk_label_new(context_id_str);
+ gtk_widget_set_name(context_label, "browser__tabbox__context_label");
GtkWidget *playing =
gtk_image_new_from_icon_name("audio-volume-high-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
gtk_widget_set_name(playing, "browser__tabbox__playing");
@@ -151,7 +186,9 @@ badwolf_new_tab_box(const gchar *title, struct Client *browser)
gtk_label_set_ellipsize(GTK_LABEL(label), BADWOLF_TAB_LABEL_ELLIPSIZE);
gtk_label_set_single_line_mode(GTK_LABEL(label), TRUE);
+ gtk_label_set_single_line_mode(GTK_LABEL(context_label), TRUE);
+ gtk_box_pack_start(GTK_BOX(tab_box), context_label, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(tab_box), playing, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(tab_box), label, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(tab_box), close, FALSE, FALSE, 0);
@@ -280,10 +317,15 @@ WebViewCb_create(WebKitWebView *related_web_view,
gpointer user_data)
{
(void)navigation_action;
- struct Window *window = (struct Window *)user_data;
- struct Client *browser = new_browser(window, NULL, related_web_view);
+ struct Client *old_browser = (struct Client *)user_data;
+ struct Client *browser = NULL;
+
+ // shouldn't be needed but better be safe
+ old_browser->webView = related_web_view;
- if(badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser, FALSE) < 0)
+ browser = new_browser(old_browser->window, NULL, old_browser);
+
+ if(badwolf_new_tab(GTK_NOTEBOOK(old_browser->window->notebook), browser, FALSE) < 0)
return NULL;
else
return browser->webView;
@@ -423,7 +465,9 @@ web_contextCb_download_started(WebKitWebContext *web_context,
{
(void)web_context;
struct Client *browser = (struct Client *)user_data;
- struct Download *download = malloc(sizeof(struct Client));
+ struct Download *download = malloc(sizeof(struct Download));
+
+ assert(webkit_download);
if(download != NULL)
{
@@ -515,7 +559,7 @@ printCb_clicked(GtkButton *print, gpointer user_data)
WebKitPrintOperation *print_operation = webkit_print_operation_new(browser->webView);
- webkit_print_operation_run_dialog(print_operation, GTK_WINDOW(browser->window));
+ webkit_print_operation_run_dialog(print_operation, GTK_WINDOW(browser->window->main_window));
}
static gboolean
@@ -577,16 +621,19 @@ widgetCb_drop_button3_event(GtkWidget *widget, GdkEvent *event, gpointer user_da
}
struct Client *
-new_browser(struct Window *window, const gchar *target_url, WebKitWebView *related_web_view)
+new_browser(struct Window *window, const gchar *target_url, struct Client *old_browser)
{
struct Client *browser = malloc(sizeof(struct Client));
- target_url = badwolf_ensure_uri_scheme(target_url, (related_web_view == NULL));
+ target_url = badwolf_ensure_uri_scheme(target_url, (old_browser == NULL));
char *badwolf_l10n = NULL;
+ WebKitWebContext *web_context;
+
if(browser == NULL) return NULL;
- browser->window = window;
- browser->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ browser->window = window;
+ browser->context_id = old_browser == NULL ? context_id_counter++ : old_browser->context_id;
+ browser->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_name(browser->box, "browser__box");
browser->toolbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
@@ -625,14 +672,27 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat
browser->statuslabel = gtk_label_new(NULL);
gtk_widget_set_name(browser->statuslabel, "browser__statuslabel");
- setenv("GTK_THEME", ":light", 0);
+ if(old_browser == NULL)
+ {
+ WebKitWebsiteDataManager *website_data_manager = webkit_website_data_manager_new_ephemeral();
+ webkit_website_data_manager_set_itp_enabled(website_data_manager, TRUE);
- WebKitWebContext *web_context = webkit_web_context_new_ephemeral();
- webkit_web_context_set_sandbox_enabled(web_context, TRUE);
- webkit_web_context_set_process_model(web_context,
- WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
+ web_context = webkit_web_context_new_with_website_data_manager(website_data_manager);
+ g_object_unref(website_data_manager);
+ webkit_web_context_set_sandbox_enabled(web_context, TRUE);
+ webkit_web_context_set_process_model(web_context,
+ WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
+ webkit_web_context_set_web_extensions_directory(web_context, web_extensions_directory);
- webkit_web_context_set_web_extensions_directory(web_context, web_extensions_directory);
+ g_signal_connect(G_OBJECT(web_context),
+ "download-started",
+ G_CALLBACK(web_contextCb_download_started),
+ browser);
+ }
+ else
+ {
+ web_context = webkit_web_view_get_context(old_browser->webView);
+ }
badwolf_l10n = getenv("BADWOLF_L10N");
@@ -656,12 +716,17 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat
"web-context",
web_context,
"related-view",
- related_web_view,
+ old_browser == NULL ? NULL : old_browser->webView,
"settings",
settings,
+ "user-content-manager",
+ window->content_manager,
NULL));
gtk_widget_set_name(GTK_WIDGET(browser->webView), "browser__webView");
- g_object_unref(web_context);
+ if(old_browser == NULL)
+ {
+ g_object_unref(web_context);
+ }
g_object_unref(settings);
gtk_box_pack_start(
@@ -720,6 +785,15 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat
gtk_label_set_single_line_mode(GTK_LABEL(browser->statuslabel), TRUE);
gtk_label_set_ellipsize(GTK_LABEL(browser->statuslabel), BADWOLF_STATUSLABEL_ELLIPSIZE);
+ if(bookmarks_completion_model != NULL)
+ {
+ GtkEntryCompletion *location_completion = gtk_entry_completion_new();
+ GtkTreeModel *location_completion_model = bookmarks_completion_model;
+
+ bookmarks_completion_setup(location_completion, location_completion_model);
+ gtk_entry_set_completion(GTK_ENTRY(browser->location), location_completion);
+ }
+
gtk_entry_set_text(GTK_ENTRY(browser->location), target_url);
gtk_entry_set_input_purpose(GTK_ENTRY(browser->location), GTK_INPUT_PURPOSE_URL);
@@ -787,7 +861,7 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat
"notify::estimated-load-progress",
G_CALLBACK(WebViewCb_notify__estimated_load_progress),
browser);
- g_signal_connect(browser->webView, "create", G_CALLBACK(WebViewCb_create), window);
+ g_signal_connect(browser->webView, "create", G_CALLBACK(WebViewCb_create), browser);
g_signal_connect(browser->webView, "close", G_CALLBACK(WebViewCb_close), browser);
g_signal_connect(
browser->webView, "key-press-event", G_CALLBACK(WebViewCb_key_press_event), browser);
@@ -801,12 +875,6 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat
browser);
g_signal_connect(browser->webView, "load-changed", G_CALLBACK(WebViewCb_load_changed), browser);
- /* signals for WebView's WebContext */
- g_signal_connect(G_OBJECT(web_context),
- "download-started",
- G_CALLBACK(web_contextCb_download_started),
- browser);
-
/* signals for search widget */
g_signal_connect(browser->search, "next-match", G_CALLBACK(SearchEntryCb_next__match), browser);
g_signal_connect(
@@ -818,7 +886,7 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat
/* signals for box container */
g_signal_connect(browser->box, "key-press-event", G_CALLBACK(boxCb_key_press_event), browser);
- if(related_web_view == NULL) webkit_web_view_load_uri(browser->webView, target_url);
+ if(old_browser == NULL) webkit_web_view_load_uri(browser->webView, target_url);
return browser;
}
@@ -887,10 +955,75 @@ notebookCb_switch__page(GtkNotebook *notebook, GtkWidget *page, guint page_num,
gtk_window_set_title(GTK_WINDOW(window->main_window), gtk_widget_get_tooltip_text(label));
}
+void
+content_managerCb_ready(GObject *store, GAsyncResult *result, gpointer user_data)
+{
+ (void)store;
+ struct Window *window = (struct Window *)user_data;
+ GError *err = NULL;
+
+ WebKitUserContentFilter *filter =
+ webkit_user_content_filter_store_load_finish(window->content_store, result, &err);
+
+ if(filter == NULL)
+ {
+ if(err == NULL)
+ {
+ fprintf(stderr, _("badwolf: failed to load content-filter, err: [%d] %s\n"), -1, "unknown");
+ }
+ else
+ {
+ fprintf(stderr,
+ _("badwolf: failed to load content-filter, err: [%d] %s\n"),
+ err->code,
+ err->message);
+ }
+ }
+ else
+ {
+ fprintf(stderr, _("badwolf: content-filter loaded, adding to content-manager…\n"));
+ webkit_user_content_manager_add_filter(window->content_manager, filter);
+ }
+}
+
+static void
+storeCb_finish(WebKitUserContentFilterStore *store, GAsyncResult *result, gpointer user_data)
+{
+ (void)store;
+ struct Window *window = (struct Window *)user_data;
+ GError *err = NULL;
+
+ WebKitUserContentFilter *filter =
+ webkit_user_content_filter_store_save_finish(window->content_store, result, &err);
+
+ if(filter == NULL)
+ {
+ if(err == NULL)
+ {
+ fprintf(stderr,
+ _("badwolf: failed to compile content-filters.json, err: [%d] %s\n"),
+ -1,
+ "unknown");
+ }
+ else
+ {
+ fprintf(stderr,
+ _("badwolf: failed to compile content-filters.json, err: [%d] %s\n"),
+ err->code,
+ err->message);
+ }
+ }
+ else
+ {
+ webkit_user_content_filter_store_load(
+ window->content_store, "a", NULL, content_managerCb_ready, window);
+ }
+}
+
int
main(int argc, char *argv[])
{
- struct Window *window = &(struct Window){NULL, NULL, NULL, NULL};
+ struct Window *window = &(struct Window){NULL, NULL, NULL, NULL, NULL, NULL};
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, DATADIR "/locale");
bind_textdomain_codeset(PACKAGE, "UTF-8");
@@ -914,10 +1047,29 @@ main(int argc, char *argv[])
g_build_filename(g_get_user_data_dir(), "badwolf", "webkit-web-extension", NULL);
fprintf(stderr, _("webkit-web-extension directory set to: %s\n"), web_extensions_directory);
+ bookmarks_completion_model = bookmarks_completion_init();
+ g_object_ref(bookmarks_completion_model);
+
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();
+ window->downloads_tab = badwolf_downloads_tab_new();
+ window->content_manager = webkit_user_content_manager_new();
+
+ gchar *contentFilterPath =
+ g_build_filename(g_get_user_config_dir(), g_get_prgname(), "content-filters.json", NULL);
+ GFile *contentFilterFile = g_file_new_for_path(contentFilterPath);
+ fprintf(stderr, _("content-filters file set to: %s\n"), contentFilterPath);
+
+ gchar *filtersPath = g_build_filename(g_get_user_cache_dir(), g_get_prgname(), "filters", NULL);
+ window->content_store = webkit_user_content_filter_store_new(filtersPath);
+
+ webkit_user_content_filter_store_save_from_file(window->content_store,
+ "a",
+ contentFilterFile,
+ NULL,
+ (GAsyncReadyCallback)storeCb_finish,
+ window);
gtk_window_set_default_size(
GTK_WINDOW(window->main_window), BADWOLF_DEFAULT_WIDTH, BADWOLF_DEFAULT_HEIGHT);
@@ -981,6 +1133,8 @@ main(int argc, char *argv[])
gtk_main();
+ g_object_unref(bookmarks_completion_model);
+
#if 0
/* TRANSLATOR Ignore this entry. Done for forcing Unicode in xgettext. */
_("ø");