From 9072abf0ae249c6903cb5966f2d64960b51d25cb Mon Sep 17 00:00:00 2001 From: Armaan Bhojwani Date: Sat, 30 Oct 2021 20:19:14 -0400 Subject: [PATCH] draft 7 --- .clang-format | 2 +- Makefile | 7 + browser.c | 473 ++++++-------------------------------------------- chorizo.h | 117 +++++++++++++ config.h | 25 ++- downloads.c | 7 +- downloads.h | 5 - globals.h | 34 ++++ shortcuts.c | 348 +++++++++++++++++++++++++++++++++++++ 9 files changed, 574 insertions(+), 444 deletions(-) create mode 100644 chorizo.h delete mode 100644 downloads.h create mode 100644 globals.h create mode 100644 shortcuts.c diff --git a/.clang-format b/.clang-format index cbd2a0c..15fa300 100644 --- a/.clang-format +++ b/.clang-format @@ -77,7 +77,7 @@ PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: true -SortIncludes: true +SortIncludes: false SortUsingDeclarations: true # Unknown to clang-format-4.0 SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true diff --git a/Makefile b/Makefile index cec6353..7d74b4a 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,13 @@ chorizo: format: for i in *.c *.h; do clang-format $$i > tmp; mv tmp $$i; done +headers: + mv config.h tmp + rm chorizo.h + makeheaders -h *.[ch] > tmp2 + mv tmp config.h + mv tmp2 chorizo.h + extensions: for i in extensions/*.c; do \ outp=$$(echo "$$i" | sed 's/\$\.c/.so/g'); \ diff --git a/browser.c b/browser.c index f8d50df..1d31c9e 100644 --- a/browser.c +++ b/browser.c @@ -6,62 +6,11 @@ #include #include "config.h" -#include "downloads.h" - -WebKitWebView *client_new_request(WebKitWebView *, WebKitNavigationAction *, - gpointer); -gboolean crashed_web_view(WebKitWebView *, gpointer); -gboolean decide_policy(WebKitWebView *, WebKitPolicyDecision *, - WebKitPolicyDecisionType, gpointer); -gboolean key_location(GtkWidget *, GdkEvent *, gpointer); -gboolean key_tablabel(GtkWidget *, GdkEvent *, gpointer); -gboolean key_web_view(GtkWidget *, GdkEvent *, gpointer); -gboolean key_common(GtkWidget *, GdkEvent *, gpointer); -gboolean key_wsearch(GtkWidget *, GdkEvent *, gpointer); -gboolean key_isearch(GtkWidget *, GdkEvent *, gpointer); -gboolean isearch_counted_matches(GtkWidget *, guint, gpointer); -gboolean remote_msg(GIOChannel *, GIOCondition, gpointer); -gchar *ensure_uri_scheme(const gchar *); -void changed_favicon(GObject *, GParamSpec *, gpointer); -void changed_load_progress(GObject *, GParamSpec *, gpointer); -void changed_title(GObject *, GParamSpec *, gpointer); -void changed_uri(GObject *, GParamSpec *, gpointer); -void grab_feeds_finished(GObject *, GAsyncResult *, gpointer); -void hover_web_view(WebKitWebView *, WebKitHitTestResult *, guint, gpointer); -void icon_location(GtkEntry *, GtkEntryIconPosition, GdkEvent *, gpointer); -void mainwindow_title(gint); -void notebook_switch_page(GtkNotebook *, GtkWidget *, guint, gpointer); -void show_web_view(WebKitWebView *, gpointer); -void trust_user_certs(WebKitWebContext *); - -struct Client { - GtkWidget *location; - GtkWidget *wsearch; - GtkWidget *isearch; - GtkWidget *isearch_box; - GtkWidget *isearch_matches; - GtkWidget *tabicon; - GtkWidget *tablabel; - GtkWidget *vbox; - GtkWidget *web_view; - WebKitSettings *settings; - gboolean focus_new_tab; - gchar *external_handler_uri; - gchar *feed_html; - gchar *hover_uri; -}; - -struct MainWindow { - GtkWidget *notebook; - GtkWidget *win; -} mw; - -struct Configuration { - gboolean cooperative_alone; - gboolean noncooperative_instances; - gboolean private; - gboolean verbose; -} cfg; +#include "chorizo.h" + +struct MainWindow mw; +struct Configuration cfg; +gboolean switch_tab; gint clients = 0; @@ -70,6 +19,43 @@ gchar *fifopath; char **closed_tabs; size_t num_closed = 0; +gboolean +isearch_counted_matches(GtkWidget *widget, guint matches, gpointer data) +{ + struct Client *c = (struct Client *)data; + char *text = malloc(12); + sprintf(text, "%d matches", matches); + gtk_label_set_text(GTK_LABEL(c->isearch_matches), text); + free(text); + return TRUE; +} + +gboolean +quit_if_nothing_active(void) +{ + if (clients == 0) { + if (downloads == 0) { + gtk_main_quit(); + return TRUE; + } else { + downloadmanager_show(); + } + } + return FALSE; +} +gboolean +remote_msg(GIOChannel *channel, GIOCondition condition, gpointer data) +{ + gchar *uri = NULL; + g_io_channel_read_line(channel, &uri, NULL, NULL, NULL); + if (uri) { + g_strstrip(uri); + client_new(uri, NULL); + g_free(uri); + } + return TRUE; +} + void allocfail(void) { @@ -127,8 +113,7 @@ set_uri(const char *uri, struct Client *c) } WebKitWebView * -client_new(const gchar *uri, WebKitWebView *related_wv, gboolean show, - gboolean focus_tab) +client_new(const gchar *uri, WebKitWebView *related_wv) { struct Client *c; gchar *f; @@ -143,7 +128,6 @@ client_new(const gchar *uri, WebKitWebView *related_wv, gboolean show, } c = calloc(1, sizeof(struct Client)); if (!c) allocfail(); - c->focus_new_tab = focus_tab; if (related_wv == NULL) { WebKitUserContentManager *ucm = @@ -224,7 +208,7 @@ client_new(const gchar *uri, WebKitWebView *related_wv, gboolean show, "notify::estimated-load-progress", G_CALLBACK(changed_load_progress), c); g_signal_connect(G_OBJECT(c->web_view), "create", - G_CALLBACK(client_new_request), NULL); + G_CALLBACK(client_new_request), c); g_signal_connect(G_OBJECT(c->web_view), "close", G_CALLBACK(client_destroy), c); g_signal_connect(G_OBJECT(c->web_view), "decide-policy", @@ -345,11 +329,7 @@ client_new(const gchar *uri, WebKitWebView *related_wv, gboolean show, gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(mw.notebook), c->vbox, TRUE); - if (show) - show_web_view(NULL, c); - else - g_signal_connect(G_OBJECT(c->web_view), "ready-to-show", - G_CALLBACK(show_web_view), c); + show_web_view(NULL, c); if (uri != NULL) { f = ensure_uri_scheme(uri); @@ -369,7 +349,10 @@ WebKitWebView * client_new_request(WebKitWebView *web_view, WebKitNavigationAction *navigation_action, gpointer data) { - return client_new(NULL, web_view, FALSE, FALSE); + switch_tab = FALSE; + WebKitWebView *new_web_view = client_new(NULL, web_view); + gtk_widget_grab_focus(GTK_WIDGET(new_web_view)); + return new_web_view; } void @@ -828,326 +811,11 @@ void reopen_tab(void) { if (num_closed == 0) return; - client_new(closed_tabs[num_closed - 1], NULL, TRUE, TRUE); + client_new(closed_tabs[num_closed - 1], NULL); num_closed--; closed_tabs = realloc(closed_tabs, num_closed * sizeof(closed_tabs[0])); if (!closed_tabs) allocfail(); } -gboolean -key_common(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - struct Client *c = (struct Client *)data; - gdouble now; - if (event->type == GDK_KEY_PRESS) { - guint mask = gtk_accelerator_get_default_mod_mask(); - int key = ((GdkEventKey *)event)->keyval; - if ((((GdkEventKey *)event)->state & mask) == - GDK_CONTROL_MASK) { - const char *uri = webkit_web_view_get_uri( - WEBKIT_WEB_VIEW(c->web_view)); - if (GDK_KEY_y == key) { - downloadmanager_show(); - return TRUE; - } else if (GDK_KEY_h == key) { - webkit_web_view_go_back( - WEBKIT_WEB_VIEW(c->web_view)); - return TRUE; - } else if (GDK_KEY_l == key) { - webkit_web_view_go_forward( - WEBKIT_WEB_VIEW(c->web_view)); - return TRUE; - } else if (GDK_KEY_s == key) { - gtk_widget_grab_focus(c->location); - return TRUE; - } else if (GDK_KEY_p == key) { - WebKitPrintOperation *operation = - webkit_print_operation_new( - WEBKIT_WEB_VIEW(c->web_view)); - GtkWidget *toplevel = - gtk_widget_get_toplevel(mw.win); - webkit_print_operation_run_dialog( - operation, GTK_WINDOW(toplevel)); - return TRUE; - } else if (GDK_KEY_g == key) { - isearch(c, 2); - gtk_widget_grab_focus(c->web_view); - if (uri) - gtk_entry_set_text( - GTK_ENTRY(c->location), uri); - webkit_web_view_run_javascript( - WEBKIT_WEB_VIEW(c->web_view), - "window.getSelection().removeAllRanges();" - "document.activeElement.blur();", - NULL, NULL, c); - gtk_widget_hide(c->isearch_box); - gtk_editable_set_position( - GTK_EDITABLE(c->location), -1); - gtk_editable_set_position( - GTK_EDITABLE(c->wsearch), -1); - return TRUE; - } else if (GDK_KEY_r == key) { - webkit_web_view_reload_bypass_cache( - WEBKIT_WEB_VIEW(c->web_view)); - return TRUE; - } else if (GDK_KEY_j == key) { - for (int i = 0; i <= cfg_scroll_lines - 1; - i++) { - event->key.keyval = GDK_KEY_Down; - gdk_event_put(event); - } - return TRUE; - } else if (GDK_KEY_k == key) { - for (int i = 0; i <= cfg_scroll_lines - 1; - i++) { - event->key.keyval = GDK_KEY_Up; - gdk_event_put(event); - } - return TRUE; - } else if (GDK_KEY_f == key) { - isearch_init(c, 1); - return TRUE; - } else if (GDK_KEY_q == key) { - client_destroy(NULL, c); - return TRUE; - } else if (GDK_KEY_1 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 0); - return TRUE; - } else if (GDK_KEY_2 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 1); - return TRUE; - } else if (GDK_KEY_3 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 2); - return TRUE; - } else if (GDK_KEY_4 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 3); - return TRUE; - } else if (GDK_KEY_5 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 4); - return TRUE; - } else if (GDK_KEY_6 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 5); - return TRUE; - } else if (GDK_KEY_7 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 6); - return TRUE; - } else if (GDK_KEY_8 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 7); - return TRUE; - } else if (GDK_KEY_9 == key) { - gtk_notebook_set_current_page( - GTK_NOTEBOOK(mw.notebook), 8); - return TRUE; - } else if (GDK_KEY_u == key) { - gtk_notebook_prev_page( - GTK_NOTEBOOK(mw.notebook)); - return TRUE; - } else if (GDK_KEY_m == key) { - gboolean muted = webkit_web_view_get_is_muted( - WEBKIT_WEB_VIEW(c->web_view)); - webkit_web_view_set_is_muted( - WEBKIT_WEB_VIEW(c->web_view), !muted); - changed_title(G_OBJECT(c->web_view), NULL, c); - return TRUE; - } else if (GDK_KEY_t == key) { - client_new(cfg_home_uri, NULL, TRUE, TRUE); - return TRUE; - } else if (GDK_KEY_bracketleft == key) { - reopen_tab(); - return TRUE; - } else if ((GDK_KEY_i == key) || (GDK_KEY_Tab == key)) { - gtk_notebook_next_page( - GTK_NOTEBOOK(mw.notebook)); - return TRUE; - } else if (GDK_KEY_d == key) { - gtk_widget_grab_focus(c->wsearch); - return TRUE; - } else if (GDK_KEY_equal == key) { - now = webkit_web_view_get_zoom_level( - WEBKIT_WEB_VIEW(c->web_view)); - webkit_web_view_set_zoom_level( - WEBKIT_WEB_VIEW(c->web_view), - now + 0.1); - return TRUE; - } else if (GDK_KEY_minus == key) { - now = webkit_web_view_get_zoom_level( - WEBKIT_WEB_VIEW(c->web_view)); - webkit_web_view_set_zoom_level( - WEBKIT_WEB_VIEW(c->web_view), - now - 0.1); - return TRUE; - } else if (GDK_KEY_0 == key) { - webkit_web_view_set_zoom_level( - WEBKIT_WEB_VIEW(c->web_view), 1); - return TRUE; - } - } else if ((((GdkEventKey *)event)->state & mask) == - (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) { - if (GDK_KEY_ISO_Left_Tab == key) { - gtk_notebook_prev_page( - GTK_NOTEBOOK(mw.notebook)); - return TRUE; - } else if (GDK_KEY_T == key) { - reopen_tab(); - return TRUE; - } - } - } - return FALSE; -} - -gboolean -isearch_counted_matches(GtkWidget *widget, guint matches, gpointer data) -{ - struct Client *c = (struct Client *)data; - char *text = malloc(12); - sprintf(text, "%d matches", matches); - gtk_label_set_text(GTK_LABEL(c->isearch_matches), text); - free(text); - return TRUE; -} - -gboolean -key_isearch(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - struct Client *c = (struct Client *)data; - if (key_common(widget, event, data)) return TRUE; - - if (event->type == GDK_KEY_PRESS) { - int key = ((GdkEventKey *)event)->keyval; - if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) { - int direction = (((GdkEventKey *)event)->state & - GDK_SHIFT_MASK) ? - -1 : - 1; - isearch(c, 0); - isearch(c, -1); - isearch(c, direction); - return TRUE; - } else if (GDK_KEY_Escape == key) { - isearch(c, 2); - gtk_widget_hide(c->isearch_box); - gtk_widget_grab_focus(c->web_view); - } - } - return FALSE; -} - -gboolean -key_wsearch(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - struct Client *c = (struct Client *)data; - if (key_common(widget, event, data)) return TRUE; - - if (event->type == GDK_KEY_PRESS) { - int key = ((GdkEventKey *)event)->keyval; - if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) { - const gchar *t = - gtk_entry_get_text(GTK_ENTRY(c->wsearch)); - int len = strlen(cfg_search_engine) + strlen(t); - gchar *f = malloc(len + 1); - if (!f) allocfail(); - - snprintf(f, len + 1, "%s%s", cfg_search_engine, t); - webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), - f); - g_free(f); - gtk_widget_grab_focus(c->web_view); - return TRUE; - } - } - return FALSE; -} - -gboolean -key_location(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - struct Client *c = (struct Client *)data; - const gchar *t; - if (key_common(widget, event, data)) return TRUE; - - if (event->type == GDK_KEY_PRESS) { - int key = ((GdkEventKey *)event)->keyval; - if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) { - gtk_widget_grab_focus(c->web_view); - t = gtk_entry_get_text(GTK_ENTRY(c->location)); - webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), - ensure_uri_scheme(t)); - return TRUE; - } else if (GDK_KEY_Escape == key) { - t = webkit_web_view_get_uri( - WEBKIT_WEB_VIEW(c->web_view)); - gtk_entry_set_text(GTK_ENTRY(c->location), - (t == NULL) ? "" : t); - return TRUE; - } - } - return FALSE; -} -gboolean -key_tablabel(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - GdkScrollDirection direction; - if (event->type == GDK_BUTTON_RELEASE) { - switch (((GdkEventButton *)event)->button) { - case 2: - client_destroy(NULL, data); - return TRUE; - } - } else if (event->type == GDK_SCROLL) { - gdk_event_get_scroll_direction(event, &direction); - switch (direction) { - case GDK_SCROLL_UP: - gtk_notebook_prev_page(GTK_NOTEBOOK(mw.notebook)); - break; - case GDK_SCROLL_DOWN: - gtk_notebook_next_page(GTK_NOTEBOOK(mw.notebook)); - break; - default: - break; - } - return TRUE; - } - return FALSE; -} - -gboolean -key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - struct Client *c = (struct Client *)data; - gdouble dx, dy; - gfloat z; - if (key_common(c->web_view, event, data)) return TRUE; - - if (event->type == GDK_KEY_PRESS) { - if (((GdkEventKey *)event)->keyval == GDK_KEY_Escape) { - webkit_web_view_stop_loading( - WEBKIT_WEB_VIEW(c->web_view)); - gtk_entry_set_progress_fraction(GTK_ENTRY(c->location), - 0); - } - } else if (event->type == GDK_SCROLL) { - event->scroll.delta_y *= cfg_scroll_lines; - if (((GdkEventScroll *)event)->state & GDK_CONTROL_MASK) { - gdk_event_get_scroll_deltas(event, &dx, &dy); - z = webkit_web_view_get_zoom_level( - WEBKIT_WEB_VIEW(c->web_view)); - z += -dy * 0.1; - z = dx != 0 ? 1 : z; - webkit_web_view_set_zoom_level( - WEBKIT_WEB_VIEW(c->web_view), z); - return TRUE; - } - } - return FALSE; -} void mainwindow_setup(void) @@ -1205,32 +873,6 @@ notebook_switch_page(GtkNotebook *nb, GtkWidget *p, guint idx, gpointer data) mainwindow_title(idx); } -gboolean -quit_if_nothing_active(void) -{ - if (clients == 0) { - if (downloads == 0) { - gtk_main_quit(); - return TRUE; - } else { - downloadmanager_show(); - } - } - return FALSE; -} -gboolean -remote_msg(GIOChannel *channel, GIOCondition condition, gpointer data) -{ - gchar *uri = NULL; - g_io_channel_read_line(channel, &uri, NULL, NULL, NULL); - if (uri) { - g_strstrip(uri); - client_new(uri, NULL, TRUE, TRUE); - g_free(uri); - } - return TRUE; -} - void show_web_view(WebKitWebView *web_view, gpointer data) { @@ -1242,13 +884,9 @@ show_web_view(WebKitWebView *web_view, gpointer data) gtk_notebook_get_nth_page(GTK_NOTEBOOK(mw.notebook), idx))); gtk_widget_hide(c->isearch_box); - if (c->focus_new_tab) { - if (idx != -1) - gtk_notebook_set_current_page(GTK_NOTEBOOK(mw.notebook), - idx); - - gtk_widget_grab_focus(c->web_view); - } + if (idx != -1 && switch_tab) + gtk_notebook_set_current_page(GTK_NOTEBOOK(mw.notebook), idx); + gtk_widget_grab_focus(c->web_view); } void @@ -1338,10 +976,9 @@ main(int argc, char **argv) mainwindow_setup(); if (optind >= argc) { - client_new(cfg_home_uri, NULL, TRUE, TRUE); + client_new(cfg_home_uri, NULL); } else { - for (i = optind; i < argc; i++) - client_new(argv[i], NULL, TRUE, TRUE); + for (i = optind; i < argc; i++) client_new(argv[i], NULL); } if (cfg.noncooperative_instances || cfg.cooperative_alone) { diff --git a/chorizo.h b/chorizo.h new file mode 100644 index 0000000..d9e860b --- /dev/null +++ b/chorizo.h @@ -0,0 +1,117 @@ +typedef struct MainWindow MainWindow; +struct MainWindow { + GtkWidget *notebook; + GtkWidget *win; +}; +extern struct MainWindow mw; +typedef struct Configuration Configuration; +struct Configuration { + gboolean cooperative_alone; + gboolean noncooperative_instances; + gboolean private; + gboolean verbose; +}; +extern struct Configuration cfg; +extern gboolean switch_tab; +extern gboolean switch_tab; +extern gint clients; +extern int cooperative_pipe_fp; +extern gchar *fifopath; +extern char **closed_tabs; +extern size_t num_closed; +gboolean isearch_counted_matches(GtkWidget *widget, guint matches, + gpointer data); +gboolean quit_if_nothing_active(void); +gboolean remote_msg(GIOChannel *channel, GIOCondition condition, gpointer data); +void allocfail(void); +void client_destroy(GtkWidget *widget, gpointer data); +typedef struct Client Client; +void set_uri(const char *uri, struct Client *c); +WebKitWebView *client_new(const gchar *uri, WebKitWebView *related_wv); +WebKitWebView *client_new_request(WebKitWebView *web_view, + WebKitNavigationAction *navigation_action, + gpointer data); +void mkdirp(const char *dir, mode_t mode); +void cooperation_setup(void); +void changed_load_progress(GObject *obj, GParamSpec *pspec, gpointer data); +void changed_favicon(GObject *obj, GParamSpec *pspec, gpointer data); +void changed_title(GObject *obj, GParamSpec *pspec, gpointer data); +void changed_uri(GObject *obj, GParamSpec *pspec, gpointer data); +gboolean crashed_web_view(WebKitWebView *web_view, gpointer data); +gboolean decide_policy(WebKitWebView *web_view, WebKitPolicyDecision *decision, + WebKitPolicyDecisionType type, gpointer data); +gchar *ensure_uri_scheme(const gchar *t); +void grab_feeds_finished(GObject *object, GAsyncResult *result, gpointer data); +void hover_web_view(WebKitWebView *web_view, WebKitHitTestResult *ht, + guint modifiers, gpointer data); +void icon_location(GtkEntry *entry, GtkEntryIconPosition icon_pos, + GdkEvent *event, gpointer data); +void init_default_web_context(void); +void isearch(gpointer data, gint direction); +void isearch_init(struct Client *c, int direction); +void reopen_tab(void); +void mainwindow_setup(void); +void mainwindow_title(gint idx); +void notebook_switch_page(GtkNotebook *nb, GtkWidget *p, guint idx, + gpointer data); +void show_web_view(WebKitWebView *web_view, gpointer data); +void trust_user_certs(WebKitWebContext *wc); +void version(void); +gboolean download_handle(WebKitDownload *, gchar *, gpointer); +gboolean download_handle(WebKitDownload *download, gchar *suggested_filename, + gpointer data); +void download_click(GtkToolButton *, gpointer); +void download_click(GtkToolButton *tb, gpointer data); +void download_cancel(GtkMenuItem *, gpointer); +void download_cancel(GtkMenuItem *tb, gpointer data); +gboolean downloadmanager_delete(GtkWidget *, gpointer); +gboolean downloadmanager_delete(GtkWidget *obj, gpointer data); +extern gint downloads; +gboolean key_downloadmanager(GtkWidget *widget, GdkEvent *event, gpointer data); +void changed_download_progress(GObject *obj, GParamSpec *pspec, gpointer data); +void download_finished(WebKitDownload *download, gpointer data); +void download_start(WebKitWebView *web_view, WebKitDownload *download, + gpointer data); +typedef struct DownloadItem DownloadItem; +const char *download_get_path(struct DownloadItem *payload); +void download_hide(GtkMenuItem *tb, gpointer data); +void download_delete(GtkMenuItem *tb, gpointer data); +void download_copy_url(GtkMenuItem *tb, gpointer data); +void download_copy_path(GtkMenuItem *tb, gpointer data); +void download_xdg_open(GtkMenuItem *tb, gpointer data); +void downloadmanager_setup(void); +void downloadmanager_show(void); +struct Client { + GtkWidget *location; + GtkWidget *wsearch; + GtkWidget *isearch; + GtkWidget *isearch_box; + GtkWidget *isearch_matches; + GtkWidget *tabicon; + GtkWidget *tablabel; + GtkWidget *vbox; + GtkWidget *web_view; + WebKitSettings *settings; + gchar *external_handler_uri; + gchar *feed_html; + gchar *hover_uri; +}; +struct DownloadItem { + GtkToolButton *tb; + WebKitDownload *download; +}; +gboolean key_common(GtkWidget *widget, GdkEvent *event, gpointer data); +void reorder_current_tab(int target); +gboolean key_isearch(GtkWidget *widget, GdkEvent *event, gpointer data); +gboolean key_wsearch(GtkWidget *widget, GdkEvent *event, gpointer data); +gboolean key_location(GtkWidget *widget, GdkEvent *event, gpointer data); +gboolean key_tablabel(GtkWidget *widget, GdkEvent *event, gpointer data); +gboolean key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data); +#define INTERFACE 0 +#define EXPORT_INTERFACE 0 +#define LOCAL_INTERFACE 0 +#define EXPORT +#define LOCAL static +#define PUBLIC +#define PRIVATE +#define PROTECTED diff --git a/config.h b/config.h index 605f728..15c30f9 100644 --- a/config.h +++ b/config.h @@ -1,30 +1,27 @@ -#ifndef CONFIG_H -#define CONFIG_H - #define VERSION "1.1.0" + // Should JavaScript be enabled by default -gboolean cfg_js_default = TRUE; +static gboolean cfg_js_default = TRUE; // Cookie policy -WebKitCookieAcceptPolicy cfg_cookie_policy = WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS; +static WebKitCookieAcceptPolicy cfg_cookie_policy = + WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS; // Default URI -gchar *cfg_home_uri = NULL; +static gchar *cfg_home_uri = NULL; // Number of lines to scroll at a time -int cfg_scroll_lines = 3; +static int cfg_scroll_lines = 3; // Search engine -gchar *cfg_search_engine = "https://searx.be/search?q="; +static gchar *cfg_search_engine = "https://searx.be/search?q="; // Max number of closed tabs -size_t cfg_max_tabs_closed = 16; +static size_t cfg_max_tabs_closed = 16; // Tab width in chars -int cfg_tab_width = 15; +static int cfg_tab_width = 15; // isearch options -WebKitFindOptions cfg_isearch_options = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | - WEBKIT_FIND_OPTIONS_WRAP_AROUND; - -#endif +static WebKitFindOptions cfg_isearch_options = + WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | WEBKIT_FIND_OPTIONS_WRAP_AROUND; diff --git a/downloads.c b/downloads.c index 9f8c73d..45f63fb 100644 --- a/downloads.c +++ b/downloads.c @@ -1,6 +1,6 @@ #include -#include "downloads.h" +#include "chorizo.h" gboolean download_handle(WebKitDownload *, gchar *, gpointer); void download_click(GtkToolButton *, gpointer); @@ -15,11 +15,6 @@ struct DownloadManager { gint downloads = 0; -struct DownloadItem { - GtkToolButton *tb; - WebKitDownload *download; -}; - gboolean key_downloadmanager(GtkWidget *widget, GdkEvent *event, gpointer data) { diff --git a/downloads.h b/downloads.h deleted file mode 100644 index a12afd5..0000000 --- a/downloads.h +++ /dev/null @@ -1,5 +0,0 @@ -extern int downloads; -gboolean quit_if_nothing_active(void); -void download_start(WebKitWebView *, WebKitDownload *, gpointer); -void downloadmanager_setup(void); -void downloadmanager_show(void); diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..ad06431 --- /dev/null +++ b/globals.h @@ -0,0 +1,34 @@ +struct MainWindow { + GtkWidget *notebook; + GtkWidget *win; +}; + +struct Configuration { + gboolean cooperative_alone; + gboolean noncooperative_instances; + gboolean private; + gboolean verbose; +}; + +struct Client { + GtkWidget *location; + GtkWidget *wsearch; + GtkWidget *isearch; + GtkWidget *isearch_box; + GtkWidget *isearch_matches; + GtkWidget *tabicon; + GtkWidget *tablabel; + GtkWidget *vbox; + GtkWidget *web_view; + WebKitSettings *settings; + gchar *external_handler_uri; + gchar *feed_html; + gchar *hover_uri; +}; + +struct DownloadItem { + GtkToolButton *tb; + WebKitDownload *download; +}; + +extern gboolean switch_tab; diff --git a/shortcuts.c b/shortcuts.c new file mode 100644 index 0000000..382e4c0 --- /dev/null +++ b/shortcuts.c @@ -0,0 +1,348 @@ +#include + +#include "config.h" +#include "chorizo.h" + +gboolean +key_common(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + struct Client *c = (struct Client *)data; + gdouble now; + if (event->type == GDK_KEY_PRESS) { + guint mask = gtk_accelerator_get_default_mod_mask(); + int key = ((GdkEventKey *)event)->keyval; + if ((((GdkEventKey *)event)->state & mask) == + GDK_CONTROL_MASK) { + const char *uri = webkit_web_view_get_uri( + WEBKIT_WEB_VIEW(c->web_view)); + if (GDK_KEY_y == key) { + downloadmanager_show(); + return TRUE; + } else if (GDK_KEY_h == key) { + webkit_web_view_go_back( + WEBKIT_WEB_VIEW(c->web_view)); + return TRUE; + } else if (GDK_KEY_l == key) { + webkit_web_view_go_forward( + WEBKIT_WEB_VIEW(c->web_view)); + return TRUE; + } else if (GDK_KEY_s == key) { + gtk_widget_grab_focus(c->location); + return TRUE; + } else if (GDK_KEY_p == key) { + WebKitPrintOperation *operation = + webkit_print_operation_new( + WEBKIT_WEB_VIEW(c->web_view)); + GtkWidget *toplevel = + gtk_widget_get_toplevel(mw.win); + webkit_print_operation_run_dialog( + operation, GTK_WINDOW(toplevel)); + return TRUE; + } else if (GDK_KEY_g == key) { + isearch(c, 2); + gtk_widget_grab_focus(c->web_view); + if (uri) + gtk_entry_set_text( + GTK_ENTRY(c->location), uri); + webkit_web_view_run_javascript( + WEBKIT_WEB_VIEW(c->web_view), + "window.getSelection().removeAllRanges();" + "document.activeElement.blur();", + NULL, NULL, c); + gtk_widget_hide(c->isearch_box); + gtk_editable_set_position( + GTK_EDITABLE(c->location), -1); + gtk_editable_set_position( + GTK_EDITABLE(c->wsearch), -1); + return TRUE; + } else if (GDK_KEY_r == key) { + webkit_web_view_reload_bypass_cache( + WEBKIT_WEB_VIEW(c->web_view)); + return TRUE; + } else if (GDK_KEY_j == key) { + for (int i = 0; i <= cfg_scroll_lines - 1; + i++) { + event->key.keyval = GDK_KEY_Down; + gdk_event_put(event); + } + return TRUE; + } else if (GDK_KEY_k == key) { + for (int i = 0; i <= cfg_scroll_lines - 1; + i++) { + event->key.keyval = GDK_KEY_Up; + gdk_event_put(event); + } + return TRUE; + } else if (GDK_KEY_f == key) { + isearch_init(c, 1); + return TRUE; + } else if (GDK_KEY_q == key) { + client_destroy(NULL, c); + return TRUE; + } else if (GDK_KEY_1 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 0); + return TRUE; + } else if (GDK_KEY_2 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 1); + return TRUE; + } else if (GDK_KEY_3 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 2); + return TRUE; + } else if (GDK_KEY_4 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 3); + return TRUE; + } else if (GDK_KEY_5 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 4); + return TRUE; + } else if (GDK_KEY_6 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 5); + return TRUE; + } else if (GDK_KEY_7 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 6); + return TRUE; + } else if (GDK_KEY_8 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 7); + return TRUE; + } else if (GDK_KEY_9 == key) { + gtk_notebook_set_current_page( + GTK_NOTEBOOK(mw.notebook), 8); + return TRUE; + } else if (GDK_KEY_u == key) { + gtk_notebook_prev_page( + GTK_NOTEBOOK(mw.notebook)); + return TRUE; + } else if (GDK_KEY_m == key) { + gboolean muted = webkit_web_view_get_is_muted( + WEBKIT_WEB_VIEW(c->web_view)); + webkit_web_view_set_is_muted( + WEBKIT_WEB_VIEW(c->web_view), !muted); + changed_title(G_OBJECT(c->web_view), NULL, c); + return TRUE; + } else if (GDK_KEY_t == key) { + switch_tab = TRUE; + client_new(cfg_home_uri, NULL); + return TRUE; + } else if (GDK_KEY_bracketleft == key) { + reopen_tab(); + return TRUE; + } else if ((GDK_KEY_i == key) || (GDK_KEY_Tab == key)) { + gtk_notebook_next_page( + GTK_NOTEBOOK(mw.notebook)); + return TRUE; + } else if (GDK_KEY_d == key) { + gtk_widget_grab_focus(c->wsearch); + return TRUE; + } else if (GDK_KEY_equal == key) { + now = webkit_web_view_get_zoom_level( + WEBKIT_WEB_VIEW(c->web_view)); + webkit_web_view_set_zoom_level( + WEBKIT_WEB_VIEW(c->web_view), + now + 0.1); + return TRUE; + } else if (GDK_KEY_minus == key) { + now = webkit_web_view_get_zoom_level( + WEBKIT_WEB_VIEW(c->web_view)); + webkit_web_view_set_zoom_level( + WEBKIT_WEB_VIEW(c->web_view), + now - 0.1); + return TRUE; + } else if (GDK_KEY_0 == key) { + webkit_web_view_set_zoom_level( + WEBKIT_WEB_VIEW(c->web_view), 1); + return TRUE; + } + } else if ((((GdkEventKey *)event)->state & mask) == + (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) { + if (GDK_KEY_ISO_Left_Tab == key) { + gtk_notebook_prev_page( + GTK_NOTEBOOK(mw.notebook)); + return TRUE; + } else if (GDK_KEY_T == key) { + reopen_tab(); + return TRUE; + } else if (GDK_KEY_exclam == key) { + reorder_current_tab(1); + return TRUE; + } else if (GDK_KEY_at == key) { + reorder_current_tab(2); + return TRUE; + } else if (GDK_KEY_numbersign == key) { + reorder_current_tab(3); + return TRUE; + } else if (GDK_KEY_dollar == key) { + reorder_current_tab(4); + return TRUE; + } else if (GDK_KEY_percent == key) { + reorder_current_tab(5); + return TRUE; + } else if (GDK_KEY_asciicircum == key) { + reorder_current_tab(6); + return TRUE; + } else if (GDK_KEY_ampersand == key) { + reorder_current_tab(7); + return TRUE; + } else if (GDK_KEY_asterisk == key) { + reorder_current_tab(8); + return TRUE; + } else if (GDK_KEY_parenleft == key) { + reorder_current_tab(9); + return TRUE; + } + } + } + return FALSE; +} + +void +reorder_current_tab(int target) +{ + gtk_notebook_reorder_child( + GTK_NOTEBOOK(mw.notebook), + gtk_notebook_get_nth_page(GTK_NOTEBOOK(mw.notebook), + gtk_notebook_get_current_page( + GTK_NOTEBOOK(mw.notebook))), + target - 1); +} + +gboolean +key_isearch(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + struct Client *c = (struct Client *)data; + if (key_common(widget, event, data)) return TRUE; + + if (event->type == GDK_KEY_PRESS) { + int key = ((GdkEventKey *)event)->keyval; + if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) { + int direction = (((GdkEventKey *)event)->state & + GDK_SHIFT_MASK) ? + -1 : + 1; + isearch(c, 0); + isearch(c, -1); + isearch(c, direction); + return TRUE; + } else if (GDK_KEY_Escape == key) { + isearch(c, 2); + gtk_widget_hide(c->isearch_box); + gtk_widget_grab_focus(c->web_view); + } + } + return FALSE; +} + +gboolean +key_wsearch(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + struct Client *c = (struct Client *)data; + if (key_common(widget, event, data)) return TRUE; + + if (event->type == GDK_KEY_PRESS) { + int key = ((GdkEventKey *)event)->keyval; + if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) { + const gchar *t = + gtk_entry_get_text(GTK_ENTRY(c->wsearch)); + int len = strlen(cfg_search_engine) + strlen(t); + gchar *f = malloc(len + 1); + if (!f) allocfail(); + + snprintf(f, len + 1, "%s%s", cfg_search_engine, t); + webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), + f); + g_free(f); + gtk_widget_grab_focus(c->web_view); + return TRUE; + } + } + return FALSE; +} + +gboolean +key_location(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + struct Client *c = (struct Client *)data; + const gchar *t; + if (key_common(widget, event, data)) return TRUE; + + if (event->type == GDK_KEY_PRESS) { + int key = ((GdkEventKey *)event)->keyval; + if ((GDK_KEY_KP_Enter == key) || (GDK_KEY_Return == key)) { + gtk_widget_grab_focus(c->web_view); + t = gtk_entry_get_text(GTK_ENTRY(c->location)); + webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), + ensure_uri_scheme(t)); + return TRUE; + } else if (GDK_KEY_Escape == key) { + t = webkit_web_view_get_uri( + WEBKIT_WEB_VIEW(c->web_view)); + gtk_entry_set_text(GTK_ENTRY(c->location), + (t == NULL) ? "" : t); + return TRUE; + } + } + return FALSE; +} +gboolean +key_tablabel(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + GdkScrollDirection direction; + if (event->type == GDK_BUTTON_RELEASE) { + switch (((GdkEventButton *)event)->button) { + case 2: + client_destroy(NULL, data); + return TRUE; + } + } else if (event->type == GDK_SCROLL) { + gdk_event_get_scroll_direction(event, &direction); + switch (direction) { + case GDK_SCROLL_UP: + gtk_notebook_prev_page(GTK_NOTEBOOK(mw.notebook)); + break; + case GDK_SCROLL_DOWN: + gtk_notebook_next_page(GTK_NOTEBOOK(mw.notebook)); + break; + default: + break; + } + return TRUE; + } + return FALSE; +} + +gboolean +key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + struct Client *c = (struct Client *)data; + gdouble dx, dy; + gfloat z; + if (key_common(c->web_view, event, data)) return TRUE; + + if (event->type == GDK_KEY_PRESS) { + if (((GdkEventKey *)event)->keyval == GDK_KEY_Escape) { + webkit_web_view_stop_loading( + WEBKIT_WEB_VIEW(c->web_view)); + gtk_entry_set_progress_fraction(GTK_ENTRY(c->location), + 0); + } + } else if (event->type == GDK_SCROLL) { + event->scroll.delta_y *= cfg_scroll_lines; + if (((GdkEventScroll *)event)->state & GDK_CONTROL_MASK) { + gdk_event_get_scroll_deltas(event, &dx, &dy); + z = webkit_web_view_get_zoom_level( + WEBKIT_WEB_VIEW(c->web_view)); + z += -dy * 0.1; + z = dx != 0 ? 1 : z; + webkit_web_view_set_zoom_level( + WEBKIT_WEB_VIEW(c->web_view), z); + return TRUE; + } + } + return FALSE; +} -- 2.39.2