From 8eadb2f771d01cf1f7b9dbfa8b29f88004bf2c44 Mon Sep 17 00:00:00 2001 From: Daniel Boles Date: Sat, 15 Dec 2018 16:44:00 +0000 Subject: [PATCH 1/2] Entry: Don't allocate size to empty icon positions We only checked whether the icon_info at the position was NULL, but if there was previously an icon there that was since cleared, we have an icon_info but no image to show, so we were allocating size for nothing. Fix by also checking whether the image storage type is empty, so if we previously had an icon but have since unset it (but keep the resources around in case needed again later), we don't allocate any size to it, nor draw it, nor consider clicks to land in it, nor return any Pixbuf. https://gitlab.gnome.org/GNOME/gtk/issues/1527 --- gtk/gtkentry.c | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 3380e5d153..824eee2740 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -3683,7 +3683,8 @@ place_windows (GtkEntry *entry) EntryIconInfo *icon_info; icon_info = priv->icons[GTK_ENTRY_ICON_PRIMARY]; - if (icon_info) + if (icon_info && + !_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) { GtkAllocation primary; @@ -3694,7 +3695,8 @@ place_windows (GtkEntry *entry) } icon_info = priv->icons[GTK_ENTRY_ICON_SECONDARY]; - if (icon_info) + if (icon_info && + !_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) { GtkAllocation secondary; @@ -3846,6 +3848,9 @@ gtk_entry_allocate (GtkCssGadget *gadget, if (!icon_info) continue; + if (_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) + continue; + gtk_css_gadget_get_preferred_size (icon_info->gadget, GTK_ORIENTATION_HORIZONTAL, -1, @@ -3987,7 +3992,10 @@ gtk_entry_draw_undershoot (GtkEntry *entry, { int icon_width = 0; int icon_idx = rtl ? 1 : 0; - if (priv->icons[icon_idx] != NULL) + EntryIconInfo *icon_info = priv->icons[icon_idx]; + + if (icon_info != NULL && + !_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) { gtk_css_gadget_get_preferred_size (priv->icons[icon_idx]->gadget, GTK_ORIENTATION_HORIZONTAL, @@ -4006,7 +4014,10 @@ gtk_entry_draw_undershoot (GtkEntry *entry, { int icon_width = 0; int icon_idx = rtl ? 0 : 1; - if (priv->icons[icon_idx] != NULL) + EntryIconInfo *icon_info = priv->icons[icon_idx]; + + if (icon_info != NULL && + !_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) { gtk_css_gadget_get_preferred_size (priv->icons[icon_idx]->gadget, GTK_ORIENTATION_HORIZONTAL, @@ -4014,6 +4025,7 @@ gtk_entry_draw_undershoot (GtkEntry *entry, &icon_width, NULL, NULL, NULL); } + gtk_style_context_save_to_node (context, priv->undershoot_node[1]); gtk_render_background (context, cr, rect.x + rect.width - UNDERSHOOT_SIZE - icon_width + 1, rect.y, UNDERSHOOT_SIZE, rect.height); gtk_render_frame (context, cr, rect.x + rect.width - UNDERSHOOT_SIZE - icon_width + 1, rect.y, UNDERSHOOT_SIZE, rect.height); @@ -4064,8 +4076,11 @@ gtk_entry_render (GtkCssGadget *gadget, { EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info != NULL) - gtk_css_gadget_draw (icon_info->gadget, cr); + if (icon_info != NULL && + !_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) + { + gtk_css_gadget_draw (icon_info->gadget, cr); + } } gtk_entry_draw_undershoot (entry, cr); @@ -8489,11 +8504,10 @@ gtk_entry_set_icon_from_pixbuf (GtkEntry *entry, g_object_freeze_notify (G_OBJECT (entry)); - if (pixbuf) - g_object_ref (pixbuf); - if (pixbuf) { + g_object_ref (pixbuf); + _gtk_icon_helper_set_pixbuf (GTK_ICON_HELPER (icon_info->gadget), pixbuf); _gtk_icon_helper_set_icon_size (GTK_ICON_HELPER (icon_info->gadget), GTK_ICON_SIZE_MENU); @@ -8518,7 +8532,7 @@ gtk_entry_set_icon_from_pixbuf (GtkEntry *entry, gtk_entry_clear_icon (entry, icon_pos); if (gtk_widget_get_visible (GTK_WIDGET (entry))) - gtk_widget_queue_resize (GTK_WIDGET (entry)); + gtk_widget_queue_allocate (GTK_WIDGET (entry)); g_object_thaw_notify (G_OBJECT (entry)); } @@ -8578,7 +8592,7 @@ gtk_entry_set_icon_from_stock (GtkEntry *entry, gtk_entry_clear_icon (entry, icon_pos); if (gtk_widget_get_visible (GTK_WIDGET (entry))) - gtk_widget_queue_resize (GTK_WIDGET (entry)); + gtk_widget_queue_allocate (GTK_WIDGET (entry)); g_object_thaw_notify (G_OBJECT (entry)); } @@ -8617,7 +8631,6 @@ gtk_entry_set_icon_from_icon_name (GtkEntry *entry, g_object_freeze_notify (G_OBJECT (entry)); - if (icon_name != NULL) { _gtk_icon_helper_set_icon_name (GTK_ICON_HELPER (icon_info->gadget), icon_name, GTK_ICON_SIZE_MENU); @@ -8640,7 +8653,7 @@ gtk_entry_set_icon_from_icon_name (GtkEntry *entry, gtk_entry_clear_icon (entry, icon_pos); if (gtk_widget_get_visible (GTK_WIDGET (entry))) - gtk_widget_queue_resize (GTK_WIDGET (entry)); + gtk_widget_queue_allocate (GTK_WIDGET (entry)); g_object_thaw_notify (G_OBJECT (entry)); } @@ -8700,7 +8713,7 @@ gtk_entry_set_icon_from_gicon (GtkEntry *entry, gtk_entry_clear_icon (entry, icon_pos); if (gtk_widget_get_visible (GTK_WIDGET (entry))) - gtk_widget_queue_resize (GTK_WIDGET (entry)); + gtk_widget_queue_allocate (GTK_WIDGET (entry)); g_object_thaw_notify (G_OBJECT (entry)); } @@ -8810,6 +8823,9 @@ gtk_entry_get_icon_pixbuf (GtkEntry *entry, if (!icon_info) return NULL; + if (_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) + return NULL; + _gtk_icon_helper_get_size (GTK_ICON_HELPER (icon_info->gadget), &width, &height); surface = gtk_icon_helper_load_surface (GTK_ICON_HELPER (icon_info->gadget), 1); @@ -9075,6 +9091,9 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry, if (icon_info == NULL) continue; + if (_gtk_icon_helper_get_is_empty (GTK_ICON_HELPER (icon_info->gadget))) + continue; + if (gtk_css_gadget_border_box_contains_point (icon_info->gadget, x, y)) return i; } @@ -11160,7 +11179,6 @@ set_show_emoji_icon (GtkEntry *entry, } g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_SHOW_EMOJI_ICON]); - gtk_widget_queue_resize (GTK_WIDGET (entry)); } static void -- GitLab From 307d0ce8669c562d4b978dd7495efd544bbd5c78 Mon Sep 17 00:00:00 2001 From: Daniel Boles Date: Sat, 15 Dec 2018 16:45:34 +0000 Subject: [PATCH 2/2] Entry: Emit notify::pixbuf whenever icon's cleared not just if it was specifically using pixbuf storage type, since the getter works for any storage type, so in any case when we had storage and clear it, we need to notify that the effective :pixbuf is now NULL. --- gtk/gtkentry.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 824eee2740..4a7aed04fb 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -7484,15 +7484,18 @@ gtk_entry_clear_icon (GtkEntry *entry, if (GDK_IS_WINDOW (icon_info->window)) gdk_window_hide (icon_info->window); + _gtk_icon_helper_clear (icon_helper); + + g_object_notify_by_pspec (G_OBJECT (entry), + entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY + ? PROP_PIXBUF_PRIMARY + : PROP_PIXBUF_SECONDARY]); + storage_type = _gtk_icon_helper_get_storage_type (icon_helper); switch (storage_type) { case GTK_IMAGE_PIXBUF: - g_object_notify_by_pspec (G_OBJECT (entry), - entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY - ? PROP_PIXBUF_PRIMARY - : PROP_PIXBUF_SECONDARY]); break; case GTK_IMAGE_STOCK: @@ -7521,8 +7524,6 @@ gtk_entry_clear_icon (GtkEntry *entry, break; } - _gtk_icon_helper_clear (icon_helper); - g_object_notify_by_pspec (G_OBJECT (entry), entry_props[icon_pos == GTK_ENTRY_ICON_PRIMARY ? PROP_STORAGE_TYPE_PRIMARY -- GitLab