1 /////////////////////////////////////////////////////////////////////////////
 
   2 // Name:        src/cocoa/window.mm
 
   3 // Purpose:     wxWindowCocoa
 
   4 // Author:      David Elliott
 
   8 // Copyright:   (c) 2002 David Elliott
 
   9 // Licence:     wxWindows license
 
  10 /////////////////////////////////////////////////////////////////////////////
 
  12 #include "wx/wxprec.h"
 
  15     #include "wx/window.h"
 
  18 #include "wx/cocoa/autorelease.h"
 
  20 #import <AppKit/NSView.h>
 
  21 #import <AppKit/NSEvent.h>
 
  22 #import <AppKit/NSScrollView.h>
 
  23 #import <AppKit/NSColor.h>
 
  24 #import <AppKit/NSClipView.h>
 
  25 #import <Foundation/NSException.h>
 
  27 #include <objc/objc-runtime.h>
 
  29 // Turn this on to paint green over the dummy views for debugging
 
  30 #undef WXCOCOA_FILL_DUMMY_VIEW
 
  32 #ifdef WXCOCOA_FILL_DUMMY_VIEW
 
  33 #import <AppKit/NSBezierPath.h>
 
  34 #endif //def WXCOCOA_FILL_DUMMY_VIEW
 
  36 // ========================================================================
 
  38 // ========================================================================
 
  39 class wxWindowCocoaHider: protected wxCocoaNSView
 
  41     DECLARE_NO_COPY_CLASS(wxWindowCocoaHider)
 
  43     wxWindowCocoaHider(wxWindow *owner);
 
  44     virtual ~wxWindowCocoaHider();
 
  45     inline WX_NSView GetNSView() { return m_dummyNSView; }
 
  47     wxWindowCocoa *m_owner;
 
  48     WX_NSView m_dummyNSView;
 
  49     virtual void Cocoa_FrameChanged(void);
 
  50 #ifdef WXCOCOA_FILL_DUMMY_VIEW
 
  51     virtual bool Cocoa_drawRect(const NSRect& rect);
 
  52 #endif //def WXCOCOA_FILL_DUMMY_VIEW
 
  57 // ========================================================================
 
  58 // wxWindowCocoaScroller
 
  59 // ========================================================================
 
  60 class wxWindowCocoaScroller: protected wxCocoaNSView
 
  62     DECLARE_NO_COPY_CLASS(wxWindowCocoaScroller)
 
  64     wxWindowCocoaScroller(wxWindow *owner);
 
  65     virtual ~wxWindowCocoaScroller();
 
  66     inline WX_NSScrollView GetNSScrollView() { return m_cocoaNSScrollView; }
 
  67     void ClientSizeToSize(int &width, int &height);
 
  68     void DoGetClientSize(int *x, int *y) const;
 
  72     wxWindowCocoa *m_owner;
 
  73     WX_NSScrollView m_cocoaNSScrollView;
 
  74     virtual void Cocoa_FrameChanged(void);
 
  76     wxWindowCocoaScroller();
 
  79 // ========================================================================
 
  81 // ========================================================================
 
  82 @interface wxDummyNSView : NSView
 
  83 - (NSView *)hitTest:(NSPoint)aPoint;
 
  86 @implementation wxDummyNSView : NSView
 
  87 - (NSView *)hitTest:(NSPoint)aPoint
 
  94 // ========================================================================
 
  96 // ========================================================================
 
  97 wxWindowCocoaHider::wxWindowCocoaHider(wxWindow *owner)
 
 101     wxASSERT(owner->GetNSViewForHiding());
 
 102     m_dummyNSView = [[wxDummyNSView alloc]
 
 103         initWithFrame:[owner->GetNSViewForHiding() frame]];
 
 104     [m_dummyNSView setAutoresizingMask: [owner->GetNSViewForHiding() autoresizingMask]];
 
 105     AssociateNSView(m_dummyNSView);
 
 108 wxWindowCocoaHider::~wxWindowCocoaHider()
 
 110     DisassociateNSView(m_dummyNSView);
 
 111     [m_dummyNSView release];
 
 114 void wxWindowCocoaHider::Cocoa_FrameChanged(void)
 
 116     // Keep the real window in synch with the dummy
 
 117     wxASSERT(m_dummyNSView);
 
 118     [m_owner->GetNSViewForHiding() setFrame:[m_dummyNSView frame]];
 
 121 #ifdef WXCOCOA_FILL_DUMMY_VIEW
 
 122 bool wxWindowCocoaHider::Cocoa_drawRect(const NSRect& rect)
 
 124     NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:rect];
 
 125     [[NSColor greenColor] set];
 
 130 #endif //def WXCOCOA_FILL_DUMMY_VIEW
 
 132 // ========================================================================
 
 133 // wxFlippedNSClipView
 
 134 // ========================================================================
 
 135 @interface wxFlippedNSClipView : NSClipView
 
 139 @implementation wxFlippedNSClipView : NSClipView
 
 147 // ========================================================================
 
 148 // wxWindowCocoaScroller
 
 149 // ========================================================================
 
 150 wxWindowCocoaScroller::wxWindowCocoaScroller(wxWindow *owner)
 
 153     wxAutoNSAutoreleasePool pool;
 
 155     wxASSERT(owner->GetNSView());
 
 156     m_cocoaNSScrollView = [[NSScrollView alloc]
 
 157         initWithFrame:[owner->GetNSView() frame]];
 
 158     AssociateNSView(m_cocoaNSScrollView);
 
 160     /* Replace the default NSClipView with a flipped one.  This ensures
 
 161        scrolling is "pinned" to the top-left instead of bottom-right. */
 
 162     NSClipView *flippedClip = [[wxFlippedNSClipView alloc]
 
 163         initWithFrame: [[m_cocoaNSScrollView contentView] frame]];
 
 164     [m_cocoaNSScrollView setContentView:flippedClip];
 
 165     [flippedClip release];
 
 167     [m_cocoaNSScrollView setBackgroundColor: [NSColor windowBackgroundColor]];
 
 168     [m_cocoaNSScrollView setHasHorizontalScroller: YES];
 
 169     [m_cocoaNSScrollView setHasVerticalScroller: YES];
 
 173 void wxWindowCocoaScroller::Encapsulate()
 
 175     // Set the scroll view autoresizingMask to match the current NSView
 
 176     [m_cocoaNSScrollView setAutoresizingMask: [m_owner->GetNSView() autoresizingMask]];
 
 177     [m_owner->GetNSView() setAutoresizingMask: NSViewNotSizable];
 
 178     // NOTE: replaceSubView will cause m_cocaNSView to be released
 
 179     // except when it hasn't been added into an NSView hierarchy in which
 
 180     // case it doesn't need to be and this should work out to a no-op
 
 181     m_owner->CocoaReplaceView(m_owner->GetNSView(), m_cocoaNSScrollView);
 
 182     // The NSView is still retained by owner
 
 183     [m_cocoaNSScrollView setDocumentView: m_owner->GetNSView()];
 
 184     // Now it's also retained by the NSScrollView
 
 187 void wxWindowCocoaScroller::Unencapsulate()
 
 189     [m_cocoaNSScrollView setDocumentView: nil];
 
 190     m_owner->CocoaReplaceView(m_cocoaNSScrollView, m_owner->GetNSView());
 
 191     if(![[m_owner->GetNSView() superview] isFlipped])
 
 192         [m_owner->GetNSView() setAutoresizingMask: NSViewMinYMargin];
 
 195 wxWindowCocoaScroller::~wxWindowCocoaScroller()
 
 197     DisassociateNSView(m_cocoaNSScrollView);
 
 198     [m_cocoaNSScrollView release];
 
 201 void wxWindowCocoaScroller::ClientSizeToSize(int &width, int &height)
 
 203     NSSize frameSize = [NSScrollView
 
 204         frameSizeForContentSize: NSMakeSize(width,height)
 
 205         hasHorizontalScroller: [m_cocoaNSScrollView hasHorizontalScroller]
 
 206         hasVerticalScroller: [m_cocoaNSScrollView hasVerticalScroller]
 
 207         borderType: [m_cocoaNSScrollView borderType]];
 
 208     width = (int)frameSize.width;
 
 209     height = (int)frameSize.height;
 
 212 void wxWindowCocoaScroller::DoGetClientSize(int *x, int *y) const
 
 214     NSSize nssize = [m_cocoaNSScrollView contentSize];
 
 216         *x = (int)nssize.width;
 
 218         *y = (int)nssize.height;
 
 221 void wxWindowCocoaScroller::Cocoa_FrameChanged(void)
 
 223     wxLogTrace(wxTRACE_COCOA,wxT("Cocoa_FrameChanged"));
 
 224     wxSizeEvent event(m_owner->GetSize(), m_owner->GetId());
 
 225     event.SetEventObject(m_owner);
 
 226     m_owner->GetEventHandler()->ProcessEvent(event);
 
 229 // ========================================================================
 
 231 // ========================================================================
 
 232 // normally the base classes aren't included, but wxWindow is special
 
 233 #ifdef __WXUNIVERSAL__
 
 234 IMPLEMENT_ABSTRACT_CLASS(wxWindowCocoa, wxWindowBase)
 
 236 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
 
 239 BEGIN_EVENT_TABLE(wxWindowCocoa, wxWindowBase)
 
 242 wxWindow *wxWindowCocoa::sm_capturedWindow = NULL;
 
 245 void wxWindowCocoa::Init()
 
 247     m_cocoaNSView = NULL;
 
 249     m_cocoaScroller = NULL;
 
 250     m_isBeingDeleted = FALSE;
 
 252     m_shouldBeEnabled = true;
 
 256 bool wxWindow::Create(wxWindow *parent, wxWindowID winid,
 
 260            const wxString& name)
 
 262     if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
 
 265     // TODO: create the window
 
 266     m_cocoaNSView = NULL;
 
 267     SetNSView([[NSView alloc] initWithFrame: MakeDefaultNSRect(size)]);
 
 268     [m_cocoaNSView release];
 
 272         m_parent->AddChild(this);
 
 273         m_parent->CocoaAddChild(this);
 
 274         SetInitialFrameRect(pos,size);
 
 281 wxWindow::~wxWindow()
 
 283     wxAutoNSAutoreleasePool pool;
 
 286     // Make sure our parent (in the wxWindows sense) is our superview
 
 287     // before we go removing from it.
 
 288     if(m_parent && m_parent->GetNSView()==[GetNSViewForSuperview() superview])
 
 289         CocoaRemoveFromParent();
 
 291     delete m_cocoaScroller;
 
 295 void wxWindowCocoa::CocoaAddChild(wxWindowCocoa *child)
 
 297     NSView *childView = child->GetNSViewForSuperview();
 
 300     [m_cocoaNSView addSubview: childView];
 
 301     child->m_isShown = !m_cocoaHider;
 
 304 void wxWindowCocoa::CocoaRemoveFromParent(void)
 
 306     [GetNSViewForSuperview() removeFromSuperview];
 
 309 void wxWindowCocoa::SetNSView(WX_NSView cocoaNSView)
 
 311     // Assume setting the NSView to NULL means this wxWindow is being destroyed
 
 312     if(m_cocoaNSView && !cocoaNSView)
 
 315     bool need_debug = cocoaNSView || m_cocoaNSView;
 
 316     if(need_debug) wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxWindowCocoa=%p::SetNSView [m_cocoaNSView=%p retainCount]=%d"),this,m_cocoaNSView,[m_cocoaNSView retainCount]);
 
 317     DisassociateNSView(m_cocoaNSView);
 
 318     [cocoaNSView retain];
 
 319     [m_cocoaNSView release];
 
 320     m_cocoaNSView = cocoaNSView;
 
 321     AssociateNSView(m_cocoaNSView);
 
 322     if(need_debug) wxLogTrace(wxTRACE_COCOA_RetainRelease,wxT("wxWindowCocoa=%p::SetNSView [cocoaNSView=%p retainCount]=%d"),this,cocoaNSView,[cocoaNSView retainCount]);
 
 325 WX_NSView wxWindowCocoa::GetNSViewForSuperview() const
 
 328         ?   m_cocoaHider->GetNSView()
 
 330             ?   m_cocoaScroller->GetNSScrollView()
 
 334 WX_NSView wxWindowCocoa::GetNSViewForHiding() const
 
 336     return m_cocoaScroller
 
 337         ?   m_cocoaScroller->GetNSScrollView()
 
 341 bool wxWindowCocoa::Cocoa_drawRect(const NSRect &rect)
 
 343     wxLogTrace(wxTRACE_COCOA,wxT("Cocoa_drawRect"));
 
 344     // Recursion can happen if the event loop runs from within the paint
 
 345     // handler.  For instance, if an assertion dialog is shown.
 
 346     // FIXME: This seems less than ideal.
 
 349         wxLogDebug(wxT("Paint event recursion!"));
 
 354     // Set m_updateRegion
 
 355     const NSRect *rects = ▭ // The bounding box of the region
 
 357     // Try replacing the larger rectangle with a list of smaller ones:
 
 359     // This only works on Panther
 
 360 //    [GetNSView() getRectsBeingDrawn:&rects count:&countRects];
 
 361     // This compiles everywhere (and still only works on Panther)
 
 362     objc_msgSend(GetNSView(),@selector(getRectsBeingDrawn:count:),&rects,&countRects);
 
 365     m_updateRegion = wxRegion(rects,countRects);
 
 367     wxPaintEvent event(m_windowId);
 
 368     event.SetEventObject(this);
 
 369     bool ret = GetEventHandler()->ProcessEvent(event);
 
 374 void wxWindowCocoa::InitMouseEvent(wxMouseEvent& event, WX_NSEvent cocoaEvent)
 
 376     wxASSERT_MSG([m_cocoaNSView window]==[cocoaEvent window],wxT("Mouse event for different NSWindow"));
 
 377     NSPoint cocoaPoint = [m_cocoaNSView convertPoint:[(NSEvent*)cocoaEvent locationInWindow] fromView:nil];
 
 378     NSRect cocoaRect = [m_cocoaNSView frame];
 
 379     const wxPoint &clientorigin = GetClientAreaOrigin();
 
 380     event.m_x = (wxCoord)cocoaPoint.x - clientorigin.x;
 
 381     event.m_y = (wxCoord)(cocoaRect.size.height - cocoaPoint.y) - clientorigin.y;
 
 383     event.m_shiftDown = [cocoaEvent modifierFlags] & NSShiftKeyMask;
 
 384     event.m_controlDown = [cocoaEvent modifierFlags] & NSControlKeyMask;
 
 385     event.m_altDown = [cocoaEvent modifierFlags] & NSAlternateKeyMask;
 
 386     event.m_metaDown = [cocoaEvent modifierFlags] & NSCommandKeyMask;
 
 388     // TODO: set timestamp?
 
 389     event.SetEventObject(this);
 
 390     event.SetId(GetId());
 
 393 bool wxWindowCocoa::Cocoa_mouseMoved(WX_NSEvent theEvent)
 
 395     wxMouseEvent event(wxEVT_MOTION);
 
 396     InitMouseEvent(event,theEvent);
 
 397     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Drag @%d,%d"),event.m_x,event.m_y);
 
 398     return GetEventHandler()->ProcessEvent(event);
 
 401 bool wxWindowCocoa::Cocoa_mouseEntered(WX_NSEvent theEvent)
 
 406 bool wxWindowCocoa::Cocoa_mouseExited(WX_NSEvent theEvent)
 
 411 bool wxWindowCocoa::Cocoa_mouseDown(WX_NSEvent theEvent)
 
 413     wxMouseEvent event([theEvent clickCount]<2?wxEVT_LEFT_DOWN:wxEVT_LEFT_DCLICK);
 
 414     InitMouseEvent(event,theEvent);
 
 415     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Down @%d,%d num clicks=%d"),event.m_x,event.m_y,[theEvent clickCount]);
 
 416     return GetEventHandler()->ProcessEvent(event);
 
 419 bool wxWindowCocoa::Cocoa_mouseDragged(WX_NSEvent theEvent)
 
 421     wxMouseEvent event(wxEVT_MOTION);
 
 422     InitMouseEvent(event,theEvent);
 
 423     event.m_leftDown = true;
 
 424     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Drag @%d,%d"),event.m_x,event.m_y);
 
 425     return GetEventHandler()->ProcessEvent(event);
 
 428 bool wxWindowCocoa::Cocoa_mouseUp(WX_NSEvent theEvent)
 
 430     wxMouseEvent event(wxEVT_LEFT_UP);
 
 431     InitMouseEvent(event,theEvent);
 
 432     wxLogTrace(wxTRACE_COCOA,wxT("Mouse Up @%d,%d"),event.m_x,event.m_y);
 
 433     return GetEventHandler()->ProcessEvent(event);
 
 436 bool wxWindowCocoa::Cocoa_rightMouseDown(WX_NSEvent theEvent)
 
 438     wxMouseEvent event([theEvent clickCount]<2?wxEVT_RIGHT_DOWN:wxEVT_RIGHT_DCLICK);
 
 439     InitMouseEvent(event,theEvent);
 
 440     wxLogDebug(wxT("Mouse Down @%d,%d num clicks=%d"),event.m_x,event.m_y,[theEvent clickCount]);
 
 441     return GetEventHandler()->ProcessEvent(event);
 
 444 bool wxWindowCocoa::Cocoa_rightMouseDragged(WX_NSEvent theEvent)
 
 446     wxMouseEvent event(wxEVT_MOTION);
 
 447     InitMouseEvent(event,theEvent);
 
 448     event.m_rightDown = true;
 
 449     wxLogDebug(wxT("Mouse Drag @%d,%d"),event.m_x,event.m_y);
 
 450     return GetEventHandler()->ProcessEvent(event);
 
 453 bool wxWindowCocoa::Cocoa_rightMouseUp(WX_NSEvent theEvent)
 
 455     wxMouseEvent event(wxEVT_RIGHT_UP);
 
 456     InitMouseEvent(event,theEvent);
 
 457     wxLogDebug(wxT("Mouse Up @%d,%d"),event.m_x,event.m_y);
 
 458     return GetEventHandler()->ProcessEvent(event);
 
 461 bool wxWindowCocoa::Cocoa_otherMouseDown(WX_NSEvent theEvent)
 
 466 bool wxWindowCocoa::Cocoa_otherMouseDragged(WX_NSEvent theEvent)
 
 471 bool wxWindowCocoa::Cocoa_otherMouseUp(WX_NSEvent theEvent)
 
 476 void wxWindowCocoa::Cocoa_FrameChanged(void)
 
 478     wxLogTrace(wxTRACE_COCOA,wxT("Cocoa_FrameChanged"));
 
 479     wxSizeEvent event(GetSize(), m_windowId);
 
 480     event.SetEventObject(this);
 
 481     GetEventHandler()->ProcessEvent(event);
 
 484 bool wxWindow::Close(bool force)
 
 486     // The only reason this function exists is that it is virtual and
 
 487     // wxTopLevelWindowCocoa will override it.
 
 488     return wxWindowBase::Close(force);
 
 491 void wxWindow::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
 
 493     [[oldView superview] replaceSubview:oldView with:newView];
 
 496 bool wxWindow::EnableSelfAndChildren(bool enable)
 
 498     // If the state isn't changing, don't do anything
 
 499     if(!wxWindowBase::Enable(enable && m_shouldBeEnabled))
 
 501     // Set the state of the Cocoa window
 
 502     CocoaSetEnabled(m_isEnabled);
 
 503     // Disable all children or (if enabling) return them to their proper state
 
 504     for(wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
 
 505         node; node = node->GetNext())
 
 507         node->GetData()->EnableSelfAndChildren(enable);
 
 512 bool wxWindow::Enable(bool enable)
 
 514     // Keep track of what the window SHOULD be doing
 
 515     m_shouldBeEnabled = enable;
 
 516     // If the parent is disabled for any reason, then this window will be too.
 
 517     if(!IsTopLevel() && GetParent())
 
 519         enable = enable && GetParent()->IsEnabled();
 
 521     return EnableSelfAndChildren(enable);
 
 524 bool wxWindow::Show(bool show)
 
 526     wxAutoNSAutoreleasePool pool;
 
 527     // If the window is marked as visible, then it shouldn't have a dummy view
 
 528     // If the window is marked hidden, then it should have a dummy view
 
 529     // wxSpinCtrl (generic) abuses m_isShown, don't use it for any logic
 
 530 //    wxASSERT_MSG( (m_isShown && !m_dummyNSView) || (!m_isShown && m_dummyNSView),wxT("wxWindow: m_isShown does not agree with m_dummyNSView"));
 
 531     // Return false if there isn't a window to show or hide
 
 532     NSView *cocoaView = GetNSViewForHiding();
 
 537         // If state isn't changing, return false
 
 540         CocoaReplaceView(m_cocoaHider->GetNSView(), cocoaView);
 
 541         wxASSERT(![m_cocoaHider->GetNSView() superview]);
 
 544         wxASSERT([cocoaView superview]);
 
 548         // If state isn't changing, return false
 
 551         m_cocoaHider = new wxWindowCocoaHider(this);
 
 552         // NOTE: replaceSubview:with will cause m_cocaNSView to be
 
 553         // (auto)released which balances out addSubview
 
 554         CocoaReplaceView(cocoaView, m_cocoaHider->GetNSView());
 
 555         // m_coocaNSView is now only retained by us
 
 556         wxASSERT([m_cocoaHider->GetNSView() superview]);
 
 557         wxASSERT(![cocoaView superview]);
 
 563 void wxWindowCocoa::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 
 565     wxLogTrace(wxTRACE_COCOA_Window_Size,wxT("wxWindow=%p::DoSetSizeWindow(%d,%d,%d,%d,Auto: %s%s)"),this,x,y,width,height,(sizeFlags&wxSIZE_AUTO_WIDTH)?"W":".",sizeFlags&wxSIZE_AUTO_HEIGHT?"H":".");
 
 566     int currentX, currentY;
 
 567     int currentW, currentH;
 
 568     DoGetPosition(¤tX, ¤tY);
 
 569     DoGetSize(¤tW, ¤tH);
 
 570     if((x==-1) && !(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
 
 572     if((y==-1) && !(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
 
 575     AdjustForParentClientOrigin(x,y,sizeFlags);
 
 579     if((width==-1)&&!(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
 
 581         if(sizeFlags&wxSIZE_AUTO_WIDTH)
 
 583             size=DoGetBestSize();
 
 589     if((height==-1)&&!(sizeFlags&wxSIZE_ALLOW_MINUS_ONE))
 
 591         if(sizeFlags&wxSIZE_AUTO_HEIGHT)
 
 594                 size=DoGetBestSize();
 
 600     DoMoveWindow(x,y,width,height);
 
 603 void wxWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
 
 605     wxAutoNSAutoreleasePool pool;
 
 606     wxLogTrace(wxTRACE_COCOA_Window_Size,wxT("wxWindow=%p::DoMoveWindow(%d,%d,%d,%d)"),this,x,y,width,height);
 
 608     NSView *nsview = GetNSViewForSuperview();
 
 609     NSView *superview = [nsview superview];
 
 610     wxCHECK_RET(superview,wxT("NSView does not have a superview"));
 
 611     NSRect parentRect = [superview bounds];
 
 613     NSRect cocoaRect = NSMakeRect(x,parentRect.size.height-(y+height),width,height);
 
 614     [nsview setFrame: cocoaRect];
 
 615     // Be sure to redraw the parent to reflect the changed position
 
 616     [superview setNeedsDisplay:YES];
 
 619 void wxWindowCocoa::SetInitialFrameRect(const wxPoint& pos, const wxSize& size)
 
 621     NSView *nsview = GetNSViewForSuperview();
 
 622     NSView *superview = [nsview superview];
 
 623     wxCHECK_RET(superview,wxT("NSView does not have a superview"));
 
 624     NSRect parentRect = [superview bounds];
 
 625     NSRect frameRect = [nsview frame];
 
 627         frameRect.size.width = size.x;
 
 629         frameRect.size.height = size.y;
 
 630     frameRect.origin.x = pos.x;
 
 631     frameRect.origin.y = parentRect.size.height-(pos.y+frameRect.size.height);
 
 632     // Tell Cocoa to change the margin between the bottom of the superview
 
 633     // and the bottom of the control.  Keeps the control pinned to the top
 
 634     // of its superview so that its position in the wxWindows coordinate
 
 635     // system doesn't change.
 
 636     if(![superview isFlipped])
 
 637         [nsview setAutoresizingMask: NSViewMinYMargin];
 
 638     // MUST set the mask before setFrame: which can generate a size event
 
 639     // and cause a scroller to be added!
 
 640     [nsview setFrame: frameRect];
 
 644 void wxWindow::DoGetSize(int *w, int *h) const
 
 646     NSRect cocoaRect = [GetNSViewForSuperview() frame];
 
 648         *w=(int)cocoaRect.size.width;
 
 650         *h=(int)cocoaRect.size.height;
 
 651     wxLogTrace(wxTRACE_COCOA_Window_Size,wxT("wxWindow=%p::DoGetSize = (%d,%d)"),this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
 
 654 void wxWindow::DoGetPosition(int *x, int *y) const
 
 656     NSView *nsview = GetNSViewForSuperview();
 
 657     NSView *superview = [nsview superview];
 
 658     wxCHECK_RET(superview,wxT("NSView does not have a superview"));
 
 659     NSRect parentRect = [superview bounds];
 
 661     NSRect cocoaRect = [nsview frame];
 
 663         *x=(int)cocoaRect.origin.x;
 
 665         *y=(int)(parentRect.size.height-(cocoaRect.origin.y+cocoaRect.size.height));
 
 666     wxLogTrace(wxTRACE_COCOA_Window_Size,wxT("wxWindow=%p::DoGetPosition = (%d,%d)"),this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
 
 669 WXWidget wxWindow::GetHandle() const
 
 671     return m_cocoaNSView;
 
 674 void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
 
 676     [m_cocoaNSView setNeedsDisplay:YES];
 
 679 void wxWindow::SetFocus()
 
 684 void wxWindow::DoCaptureMouse()
 
 687     sm_capturedWindow = this;
 
 690 void wxWindow::DoReleaseMouse()
 
 693     sm_capturedWindow = NULL;
 
 696 void wxWindow::DoScreenToClient(int *x, int *y) const
 
 701 void wxWindow::DoClientToScreen(int *x, int *y) const
 
 706 // Get size *available for subwindows* i.e. excluding menu bar etc.
 
 707 void wxWindow::DoGetClientSize(int *x, int *y) const
 
 709     wxLogTrace(wxTRACE_COCOA,wxT("DoGetClientSize:"));
 
 711         m_cocoaScroller->DoGetClientSize(x,y);
 
 713         wxWindowCocoa::DoGetSize(x,y);
 
 716 void wxWindow::DoSetClientSize(int width, int height)
 
 718     wxLogTrace(wxTRACE_COCOA_Window_Size,wxT("DoSetClientSize=(%d,%d)"),width,height);
 
 720         m_cocoaScroller->ClientSizeToSize(width,height);
 
 721     CocoaSetWxWindowSize(width,height);
 
 724 void wxWindow::CocoaSetWxWindowSize(int width, int height)
 
 726     wxWindowCocoa::DoSetSize(-1,-1,width,height,wxSIZE_USE_EXISTING);
 
 729 int wxWindow::GetCharHeight() const
 
 735 int wxWindow::GetCharWidth() const
 
 741 void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
 
 742         int *descent, int *externalLeading, const wxFont *theFont) const
 
 747 // Coordinates relative to the window
 
 748 void wxWindow::WarpPointer (int x_pos, int y_pos)
 
 753 int wxWindow::GetScrollPos(int orient) const
 
 759 // This now returns the whole range, not just the number
 
 760 // of positions that we can scroll.
 
 761 int wxWindow::GetScrollRange(int orient) const
 
 767 int wxWindow::GetScrollThumb(int orient) const
 
 773 void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
 
 778 void wxWindow::CocoaCreateNSScrollView()
 
 782         m_cocoaScroller = new wxWindowCocoaScroller(this);
 
 786 // New function that will replace some of the above.
 
 787 void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
 
 788     int range, bool refresh)
 
 790     CocoaCreateNSScrollView();
 
 794 // Does a physical scroll
 
 795 void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
 
 800 void wxWindow::DoSetVirtualSize( int x, int y )
 
 802     wxWindowBase::DoSetVirtualSize(x,y);
 
 803     CocoaCreateNSScrollView();
 
 804     [m_cocoaNSView setFrameSize:NSMakeSize(m_virtualSize.x,m_virtualSize.y)];
 
 807 bool wxWindow::SetFont(const wxFont& font)
 
 813 static int CocoaRaiseWindowCompareFunction(id first, id second, void *target)
 
 815     // first should be ordered higher
 
 817         return NSOrderedDescending;
 
 818     // second should be ordered higher
 
 820         return NSOrderedAscending;
 
 821     return NSOrderedSame;
 
 824 // Raise the window to the top of the Z order
 
 825 void wxWindow::Raise()
 
 827 //    wxAutoNSAutoreleasePool pool;
 
 828     NSView *nsview = GetNSViewForSuperview();
 
 829     [[nsview superview] sortSubviewsUsingFunction:
 
 830             CocoaRaiseWindowCompareFunction
 
 834 static int CocoaLowerWindowCompareFunction(id first, id second, void *target)
 
 836     // first should be ordered lower
 
 838         return NSOrderedAscending;
 
 839     // second should be ordered lower
 
 841         return NSOrderedDescending;
 
 842     return NSOrderedSame;
 
 845 // Lower the window to the bottom of the Z order
 
 846 void wxWindow::Lower()
 
 848     NSView *nsview = GetNSViewForSuperview();
 
 849     [[nsview superview] sortSubviewsUsingFunction:
 
 850             CocoaLowerWindowCompareFunction
 
 854 bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
 
 859 // Get the window with the focus
 
 860 wxWindow *wxWindowBase::FindFocus()
 
 866 /* static */ wxWindow *wxWindowBase::GetCapture()
 
 869     return wxWindowCocoa::sm_capturedWindow;
 
 872 wxWindow *wxGetActiveWindow()
 
 878 wxPoint wxGetMousePosition()
 
 881     return wxDefaultPosition;
 
 884 wxWindow* wxFindWindowAtPointer(wxPoint& pt)
 
 886     pt = wxGetMousePosition();