diff --git a/gtk/gtkpasswordentry.c b/gtk/gtkpasswordentry.c index 7a4019115a..36fd830db3 100644 --- a/gtk/gtkpasswordentry.c +++ b/gtk/gtkpasswordentry.c @@ -54,11 +54,10 @@ */ typedef struct { - GtkWidget *box; GtkWidget *entry; GtkWidget *icon; - GdkKeymap *keymap; GtkWidget *peek_icon; + GdkKeymap *keymap; } GtkPasswordEntryPrivate; enum { @@ -149,16 +148,9 @@ gtk_password_entry_init (GtkPasswordEntry *entry) gtk_widget_set_has_surface (GTK_WIDGET (entry), FALSE); - priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); - gtk_widget_set_hexpand (priv->box, FALSE); - gtk_widget_set_vexpand (priv->box, FALSE); - gtk_widget_set_parent (priv->box, GTK_WIDGET (entry)); - priv->entry = gtk_text_new (); gtk_text_set_visibility (GTK_TEXT (priv->entry), FALSE); - gtk_widget_set_hexpand (priv->entry, TRUE); - gtk_widget_set_vexpand (priv->entry, TRUE); - gtk_container_add (GTK_CONTAINER (priv->box), priv->entry); + gtk_widget_set_parent (priv->entry, GTK_WIDGET (entry)); gtk_editable_init_delegate (GTK_EDITABLE (entry)); g_signal_connect_swapped (priv->entry, "notify::has-focus", G_CALLBACK (focus_changed), entry); g_signal_connect (priv->entry, "populate-popup", G_CALLBACK (populate_popup), entry); @@ -167,7 +159,7 @@ gtk_password_entry_init (GtkPasswordEntry *entry) gtk_widget_set_tooltip_text (priv->icon, _("Caps Lock is on")); gtk_style_context_add_class (gtk_widget_get_style_context (priv->icon), "caps-lock-indicator"); gtk_widget_set_cursor (priv->icon, gtk_widget_get_cursor (priv->entry)); - gtk_container_add (GTK_CONTAINER (priv->box), priv->icon); + gtk_widget_set_parent (priv->icon, GTK_WIDGET (entry)); gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (entry)), I_("password")); } @@ -200,7 +192,6 @@ gtk_password_entry_dispose (GObject *object) g_clear_pointer (&priv->entry, gtk_widget_unparent); g_clear_pointer (&priv->icon, gtk_widget_unparent); g_clear_pointer (&priv->peek_icon, gtk_widget_unparent); - g_clear_pointer (&priv->box, gtk_widget_unparent); G_OBJECT_CLASS (gtk_password_entry_parent_class)->dispose (object); } @@ -289,10 +280,21 @@ gtk_password_entry_measure (GtkWidget *widget, { GtkPasswordEntry *entry = GTK_PASSWORD_ENTRY (widget); GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry); + int icon_min = 0, icon_nat = 0; - gtk_widget_measure (priv->box, orientation, for_size, + gtk_widget_measure (priv->entry, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); + + if (priv->icon && gtk_widget_get_visible (priv->icon)) + gtk_widget_measure (priv->icon, orientation, for_size, + &icon_min, &icon_nat, + NULL, NULL); + + if (priv->peek_icon && gtk_widget_get_visible (priv->peek_icon)) + gtk_widget_measure (priv->peek_icon, orientation, for_size, + &icon_min, &icon_nat, + NULL, NULL); } static void @@ -303,10 +305,35 @@ gtk_password_entry_size_allocate (GtkWidget *widget, { GtkPasswordEntry *entry = GTK_PASSWORD_ENTRY (widget); GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry); + int icon_min = 0, icon_nat = 0; + int peek_min = 0, peek_nat = 0; + int text_width; - gtk_widget_size_allocate (priv->box, - &(GtkAllocation) { 0, 0, width, height }, + if (priv->icon && gtk_widget_get_visible (priv->icon)) + gtk_widget_measure (priv->icon, GTK_ORIENTATION_HORIZONTAL, -1, + &icon_min, &icon_nat, + NULL, NULL); + + if (priv->peek_icon && gtk_widget_get_visible (priv->peek_icon)) + gtk_widget_measure (priv->peek_icon, GTK_ORIENTATION_HORIZONTAL, -1, + &peek_min, &peek_nat, + NULL, NULL); + + text_width = width - icon_nat - peek_nat; + + gtk_widget_size_allocate (priv->entry, + &(GtkAllocation) { 0, 0, text_width, height }, baseline); + + if (priv->icon && gtk_widget_get_visible (priv->icon)) + gtk_widget_size_allocate (priv->icon, + &(GtkAllocation) { text_width, 0, icon_nat, height }, + baseline); + + if (priv->peek_icon && gtk_widget_get_visible (priv->peek_icon)) + gtk_widget_size_allocate (priv->peek_icon, + &(GtkAllocation) { text_width + icon_nat, 0, peek_nat, height }, + baseline); } static AtkObject * @@ -442,7 +469,7 @@ gtk_password_entry_set_show_peek_icon (GtkPasswordEntry *entry, priv->peek_icon = gtk_image_new_from_icon_name ("eye-not-looking-symbolic"); gtk_widget_set_tooltip_text (priv->peek_icon, _("Show text")); - gtk_container_add (GTK_CONTAINER (priv->box), priv->peek_icon); + gtk_widget_set_parent (priv->peek_icon, GTK_WIDGET (entry)); press = gtk_gesture_multi_press_new (); g_signal_connect_swapped (press, "released", diff --git a/gtk/gtksearchentry.c b/gtk/gtksearchentry.c index 45ace300e7..2d84f82ab5 100644 --- a/gtk/gtksearchentry.c +++ b/gtk/gtksearchentry.c @@ -100,7 +100,6 @@ typedef struct { GtkWidget *capture_widget; GtkEventController *capture_widget_controller; - GtkWidget *box; GtkWidget *entry; GtkWidget *icon; @@ -135,7 +134,8 @@ gtk_search_entry_finalize (GObject *object) gtk_editable_finish_delegate (GTK_EDITABLE (entry)); - g_clear_pointer (&priv->box, gtk_widget_unparent); + g_clear_pointer (&priv->entry, gtk_widget_unparent); + g_clear_pointer (&priv->icon, gtk_widget_unparent); if (priv->delayed_changed_id > 0) g_source_remove (priv->delayed_changed_id); @@ -222,10 +222,16 @@ gtk_search_entry_measure (GtkWidget *widget, { GtkSearchEntry *entry = GTK_SEARCH_ENTRY (widget); GtkSearchEntryPrivate *priv = gtk_search_entry_get_instance_private (entry); + int icon_min = 0, icon_nat = 0; - gtk_widget_measure (priv->box, orientation, for_size, + gtk_widget_measure (priv->entry, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); + + if (priv->icon && gtk_widget_get_visible (priv->icon)) + gtk_widget_measure (priv->icon, orientation, for_size, + &icon_min, &icon_nat, + NULL, NULL); } static void @@ -236,10 +242,24 @@ gtk_search_entry_size_allocate (GtkWidget *widget, { GtkSearchEntry *entry = GTK_SEARCH_ENTRY (widget); GtkSearchEntryPrivate *priv = gtk_search_entry_get_instance_private (entry); + int icon_min = 0, icon_nat = 0; + int text_width; - gtk_widget_size_allocate (priv->box, - &(GtkAllocation) { 0, 0, width, height }, + if (priv->icon && gtk_widget_get_visible (priv->icon)) + gtk_widget_measure (priv->icon, GTK_ORIENTATION_HORIZONTAL, -1, + &icon_min, &icon_nat, + NULL, NULL); + + text_width = width - icon_nat; + + gtk_widget_size_allocate (priv->entry, + &(GtkAllocation) { 0, 0, text_width, height }, baseline); + + if (priv->icon && gtk_widget_get_visible (priv->icon)) + gtk_widget_size_allocate (priv->icon, + &(GtkAllocation) { text_width, 0, icon_nat, height }, + baseline); } static AtkObject * @@ -521,15 +541,8 @@ gtk_search_entry_init (GtkSearchEntry *entry) gtk_widget_set_has_surface (GTK_WIDGET (entry), FALSE); - priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_set_parent (priv->box, GTK_WIDGET (entry)); - gtk_widget_set_hexpand (priv->box, FALSE); - gtk_widget_set_vexpand (priv->box, FALSE); - priv->entry = gtk_text_new (); - gtk_widget_set_hexpand (priv->entry, TRUE); - gtk_widget_set_vexpand (priv->entry, TRUE); - gtk_container_add (GTK_CONTAINER (priv->box), GTK_WIDGET (priv->entry)); + gtk_widget_set_parent (priv->entry, GTK_WIDGET (entry)); gtk_editable_init_delegate (GTK_EDITABLE (entry)); g_signal_connect_swapped (priv->entry, "changed", G_CALLBACK (text_changed), entry); g_signal_connect_after (priv->entry, "changed", G_CALLBACK (gtk_search_entry_changed), entry); @@ -539,7 +552,7 @@ gtk_search_entry_init (GtkSearchEntry *entry) priv->icon = gtk_image_new_from_icon_name ("edit-clear-symbolic"); gtk_widget_set_tooltip_text (priv->icon, _("Clear entry")); - gtk_container_add (GTK_CONTAINER (priv->box), GTK_WIDGET (priv->icon)); + gtk_widget_set_parent (priv->icon, GTK_WIDGET (entry)); gtk_widget_hide (priv->icon); press = gtk_gesture_multi_press_new (); diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 7a4d6cc2b9..0f2c8a8b0d 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -220,6 +220,7 @@ struct _GtkTextPrivate guint cursor_handle_dragged : 1; guint selection_handle_dragged : 1; guint populate_all : 1; + guint propagate_text_width : 1; }; struct _GtkTextPasswordHint @@ -263,6 +264,7 @@ enum { PROP_POPULATE_ALL, PROP_TABS, PROP_ENABLE_EMOJI_COMPLETION, + PROP_PROPAGATE_TEXT_WIDTH, NUM_PROPERTIES }; @@ -893,6 +895,13 @@ gtk_text_class_init (GtkTextClass *class) TRUE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + text_props[PROP_PROPAGATE_TEXT_WIDTH] = + g_param_spec_boolean ("propagate-text-width", + P_("Propagate text width"), + P_("Whether the entry should grow and shrink with the content"), + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, text_props); gtk_editable_install_properties (gobject_class, NUM_PROPERTIES); @@ -1510,6 +1519,15 @@ gtk_text_set_property (GObject *object, set_enable_emoji_completion (self, g_value_get_boolean (value)); break; + case PROP_PROPAGATE_TEXT_WIDTH: + if (priv->propagate_text_width != g_value_get_boolean (value)) + { + priv->propagate_text_width = g_value_get_boolean (value); + gtk_widget_queue_resize (GTK_WIDGET (self)); + g_object_notify_by_pspec (object, pspec); + } + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1625,6 +1643,10 @@ gtk_text_get_property (GObject *object, g_value_set_boolean (value, priv->enable_emoji_completion); break; + case PROP_PROPAGATE_TEXT_WIDTH: + g_value_set_boolean (value, priv->propagate_text_width); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2077,6 +2099,17 @@ gtk_text_measure (GtkWidget *widget, else nat = char_pixels * priv->max_width_chars; + if (priv->propagate_text_width) + { + PangoLayout *layout; + int act; + + layout = gtk_text_ensure_layout (self, TRUE); + pango_layout_get_pixel_size (layout, &act, NULL); + + nat = MIN (act, nat); + } + nat = MAX (min, nat); if (priv->placeholder) @@ -3015,6 +3048,7 @@ gtk_text_insert_text (GtkText *self, int length, int *position) { + GtkTextPrivate *priv = gtk_text_get_instance_private (self); int n_inserted; int n_chars; @@ -3036,6 +3070,8 @@ gtk_text_insert_text (GtkText *self, *position += n_inserted; update_placeholder_visibility (self); + if (priv->propagate_text_width) + gtk_widget_queue_resize (GTK_WIDGET (self)); } static void @@ -3043,12 +3079,16 @@ gtk_text_delete_text (GtkText *self, int start_pos, int end_pos) { + GtkTextPrivate *priv = gtk_text_get_instance_private (self); + begin_change (self); gtk_entry_buffer_delete_text (get_buffer (self), start_pos, end_pos - start_pos); end_change (self); update_placeholder_visibility (self); + if (priv->propagate_text_width) + gtk_widget_queue_resize (GTK_WIDGET (self)); } static void