[epiphany] Use GAction for back/forward buttons
- From: Iulian Radu <iulianradu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] Use GAction for back/forward buttons
- Date: Thu, 28 Jul 2016 12:29:22 +0000 (UTC)
commit 70ce7dbc0ca6aa581ea709e6962f611d783bc534
Author: Iulian Radu <iulian radu67 gmail com>
Date: Mon Jun 27 13:47:59 2016 +0300
Use GAction for back/forward buttons
src/Makefile.am | 3 -
src/ephy-lockdown.c | 21 +-
src/ephy-navigation-history-action.c | 553 ----------------------------------
src/ephy-navigation-history-action.h | 61 ----
src/ephy-toolbar.c | 476 +++++++++++++++++++++++++++--
src/ephy-window.c | 168 +++++------
src/window-commands.c | 78 +++++
src/window-commands.h | 6 +
8 files changed, 621 insertions(+), 745 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 551c326..ce61ce2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,7 +20,6 @@ TYPES_H_FILES = \
ephy-session.h \
ephy-shell.h \
ephy-window.h \
- ephy-navigation-history-action.h \
ephy-title-box.h \
$(NULL)
@@ -51,8 +50,6 @@ libephymain_la_SOURCES = \
ephy-location-controller.h \
ephy-lockdown.c \
ephy-lockdown.h \
- ephy-navigation-history-action.c \
- ephy-navigation-history-action.h \
ephy-notebook.c \
ephy-notebook.h \
ephy-private.h \
diff --git a/src/ephy-lockdown.c b/src/ephy-lockdown.c
index 9bc44fa..e30cf7c 100644
--- a/src/ephy-lockdown.c
+++ b/src/ephy-lockdown.c
@@ -123,11 +123,9 @@ static const BindAction popup_actions[] = {
{ EPHY_PREFS_LOCKDOWN_FULLSCREEN, "OpenLinkInNewWindow", "sensitive" }
};
-static const BindAction special_toolbar_actions[] = {
- { EPHY_PREFS_LOCKDOWN_HISTORY, "NavigationBack", "visible" },
- { EPHY_PREFS_LOCKDOWN_HISTORY, "NavigationBack", "sensitive" },
- { EPHY_PREFS_LOCKDOWN_HISTORY, "NavigationForward", "visible" },
- { EPHY_PREFS_LOCKDOWN_HISTORY, "NavigationForward", "sensitive" },
+static const BindAction toolbar_actions[] = {
+ { EPHY_PREFS_LOCKDOWN_HISTORY, "navigation-back", "enabled" },
+ { EPHY_PREFS_LOCKDOWN_HISTORY, "navigation-forward", "enabled" }
};
static gboolean
@@ -290,7 +288,7 @@ window_added_cb (GtkApplication *application,
new_action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
"win");
new_bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
- G_ACTION_GROUP (new_action_group),
+ new_action_group,
new_window_actions,
G_N_ELEMENTS (new_window_actions));
@@ -305,10 +303,13 @@ window_added_cb (GtkApplication *application,
g_settings_bind_writable (settings, "picture-filename",
action, "sensitive", FALSE);
- action_group = find_action_group (manager, "SpecialToolbarActions");
- bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
- action_group, special_toolbar_actions,
- G_N_ELEMENTS (special_toolbar_actions));
+ new_action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
+ "toolbar");
+ new_bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN,
+ new_action_group,
+ toolbar_actions,
+ G_N_ELEMENTS (toolbar_actions));
+
if (ephy_embed_shell_get_mode (ephy_embed_shell_get_default ()) != EPHY_EMBED_SHELL_MODE_APPLICATION) {
location_controller = ephy_window_get_location_controller (EPHY_WINDOW (window));
bind_location_controller (EPHY_SETTINGS_LOCKDOWN, location_controller);
diff --git a/src/ephy-toolbar.c b/src/ephy-toolbar.c
index b10790d..559087a 100644
--- a/src/ephy-toolbar.c
+++ b/src/ephy-toolbar.c
@@ -20,13 +20,23 @@
#include "config.h"
#include "ephy-toolbar.h"
+#include "ephy-action-helper.h"
#include "ephy-downloads-popover.h"
#include "ephy-downloads-progress-icon.h"
+#include "ephy-embed.h"
+#include "ephy-embed-container.h"
+#include "ephy-embed-prefs.h"
+#include "ephy-embed-utils.h"
+#include "ephy-favicon-helpers.h"
+#include "ephy-gui.h"
+#include "ephy-history-service.h"
#include "ephy-location-entry.h"
#include "ephy-middle-clickable-button.h"
#include "ephy-private.h"
#include "ephy-shell.h"
+#include <webkit2/webkit2.h>
+
enum {
PROP_0,
PROP_WINDOW,
@@ -35,6 +45,9 @@ enum {
static GParamSpec *object_properties[N_PROPERTIES] = { NULL, };
+#define MAX_LABEL_LENGTH 48
+#define HISTORY_ITEM_DATA_KEY "history-item-data-key"
+
struct _EphyToolbar {
GtkHeaderBar parent_instance;
@@ -49,6 +62,8 @@ struct _EphyToolbar {
GtkWidget *downloads_popover;
GMenu *page_menu;
+
+ guint navigation_buttons_menu_timeout;
};
G_DEFINE_TYPE (EphyToolbar, ephy_toolbar, GTK_TYPE_HEADER_BAR)
@@ -153,6 +168,383 @@ sync_chromes_visibility (EphyToolbar *toolbar)
gtk_widget_set_visible (toolbar->new_tab_button, chrome & EPHY_WINDOW_CHROME_TABSBAR);
}
+typedef enum {
+ EPHY_NAVIGATION_HISTORY_DIRECTION_BACK,
+ EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD
+} EphyNavigationHistoryDirection;
+
+typedef enum {
+ WEBKIT_HISTORY_BACKWARD,
+ WEBKIT_HISTORY_FORWARD
+} WebKitHistoryType;
+
+static void
+ephy_history_cleared_cb (EphyHistoryService *history,
+ gpointer user_data)
+{
+ GActionGroup *action_group;
+ GAction *action;
+ guint i;
+ gchar **actions;
+
+ action_group = gtk_widget_get_action_group (GTK_WIDGET (user_data), "toolbar");
+ actions = g_action_group_list_actions (action_group);
+ for (i = 0; actions[i] != NULL; i++) {
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group), actions[i]);
+ new_ephy_action_change_sensitivity_flags (G_SIMPLE_ACTION (action), SENS_FLAG, TRUE);
+
+ g_free (actions[i]);
+ }
+
+ g_free (actions);
+}
+
+static gboolean
+item_enter_notify_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ EphyWebView *view)
+{
+ char *text;
+
+ text = g_object_get_data (G_OBJECT (widget), "link-message");
+ ephy_web_view_set_link_message (view, text);
+
+ return FALSE;
+}
+
+static gboolean
+item_leave_notify_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ EphyWebView *view)
+{
+ ephy_web_view_set_link_message (view, NULL);
+ return FALSE;
+}
+
+static void
+icon_loaded_cb (GObject *source,
+ GAsyncResult *result,
+ GtkImageMenuItem *item)
+{
+ WebKitFaviconDatabase *database = WEBKIT_FAVICON_DATABASE (source);
+ GdkPixbuf *favicon = NULL;
+ cairo_surface_t *icon_surface = webkit_favicon_database_get_favicon_finish (database, result, NULL);
+
+ if (icon_surface) {
+ favicon = ephy_pixbuf_get_from_surface_scaled (icon_surface, FAVICON_SIZE, FAVICON_SIZE);
+ cairo_surface_destroy (icon_surface);
+ }
+
+ if (favicon) {
+ GtkWidget *image;
+
+ image = gtk_image_new_from_pixbuf (favicon);
+ gtk_image_menu_item_set_image (item, image);
+ gtk_image_menu_item_set_always_show_image (item, TRUE);
+
+ g_object_unref (favicon);
+ }
+
+ g_object_unref (item);
+}
+
+static GtkWidget *
+new_history_menu_item (EphyWebView *view,
+ const char *origtext,
+ const char *address)
+{
+ GtkWidget *item;
+ GtkLabel *label;
+ WebKitFaviconDatabase *database;
+ EphyEmbedShell *shell = ephy_embed_shell_get_default ();
+
+ g_return_val_if_fail (address != NULL && origtext != NULL, NULL);
+
+ item = gtk_image_menu_item_new_with_label (origtext);
+
+ label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (item)));
+ gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END);
+ gtk_label_set_max_width_chars (label, MAX_LABEL_LENGTH);
+
+ database = webkit_web_context_get_favicon_database (ephy_embed_shell_get_web_context (shell));
+ webkit_favicon_database_get_favicon (database, address,
+ NULL,
+ (GAsyncReadyCallback)icon_loaded_cb,
+ g_object_ref (item));
+
+ g_object_set_data_full (G_OBJECT (item), "link-message", g_strdup (address), (GDestroyNotify)g_free);
+
+ g_signal_connect (item, "enter-notify-event",
+ G_CALLBACK (item_enter_notify_event_cb), view);
+ g_signal_connect (item, "leave-notify-event",
+ G_CALLBACK (item_leave_notify_event_cb), view);
+
+ gtk_widget_show (item);
+
+ return item;
+}
+
+static void
+set_new_back_history (EphyEmbed *source,
+ EphyEmbed *dest,
+ gint offset)
+{
+ /* TODO: WebKitBackForwardList: In WebKit2 WebKitBackForwardList can't be modified */
+}
+
+static void
+middle_click_handle_on_history_menu_item (EphyEmbed *embed,
+ WebKitBackForwardListItem *item)
+{
+ EphyEmbed *new_embed = NULL;
+ const gchar *url;
+ gint offset;
+
+ /* TODO: WebKitBackForwardList is read-only in WebKit2 */
+ offset = 0;
+
+ new_embed = ephy_shell_new_tab (ephy_shell_get_default (),
+ EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
+ embed,
+ 0);
+ g_return_if_fail (new_embed != NULL);
+
+ /* We manually set the back history instead of trusting
+ ephy_shell_new_tab because the logic is more complex than
+ usual, due to handling also the forward history */
+ set_new_back_history (embed, new_embed, offset);
+
+ /* Load the new URL */
+ url = webkit_back_forward_list_item_get_original_uri (item);
+ ephy_web_view_load_url (ephy_embed_get_web_view (new_embed), url);
+}
+
+static gboolean
+navigation_menu_item_pressed_cb (GtkWidget *menuitem,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ EphyWindow *window = EPHY_WINDOW (user_data);
+ WebKitBackForwardListItem *item;
+ EphyEmbed *embed;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+
+ item = (WebKitBackForwardListItem *)g_object_get_data (G_OBJECT (menuitem), HISTORY_ITEM_DATA_KEY);
+
+ if (((GdkEventButton *)event)->button == 2) {
+ middle_click_handle_on_history_menu_item (embed, item);
+ } else {
+ WebKitWebView *web_view;
+
+ web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+ webkit_web_view_go_to_back_forward_list_item (web_view, item);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static GList *
+construct_webkit_history_list (WebKitWebView *web_view,
+ WebKitHistoryType hist_type,
+ int limit)
+{
+ WebKitBackForwardList *back_forward_list;
+
+ back_forward_list = webkit_web_view_get_back_forward_list (web_view);
+ return hist_type == WEBKIT_HISTORY_FORWARD ?
+ g_list_reverse (webkit_back_forward_list_get_forward_list_with_limit (back_forward_list, limit)) :
+ webkit_back_forward_list_get_back_list_with_limit (back_forward_list, limit);
+}
+
+static GtkWidget *
+build_dropdown_menu (EphyWindow *window,
+ EphyNavigationHistoryDirection direction)
+{
+ GtkMenuShell *menu;
+ EphyEmbed *embed;
+ GList *list, *l;
+ WebKitWebView *web_view;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+ g_return_val_if_fail (embed != NULL, NULL);
+
+ menu = GTK_MENU_SHELL (gtk_menu_new ());
+
+ web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+
+ if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_BACK)
+ list = construct_webkit_history_list (web_view,
+ WEBKIT_HISTORY_BACKWARD, 10);
+ else
+ list = construct_webkit_history_list (web_view,
+ WEBKIT_HISTORY_FORWARD, 10);
+
+ for (l = list; l != NULL; l = l->next) {
+ GtkWidget *item;
+ WebKitBackForwardListItem *hitem;
+ const char *uri;
+ char *title;
+
+ hitem = (WebKitBackForwardListItem *)l->data;
+ uri = webkit_back_forward_list_item_get_uri (hitem);
+ title = g_strdup (webkit_back_forward_list_item_get_title (hitem));
+
+ if (title == NULL || g_strstrip (title)[0] == '\0')
+ item = new_history_menu_item (EPHY_WEB_VIEW (web_view), uri, uri);
+ else
+ item = new_history_menu_item (EPHY_WEB_VIEW (web_view), title, uri);
+
+ g_free (title);
+
+ g_object_set_data_full (G_OBJECT (item), HISTORY_ITEM_DATA_KEY,
+ g_object_ref (hitem), g_object_unref);
+
+ g_signal_connect (item, "button-release-event",
+ G_CALLBACK (navigation_menu_item_pressed_cb), window);
+
+ gtk_menu_shell_append (menu, item);
+ gtk_widget_show_all (item);
+ }
+
+ g_list_free (list);
+
+ return GTK_WIDGET (menu);
+}
+
+static void
+popup_history_menu (GtkWidget *widget,
+ EphyWindow *window,
+ EphyNavigationHistoryDirection direction,
+ GdkEventButton *event)
+{
+ GtkWidget *menu;
+
+ menu = build_dropdown_menu (window, direction);
+ gtk_menu_popup (GTK_MENU (menu),
+ NULL, NULL,
+ ephy_gui_menu_position_under_widget, widget,
+ event->button, event->time);
+}
+
+typedef struct {
+ GtkWidget *button;
+ EphyWindow *window;
+ EphyNavigationHistoryDirection direction;
+ GdkEventButton *event;
+} PopupData;
+
+static gboolean
+menu_timeout_cb (PopupData *data)
+{
+ if (data != NULL && data->window)
+ popup_history_menu (data->button, data->window, data->direction, data->event);
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+navigation_button_press_event_cb (GtkButton *button,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ EphyToolbar *toolbar = EPHY_TOOLBAR (user_data);
+ EphyNavigationHistoryDirection direction;
+ GVariant *variant;
+
+ variant = gtk_actionable_get_action_target_value (GTK_ACTIONABLE (button));
+
+ direction = g_strcmp0 (g_variant_get_string (variant, NULL), "back") == 0 ?
+ EPHY_NAVIGATION_HISTORY_DIRECTION_BACK : EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD;
+
+ if (((GdkEventButton *)event)->button == 3) {
+ popup_history_menu (GTK_WIDGET (button), toolbar->window,
+ direction, (GdkEventButton *)event);
+ } else {
+ PopupData *data;
+
+ data = g_new (PopupData, 1);
+ data->button = GTK_WIDGET (button);
+ data->window = toolbar->window;
+ data->direction = direction;
+ data->event = (GdkEventButton *)event;
+
+ toolbar->navigation_buttons_menu_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT, 500,
+ (GSourceFunc)menu_timeout_cb,
+ data,
+ (GDestroyNotify)g_free);
+ g_source_set_name_by_id (toolbar->navigation_buttons_menu_timeout, "[epiphany] menu_timeout_cb");
+ }
+
+ return FALSE;
+}
+
+static gboolean
+navigation_button_release_event_cb (GtkButton *button,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ EphyToolbar *toolbar = EPHY_TOOLBAR (user_data);
+ GActionGroup *action_group;
+ GAction *action;
+ GVariant *variant;
+ EphyNavigationHistoryDirection direction;
+
+ variant = gtk_actionable_get_action_target_value (GTK_ACTIONABLE (button));
+ action_group = gtk_widget_get_action_group (GTK_WIDGET (toolbar->window), "toolbar");
+
+ direction = g_strcmp0 (g_variant_get_string (variant, NULL), "back") == 0 ?
+ EPHY_NAVIGATION_HISTORY_DIRECTION_BACK : EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD;
+
+ switch (((GdkEventButton *)event)->button) {
+ case 1:
+ if (direction == 0) {
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
+ "navigation-back");
+ g_action_activate (action, variant);
+ } else if (direction == 1) {
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
+ "navigation-forward");
+ g_action_activate (action, variant);
+ }
+ break;
+ case 2:
+ if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_BACK) {
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
+ "navigation-back-new-tab");
+ g_action_activate (action, variant);
+ } else if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD) {
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
+ "navigation-forward-new-tab");
+ g_action_activate (action, variant);
+ }
+ break;
+ case 3:
+ popup_history_menu (GTK_WIDGET (button), toolbar->window,
+ direction, (GdkEventButton *)event);
+ break;
+ default:
+ break;
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+navigation_leave_notify_event_cb (GtkButton *button,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ EphyToolbar *toolbar = EPHY_TOOLBAR (user_data);
+
+ if (toolbar->navigation_buttons_menu_timeout > 0)
+ g_source_remove (toolbar->navigation_buttons_menu_timeout);
+
+ toolbar->navigation_buttons_menu_timeout = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
static void
ephy_toolbar_constructed (GObject *object)
{
@@ -163,6 +555,7 @@ ephy_toolbar_constructed (GObject *object)
GtkMenu *menu;
EphyDownloadsManager *downloads_manager;
GtkBuilder *builder;
+ EphyHistoryService *history_service;
G_OBJECT_CLASS (ephy_toolbar_parent_class)->constructed (object);
@@ -174,30 +567,45 @@ ephy_toolbar_constructed (GObject *object)
toolbar->navigation_box = box;
/* Back */
- button = ephy_middle_clickable_button_new ();
- /* FIXME: apparently we need an image inside the button for the action
- * icon to appear. */
- gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
+ button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (button),
+ gtk_image_new_from_icon_name ("go-previous-symbolic",
+ GTK_ICON_SIZE_BUTTON));
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
- action_group = ephy_window_get_toolbar_action_group (toolbar->window);
- action = gtk_action_group_get_action (action_group, "NavigationBack");
- gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
- action);
- gtk_button_set_label (GTK_BUTTON (button), NULL);
- gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
+ gtk_actionable_set_action_name (GTK_ACTIONABLE (button),
+ "toolbar.navigation-back");
+ gtk_actionable_set_action_target_value (GTK_ACTIONABLE (button),
+ g_variant_new ("s", "back"));
+ gtk_style_context_add_class (gtk_widget_get_style_context (button),
+ "image-button");
+ g_signal_connect (button, "button-press-event",
+ G_CALLBACK (navigation_button_press_event_cb), toolbar);
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (navigation_button_release_event_cb), toolbar);
+ g_signal_connect (button, "leave-notify-event",
+ G_CALLBACK (navigation_leave_notify_event_cb), toolbar);
+ gtk_widget_show (GTK_WIDGET (button));
gtk_container_add (GTK_CONTAINER (box), button);
/* Forward */
- button = ephy_middle_clickable_button_new ();
- /* FIXME: apparently we need an image inside the button for the action
- * icon to appear. */
- gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
+ button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (button),
+ gtk_image_new_from_icon_name ("go-next-symbolic",
+ GTK_ICON_SIZE_BUTTON));
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
- action = gtk_action_group_get_action (action_group, "NavigationForward");
- gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
- action);
- gtk_button_set_label (GTK_BUTTON (button), NULL);
- gtk_style_context_add_class (gtk_widget_get_style_context (button), "image-button");
+ gtk_actionable_set_action_name (GTK_ACTIONABLE (button),
+ "toolbar.navigation-forward");
+ gtk_actionable_set_action_target_value (GTK_ACTIONABLE (button),
+ g_variant_new ("s", "forward"));
+ gtk_style_context_add_class (gtk_widget_get_style_context (button),
+ "image-button");
+ g_signal_connect (button, "button-press-event",
+ G_CALLBACK (navigation_button_press_event_cb), toolbar);
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (navigation_button_release_event_cb), toolbar);
+ g_signal_connect (button, "leave-notify-event",
+ G_CALLBACK (navigation_leave_notify_event_cb), toolbar);
+ gtk_widget_show (GTK_WIDGET (button));
gtk_container_add (GTK_CONTAINER (box), button);
gtk_style_context_add_class (gtk_widget_get_style_context (box),
@@ -208,6 +616,8 @@ ephy_toolbar_constructed (GObject *object)
gtk_header_bar_pack_start (GTK_HEADER_BAR (toolbar), box);
/* Reload/Stop */
+ action_group = ephy_window_get_toolbar_action_group (toolbar->window);
+
button = gtk_button_new ();
/* FIXME: apparently we need an image inside the button for the action
* icon to appear. */
@@ -285,6 +695,28 @@ ephy_toolbar_constructed (GObject *object)
gtk_header_bar_pack_end (GTK_HEADER_BAR (toolbar), toolbar->downloads_revealer);
gtk_widget_show (toolbar->downloads_revealer);
+
+ history_service = EPHY_HISTORY_SERVICE (ephy_embed_shell_get_global_history_service
(ephy_embed_shell_get_default ()));
+
+ toolbar->navigation_buttons_menu_timeout = 0;
+
+ g_signal_connect (history_service,
+ "cleared", G_CALLBACK (ephy_history_cleared_cb),
+ toolbar->window);
+}
+
+static void
+ephy_toolbar_init (EphyToolbar *toolbar)
+{
+}
+
+static void
+ephy_toolbar_finalize (GObject *object)
+{
+ if (EPHY_TOOLBAR (object)->navigation_buttons_menu_timeout > 0)
+ g_source_remove (EPHY_TOOLBAR (object)->navigation_buttons_menu_timeout);
+
+ G_OBJECT_CLASS (ephy_toolbar_parent_class)->finalize (object);
}
static void
@@ -292,6 +724,7 @@ ephy_toolbar_class_init (EphyToolbarClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ephy_toolbar_finalize;
gobject_class->set_property = ephy_toolbar_set_property;
gobject_class->get_property = ephy_toolbar_get_property;
gobject_class->constructed = ephy_toolbar_constructed;
@@ -308,11 +741,6 @@ ephy_toolbar_class_init (EphyToolbarClass *klass)
object_properties);
}
-static void
-ephy_toolbar_init (EphyToolbar *toolbar)
-{
-}
-
GtkWidget *
ephy_toolbar_new (EphyWindow *window)
{
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 8213313..a20682b 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -37,7 +37,6 @@
#include "ephy-initial-state.h"
#include "ephy-link.h"
#include "ephy-location-entry.h"
-#include "ephy-navigation-history-action.h"
#include "ephy-notebook.h"
#include "ephy-prefs.h"
#include "ephy-private.h"
@@ -256,8 +255,6 @@ static const struct {
* when NumLock is on they are KP_9/3 and with NumLock and Control+Shift
* They're KP_PageUp/Down again!
*/
- { GDK_KEY_KP_4, GDK_MOD1_MASK /*Alt*/, "NavigationBack", TRUE },
- { GDK_KEY_KP_6, GDK_MOD1_MASK /*Alt*/, "NavigationForward", TRUE },
{ GDK_KEY_KP_Page_Up, GDK_CONTROL_MASK, "TabsPrevious", FALSE },
{ GDK_KEY_KP_9, GDK_CONTROL_MASK, "TabsPrevious", FALSE },
{ GDK_KEY_KP_Page_Down, GDK_CONTROL_MASK, "TabsNext", FALSE },
@@ -267,8 +264,6 @@ static const struct {
{ GDK_KEY_KP_Page_Down, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "TabsMoveRight", FALSE },
{ GDK_KEY_KP_3, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "TabsMoveRight", FALSE },
#ifdef HAVE_X11_XF86KEYSYM_H
- { XF86XK_Back, 0, "NavigationBack", TRUE },
- { XF86XK_Forward, 0, "NavigationForward", TRUE },
{ XF86XK_Go, 0, "GoLocation", FALSE },
{ XF86XK_OpenURL, 0, "GoLocation", FALSE },
{ XF86XK_AddFavorite, 0, "FileBookmarkPage", FALSE },
@@ -278,22 +273,13 @@ static const struct {
{ XF86XK_Stop, 0, "ViewStop", FALSE },
/* FIXME: what about ScrollUp, ScrollDown, Menu*, Option, LogOff, Save,.. any others? */
#endif /* HAVE_X11_XF86KEYSYM_H */
-}, navigation_keybindings_ltr [] = {
- { GDK_KEY_Left, GDK_MOD1_MASK /*Alt*/, "NavigationBack", TRUE },
- { GDK_KEY_KP_Left, GDK_MOD1_MASK /*Alt*/, "NavigationBack", TRUE },
- { GDK_KEY_Right, GDK_MOD1_MASK /*Alt*/, "NavigationForward", TRUE },
- { GDK_KEY_KP_Right, GDK_MOD1_MASK /*Alt*/, "NavigationForward", TRUE }
-}, navigation_keybindings_rtl [] = {
- { GDK_KEY_Left, GDK_MOD1_MASK /*Alt*/, "NavigationForward", TRUE },
- { GDK_KEY_KP_Left, GDK_MOD1_MASK /*Alt*/, "NavigationForward", TRUE },
- { GDK_KEY_Right, GDK_MOD1_MASK /*Alt*/, "NavigationBack", TRUE },
- { GDK_KEY_KP_Right, GDK_MOD1_MASK /*Alt*/, "NavigationBack", TRUE }
-}, *navigation_keybindings_rtl_ltr;
+};
const struct {
const gchar *action_and_target;
const gchar *accelerators[5];
} accels [] = {
+ /* Window accels */
{ "win.new-tab", { "<Primary>T", NULL } },
{ "win.open", { "<Primary>O", NULL } },
{ "win.save-as", { "<shift><Primary>S", "<Primary>S", NULL } },
@@ -314,8 +300,14 @@ const struct {
{ "win.encoding", { NULL } },
{ "win.page-source", { "<Primary>U", NULL } },
{ "win.toggle-inspector", { "<shift><Primary>I", "F12", NULL } },
- { "win.close", { "<Primary>W", NULL } }
-};
+ { "win.close", { "<Primary>W", NULL } },
+}, accels_navigation_ltr [] = {
+ { "toolbar.navigation-back", { "<alt>Left", "<alt>KP_LEFT", "KP_4", "Back", NULL } },
+ { "toolbar.navigation-forward", { "<alt>Right", "<alt>KP_RIGHT", "KP_6", "Forward", NULL } }
+}, accels_navigation_rtl [] = {
+ { "toolbar.navigation-back", { "<alt>Left", "<alt>KP_LEFT", "KP_6", "Back", NULL } },
+ { "toolbar.navigation-forward", { "<alt>Right", "<alt>KP_RIGHT", "KP_4", "Forward", NULL } }
+}, *accels_navigation_ltr_rtl;
#define SETTINGS_CONNECTION_DATA_KEY "EphyWindowSettings"
@@ -729,9 +721,6 @@ ephy_window_bound_accels (GtkWidget *widget,
guint modifier = event->state & gtk_accelerator_get_default_mod_mask ();
guint i;
- navigation_keybindings_rtl_ltr = gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL ?
- navigation_keybindings_rtl : navigation_keybindings_ltr;
-
for (i = 0; i < G_N_ELEMENTS (extra_keybindings); i++) {
if (event->keyval == extra_keybindings[i].keyval &&
modifier == extra_keybindings[i].modifier) {
@@ -748,22 +737,6 @@ ephy_window_bound_accels (GtkWidget *widget,
}
}
- for (i = 0; i < G_N_ELEMENTS (navigation_keybindings_rtl); i++) {
- if (event->keyval == navigation_keybindings_rtl_ltr[i].keyval &&
- modifier == navigation_keybindings_rtl_ltr[i].modifier) {
- GtkAction *action = gtk_action_group_get_action
- (navigation_keybindings_rtl_ltr[i].fromToolbar ?
- window->toolbar_action_group :
- window->action_group,
- navigation_keybindings_rtl_ltr[i].action);
- if (gtk_action_is_sensitive (action)) {
- gtk_action_activate (action);
- return TRUE;
- }
- break;
- }
- }
-
return FALSE;
}
@@ -1078,6 +1051,13 @@ static const GActionEntry new_ephy_page_menu_entries [] =
{ "close-tab", window_cmd_file_close_window }
};
+static const GActionEntry ephy_toolbar_entries [] = {
+ { "navigation-back", window_cmd_navigation, "s" },
+ { "navigation-back-new-tab", window_cmd_navigation_new_tab, "s" },
+ { "navigation-forward", window_cmd_navigation, "s" },
+ { "navigation-forward-new-tab", window_cmd_navigation_new_tab, "s" }
+};
+
static void
setup_ui_manager (EphyWindow *window)
{
@@ -1122,29 +1102,6 @@ setup_ui_manager (EphyWindow *window)
g_object_unref (action_group);
action_group = gtk_action_group_new ("SpecialToolbarActions");
- action =
- g_object_new (EPHY_TYPE_NAVIGATION_HISTORY_ACTION,
- "name", "NavigationBack",
- "label", _("Back"),
- "icon-name", "go-previous-symbolic",
- "window", window,
- "direction", EPHY_NAVIGATION_HISTORY_DIRECTION_BACK,
- NULL);
- gtk_action_group_add_action_with_accel (action_group, action,
- "<alt>Left");
- g_object_unref (action);
-
- action =
- g_object_new (EPHY_TYPE_NAVIGATION_HISTORY_ACTION,
- "name", "NavigationForward",
- "label", _("Forward"),
- "icon-name", "go-next-symbolic",
- "window", window,
- "direction", EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD,
- NULL);
- gtk_action_group_add_action_with_accel (action_group, action,
- "<alt>Right");
- g_object_unref (action);
action =
g_object_new (EPHY_TYPE_HOME_ACTION,
@@ -1361,12 +1318,15 @@ static void
_ephy_window_set_navigation_flags (EphyWindow *window,
EphyWebViewNavigationFlags flags)
{
- GtkAction *action;
+ GActionGroup *action_group;
+ GAction *action;
- action = gtk_action_group_get_action (window->toolbar_action_group, "NavigationBack");
- gtk_action_set_sensitive (action, flags & EPHY_WEB_VIEW_NAV_BACK);
- action = gtk_action_group_get_action (window->toolbar_action_group, "NavigationForward");
- gtk_action_set_sensitive (action, flags & EPHY_WEB_VIEW_NAV_FORWARD);
+ action_group = gtk_widget_get_action_group (GTK_WIDGET (window), "toolbar");
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "navigation-back");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), flags & EPHY_WEB_VIEW_NAV_BACK);
+ action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "navigation-forward");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), flags & EPHY_WEB_VIEW_NAV_FORWARD);
}
static void
@@ -1546,10 +1506,18 @@ action_name_to_label_for_model (GMenuModel *menu_model, const gchar *action_name
return NULL;
}
+typedef struct {
+ GAction *action;
+ GVariant *parameter;
+} GActionData;
+
static void
action_activate_cb (GtkAction *action, gpointer user_data)
{
- g_action_activate (G_ACTION (user_data), NULL);
+ GActionData *action_data = (GActionData *) user_data;
+
+ printf("%s\n", g_variant_get_string (action_data->parameter, NULL));
+ g_action_activate (G_ACTION (action_data->action), action_data->parameter);
}
static WebKitContextMenuItem*
@@ -1557,10 +1525,12 @@ webkit_context_menu_item_new_from_gaction (GAction *action, const gchar *label)
{
GtkAction *gtk_action;
WebKitContextMenuItem *item;
+ GActionData *action_data;
+ action_data = g_slice_new (GActionData);
gtk_action = gtk_action_new (g_action_get_name (action), label, NULL, NULL);
g_signal_connect (gtk_action, "activate",
- G_CALLBACK (action_activate_cb), action);
+ G_CALLBACK (action_activate_cb), action_data);
g_object_bind_property (action, "enabled", gtk_action, "sensitive", G_BINDING_BIDIRECTIONAL);
@@ -1572,15 +1542,15 @@ webkit_context_menu_item_new_from_gaction (GAction *action, const gchar *label)
static void
new_add_action_to_context_menu (WebKitContextMenu *context_menu,
GActionGroup *action_group,
- const char *action_name)
+ const char *action_name,
+ GtkWidget *toolbar)
{
GAction *action;
- EphyToolbar *toolbar;
const gchar *label;
- toolbar = EPHY_TOOLBAR (EPHY_WINDOW (action_group)->toolbar);
action = g_action_map_lookup_action (G_ACTION_MAP (action_group), action_name);
- label = action_name_to_label_for_model (G_MENU_MODEL (ephy_toolbar_get_page_menu (toolbar)), action_name);
+ label = action_name_to_label_for_model (G_MENU_MODEL (ephy_toolbar_get_page_menu (EPHY_TOOLBAR (toolbar))),
+ action_name);
webkit_context_menu_append (context_menu, webkit_context_menu_item_new_from_gaction (action, label));
}
@@ -1683,6 +1653,7 @@ populate_context_menu (WebKitWebView *web_view,
WebKitContextMenuItem *toggle_loop_item = NULL;
WebKitContextMenuItem *fullscreen_item = NULL;
GActionGroup *window_action_group;
+ GActionGroup *toolbar_action_group;
GList *spelling_guess_items = NULL;
EphyEmbedEvent *embed_event;
gboolean is_document = FALSE;
@@ -1696,6 +1667,8 @@ populate_context_menu (WebKitWebView *web_view,
window_action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
"win");
+ toolbar_action_group = gtk_widget_get_action_group (GTK_WIDGET (window),
+ "toolbar");
is_image = webkit_hit_test_result_context_is_image (hit_test_result);
@@ -1783,7 +1756,7 @@ populate_context_menu (WebKitWebView *web_view,
webkit_context_menu_item_new_separator ());
}
new_add_action_to_context_menu (context_menu,
- window_action_group, "copy");
+ window_action_group, "copy", window->toolbar);
if (can_search_selection)
add_action_to_context_menu (context_menu,
window->popups_action_group, "SearchSelection");
@@ -1820,21 +1793,21 @@ populate_context_menu (WebKitWebView *web_view,
update_edit_actions_sensitivity (window, FALSE);
new_add_action_to_context_menu (context_menu,
- window_action_group, "undo");
+ window_action_group, "undo", window->toolbar);
new_add_action_to_context_menu (context_menu,
- window_action_group, "redo");
+ window_action_group, "redo", window->toolbar);
webkit_context_menu_append (context_menu,
webkit_context_menu_item_new_separator ());
new_add_action_to_context_menu (context_menu,
- window_action_group, "cut");
+ window_action_group, "cut", window->toolbar);
new_add_action_to_context_menu (context_menu,
- window_action_group, "copy");
+ window_action_group, "copy", window->toolbar);
new_add_action_to_context_menu (context_menu,
- window_action_group, "paste");
+ window_action_group, "paste", window->toolbar);
webkit_context_menu_append (context_menu,
webkit_context_menu_item_new_separator ());
new_add_action_to_context_menu (context_menu,
- window_action_group, "select-all");
+ window_action_group, "select-all", window->toolbar);
if (input_methods_item || unicode_item)
webkit_context_menu_append (context_menu,
webkit_context_menu_item_new_separator ());
@@ -1846,10 +1819,10 @@ populate_context_menu (WebKitWebView *web_view,
update_edit_actions_sensitivity (window, TRUE);
if (!is_image && !is_media) {
- add_action_to_context_menu (context_menu,
- window->toolbar_action_group, "NavigationBack");
- add_action_to_context_menu (context_menu,
- window->toolbar_action_group, "NavigationForward");
+ new_add_action_to_context_menu (context_menu, toolbar_action_group,
+ "navigation-back", window->toolbar);
+ new_add_action_to_context_menu (context_menu, toolbar_action_group,
+ "navigation-forward", window->toolbar);
add_action_to_context_menu (context_menu,
window->action_group, "ViewReload");
webkit_context_menu_append (context_menu,
@@ -1857,7 +1830,7 @@ populate_context_menu (WebKitWebView *web_view,
}
new_add_action_to_context_menu (context_menu,
- window_action_group, "copy");
+ window_action_group, "copy", window->toolbar);
if (can_search_selection)
add_action_to_context_menu (context_menu,
window->popups_action_group, "SearchSelection");
@@ -3068,7 +3041,6 @@ static GtkWidget *
setup_toolbar (EphyWindow *window)
{
GtkWidget *toolbar;
- GtkAction *action;
EphyEmbedShellMode app_mode;
EphyTitleBox *title_box;
@@ -3080,16 +3052,6 @@ setup_toolbar (EphyWindow *window)
if (app_mode == EPHY_EMBED_SHELL_MODE_INCOGNITO)
gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), "incognito-mode");
- action = gtk_action_group_get_action (window->toolbar_action_group,
- "NavigationBack");
- g_signal_connect_swapped (action, "open-link",
- G_CALLBACK (ephy_link_open), window);
-
- action = gtk_action_group_get_action (window->toolbar_action_group,
- "NavigationForward");
- g_signal_connect_swapped (action, "open-link",
- G_CALLBACK (ephy_link_open), window);
-
title_box = ephy_toolbar_get_title_box (EPHY_TOOLBAR (toolbar));
g_signal_connect (title_box, "lock-clicked",
G_CALLBACK (title_box_lock_clicked_cb), window);
@@ -3214,6 +3176,15 @@ ephy_window_constructor (GType type,
"win",
G_ACTION_GROUP (new_simple_action_group));
+ new_simple_action_group = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (new_simple_action_group),
+ ephy_toolbar_entries,
+ G_N_ELEMENTS (ephy_toolbar_entries),
+ window);
+ gtk_widget_insert_action_group (GTK_WIDGET (window),
+ "toolbar",
+ G_ACTION_GROUP (new_simple_action_group));
+
/* Set accels for actions */
app = g_application_get_default ();
for (i = 0; i < G_N_ELEMENTS (accels); i++) {
@@ -3222,6 +3193,15 @@ ephy_window_constructor (GType type,
accels[i].accelerators);
}
+ accels_navigation_ltr_rtl = gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR ?
+ accels_navigation_ltr : accels_navigation_rtl;
+
+ for (i = 0; i < G_N_ELEMENTS (accels_navigation_ltr_rtl); i++) {
+ gtk_application_set_accels_for_action (GTK_APPLICATION (app),
+ accels_navigation_ltr_rtl[i].action_and_target,
+ accels_navigation_ltr_rtl[i].accelerators);
+ }
+
ephy_gui_ensure_window_group (GTK_WINDOW (window));
/* initialize the listener for the key theme
diff --git a/src/window-commands.c b/src/window-commands.c
index 84e5b56..4047d68 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -62,6 +62,84 @@
#define FAVICON_SIZE 16
void
+window_cmd_navigation (GSimpleAction *action,
+ GVariant *value,
+ gpointer user_data)
+{
+ EphyWindow *window = EPHY_WINDOW (user_data);
+ const gchar *direction = g_variant_get_string (value, 0);
+ EphyEmbed *embed;
+ WebKitWebView *web_view;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+ g_return_if_fail (embed != NULL);
+
+ web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+
+ if (g_strcmp0 (direction, "back") == 0) {
+ webkit_web_view_go_back (web_view);
+ gtk_widget_grab_focus (GTK_WIDGET (embed));
+ } else {
+ webkit_web_view_go_forward (web_view);
+ gtk_widget_grab_focus (GTK_WIDGET (embed));
+ }
+}
+
+void
+window_cmd_navigation_new_tab (GSimpleAction *action,
+ GVariant *value,
+ gpointer user_data)
+{
+ EphyWindow *window = EPHY_WINDOW (user_data);
+ const gchar *direction = g_variant_get_string (value, 0);
+ EphyEmbed *embed;
+ WebKitWebView *web_view;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+ g_return_if_fail (embed != NULL);
+
+ web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+
+ if (g_strcmp0 (direction, "back") == 0) {
+ const char *back_uri;
+ WebKitBackForwardList *history;
+ WebKitBackForwardListItem *back_item;
+
+ history = webkit_web_view_get_back_forward_list (web_view);
+ back_item = webkit_back_forward_list_get_back_item (history);
+ back_uri = webkit_back_forward_list_item_get_original_uri (back_item);
+
+ embed = ephy_shell_new_tab (ephy_shell_get_default (),
+ EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
+ NULL,
+ 0);
+
+ web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+ webkit_web_view_load_uri (web_view, back_uri);
+ gtk_widget_grab_focus (GTK_WIDGET (embed));
+ } else {
+ const char *forward_uri;
+ WebKitBackForwardList *history;
+ WebKitBackForwardListItem *forward_item;
+
+ /* Forward history is not copied when opening
+ a new tab, so get the forward URI manually
+ and load it */
+ history = webkit_web_view_get_back_forward_list (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed));
+ forward_item = webkit_back_forward_list_get_forward_item (history);
+ forward_uri = webkit_back_forward_list_item_get_original_uri (forward_item);
+
+ embed = ephy_shell_new_tab (ephy_shell_get_default (),
+ EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
+ embed,
+ 0);
+
+ web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+ webkit_web_view_load_uri (web_view, forward_uri);
+ }
+}
+
+void
window_cmd_undo_close_tab (GtkAction *action,
EphyWindow *window)
{
diff --git a/src/window-commands.h b/src/window-commands.h
index c5252d8..463306f 100644
--- a/src/window-commands.h
+++ b/src/window-commands.h
@@ -24,6 +24,12 @@
G_BEGIN_DECLS
+void window_cmd_navigation (GSimpleAction *action,
+ GVariant *value,
+ gpointer user_data);
+void window_cmd_navigation_new_tab (GSimpleAction *action,
+ GVariant *value,
+ gpointer user_data);
void window_cmd_view_stop (GtkAction *action,
EphyWindow *window);
void window_cmd_go_location (GtkAction *action,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]