[gimp] Bug 768966 - Keyboard Shortcut hint disappears from tooltips...



commit b5cc2a977fd09a1f4d8dc92c09d05ea4301bf6c3
Author: Michael Natterer <mitch gimp org>
Date:   Fri Sep 9 23:28:37 2016 +0200

    Bug 768966 - Keyboard Shortcut hint disappears from tooltips...
    
    ...after entering single window mode
    
    In GimpToolPalette, implement GtkWidget::hierarchy_changed() and
    re-set the tooltips using the new toplevel's actions.
    
    In gimp_widget_set_accel_help(), make sure we don't connect to the
    same action twice, and make sure we disconnect everything if either
    the widget or the accel_group go away.

 app/widgets/gimptoolpalette.c   |  202 +++++++++++++++++++-------------------
 app/widgets/gimpwidgets-utils.c |   59 +++++++++++-
 2 files changed, 155 insertions(+), 106 deletions(-)
---
diff --git a/app/widgets/gimptoolpalette.c b/app/widgets/gimptoolpalette.c
index 63c18c2..c23d0f9 100644
--- a/app/widgets/gimptoolpalette.c
+++ b/app/widgets/gimptoolpalette.c
@@ -66,6 +66,8 @@ static void     gimp_tool_palette_size_allocate       (GtkWidget       *widget,
                                                        GtkAllocation   *allocation);
 static void     gimp_tool_palette_style_set           (GtkWidget       *widget,
                                                        GtkStyle        *previous_style);
+static void     gimp_tool_palette_hierarchy_changed   (GtkWidget       *widget,
+                                                       GtkWidget       *previous_toplevel);
 
 static void     gimp_tool_palette_tool_changed        (GimpContext     *context,
                                                        GimpToolInfo    *tool_info,
@@ -79,7 +81,6 @@ static void     gimp_tool_palette_tool_button_toggled (GtkWidget       *widget,
 static gboolean gimp_tool_palette_tool_button_press   (GtkWidget       *widget,
                                                        GdkEventButton  *bevent,
                                                        GimpToolPalette *palette);
-static void     gimp_tool_palette_initialize_tools    (GimpToolPalette *palette);
 
 
 G_DEFINE_TYPE (GimpToolPalette, gimp_tool_palette, GTK_TYPE_TOOL_PALETTE)
@@ -92,8 +93,9 @@ gimp_tool_palette_class_init (GimpToolPaletteClass *klass)
 {
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  widget_class->size_allocate         = gimp_tool_palette_size_allocate;
-  widget_class->style_set             = gimp_tool_palette_style_set;
+  widget_class->size_allocate     = gimp_tool_palette_size_allocate;
+  widget_class->style_set         = gimp_tool_palette_style_set;
+  widget_class->hierarchy_changed = gimp_tool_palette_hierarchy_changed;
 
   gtk_widget_class_install_style_property (widget_class,
                                            g_param_spec_enum ("tool-icon-size",
@@ -210,6 +212,55 @@ gimp_tool_palette_style_set (GtkWidget *widget,
   gimp_dock_invalidate_geometry (GIMP_DOCK (private->toolbox));
 }
 
+static void
+gimp_tool_palette_hierarchy_changed (GtkWidget *widget,
+                                     GtkWidget *previous_tolevel)
+{
+  GimpToolPalettePrivate *private = GET_PRIVATE (widget);
+  GimpUIManager          *ui_manager;
+
+  ui_manager = gimp_dock_get_ui_manager (GIMP_DOCK (private->toolbox));
+
+  if (ui_manager)
+    {
+      GimpContext *context = gimp_toolbox_get_context (private->toolbox);
+      GList       *list;
+
+      for (list = gimp_get_tool_info_iter (context->gimp);
+           list;
+           list = g_list_next (list))
+        {
+          GimpToolInfo  *tool_info = list->data;
+          GtkToolItem   *item;
+          GtkAction     *action;
+          const gchar   *identifier;
+          gchar         *tmp;
+          gchar         *name;
+
+          item = g_object_get_data (G_OBJECT (tool_info), TOOL_BUTTON_DATA_KEY);
+
+          identifier = gimp_object_get_name (tool_info);
+
+          tmp = g_strndup (identifier + strlen ("gimp-"),
+                           strlen (identifier) - strlen ("gimp--tool"));
+          name = g_strdup_printf ("tools-%s", tmp);
+          g_free (tmp);
+
+          action = gimp_ui_manager_find_action (ui_manager, "tools", name);
+          g_free (name);
+
+          if (action)
+            gimp_widget_set_accel_help (GTK_WIDGET (item), action);
+          else
+            gimp_help_set_help_data (GTK_WIDGET (item),
+                                     tool_info->help, tool_info->help_id);
+        }
+    }
+}
+
+
+/*  public functions  */
+
 GtkWidget *
 gimp_tool_palette_new (void)
 {
@@ -222,6 +273,9 @@ gimp_tool_palette_set_toolbox (GimpToolPalette *palette,
 {
   GimpToolPalettePrivate *private;
   GimpContext            *context;
+  GtkWidget              *group;
+  GSList                 *item_group = NULL;
+  GList                  *list;
 
   g_return_if_fail (GIMP_IS_TOOL_PALETTE (palette));
   g_return_if_fail (GIMP_IS_TOOLBOX (toolbox));
@@ -229,15 +283,48 @@ gimp_tool_palette_set_toolbox (GimpToolPalette *palette,
   private = GET_PRIVATE (palette);
 
   private->toolbox = toolbox;
-  context          = gimp_toolbox_get_context (toolbox);
 
-  /**
-   * We must wait until GimpToolbox has a parent so we can use
-   * GimpDock::get_ui_manager() and ::get_dialog_factory().
-   */
-  g_signal_connect_swapped (private->toolbox, "parent-set",
-                            G_CALLBACK (gimp_tool_palette_initialize_tools),
-                            palette);
+  context = gimp_toolbox_get_context (toolbox);
+
+  group = gtk_tool_item_group_new (_("Tools"));
+  gtk_tool_item_group_set_label_widget (GTK_TOOL_ITEM_GROUP (group), NULL);
+  gtk_container_add (GTK_CONTAINER (palette), group);
+  gtk_widget_show (group);
+
+  for (list = gimp_get_tool_info_iter (context->gimp);
+       list;
+       list = g_list_next (list))
+    {
+      GimpToolInfo  *tool_info = list->data;
+      GtkToolItem   *item;
+      const gchar   *icon_name;
+
+      icon_name = gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info));
+
+      item = gtk_radio_tool_button_new (item_group);
+      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), icon_name);
+      item_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item));
+      gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
+      gtk_widget_show (GTK_WIDGET (item));
+
+      g_object_bind_property (tool_info, "visible",
+                              item,      "visible-horizontal",
+                              G_BINDING_SYNC_CREATE);
+      g_object_bind_property (tool_info, "visible",
+                              item,      "visible-vertical",
+                              G_BINDING_SYNC_CREATE);
+
+      g_object_set_data (G_OBJECT (tool_info), TOOL_BUTTON_DATA_KEY, item);
+      g_object_set_data (G_OBJECT (item)  ,    TOOL_INFO_DATA_KEY,   tool_info);
+
+      g_signal_connect (item, "toggled",
+                        G_CALLBACK (gimp_tool_palette_tool_button_toggled),
+                        palette);
+
+      g_signal_connect (gtk_bin_get_child (GTK_BIN (item)), "button-press-event",
+                        G_CALLBACK (gimp_tool_palette_tool_button_press),
+                        palette);
+    }
 
   g_signal_connect_object (context->gimp->tool_info_list, "reorder",
                            G_CALLBACK (gimp_tool_palette_tool_reorder),
@@ -247,7 +334,9 @@ gimp_tool_palette_set_toolbox (GimpToolPalette *palette,
                            G_CALLBACK (gimp_tool_palette_tool_changed),
                            palette,
                            0);
-
+  gimp_tool_palette_tool_changed (context,
+                                  gimp_context_get_tool (context),
+                                  palette);
 }
 
 gboolean
@@ -366,92 +455,3 @@ gimp_tool_palette_tool_button_press (GtkWidget       *widget,
 
   return FALSE;
 }
-
-static void
-gimp_tool_palette_initialize_tools (GimpToolPalette *palette)
-{
-  GimpContext            *context;
-  GimpToolInfo           *active_tool;
-  GList                  *list;
-  GSList                 *item_group = NULL;
-  GimpToolPalettePrivate *private    = GET_PRIVATE(palette);
-  GtkWidget              *group;
-
-  group = gtk_tool_item_group_new (_("Tools"));
-  gtk_tool_item_group_set_label_widget (GTK_TOOL_ITEM_GROUP (group), NULL);
-  gtk_container_add (GTK_CONTAINER (palette), group);
-  gtk_widget_show (group);
-
-  context     = gimp_toolbox_get_context (private->toolbox);
-  active_tool = gimp_context_get_tool (context);
-
-  for (list = gimp_get_tool_info_iter (context->gimp);
-       list;
-       list = g_list_next (list))
-    {
-      GimpToolInfo  *tool_info = list->data;
-      GtkToolItem   *item;
-      const gchar   *icon_name;
-      GimpUIManager *ui_manager;
-
-      icon_name = gimp_viewable_get_icon_name (GIMP_VIEWABLE (tool_info));
-
-      item = gtk_radio_tool_button_new (item_group);
-      gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), icon_name);
-      item_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item));
-      gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
-      gtk_widget_show (GTK_WIDGET (item));
-
-      g_object_bind_property (tool_info, "visible",
-                              item,      "visible-horizontal",
-                              G_BINDING_SYNC_CREATE);
-      g_object_bind_property (tool_info, "visible",
-                              item,      "visible-vertical",
-                              G_BINDING_SYNC_CREATE);
-
-      g_object_set_data (G_OBJECT (tool_info), TOOL_BUTTON_DATA_KEY, item);
-      g_object_set_data (G_OBJECT (item)  ,    TOOL_INFO_DATA_KEY,   tool_info);
-
-      if (tool_info == active_tool)
-        gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (item), TRUE);
-
-      g_signal_connect (item, "toggled",
-                        G_CALLBACK (gimp_tool_palette_tool_button_toggled),
-                        palette);
-
-      g_signal_connect (gtk_bin_get_child (GTK_BIN (item)), "button-press-event",
-                        G_CALLBACK (gimp_tool_palette_tool_button_press),
-                        palette);
-
-      ui_manager = gimp_dock_get_ui_manager (GIMP_DOCK (private->toolbox));
-      if (ui_manager)
-        {
-          GtkAction   *action     = NULL;
-          const gchar *identifier = NULL;
-          gchar       *tmp        = NULL;
-          gchar       *name       = NULL;
-
-          identifier = gimp_object_get_name (tool_info);
-
-          tmp = g_strndup (identifier + strlen ("gimp-"),
-                           strlen (identifier) - strlen ("gimp--tool"));
-          name = g_strdup_printf ("tools-%s", tmp);
-          g_free (tmp);
-
-          action = gimp_ui_manager_find_action (ui_manager, "tools", name);
-          g_free (name);
-
-          if (action)
-            gimp_widget_set_accel_help (GTK_WIDGET (item), action);
-          else
-            gimp_help_set_help_data (GTK_WIDGET (item),
-                                     tool_info->help, tool_info->help_id);
-        }
-      gtk_widget_set_can_focus (gtk_bin_get_child (GTK_BIN (item)), FALSE);
-    }
-
-  /* We only need to initialize tools once */
-  g_signal_handlers_disconnect_by_func (private->toolbox,
-                                        gimp_tool_palette_initialize_tools,
-                                        palette);
-}
diff --git a/app/widgets/gimpwidgets-utils.c b/app/widgets/gimpwidgets-utils.c
index 862058c..ffb5076 100644
--- a/app/widgets/gimpwidgets-utils.c
+++ b/app/widgets/gimpwidgets-utils.c
@@ -1034,7 +1034,7 @@ gimp_widget_accel_changed (GtkAccelGroup   *accel_group,
 
       if (accel_key            &&
           accel_key->accel_key &&
-          accel_key->accel_flags & GTK_ACCEL_VISIBLE)
+          (accel_key->accel_flags & GTK_ACCEL_VISIBLE))
         {
           gchar *escaped = g_markup_escape_text (tooltip, -1);
           gchar *accel   = gtk_accelerator_get_label (accel_key->accel_key,
@@ -1054,23 +1054,72 @@ gimp_widget_accel_changed (GtkAccelGroup   *accel_group,
     }
 }
 
+static void   gimp_accel_help_widget_weak_notify (gpointer  accel_group,
+                                                  GObject  *where_widget_was);
+
+static void
+gimp_accel_help_accel_group_weak_notify (gpointer  widget,
+                                         GObject  *where_accel_group_was)
+{
+  g_object_weak_unref (widget,
+                       gimp_accel_help_widget_weak_notify,
+                       where_accel_group_was);
+
+  g_object_set_data (widget, "gimp-accel-group", NULL);
+}
+
+static void
+gimp_accel_help_widget_weak_notify (gpointer  accel_group,
+                                    GObject  *where_widget_was)
+{
+  g_object_weak_unref (accel_group,
+                       gimp_accel_help_accel_group_weak_notify,
+                       where_widget_was);
+}
+
 void
 gimp_widget_set_accel_help (GtkWidget *widget,
                             GtkAction *action)
 {
-  GClosure *accel_closure = gtk_action_get_accel_closure (action);
+  GtkAccelGroup *accel_group;
+  GClosure      *accel_closure;
+
+  accel_group = g_object_get_data (G_OBJECT (widget), "gimp-accel-group");
+
+  if (accel_group)
+    {
+      g_signal_handlers_disconnect_by_func (accel_group,
+                                            gimp_widget_accel_changed,
+                                            widget);
+      g_object_weak_unref (G_OBJECT (accel_group),
+                           gimp_accel_help_accel_group_weak_notify,
+                           widget);
+      g_object_weak_unref (G_OBJECT (widget),
+                           gimp_accel_help_widget_weak_notify,
+                           accel_group);
+      g_object_set_data (G_OBJECT (widget), "gimp-accel-group", NULL);
+    }
+
+  accel_closure = gtk_action_get_accel_closure (action);
 
   if (accel_closure)
     {
-      GtkAccelGroup *accel_group;
+      accel_group = gtk_accel_group_from_accel_closure (accel_closure);
+
+      g_object_set_data (G_OBJECT (widget), "gimp-accel-group",
+                         accel_group);
+      g_object_weak_ref (G_OBJECT (accel_group),
+                         gimp_accel_help_accel_group_weak_notify,
+                         widget);
+      g_object_weak_ref (G_OBJECT (widget),
+                         gimp_accel_help_widget_weak_notify,
+                         accel_group);
 
       g_object_set_data (G_OBJECT (widget), "gimp-accel-closure",
                          accel_closure);
       g_object_set_data (G_OBJECT (widget), "gimp-accel-action",
                          action);
 
-      accel_group = gtk_accel_group_from_accel_closure (accel_closure);
-
       g_signal_connect_object (accel_group, "accel-changed",
                                G_CALLBACK (gimp_widget_accel_changed),
                                widget, 0);


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