static void gtk_text_view_selection_bubble_popup_unset (GtkTextView *text_view);
static void gtk_text_view_selection_bubble_popup_set (GtkTextView *text_view);
-static void gtk_text_view_get_rendered_rect (GtkTextView *text_view,
- GdkRectangle *rect);
-
static gboolean gtk_text_view_extend_selection (GtkTextView *text_view,
GtkTextExtendSelection granularity,
const GtkTextIter *location,
static void text_window_free (GtkTextWindow *win);
static void text_window_size_allocate (GtkTextWindow *win,
GdkRectangle *rect);
-static void text_window_invalidate_rect (GtkTextWindow *win,
- GdkRectangle *rect);
-static void text_window_invalidate_cursors (GtkTextWindow *win);
+static void text_window_invalidate (GtkTextWindow *win);
static gint text_window_get_width (GtkTextWindow *win);
static gint text_window_get_height (GtkTextWindow *win);
GtkTextView *text_view;
GtkTextViewPrivate *priv;
GtkWidget *widget;
- GdkRectangle visible_rect;
- GdkRectangle redraw_rect;
text_view = GTK_TEXT_VIEW (data);
priv = text_view->priv;
if (gtk_widget_get_realized (widget))
{
- gtk_text_view_get_rendered_rect (text_view, &visible_rect);
+ text_window_invalidate (priv->text_window);
- redraw_rect.x = visible_rect.x;
- redraw_rect.width = visible_rect.width;
- redraw_rect.y = start_y;
+ DV(g_print(" invalidated rect: %d,%d %d x %d\n",
+ redraw_rect.x,
+ redraw_rect.y,
+ redraw_rect.width,
+ redraw_rect.height));
+
+ if (priv->left_window)
+ text_window_invalidate (priv->left_window);
+ if (priv->right_window)
+ text_window_invalidate (priv->right_window);
+ if (priv->top_window)
+ text_window_invalidate (priv->top_window);
+ if (priv->bottom_window)
+ text_window_invalidate (priv->bottom_window);
- if (old_height == new_height)
- redraw_rect.height = old_height;
- else if (start_y + old_height > visible_rect.y)
- redraw_rect.height = MAX (0, visible_rect.y + visible_rect.height - start_y);
- else
- redraw_rect.height = 0;
-
- if (gdk_rectangle_intersect (&redraw_rect, &visible_rect, &redraw_rect))
- {
- /* text_window_invalidate_rect() takes buffer coordinates */
- text_window_invalidate_rect (priv->text_window,
- &redraw_rect);
-
- DV(g_print(" invalidated rect: %d,%d %d x %d\n",
- redraw_rect.x,
- redraw_rect.y,
- redraw_rect.width,
- redraw_rect.height));
-
- if (priv->left_window)
- text_window_invalidate_rect (priv->left_window,
- &redraw_rect);
- if (priv->right_window)
- text_window_invalidate_rect (priv->right_window,
- &redraw_rect);
- if (priv->top_window)
- text_window_invalidate_rect (priv->top_window,
- &redraw_rect);
- if (priv->bottom_window)
- text_window_invalidate_rect (priv->bottom_window,
- &redraw_rect);
-
- queue_update_im_spot_location (text_view);
- }
+ queue_update_im_spot_location (text_view);
}
if (old_height != new_height)
priv->blink_time += get_cursor_time (text_view);
}
- /* Block changed_handler while changing the layout's cursor visibility
- * because it would expose the whole paragraph. Instead, we expose
- * the cursor's area(s) manually below.
- */
- g_signal_handlers_block_by_func (priv->layout,
- changed_handler,
- text_view);
gtk_text_layout_set_cursor_visible (priv->layout, !visible);
- g_signal_handlers_unblock_by_func (priv->layout,
- changed_handler,
- text_view);
-
- text_window_invalidate_cursors (priv->text_window);
/* Remove ourselves */
return FALSE;
{
GtkTextViewPrivate *priv = text_view->priv;
- if (priv->text_window)
- text_window_invalidate_cursors (priv->text_window);
-
priv->overwrite_mode = !priv->overwrite_mode;
if (priv->layout)
priv->overwrite_mode && priv->editable);
if (priv->text_window)
- text_window_invalidate_cursors (priv->text_window);
+ text_window_invalidate (priv->text_window);
gtk_text_view_pend_cursor_blink (text_view);
g_slice_free (GtkTextWindow, win);
}
-static void
-gtk_text_view_get_rendered_rect (GtkTextView *text_view,
- GdkRectangle *rect)
-{
- GtkTextViewPrivate *priv = text_view->priv;
-
- rect->x = gtk_adjustment_get_value (priv->hadjustment);
- rect->y = gtk_adjustment_get_value (priv->vadjustment) - priv->top_margin;
-
- rect->height = text_window_get_height (priv->text_window);
- rect->width = text_window_get_width (priv->text_window);
-}
-
static void
text_window_size_allocate (GtkTextWindow *win,
GdkRectangle *rect)
}
static void
-text_window_invalidate_rect (GtkTextWindow *win,
- GdkRectangle *rect)
-{
- GtkTextViewPrivate *priv = GTK_TEXT_VIEW (win->widget)->priv;
- GdkRectangle window_rect;
-
- /* TODO: Remove this and fix the actual invalidation? */
- gtk_widget_queue_draw (GTK_WIDGET (win->widget));
- return;
-
- gtk_text_view_buffer_to_surface_coords (GTK_TEXT_VIEW (win->widget),
- win->type,
- rect->x,
- rect->y,
- &window_rect.x,
- &window_rect.y);
-
- window_rect.width = rect->width;
- window_rect.height = rect->height;
-
- /* Adjust the rect as appropriate */
-
- switch (win->type)
- {
- case GTK_TEXT_WINDOW_TEXT:
- window_rect.x -= priv->xoffset;
- window_rect.y -= priv->yoffset;
- break;
-
- case GTK_TEXT_WINDOW_LEFT:
- case GTK_TEXT_WINDOW_RIGHT:
- window_rect.x = 0;
- window_rect.y -= priv->yoffset;
- window_rect.width = win->allocation.width;
- break;
-
- case GTK_TEXT_WINDOW_TOP:
- case GTK_TEXT_WINDOW_BOTTOM:
- window_rect.x -= priv->xoffset;
- window_rect.y = 0;
- window_rect.height = win->allocation.height;
- break;
-
- case GTK_TEXT_WINDOW_PRIVATE:
- case GTK_TEXT_WINDOW_WIDGET:
- default:
- g_warning ("%s: bug!", G_STRFUNC);
- return;
- break;
- }
-
- window_rect.x += win->allocation.x;
- window_rect.y += win->allocation.y;
- if (!gdk_rectangle_intersect (&window_rect, &win->allocation, &window_rect))
- return;
-
- gtk_widget_queue_draw_area (win->widget,
- window_rect.x, window_rect.y,
- window_rect.width, window_rect.height);
-}
-
-static void
-text_window_invalidate_cursors (GtkTextWindow *win)
+text_window_invalidate (GtkTextWindow *win)
{
- GtkTextView *text_view;
- GtkTextViewPrivate *priv;
- GtkTextIter iter;
- GdkRectangle strong;
- GdkRectangle weak;
- gboolean draw_arrow;
- gint stem_width;
- gint arrow_width;
-
- text_view = GTK_TEXT_VIEW (win->widget);
- priv = text_view->priv;
-
- gtk_text_buffer_get_iter_at_mark (priv->buffer, &iter,
- gtk_text_buffer_get_insert (priv->buffer));
-
- if (_gtk_text_layout_get_block_cursor (priv->layout, &strong))
- {
- text_window_invalidate_rect (win, &strong);
- return;
- }
-
- gtk_text_layout_get_cursor_locations (priv->layout, &iter,
- &strong, &weak);
-
- /* cursor width calculation as in gtkstylecontext.c:draw_insertion_cursor(),
- * ignoring the text direction be exposing both sides of the cursor
- */
-
- draw_arrow = (strong.x != weak.x || strong.y != weak.y);
-
- stem_width = strong.height * CURSOR_ASPECT_RATIO + 1;
- arrow_width = stem_width + 1;
-
- strong.width = stem_width;
-
- /* round up to the next even number */
- if (stem_width & 1)
- stem_width++;
-
- strong.x -= stem_width / 2;
- strong.width += stem_width;
-
- if (draw_arrow)
- {
- strong.x -= arrow_width;
- strong.width += arrow_width * 2;
- }
-
- text_window_invalidate_rect (win, &strong);
-
- if (draw_arrow) /* == have weak */
- {
- stem_width = weak.height * CURSOR_ASPECT_RATIO + 1;
- arrow_width = stem_width + 1;
-
- weak.width = stem_width;
-
- /* round up to the next even number */
- if (stem_width & 1)
- stem_width++;
-
- weak.x -= stem_width / 2;
- weak.width += stem_width;
-
- weak.x -= arrow_width;
- weak.width += arrow_width * 2;
-
- text_window_invalidate_rect (win, &weak);
- }
+ gtk_widget_queue_draw (win->widget);
}
static gint
gtk_widget_set_focus_child (priv->parent, NULL);
if (_gtk_widget_is_drawable (priv->parent))
- gtk_widget_queue_draw_area (priv->parent,
- priv->clip.x,
- priv->clip.y,
- priv->clip.width,
- priv->clip.height);
+ gtk_widget_queue_draw (priv->parent);
if (priv->visible && _gtk_widget_get_visible (priv->parent))
gtk_widget_queue_resize (priv->parent);
gdk_paintable_invalidate_size (l->data);
}
-static void
-gtk_widget_real_queue_draw (GtkWidget *widget)
-{
- for (; widget; widget = _gtk_widget_get_parent (widget))
- {
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
- if (priv->draw_needed)
- break;
-
- priv->draw_needed = TRUE;
- g_clear_pointer (&priv->render_node, gsk_render_node_unref);
- gtk_widget_invalidate_paintable_contents (widget);
- if (_gtk_widget_get_has_surface (widget) &&
- _gtk_widget_get_realized (widget))
- gdk_surface_queue_expose (gtk_widget_get_surface (widget));
- }
-}
-
-/**
- * gtk_widget_queue_draw_area:
- * @widget: a #GtkWidget
- * @x: x coordinate of upper-left corner of rectangle to redraw
- * @y: y coordinate of upper-left corner of rectangle to redraw
- * @width: width of region to draw
- * @height: height of region to draw
- *
- * Convenience function that calls gtk_widget_queue_draw_region() on
- * the region created from the given coordinates.
- *
- * The region here is specified in widget coordinates of @widget.
- *
- * @width or @height may be 0, in this case this function does
- * nothing. Negative values for @width and @height are not allowed.
- */
-void
-gtk_widget_queue_draw_area (GtkWidget *widget,
- gint x,
- gint y,
- gint width,
- gint height)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- /* Just return if the widget isn't mapped */
- if (!_gtk_widget_get_mapped (widget))
- return;
-
- gtk_widget_real_queue_draw (widget);
-}
-
/**
* gtk_widget_queue_draw:
* @widget: a #GtkWidget
if (!_gtk_widget_get_mapped (widget))
return;
- gtk_widget_real_queue_draw (widget);
+ for (; widget; widget = _gtk_widget_get_parent (widget))
+ {
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ if (priv->draw_needed)
+ break;
+
+ priv->draw_needed = TRUE;
+ g_clear_pointer (&priv->render_node, gsk_render_node_unref);
+ gtk_widget_invalidate_paintable_contents (widget);
+ if (_gtk_widget_get_has_surface (widget) &&
+ _gtk_widget_get_realized (widget))
+ gdk_surface_queue_expose (gtk_widget_get_surface (widget));
+ }
}
static void
border->right = get_number (style, GTK_CSS_PROPERTY_PADDING_RIGHT);
}
-/**
- * gtk_widget_queue_draw_region:
- * @widget: a #GtkWidget
- * @region: region to draw, in @widget's coordinates
- *
- * Invalidates the area of @widget defined by @region. Makes sure
- * that the compositor updates the speicifed region of the toplevel
- * window.
- *
- * Normally you would only use this function in widget
- * implementations. You might also use it to schedule a redraw of a
- * #GtkDrawingArea or some portion thereof.
- **/
-void
-gtk_widget_queue_draw_region (GtkWidget *widget,
- const cairo_region_t *region)
-{
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- /* Just return if the widget isn't mapped */
- if (!_gtk_widget_get_mapped (widget))
- return;
-
- gtk_widget_real_queue_draw (widget);
-}
-
/**
* gtk_widget_size_allocate:
* @widget: a #GtkWidget
position_changed |= (old_clip.x != priv->clip.x ||
old_clip.y != priv->clip.y);
- if (_gtk_widget_get_mapped (widget))
- {
- if (position_changed || size_changed || baseline_changed)
- {
- /* Invalidate union(old_clip,priv->clip) in the toplevel's window
- */
- GtkWidget *parent = _gtk_widget_get_parent (widget);
- cairo_region_t *invalidate = cairo_region_create_rectangle (&priv->clip);
- cairo_region_union_rectangle (invalidate, &old_clip);
-
- /* Use the parent here since that's what priv->allocation and priv->clip
- * are relative to */
- gtk_widget_queue_draw_region (parent ? parent : widget, invalidate);
- cairo_region_destroy (invalidate);
- gtk_widget_real_queue_draw (widget);
- }
- }
+ if (position_changed || size_changed || baseline_changed)
+ gtk_widget_queue_draw (widget);
out:
if (priv->alloc_needed_on_child)