summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@src.gnome.org>2000-03-28 01:24:44 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-03-28 01:24:44 +0000
commit8098546227671a5d082fdf8f4811ee3ffca7f6d8 (patch)
treed1857c89ee73451cbb04bbf595c0dc8bade55987 /gtk
parent4238d406e928d1afd95ab0c6ae51b6a37f9780ea (diff)
downloadgdk-pixbuf-8098546227671a5d082fdf8f4811ee3ffca7f6d8.tar.gz
Merge no-flicker branch into HEAD
Diffstat (limited to 'gtk')
-rw-r--r--gtk/.cvsignore1
-rw-r--r--gtk/Makefile.am1
-rw-r--r--gtk/gtkaspectframe.c3
-rw-r--r--gtk/gtkbin.c4
-rw-r--r--gtk/gtkcontainer.c4
-rw-r--r--gtk/gtkentry.c67
-rw-r--r--gtk/gtkhscrollbar.c3
-rw-r--r--gtk/gtklayout.c530
-rw-r--r--gtk/gtkmain.c11
-rw-r--r--gtk/gtkrange.c19
-rw-r--r--gtk/gtkviewport.c10
-rw-r--r--gtk/gtkvpaned.c2
-rw-r--r--gtk/gtkvscrollbar.c3
-rw-r--r--gtk/gtkwidget.c558
-rw-r--r--gtk/gtkwidget.h18
15 files changed, 119 insertions, 1115 deletions
diff --git a/gtk/.cvsignore b/gtk/.cvsignore
index 14e0a2d72..af39208db 100644
--- a/gtk/.cvsignore
+++ b/gtk/.cvsignore
@@ -14,6 +14,7 @@ testtree
gtkcompat.h
testthreads
libgtk.la
+gtkfeatures.h
gtkmarshal.h
gtktypebuiltins.h
gtkmarshal.c
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index adbd67199..50b77f76c 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -288,6 +288,7 @@ gtk_built_sources = @STRIP_BEGIN@ \
@STRIP_END@
# built sources that get installed with the header files
gtk_built_public_sources = @STRIP_BEGIN@ \
+ gtkcompat.h \
gtkmarshal.h \
gtktypebuiltins.h \
@STRIP_END@
diff --git a/gtk/gtkaspectframe.c b/gtk/gtkaspectframe.c
index 788399fb5..3d084b1c9 100644
--- a/gtk/gtkaspectframe.c
+++ b/gtk/gtkaspectframe.c
@@ -238,9 +238,6 @@ gtk_aspect_frame_set (GtkAspectFrame *aspect_frame,
aspect_frame->ratio = ratio;
aspect_frame->obey_child = obey_child;
- if (GTK_WIDGET_DRAWABLE(widget))
- gtk_widget_queue_clear (widget);
-
gtk_widget_queue_resize (widget);
}
}
diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c
index bfb3dfadf..d5100ba3a 100644
--- a/gtk/gtkbin.c
+++ b/gtk/gtkbin.c
@@ -147,9 +147,7 @@ gtk_bin_unmap (GtkWidget *widget)
GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
bin = GTK_BIN (widget);
- if (GTK_WIDGET_NO_WINDOW (widget))
- gtk_widget_queue_clear (widget);
- else
+ if (!GTK_WIDGET_NO_WINDOW (widget))
gdk_window_hide (widget->window);
if (bin->child && GTK_WIDGET_MAPPED (bin->child))
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 2e9367bb5..5e3fbd149 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -847,8 +847,10 @@ gtk_container_idle_sizer (gpointer data)
gtk_container_check_resize (GTK_CONTAINER (widget));
}
+ gdk_window_process_all_updates ();
+
GDK_THREADS_LEAVE ();
-
+
return FALSE;
}
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 6cc62ad2e..50db536b0 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -826,14 +826,25 @@ static void
gtk_entry_draw (GtkWidget *widget,
GdkRectangle *area)
{
+ GtkEntry *entry;
+
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_ENTRY (widget));
g_return_if_fail (area != NULL);
+ entry = GTK_ENTRY (widget);
+
if (GTK_WIDGET_DRAWABLE (widget))
{
+ GdkRectangle tmp_area = *area;
+
+ tmp_area.x -= widget->style->klass->xthickness;
+ tmp_area.y -= widget->style->klass->xthickness;
+
+ gdk_window_begin_paint_rect (entry->text_area, &tmp_area);
gtk_widget_draw_focus (widget);
gtk_entry_draw_text (GTK_ENTRY (widget));
+ gdk_window_end_paint (entry->text_area);
}
}
@@ -1295,7 +1306,6 @@ gtk_entry_draw_text (GtkEntry *entry)
gint width, height;
gint y;
GdkDrawable *drawable;
- gint use_backing_pixmap;
GdkWChar *stars;
GdkWChar *toprint;
@@ -1327,25 +1337,10 @@ gtk_entry_draw_text (GtkEntry *entry)
gdk_window_get_size (entry->text_area, &width, &height);
- /*
- If the widget has focus, draw on a backing pixmap to avoid flickering
- and copy it to the text_area.
- Otherwise draw to text_area directly for better speed.
- */
- use_backing_pixmap = GTK_WIDGET_HAS_FOCUS (widget) && (entry->text != NULL);
- if (use_backing_pixmap)
- {
- gtk_entry_make_backing_pixmap (entry, width, height);
- drawable = entry->backing_pixmap;
- }
- else
- {
- drawable = entry->text_area;
- }
- gtk_paint_flat_box (widget->style, drawable,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
- NULL, widget, "entry_bg",
- 0, 0, width, height);
+ gtk_paint_flat_box (widget->style, entry->text_area,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
+ NULL, widget, "entry_bg",
+ 0, 0, width, height);
y = (height - (widget->style->font->ascent + widget->style->font->descent)) / 2;
y += widget->style->font->ascent;
@@ -1388,7 +1383,7 @@ gtk_entry_draw_text (GtkEntry *entry)
}
if (selection_start_pos > start_pos)
- gdk_draw_text_wc (drawable, widget->style->font,
+ gdk_draw_text_wc (entry->text_area, widget->style->font,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
INNER_BORDER + start_xoffset, y,
toprint,
@@ -1398,14 +1393,14 @@ gtk_entry_draw_text (GtkEntry *entry)
(selection_start_pos < end_pos) &&
(selection_start_pos != selection_end_pos))
{
- gtk_paint_flat_box (widget->style, drawable,
+ gtk_paint_flat_box (widget->style, entry->text_area,
selected_state, GTK_SHADOW_NONE,
NULL, widget, "text",
INNER_BORDER + selection_start_xoffset,
INNER_BORDER,
selection_end_xoffset - selection_start_xoffset,
height - 2*INNER_BORDER);
- gdk_draw_text_wc (drawable, widget->style->font,
+ gdk_draw_text_wc (entry->text_area, widget->style->font,
widget->style->fg_gc[selected_state],
INNER_BORDER + selection_start_xoffset, y,
toprint + selection_start_pos - start_pos,
@@ -1413,7 +1408,7 @@ gtk_entry_draw_text (GtkEntry *entry)
}
if (selection_end_pos < end_pos)
- gdk_draw_text_wc (drawable, widget->style->font,
+ gdk_draw_text_wc (entry->text_area, widget->style->font,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
INNER_BORDER + selection_end_xoffset, y,
toprint + selection_end_pos - start_pos,
@@ -1423,13 +1418,7 @@ gtk_entry_draw_text (GtkEntry *entry)
g_free (toprint);
if (editable->editable)
- gtk_entry_draw_cursor_on_drawable (entry, drawable);
-
- if (use_backing_pixmap)
- gdk_draw_pixmap(entry->text_area,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- entry->backing_pixmap,
- 0, 0, 0, 0, width, height);
+ gtk_entry_draw_cursor_on_drawable (entry, entry->text_area);
}
}
@@ -1472,16 +1461,26 @@ gtk_entry_draw_cursor_on_drawable (GtkEntry *entry, GdkDrawable *drawable)
}
else
{
+ int width, height;
+ GdkRectangle area;
+
gint yoffset =
(text_area_height -
(widget->style->font->ascent + widget->style->font->descent)) / 2
+ widget->style->font->ascent;
+ area.x = xoffset;
+ area.y = INNER_BORDER;
+ area.width = 1;
+ area.height = text_area_height - INNER_BORDER;
+
+ gdk_window_get_size (entry->text_area, &width, &height);
+
gtk_paint_flat_box (widget->style, drawable,
GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
- NULL, widget, "entry_bg",
- xoffset, INNER_BORDER,
- 1, text_area_height - INNER_BORDER);
+ &area, widget, "entry_bg",
+ 0, 0, width, height);
+
/* Draw the character under the cursor again
*/
diff --git a/gtk/gtkhscrollbar.c b/gtk/gtkhscrollbar.c
index 64ac38d4c..9ab5fa875 100644
--- a/gtk/gtkhscrollbar.c
+++ b/gtk/gtkhscrollbar.c
@@ -289,9 +289,6 @@ gtk_hscrollbar_size_allocate (GtkWidget *widget,
widget->style->klass->ythickness,
RANGE_CLASS (widget)->stepper_size,
widget->requisition.height - widget->style->klass->ythickness * 2);
- gdk_window_resize (range->slider,
- RANGE_CLASS (widget)->min_slider_size,
- widget->requisition.height - widget->style->klass->ythickness * 2);
gtk_range_slider_update (GTK_RANGE (widget));
}
diff --git a/gtk/gtklayout.c b/gtk/gtklayout.c
index bd21eead6..a57e52df1 100644
--- a/gtk/gtklayout.c
+++ b/gtk/gtklayout.c
@@ -30,33 +30,18 @@
#include "gdkconfig.h"
-#if defined (GDK_WINDOWING_X11)
-#include "x11/gdkx.h"
-#elif defined (GDK_WINDOWING_WIN32)
-#include "win32/gdkwin32.h"
-#endif
-
#include "gtklayout.h"
#include "gtksignal.h"
#include "gtkprivate.h"
-typedef struct _GtkLayoutAdjData GtkLayoutAdjData;
typedef struct _GtkLayoutChild GtkLayoutChild;
-struct _GtkLayoutAdjData {
- gint dx;
- gint dy;
-};
-
struct _GtkLayoutChild {
GtkWidget *widget;
gint x;
gint y;
};
-#define IS_ONSCREEN(x,y) ((x >= G_MINSHORT) && (x <= G_MAXSHORT) && \
- (y >= G_MINSHORT) && (y <= G_MAXSHORT))
-
static void gtk_layout_class_init (GtkLayoutClass *class);
static void gtk_layout_init (GtkLayout *layout);
@@ -83,33 +68,14 @@ static void gtk_layout_set_adjustments (GtkLayout *layout,
GtkAdjustment *hadj,
GtkAdjustment *vadj);
-static void gtk_layout_position_child (GtkLayout *layout,
- GtkLayoutChild *child);
static void gtk_layout_allocate_child (GtkLayout *layout,
GtkLayoutChild *child);
-static void gtk_layout_position_children (GtkLayout *layout);
-
-static void gtk_layout_adjust_allocations_recurse (GtkWidget *widget,
- gpointer cb_data);
-static void gtk_layout_adjust_allocations (GtkLayout *layout,
- gint dx,
- gint dy);
-
-static void gtk_layout_expose_area (GtkLayout *layout,
- gint x,
- gint y,
- gint width,
- gint height);
static void gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
GtkLayout *layout);
-static GdkFilterReturn gtk_layout_main_filter (GdkXEvent *gdk_xevent,
- GdkEvent *event,
- gpointer data);
static GtkWidgetClass *parent_class = NULL;
-static gboolean gravity_works;
/* Public interface
*/
@@ -261,9 +227,6 @@ gtk_layout_put (GtkLayout *layout,
if (GTK_WIDGET_REALIZED (layout))
gtk_widget_set_parent_window (child->widget, layout->bin_window);
- if (!IS_ONSCREEN (x, y))
- GTK_PRIVATE_SET_FLAG (child_widget, GTK_IS_OFFSCREEN);
-
if (GTK_WIDGET_REALIZED (layout))
gtk_widget_realize (child_widget);
@@ -323,6 +286,9 @@ gtk_layout_set_size (GtkLayout *layout,
layout->vadjustment->upper = layout->height;
gtk_signal_emit_by_name (GTK_OBJECT (layout->vadjustment), "changed");
+
+ if (GTK_WIDGET_REALIZED (layout))
+ gdk_window_resize (layout->bin_window, width, height);
}
void
@@ -342,10 +308,7 @@ gtk_layout_thaw (GtkLayout *layout)
if (layout->freeze_count)
if (!(--layout->freeze_count))
- {
- gtk_layout_position_children (layout);
- gtk_widget_draw (GTK_WIDGET (layout), NULL);
- }
+ gtk_widget_draw (GTK_WIDGET (layout), NULL);
}
/* Basic Object handling procedures
@@ -467,7 +430,9 @@ gtk_layout_realize (GtkWidget *widget)
attributes.x = 0;
attributes.y = 0;
- attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK |
+ attributes.width = layout->width;
+ attributes.height = layout->height;
+ attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK |
gtk_widget_get_events (widget);
layout->bin_window = gdk_window_new (widget->window,
@@ -478,15 +443,6 @@ gtk_layout_realize (GtkWidget *widget)
gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
gtk_style_set_background (widget->style, layout->bin_window, GTK_STATE_NORMAL);
- gdk_window_add_filter (widget->window, gtk_layout_main_filter, layout);
- /* gdk_window_add_filter (layout->bin_window, gtk_layout_filter, layout);*/
-
- /* XXX: If we ever get multiple displays for GTK+, then gravity_works
- * will have to become a widget member. Right now we just
- * keep it as a global
- */
- gravity_works = gdk_window_set_static_gravities (layout->bin_window, TRUE);
-
tmp_list = layout->children;
while (tmp_list)
{
@@ -595,7 +551,6 @@ gtk_layout_size_allocate (GtkWidget *widget,
GtkLayoutChild *child = tmp_list->data;
tmp_list = tmp_list->next;
- gtk_layout_position_child (layout, child);
gtk_layout_allocate_child (layout, child);
}
@@ -604,9 +559,6 @@ gtk_layout_size_allocate (GtkWidget *widget,
gdk_window_move_resize (widget->window,
allocation->x, allocation->y,
allocation->width, allocation->height);
- gdk_window_move_resize (GTK_LAYOUT(widget)->bin_window,
- 0, 0,
- allocation->width, allocation->height);
}
layout->hadjustment->page_size = allocation->width;
@@ -749,38 +701,6 @@ gtk_layout_forall (GtkContainer *container,
*/
static void
-gtk_layout_position_child (GtkLayout *layout,
- GtkLayoutChild *child)
-{
- gint x;
- gint y;
-
- x = child->x - layout->xoffset;
- y = child->y - layout->yoffset;
-
- if (IS_ONSCREEN (x,y))
- {
- if (GTK_WIDGET_MAPPED (layout) &&
- GTK_WIDGET_VISIBLE (child->widget))
- {
- if (!GTK_WIDGET_MAPPED (child->widget))
- gtk_widget_map (child->widget);
- }
-
- if (GTK_WIDGET_IS_OFFSCREEN (child->widget))
- GTK_PRIVATE_UNSET_FLAG (child->widget, GTK_IS_OFFSCREEN);
- }
- else
- {
- if (!GTK_WIDGET_IS_OFFSCREEN (child->widget))
- GTK_PRIVATE_SET_FLAG (child->widget, GTK_IS_OFFSCREEN);
-
- if (GTK_WIDGET_MAPPED (child->widget))
- gtk_widget_unmap (child->widget);
- }
-}
-
-static void
gtk_layout_allocate_child (GtkLayout *layout,
GtkLayoutChild *child)
{
@@ -796,451 +716,25 @@ gtk_layout_allocate_child (GtkLayout *layout,
gtk_widget_size_allocate (child->widget, &allocation);
}
-static void
-gtk_layout_position_children (GtkLayout *layout)
-{
- GList *tmp_list;
-
- tmp_list = layout->children;
- while (tmp_list)
- {
- GtkLayoutChild *child = tmp_list->data;
- tmp_list = tmp_list->next;
-
- gtk_layout_position_child (layout, child);
- }
-}
-
-static void
-gtk_layout_adjust_allocations_recurse (GtkWidget *widget,
- gpointer cb_data)
-{
- GtkLayoutAdjData *data = cb_data;
-
- widget->allocation.x += data->dx;
- widget->allocation.y += data->dy;
-
- if (GTK_WIDGET_NO_WINDOW (widget) &&
- GTK_IS_CONTAINER (widget))
- gtk_container_forall (GTK_CONTAINER (widget),
- gtk_layout_adjust_allocations_recurse,
- cb_data);
-}
-
-static void
-gtk_layout_adjust_allocations (GtkLayout *layout,
- gint dx,
- gint dy)
-{
- GList *tmp_list;
- GtkLayoutAdjData data;
-
- data.dx = dx;
- data.dy = dy;
-
- tmp_list = layout->children;
- while (tmp_list)
- {
- GtkLayoutChild *child = tmp_list->data;
- tmp_list = tmp_list->next;
-
- child->widget->allocation.x += dx;
- child->widget->allocation.y += dy;
-
- if (GTK_WIDGET_NO_WINDOW (child->widget) &&
- GTK_IS_CONTAINER (child->widget))
- gtk_container_forall (GTK_CONTAINER (child->widget),
- gtk_layout_adjust_allocations_recurse,
- &data);
- }
-}
-
/* Callbacks */
-/* Send a synthetic expose event to the widget
- */
-static void
-gtk_layout_expose_area (GtkLayout *layout,
- gint x, gint y, gint width, gint height)
-{
- if (layout->visibility == GDK_VISIBILITY_UNOBSCURED)
- {
- GdkEventExpose event;
-
- event.type = GDK_EXPOSE;
- event.send_event = TRUE;
- event.window = layout->bin_window;
- event.count = 0;
-
- event.area.x = x;
- event.area.y = y;
- event.area.width = width;
- event.area.height = height;
-
- gdk_window_ref (event.window);
- gtk_widget_event (GTK_WIDGET (layout), (GdkEvent *)&event);
- gdk_window_unref (event.window);
- }
-}
-
-#ifdef GDK_WINDOWING_X11
-
-/* This function is used to find events to process while scrolling
- */
-
-static Bool
-gtk_layout_expose_predicate (Display *display,
- XEvent *xevent,
- XPointer arg)
-{
- if ((xevent->type == Expose) ||
- ((xevent->xany.window == *(Window *)arg) &&
- (xevent->type == ConfigureNotify)))
- return True;
- else
- return False;
-}
-
-#endif /* X11 */
-
-/* This is the main routine to do the scrolling. Scrolling is
- * done by "Guffaw" scrolling, as in the Mozilla XFE, with
- * a few modifications.
- *
- * The main improvement is that we keep track of whether we
- * are obscured or not. If not, we ignore the generated expose
- * events and instead do the exposes ourself, without having
- * to wait for a roundtrip to the server. This also provides
- * a limited form of expose-event compression, since we do
- * the affected area as one big chunk.
- *
- * Real expose event compression, as in the XFE, could be added
- * here. It would help opaque drags over the region, and the
- * obscured case.
- *
- * Code needs to be added here to do the scrolling on machines
- * that don't have working WindowGravity. That could be done
- *
- * - XCopyArea and move the windows, and accept trailing the
- * background color. (Since it is only a fallback method)
- * - XmHTML style. As above, but turn off expose events when
- * not obscured and do the exposures ourself.
- * - gzilla-style. Move the window continuously, and reset
- * every 32768 pixels
- */
-
static void
gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
GtkLayout *layout)
{
GtkWidget *widget;
-#ifdef GDK_WINDOWING_X11
- XEvent xevent;
-#endif
- gint dx, dy;
widget = GTK_WIDGET (layout);
- dx = (gint)layout->hadjustment->value - layout->xoffset;
- dy = (gint)layout->vadjustment->value - layout->yoffset;
-
- layout->xoffset = (gint)layout->hadjustment->value;
- layout->yoffset = (gint)layout->vadjustment->value;
-
if (layout->freeze_count)
return;
- if (!GTK_WIDGET_MAPPED (layout))
- {
- gtk_layout_position_children (layout);
- return;
- }
-
- gtk_layout_adjust_allocations (layout, -dx, -dy);
-
- if (dx > 0)
- {
- if (gravity_works)
- {
- gdk_window_resize (layout->bin_window,
- widget->allocation.width + dx,
- widget->allocation.height);
- gdk_window_move (layout->bin_window, -dx, 0);
- gdk_window_move_resize (layout->bin_window,
- 0, 0,
- widget->allocation.width,
- widget->allocation.height);
- }
- else
- {
- /* FIXME */
- }
-
- gtk_layout_expose_area (layout,
- MAX ((gint)widget->allocation.width - dx, 0),
- 0,
- MIN (dx, widget->allocation.width),
- widget->allocation.height);
- }
- else if (dx < 0)
- {
- if (gravity_works)
- {
- gdk_window_move_resize (layout->bin_window,
- dx, 0,
- widget->allocation.width - dx,
- widget->allocation.height);
- gdk_window_move (layout->bin_window, 0, 0);
- gdk_window_resize (layout->bin_window,
- widget->allocation.width,
- widget->allocation.height);
- }
- else
- {
- /* FIXME */
- }
-
- gtk_layout_expose_area (layout,
- 0,
- 0,
- MIN (-dx, widget->allocation.width),
- widget->allocation.height);
- }
-
- if (dy > 0)
- {
- if (gravity_works)
- {
- gdk_window_resize (layout->bin_window,
- widget->allocation.width,
- widget->allocation.height + dy);
- gdk_window_move (layout->bin_window, 0, -dy);
- gdk_window_move_resize (layout->bin_window,
- 0, 0,
- widget->allocation.width,
- widget->allocation.height);
- }
- else
- {
- /* FIXME */
- }
-
- gtk_layout_expose_area (layout,
- 0,
- MAX ((gint)widget->allocation.height - dy, 0),
- widget->allocation.width,
- MIN (dy, widget->allocation.height));
- }
- else if (dy < 0)
- {
- if (gravity_works)
- {
- gdk_window_move_resize (layout->bin_window,
- 0, dy,
- widget->allocation.width,
- widget->allocation.height - dy);
- gdk_window_move (layout->bin_window, 0, 0);
- gdk_window_resize (layout->bin_window,
- widget->allocation.width,
- widget->allocation.height);
- }
- else
- {
- /* FIXME */
- }
- gtk_layout_expose_area (layout,
- 0,
- 0,
- widget->allocation.width,
- MIN (-dy, (gint)widget->allocation.height));
- }
-
- gtk_layout_position_children (layout);
-
- /* We have to make sure that all exposes from this scroll get
- * processed before we scroll again, or the expose events will
- * have invalid coordinates.
- *
- * We also do expose events for other windows, since otherwise
- * their updating will fall behind the scrolling
- *
- * This also avoids a problem in pre-1.0 GTK where filters don't
- * have access to configure events that were compressed.
- */
-
- gdk_flush();
-
-#ifdef GDK_WINDOWING_X11
- while (XCheckIfEvent(GDK_WINDOW_XDISPLAY (layout->bin_window),
- &xevent,
- gtk_layout_expose_predicate,
- (XPointer)&GDK_WINDOW_XWINDOW (layout->bin_window)))
- {
- GdkEvent event;
- GtkWidget *event_widget;
-
- switch (xevent.type)
- {
- case Expose:
-
- if (xevent.xany.window == GDK_WINDOW_XWINDOW (layout->bin_window))
- {
- /* If the window is unobscured, then we've exposed the
- * regions with the following serials already, so we
- * can throw out the expose events.
- */
- if (layout->visibility == GDK_VISIBILITY_UNOBSCURED &&
- (((dx > 0 || dy > 0) &&
- xevent.xexpose.serial == layout->configure_serial) ||
- ((dx < 0 || dy < 0) &&
- xevent.xexpose.serial == layout->configure_serial + 1)))
- continue;
- /* The following expose was generated while the origin was
- * different from the current origin, so we need to offset it.
- */
- else if (xevent.xexpose.serial == layout->configure_serial)
- {
- xevent.xexpose.x += layout->scroll_x;
- xevent.xexpose.y += layout->scroll_y;
- }
- event.expose.window = layout->bin_window;
- event_widget = widget;
- }
- else
- {
- event.expose.window = gdk_window_lookup (xevent.xany.window);
- gdk_window_get_user_data (event.expose.window,
- (gpointer *)&event_widget);
- }
-
- if (event_widget)
- {
- event.expose.type = GDK_EXPOSE;
- event.expose.area.x = xevent.xexpose.x;
- event.expose.area.y = xevent.xexpose.y;
- event.expose.area.width = xevent.xexpose.width;
- event.expose.area.height = xevent.xexpose.height;
- event.expose.count = xevent.xexpose.count;
-
- gdk_window_ref (event.expose.window);
- gtk_widget_event (event_widget, &event);
- gdk_window_unref (event.expose.window);
- }
- break;
-
- case ConfigureNotify:
- if (xevent.xany.window == GDK_WINDOW_XWINDOW (layout->bin_window) &&
- (xevent.xconfigure.x != 0 || xevent.xconfigure.y != 0))
- {
- layout->configure_serial = xevent.xconfigure.serial;
- layout->scroll_x = xevent.xconfigure.x;
- layout->scroll_y = xevent.xconfigure.y;
- }
- break;
- }
- }
-#elif defined (GDK_WINDOWING_WIN32)
- /* XXX Not implemented */
-#endif
-}
-
-#if 0
-/* The main event filter. Actually, we probably don't really need
- * this filter at all, since we are calling it directly above in the
- * expose-handling hack. But in case scrollbars
- * are fixed up in some manner...
- *
- * This routine identifies expose events that are generated when
- * we've temporarily moved the bin_window_origin, and translates
- * them or discards them, depending on whether we are obscured
- * or not.
- */
-static GdkFilterReturn
-gtk_layout_filter (GdkXEvent *gdk_xevent,
- GdkEvent *event,
- gpointer data)
-{
-#ifdef GDK_WINDOWING_X11
-
- XEvent *xevent;
- GtkLayout *layout;
-
- xevent = (XEvent *)gdk_xevent;
- layout = GTK_LAYOUT (data);
-
- switch (xevent->type)
+ if (GTK_WIDGET_REALIZED (layout))
{
- case Expose:
- if (xevent->xexpose.serial == layout->configure_serial)
- {
- if (layout->visibility == GDK_VISIBILITY_UNOBSCURED)
- return GDK_FILTER_REMOVE;
- else
- {
- xevent->xexpose.x += layout->scroll_x;
- xevent->xexpose.y += layout->scroll_y;
-
- break;
- }
- }
- break;
+ gdk_window_move (layout->bin_window,
+ - layout->hadjustment->value,
+ - layout->vadjustment->value);
- case ConfigureNotify:
- if ((xevent->xconfigure.x != 0) || (xevent->xconfigure.y != 0))
- {
- layout->configure_serial = xevent->xconfigure.serial;
- layout->scroll_x = xevent->xconfigure.x;
- layout->scroll_y = xevent->xconfigure.y;
- }
- break;
- }
-#elif defined (GDK_WINDOWING_WIN32)
- /* XXX Not implemented */
-#endif
-
- return GDK_FILTER_CONTINUE;
-}
-#endif 0
-
-/* Although GDK does have a GDK_VISIBILITY_NOTIFY event,
- * there is no corresponding event in GTK, so we have
- * to get the events from a filter
- */
-static GdkFilterReturn
-gtk_layout_main_filter (GdkXEvent *gdk_xevent,
- GdkEvent *event,
- gpointer data)
-{
-#ifdef GDK_WINDOWING_X11
- XEvent *xevent;
- GtkLayout *layout;
-
- xevent = (XEvent *)gdk_xevent;
- layout = GTK_LAYOUT (data);
-
- if (xevent->type == VisibilityNotify)
- {
- switch (xevent->xvisibility.state)
- {
- case VisibilityFullyObscured:
- layout->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
- break;
-
- case VisibilityPartiallyObscured:
- layout->visibility = GDK_VISIBILITY_PARTIAL;
- break;
-
- case VisibilityUnobscured:
- layout->visibility = GDK_VISIBILITY_UNOBSCURED;
- break;
- }
-
- return GDK_FILTER_REMOVE;
+ gdk_window_process_updates (layout->bin_window, TRUE);
}
-#elif defined (GDK_WINDOWING_WIN32)
- /* XXX Not implemented */
-#endif
-
- return GDK_FILTER_CONTINUE;
}
-
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index becef2c4c..d80dfb24c 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -742,8 +742,17 @@ gtk_main_do_event (GdkEvent *event)
}
break;
- case GDK_PROPERTY_NOTIFY:
case GDK_EXPOSE:
+ if (event->any.window)
+ gdk_window_begin_paint_rect (event->any.window, &event->expose.area);
+
+ gtk_widget_event (event_widget, event);
+
+ if (event->any.window)
+ gdk_window_end_paint (event->any.window);
+ break;
+
+ case GDK_PROPERTY_NOTIFY:
case GDK_NO_EXPOSE:
case GDK_FOCUS_CHANGE:
case GDK_CONFIGURE:
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 43c2836bc..180562911 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -810,23 +810,12 @@ gtk_range_expose (GtkWidget *widget,
range = GTK_RANGE (widget);
+ /* We should really pass another argument -
+ *the redrawn area - to all the drawing functions)
+ */
if (event->window == range->trough)
{
- /* Don't redraw if we are only exposing the literal trough region.
- * this may not work correctly if someone overrides the default
- * trough-drawing handler. (Probably should really pass another
- * argument - the redrawn area to all the drawing functions)
- */
- gint xt = widget->style->klass->xthickness;
- gint yt = widget->style->klass->ythickness;
-
- if (!((event->area.x >= xt) &&
- (event->area.y >= yt) &&
- (event->area.x + event->area.width <=
- widget->allocation.width - xt) &&
- (event->area.y + event->area.height <=
- widget->allocation.height - yt)))
- gtk_range_draw_trough (range);
+ gtk_range_draw_trough (range);
}
else if (event->window == widget->window)
{
diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c
index afffdf01a..f602e9224 100644
--- a/gtk/gtkviewport.c
+++ b/gtk/gtkviewport.c
@@ -822,9 +822,13 @@ gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
child_allocation.y = viewport->vadjustment->lower - viewport->vadjustment->value;
if (GTK_WIDGET_REALIZED (viewport))
- gdk_window_move (viewport->bin_window,
- child_allocation.x,
- child_allocation.y);
+ {
+ gdk_window_move (viewport->bin_window,
+ child_allocation.x,
+ child_allocation.y);
+
+ gdk_window_process_updates (viewport->bin_window, TRUE);
+ }
}
}
diff --git a/gtk/gtkvpaned.c b/gtk/gtkvpaned.c
index 328f7587a..698dda2f8 100644
--- a/gtk/gtkvpaned.c
+++ b/gtk/gtkvpaned.c
@@ -61,7 +61,7 @@ gtk_vpaned_get_type (void)
(GtkClassInitFunc) NULL,
};
- vpaned_type = gtk_type_unique(gtk_paned_get_type(), &vpaned_info);
+ vpaned_type = gtk_type_unique (GTK_TYPE_PANED, &vpaned_info);
}
return vpaned_type;
diff --git a/gtk/gtkvscrollbar.c b/gtk/gtkvscrollbar.c
index 867069147..082fb746b 100644
--- a/gtk/gtkvscrollbar.c
+++ b/gtk/gtkvscrollbar.c
@@ -289,9 +289,6 @@ gtk_vscrollbar_size_allocate (GtkWidget *widget,
RANGE_CLASS (widget)->stepper_size,
widget->requisition.width - widget->style->klass->xthickness * 2,
RANGE_CLASS (widget)->stepper_size);
- gdk_window_resize (range->slider,
- widget->requisition.width - widget->style->klass->xthickness * 2,
- RANGE_CLASS (range)->min_slider_size);
gtk_range_slider_update (GTK_RANGE (widget));
}
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index dd844777d..88d6d13e7 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -164,9 +164,6 @@ static void gtk_widget_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_widget_real_grab_focus (GtkWidget *focus_widget);
-static void gtk_widget_redraw_queue_remove (GtkWidget *widget);
-
-
static GdkColormap* gtk_widget_peek_colormap (void);
static GdkVisual* gtk_widget_peek_visual (void);
static GtkStyle* gtk_widget_peek_style (void);
@@ -199,7 +196,6 @@ static GSList *colormap_stack = NULL;
static GSList *visual_stack = NULL;
static GSList *style_stack = NULL;
static guint composite_child_stack = 0;
-static GSList *gtk_widget_redraw_queue = NULL;
static const gchar *aux_info_key = "gtk-aux-info";
static guint aux_info_key_id = 0;
@@ -1297,9 +1293,6 @@ gtk_widget_unparent (GtkWidget *widget)
gtk_window_set_default (GTK_WINDOW (toplevel), NULL);
}
- if (GTK_WIDGET_REDRAW_PENDING (widget))
- gtk_widget_redraw_queue_remove (widget);
-
if (GTK_IS_RESIZE_CONTAINER (widget))
gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
@@ -1697,9 +1690,6 @@ gtk_widget_unrealize (GtkWidget *widget)
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- if (GTK_WIDGET_REDRAW_PENDING (widget))
- gtk_widget_redraw_queue_remove (widget);
-
if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
gtk_widget_shape_combine_mask (widget, NULL, -1, -1);
@@ -1713,124 +1703,20 @@ gtk_widget_unrealize (GtkWidget *widget)
}
/*****************************************
- * gtk_widget_queue_draw:
- *
- * arguments:
- *
- * results:
+ * Draw queueing.
*****************************************/
-typedef struct _GtkDrawData GtkDrawData;
-struct _GtkDrawData {
- GdkRectangle rect;
- GdkWindow *window;
-};
-
-static GMemChunk *draw_data_mem_chunk = NULL;
-static GSList *draw_data_free_list = NULL;
-static const gchar *draw_data_key = "gtk-draw-data";
-static GQuark draw_data_key_id = 0;
-static const gchar *draw_data_tmp_key = "gtk-draw-data-tmp";
-static GQuark draw_data_tmp_key_id = 0;
-
-static gint gtk_widget_idle_draw (gpointer data);
-
-static void
-gtk_widget_queue_draw_data (GtkWidget *widget,
- gint x,
- gint y,
- gint width,
- gint height,
- GdkWindow *window)
-{
- GSList *node;
- GtkDrawData *data;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (!(width < 0 || height < 0) || window == NULL);
-
- if ((width != 0) && (height != 0) && GTK_WIDGET_DRAWABLE (widget))
- {
- if (!draw_data_key_id)
- draw_data_key_id = g_quark_from_static_string (draw_data_key);
-
- if (draw_data_free_list)
- {
- node = draw_data_free_list;
- data = node->data;
- draw_data_free_list = draw_data_free_list->next;
- }
- else
- {
- if (!draw_data_mem_chunk)
- draw_data_mem_chunk = g_mem_chunk_create (GtkDrawData, 64,
- G_ALLOC_ONLY);
- data = g_chunk_new (GtkDrawData, draw_data_mem_chunk);
- node = g_slist_alloc();
- node->data = data;
- }
-
- data->rect.x = x;
- data->rect.y = y;
-
- if ((width < 1 && height < 1) ||
- (width >= widget->allocation.width &&
- height >= widget->allocation.height))
- GTK_PRIVATE_SET_FLAG (widget, GTK_FULLDRAW_PENDING);
-
- if ((width < 0) || (height < 0))
- {
- data->rect.width = 0;
- data->rect.height = 0;
- }
- else
- {
- data->rect.width = width;
- data->rect.height = height;
- }
- data->window = window;
-
- if ((width < 0) || (height < 0))
- {
- GSList *draw_data_list =
- gtk_object_get_data_by_id (GTK_OBJECT (widget),
- draw_data_key_id);
- if (draw_data_list)
- draw_data_free_list = g_slist_concat (draw_data_list,
- draw_data_free_list);
- node->next = NULL;
- }
- else
- node->next = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- draw_data_key_id);
-
- if (!GTK_WIDGET_REDRAW_PENDING (widget))
- {
- GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_PENDING);
- if (gtk_widget_redraw_queue == NULL)
- gtk_idle_add_priority (GTK_PRIORITY_REDRAW,
- gtk_widget_idle_draw,
- NULL);
- gtk_widget_redraw_queue = g_slist_prepend (gtk_widget_redraw_queue, widget);
- }
-
- gtk_object_set_data_by_id (GTK_OBJECT (widget), draw_data_key_id, node);
- }
-}
-
void
gtk_widget_queue_draw_area (GtkWidget *widget,
gint x,
gint y,
gint width,
- gint height)
+ gint height)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- if (widget->window && gdk_window_is_viewable (widget->window) &&
- !gtk_widget_is_offscreen (widget))
- gtk_widget_queue_draw_data (widget, x, y, width, height, NULL);
+ gtk_widget_queue_clear_area (widget, x, y, width, height);
}
void
@@ -1839,11 +1725,12 @@ gtk_widget_queue_draw (GtkWidget *widget)
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- if (widget->window && gdk_window_is_viewable (widget->window) &&
- !gtk_widget_is_offscreen (widget))
- gtk_widget_queue_draw_data (widget, 0, 0, -1, -1, NULL);
+ gtk_widget_queue_clear (widget);
}
+/* Invalidates the given area (allocation-relative-coordinates)
+ * in all of the widget's windows
+ */
void
gtk_widget_queue_clear_area (GtkWidget *widget,
gint x,
@@ -1851,7 +1738,7 @@ gtk_widget_queue_clear_area (GtkWidget *widget,
gint width,
gint height)
{
- GtkWidget *parent;
+ GdkRectangle invalid_rect;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -1888,8 +1775,9 @@ gtk_widget_queue_clear_area (GtkWidget *widget,
{
if (widget->parent)
{
- gint wx, wy, wwidth, wheight;
/* Translate widget relative to window-relative */
+
+ gint wx, wy, wwidth, wheight;
gdk_window_get_position (widget->window, &wx, &wy);
x -= wx - widget->allocation.x;
@@ -1914,36 +1802,14 @@ gtk_widget_queue_clear_area (GtkWidget *widget,
if (y + height > wheight)
height = wheight - y;
}
-
- gtk_widget_queue_draw_data (widget, x, y, width, height, widget->window);
}
-}
-
-static void
-gtk_widget_redraw_queue_remove (GtkWidget *widget)
-{
- GSList *draw_data_list;
- GSList *tmp_list;
- g_return_if_fail (GTK_WIDGET_REDRAW_PENDING (widget));
-
- gtk_widget_redraw_queue = g_slist_remove (gtk_widget_redraw_queue, widget);
-
- draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- draw_data_key_id);
- tmp_list = g_slist_last (draw_data_list);
- if (tmp_list)
- {
- tmp_list->next = draw_data_free_list;
- draw_data_free_list = draw_data_list;
- }
-
- gtk_object_set_data_by_id (GTK_OBJECT (widget),
- draw_data_key_id,
- NULL);
+ invalid_rect.x = x;
+ invalid_rect.y = y;
+ invalid_rect.width = width;
+ invalid_rect.height = height;
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_PENDING);
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_FULLDRAW_PENDING);
+ gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
}
void
@@ -1966,324 +1832,6 @@ gtk_widget_queue_clear (GtkWidget *widget)
}
}
-static gint
-gtk_widget_draw_data_combine (GtkDrawData *parent, GtkDrawData *child)
-{
- gint parent_x2, parent_y2;
- gint child_x2, child_y2;
-
- /* Check for intersection */
-
- parent_x2 = parent->rect.x + parent->rect.width;
- child_x2 = child->rect.x + child->rect.width;
- parent_y2 = parent->rect.y + parent->rect.height;
- child_y2 = child->rect.y + child->rect.height;
-
- if ((child->rect.x > parent_x2) || (parent->rect.x > child_x2) ||
- (child->rect.y > parent_y2) || (parent->rect.y > child_y2))
- return FALSE;
- else
- {
- parent->rect.x = MIN (parent->rect.x, child->rect.x);
- parent->rect.y = MIN (parent->rect.y, child->rect.y);
- parent->rect.width = MAX (parent_x2, child_x2) - parent->rect.x;
- parent->rect.height = MAX (parent_y2, child_y2) - parent->rect.y;
- }
-
- return TRUE;
-}
-
-/* Take a rectangle with respect to window, and translate it
- * to coordinates relative to widget's allocation, clipping through
- * intermediate windows. Returns whether translation failed. If the
- * translation failed, we have something like a handlebox, where
- * the child widget's GdkWindow is not a child of the parents GdkWindow.
- */
-static gboolean
-gtk_widget_clip_rect (GtkWidget *widget,
- GdkWindow *window,
- GdkRectangle *rect,
- gint *x_offset,
- gint *y_offset)
-{
- gint x,y, width, height;
-
- while (window && (window != widget->window))
- {
- gdk_window_get_position (window, &x, &y);
- rect->x += x;
- if (x_offset)
- *x_offset += x;
- rect->y += y;
- if (y_offset)
- *y_offset += y;
-
- window = gdk_window_get_parent (window);
- if (!window)
- return FALSE;
-
- gdk_window_get_size (window, &width, &height);
-
- if (rect->x < 0)
- {
- rect->width = (rect->width > -rect->x) ? rect->width + rect->x : 0;
- rect->x = 0;
- }
- if (rect->y < 0)
- {
- rect->height = (rect->height > -rect->y) ? rect->width + rect->y : 0;
- rect->y = 0;
- }
- if (rect->x + rect->width > width)
- rect->width = (width > rect->x) ? width - rect->x : 0;
- if (rect->y + rect->height > height)
- rect->height = (height > rect->y) ? height - rect->y : 0;
- }
-
- if (!window)
- return FALSE;
-
- if (!GTK_WIDGET_NO_WINDOW (widget))
- {
- if (gdk_window_get_toplevel (window) != window)
- {
- gdk_window_get_position (window, &x, &y);
- rect->x += x - widget->allocation.x;
- if (x_offset)
- *x_offset += x - widget->allocation.x;
- rect->y += y - widget->allocation.y;
- if (y_offset)
- *y_offset += y - widget->allocation.y;
- }
- }
-
- return TRUE;
-}
-
-static gint
-gtk_widget_idle_draw (gpointer cb_data)
-{
- GSList *widget_list;
- GSList *old_queue;
- GSList *draw_data_list;
- GtkWidget *widget;
-
- if (!draw_data_tmp_key_id)
- draw_data_tmp_key_id = g_quark_from_static_string (draw_data_tmp_key);
-
- GDK_THREADS_ENTER ();
-
- old_queue = gtk_widget_redraw_queue;
- gtk_widget_redraw_queue = NULL;
-
- /* Translate all draw requests to be allocation-relative.
- * At the same time, move all the data out of the way,
- * so when we get down to the draw step, we can queue
- * more information for "next time", if the application
- * is that foolhardy.
- */
- widget_list = old_queue;
-
- while (widget_list)
- {
- widget = widget_list->data;
- draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- draw_data_key_id);
- gtk_object_set_data_by_id (GTK_OBJECT (widget),
- draw_data_key_id,
- NULL);
- gtk_object_set_data_by_id (GTK_OBJECT (widget),
- draw_data_tmp_key_id,
- draw_data_list);
-
- /* XXX: Since we are unsetting this flag here, further
- * down the only way we can check if a redraw is queued
- * on a given widget is by calling gtk_object_get_data.
- * for speed purposes we might well want a private
- * flag GTK_REDRAW_PROCESSING or something.
- */
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_PENDING);
- GTK_PRIVATE_UNSET_FLAG (widget, GTK_FULLDRAW_PENDING);
-
- while (draw_data_list)
- {
- gboolean full_allocation = FALSE;
- GtkDrawData *data = draw_data_list->data;
-
- if (data->window)
- {
- /* If the translation fails, we have a handlebox,
- * so redraw the whole widget. Could be done better?
- */
- full_allocation = !gtk_widget_clip_rect (widget,
- data->window,
- &data->rect,
- NULL, NULL);
- data->window = NULL;
- }
- else if ((data->rect.width == 0) && (data->rect.height == 0))
- full_allocation = TRUE;
-
- if (full_allocation)
- {
- if (GTK_WIDGET_NO_WINDOW (widget))
- {
- data->rect.x = widget->allocation.x;
- data->rect.y = widget->allocation.y;
- }
- else
- {
- data->rect.x = 0;
- data->rect.y = 0;
- }
- data->rect.width = widget->allocation.width;
- data->rect.height = widget->allocation.height;
- }
-
- draw_data_list = draw_data_list->next;
- }
-
- widget_list = widget_list->next;
- }
-
- /* Coalesce redraws.
- */
- widget_list = old_queue;
- while (widget_list)
- {
- GSList *prev_node = NULL;
- widget = widget_list->data;
- draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- draw_data_tmp_key_id);
-
- while (draw_data_list)
- {
- gint x_offset, y_offset;
- GtkDrawData *data = draw_data_list->data;
- GSList *parent_list = draw_data_list->next;
- GtkWidget *parent;
- GdkWindow *window;
-
- x_offset = 0;
- y_offset = 0;
-
- parent = widget;
- while (parent)
- {
- while (parent_list)
- {
- if (gtk_widget_draw_data_combine (parent_list->data, data))
- {
- GSList *tmp;
- if (prev_node)
- prev_node->next = draw_data_list->next;
- else
- gtk_object_set_data_by_id (GTK_OBJECT (widget),
- draw_data_tmp_key_id,
- draw_data_list->next);
-
- tmp = draw_data_list->next;
- draw_data_list->next = draw_data_free_list;
- draw_data_free_list = draw_data_list;
- draw_data_list = tmp;
-
- goto next_rect;
- }
-
- parent_list = parent_list->next;
- }
-
- window = parent->window;
-
- if (parent->parent && parent->parent->window != window)
- {
- if (!GTK_WIDGET_NO_WINDOW (parent))
- {
- gint x, y;
- gdk_window_get_position (window, &x, &y);
- data->rect.x -= x - parent->allocation.x;
- x_offset -= x - parent->allocation.x;
- data->rect.y -= y - parent->allocation.y;
- y_offset -= y - parent->allocation.y;
- }
- /* If we can't translate the rectangle, stop trying to
- * merge. (This occurs for a handlebox)
- */
- if (!gtk_widget_clip_rect (parent->parent, window, &data->rect,
- &x_offset, &y_offset))
- parent = NULL;
- }
-
- if (parent)
- parent = parent->parent;
-
- if (parent)
- parent_list = gtk_object_get_data_by_id (GTK_OBJECT (parent),
- draw_data_tmp_key_id);
- else
- parent_list = NULL;
- }
-
- /* OK, this rectangle stays around. But take advantage
- * of the work we've done to clip it to the visible area -
- * rect.width/height have already been appropriately
- * decreased
- */
- data->rect.x -= x_offset;
- data->rect.y -= y_offset;
-
-
- prev_node = draw_data_list;
-
- draw_data_list = draw_data_list->next;
- next_rect:
- continue;
- }
- widget_list = widget_list->next;
- }
-
- /* Process the draws */
-
- widget_list = old_queue;
-
- while (widget_list)
- {
- GSList *tmp_list;
-
- widget = widget_list->data;
- draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- draw_data_tmp_key_id);
- gtk_object_set_data_by_id (GTK_OBJECT (widget),
- draw_data_tmp_key_id,
- NULL);
-
- tmp_list = draw_data_list;
- while (tmp_list)
- {
- GtkDrawData *data = tmp_list->data;
- if ((data->rect.width != 0) && (data->rect.height != 0))
- gtk_widget_draw (widget, &data->rect);
-
- if (tmp_list->next)
- tmp_list = tmp_list->next;
- else
- {
- tmp_list->next = draw_data_free_list;
- draw_data_free_list = draw_data_list;
- break;
- }
- }
-
- widget_list = widget_list->next;
- }
-
- g_slist_free (old_queue);
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
-}
-
void
gtk_widget_queue_resize (GtkWidget *widget)
{
@@ -2338,7 +1886,25 @@ gtk_widget_draw (GtkWidget *widget,
area = &temp_area;
}
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ {
+ GdkRectangle tmp_area = *area;
+ gint x, y;
+
+ if (!GTK_WIDGET_TOPLEVEL (widget))
+ {
+ gdk_window_get_position (widget->window, &x, &y);
+ tmp_area.x -= x - widget->allocation.x;
+ tmp_area.y -= y - widget->allocation.y;
+ }
+
+ gdk_window_begin_paint_rect (widget->window, &tmp_area);
+ }
+
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW], area);
+
+ if (!GTK_WIDGET_NO_WINDOW (widget))
+ gdk_window_end_paint (widget->window);
}
}
@@ -2469,14 +2035,13 @@ gtk_widget_size_allocate (GtkWidget *widget,
real_allocation.width = MAX (real_allocation.width, 1);
real_allocation.height = MAX (real_allocation.height, 1);
- if (real_allocation.width > 32767 ||
- real_allocation.height > 32767)
+ if (real_allocation.width < 0 || real_allocation.height < 0)
{
g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
real_allocation.width,
real_allocation.height);
- real_allocation.width = MIN (real_allocation.width, 32767);
- real_allocation.height = MIN (real_allocation.height, 32767);
+ real_allocation.width = 1;
+ real_allocation.height = 1;
}
if (GTK_WIDGET_NO_WINDOW (widget))
@@ -2727,7 +2292,7 @@ gint
gtk_widget_event (GtkWidget *widget,
GdkEvent *event)
{
- gint return_val;
+ gboolean return_val;
gint signal_num;
g_return_val_if_fail (widget != NULL, TRUE);
@@ -2738,14 +2303,10 @@ gtk_widget_event (GtkWidget *widget,
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event,
&return_val);
if (return_val || GTK_OBJECT_DESTROYED (widget))
- {
- gtk_widget_unref (widget);
- return TRUE;
- }
+ goto out;
switch (event->type)
{
- GtkWidget *parent;
case GDK_NOTHING:
signal_num = -1;
break;
@@ -2821,42 +2382,9 @@ gtk_widget_event (GtkWidget *widget,
signal_num = CLIENT_EVENT;
break;
case GDK_EXPOSE:
- /* there is no sense in providing a widget with bogus expose events.
- * also we make the optimization to discard expose events for widgets
- * that have a full redraw pending (given that the event is !send_event,
- * otherwise we assume we can trust the event).
- */
- if (event->any.send_event)
- parent = NULL;
- else if (event->any.window)
- {
- parent = widget;
- while (parent)
- {
- if (GTK_WIDGET_FULLDRAW_PENDING (parent))
- break;
- parent = parent->parent;
- }
- /* <HACK> gnome-dock didn't propagate draws to torn off
- * children. So don't consider those ancestors.
- */
- if (parent)
- {
- GdkWindow *parent_window = event->any.window;
-
- while (parent_window && parent_window != parent->window)
- parent_window = gdk_window_get_parent (parent_window);
+ if (!event->any.window) /* Why is this necessary */
+ goto out;
- if (!parent_window)
- parent = NULL;
- }
- /* </HACK> */
- }
- if (!event->any.window || parent)
- {
- gtk_widget_unref (widget);
- return TRUE;
- }
signal_num = EXPOSE_EVENT;
break;
case GDK_VISIBILITY_NOTIFY:
@@ -2864,8 +2392,7 @@ gtk_widget_event (GtkWidget *widget,
break;
default:
g_warning ("could not determine signal number for event: %d", event->type);
- gtk_widget_unref (widget);
- return TRUE;
+ goto out;
}
if (signal_num != -1)
@@ -2873,6 +2400,7 @@ gtk_widget_event (GtkWidget *widget,
return_val |= GTK_OBJECT_DESTROYED (widget);
+ out:
gtk_widget_unref (widget);
return return_val;
@@ -3056,7 +2584,7 @@ gtk_widget_intersect (GtkWidget *widget,
else
dest = &tmp;
- return_val = gdk_rectangle_intersect ((GdkRectangle*) &widget->allocation, area, dest);
+ return_val = gdk_rectangle_intersect (&widget->allocation, area, dest);
if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
{
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 15e3c628e..66568b422 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -110,7 +110,7 @@ typedef enum
typedef struct _GtkRequisition GtkRequisition;
-typedef struct _GtkAllocation GtkAllocation;
+typedef struct _GdkRectangle GtkAllocation;
typedef struct _GtkSelectionData GtkSelectionData;
typedef struct _GtkWidgetClass GtkWidgetClass;
typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo;
@@ -124,20 +124,8 @@ typedef void (*GtkCallback) (GtkWidget *widget,
*/
struct _GtkRequisition
{
- gint16 width;
- gint16 height;
-};
-
-/* An allocation is a size and position. Where a widget
- * can ask for a desired size, it is actually given
- * this amount of space at the specified position.
- */
-struct _GtkAllocation
-{
- gint16 x;
- gint16 y;
- guint16 width;
- guint16 height;
+ gint width;
+ gint height;
};
/* The contents of a selection are returned in a GtkSelectionData