+ if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+ GTK_IS_CONTAINER (child->widget))
+ {
+ gtk_container_forall (GTK_CONTAINER (child->widget),
+ gtk_pizza_adjust_allocations_recurse,
+ &data);
+ }
+ }
+}
+
+/* This function is used to find events to process while scrolling */
+
+static Bool
+gtk_pizza_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;
+}
+
+/* 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.
+ */
+
+void
+gtk_pizza_scroll (GtkPizza *pizza, gint dx, gint dy)
+{
+ GtkWidget *widget;
+ XEvent xevent;
+ XID win;
+
+ gint x,y,w,h,border;
+
+ widget = GTK_WIDGET (pizza);
+
+ pizza->xoffset += dx;
+ pizza->yoffset += dy;
+
+ if (!GTK_WIDGET_MAPPED (pizza))
+ {
+ gtk_pizza_position_children (pizza);
+ return;
+ }
+
+ gtk_pizza_adjust_allocations (pizza, -dx, -dy);
+
+ if (pizza->shadow_type == GTK_MYSHADOW_NONE)
+ border = 0;
+ else
+ if (pizza->shadow_type == GTK_MYSHADOW_THIN)
+ border = 1;
+ else
+ border = 2;
+
+ x = 0;
+ y = 0;
+ w = widget->allocation.width - 2*border;
+ h = widget->allocation.height - 2*border;
+
+ if (dx > 0)
+ {
+ if (gravity_works)
+ {
+ gdk_window_resize (pizza->bin_window,
+ w + dx,
+ h);
+ gdk_window_move (pizza->bin_window, x-dx, y);
+ gdk_window_move_resize (pizza->bin_window, x, y, w, h );
+ }
+ else
+ {
+ /* FIXME */
+ }
+ }
+ else if (dx < 0)
+ {
+ if (gravity_works)
+ {
+ gdk_window_move_resize (pizza->bin_window,
+ x + dx,
+ y,
+ w - dx,
+ h);
+ gdk_window_move (pizza->bin_window, x, y);
+ gdk_window_resize (pizza->bin_window, w, h );
+ }
+ else
+ {
+ /* FIXME */
+ }
+ }
+
+ if (dy > 0)
+ {
+ if (gravity_works)
+ {
+ gdk_window_resize (pizza->bin_window, w, h + dy);
+ gdk_window_move (pizza->bin_window, x, y-dy);
+ gdk_window_move_resize (pizza->bin_window,
+ x, y, w, h );
+ }
+ else
+ {
+ /* FIXME */
+ }
+ }
+ else if (dy < 0)
+ {
+ if (gravity_works)
+ {
+ gdk_window_move_resize (pizza->bin_window,
+ x, y+dy, w, h - dy );
+ gdk_window_move (pizza->bin_window, x, y);
+ gdk_window_resize (pizza->bin_window, w, h );
+ }
+ else
+ {
+ /* FIXME */
+ }
+ }