Index: gtk/gtkrange.c
===================================================================
--- gtk/gtkrange.c	(revision 20839)
+++ gtk/gtkrange.c	(working copy)
@@ -2136,7 +2136,8 @@
       gboolean handled;
 
       delta = _gtk_range_get_wheel_delta (range, event->direction);
-
+      delta *= event->delta;
+      
       g_signal_emit (range, signals[CHANGE_VALUE], 0,
                      GTK_SCROLL_JUMP, adj->value + delta,
                      &handled);
Index: gtk/gtktreeview.c
===================================================================
--- gtk/gtktreeview.c	(revision 20839)
+++ gtk/gtktreeview.c	(working copy)
@@ -99,6 +99,9 @@
 
   guint source_set : 1;
   guint dest_set : 1;
+
+  GtkTreePath* path;
+  GtkTreeModel* model;
 };
 
 
@@ -2536,6 +2539,7 @@
       gboolean row_double_click = FALSE;
       gboolean rtl;
       gboolean node_selected;
+      gboolean edits_allowed;
 
       /* Empty tree? */
       if (tree_view->priv->tree == NULL)
@@ -2645,9 +2649,17 @@
 
       tree_view->priv->focus_column = column;
 
+      /* ARDOUR HACK */
+
+      if (g_object_get_data (G_OBJECT(tree_view), "mouse-edits-require-mod1")) {
+	      edits_allowed = (event->state & GDK_MOD1_MASK);
+      } else {
+	      /* regular GTK design: do edits if none of the default modifiers are active */
+	      edits_allowed = !(event->state & gtk_accelerator_get_default_mod_mask ());
+      }
+
       /* decide if we edit */
-      if (event->type == GDK_BUTTON_PRESS && event->button == 1 &&
-	  !(event->state & gtk_accelerator_get_default_mod_mask ()))
+      if (event->type == GDK_BUTTON_PRESS && event->button == 1 && edits_allowed)
 	{
 	  GtkTreePath *anchor;
 	  GtkTreeIter iter;
@@ -3012,8 +3024,7 @@
       if (tree_view->priv->button_pressed_node == tree_view->priv->prelight_node &&
           GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_ARROW_PRELIT))
 	{
-	  GtkTreePath *path = NULL;
-
+          GtkTreePath *path = NULL;
 	  path = _gtk_tree_view_find_path (tree_view,
 					   tree_view->priv->button_pressed_tree,
 					   tree_view->priv->button_pressed_node);
@@ -6963,6 +6974,17 @@
   return path;
 }
 
+#ifdef GDK_WINDOWING_QUARTZ
+static void
+gtk_tree_view_catch_drag_begin (GtkWidget* widget,
+				GdkDragContext* context,
+				gpointer user_data)
+{
+	TreeViewDragInfo* drag_info = (TreeViewDragInfo*) user_data;
+	set_source_row (context, drag_info->model, drag_info->path);
+}
+#endif
+
 static gboolean
 gtk_tree_view_maybe_begin_dragging_row (GtkTreeView      *tree_view,
                                         GdkEventMotion   *event)
@@ -6975,6 +6997,7 @@
   gint cell_x, cell_y;
   GtkTreeModel *model;
   gboolean retval = FALSE;
+  gint drag_begin_id;
 
   di = get_info (tree_view);
 
@@ -7021,13 +7044,25 @@
 
   retval = TRUE;
 
+#ifdef GDK_WINDOWING_QUARTZ
+  /* catch drag-being signal */
+  di->model = model;
+  di->path = path;
+  drag_begin_id = g_signal_connect (tree_view, "drag-begin", G_CALLBACK (gtk_tree_view_catch_drag_begin), (gpointer) di);
+#endif
+
   context = gtk_drag_begin (widget,
                             gtk_drag_source_get_target_list (widget),
                             di->source_actions,
                             button,
                             (GdkEvent*)event);
 
+#ifndef GDK_WINDOWING_QUARTZ
   set_source_row (context, model, path);
+#else 
+   /* disconnect drag-begin and catch drag-end */
+   g_signal_handler_disconnect (tree_view, drag_begin_id);
+#endif
 
  out:
   if (path)
Index: gtk/gtkquartz.c
===================================================================
--- gtk/gtkquartz.c	(revision 20839)
+++ gtk/gtkquartz.c	(working copy)
@@ -24,6 +24,23 @@
 #include "gtkalias.h"
 
 NSImage *
+_gtk_quartz_create_image_from_drawable (GdkDrawable* drawable)
+{
+	GdkPixbuf* pixbuf;
+	NSImage* image = NULL;
+
+	pixbuf = gdk_pixbuf_get_from_drawable (NULL, drawable, NULL, 
+						  0, 0, /* src */
+						  0, 0, /* dst */
+						  -1, -1);
+	if (pixbuf) 
+   	  image = _gtk_quartz_create_image_from_pixbuf (pixbuf);
+	
+	return image;
+}
+
+
+NSImage *
 _gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf)
 {
   CGColorSpaceRef colorspace;
Index: gtk/gtkquartz.h
===================================================================
--- gtk/gtkquartz.h	(revision 20839)
+++ gtk/gtkquartz.h	(working copy)
@@ -41,6 +41,7 @@
 						    GtkSelectionData *selection_data);
 			
 NSImage *_gtk_quartz_create_image_from_pixbuf (GdkPixbuf *pixbuf);
+NSImage *_gtk_quartz_create_image_from_drawable (GdkDrawable *drawable);
 			    
 G_END_DECLS
 
Index: gtk/gtkdnd-quartz.c
===================================================================
--- gtk/gtkdnd-quartz.c	(revision 20839)
+++ gtk/gtkdnd-quartz.c	(working copy)
@@ -1086,13 +1086,13 @@
 		GdkPixbuf *pixbuf;
 
 		pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 1, 1);
-		gdk_pixbuf_fill (pixbuf, 0xffffff);
-	    
-		gtk_drag_set_icon_pixbuf (context,
-					  pixbuf,
+ 		gdk_pixbuf_fill (pixbuf, 0xffffff);
+
+ 		gtk_drag_set_icon_pixbuf (context,
+ 					  pixbuf,
 					  0, 0);
 
-		g_object_unref (pixbuf);
+ 		g_object_unref (pixbuf);
 	      }
 	    break;
 	  case GTK_IMAGE_PIXBUF:
@@ -1668,7 +1668,20 @@
 			  gint               hot_x,
 			  gint               hot_y)
 {
-  g_warning ("gtk_drag_set_icon_pixmap is not supported on Mac OS X");
+  GdkPixbuf *pixbuf;
+  
+  g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
+  g_return_if_fail (context->is_source);
+  g_return_if_fail (GDK_IS_COLORMAP (colormap));
+  g_return_if_fail (GDK_IS_PIXMAP (pixmap));
+  
+  pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, colormap,
+					 0, 0, /* src */
+					 0, 0, /* dst */
+					 -1, -1);
+  
+  gtk_drag_set_icon_pixbuf (context, pixbuf, hot_x, hot_y);
+  g_object_unref (pixbuf);
 }
 
 /**
Index: docs/reference/gdk/tmpl/event_structs.sgml
===================================================================
--- docs/reference/gdk/tmpl/event_structs.sgml	(revision 20839)
+++ docs/reference/gdk/tmpl/event_structs.sgml	(working copy)
@@ -185,6 +185,8 @@
 @time: the time of the event in milliseconds.
 @x: the x coordinate of the pointer relative to the window.
 @y: the y coordinate of the pointer relative to the window.
+@delta: the distance scrolled (1.0 by default and on backends that do
+   not support distance reporting)
 @state: a bit-mask representing the state of the modifier keys (e.g. Control,
 Shift and Alt) and the pointer buttons. See #GdkModifierType.
 @direction: the direction to scroll to (one of %GDK_SCROLL_UP, 
Index: tests/dummy-headers/AppKit/AppKit.h
===================================================================
--- tests/dummy-headers/AppKit/AppKit.h	(revision 20839)
+++ tests/dummy-headers/AppKit/AppKit.h	(working copy)
@@ -11,6 +11,12 @@
 @interface NSEvent {}
 @end
 
+@interface NSPoint {}
+@end
+
+@interface NSRect {}
+@end
+
 @interface NSImage {}
 @end
 
Index: demos/Makefile.am
===================================================================
--- demos/Makefile.am	(revision 20839)
+++ demos/Makefile.am	(working copy)
@@ -39,7 +39,7 @@
 pixbuf_csource=$(GDK_PIXBUF_CSOURCE)
 pixbuf_csource_deps=
 else
-pixbuf_csource=GDK_PIXBUF_MODULE_FILE=$(top_builddir)/gdk-pixbuf/gdk-pixbuf.loaders $(top_builddir)/gdk-pixbuf/gdk-pixbuf-csource
+pixbuf_csource=GDK_PIXBUF_MODULE_FILE=$(top_builddir)/gdk-pixbuf/gdk-pixbuf.loaders $(top_builddir)/gdk-pixbuf/.libs/gdk-pixbuf-csource
 pixbuf_csource_deps=$(top_builddir)/gdk-pixbuf/gdk-pixbuf-csource $(top_builddir)/gdk-pixbuf/gdk-pixbuf.loaders 
 endif
 
Index: gdk/gdkevents.c
===================================================================
--- gdk/gdkevents.c	(revision 20839)
+++ gdk/gdkevents.c	(working copy)
@@ -335,6 +335,7 @@
       new_event->scroll.y = 0.;
       new_event->scroll.x_root = 0.;
       new_event->scroll.y_root = 0.;
+      new_event->scroll.delta = 0;
       break;
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
Index: gdk/gdkevents.h
===================================================================
--- gdk/gdkevents.h	(revision 20839)
+++ gdk/gdkevents.h	(working copy)
@@ -333,6 +333,7 @@
   GdkScrollDirection direction;
   GdkDevice *device;
   gdouble x_root, y_root;
+  gdouble delta;
 };
 
 struct _GdkEventKey
Index: gdk/directfb/gdkevents-directfb.c
===================================================================
--- gdk/directfb/gdkevents-directfb.c	(revision 20839)
+++ gdk/directfb/gdkevents-directfb.c	(working copy)
@@ -870,6 +870,7 @@
             event->scroll.y      = dfbevent->y;
             event->scroll.state  = _gdk_directfb_modifiers;
             event->scroll.device = display->core_pointer;
+	    event->scroll.delta = 1;
           }
       }
       break;
Index: gdk/quartz/gdkevents-quartz.c
===================================================================
--- gdk/quartz/gdkevents-quartz.c	(revision 20839)
+++ gdk/quartz/gdkevents-quartz.c	(working copy)
@@ -112,6 +112,18 @@
   return ((GdkEventPrivate *) event)->windowing_data;
 }
 
+/* A category that exposes the protected carbon event for an NSEvent. */
+@interface NSEvent (GdkQuartzNSEvent)
+- (void *)gdk_quartz_event_ref;
+@end 
+
+@implementation NSEvent (GdkQuartzNSEvent)
+- (void *)gdk_quartz_event_ref
+{
+  return _eventRef;
+}
+@end
+
 void 
 _gdk_events_init (void)
 {
@@ -569,7 +581,7 @@
 {
   GdkEvent *event;
 
-  if (got_focus && window == current_keyboard_window)
+  if (got_focus && window == current_keyboard_window) 
     return;
 
   /* FIXME: Don't do this when grabbed? Or make GdkQuartzWindow
@@ -1520,7 +1532,8 @@
 static GdkEvent *
 create_scroll_event (GdkWindow          *window, 
                      NSEvent            *nsevent, 
-                     GdkScrollDirection  direction)
+                     GdkScrollDirection  direction,
+		     gdouble             delta)
 {
   GdkEvent *event;
   NSPoint point;
@@ -1537,6 +1550,7 @@
 				      &event->scroll.x_root,
 				      &event->scroll.y_root);
 
+  event->scroll.delta = delta;
   event->scroll.direction = direction;
   event->scroll.device = _gdk_display->core_pointer;
   
@@ -1554,7 +1568,6 @@
   gunichar c = 0;
 
   event = gdk_event_new (type);
-
   priv = (GdkEventPrivate *) event;
   priv->windowing_data = [nsevent retain];
 
@@ -1670,6 +1683,65 @@
 }
 
 static gboolean
+_gdk_quartz_possibly_forward_accelerator (NSEvent* nsevent)
+{
+  /* Special-case menu shortcut events. We create command events for
+   * those and forward to the corresponding menu.
+   */
+  if ((!_gdk_quartz_keyboard_grab_window ||
+       (_gdk_quartz_keyboard_grab_window && keyboard_grab_owner_events)) &&
+      [nsevent type] == NSKeyDown)
+    {
+      EventRef event_ref;
+      MenuRef menu_ref;
+      MenuItemIndex index;
+
+      event_ref = [nsevent gdk_quartz_event_ref];
+      if (IsMenuKeyEvent (NULL, event_ref,
+                          kMenuEventQueryOnly, 
+                          &menu_ref, &index))
+        {
+          MenuCommand menu_command;
+          HICommand hi_command;
+
+          if (GetMenuItemCommandID (menu_ref, index, &menu_command) != noErr)
+            return FALSE;
+   
+          hi_command.commandID = menu_command;
+          hi_command.menu.menuRef = menu_ref;
+          hi_command.menu.menuItemIndex = index;
+
+          CreateEvent (NULL, kEventClassCommand, kEventCommandProcess, 
+                       0, kEventAttributeUserEvent, &event_ref);
+          SetEventParameter (event_ref, kEventParamDirectObject, 
+                             typeHICommand, 
+                             sizeof (HICommand), &hi_command);
+
+          SendEventToEventTarget (event_ref, GetMenuEventTarget (menu_ref));
+
+          ReleaseEvent (event_ref);
+
+          return TRUE;
+        }
+    }
+  return FALSE;
+}
+
+gboolean
+gdk_quartz_possibly_forward (GdkEvent* event)
+{
+  NSEvent *nsevent;
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  nsevent = ((GdkEventPrivate*)event)->windowing_data;
+
+  if (nsevent)
+    return _gdk_quartz_possibly_forward_accelerator (nsevent);
+
+  return FALSE;
+}
+
+static gboolean
 gdk_event_translate (NSEvent *nsevent)
 {
   NSWindow *nswindow;
@@ -1830,10 +1902,6 @@
 	float dy = [nsevent deltaY];
 	GdkScrollDirection direction;
 
-	/* The delta is how much the mouse wheel has moved. Since there's no such thing in GTK+
-	 * we accomodate by sending a different number of scroll wheel events.
-	 */
-
 	/* First do y events */
 	if (dy < 0.0)
 	  {
@@ -1843,16 +1911,9 @@
 	else
 	  direction = GDK_SCROLL_UP;
 
-	while (dy > 0.0)
-	  {
-	    event = create_scroll_event (window, nsevent, direction);
-	    append_event (event);
-	    dy--;
+	event = create_scroll_event (window, nsevent, direction, dy);
+	append_event (event);
 
-            /* Ignore the delta for now, things get too slow when the events queue up. */
-            break;
-	  }
-
 	/* Now do x events */
 	if (dx < 0.0)
 	  {
@@ -1862,16 +1923,8 @@
 	else
 	  direction = GDK_SCROLL_LEFT;
 
-	while (dx > 0.0)
-	  {
-	    event = create_scroll_event (window, nsevent, direction);
-	    append_event (event);
-	    dx--;
-            
-            /* Ignore the delta for now, things get too slow when the events queue up. */
-            break;
-	  }
-
+	event = create_scroll_event (window, nsevent, direction, dx);
+	append_event (event);
       }
       break;
 
@@ -1902,6 +1955,7 @@
 void
 _gdk_events_queue (GdkDisplay *display)
 {  
+  extern NSEvent* _gdk_quartz_event_loop_get_pending ();
   NSEvent *event;
 
   event = _gdk_quartz_event_loop_get_pending ();
Index: gdk/quartz/gdkeventloop-quartz.c
===================================================================
--- gdk/quartz/gdkeventloop-quartz.c	(revision 20839)
+++ gdk/quartz/gdkeventloop-quartz.c	(working copy)
@@ -9,7 +9,6 @@
 #include "gdkprivate-quartz.h"
 
 static GPollFD event_poll_fd;
-static NSEvent *current_event;
 
 static GPollFunc old_poll_func;
 
@@ -23,6 +22,7 @@
 static guint n_pollfds;
 static CFRunLoopSourceRef select_main_thread_source;
 static CFRunLoopRef main_thread_run_loop;
+static NSEvent* current_event;
 static NSAutoreleasePool *autorelease_pool;
 
 gboolean
@@ -94,6 +94,8 @@
   return retval;
 }
 
+extern void gdk_window_quartz_update_timed ();
+
 static gboolean
 gdk_event_dispatch (GSource     *source,
 		    GSourceFunc  callback,
Index: gdk/quartz/GdkQuartzWindow.c
===================================================================
--- gdk/quartz/GdkQuartzWindow.c	(revision 20839)
+++ gdk/quartz/GdkQuartzWindow.c	(working copy)
@@ -201,6 +201,9 @@
   [self setAcceptsMouseMovedEvents:YES];
   [self setDelegate:self];
   [self setReleasedWhenClosed:YES];
+  [self setAutodisplay:NO];
+  
+  [self setViewsNeedDisplay:YES];
 
   return self;
 }
@@ -604,4 +607,8 @@
   _gdk_quartz_drag_source_context = NULL;
 }
 
+- (void)_verifyDefaultButtonCell:(id)sender
+{
+}
+
 @end
Index: gdk/quartz/GdkQuartzView.c
===================================================================
--- gdk/quartz/GdkQuartzView.c	(revision 20839)
+++ gdk/quartz/GdkQuartzView.c	(working copy)
@@ -57,6 +57,7 @@
   const NSRect *drawn_rects;
   int count, i;
   GdkRegion *region;
+  GdkEvent event;
 
   if (GDK_WINDOW_DESTROYED (gdk_window))
     return;
@@ -69,44 +70,49 @@
 
   GDK_QUARTZ_ALLOC_POOL;
 
+  gdk_rect.x = rect.origin.x;
+  gdk_rect.y = rect.origin.y;
+  gdk_rect.width = rect.size.width;
+  gdk_rect.height = rect.size.height;
+  
+  /* Shortcut when drawing many rects or just one that matches the full
+   * view. This helps a lot for apps that do a lot of repaints or has many
+   * gdk windows (arbitrarily set the limit at 50 rects).
+   */
   [self getRectsBeingDrawn:&drawn_rects count:&count];
+  if (count < 50 && !NSEqualRects(rect, [self bounds]))
+    {
+      region = gdk_region_new ();
 
-  region = gdk_region_new ();
+      for (i = 0; i < count; i++)
+        {
+          GdkRectangle tmp_rect;
 
-  for (i = 0; i < count; i++)
-    {
-      gdk_rect.x = drawn_rects[i].origin.x;
-      gdk_rect.y = drawn_rects[i].origin.y;
-      gdk_rect.width = drawn_rects[i].size.width;
-      gdk_rect.height = drawn_rects[i].size.height;
-
-      gdk_region_union_with_rect (region, &gdk_rect);
+          tmp_rect.x = drawn_rects[i].origin.x;
+          tmp_rect.y = drawn_rects[i].origin.y;
+          tmp_rect.width = drawn_rects[i].size.width;
+          tmp_rect.height = drawn_rects[i].size.height;
+          
+          gdk_region_union_with_rect (region, &tmp_rect);
+        }
     }
+  else
+    region = gdk_region_rectangle (&gdk_rect);
 
-  if (!gdk_region_empty (region))
-    {
-      GdkEvent event;
+  event.expose.type = GDK_EXPOSE;
+  event.expose.window = g_object_ref (gdk_window);
+  event.expose.send_event = FALSE;
+  event.expose.count = 0;
+  event.expose.region = region;
+  event.expose.area = gdk_rect;
       
-      gdk_rect.x = rect.origin.x;
-      gdk_rect.y = rect.origin.y;
-      gdk_rect.width = rect.size.width;
-      gdk_rect.height = rect.size.height;
-      
-      event.expose.type = GDK_EXPOSE;
-      event.expose.window = g_object_ref (gdk_window);
-      event.expose.send_event = FALSE;
-      event.expose.count = 0;
-      event.expose.region = region;
-      event.expose.area = gdk_rect;
-      
-      impl->in_paint_rect_count++;
+  impl->in_paint_rect_count++;
 
-      (*_gdk_event_func) (&event, _gdk_event_data);
+  (*_gdk_event_func) (&event, _gdk_event_data);
 
-      impl->in_paint_rect_count--;
+  impl->in_paint_rect_count--;
 
-      g_object_unref (gdk_window);
-    }
+  g_object_unref (gdk_window);
 
   gdk_region_destroy (region);
 
@@ -139,7 +145,7 @@
       trackingRect = 0;
     }
 
-  if (!impl->toplevel)
+  if (!impl || !impl->toplevel)
     return;
 
   /* Note, if we want to set assumeInside we can use:
Index: gdk/quartz/gdkwindow-quartz.c
===================================================================
--- gdk/quartz/gdkwindow-quartz.c	(revision 20839)
+++ gdk/quartz/gdkwindow-quartz.c	(working copy)
@@ -31,6 +31,9 @@
 static GSList *update_windows;
 static guint   update_idle;
 
+static GSList *flush_nswindows;
+static GSList *flush_nsviews;
+
 static GSList *main_window_stack;
 
 #define FULLSCREEN_DATA "fullscreen-data"
@@ -304,11 +307,108 @@
 }
 
 static void
+quartz_autodisplay_one_window (NSWindow* nswindow)
+{
+      struct timeval now;
+      if ([nswindow isFlushWindowDisabled])
+	{
+	   if ([nswindow viewsNeedDisplay])
+	     {
+		     //g_print ("%p extra window display\n", nswindow);
+            
+		[nswindow displayIfNeeded];
+		[nswindow setViewsNeedDisplay:NO];
+	     }
+	   [nswindow enableFlushWindow];
+	   [nswindow flushWindowIfNeeded];
+	   [nswindow release];
+	} 
+      gettimeofday (&now, NULL);
+      //g_print ("FLUSH @ %d.%d\n", now.tv_sec, now.tv_usec);
+}
+
+/* Flushes any updates that have happened since the earliest non-displayed
+ * invalidation.
+ */
+static void
+quartz_window_autodisplay (void)
+{
+  GSList *l;
+  struct timeval now;
+
+  for (l = flush_nsviews; l; l = l->next)
+    {
+	    NSView* view = (NSView*) l->data;
+	    gettimeofday (&now, NULL);
+	    //g_print ("display @%d.%d %p\n", now.tv_sec, now.tv_usec, view);
+	    [view displayIfNeeded];
+    }
+
+
+  for (l = flush_nswindows; l; l = l->next)
+    {
+      quartz_autodisplay_one_window ((NSWindow*)l->data);
+    }
+
+  g_slist_free (flush_nswindows);
+  flush_nswindows = NULL;
+  g_slist_free (flush_nsviews);
+  flush_nsviews = NULL;
+}
+
+/* Marks the toplevel for the specified window as needing an update. This
+ * works by disabling auto flushing of the window, which will be enabled in
+ * the next processing of updates.
+ */
+static void
+quartz_window_mark_for_update (GdkWindow *window)
+{
+  GdkWindow *toplevel;
+  GdkWindowImplQuartz *impl;
+  NSView* nsview;
+
+  toplevel = gdk_window_get_toplevel (window);
+
+  if (toplevel)
+    {
+      GdkWindowObject *private;
+      GdkWindowImplQuartz *top_impl;
+      NSWindow *nswindow;
+
+      private = (GdkWindowObject *) toplevel;
+      top_impl = (GdkWindowImplQuartz *) private->impl;
+      nswindow = top_impl->toplevel;
+
+      if (nswindow && ![nswindow isFlushWindowDisabled])
+        {
+          [nswindow retain];
+          [nswindow disableFlushWindow];
+          flush_nswindows = g_slist_prepend (flush_nswindows, nswindow);
+        }
+    }
+
+  /* queue the view independently of the window, so that we can update
+     just some views per window when the time is right
+  */
+
+  impl = (GdkWindowImplQuartz*)(((GdkWindowObject*)window)->impl);
+  nsview = impl->view;
+  
+  if (nsview && g_slist_find (flush_nsviews, nsview) == NULL)
+    {
+	  flush_nsviews = g_slist_prepend (flush_nsviews, nsview);
+    }
+}
+
+static void
 gdk_window_quartz_process_updates_internal (GdkWindow *window)
 {
   GdkWindowObject *private = (GdkWindowObject *) window;
   GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *) private->impl;
-      
+  struct timeval now;
+
+  //g_print ("update on windows @ %p\n", window);
+
   if (private->update_area)
     {
       int i, n_rects;
@@ -321,14 +421,17 @@
 
       for (i = 0; i < n_rects; i++) 
 	{
+		gettimeofday (&now, NULL);
+		//g_print ("@ %d.%d mark %p (V=%p)invalid for %d,%d %dx%d\n", now.tv_sec, now.tv_usec, window, 
+		// impl->view, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
 	  [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y,
 							rects[i].width, rects[i].height)];
 	}
 
-      [impl->view displayIfNeeded];
-
       g_free (rects);
     }
+
+  
 }
 
 static void
@@ -336,61 +439,32 @@
 {
   GSList *old_update_windows = update_windows;
   GSList *tmp_list = update_windows;
-  GSList *nswindows;
+  struct timeval now;
 
   update_idle = 0;
   update_windows = NULL;
-  nswindows = NULL;
 
   g_slist_foreach (old_update_windows, (GFunc) g_object_ref, NULL);
   
   GDK_QUARTZ_ALLOC_POOL;
 
+  gettimeofday (&now, NULL);
+  //g_print ("@ %d.%d process all updates operating on %d windows\n", 
+  //now.tv_sec, now.tv_usec, g_slist_length (tmp_list));
+
   while (tmp_list)
     {
-      GdkWindow *window = tmp_list->data;
-      GdkWindow *toplevel;
-
-      /* Only flush each toplevel at most once. */
-      toplevel = gdk_window_get_toplevel (window);
-      if (toplevel)
-        {
-          GdkWindowObject *private;
-          GdkWindowImplQuartz *impl;
-          NSWindow *nswindow;
-
-          private = (GdkWindowObject *) toplevel;
-          impl = (GdkWindowImplQuartz *) private->impl;
-          nswindow = impl->toplevel;
-
-          if (nswindow && ![nswindow isFlushWindowDisabled]) 
-            {
-              [nswindow disableFlushWindow];
-              nswindows = g_slist_prepend (nswindows, nswindow);
-            }
-        }
-
       gdk_window_quartz_process_updates_internal (tmp_list->data);
 
       g_object_unref (tmp_list->data);
       tmp_list = tmp_list->next;
     }
-
-  tmp_list = nswindows;
-  while (tmp_list) 
-    {
-      NSWindow *nswindow = tmp_list->data;
-
-      [nswindow enableFlushWindow];
-      [nswindow flushWindow];
-
-      tmp_list = tmp_list->next;
-    }
+  
+  quartz_window_autodisplay ();
 		    
   GDK_QUARTZ_RELEASE_POOL;
 
   g_slist_free (old_update_windows);
-  g_slist_free (nswindows);
 }
 
 static gboolean
@@ -434,6 +508,7 @@
       if (update_idle == 0)
         update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
                                                  gdk_window_quartz_update_idle, NULL, NULL);
+      quartz_window_mark_for_update (window);
     }
 }
 
@@ -447,8 +522,35 @@
 
   if (private->update_area)
     {
+      GdkWindowObject *top_private;	    
+      GdkWindowImplQuartz *top_impl;
+      NSWindow *nswindow;
+      GdkWindow *toplevel;
+
       GDK_QUARTZ_ALLOC_POOL;
+
+      /* setup invalid rects at quartz level */
+
       gdk_window_quartz_process_updates_internal ((GdkWindow *) private);
+      
+      /* redraw just the view */
+
+      [impl->view displayIfNeeded];
+
+      toplevel = gdk_window_get_toplevel ((GdkWindow*) private);
+
+      if (toplevel) {
+	      top_private = (GdkWindowObject *) toplevel;
+	      top_impl = (GdkWindowImplQuartz *) top_private->impl;
+	      nswindow = top_impl->toplevel;
+
+	      /* flush the window */
+	      
+	      quartz_autodisplay_one_window (nswindow);
+      }
+
+      flush_nswindows = g_slist_remove (flush_nswindows, nswindow);
+      flush_nsviews = g_slist_remove (flush_nsviews, impl->view);
       update_windows = g_slist_remove (update_windows, private);
       GDK_QUARTZ_RELEASE_POOL;
     }
@@ -1060,6 +1162,7 @@
   GdkWindowImplQuartz *impl;
   GdkWindowObject *parent;
   GdkWindow *mouse_window;
+  GdkWindow *toplevel;
 
   private = GDK_WINDOW_OBJECT (window);
   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
@@ -1067,6 +1170,29 @@
   update_windows = g_slist_remove (update_windows, window);
   main_window_stack = g_slist_remove (main_window_stack, window);
 
+  flush_nsviews = g_slist_remove (flush_nsviews, impl->view);
+
+  toplevel = gdk_window_get_toplevel (window);
+
+  if (toplevel)
+    {
+      GdkWindowObject *top_private;
+      GdkWindowImplQuartz *top_impl;
+      NSWindow *nswindow;
+
+      top_private = (GdkWindowObject *) toplevel;
+      top_impl = (GdkWindowImplQuartz *) top_private->impl;
+      nswindow = top_impl->toplevel;
+
+      if (nswindow && [nswindow isFlushWindowDisabled]) 
+        {
+	    [nswindow enableFlushWindow];
+	    [nswindow flushWindowIfNeeded];
+	    flush_nswindows = g_slist_remove (flush_nswindows, nswindow);
+	    [nswindow release];
+	}
+    }
+
   g_list_free (impl->sorted_children);
   impl->sorted_children = NULL;
 
@@ -2928,6 +3054,7 @@
   GdkWindowObject *private = (GdkWindowObject *) window;
   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
   NSRect frame;
+  int menu_bar_height;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
@@ -2952,9 +3079,10 @@
       gdk_window_set_decorations (window, 0);
 
       frame = [[NSScreen mainScreen] frame];
+      menu_bar_height = GetMBarHeight();
       move_resize_window_internal (window,
-                                   0, 0, 
-                                   frame.size.width, frame.size.height);
+				   0, menu_bar_height, 
+				   frame.size.width, frame.size.height - menu_bar_height);
     }
 
   SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
Index: gdk/gdkinternals.h
===================================================================
--- gdk/gdkinternals.h	(revision 20839)
+++ gdk/gdkinternals.h	(working copy)
@@ -181,6 +181,11 @@
 void      _gdk_events_queue  (GdkDisplay *display);
 GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
 
+void      _gdk_event_set_windowing_data (GdkEvent *event,
+					 gpointer data,
+					 GDestroyNotify notify);
+gpointer  _gdk_event_get_windowing_data (GdkEvent *event);
+
 GList* _gdk_event_queue_find_first  (GdkDisplay *display);
 void   _gdk_event_queue_remove_link (GdkDisplay *display,
 				     GList      *node);
Index: gdk/win32/gdkevents-win32.c
===================================================================
--- gdk/win32/gdkevents-win32.c	(revision 20839)
+++ gdk/win32/gdkevents-win32.c	(working copy)
@@ -1071,9 +1071,10 @@
 	       event->configure.width, event->configure.height);
       break;
     case GDK_SCROLL:
-      g_print ("(%.4g,%.4g) (%.4g,%.4g) %s ",
+      g_print ("(%.4g,%.4g) (%.4g,%.4g) %.4g %s ",
 	       event->scroll.x, event->scroll.y,
 	       event->scroll.x_root, event->scroll.y_root,
+	       event->scroll.delta,
 	       (event->scroll.direction == GDK_SCROLL_UP ? "UP" :
 		(event->scroll.direction == GDK_SCROLL_DOWN ? "DOWN" :
 		 (event->scroll.direction == GDK_SCROLL_LEFT ? "LEFT" :
@@ -2731,6 +2732,7 @@
       event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y;
       event->scroll.state = build_pointer_event_state (msg);
       event->scroll.device = _gdk_display->core_pointer;
+      event->scroll.delta = 1;
 
       append_event (event);
       
Index: gdk/x11/gdkevents-x11.c
===================================================================
--- gdk/x11/gdkevents-x11.c	(revision 20839)
+++ gdk/x11/gdkevents-x11.c	(working copy)
@@ -1135,7 +1135,8 @@
 	  event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
 	  event->scroll.state = (GdkModifierType) xevent->xbutton.state;
 	  event->scroll.device = display->core_pointer;
-	  
+	  event->scroll.delta = 1;
+
 	  if (!set_screen_from_root (display, event, xevent->xbutton.root))
 	    {
 	      return_val = FALSE;
