summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Catanzaro <mcatanzaro@gnome.org>2016-11-15 20:47:52 -0600
committerMichael Catanzaro <mcatanzaro@gnome.org>2016-11-20 19:52:09 -0600
commit2cf6d7b0b7599d402f2006840d39b13271b5dcc8 (patch)
tree5ac0dfd48a5e401f94ac152b36e21c8f4a3ecf6e
parentfca037911c2c74ce0c336c871dceb368207d596c (diff)
downloadepiphany-2cf6d7b0b7599d402f2006840d39b13271b5dcc8.tar.gz
window: fix web view receiving events twice
The current code propagates the event to the web view, then chains up if the web view doesn't handle the event. But chaining up causes GtkWindow to propagate the event to the web view yet again. Surely we never want to do that, so stop doing it. I think there must be some other bug here, though, in WebKit, that causes WebKit to sometimes do something with the event but then propagate anyway, which is wrong. If I'm right, then WebKit is unfortunately still broken, but this works around it in Epiphany and is the right thing to do anyway, since sending the same event to the web view twice is nonsense regardless of whether the web view propagates it or not. https://bugzilla.gnome.org/show_bug.cgi?id=764653
-rw-r--r--src/ephy-window.c75
1 files changed, 18 insertions, 57 deletions
diff --git a/src/ephy-window.c b/src/ephy-window.c
index faf369405..0fb186d67 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -794,67 +794,28 @@ static gboolean
ephy_window_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
- EphyWindow *window = EPHY_WINDOW (widget);
- GtkWidget *focus_widget;
- gboolean shortcircuit = FALSE, force_chain = FALSE, handled = FALSE;
- guint modifier = event->state & gtk_accelerator_get_default_mod_mask ();
-
- /* 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.
- *
- * We achieve this by first evaluating the event to see if it's important, and if
- * so, we get the focus widget and attempt to get the widget to handle that event.
- * If the widget does handle it, we're done (unless force_chain is true, in which
- * case the event is handled as normal in addition to being sent to the focus
- * widget), otherwise the event follows the normal handling path.
- */
-
- if ((event->state & GDK_CONTROL_MASK ||
- event->state & GDK_MOD1_MASK ||
- event->state & GDK_SHIFT_MASK) &&
- event->length > 0) {
- /* Pass (CTRL|ALT|SHIFT)+letter characters to the widget */
- shortcircuit = TRUE;
- } else if (event->keyval == GDK_KEY_Escape && modifier == 0) {
- /* Always pass Escape to both the widget, and the parent */
- shortcircuit = TRUE;
- force_chain = TRUE;
- } else if (window->key_theme_is_emacs &&
- (modifier == GDK_CONTROL_MASK) &&
- event->length > 0 &&
- /* But don't pass Ctrl+Enter twice */
- event->keyval != GDK_KEY_Return &&
- event->keyval != GDK_KEY_KP_Enter &&
- event->keyval != GDK_KEY_ISO_Enter) {
- /* Pass CTRL+letter characters to the widget */
- shortcircuit = TRUE;
- }
-
- if (shortcircuit) {
- focus_widget = gtk_window_get_focus (GTK_WINDOW (window));
-
- if (GTK_IS_WIDGET (focus_widget)) {
- handled = gtk_widget_event (focus_widget,
- (GdkEvent *)event);
- }
+ EphyWebView *view;
- if (handled && !force_chain) {
- return handled;
- }
+ view = ephy_embed_get_web_view (EPHY_WINDOW (widget)->active_embed);
+ if (gtk_window_get_focus (GTK_WINDOW (widget)) != GTK_WIDGET (view)) {
+ if (ephy_window_bound_accels (widget, event))
+ return GDK_EVENT_STOP;
+ return GTK_WIDGET_CLASS (ephy_window_parent_class)->key_press_event (widget, event);
}
- /* Handle accelerators that we want bound, but aren't associated with
- * an action */
- if (ephy_window_bound_accels (widget, event)) {
- return TRUE;
+ /* GtkWindow's key press handler first calls gtk_window_activate_key,
+ * then gtk_window_propagate_key_event. We want to do the opposite,
+ * because we want to give webpages the chance to override most
+ * Epiphany shortcuts. For example, Ctrl+I in Google Docs should
+ * italicize your text and not open a new incognito window. So:
+ * first propagate the event to the web view. Next, try
+ * accelerators only if the web view did not handle the event.
+ */
+ if (!gtk_window_propagate_key_event (GTK_WINDOW (widget), event)) {
+ if (!gtk_window_activate_key (GTK_WINDOW (widget), event))
+ ephy_window_bound_accels (widget, event);
}
-
- return GTK_WIDGET_CLASS (ephy_window_parent_class)->key_press_event (widget, event);
+ return GDK_EVENT_STOP;
}
static gboolean