[Xfce4-commits] <midori:master> Support keyboard hotkeys that GTK+ considers invalid

Christian Dywan noreply at xfce.org
Wed Nov 4 14:38:03 CET 2009


Updating branch refs/heads/master
         to d0215c4032f4301e6b6068febc95d2f0fbc167b1 (commit)
       from 3a491840f5358037adf705db7ac43ae3ffebcfd4 (commit)

commit d0215c4032f4301e6b6068febc95d2f0fbc167b1
Author: Christian Dywan <christian at twotoasts.de>
Date:   Tue Nov 3 23:47:33 2009 +0100

    Support keyboard hotkeys that GTK+ considers invalid
    
    We re-implement the usual key handling by overriding the key press
    handler, emulating the according steps but leaving out the
    validation that normally rejects certain combinations.
    
    Single key hotkeys work unless an entry is focussed, in which case
    the entry receives the input, and Control+Tab works as well.
    
    The shortcuts extension is adjusted to accept any hotkeys.

 extensions/shortcuts.c  |    1 +
 midori/midori-browser.c |   35 +++++++++++++++++++++++++++++++++++
 midori/sokoke.c         |   38 ++++++++++++++++++++++++++++++++++++++
 midori/sokoke.h         |    4 ++++
 4 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/extensions/shortcuts.c b/extensions/shortcuts.c
index e555b97..9791dc8 100644
--- a/extensions/shortcuts.c
+++ b/extensions/shortcuts.c
@@ -88,6 +88,7 @@ shortcuts_preferences_render_accel (GtkTreeViewColumn* column,
                 g_object_set (renderer,
                               "accel-key", key.accel_key,
                               "accel-mods", key.accel_mods,
+                              "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
                               NULL);
             else
                 g_object_set (renderer, "text", _("None"), NULL);
diff --git a/midori/midori-browser.c b/midori/midori-browser.c
index f9b18ab..e1ed1b7 100644
--- a/midori/midori-browser.c
+++ b/midori/midori-browser.c
@@ -1684,9 +1684,41 @@ _midori_browser_quit (MidoriBrowser* browser)
     /* Nothing to do */
 }
 
+static gboolean
+midori_browser_key_press_event (GtkWidget*   widget,
+                                GdkEventKey* event)
+{
+    GtkWindow* window = GTK_WINDOW (widget);
+    GtkWidget* focus = gtk_window_get_focus (window);
+    GtkWidgetClass* widget_class;
+    gboolean priority = GTK_IS_EDITABLE (focus) || GTK_IS_TEXT_VIEW (focus)
+                     || WEBKIT_IS_WEB_VIEW (focus);
+
+    if (priority && !event->state && gtk_window_propagate_key_event (window, event))
+        return TRUE;
+
+    if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))
+        if (sokoke_window_activate_key (window, event))
+            return TRUE;
+
+    if (gtk_window_propagate_key_event (window, event))
+        return TRUE;
+
+    if (!(event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
+        if (sokoke_window_activate_key (window, event))
+            return TRUE;
+
+    if (!priority && event->state && gtk_window_propagate_key_event (window, event))
+        return TRUE;
+
+    widget_class = g_type_class_peek_static (g_type_parent (GTK_TYPE_WINDOW));
+    return widget_class->key_press_event (widget, event);
+}
+
 static void
 midori_browser_class_init (MidoriBrowserClass* class)
 {
+    GtkWidgetClass* gtkwidget_class;
     GObjectClass* gobject_class;
     GParamFlags flags;
 
@@ -1844,6 +1876,9 @@ midori_browser_class_init (MidoriBrowserClass* class)
     class->activate_action = _midori_browser_activate_action;
     class->quit = _midori_browser_quit;
 
+    gtkwidget_class = GTK_WIDGET_CLASS (class);
+    gtkwidget_class->key_press_event = midori_browser_key_press_event;
+
     gobject_class = G_OBJECT_CLASS (class);
     gobject_class->dispose = midori_browser_dispose;
     gobject_class->finalize = midori_browser_finalize;
diff --git a/midori/sokoke.c b/midori/sokoke.c
index cc50277..e87d797 100644
--- a/midori/sokoke.c
+++ b/midori/sokoke.c
@@ -1260,3 +1260,41 @@ sokoke_replace_variables (const gchar* template,
 
     return result;
 }
+
+/**
+ * sokoke_window_activate_key:
+ * @window: a #GtkWindow
+ * @event: a #GdkEventKey
+ *
+ * Attempts to activate they key from the event, much
+ * like gtk_window_activate_key(), including keys
+ * that gtk_accelerator_valid() considers invalid.
+ *
+ * Return value: %TRUE on success
+ **/
+gboolean
+sokoke_window_activate_key (GtkWindow*   window,
+                            GdkEventKey* event)
+{
+    gchar *accel_name;
+    GQuark accel_quark;
+    GObject* object;
+    GSList *slist;
+
+    if (gtk_window_activate_key (window, event))
+        return TRUE;
+
+    /* We don't use gtk_accel_groups_activate because it refuses to
+        activate anything that gtk_accelerator_valid doesn't like. */
+    accel_name = gtk_accelerator_name (event->keyval, (event->state & gtk_accelerator_get_default_mod_mask ()));
+    accel_quark = g_quark_from_string (accel_name);
+    g_free (accel_name);
+    object = G_OBJECT (window);
+
+    for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)
+        if (gtk_accel_group_activate (slist->data, accel_quark,
+                                      object, event->keyval, event->state))
+            return TRUE;
+
+    return FALSE;
+}
diff --git a/midori/sokoke.h b/midori/sokoke.h
index 5074d74..1039a70 100644
--- a/midori/sokoke.h
+++ b/midori/sokoke.h
@@ -172,4 +172,8 @@ gchar*
 sokoke_replace_variables                (const gchar* template,
                                          const gchar* variable_first, ...);
 
+gboolean
+sokoke_window_activate_key              (GtkWindow*      window,
+                                         GdkEventKey*    event);
+
 #endif /* !__SOKOKE_H__ */



More information about the Xfce4-commits mailing list