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.
This commit is contained in:
Michael Natterer 2016-09-09 23:28:37 +02:00
parent 57d0c89818
commit b5cc2a977f
2 changed files with 155 additions and 106 deletions

View File

@ -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);
}

View File

@ -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);