[gtk+] shortcuts: Follow changes of accels



commit 50f041bc5750e615aef8ba81ecc7614542989143
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Apr 17 13:38:51 2016 -0400

    shortcuts: Follow changes of accels
    
    Add a way to associate a detailed action name with a shortcut.
    If the action name is set, update the accelerator whenever
    accels change on the window that the shortcuts window is
    associated with.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=764975

 gtk/Makefile.am                   |    2 +
 gtk/gtkapplicationwindow.c        |    3 ++
 gtk/gtkshortcutsshortcut.c        |   64 +++++++++++++++++++++++++++++++++++++
 gtk/gtkshortcutsshortcutprivate.h |   37 +++++++++++++++++++++
 gtk/gtkshortcutswindow.c          |   62 +++++++++++++++++++++++++++++++++++-
 gtk/gtkshortcutswindowprivate.h   |   38 ++++++++++++++++++++++
 6 files changed, 205 insertions(+), 1 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 90b3235..c9f3430 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -540,6 +540,8 @@ gtk_private_h_sources =             \
        gtkselectionprivate.h   \
        gtksettingsprivate.h    \
        gtkshortcutlabelprivate.h       \
+       gtkshortcutswindowprivate.h     \
+       gtkshortcutsshortcutprivate.h   \
        gtksidebarrowprivate.h  \
        gtksizegroup-private.h  \
        gtksizerequestcacheprivate.h    \
diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c
index f921a3d..62d133a 100644
--- a/gtk/gtkapplicationwindow.c
+++ b/gtk/gtkapplicationwindow.c
@@ -28,6 +28,7 @@
 #include "gtkmenubar.h"
 #include "gtkintl.h"
 #include "gtksettings.h"
+#include "gtkshortcutswindowprivate.h"
 
 #ifdef HAVE_GIO_UNIX
 #include <gio/gdesktopappinfo.h>
@@ -1001,6 +1002,8 @@ gtk_application_window_set_help_overlay (GtkApplicationWindow *window,
 
   gtk_window_set_modal (GTK_WINDOW (help_overlay), TRUE);
   gtk_window_set_transient_for (GTK_WINDOW (help_overlay), GTK_WINDOW (window));
+  gtk_shortcuts_window_set_window (help_overlay, GTK_WINDOW (window));
+
   g_signal_connect (help_overlay, "delete-event",
                     G_CALLBACK (gtk_widget_hide_on_delete), NULL);
 
diff --git a/gtk/gtkshortcutsshortcut.c b/gtk/gtkshortcutsshortcut.c
index 018322c..01df8b9 100644
--- a/gtk/gtkshortcutsshortcut.c
+++ b/gtk/gtkshortcutsshortcut.c
@@ -21,6 +21,7 @@
 #include "gtkshortcutsshortcut.h"
 
 #include "gtkshortcutlabelprivate.h"
+#include "gtkshortcutswindowprivate.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 
@@ -49,6 +50,7 @@ struct _GtkShortcutsShortcut
   gboolean subtitle_set;
   gboolean icon_set;
   GtkTextDirection direction;
+  gchar *action_name;
   GtkShortcutType  shortcut_type;
 };
 
@@ -71,6 +73,7 @@ enum {
   PROP_TITLE_SIZE_GROUP,
   PROP_DIRECTION,
   PROP_SHORTCUT_TYPE,
+  PROP_ACTION_NAME,
   LAST_PROP
 };
 
@@ -313,6 +316,16 @@ gtk_shortcuts_shortcut_set_type (GtkShortcutsShortcut *self,
 }
 
 static void
+gtk_shortcuts_shortcut_set_action_name (GtkShortcutsShortcut *self,
+                                        const gchar          *action_name)
+{
+  g_free (self->action_name);
+  self->action_name = g_strdup (action_name);
+
+  g_object_notify (G_OBJECT (self), "action-name");
+}
+
+static void
 gtk_shortcuts_shortcut_get_property (GObject    *object,
                                      guint       prop_id,
                                      GValue     *value,
@@ -359,6 +372,10 @@ gtk_shortcuts_shortcut_get_property (GObject    *object,
       g_value_set_enum (value, self->shortcut_type);
       break;
 
+    case PROP_ACTION_NAME:
+      g_value_set_string (value, self->action_name);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -414,6 +431,10 @@ gtk_shortcuts_shortcut_set_property (GObject      *object,
       gtk_shortcuts_shortcut_set_type (self, g_value_get_enum (value));
       break;
 
+    case PROP_ACTION_NAME:
+      gtk_shortcuts_shortcut_set_action_name (self, g_value_get_string (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -427,6 +448,7 @@ gtk_shortcuts_shortcut_finalize (GObject *object)
 
   g_clear_object (&self->accel_size_group);
   g_clear_object (&self->title_size_group);
+  g_free (self->action_name);
 
   G_OBJECT_CLASS (gtk_shortcuts_shortcut_parent_class)->finalize (object);
 }
@@ -444,6 +466,30 @@ gtk_shortcuts_shortcut_child_type (GtkContainer *container)
   return G_TYPE_NONE;
 }
 
+void
+gtk_shortcuts_shortcut_update_accel (GtkShortcutsShortcut *self,
+                                     GtkWindow            *window)
+{
+  GtkApplication *app;
+  gchar **accels;
+  gchar *str;
+
+  if (self->action_name == NULL)
+    return;
+
+  app = gtk_window_get_application (window);
+  if (app == NULL)
+    return;
+
+  accels = gtk_application_get_accels_for_action (app, self->action_name);
+  str = g_strjoinv (" ", accels);
+
+  gtk_shortcuts_shortcut_set_accelerator (self, str);
+
+  g_free (str);
+  g_strfreev (accels);
+}
+
 static void
 gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
 {
@@ -615,6 +661,24 @@ gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
                        GTK_SHORTCUT_ACCELERATOR,
                        (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
 
+  /**
+   * GtkShortcutsShortcut:action-name:
+   *
+   * A detailed action name. If this is set for a shortcut
+   * of type %GTK_SHORTCUT_ACCELERATOR, then GTK+ will use
+   * the accelerators that are associated with the action
+   * via gtk_application_set_accels_for_action(), and setting
+   * #GtkShortcutsShortcut::accelerator is not necessary.
+   *
+   * Since: 3.22
+   */
+  properties[PROP_ACTION_NAME] =
+    g_param_spec_string ("action-name",
+                         P_("Action Name"),
+                         P_("The name of the action"),
+                         NULL,
+                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (object_class, LAST_PROP, properties);
   gtk_widget_class_set_css_name (widget_class, "shortcut");
 }
diff --git a/gtk/gtkshortcutsshortcutprivate.h b/gtk/gtkshortcutsshortcutprivate.h
new file mode 100644
index 0000000..5596100
--- /dev/null
+++ b/gtk/gtkshortcutsshortcutprivate.h
@@ -0,0 +1,37 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GTK_SHORTCUTS_SHORTCUT_PRIVATE_H__
+#define __GTK_SHORTCUTS_SHORTCUT_PRIVATE_H__
+
+#include "gtkshortcutsshortcut.h"
+
+G_BEGIN_DECLS
+
+void gtk_shortcuts_shortcut_update_accel (GtkShortcutsShortcut *self,
+                                          GtkWindow            *window);
+
+G_END_DECLS
+
+#endif /* __GTK_sHORTCUTS_SHORTCUT_PRIVATE_H__ */
diff --git a/gtk/gtkshortcutswindow.c b/gtk/gtkshortcutswindow.c
index 0bea2ce..3fdaf78 100644
--- a/gtk/gtkshortcutswindow.c
+++ b/gtk/gtkshortcutswindow.c
@@ -22,7 +22,7 @@
 #include "gtkscrolledwindow.h"
 #include "gtkshortcutssection.h"
 #include "gtkshortcutsgroup.h"
-#include "gtkshortcutsshortcut.h"
+#include "gtkshortcutsshortcutprivate.h"
 #include "gtksearchbar.h"
 #include "gtksearchentry.h"
 #include "gtkwidgetprivate.h"
@@ -98,6 +98,9 @@ typedef struct
   GtkListBox     *list_box;
   GtkBox         *search_gestures;
   GtkBox         *search_shortcuts;
+
+  GtkWindow      *window;
+  gulong          keys_changed_id;
 } GtkShortcutsWindowPrivate;
 
 typedef struct
@@ -187,6 +190,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
   gboolean subtitle_set = FALSE;
   GtkTextDirection direction;
   GtkShortcutType shortcut_type;
+  gchar *action_name = NULL;
   gchar *subtitle;
   gchar *str;
   gchar *keywords;
@@ -200,6 +204,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
                     "icon-set", &icon_set,
                     "subtitle-set", &subtitle_set,
                     "shortcut-type", &shortcut_type,
+                    "action-name", &action_name,
                     NULL);
 
       hash_key = g_strdup_printf ("%s-%s", title, accelerator);
@@ -220,6 +225,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
                            "shortcut-type", shortcut_type,
                            "accel-size-group", priv->search_image_group,
                            "title-size-group", priv->search_text_group,
+                           "action-name", action_name,
                            NULL);
       if (icon_set)
         {
@@ -245,6 +251,7 @@ gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
       g_free (title);
       g_free (accelerator);
       g_free (str);
+      g_free (action_name);
     }
   else if (GTK_IS_CONTAINER (child))
     {
@@ -435,6 +442,57 @@ gtk_shortcuts_window_set_section_name (GtkShortcutsWindow *self,
 }
 
 static void
+update_accels_cb (GtkWidget *widget,
+                  gpointer   data)
+{
+  GtkShortcutsWindow *self = data;
+  GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
+
+  if (GTK_IS_SHORTCUTS_SHORTCUT (widget))
+    gtk_shortcuts_shortcut_update_accel (GTK_SHORTCUTS_SHORTCUT (widget), priv->window);
+  else if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget), update_accels_cb, self);
+}
+
+static void
+update_accels_for_actions (GtkShortcutsWindow *self)
+{
+  GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
+
+  if (priv->window)
+    gtk_container_forall (GTK_CONTAINER (self), update_accels_cb, self);
+}
+
+static void
+keys_changed_handler (GtkWindow          *window,
+                      GtkShortcutsWindow *self)
+{
+  update_accels_for_actions (self);
+}
+
+void
+gtk_shortcuts_window_set_window (GtkShortcutsWindow *self,
+                                 GtkWindow          *window)
+{
+  GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
+
+  if (priv->keys_changed_id)
+    {
+      g_signal_handler_disconnect (priv->window, priv->keys_changed_id);
+      priv->keys_changed_id = 0;
+    }
+
+  priv->window = window;
+
+  if (priv->window)
+    priv->keys_changed_id = g_signal_connect (window, "keys-changed",
+                                              G_CALLBACK (keys_changed_handler),
+                                              self);
+
+  update_accels_for_actions (self);
+}
+
+static void
 gtk_shortcuts_window__list_box__row_activated (GtkShortcutsWindow *self,
                                                GtkListBoxRow      *row,
                                                GtkListBox         *list_box)
@@ -589,6 +647,8 @@ gtk_shortcuts_window_dispose (GObject *object)
 
   g_signal_handlers_disconnect_by_func (priv->stack, G_CALLBACK (update_title_stack), self);
 
+  gtk_shortcuts_window_set_window (self, NULL);
+
   if (priv->header_bar)
     {
       gtk_widget_destroy (GTK_WIDGET (priv->header_bar));
diff --git a/gtk/gtkshortcutswindowprivate.h b/gtk/gtkshortcutswindowprivate.h
new file mode 100644
index 0000000..b3a2e4b
--- /dev/null
+++ b/gtk/gtkshortcutswindowprivate.h
@@ -0,0 +1,38 @@
+
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GTK_SHORTCUTS_WINDOW_PRIVATE_H__
+#define __GTK_SHORTCUTS_WINDOW_PRIVATE_H__
+
+#include "gtkshortcutswindow.h"
+
+G_BEGIN_DECLS
+
+void gtk_shortcuts_window_set_window (GtkShortcutsWindow *self,
+                                      GtkWindow          *window);
+
+G_END_DECLS
+
+#endif /* __GTK_sHORTCUTS_WINDOW_PRIVATE_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]