[gimp] app: check and clean out duplicate accelerators on startup.



commit 2a232398c4ad5a3108b5ad75be7bc8ef5d98e6fb
Author: Jehan <jehan girinstud io>
Date:   Mon Nov 21 16:52:52 2016 +0100

    app: check and clean out duplicate accelerators on startup.
    
    Duplicate accelerators are not supposed to happen. It is not possible
    to set them through the GUI in particular. Nevertheless
    gtk_accel_map_load() would apparently let duplicates pass, which could
    happen after editing the menurc directly, or using the development
    version (no action name migration happens there), or simply after a
    potential bug. This is then very annoying because you may see several
    actions displaying the same shortcut but only one actually work. And
    trying to re-set through GUI the shortcut to the one action you wish to
    run does not fix the duplicate issue (you have to laboriously find which
    other action use the same accelerator and delete it first).
    Better be safe than sorry and make a quick check at startup, then delete
    the accelerator on one of the duplicates (you can't guess which one was
    actually wanted, but at least you will facilitate manual reset through
    the GUI).

 app/gui/gui.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)
---
diff --git a/app/gui/gui.c b/app/gui/gui.c
index 9d4ed9c..84582eb 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -135,6 +135,17 @@ static void       gui_display_changed           (GimpContext        *context,
                                                  GimpDisplay        *display,
                                                  Gimp               *gimp);
 
+static void       gui_compare_accelerator       (gpointer            data,
+                                                 const gchar        *accel_path,
+                                                 guint               accel_key,
+                                                 GdkModifierType     accel_mods,
+                                                 gboolean            changed);
+static void      gui_check_unique_accelerator   (gpointer            data,
+                                                 const gchar        *accel_path,
+                                                 guint               accel_key,
+                                                 GdkModifierType     accel_mods,
+                                                 gboolean            changed);
+
 
 /*  private variables  */
 
@@ -530,6 +541,10 @@ gui_restore_after_callback (Gimp               *gimp,
                                                     gui_config->tearoff_menus);
   gimp_ui_manager_update (image_ui_manager, gimp);
 
+  /* Check that every accelerator is unique. */
+  gtk_accel_map_foreach_unfiltered (NULL,
+                                    gui_check_unique_accelerator);
+
   gimp_action_history_init (gimp);
 
 #ifdef GDK_WINDOWING_QUARTZ
@@ -861,3 +876,50 @@ gui_display_changed (GimpContext *context,
 
   gimp_ui_manager_update (image_ui_manager, display);
 }
+
+typedef struct
+{
+  const gchar     *path;
+  guint            key;
+  GdkModifierType  mods;
+}
+accelData;
+
+static void
+gui_compare_accelerator (gpointer         data,
+                         const gchar     *accel_path,
+                         guint            accel_key,
+                         GdkModifierType  accel_mods,
+                         gboolean         changed)
+{
+  accelData *accel = data;
+
+  if (accel->key == accel_key && accel->mods == accel_mods &&
+      g_strcmp0 (accel->path, accel_path))
+    {
+      g_warning ("Actions \"%s\" and \"%s\" use the same accelerator.\n"
+                 "Disable the accelerator on \"%s\".",
+                 accel->path, accel_path, accel_path);
+      gtk_accel_map_change_entry (accel_path, 0, 0, FALSE);
+    }
+}
+
+static void
+gui_check_unique_accelerator (gpointer         data,
+                              const gchar     *accel_path,
+                              guint            accel_key,
+                              GdkModifierType  accel_mods,
+                              gboolean         changed)
+{
+  if (gtk_accelerator_valid (accel_key, accel_mods))
+    {
+      accelData accel;
+
+      accel.path = accel_path;
+      accel.key  = accel_key;
+      accel.mods = accel_mods;
+
+      gtk_accel_map_foreach_unfiltered (&accel,
+                                        gui_compare_accelerator);
+    }
+}


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