123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759 |
- // BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser
- // Copyright © 2019 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
- // SPDX-License-Identifier: BSD-3-Clause
- #include "config.h"
- #include <glib/gi18n.h> /* _() and other internationalization/localization helpers */
- #include <glib/gprintf.h> /* g_fprintf() */
- #include <gtk/gtk.h>
- #include <locale.h> /* LC_* */
- #include <webkit2/webkit2.h>
- const gchar *homepage = "https://hacktivis.me/projects/badwolf";
- const gchar *version = "0.1.1";
- struct Window
- {
- GtkWidget *main_window;
- GtkWidget *notebook;
- GtkWidget *new_tab;
- };
- struct Client
- {
- GtkWidget *box;
- GtkWidget *toolbar;
- GtkWidget *javascript;
- GtkWidget *location;
- WebKitWebView *webView;
- struct Window *window;
- GtkWidget *statusbar;
- GtkWidget *statuslabel;
- GtkWidget *search;
- };
- 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);
- static gboolean
- WebViewCb_notify__uri(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data);
- GtkWidget *badwolf_new_tab_box(const gchar *title, struct Client *browser);
- static gboolean
- WebViewCb_notify__title(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data);
- static gboolean
- WebViewCb_notify__is__playing__audio(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data);
- void webView_tab_label_change(struct Client *browser, const gchar *title);
- static gboolean WebViewCb_notify__estimated_load_progress(WebKitWebView *webView,
- GParamSpec *pspec,
- gpointer user_data);
- static gboolean WebViewCb_mouse_target_changed(WebKitWebView *webView,
- WebKitHitTestResult *hit,
- guint modifiers,
- gpointer user_data);
- static WebKitWebView *WebViewCb_create(WebKitWebView *related_web_view,
- WebKitNavigationAction *navigation_action,
- 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);
- static gboolean SearchEntryCb_previous__match(GtkSearchEntry *search, gpointer user_data);
- static gboolean SearchEntryCb_search__changed(GtkSearchEntry *search, gpointer user_data);
- static gboolean SearchEntryCb_stop__search(GtkSearchEntry *search, gpointer user_data);
- struct Client *
- new_browser(struct Window *window, gchar *target_url, WebKitWebView *related_web_view);
- int badwolf_new_tab(GtkNotebook *notebook, struct Client *browser);
- 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);
- gint get_tab_position(GtkContainer *notebook, GtkWidget *child);
- void move_tab_position(GtkNotebook *notebook, GtkWidget *child, int delta);
- 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)
- {
- (void)webView;
- struct Client *browser = (struct Client *)user_data;
- GtkNotebook *notebook = GTK_NOTEBOOK(browser->window->notebook);
- gtk_notebook_remove_page(notebook, get_tab_position(GTK_CONTAINER(notebook), browser->box));
- gtk_widget_destroy(browser->box);
- free(browser);
- 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_SHIFT_MASK | GDK_CONTROL_MASK)) && (browser != NULL))
- {
- switch(((GdkEventKey *)event)->keyval)
- {
- case GDK_KEY_Page_Down: move_tab_position(notebook, browser->box, 1); return TRUE;
- case GDK_KEY_Page_Up: move_tab_position(notebook, browser->box, -1); return TRUE;
- }
- }
- 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;
- }
- }
- 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,
- gpointer user_data)
- {
- (void)webView;
- struct Client *browser = (struct Client *)user_data;
- switch(reason)
- {
- case WEBKIT_WEB_PROCESS_CRASHED:
- g_fprintf(stderr, _("the web process crashed.\n"));
- webView_tab_label_change(browser, _("title|Crashed"));
- break;
- case WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT:
- g_fprintf(stderr, _("the web process exceeded the memory limit.\n"));
- webView_tab_label_change(browser, _("title|Out of Memory"));
- break;
- default:
- g_fprintf(stderr, _("the web process terminated for an unknown reason.\n"));
- webView_tab_label_change(browser, _("title|Unknown Crash"));
- }
- return FALSE;
- }
- static gboolean
- WebViewCb_notify__uri(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data)
- {
- (void)webView;
- (void)pspec;
- const gchar *location_uri;
- struct Client *browser = (struct Client *)user_data;
- location_uri = webkit_web_view_get_uri(browser->webView);
- 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;
- }
- GtkWidget *
- badwolf_new_tab_box(const gchar *title, struct Client *browser)
- {
- (void)browser;
- GtkWidget *tab_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- GtkWidget *close =
- gtk_button_new_from_icon_name("window-close-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
- GtkWidget *label = gtk_label_new(title);
- GtkWidget *playing =
- gtk_image_new_from_icon_name("audio-volume-high-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
- #ifdef BADWOLF_TAB_BOX_WIDTH
- gtk_widget_set_size_request(label, BADWOLF_TAB_BOX_WIDTH, -1);
- #endif
- #ifdef BADWOLF_TAB_LABEL_CHARWIDTH
- gtk_label_set_width_chars(GTK_LABEL(label), BADWOLF_TAB_LABEL_CHARWIDTH);
- #endif
- gtk_widget_set_hexpand(tab_box, BADWOLF_TAB_HEXPAND);
- gtk_label_set_ellipsize(GTK_LABEL(label), BADWOLF_TAB_LABEL_ELLIPSIZE);
- gtk_label_set_single_line_mode(GTK_LABEL(label), TRUE);
- 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);
- gtk_button_set_relief(GTK_BUTTON(close), GTK_RELIEF_NONE);
- g_signal_connect(close, "clicked", G_CALLBACK(closeCb_clicked), browser);
- gtk_widget_set_tooltip_text(tab_box, title);
- gtk_widget_show_all(tab_box);
- gtk_widget_set_visible(playing, webkit_web_view_is_playing_audio(browser->webView));
- return tab_box;
- }
- static gboolean
- WebViewCb_notify__title(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data)
- {
- (void)webView;
- (void)pspec;
- struct Client *browser = (struct Client *)user_data;
- webView_tab_label_change(browser, NULL);
- return TRUE;
- }
- static gboolean
- WebViewCb_notify__is__playing__audio(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data)
- {
- (void)webView;
- (void)pspec;
- struct Client *browser = (struct Client *)user_data;
- webView_tab_label_change(browser, NULL);
- return TRUE;
- }
- void
- webView_tab_label_change(struct Client *browser, const gchar *title)
- {
- GtkWidget *notebook = browser->window->notebook;
- #define title_IS_EMPTY (title == NULL) || (title == (const gchar *)"")
- if(title_IS_EMPTY) title = webkit_web_view_get_title(browser->webView);
- if(title_IS_EMPTY) title = webkit_web_view_get_uri(browser->webView);
- if(title_IS_EMPTY) title = "BadWolf";
- gtk_notebook_set_tab_label(
- GTK_NOTEBOOK(notebook), browser->box, badwolf_new_tab_box(title, browser));
- if(get_tab_position(GTK_CONTAINER(notebook), browser->box) ==
- gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)))
- gtk_window_set_title(GTK_WINDOW(browser->window->main_window), title);
- }
- static gboolean
- WebViewCb_notify__estimated_load_progress(WebKitWebView *webView,
- GParamSpec *pspec,
- gpointer user_data)
- {
- (void)webView;
- (void)pspec;
- struct Client *browser = (struct Client *)user_data;
- gdouble progress;
- progress = webkit_web_view_get_estimated_load_progress(browser->webView);
- if(progress == 1)
- {
- progress = 0;
- }
- gtk_entry_set_progress_fraction(GTK_ENTRY(browser->location), progress);
- return TRUE;
- }
- static gboolean
- WebViewCb_mouse_target_changed(WebKitWebView *webView,
- WebKitHitTestResult *hit,
- guint modifiers,
- gpointer user_data)
- {
- (void)webView;
- (void)modifiers;
- 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), 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,
- gpointer user_data)
- {
- (void)navigation_action;
- struct Window *window = (struct Window *)user_data;
- struct Client *browser = new_browser(window, NULL, related_web_view);
- if(badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser) < 0)
- {
- return NULL;
- }
- else
- {
- return browser->webView;
- }
- }
- static gboolean
- locationCb_activate(GtkEntry *location, gpointer user_data)
- {
- const char *target_url;
- struct Client *browser = (struct Client *)user_data;
- target_url = gtk_entry_get_text(location);
- if(target_url != NULL) webkit_web_view_load_uri(browser->webView, target_url);
- return TRUE;
- }
- static gboolean
- javascriptCb_toggled(GtkButton *javascript, gpointer user_data)
- {
- struct Client *browser = (struct Client *)user_data;
- WebKitSettings *settings = webkit_web_view_get_settings(browser->webView);
- webkit_settings_set_enable_javascript(
- settings, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(javascript)));
- webkit_web_view_set_settings(browser->webView, settings);
- return TRUE;
- }
- static gboolean
- SearchEntryCb_next__match(GtkSearchEntry *search, gpointer user_data)
- {
- (void)search;
- struct Client *browser = (struct Client *)user_data;
- WebKitFindController *findController = webkit_web_view_get_find_controller(browser->webView);
- webkit_find_controller_search_next(findController);
- return TRUE;
- }
- static gboolean
- SearchEntryCb_previous__match(GtkSearchEntry *search, gpointer user_data)
- {
- (void)search;
- struct Client *browser = (struct Client *)user_data;
- WebKitFindController *findController = webkit_web_view_get_find_controller(browser->webView);
- webkit_find_controller_search_previous(findController);
- return TRUE;
- }
- static gboolean
- SearchEntryCb_search__changed(GtkSearchEntry *search, gpointer user_data)
- {
- struct Client *browser = (struct Client *)user_data;
- WebKitFindController *findController = webkit_web_view_get_find_controller(browser->webView);
- const gchar *search_text = gtk_entry_get_text(GTK_ENTRY(search));
- webkit_find_controller_search(findController, search_text, 0, 0);
- return TRUE;
- }
- static gboolean
- SearchEntryCb_stop__search(GtkSearchEntry *search, gpointer user_data)
- {
- (void)search;
- struct Client *browser = (struct Client *)user_data;
- WebKitFindController *findController = webkit_web_view_get_find_controller(browser->webView);
- webkit_find_controller_search_finish(findController);
- return TRUE;
- }
- 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";
- browser->window = window;
- browser->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- browser->toolbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- browser->location = gtk_entry_new();
- browser->javascript = gtk_check_button_new();
- browser->statusbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- browser->statuslabel = gtk_label_new(NULL);
- browser->search = gtk_search_entry_new();
- WebKitWebContext *web_context = webkit_web_context_new_ephemeral();
- webkit_web_context_set_process_model(web_context,
- WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
- WebKitSettings *settings = webkit_settings_new_with_settings(BADWOLF_WEBKIT_SETTINGS);
- browser->webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
- "web-context",
- webkit_web_context_new_ephemeral(),
- "related-view",
- related_web_view,
- "settings",
- settings,
- NULL));
- gtk_widget_set_tooltip_text(browser->javascript, _("Toggle javascript"));
- gtk_box_pack_start(GTK_BOX(browser->toolbar),
- GTK_WIDGET(browser->javascript),
- FALSE,
- FALSE,
- BADWOLF_TOOLBAR_PADDING);
- gtk_box_pack_start(GTK_BOX(browser->toolbar),
- GTK_WIDGET(browser->location),
- TRUE,
- TRUE,
- BADWOLF_TOOLBAR_PADDING);
- gtk_box_pack_start(
- GTK_BOX(browser->box), GTK_WIDGET(browser->toolbar), FALSE, FALSE, BADWOLF_BOX_PADDING);
- gtk_box_pack_start(
- GTK_BOX(browser->box), GTK_WIDGET(browser->webView), TRUE, TRUE, BADWOLF_BOX_PADDING);
- gtk_box_pack_start(
- GTK_BOX(browser->box), GTK_WIDGET(browser->statusbar), FALSE, FALSE, BADWOLF_BOX_PADDING);
- gtk_box_pack_start(GTK_BOX(browser->statusbar),
- GTK_WIDGET(browser->search),
- FALSE,
- FALSE,
- BADWOLF_STATUSBAR_PADDING);
- gtk_box_pack_start(GTK_BOX(browser->statusbar),
- GTK_WIDGET(browser->statuslabel),
- FALSE,
- FALSE,
- BADWOLF_STATUSBAR_PADDING);
- gtk_widget_set_halign(browser->statusbar, GTK_ALIGN_START);
- gtk_label_set_single_line_mode(GTK_LABEL(browser->statuslabel), TRUE);
- gtk_entry_set_text(GTK_ENTRY(browser->location), target_url);
- gtk_entry_set_has_frame(GTK_ENTRY(browser->location), FALSE);
- gtk_entry_set_input_purpose(GTK_ENTRY(browser->location), GTK_INPUT_PURPOSE_URL);
- gtk_entry_set_placeholder_text(GTK_ENTRY(browser->search), _("search in current page"));
- gtk_entry_set_has_frame(GTK_ENTRY(browser->search), FALSE);
- g_signal_connect(browser->location, "activate", G_CALLBACK(locationCb_activate), browser);
- g_signal_connect(browser->javascript, "toggled", G_CALLBACK(javascriptCb_toggled), browser);
- g_signal_connect(browser->webView,
- "web-process-terminated",
- G_CALLBACK(WebViewCb_web_process_terminated),
- browser);
- g_signal_connect(browser->webView, "notify::uri", G_CALLBACK(WebViewCb_notify__uri), browser);
- g_signal_connect(browser->webView, "notify::title", G_CALLBACK(WebViewCb_notify__title), browser);
- g_signal_connect(browser->webView,
- "notify::is-playing-audio",
- G_CALLBACK(WebViewCb_notify__is__playing__audio),
- browser);
- g_signal_connect(browser->webView,
- "mouse-target-changed",
- G_CALLBACK(WebViewCb_mouse_target_changed),
- browser);
- g_signal_connect(browser->webView,
- "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, "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(
- browser->search, "previous-match", G_CALLBACK(SearchEntryCb_previous__match), browser);
- g_signal_connect(
- 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;
- }
- int
- badwolf_new_tab(GtkNotebook *notebook, struct Client *browser)
- {
- gint current_page = gtk_notebook_get_current_page(notebook);
- gchar *title = _("New tab");
- gtk_widget_show_all(browser->box);
- if(gtk_notebook_insert_page(notebook, browser->box, NULL, (current_page + 2)) == -1)
- {
- return -1;
- }
- gtk_notebook_set_tab_reorderable(notebook, browser->box, TRUE);
- gtk_notebook_set_tab_label(notebook, browser->box, badwolf_new_tab_box(title, browser));
- gtk_widget_queue_draw(GTK_WIDGET(notebook));
- return 0;
- }
- static void
- new_tabCb_clicked(GtkButton *new_tab, gpointer user_data)
- {
- (void)new_tab;
- struct Window *window = (struct Window *)user_data;
- struct Client *browser = new_browser(window, NULL, NULL);
- badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser);
- }
- static void
- closeCb_clicked(GtkButton *close, gpointer user_data)
- {
- (void)close;
- struct Client *browser = (struct Client *)user_data;
- webkit_web_view_try_close(browser->webView);
- }
- static void
- notebookCb_switch__page(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data)
- {
- (void)page_num;
- struct Window *window = (struct Window *)user_data;
- GtkWidget *label = gtk_notebook_get_tab_label(notebook, page);
- // TODO: Maybe find a better way to store the title
- gtk_window_set_title(GTK_WINDOW(window->main_window), gtk_widget_get_tooltip_text(label));
- }
- gint
- get_tab_position(GtkContainer *notebook, GtkWidget *child)
- {
- GValue position = G_VALUE_INIT;
- g_value_init(&position, G_TYPE_INT);
- gtk_container_child_get_property(notebook, child, "position", &position);
- return g_value_get_int(&position);
- }
- void
- move_tab_position(GtkNotebook *notebook, GtkWidget *child, int delta)
- {
- if(notebook == NULL) return;
- if(child == NULL) return;
- printf("Moving tab: %d\n", delta);
- gint position = get_tab_position(GTK_CONTAINER(notebook), child) + delta;
- if(position < 0) position = 0;
- gtk_notebook_reorder_child(notebook, child, position);
- }
- int
- main(int argc, char *argv[])
- {
- struct Window *window = g_malloc(sizeof(struct Client));
- gchar *target_url = NULL;
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, DATADIR "/locale");
- 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,
- WEBKIT_MINOR_VERSION,
- WEBKIT_MICRO_VERSION);
- g_fprintf(stderr,
- _("Runtime WebKit version: %d.%d.%d\n"),
- webkit_get_major_version(),
- webkit_get_minor_version(),
- webkit_get_micro_version());
- gtk_init(&argc, &argv);
- if(argv[1]) target_url = argv[1];
- 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);
- gtk_window_set_default_size(
- GTK_WINDOW(window->main_window), BADWOLF_DEFAULT_WIDTH, BADWOLF_DEFAULT_HEIGHT);
- gtk_window_set_role(GTK_WINDOW(window->main_window), "browser");
- gtk_widget_set_tooltip_text(window->new_tab, _("Open new tab"));
- gtk_notebook_set_action_widget(GTK_NOTEBOOK(window->notebook), window->new_tab, GTK_PACK_END);
- gtk_notebook_set_scrollable(GTK_NOTEBOOK(window->notebook), TRUE);
- gtk_notebook_set_tab_pos(GTK_NOTEBOOK(window->notebook), BADWOLF_TAB_POSITION);
- gtk_notebook_popup_enable(GTK_NOTEBOOK(window->notebook));
- gtk_container_add(GTK_CONTAINER(window->main_window), window->notebook);
- 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;
- }
|