aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@mail.utexas.edu>2005-10-26 14:27:34 +0800
committerPhilip Langdale <philipl@src.gnome.org>2005-10-26 14:27:34 +0800
commit923b47f0d09b21fcfb2a131c08b4e313a4d58c05 (patch)
tree15b47f9877c31068df1d422e97a39dd3de92c637 /src
parent12a8233cc88965fa9aee22095cb2005eb4f57532 (diff)
downloadgsoc2013-epiphany-923b47f0d09b21fcfb2a131c08b4e313a4d58c05.tar.gz
gsoc2013-epiphany-923b47f0d09b21fcfb2a131c08b4e313a4d58c05.tar.zst
gsoc2013-epiphany-923b47f0d09b21fcfb2a131c08b4e313a4d58c05.zip
src/ephy-link-action.c
2005-10-25 Philip Langdale <philipl@mail.utexas.edu> * src/ephy-link-action.c * src/ephy-link-action.h: (proxy_button_press_event_cb), (proxy_button_release_event_cb), (proxy_drag_begin_cb), (ephy_link_action_connect_proxy), (ephy_link_action_disconnect_proxy), (ephy_link_action_class_init), (ephy_link_action_init): Well, that didn't last long. Turns out this was a solved problem in EphyBookmarkAction but no one pointed it out until just now. Using gtk_button_pressed/released fixes everything.
Diffstat (limited to 'src')
-rw-r--r--src/ephy-link-action.c67
-rw-r--r--src/ephy-link-action.h4
-rw-r--r--src/ephy-window.c156
3 files changed, 170 insertions, 57 deletions
diff --git a/src/ephy-link-action.c b/src/ephy-link-action.c
index da627f451..f5be71675 100644
--- a/src/ephy-link-action.c
+++ b/src/ephy-link-action.c
@@ -32,17 +32,23 @@
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkmenutoolbutton.h>
-#define EPHY_LINK_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LINK_ACTION, EphyLinkActionPrivate))
+static GObjectClass *parent_class = NULL;
-struct _EphyLinkActionPrivate
+static gboolean
+proxy_button_press_event_cb (GtkButton *button,
+ GdkEventButton *event,
+ EphyLinkAction *action)
{
- gboolean ignore_next_middle_click;
-};
+ if (event->button == 2)
+ {
+ gtk_button_pressed(button);
+ }
-static GObjectClass *parent_class = NULL;
+ return FALSE;
+}
static gboolean
-proxy_button_release_event_cb (GtkWidget *widget,
+proxy_button_release_event_cb (GtkButton *button,
GdkEventButton *event,
EphyLinkAction *action)
{
@@ -53,37 +59,12 @@ proxy_button_release_event_cb (GtkWidget *widget,
*/
if (event->button == 2)
{
- if (!action->priv->ignore_next_middle_click)
- {
- gtk_action_activate (GTK_ACTION (action));
- }
- action->priv->ignore_next_middle_click = FALSE;
+ gtk_button_released(button);
}
return FALSE;
}
-static void
-proxy_drag_begin_cb (GtkWidget *widget,
- GdkDragContext *context,
- EphyLinkAction *action)
-{
- GdkEventMotion *event;
- GdkEvent *base_event = gtk_get_current_event ();
-
- g_return_if_fail (base_event != NULL);
- g_return_if_fail (base_event->type == GDK_MOTION_NOTIFY);
-
- event = (GdkEventMotion *) base_event;
-
- if (event->state & GDK_BUTTON2_MASK)
- {
- action->priv->ignore_next_middle_click = TRUE;
- }
-
- gdk_event_free(base_event);
-}
-
static GtkWidget *
get_event_widget (GtkWidget *proxy)
{
@@ -137,12 +118,12 @@ ephy_link_action_connect_proxy (GtkAction *action, GtkWidget *proxy)
widget = get_event_widget(proxy);
if (widget)
{
+ 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);
- g_signal_connect (widget, "drag-begin",
- G_CALLBACK (proxy_drag_begin_cb),
- action);
}
GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
@@ -159,10 +140,10 @@ ephy_link_action_disconnect_proxy (GtkAction *action, GtkWidget *proxy)
if (widget)
{
g_signal_handlers_disconnect_by_func (widget,
- G_CALLBACK (proxy_button_release_event_cb),
+ G_CALLBACK (proxy_button_press_event_cb),
action);
g_signal_handlers_disconnect_by_func (widget,
- G_CALLBACK (proxy_drag_begin_cb),
+ G_CALLBACK (proxy_button_release_event_cb),
action);
}
@@ -172,22 +153,12 @@ ephy_link_action_disconnect_proxy (GtkAction *action, GtkWidget *proxy)
static void
ephy_link_action_class_init (EphyLinkActionClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkActionClass *action_class = GTK_ACTION_CLASS (class);
parent_class = g_type_class_peek_parent (class);
action_class->connect_proxy = ephy_link_action_connect_proxy;
action_class->disconnect_proxy = ephy_link_action_disconnect_proxy;
-
- g_type_class_add_private (object_class, sizeof (EphyLinkActionPrivate));
-}
-
-static void
-ephy_link_action_init (EphyLinkAction *action)
-{
- action->priv = EPHY_LINK_ACTION_GET_PRIVATE (action);
- action->priv->ignore_next_middle_click = FALSE;
}
GType
@@ -207,7 +178,7 @@ ephy_link_action_get_type (void)
NULL, /* class_data */
sizeof (EphyLinkAction),
0, /* n_preallocs */
- (GInstanceInitFunc) ephy_link_action_init
+ NULL /* instance_init */
};
static const GInterfaceInfo link_info =
{
diff --git a/src/ephy-link-action.h b/src/ephy-link-action.h
index 3bccd157b..7dbc5794c 100644
--- a/src/ephy-link-action.h
+++ b/src/ephy-link-action.h
@@ -41,7 +41,6 @@ G_BEGIN_DECLS
#define EPHY_LINK_ACTION_GROUP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_LINK_ACTION_GROUP, EphyLinkActionGroupClass))
typedef struct _EphyLinkAction EphyLinkAction;
-typedef struct _EphyLinkActionPrivate EphyLinkActionPrivate;
typedef struct _EphyLinkActionClass EphyLinkActionClass;
typedef struct _EphyLinkActionGroup EphyLinkActionGroup;
@@ -50,9 +49,6 @@ typedef struct _EphyLinkActionGroupClass EphyLinkActionGroupClass;
struct _EphyLinkAction
{
GtkAction parent_instance;
-
- /*< private >*/
- EphyLinkActionPrivate *priv;
};
struct _EphyLinkActionClass
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 9d9948e2b..22f01e7e5 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -106,6 +106,10 @@ static void sync_tab_security (EphyTab *tab,
static void sync_tab_zoom (EphyTab *tab,
GParamSpec *pspec,
EphyWindow *window);
+static void gtk_key_theme_changed_cb (GtkSettings *settings,
+ GParamSpec *pspec,
+ gpointer dummy);
+
static const GtkActionEntry ephy_menu_entries [] = {
@@ -375,6 +379,7 @@ static const struct
};
#endif /* HAVE_X11_XF86KEYSYM_H */
+
#define CONF_LOCKDOWN_HIDE_MENUBAR "/apps/epiphany/lockdown/hide_menubar"
#define CONF_DESKTOP_BG_PICTURE "/desktop/gnome/background/picture_filename"
@@ -440,6 +445,9 @@ enum
SENS_FLAG_NAVIGATION = 1 << 4
};
+/* Static class variables */
+static gboolean key_theme_is_emacs = FALSE;
+
static GObjectClass *parent_class = NULL;
GType
@@ -684,17 +692,124 @@ menubar_deactivate_cb (GtkWidget *menubar,
sync_chromes_visibility (window);
}
-static gboolean
+static gboolean
ephy_window_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
- EphyWindow *window = EPHY_WINDOW (widget);
+ EphyWindow *window = EPHY_WINDOW(widget);
GtkWidget *menubar;
guint keyval = GDK_F10;
- guint modifier = 0;
guint mask = gtk_accelerator_get_default_mod_mask ();
char *accel = NULL;
+ /* In an attempt to get the mozembed playing nice with things like emacs keybindings
+ * we are passing important events to the focused child widget before letting the window's
+ * base handler see them. This is *completely against* stated gtk2 policy but the
+ * 'correct' behaviour is exceptionally useless. We need to keep an eye out for
+ * unexpected consequences of this decision. IME's should be a high concern, but
+ * considering that the IME folks complained about the upside-down event propagation
+ * rules, we might be doing them a favour.
+ */
+
+ gboolean shortcircuit = FALSE;
+ gboolean force_chain = FALSE;
+ gboolean handled = FALSE;
+ guint modifier = event->state & gtk_accelerator_get_default_mod_mask ();
+ guint i;
+
+ if (event->keyval == GDK_Escape)
+ {
+ /* Always pass Escape to both the widget, and the parent */
+ shortcircuit = TRUE;
+ force_chain = TRUE;
+ }
+ else if (key_theme_is_emacs &&
+ (modifier == GDK_CONTROL_MASK) && event->length > 0 &&
+ /* But don't pass Ctrl+Enter twice */
+ event->keyval != GDK_Return)
+ {
+ /* Pass CTRL+letter characters to the widget */
+ shortcircuit = TRUE;
+ }
+
+ if (shortcircuit)
+ {
+ GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
+
+ if (GTK_IS_WIDGET (widget))
+ {
+ handled = gtk_widget_event (widget, (GdkEvent*)event);
+ }
+
+ if (handled && !force_chain)
+ {
+ return handled;
+ }
+ }
+
+#if 0
+ /* Handle accelerators that we want bound, but aren't associated with
+ * an action */
+ for (i = 0; i < G_N_ELEMENTS (extra_keybindings); i++)
+ {
+ if (modifier == extra_keybindings[i].modifier &&
+ event->keyval == extra_keybindings[i].keyval)
+ {
+ GtkAction * action = gtk_action_group_get_action
+ (priv->action_group,
+ extra_keybindings[i].action);
+ gtk_action_activate (action);
+ return TRUE;
+ }
+ }
+#endif
+
+ /* Don't activate menubar in ppv mode, or in lockdown mode */
+ if (window->priv->ppv_mode || eel_gconf_get_boolean (CONF_LOCKDOWN_HIDE_MENUBAR))
+ {
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+ }
+
+ g_object_get (gtk_widget_get_settings (widget),
+ "gtk-menu-bar-accel", &accel,
+ NULL);
+
+ if (accel != NULL)
+ {
+ gtk_accelerator_parse (accel, &keyval, &modifier);
+
+ g_free (accel);
+ }
+
+ /* Show and activate the menubar, if it isn't visible */
+ if (event->keyval == keyval && (event->state & mask) == (modifier & mask))
+ {
+ menubar = gtk_ui_manager_get_widget (window->priv->manager, "/menubar");
+ g_return_val_if_fail (menubar != NULL , FALSE);
+
+ if (!GTK_WIDGET_VISIBLE (menubar))
+ {
+ g_signal_connect (menubar, "deactivate",
+ G_CALLBACK (menubar_deactivate_cb), window);
+
+ gtk_widget_show (menubar);
+ gtk_menu_shell_select_first (GTK_MENU_SHELL (menubar), FALSE);
+
+ return TRUE;
+ }
+ }
+
+ return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+}
+
+#if 0
+static gboolean
+ephy_window_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ EphyWindow *window = EPHY_WINDOW (widget);
+ GtkWidget *menubar;
+
/* Handle ESC here instead of an action callback, so we can
* handle it differently in the location entry, and we can
* stop even when the page is not loading (to stop animations).
@@ -761,6 +876,7 @@ ephy_window_key_press_event (GtkWidget *widget,
return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
}
+#endif
static gboolean
ephy_window_delete_event (GtkWidget *widget,
@@ -1344,8 +1460,6 @@ sync_tab_navigation (EphyTab *tab,
EphyWindow *window)
{
EphyTabNavigationFlags flags;
- GtkActionGroup *action_group;
- GtkAction *action;
gboolean up = FALSE, back = FALSE, forward = FALSE;
if (window->priv->closing) return;
@@ -2754,6 +2868,8 @@ ephy_window_link_iface_init (EphyLinkIface *iface)
static void
ephy_window_class_init (EphyWindowClass *klass)
{
+ GtkSettings *settings;
+
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
@@ -2808,6 +2924,14 @@ ephy_window_class_init (EphyWindowClass *klass)
G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (object_class, sizeof (EphyWindowPrivate));
+
+ /* initialize the listener for the key theme */
+ settings = gtk_settings_get_default();
+ g_signal_connect (settings,
+ "notify::gtk-key-theme-name",
+ G_CALLBACK (gtk_key_theme_changed_cb),
+ NULL);
+ gtk_key_theme_changed_cb (settings, NULL, NULL);
}
static void
@@ -3576,6 +3700,27 @@ ephy_window_view_popup_windows_cb (GtkAction *action,
g_object_set (G_OBJECT (tab), "popups-allowed", allow, NULL);
}
+static void
+gtk_key_theme_changed_cb (GtkSettings *settings,
+ GParamSpec *pspec,
+ gpointer dummy)
+{
+ gchar *key_theme_name;
+
+ g_object_get (settings,
+ "gtk-key-theme-name", &key_theme_name,
+ NULL);
+ if (key_theme_name && g_ascii_strcasecmp (key_theme_name, "Emacs") == 0)
+ {
+ key_theme_is_emacs = TRUE;
+ }
+ else
+ {
+ key_theme_is_emacs = FALSE;
+ }
+ g_free (key_theme_name);
+}
+
/**
* ephy_window_get_is_popup:
* @window: an #EphyWindow
@@ -3624,3 +3769,4 @@ ephy_window_get_context_event (EphyWindow *window)
return window->priv->context_event;
}
+