diff --git a/gdk/quartz/GdkQuartzWindow.c b/gdk/quartz/GdkQuartzWindow.c
index dcd7250..9da005f 100644
--- a/gdk/quartz/GdkQuartzWindow.c
+++ b/gdk/quartz/GdkQuartzWindow.c
@@ -22,11 +22,11 @@
 #include "gdkwindow-quartz.h"
 #include "gdkprivate-quartz.h"
 
-@implementation GdkQuartzWindow
+@implementation GdkQuartzWindowDelegate
 
 -(BOOL)windowShouldClose:(id)sender
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
   GdkEvent *event;
 
   event = gdk_event_new (GDK_DELETE);
@@ -41,14 +41,14 @@
 
 -(void)windowWillMiniaturize:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
 
   _gdk_quartz_window_detach_from_parent (window);
 }
 
 -(void)windowDidMiniaturize:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
 
   gdk_synthesize_window_state (window, 0, 
 			       GDK_WINDOW_STATE_ICONIFIED);
@@ -56,7 +56,7 @@
 
 -(void)windowDidDeminiaturize:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
 
   _gdk_quartz_window_attach_to_parent (window);
 
@@ -65,29 +65,29 @@
 
 -(void)windowDidBecomeKey:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
 
   _gdk_quartz_events_update_focus_window (window, TRUE);
 }
 
 -(void)windowDidResignKey:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
 
   _gdk_quartz_events_update_focus_window (window, FALSE);
 }
 
 -(void)windowDidBecomeMain:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
 
-  if (![self isVisible])
+  if (![component isVisible])
     {
       /* Note: This is a hack needed because for unknown reasons, hidden
        * windows get shown when clicking the dock icon when the application
        * is not already active.
        */
-      [self orderOut:nil];
+      [component orderOut:nil];
       return;
     }
 
@@ -98,7 +98,7 @@
 {
   GdkWindow *window;
 
-  window = [[self contentView] gdkWindow];
+  window = [[component contentView] gdkWindow];
   _gdk_quartz_window_did_resign_main (window);
 }
 
@@ -110,36 +110,9 @@
   inMove = YES;
 }
 
--(void)sendEvent:(NSEvent *)event
-{
-  switch ([event type])
-    {
-    case NSLeftMouseUp:
-      inManualMove = NO;
-      inManualResize = NO;
-      inMove = NO;
-      break;
-
-    case NSLeftMouseDragged:
-      if ([self trackManualMove] || [self trackManualResize])
-        return;
-      break;
-
-    default:
-      break;
-    }
-
-  [super sendEvent:event];
-}
-
--(BOOL)isInMove
-{
-  return inMove;
-}
-
 -(void)windowDidMove:(NSNotification *)aNotification
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindow *window = [[component contentView] gdkWindow];
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkEvent *event;
 
@@ -158,15 +131,15 @@
 
 -(void)windowDidResize:(NSNotification *)aNotification
 {
-  NSRect content_rect = [self contentRectForFrameRect:[self frame]];
-  GdkWindow *window = [[self contentView] gdkWindow];
+  NSRect content_rect = [component contentRectForFrameRect:[component frame]];
+  GdkWindow *window = [[component contentView] gdkWindow];
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkEvent *event;
 
   private->width = content_rect.size.width;
   private->height = content_rect.size.height;
 
-  [[self contentView] setFrame:NSMakeRect (0, 0, private->width, private->height)];
+  [[component contentView] setFrame:NSMakeRect (0, 0, private->width, private->height)];
 
   _gdk_window_update_size (window);
 
@@ -181,115 +154,37 @@
   _gdk_event_queue_append (gdk_display_get_default (), event);
 }
 
--(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
+
+-(id)initWithWindow:(NSWindow *)window contentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
 {
-  self = [super initWithContentRect:contentRect
-	                  styleMask:styleMask
-	                    backing:backingType
-	                      defer:flag
-                             screen:screen];
+  component = [window initWithContentRect:contentRect
+                                styleMask:styleMask
+                                  backing:backingType
+                                    defer:flag
+                                   screen:screen];
 
-  [self setAcceptsMouseMovedEvents:YES];
-  [self setDelegate:self];
-  [self setReleasedWhenClosed:YES];
+  [component setAcceptsMouseMovedEvents:YES];
+  [component setDelegate:self];
+  [component setReleasedWhenClosed:YES];
 
-  return self;
+  return component;
 }
 
--(BOOL)canBecomeMainWindow
-{
-  GdkWindow *window = [[self contentView] gdkWindow];
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
-
-  switch (impl->type_hint)
-    {
-    case GDK_WINDOW_TYPE_HINT_NORMAL:
-    case GDK_WINDOW_TYPE_HINT_DIALOG:
-      return YES;
-      
-    case GDK_WINDOW_TYPE_HINT_MENU:
-    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
-    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
-    case GDK_WINDOW_TYPE_HINT_UTILITY:
-    case GDK_WINDOW_TYPE_HINT_DOCK:
-    case GDK_WINDOW_TYPE_HINT_DESKTOP:
-    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
-    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
-    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
-    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
-    case GDK_WINDOW_TYPE_HINT_COMBO:
-    case GDK_WINDOW_TYPE_HINT_DND:
-      return NO;
-    }
-  
-  return YES;
-}
 
--(BOOL)canBecomeKeyWindow
+- (BOOL)isInMove
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
-
-  if (!private->accept_focus)
-    return NO;
-
-  /* Popup windows should not be able to get focused in the window
-   * manager sense, it's only handled through grabs.
-   */
-  if (private->window_type == GDK_WINDOW_TEMP)
-    return NO;
-
-  switch (impl->type_hint)
-    {
-    case GDK_WINDOW_TYPE_HINT_NORMAL:
-    case GDK_WINDOW_TYPE_HINT_DIALOG:
-    case GDK_WINDOW_TYPE_HINT_MENU:
-    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
-    case GDK_WINDOW_TYPE_HINT_UTILITY:
-    case GDK_WINDOW_TYPE_HINT_DOCK:
-    case GDK_WINDOW_TYPE_HINT_DESKTOP:
-    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
-    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
-    case GDK_WINDOW_TYPE_HINT_COMBO:
-      return YES;
-      
-    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
-    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
-    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
-    case GDK_WINDOW_TYPE_HINT_DND:
-      return NO;
-    }
-  
-  return YES;
+  return inMove;
 }
 
-- (void)showAndMakeKey:(BOOL)makeKey
+- (void)setIsInMove:(BOOL)setting
 {
-  GdkWindow *window = [[self contentView] gdkWindow];
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
-
-  inShowOrHide = YES;
-
-  if (makeKey)
-    [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
-  else
-    [impl->toplevel orderFront:nil];
-
-  inShowOrHide = NO;
+  inMove = setting;
 }
 
-- (void)hide
-{
-  GdkWindow *window = [[self contentView] gdkWindow];
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
 
-  inShowOrHide = YES;
-  [impl->toplevel orderOut:nil];
-  inShowOrHide = NO;
+- (void)setIsInManualMove:(BOOL)setting
+{
+  inManualMove = setting;
 }
 
 - (BOOL)trackManualMove
@@ -297,12 +192,12 @@
   NSPoint currentLocation;
   NSPoint newOrigin;
   NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
-  NSRect windowFrame = [self frame];
+  NSRect windowFrame = [component frame];
 
   if (!inManualMove)
     return NO;
 
-  currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+  currentLocation = [component convertBaseToScreen:[component mouseLocationOutsideOfEventStream]];
   newOrigin.x = currentLocation.x - initialMoveLocation.x;
   newOrigin.y = currentLocation.y - initialMoveLocation.y;
 
@@ -310,25 +205,31 @@
   if (newOrigin.y + windowFrame.size.height > screenFrame.origin.y + screenFrame.size.height)
     newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height;
 
-  [self setFrameOrigin:newOrigin];
+  [component setFrameOrigin:newOrigin];
 
   return YES;
 }
 
 -(void)beginManualMove
 {
-  NSRect frame = [self frame];
+  NSRect frame = [component frame];
 
   if (inMove || inManualMove || inManualResize)
     return;
 
   inManualMove = YES;
 
-  initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+  initialMoveLocation = [component convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
   initialMoveLocation.x -= frame.origin.x;
   initialMoveLocation.y -= frame.origin.y;
 }
 
+
+- (void)setIsInManualResize:(BOOL)setting
+{
+  inManualResize = setting;
+}
+
 - (BOOL)trackManualResize
 {
   NSPoint currentLocation;
@@ -341,7 +242,7 @@
 
   inTrackManualResize = YES;
 
-  currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+  currentLocation = [component convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
   currentLocation.x -= initialResizeFrame.origin.x;
   currentLocation.y -= initialResizeFrame.origin.y;
 
@@ -352,7 +253,7 @@
   newFrame.size.width = initialResizeFrame.size.width + dx;
   newFrame.size.height = initialResizeFrame.size.height + dy;
 
-  min_size = [self contentMinSize];
+  min_size = [component contentMinSize];
   if (newFrame.size.width < min_size.width)
     newFrame.size.width = min_size.width;
   if (newFrame.size.height < min_size.height)
@@ -367,7 +268,7 @@
   newFrame.origin.x = initialResizeFrame.origin.x;
   newFrame.origin.y = initialResizeFrame.origin.y - dy;
 
-  [self setFrame:newFrame display:YES];
+  [component setFrame:newFrame display:YES];
 
   /* Let the resizing be handled by GTK+. */
   if (g_main_context_pending (NULL))
@@ -385,14 +286,13 @@
 
   inManualResize = YES;
 
-  initialResizeFrame = [self frame];
-  initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+  initialResizeFrame = [component frame];
+  initialResizeLocation = [component convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
   initialResizeLocation.x -= initialResizeFrame.origin.x;
   initialResizeLocation.y -= initialResizeFrame.origin.y;
 }
 
 
-
 static GdkDragContext *current_context = NULL;
 
 static GdkDragAction
@@ -463,7 +363,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
   update_context_from_dragging_info (sender);
 
   event.dnd.type = GDK_DRAG_ENTER;
-  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+  event.dnd.window = g_object_ref ([[component contentView] gdkWindow]);
   event.dnd.send_event = FALSE;
   event.dnd.context = current_context;
   event.dnd.time = GDK_CURRENT_TIME;
@@ -489,7 +389,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
   GdkEvent event;
   
   event.dnd.type = GDK_DRAG_LEAVE;
-  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+  event.dnd.window = g_object_ref ([[component contentView] gdkWindow]);
   event.dnd.send_event = FALSE;
   event.dnd.context = current_context;
   event.dnd.time = GDK_CURRENT_TIME;
@@ -503,7 +403,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
 {
   NSPoint point = [sender draggingLocation];
-  NSPoint screen_point = [self convertBaseToScreen:point];
+  NSPoint screen_point = [component convertBaseToScreen:point];
   GdkEvent event;
   int gx, gy;
 
@@ -511,7 +411,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
   _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy);
 
   event.dnd.type = GDK_DRAG_MOTION;
-  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+  event.dnd.window = g_object_ref ([[component contentView] gdkWindow]);
   event.dnd.send_event = FALSE;
   event.dnd.context = current_context;
   event.dnd.time = GDK_CURRENT_TIME;
@@ -528,7 +428,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
 {
   NSPoint point = [sender draggingLocation];
-  NSPoint screen_point = [self convertBaseToScreen:point];
+  NSPoint screen_point = [component convertBaseToScreen:point];
   GdkEvent event;
   int gy, gx;
 
@@ -536,7 +436,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
   _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy);
 
   event.dnd.type = GDK_DROP_START;
-  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+  event.dnd.window = g_object_ref ([[component contentView] gdkWindow]);
   event.dnd.send_event = FALSE;
   event.dnd.context = current_context;
   event.dnd.time = GDK_CURRENT_TIME;
@@ -565,7 +465,7 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
   g_assert (_gdk_quartz_drag_source_context != NULL);
 
   event.dnd.type = GDK_DROP_FINISHED;
-  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
+  event.dnd.window = g_object_ref ([[component contentView] gdkWindow]);
   event.dnd.send_event = FALSE;
   event.dnd.context = _gdk_quartz_drag_source_context;
 
@@ -577,4 +477,206 @@ update_context_from_dragging_info (id <NSDraggingInfo> sender)
   _gdk_quartz_drag_source_context = NULL;
 }
 
+
+- (void)showAndMakeKey:(BOOL)makeKey
+{
+  GdkWindow *window = [[component contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+  inShowOrHide = YES;
+
+  if (makeKey)
+    [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
+  else
+    [impl->toplevel orderFront:nil];
+
+  inShowOrHide = NO;
+}
+
+- (void)hide
+{
+  GdkWindow *window = [[component contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+  inShowOrHide = YES;
+  [impl->toplevel orderOut:nil];
+  inShowOrHide = NO;
+}
+
+@end
+
+
+@implementation GdkQuartzWindow
+- (void)draggingEnded:(id <NSDraggingInfo>)sender
+{
+  /* Cocoa does not delegate this message by default. */
+  return [(GdkQuartzWindowDelegate *)[self delegate] draggingEnded:sender];
+}
+
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+  return [(GdkQuartzWindowDelegate *)[self delegate] wantsPeriodicDraggingUpdates];
+}
+
+- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
+{
+  [(GdkQuartzWindowDelegate *)[self delegate] draggedImage:anImage endedAt:aPoint operation:operation];
+}
+
+-(void)sendEvent:(NSEvent *)event
+{
+  GdkQuartzWindowDelegate *delegate = (GdkQuartzWindowDelegate *)[self delegate];
+
+  switch ([event type])
+    {
+    case NSLeftMouseUp:
+      [delegate setIsInManualMove:NO];
+      [delegate setIsInManualResize:NO];
+      [delegate setIsInMove:NO];
+      break;
+
+    case NSLeftMouseDragged:
+      if ([delegate trackManualMove] ||
+          [delegate trackManualResize])
+        return;
+      break;
+
+    default:
+      break;
+    }
+
+  [super sendEvent:event];
+}
+
+-(BOOL)canBecomeMainWindow
+{
+  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+  switch (impl->type_hint)
+    {
+    case GDK_WINDOW_TYPE_HINT_NORMAL:
+    case GDK_WINDOW_TYPE_HINT_DIALOG:
+      return YES;
+      
+    case GDK_WINDOW_TYPE_HINT_MENU:
+    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+    case GDK_WINDOW_TYPE_HINT_UTILITY:
+    case GDK_WINDOW_TYPE_HINT_DOCK:
+    case GDK_WINDOW_TYPE_HINT_DESKTOP:
+    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+    case GDK_WINDOW_TYPE_HINT_COMBO:
+    case GDK_WINDOW_TYPE_HINT_DND:
+      return NO;
+    }
+  
+  return YES;
+}
+
+-(BOOL)canBecomeKeyWindow
+{
+  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+  if (!private->accept_focus)
+    return NO;
+
+  /* Popup windows should not be able to get focused in the window
+   * manager sense, it's only handled through grabs.
+   */
+  if (private->window_type == GDK_WINDOW_TEMP)
+    return NO;
+
+  switch (impl->type_hint)
+    {
+    case GDK_WINDOW_TYPE_HINT_NORMAL:
+    case GDK_WINDOW_TYPE_HINT_DIALOG:
+    case GDK_WINDOW_TYPE_HINT_MENU:
+    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+    case GDK_WINDOW_TYPE_HINT_UTILITY:
+    case GDK_WINDOW_TYPE_HINT_DOCK:
+    case GDK_WINDOW_TYPE_HINT_DESKTOP:
+    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+    case GDK_WINDOW_TYPE_HINT_COMBO:
+      return YES;
+      
+    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+    case GDK_WINDOW_TYPE_HINT_DND:
+      return NO;
+    }
+  
+  return YES;
+}
+
+@end
+
+
+@implementation GdkQuartzPanel
+- (void)draggingEnded:(id <NSDraggingInfo>)sender
+{
+  /* Cocoa does not delegate this message by default. */
+  return [(GdkQuartzWindowDelegate *)[self delegate] draggingEnded:sender];
+}
+
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+  return [(GdkQuartzWindowDelegate *)[self delegate] wantsPeriodicDraggingUpdates];
+}
+
+- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
+{
+  [(GdkQuartzWindowDelegate *)[self delegate] draggedImage:anImage endedAt:aPoint operation:operation];
+}
+
+-(void)sendEvent:(NSEvent *)event
+{
+  GdkQuartzWindowDelegate *delegate = (GdkQuartzWindowDelegate *)[self delegate];
+
+  switch ([event type])
+    {
+    case NSLeftMouseUp:
+      [delegate setIsInManualMove:NO];
+      [delegate setIsInManualResize:NO];
+      [delegate setIsInMove:NO];
+      break;
+
+    case NSLeftMouseDragged:
+      if ([delegate trackManualMove] ||
+          [delegate trackManualResize])
+        return;
+      break;
+
+    default:
+      break;
+    }
+
+  [super sendEvent:event];
+}
+
+/* Panels cannot become the main window, but they can become the
+ * key window.
+ */
+
+-(BOOL)canBecomeKeyWindow
+{
+  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+
+  if (!private->accept_focus)
+    return NO;
+
+  return YES;
+}
+
 @end
diff --git a/gdk/quartz/GdkQuartzWindow.h b/gdk/quartz/GdkQuartzWindow.h
index e6d1b4e..45eeb27 100644
--- a/gdk/quartz/GdkQuartzWindow.h
+++ b/gdk/quartz/GdkQuartzWindow.h
@@ -22,29 +22,45 @@
 #import <Foundation/Foundation.h>
 #include <glib.h>
 
-@interface GdkQuartzWindow : NSWindow {
-  BOOL    inMove;
-  BOOL    inShowOrHide;
-
-  /* Manually triggered move/resize (not by the window manager) */
-  BOOL    inManualMove;
-  BOOL    inManualResize;
-  BOOL    inTrackManualResize;
-  NSPoint initialMoveLocation;
-  NSPoint initialResizeLocation;
-  NSRect  initialResizeFrame;
-}
+#if NAC_OS_X_VERSION_10_6 > MAX_OS_X_VERSION_MAX_ALLOWED
+@protocol NSWindowDelegate <NSObject> @end
+#endif
 
+@protocol GdkQuartzWindowProtocol < NSWindowDelegate >
 -(BOOL)isInMove;
+-(void)setIsInMove:(BOOL)setting;
+
+-(void)setIsInManualMove:(BOOL)setting;
 -(void)beginManualMove;
 -(BOOL)trackManualMove;
+
+-(void)setIsInManualResize:(BOOL)setting;
 -(void)beginManualResize;
 -(BOOL)trackManualResize;
+
 -(void)showAndMakeKey:(BOOL)makeKey;
 -(void)hide;
-
 @end
 
 
+@interface GdkQuartzWindow : NSWindow < NSWindowDelegate > { }@end
+@interface GdkQuartzPanel : NSPanel < NSWindowDelegate > { }@end
 
 
+@interface GdkQuartzWindowDelegate : NSWindow < GdkQuartzWindowProtocol > {
+  GdkQuartzWindow *component;
+
+  BOOL    inMove;
+  BOOL    inShowOrHide;
+
+  /* Manually triggered move/resize (not by the window manager) */
+  BOOL    inManualMove;
+  BOOL    inManualResize;
+  BOOL    inTrackManualResize;
+  NSPoint initialMoveLocation;
+  NSPoint initialResizeLocation;
+  NSRect  initialResizeFrame;
+}
+
+-(id)initWithWindow:(NSWindow *)window contentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backinType defer:(BOOL)flag screen:(NSScreen *)screen;
+@end
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index 1a0b678..fb1fb90 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -1130,7 +1130,7 @@ gdk_event_translate (GdkEvent *event,
    * dragged. This is a workaround for the window getting events for
    * the window title.
    */
-  if ([(GdkQuartzWindow *)nswindow isInMove])
+  if ([(GdkQuartzWindowDelegate *)[nswindow delegate] isInMove])
     {
       break_all_grabs (get_time_from_ns_event (nsevent));
       return FALSE;
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index a8e385f..6549fc4 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -964,6 +964,12 @@ _gdk_window_impl_new (GdkWindow     *window,
           {
             style_mask = NSBorderlessWindowMask;
           }
+        else if (attributes->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
+          {
+            style_mask = (NSTitledWindowMask |
+                          NSClosableWindowMask |
+                          NSUtilityWindowMask);
+          }
         else
           {
             style_mask = (NSTitledWindowMask |
@@ -972,11 +978,21 @@ _gdk_window_impl_new (GdkWindow     *window,
                           NSResizableWindowMask);
           }
 
-	impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect 
-			                                    styleMask:style_mask
-			                                      backing:NSBackingStoreBuffered
-			                                        defer:NO
-                                                                screen:screen];
+        if (attributes->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
+          impl->toplevel = [[GdkQuartzWindowDelegate alloc] initWithWindow:[GdkQuartzPanel alloc]
+                                                               contentRect:content_rect
+                                                                 styleMask:style_mask
+                                                                   backing:NSBackingStoreBuffered
+                                                                     defer:NO
+                                                                    screen:screen];
+        else
+          impl->toplevel = [[GdkQuartzWindowDelegate alloc] initWithWindow:[GdkQuartzWindow alloc]
+                                                               contentRect:content_rect
+                                                                 styleMask:style_mask
+                                                                   backing:NSBackingStoreBuffered
+                                                                     defer:NO
+                                                                    screen:screen];
+
 
 	if (attributes_mask & GDK_WA_TITLE)
 	  title = attributes->title;
@@ -1184,7 +1200,7 @@ gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
       make_key = (private->accept_focus && focus_on_map &&
                   private->window_type != GDK_WINDOW_TEMP);
 
-      [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key];
+      [(GdkQuartzWindowDelegate*)[impl->toplevel delegate] showAndMakeKey:make_key];
       clear_toplevel_order ();
 
       _gdk_quartz_events_send_map_event (window);
@@ -1282,7 +1298,7 @@ gdk_window_quartz_hide (GdkWindow *window)
       if (impl->transient_for)
         _gdk_quartz_window_detach_from_parent (window);
 
-      [(GdkQuartzWindow*)impl->toplevel hide];
+      [(GdkQuartzWindowDelegate*)[impl->toplevel delegate] hide];
     }
   else if (impl->view)
     {
@@ -1570,8 +1586,7 @@ update_toplevel_order (void)
 {
   GdkWindowObject *root;
   GdkWindowImplQuartz *root_impl;
-  NSEnumerator *enumerator;
-  id nswindow;
+  NSInteger count;
   GList *toplevels = NULL;
 
   root = GDK_WINDOW_OBJECT (_gdk_root);
@@ -1582,16 +1597,36 @@ update_toplevel_order (void)
 
   GDK_QUARTZ_ALLOC_POOL;
 
-  enumerator = [[NSApp orderedWindows] objectEnumerator];
-  while ((nswindow = [enumerator nextObject]))
+  /* We cannot use the orderedWindows message of NSApplication, because
+   * the returned window list by that message does not contain NSPanels.
+   * For supporting "utility windows" we use NSPanels and to get the
+   * event handling fully right they have to be considered as normal
+   * toplevels here.
+   */
+  NSCountWindowsForContext ((NSInteger)[NSApp contextID], &count);
+  if (count)
     {
-      GdkWindow *window;
+      NSInteger i;
+      NSInteger *windows = g_new0 (NSInteger, count);
+
+      NSWindowListForContext ((NSInteger)[NSApp contextID], count, windows);
+
+      for (i = 0; i < count; i++)
+        {
+          id nswindow;
 
-      if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
-        continue;
+          nswindow = [NSApp windowWithWindowNumber:windows[i]];
 
-      window = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
-      toplevels = g_list_prepend (toplevels, window);
+          if ([[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
+            {
+              GdkWindow *window;
+
+              window = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
+              toplevels = g_list_prepend (toplevels, window);
+            }
+        }
+
+      free (windows);
     }
 
   GDK_QUARTZ_RELEASE_POOL;
@@ -2360,7 +2395,6 @@ gint window_type_hint_to_level (GdkWindowTypeHint hint)
   switch (hint)
     {
     case GDK_WINDOW_TYPE_HINT_DOCK:
-    case GDK_WINDOW_TYPE_HINT_UTILITY:
       return NSFloatingWindowLevel;
 
     case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
@@ -2377,6 +2411,7 @@ gint window_type_hint_to_level (GdkWindowTypeHint hint)
     case GDK_WINDOW_TYPE_HINT_DND:
       return NSPopUpMenuWindowLevel;
 
+    case GDK_WINDOW_TYPE_HINT_UTILITY:
     case GDK_WINDOW_TYPE_HINT_NORMAL:  /* Normal toplevel window */
     case GDK_WINDOW_TYPE_HINT_DIALOG:  /* Dialog window */
     case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
@@ -2517,7 +2552,7 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
       return;
     }
 
-  [(GdkQuartzWindow *)impl->toplevel beginManualResize];
+  [(GdkQuartzWindowDelegate *)[impl->toplevel delegate] beginManualResize];
 }
 
 void
@@ -2543,7 +2578,7 @@ gdk_window_begin_move_drag (GdkWindow *window,
       return;
     }
 
-  [(GdkQuartzWindow *)impl->toplevel beginManualMove];
+  [(GdkQuartzWindowDelegate *)[impl->toplevel delegate] beginManualMove];
 }
 
 void
@@ -2603,6 +2638,11 @@ gdk_window_set_decorations (GdkWindow       *window,
     {
       new_mask = NSBorderlessWindowMask;
     }
+  else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
+    {
+      new_mask = (NSTitledWindowMask | NSClosableWindowMask |
+                  NSUtilityWindowMask);
+    }
   else
     {
       /* FIXME: Honor other GDK_DECOR_* flags. */
