[devhelp] Let middle click open links in new tabs, in the background
- From: Frederic Peters <fpeters src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [devhelp] Let middle click open links in new tabs, in the background
- Date: Fri, 28 Aug 2009 19:52:15 +0000 (UTC)
commit 2b0ddd3adc7fdb1abb9c0b09a76e5380194bf273
Author: Frédéric Péters <fpeters 0d be>
Date: Fri Aug 28 21:50:22 2009 +0200
Let middle click open links in new tabs, in the background
.gitignore | 2 +
configure.ac | 1 +
src/Makefile.am | 18 +++++-
src/dh-enum-types.c.template | 39 +++++++++++++
src/dh-enum-types.h.template | 27 +++++++++
src/dh-marshal.list | 1 +
src/dh-window.c | 129 +++++++++++++++++++++++++++---------------
src/dh-window.h | 13 ++++-
8 files changed, 182 insertions(+), 48 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index a392796..0f0810d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,4 +42,6 @@ libtool
/src/devhelp
/src/dh-marshal.c
/src/dh-marshal.h
+/src/dh-enum-types.c
+/src/dh-enum-types.h
/stamp-h1
diff --git a/configure.ac b/configure.ac
index b7fe5a4..7c4d53c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,6 +98,7 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Package name for gettext
AM_GLIB_GNU_GETTEXT
AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
+AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums)
AM_PATH_PYTHON([2.3],[],[no])
diff --git a/src/Makefile.am b/src/Makefile.am
index 4988b3d..89b6260 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,10 +8,14 @@ dh-marshal.c: dh-marshal.list
BUILT_SOURCES = \
dh-marshal.h \
dh-marshal.c \
+ dh-enum-types.h \
+ dh-enum-types.c \
$(NULL)
EXTRA_DIST = \
dh-marshal.list \
+ dh-enum-types.c.template \
+ dh-enum-types.h.template \
$(NULL)
AM_CPPFLAGS = \
@@ -44,8 +48,7 @@ devhelp_LDADD = \
lib_LTLIBRARIES = libdevhelp-1.la
-devhelpincludedir = $(includedir)/devhelp-1.0/devhelp
-devhelpinclude_HEADERS = \
+INST_H_FILES = \
dh-assistant.h \
dh-assistant-view.h \
dh-base.h \
@@ -56,9 +59,14 @@ devhelpinclude_HEADERS = \
dh-search.h \
dh-window.h
+devhelpincludedir = $(includedir)/devhelp-1.0/devhelp
+devhelpinclude_HEADERS = $(INST_H_FILES)
+
libdevhelp_1_la_SOURCES = \
dh-marshal.c \
dh-marshal.h \
+ dh-enum-types.c \
+ dh-enum-types.h \
dh-assistant.c \
dh-assistant-view.c \
dh-base.c \
@@ -98,6 +106,12 @@ libdevhelp_1_la_LDFLAGS = \
-export-symbols-regex ^dh_ \
$(ZLIB_LDFLAGS)
+dh-enum-types.h: dh-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS)
+ $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template dh-enum-types.h.template $(INST_H_FILES)) > $@
+
+dh-enum-types.c: dh-enum-types.c.template $(INST_H_FILES) $(GLIB_MKENUMS)
+ $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template dh-enum-types.c.template $(INST_H_FILES)) > $@
+
if HAVE_PLATFORM_OSX
conf_platform_sources = ige-conf-mac.c
libdevhelp_1_la_CPPFLAGS += -xobjective-c
diff --git a/src/dh-enum-types.c.template b/src/dh-enum-types.c.template
new file mode 100644
index 0000000..1b5957e
--- /dev/null
+++ b/src/dh-enum-types.c.template
@@ -0,0 +1,39 @@
+/*** BEGIN file-header ***/
+#include "dh-enum-types.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+ enum_name@_get_type (void)
+{
+ static GType the_type = 0;
+
+ if (the_type == 0)
+ {
+ static const G Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@,
+ "@VALUENAME@",
+ "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ the_type = g_ type@_register_static (
+ g_intern_static_string ("@EnumName@"),
+ values);
+ }
+ return the_type;
+}
+
+/*** END value-tail ***/
diff --git a/src/dh-enum-types.h.template b/src/dh-enum-types.h.template
new file mode 100644
index 0000000..fc97c74
--- /dev/null
+++ b/src/dh-enum-types.h.template
@@ -0,0 +1,27 @@
+/*** BEGIN file-header ***/
+#ifndef __DH_ENUM_TYPES_H__
+#define __DH_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* Enumerations from "@filename@" */
+
+/*** END file-production ***/
+
+/*** BEGIN enumeration-production ***/
+#define DH_TYPE_ ENUMSHORT@ (@enum_name _get_type())
+GType @enum_name _get_type (void) G_GNUC_CONST;
+
+/*** END enumeration-production ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* __DH_ENUM_TYPES_H__ */
+/*** END file-tail ***/
+
diff --git a/src/dh-marshal.list b/src/dh-marshal.list
index 0e021f4..969dff3 100644
--- a/src/dh-marshal.list
+++ b/src/dh-marshal.list
@@ -2,3 +2,4 @@ VOID:BOOLEAN
VOID:POINTER
VOID:STRING
BOOLEAN:STRING
+VOID:STRING,FLAGS
diff --git a/src/dh-window.c b/src/dh-window.c
index 73044af..f5ebb6b 100644
--- a/src/dh-window.c
+++ b/src/dh-window.c
@@ -34,6 +34,8 @@
#include "dh-search.h"
#include "dh-window.h"
#include "dh-util.h"
+#include "dh-marshal.h"
+#include "dh-enum-types.h"
#include "eggfindbar.h"
#include "ige-conf.h"
@@ -57,6 +59,13 @@ struct _DhWindowPriv {
GtkActionGroup *action_group;
};
+enum {
+ OPEN_LINK,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = { 0 };
+
static guint tab_accel_keys[] = {
GDK_1, GDK_2, GDK_3, GDK_4, GDK_5,
GDK_6, GDK_7, GDK_8, GDK_9, GDK_0
@@ -118,8 +127,9 @@ static void window_findbar_close_cb (GtkWidget *widget,
DhWindow *window);
static GtkWidget * window_new_tab_label (DhWindow *window,
const gchar *label);
-static void window_open_new_tab (DhWindow *window,
- const gchar *location);
+static int window_open_new_tab (DhWindow *window,
+ const gchar *location,
+ gboolean switch_focus);
static WebKitWebView *window_get_active_web_view (DhWindow *window);
static void window_update_title (DhWindow *window,
WebKitWebView *web_view,
@@ -154,7 +164,7 @@ window_activate_new_tab (GtkAction *action,
priv = window->priv;
- window_open_new_tab (window, NULL);
+ window_open_new_tab (window, NULL, TRUE);
}
static void
@@ -379,6 +389,24 @@ window_activate_about (GtkAction *action,
NULL);
}
+static void
+window_open_link_cb (DhWindow *window,
+ const char *location,
+ DhOpenLinkFlags flags)
+{
+ DhWindowPriv *priv;
+ priv = window->priv;
+
+ if (flags & DH_OPEN_LINK_NEW_TAB) {
+ window_open_new_tab (window, location, FALSE);
+ }
+ else if (flags & DH_OPEN_LINK_NEW_WINDOW) {
+ GtkWidget *new_window;
+ new_window = dh_base_new_window (priv->base);
+ gtk_widget_show (new_window);
+ }
+}
+
static const GtkActionEntry actions[] = {
{ "FileMenu", NULL, N_("_File") },
{ "EditMenu", NULL, N_("_Edit") },
@@ -462,6 +490,18 @@ dh_window_class_init (DhWindowClass *klass)
object_class->finalize = window_finalize;
+ signals[OPEN_LINK] =
+ g_signal_new ("open-link",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (DhWindowClass, open_link),
+ NULL, NULL,
+ _dh_marshal_VOID__STRING_FLAGS,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_STRING,
+ DH_TYPE_OPEN_LINK_FLAGS);
+
gtk_rc_parse_string ("style \"devhelp-tab-close-button-style\"\n"
"{\n"
"GtkWidget::focus-padding = 0\n"
@@ -505,6 +545,11 @@ dh_window_init (DhWindow *window)
gtk_container_add (GTK_CONTAINER (window), priv->main_box);
+ g_signal_connect (window,
+ "open-link",
+ G_CALLBACK (window_open_link_cb),
+ window);
+
g_signal_connect (priv->manager,
"add-widget",
G_CALLBACK (window_manager_add_widget),
@@ -780,14 +825,16 @@ window_populate (DhWindow *window)
gtk_widget_show_all (priv->hpaned);
- window_open_new_tab (window, NULL);
+ window_open_new_tab (window, NULL, TRUE);
}
-static WebKitNavigationResponse
-window_web_view_navigation_requested_cb (WebKitWebView *web_view,
- WebKitWebFrame *frame,
- WebKitNetworkRequest *request,
- DhWindow *window)
+static gboolean
+window_web_view_navigation_policy_decision_requested (WebKitWebView *web_view,
+ WebKitWebFrame *frame,
+ WebKitNetworkRequest *request,
+ WebKitWebNavigationAction *navigation_action,
+ WebKitWebPolicyDecision *policy_decision,
+ DhWindow *window)
{
DhWindowPriv *priv;
const char *uri;
@@ -795,25 +842,29 @@ window_web_view_navigation_requested_cb (WebKitWebView *web_view,
priv = window->priv;
uri = webkit_network_request_get_uri (request);
- if (strcmp (uri, "about:blank") == 0) {
- return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
+
+ if (webkit_web_navigation_action_get_button (navigation_action) == 2) { /* middle click */
+ webkit_web_policy_decision_ignore (policy_decision);
+ g_signal_emit (window, signals[OPEN_LINK], 0, uri, DH_OPEN_LINK_NEW_TAB);
+ return TRUE;
}
if (strncmp (uri, "file://", 7) != 0) {
+ webkit_web_policy_decision_ignore (policy_decision);
gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, NULL);
- return WEBKIT_NAVIGATION_RESPONSE_IGNORE;
+ return TRUE;
}
- if (web_view == window_get_active_web_view (window)) {
- const gchar *uri;
-
- uri = webkit_network_request_get_uri (request);
+ if (strcmp (uri, "about:blank") == 0) {
+ return FALSE;
+ }
+ if (web_view == window_get_active_web_view (window)) {
dh_book_tree_select_uri (DH_BOOK_TREE (priv->book_tree), uri);
window_check_history (window, web_view);
}
- return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
+ return FALSE;
}
static void
@@ -829,21 +880,10 @@ window_tree_link_selected_cb (GObject *ignored,
view = window_get_active_web_view (window);
- /* Block so we don't try to sync the tree when we have already
- * clicked in it.
- */
- g_signal_handlers_block_by_func (view,
- window_web_view_navigation_requested_cb,
- window);
-
uri = dh_link_get_uri (link);
webkit_web_view_open (view, uri);
g_free (uri);
- g_signal_handlers_unblock_by_func (view,
- window_web_view_navigation_requested_cb,
- window);
-
window_check_history (window, view);
}
@@ -908,9 +948,11 @@ window_web_view_title_changed_cb (WebKitWebView *web_view,
const gchar *title,
DhWindow *window)
{
- window_update_title (window,
- window_get_active_web_view (window),
- title);
+ if (web_view == window_get_active_web_view (window)) {
+ window_update_title (window, web_view, title);
+ }
+
+ window_tab_set_title (window, web_view, title);
}
static gboolean
@@ -1057,9 +1099,10 @@ window_web_view_tab_accel_cb (GtkAccelGroup *accel_group,
}
}
-static void
+static int
window_open_new_tab (DhWindow *window,
- const gchar *location)
+ const gchar *location,
+ gboolean switch_focus)
{
DhWindowPriv *priv;
GtkWidget *view;
@@ -1104,16 +1147,10 @@ window_open_new_tab (DhWindow *window,
G_CALLBACK (window_web_view_button_press_event_cb),
window);
- g_signal_connect (view, "navigation-requested",
- G_CALLBACK (window_web_view_navigation_requested_cb),
+ g_signal_connect (view, "navigation-policy-decision-requested",
+ G_CALLBACK (window_web_view_navigation_policy_decision_requested),
window);
- /*
- g_signal_connect (view, "open-new-tab",
- G_CALLBACK (window_web_view_open_new_tab_cb),
- window);
- */
-
num = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
scrolled_window, NULL);
@@ -1127,12 +1164,16 @@ window_open_new_tab (DhWindow *window,
}
if (location) {
- webkit_web_view_open (WEBKIT_WEB_VIEW (view), location);
+ webkit_web_view_load_uri (WEBKIT_WEB_VIEW (view), location);
} else {
webkit_web_view_open (WEBKIT_WEB_VIEW (view), "about:blank");
}
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), num);
+ if (switch_focus) {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), num);
+ }
+
+ return num;
}
#ifndef GDK_WINDOWING_QUARTZ
@@ -1264,8 +1305,6 @@ window_update_title (DhWindow *window,
web_view_title = webkit_web_frame_get_title (web_frame);
}
- window_tab_set_title (window, web_view, web_view_title);
-
if (web_view_title && *web_view_title == '\0') {
web_view_title = NULL;
}
diff --git a/src/dh-window.h b/src/dh-window.h
index 969c487..8003806 100644
--- a/src/dh-window.h
+++ b/src/dh-window.h
@@ -39,13 +39,24 @@ typedef struct _DhWindow DhWindow;
typedef struct _DhWindowClass DhWindowClass;
typedef struct _DhWindowPriv DhWindowPriv;
+typedef enum
+{
+ DH_OPEN_LINK_NEW_WINDOW = 1 << 0,
+ DH_OPEN_LINK_NEW_TAB = 1 << 1
+} DhOpenLinkFlags;
+
struct _DhWindow {
GtkWindow parent_instance;
- DhWindowPriv *priv;
+ DhWindowPriv *priv;
};
struct _DhWindowClass {
GtkWindowClass parent_class;
+
+ /* Signals */
+ void (*open_link) (DhWindow *window,
+ const char *location,
+ DhOpenLinkFlags flags);
};
GType dh_window_get_type (void) G_GNUC_CONST;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]