From 923b47f0d09b21fcfb2a131c08b4e313a4d58c05 Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Wed, 26 Oct 2005 06:27:34 +0000 Subject: src/ephy-link-action.c 2005-10-25 Philip Langdale * 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. --- src/ephy-link-action.c | 67 ++++++--------------- src/ephy-link-action.h | 4 -- src/ephy-window.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 170 insertions(+), 57 deletions(-) (limited to 'src') 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 #include -#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; } + -- cgit v1.2.3