diff options
| Commit | 9a186b4bc0dca9533c0697cde7cc36fe35a9c978 (patch) | |
|---|---|---|
| Author | 2019-05-13 10:44:58 +0200 | |
| Committer | 2019-05-13 10:44:58 +0200 | |
| Files | f4bd364255f155cb59004652bade89ba999be651 /badwolf.c | |
| goodwolf-0.2.0.tar goodwolf-0.2.0.tar.gz goodwolf-0.2.0.zip | ||
| Parent | 1b868aad609d9c3460af8df0e2c151d4f755f210 (diff) | |
| Parent | fb531698c4e5f3c0c2f7a9151222ba8aaa6bd1e7 (diff) | |
Release 0.2.0 v0.2.0
1 files changed, 201 insertions, 4 deletions
| -rw-r--r-- | badwolf.c | 205 |
@@ -8,8 +8,12 @@ #include <glib/gprintf.h> /* g_fprintf() */ #include <gtk/gtk.h> #include <locale.h> /* LC_* */ +#include <stdlib.h> /* realpath() */ #include <webkit2/webkit2.h> +const gchar *homepage = "https://hacktivis.me/projects/badwolf"; +const gchar *version = "0.2.0"; + struct Window { GtkWidget *main_window; @@ -33,7 +37,15 @@ struct Client GtkWidget *search; }; +gchar *ensure_uri_scheme(gchar *text, gboolean try_file); static gboolean WebViewCb_close(WebKitWebView *webView, gpointer user_data); +static gboolean +commonCb_key_press_event(struct Window *window, GdkEvent *event, struct Client *browser); +static gboolean +WebViewCb_key_press_event(WebKitWebView *webView, GdkEvent *event, gpointer user_data); +static gboolean +main_windowCb_key_press_event(GtkWidget *widget, GdkEvent *event, gpointer user_data); +static gboolean boxCb_key_press_event(GtkWidget *widget, GdkEvent *event, gpointer user_data); static gboolean WebViewCb_web_process_terminated(WebKitWebView *webView, WebKitWebProcessTerminationReason reason, gpointer user_data); @@ -70,6 +82,49 @@ static void notebookCb_switch__page(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data); gint get_tab_position(GtkContainer *notebook, GtkWidget *child); +gchar * +ensure_uri_scheme(gchar *text, gboolean try_file) +{ + if(text == NULL) return "about:blank"; + + char *scheme = g_uri_parse_scheme(text); + + if(scheme != NULL) return text; + + if(try_file) + { + gchar *f; + char *path; + path = realpath(text, NULL); + + if(path != NULL) + { + f = g_strdup_printf("file://%s", path); + free(path); + return f; + } + } + + return g_strdup_printf("http://%s", text); +} + +static void +badwolf_about_dialog(GtkWindow *main_window) +{ + // clang-format off + gtk_show_about_dialog( + main_window, + "license", "SPDX-License-Identifier: BSD-3-Clause", + "copyright", "2019 Haelwenn (lanodan) Monnier <contact+badwolf@hacktivis.me>", + "website", homepage, + "comments", "Minimalist and privacy-oriented WebKitGTK+ browser", + "version", version, + //FIXME: "logo-icon-name", g_get_application_name(), + NULL + ); + // clang-format on +} + static gboolean WebViewCb_close(WebKitWebView *webView, gpointer user_data) { @@ -86,6 +141,113 @@ WebViewCb_close(WebKitWebView *webView, gpointer user_data) return TRUE; } +/* commonCb_key_press_event: Global callback for keybindings + * + * Theses shortcuts should be avoided as much as possible: + * - Single key shortcuts (ie. backspace and space) + * - Triple key shortcuts (except for Ctrl+Shift) + * - Unix Terminal shortcuts (specially Ctrl-W) + * + * loosely follows https://developer.gnome.org/hig/stable/keyboard-input.html + */ +static gboolean +commonCb_key_press_event(struct Window *window, GdkEvent *event, struct Client *browser) +{ + GtkNotebook *notebook = GTK_NOTEBOOK(window->notebook); + + if(((GdkEventKey *)event)->state & GDK_CONTROL_MASK) + { + if(browser != NULL) + { + switch(((GdkEventKey *)event)->keyval) + { + case GDK_KEY_F4: webkit_web_view_try_close(browser->webView); return TRUE; + case GDK_KEY_r: + if(((GdkEventKey *)event)->state & GDK_SHIFT_MASK) + webkit_web_view_reload_bypass_cache(browser->webView); + else + webkit_web_view_reload(browser->webView); + + return TRUE; + case GDK_KEY_f: gtk_widget_grab_focus(browser->search); return TRUE; + case GDK_KEY_l: gtk_widget_grab_focus(browser->location); return TRUE; + case GDK_KEY_bracketleft: webkit_web_view_go_back(browser->webView); return TRUE; + case GDK_KEY_bracketright: webkit_web_view_go_forward(browser->webView); return TRUE; + case GDK_KEY_0: + webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(browser->webView), 1); + return TRUE; + } + } + else + { + switch(((GdkEventKey *)event)->keyval) + { + case GDK_KEY_Page_Down: gtk_notebook_next_page(notebook); return TRUE; + case GDK_KEY_Page_Up: gtk_notebook_prev_page(notebook); return TRUE; + case GDK_KEY_t: badwolf_new_tab(notebook, new_browser(window, NULL, NULL)); return TRUE; + } + } + } + + if((((GdkEventKey *)event)->state & GDK_MOD1_MASK) && browser != NULL) + { + switch(((GdkEventKey *)event)->keyval) + { + case GDK_KEY_Left: gtk_notebook_prev_page(notebook); return TRUE; + case GDK_KEY_Right: gtk_notebook_next_page(notebook); return TRUE; + } + } + + if(browser != NULL) + { + switch(((GdkEventKey *)event)->keyval) + { + case GDK_KEY_F5: webkit_web_view_reload(browser->webView); return TRUE; + } + } + else + { + switch(((GdkEventKey *)event)->keyval) + { + case GDK_KEY_F1: badwolf_about_dialog(GTK_WINDOW(window->main_window)); return TRUE; + } + } + + return FALSE; +} + +static gboolean +WebViewCb_key_press_event(WebKitWebView *webView, GdkEvent *event, gpointer user_data) +{ + (void)webView; + struct Client *browser = (struct Client *)user_data; + + if(commonCb_key_press_event(browser->window, event, browser)) return TRUE; + + return FALSE; +} + +static gboolean +boxCb_key_press_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + (void)widget; + struct Client *browser = (struct Client *)user_data; + + if(commonCb_key_press_event(browser->window, event, browser)) return TRUE; + + return FALSE; +} + +static gboolean +main_windowCb_key_press_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + (void)widget; + struct Window *window = (struct Window *)user_data; + + if(commonCb_key_press_event(window, event, NULL)) return TRUE; + + return FALSE; +} static gboolean WebViewCb_web_process_terminated(WebKitWebView *webView, WebKitWebProcessTerminationReason reason, @@ -124,6 +286,11 @@ WebViewCb_notify__uri(WebKitWebView *webView, GParamSpec *pspec, gpointer user_d gtk_entry_set_text(GTK_ENTRY(browser->location), location_uri); + if(webkit_uri_for_display(location_uri) != location_uri) + gtk_widget_set_tooltip_text(browser->location, webkit_uri_for_display(location_uri)); + else + gtk_widget_set_has_tooltip(browser->location, false); + return TRUE; } @@ -239,11 +406,31 @@ WebViewCb_mouse_target_changed(WebKitWebView *webView, struct Client *browser = (struct Client *)user_data; const gchar *link_uri = webkit_hit_test_result_get_link_uri(hit); - gtk_label_set_text(GTK_LABEL(browser->statuslabel), link_uri); + gtk_label_set_text(GTK_LABEL(browser->statuslabel), webkit_uri_for_display(link_uri)); return TRUE; } +static gboolean +WebViewCb_scroll_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + (void)widget; + struct Client *browser = (struct Client *)data; + gdouble delta_x, delta_y; + gfloat zoom; + + if(((GdkEventScroll *)event)->state & GDK_CONTROL_MASK) + { + gdk_event_get_scroll_deltas(event, &delta_x, &delta_y); + zoom = webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(browser->webView)); + zoom -= delta_y * 0.1; + webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(browser->webView), zoom); + return TRUE; + } + + return FALSE; +} + static WebKitWebView * WebViewCb_create(WebKitWebView *related_web_view, WebKitNavigationAction *navigation_action, @@ -266,10 +453,10 @@ WebViewCb_create(WebKitWebView *related_web_view, static gboolean locationCb_activate(GtkEntry *location, gpointer user_data) { - const char *target_url; + char *target_url; struct Client *browser = (struct Client *)user_data; - target_url = gtk_entry_get_text(location); + target_url = ensure_uri_scheme((char *)gtk_entry_get_text(location), FALSE); if(target_url != NULL) webkit_web_view_load_uri(browser->webView, target_url); @@ -343,7 +530,7 @@ struct Client * new_browser(struct Window *window, gchar *target_url, WebKitWebView *related_web_view) { struct Client *browser = g_malloc(sizeof(struct Client)); - if(target_url == NULL) target_url = "about:blank"; + target_url = ensure_uri_scheme(target_url, (related_web_view != NULL)); browser->window = window; browser->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); @@ -437,6 +624,9 @@ new_browser(struct Window *window, gchar *target_url, WebKitWebView *related_web browser); g_signal_connect(browser->webView, "create", G_CALLBACK(WebViewCb_create), window); 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); + g_signal_connect(browser->webView, "scroll-event", G_CALLBACK(WebViewCb_scroll_event), browser); g_signal_connect(browser->search, "next-match", G_CALLBACK(SearchEntryCb_next__match), browser); g_signal_connect( @@ -445,6 +635,8 @@ new_browser(struct Window *window, gchar *target_url, WebKitWebView *related_web browser->search, "search-changed", G_CALLBACK(SearchEntryCb_search__changed), browser); g_signal_connect(browser->search, "stop-search", G_CALLBACK(SearchEntryCb_stop__search), browser); + 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); return browser; @@ -523,6 +715,7 @@ main(int argc, char *argv[]) bind_textdomain_codeset(PACKAGE, "UTF-8"); textdomain(PACKAGE); + g_fprintf(stderr, _("Running Badwolf version: %s\n"), version); g_fprintf(stderr, _("Buildtime WebKit version: %d.%d.%d\n"), WEBKIT_MAJOR_VERSION, @@ -557,12 +750,16 @@ main(int argc, char *argv[]) badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, target_url, NULL)); + g_signal_connect( + window->main_window, "key-press-event", G_CALLBACK(main_windowCb_key_press_event), window); + g_signal_connect(window->main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(window->new_tab, "clicked", G_CALLBACK(new_tabCb_clicked), window); g_signal_connect(window->notebook, "switch-page", G_CALLBACK(notebookCb_switch__page), window); gtk_widget_show(window->new_tab); gtk_widget_show_all(window->main_window); + gtk_main(); return 0; } |