summaryrefslogtreecommitdiff
path: root/gtk/gtktext.c
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2019-10-19 09:23:56 +0200
committerTimm Bäder <mail@baedert.org>2019-10-22 09:37:08 +0200
commitacf927fe14da5a4b46af77ceb1bdbb557f06010d (patch)
treeb2e51d66254c9fd4b7802a1a630b4ba8791aef8c /gtk/gtktext.c
parentca71340c6bfa10092c756e5fdd5e41230e2981b5 (diff)
downloadgtk+-acf927fe14da5a4b46af77ceb1bdbb557f06010d.tar.gz
text: Don't destroy pango layout in size_allocate
It's not needed.
Diffstat (limited to 'gtk/gtktext.c')
-rw-r--r--gtk/gtktext.c267
1 files changed, 138 insertions, 129 deletions
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index f0d228af8c..4278623b0e 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -2070,6 +2070,133 @@ gtk_text_unrealize (GtkWidget *widget)
}
static void
+update_im_cursor_location (GtkText *self)
+{
+ GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+ GdkRectangle area;
+ GtkAllocation text_area;
+ int strong_x;
+ int strong_xoffset;
+
+ gtk_text_get_cursor_locations (self, &strong_x, NULL);
+ gtk_text_get_text_allocation (self, &text_area);
+
+ strong_xoffset = strong_x - priv->scroll_offset;
+ if (strong_xoffset < 0)
+ strong_xoffset = 0;
+ else if (strong_xoffset > text_area.width)
+ strong_xoffset = text_area.width;
+
+ area.x = strong_xoffset;
+ area.y = 0;
+ area.width = 0;
+ area.height = text_area.height;
+
+ gtk_im_context_set_cursor_location (priv->im_context, &area);
+}
+
+static void
+gtk_text_move_handle (GtkText *self,
+ GtkTextHandlePosition pos,
+ int x,
+ int y,
+ int height)
+{
+ GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+ GtkAllocation text_allocation;
+
+ gtk_text_get_text_allocation (self, &text_allocation);
+
+ if (!_gtk_text_handle_get_is_dragged (priv->text_handle, pos) &&
+ (x < 0 || x > text_allocation.width))
+ {
+ /* Hide the handle if it's not being manipulated
+ * and fell outside of the visible text area.
+ */
+ _gtk_text_handle_set_visible (priv->text_handle, pos, FALSE);
+ }
+ else
+ {
+ GdkRectangle rect;
+
+ rect.x = x + text_allocation.x;
+ rect.y = y + text_allocation.y;
+ rect.width = 1;
+ rect.height = height;
+
+ _gtk_text_handle_set_visible (priv->text_handle, pos, TRUE);
+ _gtk_text_handle_set_position (priv->text_handle, pos, &rect);
+ _gtk_text_handle_set_direction (priv->text_handle, pos, priv->resolved_dir);
+ }
+}
+
+static int
+gtk_text_get_selection_bound_location (GtkText *self)
+{
+ GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+ PangoLayout *layout;
+ PangoRectangle pos;
+ int x;
+ const char *text;
+ int index;
+
+ layout = gtk_text_ensure_layout (self, FALSE);
+ text = pango_layout_get_text (layout);
+ index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
+ pango_layout_index_to_pos (layout, index, &pos);
+
+ if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
+ x = (pos.x + pos.width) / PANGO_SCALE;
+ else
+ x = pos.x / PANGO_SCALE;
+
+ return x;
+}
+
+static void
+gtk_text_update_handles (GtkText *self,
+ GtkTextHandleMode mode)
+{
+ GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+ GtkAllocation text_allocation;
+ int strong_x;
+ int cursor, bound;
+
+ _gtk_text_handle_set_mode (priv->text_handle, mode);
+ gtk_text_get_text_allocation (self, &text_allocation);
+
+ gtk_text_get_cursor_locations (self, &strong_x, NULL);
+ cursor = strong_x - priv->scroll_offset;
+
+ if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
+ {
+ int start, end;
+
+ bound = gtk_text_get_selection_bound_location (self) - priv->scroll_offset;
+
+ if (priv->selection_bound > priv->current_pos)
+ {
+ start = cursor;
+ end = bound;
+ }
+ else
+ {
+ start = bound;
+ end = cursor;
+ }
+
+ /* Update start selection bound */
+ gtk_text_move_handle (self, GTK_TEXT_HANDLE_POSITION_SELECTION_START,
+ start, 0, text_allocation.height);
+ gtk_text_move_handle (self, GTK_TEXT_HANDLE_POSITION_SELECTION_END,
+ end, 0, text_allocation.height);
+ }
+ else
+ gtk_text_move_handle (self, GTK_TEXT_HANDLE_POSITION_CURSOR,
+ cursor, 0, text_allocation.height);
+}
+
+static void
gtk_text_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
@@ -2189,13 +2316,22 @@ gtk_text_size_allocate (GtkWidget *widget,
-1);
}
- if (gtk_widget_get_realized (widget))
- gtk_text_recompute (self);
+ gtk_text_adjust_scroll (self);
+ gtk_text_check_cursor_blink (self);
+ update_im_cursor_location (self);
chooser = g_object_get_data (G_OBJECT (self), "gtk-emoji-chooser");
if (chooser)
gtk_native_check_resize (GTK_NATIVE (chooser));
+ if (priv->text_handle)
+ {
+ GtkTextHandleMode handle_mode = _gtk_text_handle_get_mode (priv->text_handle);
+
+ if (handle_mode != GTK_TEXT_HANDLE_MODE_NONE)
+ gtk_text_update_handles (self, handle_mode);
+ }
+
if (priv->emoji_completion)
gtk_native_check_resize (GTK_NATIVE (priv->emoji_completion));
@@ -2339,107 +2475,6 @@ in_selection (GtkText *self,
}
static void
-gtk_text_move_handle (GtkText *self,
- GtkTextHandlePosition pos,
- int x,
- int y,
- int height)
-{
- GtkTextPrivate *priv = gtk_text_get_instance_private (self);
- GtkAllocation text_allocation;
-
- gtk_text_get_text_allocation (self, &text_allocation);
-
- if (!_gtk_text_handle_get_is_dragged (priv->text_handle, pos) &&
- (x < 0 || x > text_allocation.width))
- {
- /* Hide the handle if it's not being manipulated
- * and fell outside of the visible text area.
- */
- _gtk_text_handle_set_visible (priv->text_handle, pos, FALSE);
- }
- else
- {
- GdkRectangle rect;
-
- rect.x = x + text_allocation.x;
- rect.y = y + text_allocation.y;
- rect.width = 1;
- rect.height = height;
-
- _gtk_text_handle_set_visible (priv->text_handle, pos, TRUE);
- _gtk_text_handle_set_position (priv->text_handle, pos, &rect);
- _gtk_text_handle_set_direction (priv->text_handle, pos, priv->resolved_dir);
- }
-}
-
-static int
-gtk_text_get_selection_bound_location (GtkText *self)
-{
- GtkTextPrivate *priv = gtk_text_get_instance_private (self);
- PangoLayout *layout;
- PangoRectangle pos;
- int x;
- const char *text;
- int index;
-
- layout = gtk_text_ensure_layout (self, FALSE);
- text = pango_layout_get_text (layout);
- index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
- pango_layout_index_to_pos (layout, index, &pos);
-
- if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
- x = (pos.x + pos.width) / PANGO_SCALE;
- else
- x = pos.x / PANGO_SCALE;
-
- return x;
-}
-
-static void
-gtk_text_update_handles (GtkText *self,
- GtkTextHandleMode mode)
-{
- GtkTextPrivate *priv = gtk_text_get_instance_private (self);
- GtkAllocation text_allocation;
- int strong_x;
- int cursor, bound;
-
- _gtk_text_handle_set_mode (priv->text_handle, mode);
- gtk_text_get_text_allocation (self, &text_allocation);
-
- gtk_text_get_cursor_locations (self, &strong_x, NULL);
- cursor = strong_x - priv->scroll_offset;
-
- if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
- {
- int start, end;
-
- bound = gtk_text_get_selection_bound_location (self) - priv->scroll_offset;
-
- if (priv->selection_bound > priv->current_pos)
- {
- start = cursor;
- end = bound;
- }
- else
- {
- start = bound;
- end = cursor;
- }
-
- /* Update start selection bound */
- gtk_text_move_handle (self, GTK_TEXT_HANDLE_POSITION_SELECTION_START,
- start, 0, text_allocation.height);
- gtk_text_move_handle (self, GTK_TEXT_HANDLE_POSITION_SELECTION_END,
- end, 0, text_allocation.height);
- }
- else
- gtk_text_move_handle (self, GTK_TEXT_HANDLE_POSITION_CURSOR,
- cursor, 0, text_allocation.height);
-}
-
-static void
gesture_get_current_point_in_layout (GtkGestureSingle *gesture,
GtkText *self,
int *x,
@@ -4119,32 +4154,6 @@ gtk_text_reset_layout (GtkText *self)
}
static void
-update_im_cursor_location (GtkText *self)
-{
- GtkTextPrivate *priv = gtk_text_get_instance_private (self);
- GdkRectangle area;
- GtkAllocation text_area;
- int strong_x;
- int strong_xoffset;
-
- gtk_text_get_cursor_locations (self, &strong_x, NULL);
- gtk_text_get_text_allocation (self, &text_area);
-
- strong_xoffset = strong_x - priv->scroll_offset;
- if (strong_xoffset < 0)
- strong_xoffset = 0;
- else if (strong_xoffset > text_area.width)
- strong_xoffset = text_area.width;
-
- area.x = strong_xoffset;
- area.y = 0;
- area.width = 0;
- area.height = text_area.height;
-
- gtk_im_context_set_cursor_location (priv->im_context, &area);
-}
-
-static void
gtk_text_recompute (GtkText *self)
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);