diff options
Diffstat (limited to 'src/tab-chrome.c')
-rw-r--r-- | src/tab-chrome.c | 302 |
1 files changed, 4 insertions, 298 deletions
diff --git a/src/tab-chrome.c b/src/tab-chrome.c index 8164846..285b42f 100644 --- a/src/tab-chrome.c +++ b/src/tab-chrome.c @@ -27,260 +27,10 @@ #include "tab-chrome.h" #include "tab.h" +#include "back-forward-button-box.h" #include "find-toolbar.h" static void -back_clicked_cb(GtkButton G_GNUC_UNUSED *toolbutton, MqTabChrome *chrome) -{ - webkit_web_view_go_back(WEBKIT_WEB_VIEW(chrome->web_view)); -} - -static void -forward_clicked_cb(GtkButton G_GNUC_UNUSED *toolbutton, MqTabChrome *chrome) -{ - webkit_web_view_go_forward(WEBKIT_WEB_VIEW(chrome->web_view)); -} - -static GtkWidget * -back_forward_list_item_new(WebKitBackForwardListItem *list_item, - gint type) -{ - GtkWidget *label; - GtkWidget *icon_stack; - GtkWidget *icon; - GtkWidget *box; - - label = gtk_label_new(webkit_back_forward_list_item_get_title( - list_item)); - gtk_widget_set_halign(label, GTK_ALIGN_START); - - icon_stack = gtk_stack_new(); - switch (type) { - case 0: - icon = gtk_radio_button_new(NULL); - gtk_stack_add_named(GTK_STACK(icon_stack), icon, - "current"); - gtk_widget_set_can_focus(icon, FALSE); - gtk_stack_add_named(GTK_STACK(icon_stack), - gtk_image_new_from_icon_name("go-previous", - GTK_ICON_SIZE_BUTTON), "back"); - break; - case -1: - gtk_stack_add_named(GTK_STACK(icon_stack), - gtk_image_new_from_icon_name("go-previous", - GTK_ICON_SIZE_BUTTON), "back"); - gtk_stack_add_named(GTK_STACK(icon_stack), - gtk_radio_button_new(NULL), "current"); - break; - case 1: - gtk_stack_add_named(GTK_STACK(icon_stack), - gtk_image_new_from_icon_name("go-next", - GTK_ICON_SIZE_BUTTON), "forward"); - gtk_stack_add_named(GTK_STACK(icon_stack), - gtk_radio_button_new(NULL), "current"); - break; - } - - box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start(GTK_BOX(box), icon_stack, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0); - gtk_widget_set_tooltip_text(box, - webkit_back_forward_list_item_get_uri(list_item)); - - return box; -} - -static void -back_forward_list_box_row_activated_cb(GtkListBox G_GNUC_UNUSED *box, - GtkListBoxRow *row, MqTabChrome *chrome) -{ - webkit_web_view_go_to_back_forward_list_item( - WEBKIT_WEB_VIEW(chrome->web_view), - webkit_back_forward_list_get_nth_item( - webkit_web_view_get_back_forward_list( - WEBKIT_WEB_VIEW(chrome->web_view)), - gtk_list_box_row_get_index(row) - chrome->back_items)); - - gtk_widget_hide(chrome->back_forward_popover); -} - -static void -back_forward_toggle_button_toggled_cb(GtkToggleButton *toggle_button, - GtkStack *stack) -{ - /* Use gtk_widget_show() and gtk_widget_hide() instead of - * gtk_stack_set_visible_child() so that the stack fits the size of only - * the visible child. */ - gtk_widget_show_all(gtk_stack_get_child_by_name(stack, - gtk_toggle_button_get_active(toggle_button) ? - "text" : "list")); - gtk_widget_hide(gtk_stack_get_child_by_name(stack, - gtk_toggle_button_get_active(toggle_button) ? - "list" : "text")); -} - -static gboolean -back_forward_box_button_press_cb(GtkWidget *widget, - GdkEventButton G_GNUC_UNUSED *event, MqTabChrome *chrome) -{ - WebKitBackForwardList *back_forward_list; - GtkWidget *list_box; - GtkWidget *text_view; - GtkTextBuffer *text_buffer; - GList *list_item; - GtkTextIter text_iter; - gchar *str; - GtkTextTag *text_tag; - GtkWidget *list_scrolled_window; - GtkWidget *text_scrolled_window; - GtkWidget *stack; - GtkWidget *toggle_button; - GtkWidget *box; - - /* Get the back/forward list for the Web view. */ - back_forward_list = webkit_web_view_get_back_forward_list( - WEBKIT_WEB_VIEW(chrome->web_view)); - - /* Set up the list box. */ - list_box = gtk_list_box_new(); - gtk_list_box_set_selection_mode(GTK_LIST_BOX(list_box), - GTK_SELECTION_BROWSE); - gtk_list_box_set_activate_on_single_click(GTK_LIST_BOX(list_box), TRUE); - g_signal_connect(list_box, "row-activated", - G_CALLBACK(back_forward_list_box_row_activated_cb), chrome); - - /* Set up the text view. */ - text_view = gtk_text_view_new(); - text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), FALSE); - - /* Insert forward list items. */ - /* The forward list is backwards, so we need to prepend each item to our - * list box and text buffer. */ - list_item = webkit_back_forward_list_get_forward_list( - back_forward_list); - for (; list_item; list_item = list_item->next) { - gtk_list_box_prepend(GTK_LIST_BOX(list_box), - back_forward_list_item_new(list_item->data, 1)); - gtk_text_buffer_get_start_iter(text_buffer, &text_iter); - str = g_strdup_printf("\n%s", - webkit_back_forward_list_item_get_uri(list_item->data)); - gtk_text_buffer_insert(text_buffer, &text_iter, str, -1); - g_free(str); - } - - /* Insert the current item. */ - gtk_list_box_prepend(GTK_LIST_BOX(list_box), back_forward_list_item_new( - webkit_back_forward_list_get_current_item( - back_forward_list), 0)); - gtk_list_box_select_row(GTK_LIST_BOX(list_box), - gtk_list_box_get_row_at_index(GTK_LIST_BOX(list_box), 0)); - gtk_text_buffer_get_start_iter(text_buffer, &text_iter); - text_tag = gtk_text_buffer_create_tag(text_buffer, NULL, "weight", - PANGO_WEIGHT_BOLD, NULL); - gtk_text_buffer_insert_with_tags(text_buffer, &text_iter, - webkit_back_forward_list_item_get_uri( - webkit_back_forward_list_get_current_item( - back_forward_list)), -1, text_tag, NULL); - - /* Insert back list items. */ - list_item = webkit_back_forward_list_get_back_list( - back_forward_list); - chrome->back_items = 0; - for (; list_item; list_item = list_item->next) { - gtk_list_box_prepend(GTK_LIST_BOX(list_box), - back_forward_list_item_new(list_item->data, -1)); - gtk_text_buffer_get_start_iter(text_buffer, &text_iter); - str = g_strdup_printf("%s\n", - webkit_back_forward_list_item_get_uri(list_item->data)); - gtk_text_buffer_insert(text_buffer, &text_iter, str, -1); - g_free(str); - ++chrome->back_items; - } - - /* - * The following GtkScrolledWindow widgets have hardcoded minimum sizes, - * because there seems to be (in GTK+ versions before 3.22) no way to - * set the natural size of GtkScrolledWindow and its GtkViewport. - * - * I tried: - * - * - Setting size requests of the sizes of child widgets plus - * scrollbars (commit 2205669) - * - Putting GtkScrolledWindow widgets in stacks with non-scrolled - * versions of children, to allocate more area for the - * GtkScrolledWindow widgets to fill (commits 922cdef and 90686fa) - * - Setting policies to disable scrollbars upon GtkScrolledWindow - * instantiation, then enabling scrollbars on the GtkScrolledWindow - * "size-allocate" signal (commits c534c7e and 42ca783) - * - * Attempts to match the size of a GtkScrolledWindow's GtkViewport to - * its child's size don't allow the GtkScrolledWindow and GtkViewport to - * shrink when necessary to fit within the window. Therefore, such - * methods are equivalent to simply not using GtkScrolledWindow at all. - * And there appears to be no easy way to calculate the available size - * (the size of the GtkWindow minus all of the surrounding widgets) to - * manually manage a GtkViewport's size. - * - * GtkScrolledWindow or GtkViewport ignores the child's preferred - * (minimum and natural) sizes and apparently just sets a hardcoded size - * of about 64x64 px. I considered subclassing GtkScrolledWindow or - * GtkViewport, but I'm not sure where the hardcoded size is set. - * - * The functions gtk_scrolled_window_set_propagate_natural_width() and - * gtk_scrolled_window_set_propagate_natural_height() were introduced in - * GTK+ 3.22 and probably do what I want. However, I want to maintain - * compatibility with at least GTK+ 3.12 or 3.14. - */ - - /* Set up the list scrolled window. */ - list_scrolled_window = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_min_content_width( - GTK_SCROLLED_WINDOW(list_scrolled_window), 400); - gtk_scrolled_window_set_min_content_height( - GTK_SCROLLED_WINDOW(list_scrolled_window), 200); - gtk_container_add(GTK_CONTAINER(list_scrolled_window), list_box); - - /* Set up the text scrolled window. */ - text_scrolled_window = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_min_content_width( - GTK_SCROLLED_WINDOW(text_scrolled_window), 400); - gtk_scrolled_window_set_min_content_height( - GTK_SCROLLED_WINDOW(text_scrolled_window), 200); - gtk_container_add(GTK_CONTAINER(text_scrolled_window), text_view); - - /* Set up the stack. */ - stack = gtk_stack_new(); - gtk_stack_add_named(GTK_STACK(stack), list_scrolled_window, "list"); - gtk_stack_add_named(GTK_STACK(stack), text_scrolled_window, "text"); - - /* Set up the toggle button. */ - toggle_button = gtk_toggle_button_new(); - gtk_button_set_image(GTK_BUTTON(toggle_button), - gtk_image_new_from_icon_name("edit-select-all", - GTK_ICON_SIZE_SMALL_TOOLBAR)); - gtk_widget_set_halign(toggle_button, GTK_ALIGN_START); - g_signal_connect(toggle_button, "toggled", - G_CALLBACK(back_forward_toggle_button_toggled_cb), - GTK_STACK(stack)); - - /* Set up the containing box. */ - box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_box_pack_start(GTK_BOX(box), toggle_button, TRUE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(box), stack, TRUE, FALSE, 0); - - /* Set up the popover. */ - chrome->back_forward_popover = gtk_popover_new(widget); - gtk_container_add(GTK_CONTAINER(chrome->back_forward_popover), box); - - /* NB: gtk_popover_popup() is new in GTK+ 3.22. */ - gtk_widget_show_all(chrome->back_forward_popover); - gtk_widget_hide(text_view); - - return FALSE; -} - -static void stop_reload_clicked_cb(GtkToolButton G_GNUC_UNUSED *toolbutton, MqTabChrome *chrome) { @@ -599,20 +349,6 @@ loading_cb(MqWebView *web_view, GParamSpec G_GNUC_UNUSED *paramspec, gtk_widget_show_all(GTK_WIDGET(chrome->stop_reload_button)); } -static void -back_forward_list_changed_cb( - WebKitBackForwardList G_GNUC_UNUSED *back_forward_list, - WebKitBackForwardListItem G_GNUC_UNUSED *item_added, - gpointer G_GNUC_UNUSED items_removed, MqTabChrome *chrome) -{ - gtk_widget_set_sensitive(GTK_WIDGET(chrome->back_button), - webkit_web_view_can_go_back( - WEBKIT_WEB_VIEW(chrome->web_view))); - gtk_widget_set_sensitive(GTK_WIDGET(chrome->forward_button), - webkit_web_view_can_go_forward( - WEBKIT_WEB_VIEW(chrome->web_view))); -} - static GtkWidget * navigation_toolbar_new(MqTabChrome *chrome, const gchar *uri) { @@ -624,37 +360,10 @@ navigation_toolbar_new(MqTabChrome *chrome, const gchar *uri) navigation_toolbar = GTK_TOOLBAR(gtk_toolbar_new()); + /* Back/forward button box */ back_forward_tool_item = gtk_tool_item_new(); - chrome->back_forward_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - - /* Back button */ - chrome->back_button = gtk_button_new_from_icon_name("go-previous", - GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_widget_set_tooltip_text(GTK_WIDGET(chrome->back_button), - "Go back one page"); - g_signal_connect(chrome->back_button, "clicked", - G_CALLBACK(back_clicked_cb), chrome); - gtk_box_pack_start(GTK_BOX(chrome->back_forward_box), - chrome->back_button, FALSE, FALSE, 0); - - /* Forward button */ - chrome->forward_button = gtk_button_new_from_icon_name("go-next", - GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_widget_set_tooltip_text(GTK_WIDGET(chrome->forward_button), - "Go forward one page"); - g_signal_connect(chrome->forward_button, "clicked", - G_CALLBACK(forward_clicked_cb), chrome); - gtk_box_pack_start(GTK_BOX(chrome->back_forward_box), - chrome->forward_button, FALSE, FALSE, 0); - - gtk_style_context_add_class( - gtk_widget_get_style_context(chrome->back_forward_box), - "linked"); - back_forward_event_box = gtk_event_box_new(); - g_signal_connect(back_forward_event_box, "button-press-event", - G_CALLBACK(back_forward_box_button_press_cb), chrome); - gtk_container_add(GTK_CONTAINER(back_forward_event_box), - chrome->back_forward_box); + back_forward_event_box = mq_back_forward_button_box_new(chrome->tab, + chrome->web_view); gtk_container_add(GTK_CONTAINER(back_forward_tool_item), back_forward_event_box); gtk_toolbar_insert(navigation_toolbar, back_forward_tool_item, -1); @@ -733,9 +442,6 @@ navigation_toolbar_new(MqTabChrome *chrome, const gchar *uri) G_CALLBACK(uri_cb), chrome); g_signal_connect(chrome->web_view, "notify::is-loading", G_CALLBACK(loading_cb), chrome); - g_signal_connect(webkit_web_view_get_back_forward_list( - WEBKIT_WEB_VIEW(chrome->web_view)), - "changed", G_CALLBACK(back_forward_list_changed_cb), chrome); return GTK_WIDGET(navigation_toolbar); } |