Home | History | Annotate | Download | only in Carbon
      1 /*
      2  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 // I don't think this class belongs in WebKit. Lets move it out.
     30 
     31 // Things that I've never bothered working out:
     32 // For non-sheet windows, handle Carbon WindowMove events so as to do the same things as -[NSWindow _windowMoved].
     33 // Check to see how this stuff deals with various screen size change scenarious.
     34 // M.P. Warning - 9/17/01
     35 
     36 // There are some invariants I'm maintaining for objects of this class which have been successfully initialized but not deallocated.  These all make it easier to not override every single method of NSWindow.
     37 // _auxiliaryStorage->auxWFlags.hasShadow will always be false if the Carbon window has a kWindowNoShadowAttribute, and vice versa.
     38 // _auxiliaryStorage->_auxWFlags.minimized will always reflect the window's Carbon collapsed state.
     39 // _borderView will always point to an NSCarbonWindowFrame.
     40 // _contentView will always point to an NSCarbonWindowContentView;
     41 // _frame will always reflect the window's Carbon kWindowStructureRgn bounds.
     42 // _styleMask will always have _NSCarbonWindowMask set, and will have NSClosableWindowMask, NSMiniaturizableWindowMask, NSResizableWindowMask, and/or NSTitledWindowMask set as appropriate.
     43 // _wflags.oneShot and _wflags.delayedOneShot will always be false.
     44 // _wFlags.visible will always reflect the window's Carbon visibility.
     45 // _windowNum will always be greater than zero, and valid.
     46 // The instance variables involved are ones that came to my attention during the initial writing of this class; I haven't methodically gone through NSWindow's ivar list or anything like that.  M.P. Notice - 10/10/00
     47 
     48 // Things that have to be worked on if NSCarbonWindows are ever used for something other than dialogs and sheets:
     49 // Clicking on an NSCarbonWindow while a Cocoa app-modal dialog is shown does not beep, as it should [old bug, maybe fixed now].
     50 // Handling of mouse clicks or key presses for any window control (close, miniaturize, zoom) might not be all there.
     51 // Handling of miniaturization of Carbon windows via title bar double-click might not be all there.
     52 // The background on NSCarbonWindowTester's sample window (not sample dialog or sample sheet) might be wrong.
     53 // The controls on NSCarbonWindowTester's sample window look inactive when the window is inactive, but have first-click behavior.
     54 // M.P. Warning - 12/14/00
     55 
     56 // Some things would have to be made public if someone wanted to subclass this so as to support more menu item commands.  M.P. Warning - 9/19/00
     57 
     58 #ifndef __LP64__
     59 
     60 #import "CarbonWindowAdapter.h"
     61 
     62 #import "CarbonWindowFrame.h"
     63 #import "CarbonWindowContentView.h"
     64 #import "HIViewAdapter.h"
     65 
     66 #import <WebKitSystemInterface.h>
     67 
     68 #import <AppKit/AppKit.h>
     69 //#import <CoreGraphics/CGSWindow.h>
     70 #import <HIToolbox/CarbonEvents.h>
     71 #import <HIToolbox/Controls.h>
     72 #import <HIToolbox/HIView.h>
     73 #import <assert.h>
     74 
     75 #import <WebCore/WebCoreObjCExtras.h>
     76 #import <runtime/InitializeThreading.h>
     77 
     78 #import "WebKitLogging.h"
     79 #import "WebNSObjectExtras.h"
     80 #import "WebTypesInternal.h"
     81 
     82 @interface NSWindow(HIWebFrameView)
     83 - _initContent:(const NSRect *)contentRect styleMask:(unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag contentView:aView;
     84 - (void)_oldPlaceWindow:(NSRect)frameRect;
     85 - (void)_windowMovedToRect:(NSRect)actualFrame;
     86 - (void)_setWindowNumber:(NSInteger)nativeWindow;
     87 - (NSGraphicsContext *)_threadContext;
     88 - (void)_setFrame:(NSRect)newWindowFrameRect;
     89 - (void)_setVisible:(BOOL)flag;
     90 @end
     91 
     92 @interface NSApplication(HIWebFrameView)
     93 - (void)setIsActive:(BOOL)aFlag;
     94 - (id)_setMouseActivationInProgress:(BOOL)flag;
     95 - (BOOL)_handleKeyEquivalent:(NSEvent*)theEvent;
     96 @end
     97 
     98 @interface NSInputContext
     99 - (BOOL)processInputKeyBindings:(NSEvent *)event;
    100 @end
    101 
    102 // Forward declarations.
    103 static OSStatus NSCarbonWindowHandleEvent(EventHandlerCallRef inEventHandlerCallRef, EventRef inEventRef, void *inUserData);
    104 
    105 @implementation CarbonWindowAdapter
    106 
    107 
    108 // Return an appropriate window frame class.
    109 + (Class)frameViewClassForStyleMask:(unsigned int)style {
    110 
    111     // There's only one appropriate window style, and only one appropriate window frame class.
    112     assert(style & WKCarbonWindowMask());
    113     return [CarbonWindowFrame class];
    114 
    115 }
    116 
    117 
    118 // Overriding of the parent class' designated initializer, just for safety's sake.
    119 - (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)style backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
    120 
    121     // Do the standard Cocoa thing.
    122     self = [super initWithContentRect:contentRect styleMask:style backing:bufferingType defer:flag];
    123     if (self==nil) return nil;
    124 
    125     // Simple.
    126     _windowRef = NULL;
    127     _windowRefIsOwned = NO;
    128     _eventHandler = NULL;
    129 
    130     // Done.
    131     return self;
    132 
    133 }
    134 
    135 // Given a reference to a Carbon window that is to be encapsulated, an indicator of whether or not this object should take responsibility for disposing of the Carbon window, and an indicator of whether to disable Carbon window ordering, initialize.  This is the class' designated initializer.
    136 - (id)initWithCarbonWindowRef:(WindowRef)inWindowRef takingOwnership:(BOOL)inWindowRefIsOwned disableOrdering:(BOOL)inDisableOrdering carbon:(BOOL)inCarbon {
    137 
    138     NSBackingStoreType backingStoreType;
    139     CarbonWindowContentView *carbonWindowContentView;
    140     NSWindow *windowAsProperty;
    141     OSStatus osStatus;
    142     UInt32 windowFeatures;
    143     WindowAttributes windowAttributes;
    144     unsigned int styleMask;
    145     void *nativeWindow;
    146     WindowModality windowModality;
    147 	ControlRef		contentView;
    148 
    149     // Simple.
    150     // It's very weak to have to put this before the invocation of [super initWithContentRect:...], but -setContentView: is invoked from within that initializer.  It turns out that the common admonition about not calling virtual functions from within C++ constructors makes sense in Objective-C too.  M.P. Notice - 10/10/00
    151     _windowRef = inWindowRef;
    152     //_auxiliaryStorage->_windowRef = inWindowRef;
    153     _windowRefIsOwned = inWindowRefIsOwned;
    154 	_carbon = inCarbon;
    155 
    156     // Find out the window's CoreGraphics window reference.
    157     nativeWindow = WKGetNativeWindowFromWindowRef(inWindowRef);
    158 
    159     // Find out the window's Carbon window attributes.
    160     GetWindowAttributes(inWindowRef, &windowAttributes);
    161 
    162     // Find out the window's Carbon window features.
    163     GetWindowFeatures(inWindowRef, &windowFeatures);
    164 
    165     // Figure out the window's backing store type.
    166     // At one time, this had code stolen from CreatePlatformWindow in HIToolbox/Windows/Platform/CGSPlatform.c
    167 	// But now the non-retained window class is a Carbon secret that's not even in
    168 	// WindowsPriv.h; maybe we'll have to revisit this if someone needs to use WebKit
    169 	// in a non-retained window.
    170     backingStoreType = NSBackingStoreRetained;
    171 
    172     // Figure out the window's style mask.
    173     styleMask = WKCarbonWindowMask();
    174     if (windowAttributes & kWindowCloseBoxAttribute) styleMask |= NSClosableWindowMask;
    175     if (windowAttributes & kWindowResizableAttribute) styleMask |= NSResizableWindowMask;
    176     if (windowFeatures & kWindowCanCollapse) styleMask |= NSMiniaturizableWindowMask;
    177     if (windowFeatures & kWindowHasTitleBar) styleMask |= NSTitledWindowMask;
    178 
    179     osStatus = GetWindowModality(_windowRef, &windowModality, NULL);
    180     if (osStatus != noErr) {
    181         NSLog(@"Couldn't get window modality: error=%d", osStatus);
    182         return nil;
    183     }
    184 
    185     // Create one of our special content views.
    186     carbonWindowContentView = [[[CarbonWindowContentView alloc] init] autorelease];
    187 
    188     // Do some standard Cocoa initialization.  The defer argument's value is YES because we don't want -[NSWindow _commonAwake] to get called.  It doesn't appear that any relevant NSWindow code checks _wFlags.deferred, so we should be able to get away with the lie.
    189     self = (CarbonWindowAdapter*)[super _initContent:NULL styleMask:styleMask backing:backingStoreType defer:YES contentView:carbonWindowContentView];
    190     if (!self) return nil;
    191     assert(_contentView);
    192 
    193     // Record accurately whether or not this window has a shadow, in case someone asks.
    194  //   _auxiliaryStorage->_auxWFlags.hasShadow = (windowAttributes & kWindowNoShadowAttribute) ? NO : YES;
    195 
    196     // Record the window number.
    197     [self _setWindowNumber:(NSInteger)nativeWindow];
    198 
    199     // Set up from the frame rectangle.
    200     // We didn't even really try to get it right at _initContent:... time, because it's more trouble that it's worth to write a real +[NSCarbonWindow frameRectForContentRect:styleMask:].  M.P. Notice - 10/10/00
    201     [self reconcileToCarbonWindowBounds];
    202 
    203     // Install an event handler for the Carbon window events in which we're interested.
    204     const EventTypeSpec kEvents[] = {
    205             { kEventClassWindow, kEventWindowActivated },
    206             { kEventClassWindow, kEventWindowDeactivated },
    207             { kEventClassWindow, kEventWindowBoundsChanged },
    208             { kEventClassWindow, kEventWindowShown },
    209             { kEventClassWindow, kEventWindowHidden }
    210     };
    211 
    212     const EventTypeSpec kControlBoundsChangedEvent = { kEventClassControl, kEventControlBoundsChanged };
    213 
    214     osStatus = InstallEventHandler( GetWindowEventTarget(_windowRef), NSCarbonWindowHandleEvent, GetEventTypeCount( kEvents ), kEvents, (void*)self, &_eventHandler);
    215     if (osStatus!=noErr) {
    216             [self release];
    217             return nil;
    218     }
    219 
    220     osStatus = InstallEventHandler( GetControlEventTarget( HIViewGetRoot( _windowRef ) ), NSCarbonWindowHandleEvent, 1, &kControlBoundsChangedEvent, (void*)self, &_eventHandler);
    221     if (osStatus!=noErr) {
    222             [self release];
    223             return nil;
    224     }
    225 
    226     HIViewFindByID( HIViewGetRoot( _windowRef ), kHIViewWindowContentID, &contentView );
    227     osStatus = InstallEventHandler( GetControlEventTarget( contentView ), NSCarbonWindowHandleEvent, 1, &kControlBoundsChangedEvent, (void*)self, &_eventHandler);
    228     if (osStatus!=noErr) {
    229             [self release];
    230             return nil;
    231     }
    232 
    233     // Put a pointer to this Cocoa NSWindow in a Carbon window property tag.
    234     // Right now, this is just used by NSViewCarbonControl.  M.P. Notice - 10/9/00
    235     windowAsProperty = self;
    236     osStatus = SetWindowProperty(_windowRef, WKCarbonWindowPropertyCreator(), WKCarbonWindowPropertyTag(), sizeof(NSWindow *), &windowAsProperty);
    237     if (osStatus!=noErr) {
    238         [self release];
    239         return nil;
    240     }
    241 
    242     // Ignore the Carbon window activation/deactivation events that Carbon sends to its windows at app activation/deactivation.  We'll send such events when we think it's appropriate.
    243     _passingCarbonWindowActivationEvents = NO;
    244 
    245     // Be sure to sync up visibility
    246     [self _setVisible:(BOOL)IsWindowVisible( _windowRef )];
    247 
    248     // Done.
    249     return self;
    250 
    251 }
    252 
    253 - (void)setViewsNeedDisplay:(BOOL)wellDoThey {
    254 	// Make sure we can flush anything that needs it.
    255 
    256 	// We need to sync the context here. I was hoping I didn't need to do this,
    257 	// but apparently when scrolling, the AppKit view system draws directly.
    258 	// When this occurs, I cannot intercept it to make it draw in my HIView
    259 	// context. What ends up happening is that it draws, but nothing ever
    260 	// flushes it.
    261 
    262 	if ( [self windowNumber] != -1 )
    263 	{
    264 		CGContextRef cgContext = (CGContextRef)[[self _threadContext] graphicsPort];
    265 		CGContextSynchronize( cgContext );
    266 	}
    267 }
    268 
    269 + (void)initialize
    270 {
    271     JSC::initializeThreading();
    272 #ifndef BUILDING_ON_TIGER
    273     WebCoreObjCFinalizeOnMainThread(self);
    274 #endif
    275 }
    276 
    277 // Given a reference to a Carbon window that is to be encapsulated, and an indicator of whether or not this object should take responsibility for disposing of the Carbon window, initialize.
    278 - (id)initWithCarbonWindowRef:(WindowRef)inWindowRef takingOwnership:(BOOL)inWindowRefIsOwned {
    279     // for now, set disableOrdering to YES because that is what we've been doing and is therefore lower risk. However, I think it would be correct to set it to NO.
    280     return [self initWithCarbonWindowRef:inWindowRef takingOwnership:inWindowRefIsOwned disableOrdering:YES carbon:NO];
    281 }
    282 
    283 
    284 // Clean up.
    285 - (void)dealloc {
    286     if (WebCoreObjCScheduleDeallocateOnMainThread([CarbonWindowAdapter class], self))
    287         return;
    288 
    289     // Clean up, if necessary.
    290     // if we didn't remove the event handler at dealloc time, we would risk getting sent events after the window has been deallocated.  See 2702179.  M.P. Notice - 6/1/01
    291     if (_eventHandler) RemoveEventHandler(_eventHandler);
    292 
    293     // Do the standard Cocoa thing.
    294     [super dealloc];
    295 }
    296 
    297 - (void)finalize {
    298     ASSERT_MAIN_THREAD();
    299     if (_eventHandler) RemoveEventHandler(_eventHandler);
    300     [super finalize];
    301 }
    302 
    303 - (WindowRef)windowRef {
    304 
    305     // Simple.
    306     return _windowRef;
    307 
    308 }
    309 
    310 // should always be YES, but check in order to avoid initialization or deallocation surprises
    311 - (BOOL)_hasWindowRef {
    312     return (_windowRef != NULL);
    313 }
    314 
    315 // an NSCarbonWindow does not manage the windowRef.  The windowRef manages the NSCarbonWindow
    316 - (BOOL)_managesWindowRef {
    317     return NO;
    318 }
    319 
    320 - (void)_removeWindowRef {
    321     _windowRef = NULL;
    322 
    323     if (_eventHandler) RemoveEventHandler(_eventHandler);
    324 
    325 	_eventHandler = NULL;
    326 }
    327 
    328 - (WindowClass)_carbonWindowClass {
    329     WindowClass windowClass = kDocumentWindowClass;
    330     OSStatus osStatus;
    331 
    332     if ([self _hasWindowRef]) {
    333         osStatus = GetWindowClass([self windowRef], &windowClass);
    334         if (osStatus != noErr) {
    335             NSLog(@"Couldn't get window class: error=%d", osStatus);
    336         }
    337     }
    338     return windowClass;
    339 }
    340 
    341 // Update this window's frame and content frame rectangles to match the Carbon window's structure bounds and content bounds rectangles.  Return yes if the update was really necessary, no otherwise.
    342 - (BOOL)reconcileToCarbonWindowBounds {
    343 
    344     OSStatus osStatus;
    345     NSRect newContentFrameRect;
    346     NSRect newWindowFrameRect;
    347     NSRect oldContentFrameRect;
    348     Rect windowContentBoundsRect;
    349     Rect windowStructureBoundsRect;
    350 
    351     // Initialize for safe returning.
    352     BOOL reconciliationWasNecessary = NO;
    353 
    354     // Precondition check.
    355     assert(_contentView);
    356 
    357     // Get the Carbon window's bounds, which are expressed in global screen coordinates, with (0,0) at the top-left of the main screen.
    358     osStatus = GetWindowBounds(_windowRef, kWindowStructureRgn, &windowStructureBoundsRect);
    359     if (osStatus!=noErr) NSLog(@"A Carbon window's structure bounds couldn't be gotten.");
    360     osStatus = GetWindowBounds(_windowRef, kWindowContentRgn, &windowContentBoundsRect);
    361     if (osStatus!=noErr) NSLog(@"A Carbon window's content bounds couldn't be gotten.");
    362 
    363     // Set the frame rectangle of the border view and this window from the Carbon window's structure region bounds.
    364     newWindowFrameRect.origin.x = windowStructureBoundsRect.left;
    365     newWindowFrameRect.origin.y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - windowStructureBoundsRect.bottom;
    366     newWindowFrameRect.size.width = windowStructureBoundsRect.right - windowStructureBoundsRect.left;
    367     newWindowFrameRect.size.height = windowStructureBoundsRect.bottom - windowStructureBoundsRect.top;
    368     if (!NSEqualRects(newWindowFrameRect, _frame)) {
    369         [self _setFrame:newWindowFrameRect];
    370         [_borderView setFrameSize:newWindowFrameRect.size];
    371         reconciliationWasNecessary = YES;
    372     }
    373 
    374     // Set the content view's frame rect from the Carbon window's content region bounds.
    375     newContentFrameRect.origin.x = windowContentBoundsRect.left - windowStructureBoundsRect.left;
    376     newContentFrameRect.origin.y = windowStructureBoundsRect.bottom - windowContentBoundsRect.bottom;
    377     newContentFrameRect.size.width = windowContentBoundsRect.right - windowContentBoundsRect.left;
    378     newContentFrameRect.size.height = windowContentBoundsRect.bottom - windowContentBoundsRect.top;
    379     oldContentFrameRect = [_contentView frame];
    380     if (!NSEqualRects(newContentFrameRect, oldContentFrameRect)) {
    381         [_contentView setFrame:newContentFrameRect];
    382         reconciliationWasNecessary = YES;
    383     }
    384 
    385     // Done.
    386     return reconciliationWasNecessary;
    387 
    388 }
    389 
    390 
    391 // Handle an event just like an NSWindow would.
    392 - (void)sendSuperEvent:(NSEvent *)inEvent {
    393 
    394     // Filter out a few events that just result in complaints in the log.
    395     // Ignore some unknown event that gets sent when NSTextViews in printing accessory views are focused.  M.P. Notice - 12/7/00
    396     BOOL ignoreEvent = NO;
    397     NSEventType eventType = [inEvent type];
    398     if (eventType==NSSystemDefined) {
    399         short eventSubtype = [inEvent subtype];
    400         if (eventSubtype==7) {
    401             ignoreEvent = YES;
    402         }
    403     } else if (eventType == NSKeyDown) {
    404         // Handle command-space as [NSApp sendEvent:] does.
    405         if ([NSInputContext processInputKeyBindings:inEvent]) {
    406             return;
    407         }
    408     }
    409 
    410     // Simple.
    411     if (!ignoreEvent) [super sendEvent:inEvent];
    412 }
    413 
    414 - (void)relinquishFocus
    415 {
    416     NSResponder*  firstResponder;
    417 
    418     // Carbon thinks that a control has the keyboard focus,
    419     // or we wouldn't be being asked to relinquish focus.
    420 
    421 	firstResponder = [self firstResponder];
    422 	if ([firstResponder isKindOfClass:[NSView class]] ){
    423 		// Make the window the first responder, so that no view is the key view.
    424         [self makeFirstResponder:self];
    425     }
    426 }
    427 
    428 - (BOOL)makeFirstResponder:(NSResponder *)aResponder
    429 {
    430     // Let NSWindow focus the appropriate NSView.
    431     if (![super makeFirstResponder:aResponder])
    432         return NO;
    433 
    434     // Now, if the view we're focusing is in a HIWebView, find the
    435     // corresponding HIWebView for the NSView, and tell carbon to
    436     // clear any focused control.
    437     HIViewRef viewRef = 0;
    438     NSResponder *firstResponder = [self firstResponder];
    439     if ([firstResponder isKindOfClass:[NSView class]]) {
    440         NSView *view = (NSView *)firstResponder;
    441         while (view) {
    442             viewRef = [HIViewAdapter getHIViewForNSView:view];
    443             if (viewRef)
    444                 break;
    445             view = [view superview];
    446         }
    447     }
    448 
    449     HIViewRef focus;
    450     GetKeyboardFocus (_windowRef, &focus);
    451     if (focus != viewRef) {
    452         SetKeyboardFocus (_windowRef, viewRef, kControlIndicatorPart );
    453     }
    454 
    455     return YES;
    456 }
    457 
    458 // There's no override of _addCursorRect:cursor:forView:, despite the fact that NSWindow's invokes [self windowNumber], because Carbon windows won't have subviews, and therefore won't have cursor rects.
    459 
    460 
    461 // There's no override of _autoResizeState, despite the fact that NSWindow's operates on _windowNum, because it looks like it might work on Carbon windows as is.
    462 
    463 
    464 // Disappointingly, -_blockHeartBeat: is not immediately invoked to turn off heartbeating.  Heartbeating is turned off by setting the gDefaultButtonPaused global variable, and then this method is invoked later, if that global is set (at heartbeating time I guess).  Something has to change if we want to hook this up in Carbon windows.  M.P. Warning - 9/17/01
    465 /*
    466 // Do the right thing for a Carbon window.
    467 - (void)_blockHeartBeat:(BOOL)flag {
    468 
    469     ControlRef defaultButton;
    470     OSStatus osStatus;
    471 
    472     // Do the standard Cocoa thing.
    473     [super _blockHeartBeat:flag];
    474 
    475     // If there's a default Carbon button in this Carbon window, make it stop pulsing, the Carbon way.
    476     // This is inspired by HIToolbox/Controls/Definitions/ButtonCDEF.c's ButtonEventHandler().  M.P. Notice - 12/5/00
    477     osStatus = GetWindowDefaultButton(_windowRef, &defaultButton);
    478     if (osStatus==noErr && defaultButton) {
    479         Boolean anotherButtonIsTracking = flag ? TRUE : FALSE;
    480         osStatus = SetControlData(defaultButton, kControlNoPart, kControlPushButtonAnotherButtonTrackingTag, sizeof(Boolean), &anotherButtonIsTracking);
    481         if (osStatus==noErr) DrawOneControl(defaultButton);
    482         else NSLog(@"Some data couldn't be set in a Carbon control.");
    483     }
    484 
    485 }
    486 */
    487 
    488 
    489 // Do the right thing for a Carbon window.
    490 - (void)_cancelKey:(id)sender {
    491 
    492     // Most of the time the handling of the cancel key will be done by Carbon, but this method will be invoked if an NSCarbonWindow is wrapping a Carbon window that contains an NSViewCarbonControl, and the escape key or whatever is pressed with an NSTextView focused.  Just do what Carbon would do.
    493     ControlRef cancelButton;
    494     GetWindowCancelButton(_windowRef, &cancelButton);
    495     if (cancelButton) {
    496         if (IsControlActive(cancelButton)) {
    497             HIViewSimulateClick(cancelButton, kControlButtonPart, 0, NULL);
    498         }
    499     }
    500 
    501 }
    502 
    503 
    504 
    505 // Do the right thing for a Carbon window.
    506 - (void)_commonAwake {
    507 
    508     // Complain, because this should never be called.  We insist that -[NSCarbonWindow initWithCarbonWindowRef] is the only valid initializer for instances of this class, and that there's no such thing as a one-shot NSCarbonWindow.
    509     NSLog(@"-[NSCarbonWindow _commonAwake] is not implemented.");
    510 
    511 }
    512 
    513 
    514 // There's no override of _commonInitFrame:styleMask:backing:defer:, despite the fact that NSWindow's modifies quite a few instance variables, because it gets called in a harmless way if the class instance is properly initialized with -[NSCarbonWindow initWithCarbonWindowRef:takingOwnership:].
    515 
    516 
    517 // Do the right thing for a Carbon window.
    518 - _destroyRealWindow:(BOOL)orderingOut {
    519 
    520     // Complain, because this should never be called.  We don't support one-shot NSCarbonWindows.
    521     NSLog(@"-[NSCarbonWindow _destroyRealWindow:] is not implemented.");
    522     return self;
    523 
    524 }
    525 
    526 
    527 // There's no override of _discardCursorRectsForView, despite the fact that NSWindow's invokes [self windowNumber], because Carbon windows won't have subviews, and therefore won't have cursor rects.
    528 
    529 
    530 // There's no override of _forceFlushWindowToScreen, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    531 
    532 
    533 // There's no override of _getPositionFromServer, despite the fact that NSWindow's operates on _windowNum, because it's only called from -[NSApplication _activateWindows], which is hopefully about to become obsolete any second now.
    534 
    535 
    536 // There's no override of _globalWindowNum, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    537 
    538 
    539 // There's no override of _initContent:styleMask:backing:defer:contentView:, despite the fact that NSWindow's modifies _auxiliaryStorage->_auxWFlags.hasShadow, because it will never get called if the class instance is properly initialized with -[NSCarbonWindow initWithCarbonWindowRef:takingOwnership:].
    540 
    541 
    542 // There's no override of _initContent:styleMask:backing:defer:counterpart:, despite the fact that NSWindow's modifies _auxiliaryStorage->_auxWFlags.hasShadow, because it will never get called if the class instance is properly initialized with -[NSCarbonWindow initWithCarbonWindowRef:takingOwnership:].
    543 
    544 
    545 // Do what NSWindow would do, but then sychronize the Carbon window structures.
    546 - (void)_oldPlaceWindow:(NSRect)frameRect {
    547 
    548     OSStatus osStatus;
    549 
    550     // Do the standard Cocoa thing.
    551     [super _oldPlaceWindow:frameRect];
    552 
    553     // Tell Carbon to update its various regions.
    554     // Despite its name, this function should be called early and often, even if the window isn't visible yet.  2702648.  M.P. Notice - 7/24/01
    555     osStatus = WKSyncWindowWithCGAfterMove(_windowRef);
    556     if (osStatus!=noErr) NSLog(@"A Carbon window's bounds couldn't be synchronized (%i).", (int)osStatus);
    557 
    558 }
    559 
    560 
    561 // There's no override of _orderOutAndCalcKeyWithCounter:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    562 
    563 
    564 // There's no override of _realHeartBeatThreadContext, despite the fact that NSWindows's invokes [self windowNumber], because it looks like it might not do anything that will effect a Carbon window.
    565 
    566 
    567 // There's no override of _registerWithDockIfNeeded, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    568 
    569 
    570 // There's no override of _removeCursorRect:cursor:forView:, despite the fact that NSWindow's invokes [self windowNumber], because Carbon windows won't have subviews, and therefore won't have cursor rects.
    571 
    572 
    573 // There's no override of _setAvoidsActivation:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    574 
    575 
    576 // There's no override of _setFrame:, despite the fact that NSWindow's modifies _frame, because it looks like it might work on Carbon windows as is.  The synchronization of the Carbon window bounds rect to the Cocoa frame rect is done in the overrides of _oldPlaceWindow: and _windowMovedToRect:.
    577 
    578 
    579 // There's no override of _setFrameCommon:display:stashSize:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    580 
    581 
    582 // There's no override of _setWindowNumber:, despite the fact that NSWindow's modifies _windowNum and invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    583 
    584 
    585 // Do what NSWindow would do, but for a Carbon window.
    586 // This function is mostly cut-and-pasted from -[NSWindow _termWindowIfOwner].  M.P. Notice - 8/7/00
    587 - (void)_termWindowIfOwner {
    588     [self _setWindowNumber:-1];
    589     _wFlags.isTerminating = YES;
    590     if (_windowRef && _windowRefIsOwned) DisposeWindow(_windowRef);
    591     // KW - need to clear window shadow state so it gets reset correctly when new window created
    592 //    if ([_borderView respondsToSelector:@selector(setShadowState:)]) {
    593 //        [_borderView setShadowState:kFrameShadowNone];
    594 //    }
    595     _wFlags.isTerminating = NO;
    596 }
    597 
    598 
    599 // There's no override of _threadContext, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might not do anything that will effect a Carbon window.
    600 
    601 
    602 // There's no override of _windowMoved:, despite the fact that NSWindow's operates on _windowNum, because it looks like it might work on Carbon windows as is.
    603 
    604 
    605 // Do what NSWindow would do, but then sychronize the Carbon window structures.
    606 - (void)_windowMovedToRect:(NSRect)actualFrame {
    607 
    608     OSStatus osStatus;
    609 
    610     // Do the standard Cocoa thing.
    611     [super _windowMovedToRect:actualFrame];
    612 
    613     // Let Carbon know that the window has been moved, unless this method is being called "early."
    614     if (_wFlags.visible) {
    615         osStatus = WKSyncWindowWithCGAfterMove(_windowRef);
    616         if (osStatus!=noErr) NSLog(@"A Carbon window's bounds couldn't be synchronized (%i).", (int)osStatus);
    617     }
    618 
    619 }
    620 
    621 - (NSRect)constrainFrameRect:(NSRect)actualFrame toScreen:(NSScreen *)screen {
    622     // let Carbon decide window size and position
    623     return actualFrame;
    624 }
    625 
    626 - (void)selectKeyViewFollowingView:(NSView *)aView {
    627 	HIViewRef	view = NULL;
    628 
    629 	view = [HIViewAdapter getHIViewForNSView:aView];
    630 
    631 	if ( view )
    632 	{
    633 		HIViewRef	contentView;
    634 
    635 		GetRootControl( GetControlOwner( view ), &contentView );
    636 		HIViewAdvanceFocus( contentView, 0 );
    637 	}
    638 	else
    639 	{
    640 		[super selectKeyViewFollowingView:aView];
    641 	}
    642 }
    643 
    644 - (void)selectKeyViewPrecedingView:(NSView *)aView {
    645 	HIViewRef	view = NULL;
    646 
    647 	view = [HIViewAdapter getHIViewForNSView:aView];
    648 
    649 	if ( view )
    650 	{
    651 		HIViewRef	contentView;
    652 
    653 		GetRootControl( GetControlOwner( view ), &contentView );
    654 		HIViewAdvanceFocus( contentView, shiftKey );
    655 	}
    656 	else
    657 	{
    658 		[super selectKeyViewPrecedingView:aView];
    659 	}
    660 }
    661 
    662 - (void)makeKeyWindow {
    663 	[NSApp _setMouseActivationInProgress:NO];
    664 	[NSApp setIsActive:YES];
    665 	[super makeKeyWindow];
    666 	WKShowKeyAndMain();
    667 }
    668 
    669 
    670 // Do the right thing for a Carbon window.
    671 - (BOOL)canBecomeKeyWindow {
    672 
    673     return YES;
    674 }
    675 
    676 // Do the right thing for a Carbon window.
    677 - (BOOL)canBecomeMainWindow {
    678     OSStatus osStatus;
    679     WindowClass windowClass;
    680     // By default, Carbon windows cannot become the main window.
    681     // What about when the default isn't right?  Requiring subclassing seems harsh.  M.P. Warning - 9/17/01
    682     // KW -  modify this to allow document windows to become main
    683     // This is primarily to get the right look, so that you don't have two windows that both look active - one Cocoa document and one Carbon document
    684     osStatus = GetWindowClass(_windowRef, &windowClass);
    685     return (osStatus == noErr && windowClass == kDocumentWindowClass);
    686 
    687 }
    688 
    689 
    690 // There's no override of deminiaturize:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    691 
    692 
    693 // There's no override of disableCursorRects, despite the fact that NSWindow's invokes [self windowNumber], because Carbon windows won't have subviews, and therefore won't have cursor rects.
    694 
    695 
    696 
    697 // There's no override of enableCursorRects, despite the fact that NSWindow's invokes [self windowNumber], because Carbon windows won't have subviews, and therefore won't have cursor rects.
    698 
    699 
    700 // Do the right thing for a Carbon window.
    701 - (void)encodeWithCoder:(NSCoder *)coder {
    702 
    703     // Actually, this will probably never be implemented.  M.P. Notice - 8/2/00
    704     NSLog(@"-[NSCarbonWindow encodeWithCoder:] is not implemented.");
    705 
    706 }
    707 
    708 
    709 // There's no override of frame, despite the fact that NSWindow's returns _frame, because _frame is one of the instance variables whose value we're keeping synchronized with the Carbon window.
    710 
    711 
    712 // Do the right thing for a Carbon window.
    713 - (id)initWithCoder:(NSCoder *)coder {
    714 
    715     // Actually, this will probably never be implemented.  M.P. Notice - 8/2/00
    716     NSLog(@"-[NSCarbonWindow initWithCoder:] is not implemented.");
    717     [self release];
    718     return nil;
    719 
    720 }
    721 
    722 
    723 // There's no override of level, despite the fact that NSWindow's returns _level, because _level is one of the instance variables whose value we're keeping synchronized with the Carbon window.
    724 
    725 
    726 // There's no override of miniaturize:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    727 
    728 
    729 // There's no override of resizeToScreenWithEvent:, despite the fact that NSWindow's operates on _windowNum.
    730 // It looks like it's only called when an _NSForceResizeEventType event is passed into -[NSWindow sendEvent:], and I can't find any instances of that happening.
    731 
    732 /*
    733 // Do the right thing for a Carbon Window.
    734 - (void)sendEvent:(NSEvent *)theEvent {
    735 
    736     // Not all events are handled in the same manner.
    737     NSEventType eventType = [theEvent type];
    738     if (eventType==NSAppKitDefined) {
    739 
    740         // Handle the event the Cocoa way.  Carbon won't understand it anyway.
    741         [super sendEvent:theEvent];
    742 
    743     }
    744 }
    745 */
    746 
    747 // There's no override of setAcceptsMouseMovedEvents:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    748 
    749 
    750 // There's no override of setBackingType:, despite the fact that NSWindow's invokes [self windowNumber], because it's apparently not expected to do anything anyway, judging from the current implementation of PSsetwindowtype().
    751 
    752 
    753 // Do what NSWindow would do, but for a Carbon window.
    754 - (void)setContentView:(NSView *)aView {
    755 
    756     NSRect contentFrameRect;
    757     OSStatus osStatus;
    758     Rect windowContentBoundsRect;
    759 
    760     // Precondition check.
    761     assert(_borderView);
    762     assert([_borderView isKindOfClass:[CarbonWindowFrame class]]);
    763     assert(_windowRef);
    764 
    765     // Parameter check.
    766     assert(aView);
    767     assert([aView isKindOfClass:[CarbonWindowContentView class]]);
    768 
    769     // Find out the window's Carbon window structure region (content) bounds.
    770     osStatus = GetWindowBounds(_windowRef, kWindowContentRgn, &windowContentBoundsRect);
    771     if (osStatus!=noErr) NSLog(@"A Carbon window's content bounds couldn't be gotten.");
    772     contentFrameRect.origin = NSZeroPoint;
    773     contentFrameRect.size.width = windowContentBoundsRect.right - windowContentBoundsRect.left;
    774     contentFrameRect.size.height = windowContentBoundsRect.bottom - windowContentBoundsRect.top;
    775 
    776     // If the content view is still in some other view hierarchy, pry it free.
    777     [_contentView removeFromSuperview];
    778     assert(![_contentView superview]);
    779 
    780     // Record the content view, and size it to this window's content frame.
    781     _contentView = aView;
    782     [_contentView setFrame:contentFrameRect];
    783 
    784     // Make the content view a subview of the border view.
    785     [_borderView addSubview:_contentView];
    786 
    787     // Tell the content view it's new place in the responder chain.
    788     [_contentView setNextResponder:self];
    789 
    790 }
    791 
    792 
    793 // There's no override of setDepthLimit:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    794 
    795 
    796 - (BOOL)worksWhenModal {
    797     WindowClass windowClass = [self _carbonWindowClass];
    798     return (windowClass == kFloatingWindowClass || windowClass == kUtilityWindowClass);
    799 }
    800 
    801 - (void)_setModalWindowLevel {
    802     return;
    803 }
    804 
    805 - _clearModalWindowLevel {
    806     return nil;
    807 }
    808 
    809 // There's no override of setLevel:, despite the fact that NSWindow's invokes [self windowNumber], because it looks like it might work on Carbon windows as is.
    810 // I thought at first that there should be a mapping between Cocoa level and Carbon window class, but experiments convince me that such is not the case.  M.P. Notice - 9/18/00
    811 
    812 
    813 // There's no override of windowNumber, despite the fact that NSWindow's returns _windowNum, because _windowNum is one of the instance variables whose value we're keeping synchronized with the Carbon window.
    814 
    815 
    816 - (UInt32)carbonHICommandIDFromActionSelector:(SEL)inActionSelector {
    817 
    818     // Initialize with the default return value.
    819     UInt32 hiCommandID = 0;
    820 
    821     // Pretty simple, if tedious.
    822     if (inActionSelector==@selector(clear:)) hiCommandID = kHICommandClear;
    823     else if (inActionSelector==@selector(copy:)) hiCommandID = kHICommandCopy;
    824     else if (inActionSelector==@selector(cut:)) hiCommandID = kHICommandCut;
    825     else if (inActionSelector==@selector(paste:)) hiCommandID = kHICommandPaste;
    826     else if (inActionSelector==@selector(redo:)) hiCommandID = kHICommandRedo;
    827     else if (inActionSelector==@selector(selectAll:)) hiCommandID = kHICommandSelectAll;
    828     else if (inActionSelector==@selector(undo:)) hiCommandID = kHICommandUndo;
    829 
    830     // Done.
    831     return hiCommandID;
    832 
    833 }
    834 
    835 
    836 - (void)sendCarbonProcessHICommandEvent:(UInt32)inHICommandID {
    837 
    838     EventTargetRef eventTargetRef;
    839     HICommand hiCommand;
    840     OSStatus osStatus;
    841 
    842     // Initialize for safe error handling.
    843     EventRef eventRef = NULL;
    844 
    845     // Create a Process Command event.  Don't mention anything about the menu item, because we don't want the Carbon Event handler fiddling with it.
    846     hiCommand.attributes = 0;
    847     hiCommand.commandID = inHICommandID;
    848     hiCommand.menu.menuRef = 0;
    849     hiCommand.menu.menuItemIndex = 0;
    850     osStatus = CreateEvent(NULL, kEventClassCommand, kEventCommandProcess, GetCurrentEventTime(), kEventAttributeNone, &eventRef);
    851     if (osStatus!=noErr) {
    852         NSLog(@"CreateEvent() returned %i.", (int)osStatus);
    853         goto CleanUp;
    854     }
    855     osStatus = SetEventParameter(eventRef, kEventParamDirectObject, typeHICommand, sizeof(HICommand), &hiCommand);
    856     if (osStatus!=noErr) {
    857         NSLog(@"SetEventParameter() returned %i.", (int)osStatus);
    858         goto CleanUp;
    859     }
    860 
    861     // Send a Carbon event to whatever has the Carbon user focus.
    862     eventTargetRef = GetUserFocusEventTarget();
    863     osStatus = SendEventToEventTarget(eventRef, eventTargetRef);
    864     if (osStatus!=noErr) {
    865         NSLog(@"SendEventToEventTarget() returned %i.", (int)osStatus);
    866         goto CleanUp;
    867     }
    868 
    869 CleanUp:
    870 
    871     // Clean up.
    872     if (eventRef) ReleaseEvent(eventRef);
    873 
    874 }
    875 
    876 
    877 - (Boolean)sendCarbonUpdateHICommandStatusEvent:(UInt32)inHICommandID withMenuRef:(MenuRef)inMenuRef andMenuItemIndex:(UInt16)inMenuItemIndex {
    878 
    879     EventTargetRef eventTargetRef;
    880     HICommand hiCommand;
    881     OSStatus osStatus;
    882 
    883     // Initialize for safe error handling and flag returning.
    884     Boolean eventWasHandled = FALSE;
    885     EventRef eventRef = NULL;
    886 
    887     // Create a Process Command event.  Don't mention anything about the menu item, because we don't want the Carbon Event handler fiddling with it.
    888     hiCommand.attributes = kHICommandFromMenu;
    889     hiCommand.commandID = inHICommandID;
    890     hiCommand.menu.menuRef = inMenuRef;
    891     hiCommand.menu.menuItemIndex = inMenuItemIndex;
    892     osStatus = CreateEvent(NULL, kEventClassCommand, kEventCommandUpdateStatus, GetCurrentEventTime(), kEventAttributeNone, &eventRef);
    893     if (osStatus!=noErr) {
    894         NSLog(@"CreateEvent() returned %i.", (int)osStatus);
    895         goto CleanUp;
    896     }
    897     osStatus = SetEventParameter(eventRef, kEventParamDirectObject, typeHICommand, sizeof(HICommand), &hiCommand);
    898     if (osStatus!=noErr) {
    899         NSLog(@"SetEventParameter() returned %i.", (int)osStatus);
    900         goto CleanUp;
    901     }
    902 
    903     // Send a Carbon event to whatever has the Carbon user focus.
    904     eventTargetRef = GetUserFocusEventTarget();
    905     osStatus = SendEventToEventTarget(eventRef, eventTargetRef);
    906     if (osStatus==noErr) {
    907         eventWasHandled = TRUE;
    908     } else if (osStatus!=eventNotHandledErr) {
    909         NSLog(@"SendEventToEventTarget() returned %i.", (int)osStatus);
    910         goto CleanUp;
    911     }
    912 
    913 CleanUp:
    914 
    915     // Clean up.
    916     if (eventRef) ReleaseEvent(eventRef);
    917 
    918     // Done.
    919     return eventWasHandled;
    920 
    921 }
    922 
    923 - (void)_handleRootBoundsChanged
    924 {
    925 	HIViewRef	root = HIViewGetRoot( _windowRef );
    926 	HIRect		frame;
    927 
    928 	HIViewGetFrame( root, &frame );
    929 	[_borderView setFrameSize:*(NSSize*)&frame.size];
    930 }
    931 
    932 - (void)_handleContentBoundsChanged
    933 {
    934 	HIViewRef	root, contentView;
    935 	HIRect		rootBounds, contentFrame;
    936 	NSRect		oldContentFrameRect;
    937 
    938 	root = HIViewGetRoot( _windowRef );
    939 	HIViewFindByID( root, kHIViewWindowContentID, &contentView );
    940 	HIViewGetFrame( contentView, &contentFrame );
    941 	HIViewGetBounds( root, &rootBounds );
    942 
    943     // Set the content view's frame rect from the Carbon window's content region bounds.
    944     contentFrame.origin.y = rootBounds.size.height - CGRectGetMaxY( contentFrame );
    945 
    946     oldContentFrameRect = [_contentView frame];
    947     if ( !NSEqualRects( *(NSRect*)&contentFrame, oldContentFrameRect ) ) {
    948         [_contentView setFrame:*(NSRect*)&contentFrame];
    949     }
    950 }
    951 
    952 - (OSStatus)_handleCarbonEvent:(EventRef)inEvent callRef:(EventHandlerCallRef)inCallRef {
    953     OSStatus result = eventNotHandledErr;
    954 
    955     switch ( GetEventClass( inEvent ) )
    956     {
    957 		case kEventClassControl:
    958 			{
    959 				ControlRef		control;
    960 
    961 				check( GetEventKind( inEvent ) == kEventControlBoundsChanged );
    962 
    963 				GetEventParameter( inEvent, kEventParamDirectObject, typeControlRef, NULL,
    964 						sizeof( ControlRef ), NULL, &control );
    965 
    966 				if ( control == HIViewGetRoot( _windowRef ) )
    967 					[self _handleRootBoundsChanged];
    968 				else
    969 					[self _handleContentBoundsChanged];
    970 			}
    971 			break;
    972 
    973     	case kEventClassWindow:
    974     		switch ( GetEventKind( inEvent ) )
    975     		{
    976     			case kEventWindowShown:
    977 					[self _setVisible:YES];
    978     				break;
    979 
    980     			case kEventWindowHidden:
    981 					[self _setVisible:NO];
    982     				break;
    983 
    984     			case kEventWindowActivated:
    985 					[self makeKeyWindow];
    986 					break;
    987 
    988     			case kEventWindowDeactivated:
    989 					[self resignKeyWindow];
    990 					break;
    991 
    992 				case kEventWindowBoundsChanged:
    993 					[self reconcileToCarbonWindowBounds];
    994 					break;
    995 			}
    996     		break;
    997    	}
    998 
    999     return result;
   1000 }
   1001 
   1002 // Handle various events that Carbon is sending to our window.
   1003 static OSStatus NSCarbonWindowHandleEvent(EventHandlerCallRef inEventHandlerCallRef, EventRef inEventRef, void *inUserData) {
   1004 
   1005     // default action is to send event to next handler.  We modify osStatus as necessary where we don't want this behavior
   1006     OSStatus osStatus = eventNotHandledErr;
   1007 
   1008     // We do different things for different event types.
   1009     CarbonWindowAdapter *carbonWindow = (CarbonWindowAdapter *)inUserData;
   1010 
   1011 	osStatus = [carbonWindow _handleCarbonEvent: inEventRef callRef: inEventHandlerCallRef];
   1012 
   1013     // Done.  If we want to propagate the event, we return eventNotHandledErr to send it to the next handler
   1014     return osStatus;
   1015 
   1016 }
   1017 
   1018 // [3364117] We need to make sure this does not fall through to the AppKit implementation! bad things happen.
   1019 - (void)_reallyDoOrderWindow:(NSWindowOrderingMode)place relativeTo:(int)otherWin findKey:(BOOL)doKeyCalc forCounter:(BOOL)isACounter force:(BOOL)doForce isModal:(BOOL)isModal {
   1020 }
   1021 
   1022 - (NSRect) _growBoxRect
   1023 {
   1024       WindowAttributes                attrs;
   1025       NSRect                                  retRect = NSZeroRect;
   1026 
   1027       GetWindowAttributes( _windowRef, &attrs );
   1028 
   1029       if ( attrs & kWindowResizableAttribute )
   1030       {
   1031               HIRect          bounds, rect;
   1032               HIViewRef   view;
   1033 
   1034               HIViewGetBounds( HIViewGetRoot( _windowRef ), &bounds );
   1035               HIViewFindByID( HIViewGetRoot( _windowRef ), kHIViewWindowGrowBoxID, &view );
   1036               HIViewGetFrame( view, &rect );
   1037 
   1038               rect.origin.y = bounds.size.height - CGRectGetMaxY( rect ) - 1;
   1039               rect.origin.x++;
   1040 
   1041               retRect = *(NSRect*)&rect;
   1042       }
   1043 
   1044       return retRect;
   1045 }
   1046 
   1047 @end // implementation CarbonWindowAdapter
   1048 
   1049 #endif
   1050