aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/widgets/Makefile.am4
-rw-r--r--lib/widgets/ephy-middle-clickable-button.c68
-rw-r--r--lib/widgets/ephy-middle-clickable-button.h56
-rw-r--r--lib/widgets/ephy-middle-clickable-tool-button.c46
-rw-r--r--lib/widgets/ephy-middle-clickable-tool-button.h55
-rw-r--r--src/ephy-link-action.c63
-rw-r--r--src/ephy-link-action.h6
-rw-r--r--src/ephy-navigation-action.c3
-rw-r--r--src/ephy-navigation-history-action.c10
9 files changed, 278 insertions, 33 deletions
diff --git a/lib/widgets/Makefile.am b/lib/widgets/Makefile.am
index 941a9548a..57d5c73ce 100644
--- a/lib/widgets/Makefile.am
+++ b/lib/widgets/Makefile.am
@@ -5,6 +5,10 @@ libephywidgets_la_SOURCES = \
ephy-download-widget.h \
ephy-location-entry.c \
ephy-location-entry.h \
+ ephy-middle-clickable-button.c \
+ ephy-middle-clickable-button.h \
+ ephy-middle-clickable-tool-button.c \
+ ephy-middle-clickable-tool-button.h \
ephy-node-view.c \
ephy-node-view.h \
ephy-search-entry.c \
diff --git a/lib/widgets/ephy-middle-clickable-button.c b/lib/widgets/ephy-middle-clickable-button.c
new file mode 100644
index 000000000..1e6f53e98
--- /dev/null
+++ b/lib/widgets/ephy-middle-clickable-button.c
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright © 2011 Alexandre Mazari
+ * Copyright © 2011 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ephy-middle-clickable-button.h"
+
+G_DEFINE_TYPE (EphyMiddleClickableButton, ephy_middle_clickable_button, GTK_TYPE_BUTTON)
+
+static gboolean
+ephy_middle_clickable_button_handle_event (GtkWidget * widget,
+ GdkEventButton * event)
+{
+ gboolean ret;
+ int actual_button;
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (ephy_middle_clickable_button_parent_class);
+
+ actual_button = event->button;
+
+ if (actual_button == 2)
+ event->button = 1;
+
+ if (event->type == GDK_BUTTON_PRESS)
+ ret = widget_class->button_press_event (widget, event);
+ else
+ ret = widget_class->button_release_event (widget, event);
+
+ event->button = actual_button;
+
+ return ret;
+}
+
+static void
+ephy_middle_clickable_button_class_init (EphyMiddleClickableButtonClass *class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ widget_class->button_press_event = ephy_middle_clickable_button_handle_event;
+ widget_class->button_release_event = ephy_middle_clickable_button_handle_event;
+}
+
+static void
+ephy_middle_clickable_button_init (EphyMiddleClickableButton *class)
+{
+}
+
+GtkWidget *
+ephy_middle_clickable_button_new ()
+{
+ return gtk_widget_new (EPHY_TYPE_MIDDLE_CLICKABLE_BUTTON, NULL);
+}
diff --git a/lib/widgets/ephy-middle-clickable-button.h b/lib/widgets/ephy-middle-clickable-button.h
new file mode 100644
index 000000000..e346a1488
--- /dev/null
+++ b/lib/widgets/ephy-middle-clickable-button.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright © 2011 Alexandre Mazari
+ * Copyright © 2011 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if !defined (__EPHY_EPIPHANY_H_INSIDE__) && !defined (EPIPHANY_COMPILATION)
+#error "Only <epiphany/epiphany.h> can be included directly."
+#endif
+
+#ifndef __EPHY_MIDDLE_CLICKABLE_BUTTON_H__
+#define __EPHY_MIDDLE_CLICKABLE_BUTTON_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_MIDDLE_CLICKABLE_BUTTON (ephy_middle_clickable_button_get_type ())
+#define EPHY_MIDDLE_CLICKABLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),EPHY_TYPE_MIDDLE_CLICKABLE_BUTTN, EphyMiddleClickableButton))
+#define EPHY_MIDDLE_CLICKABLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_MIDDLE_CLICKABLE_BUTTN, EphyMiddleClickableButtonClass))
+#define EPHY_IS_MIDDLE_CLICKABLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_MIDDLE_CLICKABLE_BUTON))
+#define EPHY_IS_MIDDLE_CLICKABLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EPHY_TYPE_MIDDLE_CLICKABLE_BUTTN))
+#define EPHY_MIDDLE_CLICKABLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_TYPE_MIDDLE_CLICKABLE_BUTTN, EphyMiddleClickableButtonClass))
+
+typedef struct _EphyMiddleClickableButton EphyMiddleClickableButton;
+typedef struct _EphyMiddleClickableButtonClass EphyMiddleClickableButtonClass;
+
+struct _EphyMiddleClickableButton {
+ GtkButton parent;
+};
+
+struct _EphyMiddleClickableButtonClass {
+ GtkButtonClass parent_class;
+};
+
+GType ephy_middle_clickable_button_get_type (void) G_GNUC_CONST;
+GtkWidget *ephy_middle_clickable_button_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/widgets/ephy-middle-clickable-tool-button.c b/lib/widgets/ephy-middle-clickable-tool-button.c
new file mode 100644
index 000000000..6bcce5eb7
--- /dev/null
+++ b/lib/widgets/ephy-middle-clickable-tool-button.c
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright © 2011 Alexandre Mazari
+ * Copyright © 2011 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ephy-middle-clickable-tool-button.h"
+
+#include "ephy-middle-clickable-button.h"
+
+G_DEFINE_TYPE (EphyMiddleClickableToolButton, ephy_middle_clickable_tool_button, GTK_TYPE_TOOL_BUTTON)
+
+static void
+ephy_middle_clickable_tool_button_class_init (EphyMiddleClickableToolButtonClass *class)
+{
+ GtkToolButtonClass *tool_button_class = GTK_TOOL_BUTTON_CLASS (class);
+
+ tool_button_class->button_type = EPHY_TYPE_MIDDLE_CLICKABLE_BUTTON;
+}
+
+static void
+ephy_middle_clickable_tool_button_init (EphyMiddleClickableToolButton *class)
+{
+}
+
+GtkWidget *
+ephy_middle_clickable_tool_button_new ()
+{
+ return gtk_widget_new (EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON, NULL);
+}
diff --git a/lib/widgets/ephy-middle-clickable-tool-button.h b/lib/widgets/ephy-middle-clickable-tool-button.h
new file mode 100644
index 000000000..a5863b9d7
--- /dev/null
+++ b/lib/widgets/ephy-middle-clickable-tool-button.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright © 2011 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if !defined (__EPHY_EPIPHANY_H_INSIDE__) && !defined (EPIPHANY_COMPILATION)
+#error "Only <epiphany/epiphany.h> can be included directly."
+#endif
+
+#ifndef __EPHY_MIDDLE_CLICKABLE_TOOL_BUTTON_H__
+#define __EPHY_MIDDLE_CLICKABLE_TOOL_BUTTON_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON (ephy_middle_clickable_tool_button_get_type ())
+#define EPHY_MIDDLE_CLICKABLE_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON, EphyMiddleClickableToolBtton))
+#define EPHY_MIDDLE_CLICKABLE_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON, EphyMiddleClickableToolBttonClass))
+#define EPHY_IS_MIDDLE_CLICKABLE_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON))
+#define EPHY_IS_MIDDLE_CLICKABLE_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON))
+#define EPHY_MIDDLE_CLICKABLE_TOOL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON, EphyMiddleClickableToolBttonClass))
+
+typedef struct _EphyMiddleClickableToolButton EphyMiddleClickableToolButton;
+typedef struct _EphyMiddleClickableToolButtonClass EphyMiddleClickableToolButtonClass;
+
+struct _EphyMiddleClickableToolButton {
+ GtkToolButton parent;
+};
+
+struct _EphyMiddleClickableToolButtonClass {
+ GtkToolButtonClass parent_class;
+};
+
+GType ephy_middle_clickable_tool_button_get_type (void) G_GNUC_CONST;
+GtkWidget *ephy_middle_clickable_tool_button_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-link-action.c b/src/ephy-link-action.c
index 160b253d3..804aae7c4 100644
--- a/src/ephy-link-action.c
+++ b/src/ephy-link-action.c
@@ -32,33 +32,19 @@ G_DEFINE_TYPE_WITH_CODE (EphyLinkAction, ephy_link_action, GTK_TYPE_ACTION,
G_IMPLEMENT_INTERFACE (EPHY_TYPE_LINK,
NULL))
+#define EPHY_LINK_ACTION_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LINK_ACTION, EphyLinkActionPrivate))
+
+struct _EphyLinkActionPrivate
+{
+ guint button;
+};
+
static gboolean
proxy_button_press_event_cb (GtkButton *button,
GdkEventButton *event,
EphyLinkAction *action)
{
- if (event->button == 2)
- {
- gtk_button_pressed (button);
- }
-
- return FALSE;
-}
-
-static gboolean
-proxy_button_release_event_cb (GtkButton *button,
- GdkEventButton *event,
- EphyLinkAction *action)
-{
- /*
- * We do not use ephy_gui_is_middle_click() here because
- * that also catches ctrl + left_click which already
- * triggers an activate event for all proxies.
- */
- if (event->button == 2)
- {
- gtk_button_released (button);
- }
+ action->priv->button = event->button;
return FALSE;
}
@@ -109,9 +95,6 @@ ephy_link_action_connect_proxy (GtkAction *action, GtkWidget *proxy)
g_signal_connect (widget, "button-press-event",
G_CALLBACK (proxy_button_press_event_cb),
action);
- g_signal_connect (widget, "button-release-event",
- G_CALLBACK (proxy_button_release_event_cb),
- action);
}
GTK_ACTION_CLASS (ephy_link_action_parent_class)->connect_proxy (action, proxy);
@@ -130,9 +113,6 @@ ephy_link_action_disconnect_proxy (GtkAction *action, GtkWidget *proxy)
g_signal_handlers_disconnect_by_func (widget,
G_CALLBACK (proxy_button_press_event_cb),
action);
- g_signal_handlers_disconnect_by_func (widget,
- G_CALLBACK (proxy_button_release_event_cb),
- action);
}
GTK_ACTION_CLASS (ephy_link_action_parent_class)->disconnect_proxy (action, proxy);
@@ -141,7 +121,7 @@ ephy_link_action_disconnect_proxy (GtkAction *action, GtkWidget *proxy)
static void
ephy_link_action_init (EphyLinkAction *action)
{
- /* Empty, needed for G_DEFINE_TYPE macro */
+ action->priv = EPHY_LINK_ACTION_GET_PRIVATE (action);
}
static void
@@ -151,6 +131,31 @@ ephy_link_action_class_init (EphyLinkActionClass *class)
action_class->connect_proxy = ephy_link_action_connect_proxy;
action_class->disconnect_proxy = ephy_link_action_disconnect_proxy;
+
+ g_type_class_add_private (G_OBJECT_CLASS (class), sizeof (EphyLinkActionPrivate));
+}
+
+/**
+ * ephy_link_action_get_button:
+ * @action: an #EphyLinkAction
+ *
+ * This method stores the mouse button number that last activated, or
+ * is activating, the @action. This is useful because #GtkButton's
+ * cannot be clicked with a middle click by default, so inside
+ * Epiphany we fake this by forwarding a left click (button 1) event
+ * instead of a middle click (button 2) to the button. That makes the
+ * EphyGUI methods like ephy_gui_is_middle_click not work here, so we
+ * need to ask the @action directly about the button that activated
+ * it.
+ *
+ * Returns: the button number that last activated (or is activating) the @action
+ **/
+guint
+ephy_link_action_get_button (EphyLinkAction *action)
+{
+ g_return_val_if_fail (EPHY_IS_LINK_ACTION (action), 0);
+
+ return action->priv->button;
}
static void
diff --git a/src/ephy-link-action.h b/src/ephy-link-action.h
index 6dbf03728..a6b4419cc 100644
--- a/src/ephy-link-action.h
+++ b/src/ephy-link-action.h
@@ -44,6 +44,7 @@ G_BEGIN_DECLS
typedef struct _EphyLinkAction EphyLinkAction;
typedef struct _EphyLinkActionClass EphyLinkActionClass;
+typedef struct _EphyLinkActionPrivate EphyLinkActionPrivate;
typedef struct _EphyLinkActionGroup EphyLinkActionGroup;
typedef struct _EphyLinkActionGroupClass EphyLinkActionGroupClass;
@@ -51,6 +52,8 @@ typedef struct _EphyLinkActionGroupClass EphyLinkActionGroupClass;
struct _EphyLinkAction
{
GtkAction parent_instance;
+
+ EphyLinkActionPrivate *priv;
};
struct _EphyLinkActionClass
@@ -68,7 +71,8 @@ struct _EphyLinkActionGroupClass
GtkActionGroupClass parent_class;
};
-GType ephy_link_action_get_type (void);
+GType ephy_link_action_get_type (void);
+guint ephy_link_action_get_button (EphyLinkAction *action);
GType ephy_link_action_group_get_type (void);
diff --git a/src/ephy-navigation-action.c b/src/ephy-navigation-action.c
index ed544430b..438e6cf51 100644
--- a/src/ephy-navigation-action.c
+++ b/src/ephy-navigation-action.c
@@ -24,6 +24,7 @@
#include "config.h"
#include "ephy-navigation-action.h"
+#include "ephy-middle-clickable-tool-button.h"
#include "ephy-window.h"
#include <gtk/gtk.h>
@@ -93,7 +94,7 @@ ephy_navigation_action_class_init (EphyNavigationActionClass *class)
object_class->set_property = ephy_navigation_action_set_property;
object_class->get_property = ephy_navigation_action_get_property;
- action_class->toolbar_item_type = GTK_TYPE_TOOL_BUTTON;
+ action_class->toolbar_item_type = EPHY_TYPE_MIDDLE_CLICKABLE_TOOL_BUTTON;
g_object_class_install_property (object_class,
PROP_WINDOW,
diff --git a/src/ephy-navigation-history-action.c b/src/ephy-navigation-history-action.c
index daf98ad5e..7c8d9f3d7 100644
--- a/src/ephy-navigation-history-action.c
+++ b/src/ephy-navigation-history-action.c
@@ -87,8 +87,13 @@ action_activate (GtkAction *action)
web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
+ /* We use ephy_link_action_get_button on top of
+ * ephy_gui_is_middle_click because of the hacks we have to do to
+ * fake middle clicks on tool buttons. Read the documentation of
+ * ephy_link_action_get_button for more details. */
if (history_action->priv->direction == EPHY_NAVIGATION_HISTORY_DIRECTION_BACK) {
- if (ephy_gui_is_middle_click ()) {
+ if (ephy_gui_is_middle_click () ||
+ ephy_link_action_get_button (EPHY_LINK_ACTION (history_action)) == 2) {
embed = ephy_shell_new_tab (ephy_shell_get_default (),
EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
embed,
@@ -98,7 +103,8 @@ action_activate (GtkAction *action)
}
webkit_web_view_go_back (web_view);
} else if (history_action->priv->direction == EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD) {
- if (ephy_gui_is_middle_click ()) {
+ if (ephy_gui_is_middle_click () ||
+ ephy_link_action_get_button (EPHY_LINK_ACTION (history_action)) == 2) {
const char *forward_uri;
WebKitWebHistoryItem *forward_item;
WebKitWebBackForwardList *history;