]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/toplevel.cpp
changing asserts to debug info
[wxWidgets.git] / src / mac / carbon / toplevel.cpp
CommitLineData
a15eb0a5 1///////////////////////////////////////////////////////////////////////////////
fb5246be 2// Name: src/mac/carbon/toplevel.cpp
d66c3960
SC
3// Purpose: implements wxTopLevelWindow for Mac
4// Author: Stefan Csomor
a15eb0a5
SC
5// Modified by:
6// Created: 24.09.01
7// RCS-ID: $Id$
d66c3960 8// Copyright: (c) 2001-2004 Stefan Csomor
65571936 9// License: wxWindows licence
a15eb0a5
SC
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
a15eb0a5
SC
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
1832043f
WS
27#include "wx/toplevel.h"
28
a15eb0a5
SC
29#ifndef WX_PRECOMP
30 #include "wx/app.h"
422644a3 31 #include "wx/frame.h"
a15eb0a5
SC
32 #include "wx/string.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
37ec2bd3 35 #include "wx/settings.h"
2d17efa9 36 #include "wx/strconv.h"
179e085f 37 #include "wx/control.h"
a15eb0a5
SC
38#endif //WX_PRECOMP
39
5f0b2f22 40#include "wx/mac/uma.h"
422644a3 41#include "wx/mac/aga.h"
5f0b2f22 42#include "wx/tooltip.h"
a07c1212 43#include "wx/dnd.h"
a979e444 44
1f90939c
SC
45#if wxUSE_SYSTEM_OPTIONS
46 #include "wx/sysopt.h"
47#endif
5f0b2f22 48
3c393c0a 49#ifndef __DARWIN__
7f0c3a63 50#include <ToolUtils.h>
3c393c0a 51#endif
dd49c691 52
a979e444 53// for targeting OSX
eab19a7c
RN
54#include "wx/mac/private.h"
55
f02a4ffa
VZ
56// ----------------------------------------------------------------------------
57// constants
58// ----------------------------------------------------------------------------
59
60// trace mask for activation tracing messages
61static const wxChar *TRACE_ACTIVATE = _T("activation");
62
a15eb0a5
SC
63// ----------------------------------------------------------------------------
64// globals
65// ----------------------------------------------------------------------------
66
67// list of all frames and modeless dialogs
32b5be3d
RR
68wxWindowList wxModelessWindows;
69
6a7e6411
RD
70static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param);
71
a15eb0a5
SC
72// ============================================================================
73// wxTopLevelWindowMac implementation
74// ============================================================================
75
facd6764
SC
76BEGIN_EVENT_TABLE(wxTopLevelWindowMac, wxTopLevelWindowBase)
77END_EVENT_TABLE()
78
79
851b3a88
SC
80// ---------------------------------------------------------------------------
81// Carbon Events
82// ---------------------------------------------------------------------------
83
1542ea39 84static const EventTypeSpec eventList[] =
851b3a88 85{
a979e444 86 // TODO: remove control related event like key and mouse (except for WindowLeave events)
ffc75ee4 87
e40298d5 88 { kEventClassKeyboard, kEventRawKeyDown } ,
c5c9378c
SC
89 { kEventClassKeyboard, kEventRawKeyRepeat } ,
90 { kEventClassKeyboard, kEventRawKeyUp } ,
91 { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
92
ffc75ee4
SC
93 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
94 { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
30c23e74 95
16a76184 96 { kEventClassWindow , kEventWindowShown } ,
851b3a88
SC
97 { kEventClassWindow , kEventWindowActivated } ,
98 { kEventClassWindow , kEventWindowDeactivated } ,
99 { kEventClassWindow , kEventWindowBoundsChanging } ,
100 { kEventClassWindow , kEventWindowBoundsChanged } ,
101 { kEventClassWindow , kEventWindowClose } ,
102
a979e444
DS
103 // we have to catch these events on the toplevel window level,
104 // as controls don't get the raw mouse events anymore
902725ee 105
851b3a88
SC
106 { kEventClassMouse , kEventMouseDown } ,
107 { kEventClassMouse , kEventMouseUp } ,
de127c69 108 { kEventClassMouse , kEventMouseWheelMoved } ,
851b3a88
SC
109 { kEventClassMouse , kEventMouseMoved } ,
110 { kEventClassMouse , kEventMouseDragged } ,
851b3a88
SC
111} ;
112
c5c9378c
SC
113static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
114{
115 OSStatus result = eventNotHandledErr ;
b3bd613a 116 // call DoFindFocus instead of FindFocus, because for Composite Windows(like WxGenericListCtrl)
a979e444 117 // FindFocus does not return the actual focus window, but the enclosing window
b3bd613a 118 wxWindow* focus = wxWindow::DoFindFocus();
92a7272f 119 if ( focus == NULL )
ccf1ef0f 120 focus = (wxTopLevelWindowMac*) data ;
52c3df99 121
19fc48c6 122 unsigned char charCode ;
f3097709 123 wxChar uniChar[2] ;
670f9935
WS
124 uniChar[0] = 0;
125 uniChar[1] = 0;
126
1542ea39 127 UInt32 keyCode ;
c5c9378c 128 UInt32 modifiers ;
e40298d5
JS
129 Point point ;
130 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
131
2d17efa9 132#if wxUSE_UNICODE
7cd7bc23 133 ByteCount dataSize = 0 ;
a979e444 134 if ( GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr )
2d17efa9
SC
135 {
136 UniChar buf[2] ;
f3097709 137 int numChars = dataSize / sizeof( UniChar) + 1;
902725ee 138
2d17efa9 139 UniChar* charBuf = buf ;
902725ee 140
f3097709
SC
141 if ( numChars * 2 > 4 )
142 charBuf = new UniChar[ numChars ] ;
2d17efa9 143 GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
670f9935 144 charBuf[ numChars - 1 ] = 0;
a979e444 145
2d17efa9
SC
146#if SIZEOF_WCHAR_T == 2
147 uniChar = charBuf[0] ;
148#else
d9d488cf 149 wxMBConvUTF16 converter ;
0cc00f4f 150 converter.MB2WC( uniChar , (const char*)charBuf , 2 ) ;
902725ee 151#endif
a979e444 152
f3097709 153 if ( numChars * 2 > 4 )
2d17efa9
SC
154 delete[] charBuf ;
155 }
156#endif
157
a979e444 158 GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
52c3df99
DS
159 GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
160 GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
161 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
902725ee 162
e40298d5 163 UInt32 message = (keyCode << 8) + charCode;
a979e444 164 switch ( GetEventKind( event ) )
e40298d5
JS
165 {
166 case kEventRawKeyRepeat :
167 case kEventRawKeyDown :
e40298d5 168 {
404f1d80
SC
169 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
170 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
171 wxTheApp->MacSetCurrentEvent( event , handler ) ;
902725ee 172 if ( /* focus && */ wxTheApp->MacSendKeyDownEvent(
f3097709 173 focus , message , modifiers , when , point.h , point.v , uniChar[0] ) )
404f1d80
SC
174 {
175 result = noErr ;
176 }
177 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
e40298d5
JS
178 }
179 break ;
52c3df99 180
e40298d5 181 case kEventRawKeyUp :
902725ee 182 if ( /* focus && */ wxTheApp->MacSendKeyUpEvent(
f3097709 183 focus , message , modifiers , when , point.h , point.v , uniChar[0] ) )
e40298d5
JS
184 {
185 result = noErr ;
186 }
187 break ;
52c3df99 188
e40298d5
JS
189 case kEventRawKeyModifiersChanged :
190 {
191 wxKeyEvent event(wxEVT_KEY_DOWN);
192
193 event.m_shiftDown = modifiers & shiftKey;
194 event.m_controlDown = modifiers & controlKey;
195 event.m_altDown = modifiers & optionKey;
196 event.m_metaDown = modifiers & cmdKey;
a979e444
DS
197 event.m_x = point.h;
198 event.m_y = point.v;
199
2d17efa9 200#if wxUSE_UNICODE
0cc00f4f 201 event.m_uniChar = uniChar[0] ;
2d17efa9 202#endif
a979e444 203
687706f5 204 event.SetTimestamp(when);
e40298d5
JS
205 event.SetEventObject(focus);
206
902725ee 207 if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & controlKey )
e40298d5
JS
208 {
209 event.m_keyCode = WXK_CONTROL ;
210 event.SetEventType( ( modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
211 focus->GetEventHandler()->ProcessEvent( event ) ;
212 }
902725ee 213 if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & shiftKey )
e40298d5
JS
214 {
215 event.m_keyCode = WXK_SHIFT ;
216 event.SetEventType( ( modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
217 focus->GetEventHandler()->ProcessEvent( event ) ;
218 }
902725ee 219 if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & optionKey )
e40298d5
JS
220 {
221 event.m_keyCode = WXK_ALT ;
222 event.SetEventType( ( modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
223 focus->GetEventHandler()->ProcessEvent( event ) ;
224 }
902725ee 225 if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & cmdKey )
b7aec135
SC
226 {
227 event.m_keyCode = WXK_COMMAND ;
228 event.SetEventType( ( modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
229 focus->GetEventHandler()->ProcessEvent( event ) ;
230 }
a979e444 231
2a1f999f 232 wxApp::s_lastModifiers = modifiers ;
e40298d5 233 }
902725ee 234 break ;
52c3df99
DS
235
236 default:
237 break;
e40298d5 238 }
851b3a88
SC
239
240 return result ;
241}
242
facd6764 243// we don't interfere with foreign controls on our toplevel windows, therefore we always give back eventNotHandledErr
52c3df99 244// for windows that we didn't create (like eg Scrollbars in a databrowser), or for controls where we did not handle the
facd6764 245// mouse down at all
52c3df99 246//
facd6764 247// This handler can also be called from app level where data (ie target window) may be null or a non wx window
1542ea39 248
facd6764 249wxWindow* g_MacLastWindow = NULL ;
a3195b73 250
bdf895fd 251EventMouseButton g_lastButton = 0 ;
86a9144f 252
bdf895fd 253void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent )
facd6764
SC
254{
255 UInt32 modifiers = cEvent.GetParameter<UInt32>(kEventParamKeyModifiers, typeUInt32) ;
256 Point screenMouseLocation = cEvent.GetParameter<Point>(kEventParamMouseLocation) ;
67245665 257
902725ee 258 // this parameter are not given for all events
facd6764 259 EventMouseButton button = 0 ;
902725ee 260 UInt32 clickCount = 0 ;
a979e444
DS
261 cEvent.GetParameter<EventMouseButton>( kEventParamMouseButton, typeMouseButton , &button ) ;
262 cEvent.GetParameter<UInt32>( kEventParamClickCount, typeUInt32 , &clickCount ) ;
facd6764
SC
263
264 wxevent.m_x = screenMouseLocation.h;
265 wxevent.m_y = screenMouseLocation.v;
266 wxevent.m_shiftDown = modifiers & shiftKey;
267 wxevent.m_controlDown = modifiers & controlKey;
268 wxevent.m_altDown = modifiers & optionKey;
269 wxevent.m_metaDown = modifiers & cmdKey;
270 wxevent.SetTimestamp( cEvent.GetTicks() ) ;
52c3df99 271
902725ee 272 // a control click is interpreted as a right click
facd6764 273 if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) )
facd6764 274 button = kEventMouseButtonSecondary ;
902725ee 275
b343fb9f 276 // otherwise we report double clicks by connecting a left click with a ctrl-left click
bdf895fd 277 if ( clickCount > 1 && button != g_lastButton )
b343fb9f 278 clickCount = 1 ;
902725ee 279
86a9144f
SC
280 // we must make sure that our synthetic 'right' button corresponds in
281 // mouse down, moved and mouse up, and does not deliver a right down and left up
902725ee 282
86a9144f 283 if ( cEvent.GetKind() == kEventMouseDown )
bdf895fd 284 g_lastButton = button ;
902725ee 285
4e4e6dce 286 if ( button == 0 )
bdf895fd
KO
287 g_lastButton = 0 ;
288 else if ( g_lastButton )
289 button = g_lastButton ;
facd6764 290
a979e444
DS
291 // determine the correct down state, wx does not want a 'down' for a mouseUp event,
292 // while mac delivers this button
facd6764
SC
293 if ( button != 0 && cEvent.GetKind() != kEventMouseUp )
294 {
a979e444 295 switch ( button )
e40298d5 296 {
facd6764
SC
297 case kEventMouseButtonPrimary :
298 wxevent.m_leftDown = true ;
e40298d5 299 break ;
52c3df99 300
facd6764
SC
301 case kEventMouseButtonSecondary :
302 wxevent.m_rightDown = true ;
e40298d5 303 break ;
52c3df99 304
facd6764
SC
305 case kEventMouseButtonTertiary :
306 wxevent.m_middleDown = true ;
e40298d5 307 break ;
52c3df99
DS
308
309 default:
310 break ;
facd6764
SC
311 }
312 }
52c3df99 313
90ff87d7
SC
314 // translate into wx types
315 switch ( cEvent.GetKind() )
facd6764 316 {
90ff87d7 317 case kEventMouseDown :
52c3df99 318 switch ( button )
90ff87d7
SC
319 {
320 case kEventMouseButtonPrimary :
a979e444 321 wxevent.SetEventType( clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ;
90ff87d7 322 break ;
52c3df99 323
90ff87d7
SC
324 case kEventMouseButtonSecondary :
325 wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ;
326 break ;
52c3df99 327
90ff87d7 328 case kEventMouseButtonTertiary :
a979e444 329 wxevent.SetEventType( clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ;
90ff87d7 330 break ;
52c3df99
DS
331
332 default:
333 break ;
90ff87d7
SC
334 }
335 break ;
52c3df99 336
90ff87d7 337 case kEventMouseUp :
52c3df99 338 switch ( button )
90ff87d7
SC
339 {
340 case kEventMouseButtonPrimary :
341 wxevent.SetEventType( wxEVT_LEFT_UP ) ;
342 break ;
52c3df99 343
90ff87d7
SC
344 case kEventMouseButtonSecondary :
345 wxevent.SetEventType( wxEVT_RIGHT_UP ) ;
346 break ;
52c3df99 347
90ff87d7
SC
348 case kEventMouseButtonTertiary :
349 wxevent.SetEventType( wxEVT_MIDDLE_UP ) ;
350 break ;
52c3df99
DS
351
352 default:
353 break ;
90ff87d7
SC
354 }
355 break ;
52c3df99 356
2cce9b11 357 case kEventMouseWheelMoved :
52c3df99 358 {
a979e444 359 wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ;
facd6764
SC
360
361 // EventMouseWheelAxis axis = cEvent.GetParameter<EventMouseWheelAxis>(kEventParamMouseWheelAxis, typeMouseWheelAxis) ;
7cd7bc23 362 SInt32 delta = cEvent.GetParameter<SInt32>(kEventParamMouseWheelDelta, typeSInt32) ;
facd6764
SC
363
364 wxevent.m_wheelRotation = delta;
365 wxevent.m_wheelDelta = 1;
366 wxevent.m_linesPerAction = 1;
52c3df99
DS
367 }
368 break ;
369
90ff87d7 370 default :
a979e444 371 wxevent.SetEventType( wxEVT_MOTION ) ;
90ff87d7 372 break ;
902725ee 373 }
facd6764
SC
374}
375
fbfb8bcc 376ControlRef wxMacFindSubControl( wxTopLevelWindowMac* toplevelWindow, const Point& location , ControlRef superControl , ControlPartCode *outPart )
facd6764
SC
377{
378 if ( superControl )
379 {
380 UInt16 childrenCount = 0 ;
a979e444
DS
381 ControlHandle sibling ;
382 Rect r ;
902725ee 383 OSStatus err = CountSubControls( superControl , &childrenCount ) ;
facd6764
SC
384 if ( err == errControlIsNotEmbedder )
385 return NULL ;
a979e444 386
facd6764 387 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
902725ee 388
facd6764
SC
389 for ( UInt16 i = childrenCount ; i >=1 ; --i )
390 {
facd6764
SC
391 err = GetIndexedSubControl( superControl , i , & sibling ) ;
392 if ( err == errControlIsNotEmbedder )
393 return NULL ;
902725ee 394
facd6764
SC
395 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
396 if ( IsControlVisible( sibling ) )
397 {
d6fd667b 398 UMAGetControlBoundsInWindowCoords( sibling , &r ) ;
facd6764 399 if ( MacPtInRect( location , &r ) )
de127c69 400 {
789ae0cf 401 ControlHandle child = wxMacFindSubControl( toplevelWindow , location , sibling , outPart ) ;
facd6764 402 if ( child )
a979e444 403 {
facd6764 404 return child ;
a979e444 405 }
facd6764 406 else
de127c69 407 {
d6fd667b 408 Point testLocation = location ;
789ae0cf 409
f21449ae 410 if ( toplevelWindow )
789ae0cf
SC
411 {
412 testLocation.h -= r.left ;
413 testLocation.v -= r.top ;
414 }
902725ee 415
d6fd667b 416 *outPart = TestControl( sibling , testLocation ) ;
a979e444 417
facd6764 418 return sibling ;
de127c69
GD
419 }
420 }
facd6764 421 }
e40298d5
JS
422 }
423 }
52c3df99 424
facd6764
SC
425 return NULL ;
426}
1542ea39 427
fbfb8bcc 428ControlRef wxMacFindControlUnderMouse( wxTopLevelWindowMac* toplevelWindow , const Point& location , WindowRef window , ControlPartCode *outPart )
facd6764
SC
429{
430#if TARGET_API_MAC_OSX
f21449ae 431 if ( UMAGetSystemVersion() >= 0x1030 )
30e0b1c9
SC
432 return FindControlUnderMouse( location , window , outPart ) ;
433#endif
a979e444 434
facd6764
SC
435 ControlRef rootControl = NULL ;
436 verify_noerr( GetRootControl( window , &rootControl ) ) ;
30e0b1c9 437
a979e444 438 return wxMacFindSubControl( toplevelWindow , location , rootControl , outPart ) ;
facd6764 439}
3c393c0a
SC
440
441#define NEW_CAPTURE_HANDLING 1
442
facd6764
SC
443pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
444{
789ae0cf 445 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
902725ee 446
facd6764
SC
447 OSStatus result = eventNotHandledErr ;
448
449 wxMacCarbonEvent cEvent( event ) ;
902725ee 450
facd6764
SC
451 Point screenMouseLocation = cEvent.GetParameter<Point>(kEventParamMouseLocation) ;
452 Point windowMouseLocation = screenMouseLocation ;
453
30c23e74 454 WindowRef window = NULL;
facd6764
SC
455 short windowPart = ::FindWindow(screenMouseLocation, &window);
456
457 wxWindow* currentMouseWindow = NULL ;
d88ffaaa 458 ControlRef control = NULL ;
902725ee 459
3c393c0a
SC
460#if NEW_CAPTURE_HANDLING
461 if ( wxApp::s_captureWindow )
462 {
463 window = (WindowRef) wxApp::s_captureWindow->MacGetTopLevelWindowRef() ;
8fc754bf 464 windowPart = inContent ;
3c393c0a
SC
465 }
466#endif
fb5246be 467
facd6764
SC
468 if ( window )
469 {
7cd7bc23 470 wxMacGlobalToLocal( window, &windowMouseLocation ) ;
facd6764 471
3c393c0a
SC
472 if ( wxApp::s_captureWindow
473#if !NEW_CAPTURE_HANDLING
474 && wxApp::s_captureWindow->MacGetTopLevelWindowRef() == (WXWindow) window && windowPart == inContent
475#endif
476 )
facd6764 477 {
2a1f999f 478 currentMouseWindow = wxApp::s_captureWindow ;
facd6764
SC
479 }
480 else if ( (IsWindowActive(window) && windowPart == inContent) )
481 {
482 ControlPartCode part ;
789ae0cf 483 control = wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &part ) ;
d88ffaaa 484 // if there is no control below the mouse position, send the event to the toplevel window itself
b19bf058 485 if ( control == 0 )
a979e444 486 {
b19bf058 487 currentMouseWindow = (wxWindow*) data ;
a979e444 488 }
b19bf058 489 else
b16f4bfa 490 {
b19bf058 491 currentMouseWindow = wxFindControlFromMacControl( control ) ;
8198ae50 492 if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved )
b16f4bfa 493 {
179e085f 494#if wxUSE_TOOLBAR
902725ee
WS
495 // for wxToolBar to function we have to send certaint events to it
496 // instead of its children (wxToolBarTools)
b16f4bfa
SC
497 ControlRef parent ;
498 GetSuperControl(control, &parent );
499 wxWindow *wxParent = wxFindControlFromMacControl( parent ) ;
500 if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) )
501 currentMouseWindow = wxParent ;
179e085f 502#endif
b16f4bfa
SC
503 }
504 }
f0756835
VZ
505
506 // disabled windows must not get any input messages
507 if ( currentMouseWindow && !currentMouseWindow->MacIsReallyEnabled() )
508 currentMouseWindow = NULL;
902725ee 509 }
facd6764 510 }
902725ee 511
facd6764
SC
512 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
513 SetupMouseEvent( wxevent , cEvent ) ;
514
515 // handle all enter / leave events
902725ee 516
facd6764
SC
517 if ( currentMouseWindow != g_MacLastWindow )
518 {
519 if ( g_MacLastWindow )
520 {
521 wxMouseEvent eventleave(wxevent);
522 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
523 g_MacLastWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
524 eventleave.SetEventObject( g_MacLastWindow ) ;
d4bd6c97 525 wxevent.SetId( g_MacLastWindow->GetId() ) ;
a979e444 526
facd6764
SC
527#if wxUSE_TOOLTIPS
528 wxToolTip::RelayEvent( g_MacLastWindow , eventleave);
a979e444
DS
529#endif
530
facd6764
SC
531 g_MacLastWindow->GetEventHandler()->ProcessEvent(eventleave);
532 }
52c3df99 533
facd6764
SC
534 if ( currentMouseWindow )
535 {
536 wxMouseEvent evententer(wxevent);
537 evententer.SetEventType( wxEVT_ENTER_WINDOW );
538 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
539 evententer.SetEventObject( currentMouseWindow ) ;
d4bd6c97 540 wxevent.SetId( currentMouseWindow->GetId() ) ;
a979e444 541
facd6764 542#if wxUSE_TOOLTIPS
a979e444
DS
543 wxToolTip::RelayEvent( currentMouseWindow , evententer );
544#endif
545
facd6764
SC
546 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
547 }
52c3df99 548
facd6764
SC
549 g_MacLastWindow = currentMouseWindow ;
550 }
902725ee 551
facd6764
SC
552 if ( windowPart == inMenuBar )
553 {
554 // special case menu bar, as we are having a low-level runloop we must do it ourselves
555 if ( cEvent.GetKind() == kEventMouseDown )
556 {
557 ::MenuSelect( screenMouseLocation ) ;
558 result = noErr ;
559 }
52c3df99 560 }
facd6764
SC
561 else if ( currentMouseWindow )
562 {
e10e9469 563 wxWindow *currentMouseWindowParent = currentMouseWindow->GetParent();
62ade180
RR
564
565 currentMouseWindow->ScreenToClient( &wxevent.m_x , &wxevent.m_y ) ;
902725ee 566
facd6764 567 wxevent.SetEventObject( currentMouseWindow ) ;
d4bd6c97 568 wxevent.SetId( currentMouseWindow->GetId() ) ;
facd6764 569
facd6764 570 // make tooltips current
902725ee 571
a979e444 572#if wxUSE_TOOLTIPS
f124c908 573 if ( wxevent.GetEventType() == wxEVT_MOTION )
a979e444
DS
574 wxToolTip::RelayEvent( currentMouseWindow , wxevent );
575#endif
576
facd6764 577 if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) )
62ade180 578 {
902725ee 579 if ((currentMouseWindowParent != NULL) &&
62ade180
RR
580 (currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
581 currentMouseWindow = NULL;
902725ee 582
facd6764 583 result = noErr;
62ade180 584 }
30e0b1c9
SC
585 else
586 {
f90387b4
VZ
587 // if the user code did _not_ handle the event, then perform the
588 // default processing
589 if ( wxevent.GetEventType() == wxEVT_LEFT_DOWN )
590 {
591 // ... that is set focus to this window
592 if (currentMouseWindow->AcceptsFocus() && wxWindow::FindFocus()!=currentMouseWindow)
593 currentMouseWindow->SetFocus();
594 }
595
30e0b1c9
SC
596 ControlPartCode dummyPart ;
597 // if built-in find control is finding the wrong control (ie static box instead of overlaid
598 // button, we cannot let the standard handler do its job, but must handle manually
599
902725ee 600 if ( ( cEvent.GetKind() == kEventMouseDown )
23ad132c 601#ifdef __WXMAC_OSX__
902725ee
WS
602 &&
603 (FindControlUnderMouse(windowMouseLocation , window , &dummyPart) !=
604 wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &dummyPart ) )
23ad132c
SC
605#endif
606 )
30e0b1c9 607 {
902725ee 608 if ( currentMouseWindow->MacIsReallyEnabled() )
7ce1a4e1
SC
609 {
610 EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
611 Point clickLocation = windowMouseLocation ;
789ae0cf 612
f21449ae 613 currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
789ae0cf 614
7ce1a4e1
SC
615 HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
616 modifiers , (ControlActionUPP ) -1 ) ;
902725ee
WS
617
618 if ((currentMouseWindowParent != NULL) &&
62ade180 619 (currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
a979e444 620 {
e10e9469 621 currentMouseWindow = NULL;
a979e444 622 }
7ce1a4e1 623 }
a979e444 624
30e0b1c9
SC
625 result = noErr ;
626 }
627 }
52c3df99 628
2a1f999f 629 if ( cEvent.GetKind() == kEventMouseUp && wxApp::s_captureWindow )
facd6764 630 {
2a1f999f 631 wxApp::s_captureWindow = NULL ;
facd6764
SC
632 // update cursor ?
633 }
6d63e2fc
SC
634
635 // update cursor
902725ee 636
6d63e2fc
SC
637 wxWindow* cursorTarget = currentMouseWindow ;
638 wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
639
52c3df99 640 while ( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
6d63e2fc
SC
641 {
642 cursorTarget = cursorTarget->GetParent() ;
643 if ( cursorTarget )
e10e9469 644 cursorPoint += cursorTarget->GetPosition();
6d63e2fc
SC
645 }
646
f124c908
VZ
647 }
648 else // currentMouseWindow == NULL
d88ffaaa
SC
649 {
650 // don't mess with controls we don't know about
651 // for some reason returning eventNotHandledErr does not lead to the correct behaviour
652 // so we try sending them the correct control directly
e4b7e0b4 653 if ( cEvent.GetKind() == kEventMouseDown && toplevelWindow && control )
d88ffaaa
SC
654 {
655 EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
656 Point clickLocation = windowMouseLocation ;
f124c908 657#if TARGET_API_MAC_OSX
f21449ae
SC
658 HIPoint hiPoint ;
659 hiPoint.x = clickLocation.h ;
660 hiPoint.y = clickLocation.v ;
661 HIViewConvertPoint( &hiPoint , (ControlRef) toplevelWindow->GetHandle() , control ) ;
662 clickLocation.h = (int)hiPoint.x ;
663 clickLocation.v = (int)hiPoint.y ;
f124c908 664#endif // TARGET_API_MAC_OSX
52c3df99
DS
665
666 HandleControlClick( control , clickLocation , modifiers , (ControlActionUPP ) -1 ) ;
d88ffaaa
SC
667 result = noErr ;
668 }
669 }
a979e444 670
facd6764 671 return result ;
851b3a88 672}
facd6764
SC
673
674static pascal OSStatus wxMacTopLevelWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
851b3a88
SC
675{
676 OSStatus result = eventNotHandledErr ;
851b3a88 677
facd6764 678 wxMacCarbonEvent cEvent( event ) ;
902725ee 679
facd6764 680 // WindowRef windowRef = cEvent.GetParameter<WindowRef>(kEventParamDirectObject) ;
e40298d5 681 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
1542ea39 682
52c3df99 683 switch ( GetEventKind( event ) )
e40298d5 684 {
e40298d5 685 case kEventWindowActivated :
facd6764
SC
686 {
687 toplevelWindow->MacActivate( cEvent.GetTicks() , true) ;
facd6764
SC
688 wxActivateEvent wxevent(wxEVT_ACTIVATE, true , toplevelWindow->GetId());
689 wxevent.SetTimestamp( cEvent.GetTicks() ) ;
690 wxevent.SetEventObject(toplevelWindow);
691 toplevelWindow->GetEventHandler()->ProcessEvent(wxevent);
73fe67bd 692 // we still sending an eventNotHandledErr in order to allow for default processing
facd6764 693 }
52c3df99
DS
694 break ;
695
e40298d5 696 case kEventWindowDeactivated :
facd6764
SC
697 {
698 toplevelWindow->MacActivate(cEvent.GetTicks() , false) ;
699 wxActivateEvent wxevent(wxEVT_ACTIVATE, false , toplevelWindow->GetId());
700 wxevent.SetTimestamp( cEvent.GetTicks() ) ;
701 wxevent.SetEventObject(toplevelWindow);
702 toplevelWindow->GetEventHandler()->ProcessEvent(wxevent);
73fe67bd 703 // we still sending an eventNotHandledErr in order to allow for default processing
facd6764 704 }
52c3df99
DS
705 break ;
706
902725ee 707 case kEventWindowShown :
902725ee
WS
708 toplevelWindow->Refresh() ;
709 result = noErr ;
710 break ;
52c3df99 711
e40298d5 712 case kEventWindowClose :
52c3df99 713 toplevelWindow->Close() ;
e40298d5
JS
714 result = noErr ;
715 break ;
52c3df99 716
e40298d5 717 case kEventWindowBoundsChanged :
facd6764 718 {
52c3df99 719 UInt32 attributes = cEvent.GetParameter<UInt32>(kEventParamAttributes, typeUInt32) ;
facd6764
SC
720 Rect newRect = cEvent.GetParameter<Rect>(kEventParamCurrentBounds) ;
721 wxRect r( newRect.left , newRect.top , newRect.right - newRect.left , newRect.bottom - newRect.top ) ;
722 if ( attributes & kWindowBoundsChangeSizeChanged )
e40298d5 723 {
facd6764
SC
724 // according to the other ports we handle this within the OS level
725 // resize event, not within a wxSizeEvent
726 wxFrame *frame = wxDynamicCast( toplevelWindow , wxFrame ) ;
727 if ( frame )
728 {
6f02a879 729 frame->PositionBars();
facd6764 730 }
1542ea39 731
facd6764
SC
732 wxSizeEvent event( r.GetSize() , toplevelWindow->GetId() ) ;
733 event.SetEventObject( toplevelWindow ) ;
851b3a88 734
facd6764 735 toplevelWindow->GetEventHandler()->ProcessEvent(event) ;
5e533062 736 toplevelWindow->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
e40298d5 737 }
52c3df99 738
facd6764
SC
739 if ( attributes & kWindowBoundsChangeOriginChanged )
740 {
741 wxMoveEvent event( r.GetLeftTop() , toplevelWindow->GetId() ) ;
742 event.SetEventObject( toplevelWindow ) ;
743 toplevelWindow->GetEventHandler()->ProcessEvent(event) ;
744 }
52c3df99 745
facd6764 746 result = noErr ;
facd6764 747 }
52c3df99
DS
748 break ;
749
f81bfef9 750 case kEventWindowBoundsChanging :
facd6764
SC
751 {
752 UInt32 attributes = cEvent.GetParameter<UInt32>(kEventParamAttributes,typeUInt32) ;
753 Rect newRect = cEvent.GetParameter<Rect>(kEventParamCurrentBounds) ;
83901ec2 754
facd6764
SC
755 if ( (attributes & kWindowBoundsChangeSizeChanged) || (attributes & kWindowBoundsChangeOriginChanged) )
756 {
29281095
SC
757 // all (Mac) rects are in content area coordinates, all wxRects in structure coordinates
758 int left , top , right , bottom ;
759 toplevelWindow->MacGetContentAreaInset( left , top , right , bottom ) ;
52c3df99
DS
760
761 wxRect r(
762 newRect.left - left,
763 newRect.top - top,
764 newRect.right - newRect.left + left + right,
765 newRect.bottom - newRect.top + top + bottom ) ;
766
facd6764
SC
767 // this is a EVT_SIZING not a EVT_SIZE type !
768 wxSizeEvent wxevent( r , toplevelWindow->GetId() ) ;
769 wxevent.SetEventObject( toplevelWindow ) ;
770 wxRect adjustR = r ;
771 if ( toplevelWindow->GetEventHandler()->ProcessEvent(wxevent) )
facd6764 772 adjustR = wxevent.GetRect() ;
29281095 773
facd6764
SC
774 if ( toplevelWindow->GetMaxWidth() != -1 && adjustR.GetWidth() > toplevelWindow->GetMaxWidth() )
775 adjustR.SetWidth( toplevelWindow->GetMaxWidth() ) ;
2c25bd55 776 if ( toplevelWindow->GetMaxHeight() != -1 && adjustR.GetHeight() > toplevelWindow->GetMaxHeight() )
facd6764
SC
777 adjustR.SetHeight( toplevelWindow->GetMaxHeight() ) ;
778 if ( toplevelWindow->GetMinWidth() != -1 && adjustR.GetWidth() < toplevelWindow->GetMinWidth() )
779 adjustR.SetWidth( toplevelWindow->GetMinWidth() ) ;
2c25bd55 780 if ( toplevelWindow->GetMinHeight() != -1 && adjustR.GetHeight() < toplevelWindow->GetMinHeight() )
facd6764 781 adjustR.SetHeight( toplevelWindow->GetMinHeight() ) ;
4a5f2351 782 const Rect adjustedRect = { adjustR.y + top , adjustR.x + left , adjustR.y + adjustR.height - bottom , adjustR.x + adjustR.width - right } ;
facd6764 783 if ( !EqualRect( &newRect , &adjustedRect ) )
1f919f38 784 cEvent.SetParameter<Rect>( kEventParamCurrentBounds , &adjustedRect ) ;
4817190d 785 toplevelWindow->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
f81bfef9 786 }
facd6764 787
902725ee 788 result = noErr ;
facd6764 789 }
52c3df99
DS
790 break ;
791
e40298d5
JS
792 default :
793 break ;
794 }
52c3df99 795
e40298d5 796 return result ;
851b3a88
SC
797}
798
ffc75ee4
SC
799// mix this in from window.cpp
800pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ;
801
facd6764 802pascal OSStatus wxMacTopLevelEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
851b3a88
SC
803{
804 OSStatus result = eventNotHandledErr ;
805
806 switch ( GetEventClass( event ) )
807 {
ffc75ee4
SC
808 case kEventClassTextInput :
809 result = wxMacUnicodeTextEventHandler( handler, event , data ) ;
810 break ;
811
c5c9378c 812 case kEventClassKeyboard :
e40298d5 813 result = KeyboardEventHandler( handler, event , data ) ;
c5c9378c 814 break ;
52c3df99 815
851b3a88 816 case kEventClassWindow :
facd6764 817 result = wxMacTopLevelWindowEventHandler( handler, event , data ) ;
e40298d5 818 break ;
52c3df99 819
851b3a88 820 case kEventClassMouse :
facd6764 821 result = wxMacTopLevelMouseEventHandler( handler, event , data ) ;
e40298d5 822 break ;
52c3df99 823
851b3a88
SC
824 default :
825 break ;
826 }
52c3df99 827
851b3a88
SC
828 return result ;
829}
830
facd6764 831DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTopLevelEventHandler )
851b3a88 832
5f0b2f22
SC
833// ---------------------------------------------------------------------------
834// wxWindowMac utility functions
835// ---------------------------------------------------------------------------
836
837// Find an item given the Macintosh Window Reference
838
71f2fb52
RN
839WX_DECLARE_HASH_MAP(WindowRef, wxTopLevelWindowMac*, wxPointerHash, wxPointerEqual, MacWindowMap);
840
841static MacWindowMap wxWinMacWindowList;
842
843wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
844{
845 MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef);
846
847 return (node == wxWinMacWindowList.end()) ? NULL : node->second;
848}
849
850void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win) ;
851void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win)
852{
853 // adding NULL WindowRef is (first) surely a result of an error and
854 // nothing else :-)
855 wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
856
857 wxWinMacWindowList[inWindowRef] = win;
858}
859
860void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win) ;
861void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
862{
863 MacWindowMap::iterator it;
864 for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it )
865 {
866 if ( it->second == win )
867 {
868 wxWinMacWindowList.erase(it);
869 break;
870 }
871 }
872}
5f0b2f22 873
a15eb0a5
SC
874// ----------------------------------------------------------------------------
875// wxTopLevelWindowMac creation
876// ----------------------------------------------------------------------------
877
245f3581 878wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL;
5f0b2f22 879
902725ee 880typedef struct
c5985061
SC
881{
882 wxPoint m_position ;
902725ee 883 wxSize m_size ;
f3b2e2d7 884 bool m_wasResizable ;
716d0327 885} FullScreenData ;
c5985061 886
a15eb0a5
SC
887void wxTopLevelWindowMac::Init()
888{
889 m_iconized =
902725ee 890 m_maximizeOnShow = false;
6a17ca35 891 m_macWindow = NULL ;
52c3df99 892
7c091673 893 m_macEventHandler = NULL ;
c5985061 894 m_macFullScreenData = NULL ;
a15eb0a5
SC
895}
896
118f012e
SC
897class wxMacDeferredWindowDeleter : public wxObject
898{
899public :
1542ea39
RD
900 wxMacDeferredWindowDeleter( WindowRef windowRef )
901 {
902 m_macWindow = windowRef ;
118f012e 903 }
52c3df99 904
1542ea39
RD
905 virtual ~wxMacDeferredWindowDeleter()
906 {
907 UMADisposeWindow( (WindowRef) m_macWindow ) ;
118f012e 908 }
52c3df99
DS
909
910protected :
118f012e
SC
911 WindowRef m_macWindow ;
912} ;
913
a15eb0a5
SC
914bool wxTopLevelWindowMac::Create(wxWindow *parent,
915 wxWindowID id,
916 const wxString& title,
917 const wxPoint& pos,
918 const wxSize& size,
919 long style,
920 const wxString& name)
921{
922 // init our fields
923 Init();
924
925 m_windowStyle = style;
926
52c3df99 927 SetName( name );
a15eb0a5
SC
928
929 m_windowId = id == -1 ? NewControlId() : id;
fb5246be 930 wxWindow::SetLabel( title ) ;
a15eb0a5 931
a0232aa5 932 MacCreateRealWindow( title, pos , size , style , name ) ;
facd6764 933
94d1d0f4 934 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
902725ee 935
5bd78bbc
JS
936 if (GetExtraStyle() & wxFRAME_EX_METAL)
937 MacSetMetalAppearance(true);
94d1d0f4 938
a15eb0a5
SC
939 wxTopLevelWindows.Append(this);
940
941 if ( parent )
942 parent->AddChild(this);
943
902725ee 944 return true;
a15eb0a5
SC
945}
946
947wxTopLevelWindowMac::~wxTopLevelWindowMac()
948{
6a17ca35
SC
949 if ( m_macWindow )
950 {
c81c6d54 951#if wxUSE_TOOLTIPS
6a17ca35 952 wxToolTip::NotifyWindowDelete(m_macWindow) ;
c81c6d54 953#endif
118f012e 954 wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
6a17ca35 955 }
1542ea39 956
7c091673
SC
957 if ( m_macEventHandler )
958 {
959 ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
960 m_macEventHandler = NULL ;
961 }
851b3a88 962
5f0b2f22
SC
963 wxRemoveMacWindowAssociation( this ) ;
964
a15eb0a5
SC
965 if ( wxModelessWindows.Find(this) )
966 wxModelessWindows.DeleteObject(this);
902725ee 967
c5985061
SC
968 FullScreenData *data = (FullScreenData *) m_macFullScreenData ;
969 delete data ;
970 m_macFullScreenData = NULL ;
a15eb0a5
SC
971}
972
973
974// ----------------------------------------------------------------------------
975// wxTopLevelWindowMac maximize/minimize
976// ----------------------------------------------------------------------------
977
978void wxTopLevelWindowMac::Maximize(bool maximize)
979{
6643c354
SC
980 Point idealSize = { 0 , 0 } ;
981 if ( maximize )
982 {
7cd7bc23
SC
983#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
984 HIRect bounds ;
985 HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal,
986 &bounds);
987 idealSize.h = bounds.size.width;
988 idealSize.v = bounds.size.height;
989#else
6643c354
SC
990 Rect rect ;
991 GetAvailableWindowPositioningBounds(GetMainDevice(),&rect) ;
992 idealSize.h = rect.right - rect.left ;
993 idealSize.v = rect.bottom - rect.top ;
7cd7bc23 994#endif
6643c354
SC
995 }
996 ZoomWindowIdeal( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , &idealSize ) ;
a15eb0a5
SC
997}
998
999bool wxTopLevelWindowMac::IsMaximized() const
1000{
a979e444 1001 return IsWindowInStandardState( (WindowRef)m_macWindow , NULL , NULL ) ;
a15eb0a5
SC
1002}
1003
1004void wxTopLevelWindowMac::Iconize(bool iconize)
1005{
52c3df99
DS
1006 if ( IsWindowCollapsable( (WindowRef)m_macWindow) )
1007 CollapseWindow( (WindowRef)m_macWindow , iconize ) ;
a15eb0a5
SC
1008}
1009
1010bool wxTopLevelWindowMac::IsIconized() const
1011{
b7aec135 1012 return IsWindowCollapsed((WindowRef)m_macWindow ) ;
a15eb0a5
SC
1013}
1014
1015void wxTopLevelWindowMac::Restore()
1016{
902725ee 1017 if ( IsMaximized() )
699b6af4 1018 Maximize(false);
902725ee 1019 else if ( IsIconized() )
699b6af4 1020 Iconize(false);
a15eb0a5
SC
1021}
1022
1023// ----------------------------------------------------------------------------
1024// wxTopLevelWindowMac misc
1025// ----------------------------------------------------------------------------
1026
facd6764
SC
1027wxPoint wxTopLevelWindowMac::GetClientAreaOrigin() const
1028{
52c3df99 1029 return wxPoint(0, 0) ;
facd6764
SC
1030}
1031
a15eb0a5
SC
1032void wxTopLevelWindowMac::SetIcon(const wxIcon& icon)
1033{
1034 // this sets m_icon
1035 wxTopLevelWindowBase::SetIcon(icon);
1036}
5f0b2f22 1037
facd6764 1038void wxTopLevelWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
902725ee 1039{
facd6764
SC
1040 wxTopLevelWindowBase::MacSetBackgroundBrush( brush ) ;
1041
1042 if ( m_macBackgroundBrush.Ok() && m_macBackgroundBrush.GetStyle() != wxTRANSPARENT && m_macBackgroundBrush.MacGetBrushKind() == kwxMacBrushTheme )
1043 {
1044 SetThemeWindowBackground( (WindowRef) m_macWindow , m_macBackgroundBrush.MacGetTheme() , false ) ;
1045 }
1046}
1047
902725ee 1048void wxTopLevelWindowMac::MacInstallTopLevelWindowEventHandler()
949cb163
SC
1049{
1050 if ( m_macEventHandler != NULL )
1051 {
1052 verify_noerr( ::RemoveEventHandler( (EventHandlerRef) m_macEventHandler ) ) ;
1053 }
52c3df99
DS
1054
1055 InstallWindowEventHandler(
1056 MAC_WXHWND(m_macWindow), GetwxMacTopLevelEventHandlerUPP(),
1057 GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macEventHandler );
949cb163
SC
1058}
1059
a979e444
DS
1060void wxTopLevelWindowMac::MacCreateRealWindow(
1061 const wxString& title,
1062 const wxPoint& pos,
1063 const wxSize& size,
1064 long style,
1065 const wxString& name )
5f0b2f22 1066{
47ac4f9b 1067 OSStatus err = noErr ;
e40298d5
JS
1068 SetName(name);
1069 m_windowStyle = style;
902725ee 1070 m_isShown = false;
1542ea39 1071
e40298d5 1072 // create frame.
facd6764
SC
1073 int x = (int)pos.x;
1074 int y = (int)pos.y;
902725ee 1075
52c3df99 1076 Rect theBoundsRect;
5a486641
SC
1077 wxRect display = wxGetClientDisplayRect() ;
1078
1079 if ( x == wxDefaultPosition.x )
1080 x = display.x ;
902725ee 1081
5a486641
SC
1082 if ( y == wxDefaultPosition.y )
1083 y = display.y ;
1542ea39 1084
facd6764
SC
1085 int w = WidthDefault(size.x);
1086 int h = HeightDefault(size.y);
1542ea39 1087
facd6764 1088 ::SetRect(&theBoundsRect, x, y , x + w, y + h);
1542ea39 1089
5f0b2f22 1090 // translate the window attributes in the appropriate window class and attributes
5f0b2f22
SC
1091 WindowClass wclass = 0;
1092 WindowAttributes attr = kWindowNoAttributes ;
e353795e 1093 WindowGroupRef group = NULL ;
1542ea39 1094
f5744893 1095 if ( HasFlag( wxFRAME_TOOL_WINDOW) )
5f0b2f22 1096 {
1542ea39 1097 if (
f5744893
SC
1098 HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
1099 HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) ||
1100 HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT)
e40298d5 1101 )
5f0b2f22 1102 {
f5744893 1103 wclass = kFloatingWindowClass ;
52c3df99 1104
f5744893 1105 if ( HasFlag(wxTINY_CAPTION_VERT) )
f5744893 1106 attr |= kWindowSideTitlebarAttribute ;
f5744893
SC
1107 }
1108 else
1109 {
1110 wclass = kPlainWindowClass ;
5f0b2f22
SC
1111 }
1112 }
a0232aa5
RD
1113 else if ( HasFlag( wxPOPUP_WINDOW ) )
1114 {
1115 // TEMPORARY HACK!
1116 // Until we've got a real wxPopupWindow class on wxMac make it a
1117 // little easier for wxFrame to be used to emulate it and workaround
1118 // the lack of wxPopupWindow.
1119 if ( HasFlag( wxBORDER_NONE ) )
1120 wclass = kHelpWindowClass ; // has no border
1121 else
1122 wclass = kPlainWindowClass ; // has a single line border, it will have to do for now
1123 //attr |= kWindowNoShadowAttribute; // turn off the shadow Should we??
1124 group = GetWindowGroupOfClass( // float above other windows
1125 kFloatingWindowClass) ;
1126 }
5f0b2f22
SC
1127 else if ( HasFlag( wxCAPTION ) )
1128 {
1542ea39 1129 wclass = kDocumentWindowClass ;
22e3c5bd 1130 attr |= kWindowInWindowMenuAttribute ;
5f0b2f22 1131 }
eab19a7c 1132#if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 )
3e17bc3f
RN
1133 else if ( HasFlag( wxFRAME_DRAWER ) )
1134 {
1135 wclass = kDrawerWindowClass;
3e17bc3f
RN
1136 }
1137#endif //10.2 and up
5f0b2f22
SC
1138 else
1139 {
f5744893 1140 if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
47ac4f9b 1141 HasFlag( wxCLOSE_BOX ) || HasFlag( wxSYSTEM_MENU ) )
f5744893
SC
1142 {
1143 wclass = kDocumentWindowClass ;
1144 }
1145 else
1146 {
1147 wclass = kPlainWindowClass ;
1148 }
5f0b2f22 1149 }
1542ea39 1150
52c3df99 1151 if ( wclass != kPlainWindowClass )
5f0b2f22 1152 {
52c3df99
DS
1153 if ( HasFlag( wxMINIMIZE_BOX ) )
1154 attr |= kWindowCollapseBoxAttribute ;
1155
1156 if ( HasFlag( wxMAXIMIZE_BOX ) )
1157 attr |= kWindowFullZoomAttribute ;
1158
1159 if ( HasFlag( wxRESIZE_BORDER ) )
1160 attr |= kWindowResizableAttribute ;
1161
1162 if ( HasFlag( wxCLOSE_BOX) )
1163 attr |= kWindowCloseBoxAttribute ;
5f0b2f22 1164 }
1542ea39 1165
52c3df99 1166 // turn on live resizing (OS X only)
eb630bf1 1167 if (UMAGetSystemVersion() >= 0x1000)
eb630bf1 1168 attr |= kWindowLiveResizeAttribute;
eb630bf1 1169
e353795e 1170 if ( HasFlag(wxSTAY_ON_TOP) )
e353795e 1171 group = GetWindowGroupOfClass(kUtilityWindowClass) ;
6a7e6411 1172
a0232aa5
RD
1173 if ( HasFlag( wxFRAME_FLOAT_ON_PARENT ) )
1174 group = GetWindowGroupOfClass(kFloatingWindowClass) ;
1175
f21449ae 1176 attr |= kWindowCompositingAttribute;
24fcd264
SC
1177#if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale)
1178 attr |= kWindowFrameworkScaledAttribute;
d66c3960 1179#endif
902725ee 1180
6a7e6411
RD
1181 if ( HasFlag(wxFRAME_SHAPED) )
1182 {
1183 WindowDefSpec customWindowDefSpec;
1184 customWindowDefSpec.defType = kWindowDefProcPtr;
7cd7bc23
SC
1185 customWindowDefSpec.u.defProc =
1186#ifdef __LP64__
1187 (WindowDefUPP) wxShapedMacWindowDef;
1188#else
1189 NewWindowDefUPP(wxShapedMacWindowDef);
1190#endif
47ac4f9b 1191 err = ::CreateCustomWindow( &customWindowDefSpec, wclass,
6a7e6411
RD
1192 attr, &theBoundsRect,
1193 (WindowRef*) &m_macWindow);
1194 }
1195 else
1196 {
47ac4f9b 1197 err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
6a7e6411
RD
1198 }
1199
e353795e
SC
1200 if ( err == noErr && m_macWindow != NULL && group != NULL )
1201 SetWindowGroup( (WindowRef) m_macWindow , group ) ;
1202
47ac4f9b 1203 wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") );
f83b6761 1204
832f330f
SC
1205 // setup a separate group for each window, so that overlays can be handled easily
1206 verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrHideOnCollapse, &group ));
1207 verify_noerr( SetWindowGroupParent( group, GetWindowGroup( (WindowRef) m_macWindow )));
1208 verify_noerr( SetWindowGroup( (WindowRef) m_macWindow , group ));
1209
a979e444
DS
1210 // the create commands are only for content rect,
1211 // so we have to set the size again as structure bounds
f83b6761
SC
1212 SetWindowBounds( (WindowRef) m_macWindow , kWindowStructureRgn , &theBoundsRect ) ;
1213
facd6764
SC
1214 wxAssociateWinWithMacWindow( (WindowRef) m_macWindow , this ) ;
1215 UMASetWTitle( (WindowRef) m_macWindow , title , m_font.GetEncoding() ) ;
1f1c8bd4 1216 m_peer = new wxMacControl(this , true /*isRootControl*/) ;
902725ee 1217
f21449ae
SC
1218 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1219 // the content view, so we have to retrieve it explicitly
1220 HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID ,
1221 m_peer->GetControlRefAddr() ) ;
1222 if ( !m_peer->Ok() )
789ae0cf 1223 {
f21449ae
SC
1224 // compatibility mode fallback
1225 GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ;
789ae0cf 1226 }
52c3df99
DS
1227
1228 // the root control level handler
5ca0d812 1229 MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ;
facd6764 1230
9dc1d180
JS
1231 // Causes the inner part of the window not to be metal
1232 // if the style is used before window creation.
1233#if 0 // TARGET_API_MAC_OSX
8ec0a8fa
SC
1234 if ( m_macUsesCompositing && m_macWindow != NULL )
1235 {
1236 if ( GetExtraStyle() & wxFRAME_EX_METAL )
1237 MacSetMetalAppearance( true ) ;
1238 }
1239#endif
52c3df99 1240
73fe67bd 1241 // the frame window event handler
e40298d5 1242 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ;
949cb163 1243 MacInstallTopLevelWindowEventHandler() ;
b19bf058 1244
14c96cf2
SC
1245 DoSetWindowVariant( m_windowVariant ) ;
1246
facd6764 1247 m_macFocus = NULL ;
6a7e6411
RD
1248
1249 if ( HasFlag(wxFRAME_SHAPED) )
1250 {
1251 // default shape matches the window size
52c3df99
DS
1252 wxRegion rgn( 0, 0, w, h );
1253 SetShape( rgn );
6a7e6411 1254 }
3dfafdb9
RD
1255
1256 wxWindowCreateEvent event(this);
1257 GetEventHandler()->ProcessEvent(event);
5f0b2f22
SC
1258}
1259
5d2e69e8 1260void wxTopLevelWindowMac::ClearBackground()
5f0b2f22 1261{
5d2e69e8 1262 wxWindow::ClearBackground() ;
5f0b2f22
SC
1263}
1264
5f0b2f22
SC
1265// Raise the window to the top of the Z order
1266void wxTopLevelWindowMac::Raise()
1267{
7f3c339c 1268 ::SelectWindow( (WindowRef)m_macWindow ) ;
5f0b2f22
SC
1269}
1270
1271// Lower the window to the bottom of the Z order
1272void wxTopLevelWindowMac::Lower()
1273{
76a5e5d2 1274 ::SendBehind( (WindowRef)m_macWindow , NULL ) ;
5f0b2f22
SC
1275}
1276
245f3581
DE
1277void wxTopLevelWindowMac::MacDelayedDeactivation(long timestamp)
1278{
52c3df99 1279 if (s_macDeactivateWindow)
245f3581 1280 {
f02a4ffa
VZ
1281 wxLogTrace(TRACE_ACTIVATE,
1282 wxT("Doing delayed deactivation of %p"),
1283 s_macDeactivateWindow);
52c3df99 1284
245f3581
DE
1285 s_macDeactivateWindow->MacActivate(timestamp, false);
1286 }
1287}
1288
851b3a88 1289void wxTopLevelWindowMac::MacActivate( long timestamp , bool inIsActivating )
5f0b2f22 1290{
f02a4ffa 1291 wxLogTrace(TRACE_ACTIVATE, wxT("TopLevel=%p::MacActivate"), this);
17f8d2a7 1292
52c3df99
DS
1293 if (s_macDeactivateWindow == this)
1294 s_macDeactivateWindow = NULL;
1295
245f3581 1296 MacDelayedDeactivation(timestamp);
8ab50549 1297 MacPropagateHiliteChanged() ;
5f0b2f22
SC
1298}
1299
1300void wxTopLevelWindowMac::SetTitle(const wxString& title)
1301{
fb5246be 1302 wxWindow::SetLabel( title ) ;
16a76184 1303 UMASetWTitle( (WindowRef)m_macWindow , title , m_font.GetEncoding() ) ;
5f0b2f22
SC
1304}
1305
d4bd6c97 1306wxString wxTopLevelWindowMac::GetTitle() const
fb5246be
WS
1307{
1308 return wxWindow::GetLabel();
1309}
1310
5f0b2f22
SC
1311bool wxTopLevelWindowMac::Show(bool show)
1312{
facd6764 1313 if ( !wxTopLevelWindowBase::Show(show) )
902725ee 1314 return false;
5f0b2f22 1315
21e77aa1
DS
1316 bool plainTransition = false;
1317
a979e444 1318#if wxUSE_SYSTEM_OPTIONS
21e77aa1
DS
1319 // code contributed by Ryan Wilcox December 18, 2003
1320 plainTransition = UMAGetSystemVersion() >= 0x1000 ;
1321 if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) )
1322 plainTransition = ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1 ) ;
1323#endif
52c3df99 1324
21e77aa1
DS
1325 if (show)
1326 {
8c8f6a4b 1327 if ( plainTransition )
1f90939c 1328 ::ShowWindow( (WindowRef)m_macWindow );
1f90939c 1329 else
52c3df99 1330 ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL );
52c3df99 1331
1f90939c 1332 ::SelectWindow( (WindowRef)m_macWindow ) ;
52c3df99
DS
1333
1334 // because apps expect a size event to occur at this moment
a979e444 1335 wxSizeEvent event(GetSize() , m_windowId);
1f90939c
SC
1336 event.SetEventObject(this);
1337 GetEventHandler()->ProcessEvent(event);
5f0b2f22
SC
1338 }
1339 else
1340 {
8c8f6a4b 1341 if ( plainTransition )
21e77aa1 1342 ::HideWindow( (WindowRef)m_macWindow );
1f90939c 1343 else
21e77aa1 1344 ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowHideTransitionAction, NULL );
5f0b2f22
SC
1345 }
1346
facd6764 1347 MacPropagateVisibilityChanged() ;
5f0b2f22 1348
902725ee 1349 return true ;
5f0b2f22
SC
1350}
1351
c5985061 1352bool wxTopLevelWindowMac::ShowFullScreen(bool show, long style)
902725ee 1353{
c5985061
SC
1354 if ( show )
1355 {
1356 FullScreenData *data = (FullScreenData *)m_macFullScreenData ;
1357 delete data ;
1358 data = new FullScreenData() ;
902725ee 1359
c5985061
SC
1360 m_macFullScreenData = data ;
1361 data->m_position = GetPosition() ;
1362 data->m_size = GetSize() ;
f3b2e2d7 1363 data->m_wasResizable = MacGetWindowAttributes() & kWindowResizableAttribute ;
902725ee 1364
c5985061 1365 if ( style & wxFULLSCREEN_NOMENUBAR )
52c3df99
DS
1366 HideMenuBar() ;
1367
c5985061
SC
1368 wxRect client = wxGetClientDisplayRect() ;
1369
52c3df99 1370 int left , top , right , bottom ;
c5985061 1371 int x, y, w, h ;
902725ee 1372
c5985061
SC
1373 x = client.x ;
1374 y = client.y ;
1375 w = client.width ;
1376 h = client.height ;
902725ee 1377
c5985061
SC
1378 MacGetContentAreaInset( left , top , right , bottom ) ;
1379
1380 if ( style & wxFULLSCREEN_NOCAPTION )
1381 {
1382 y -= top ;
1383 h += top ;
1384 }
52c3df99 1385
c5985061
SC
1386 if ( style & wxFULLSCREEN_NOBORDER )
1387 {
1388 x -= left ;
1389 w += left + right ;
1390 h += bottom ;
1391 }
52c3df99 1392
c5985061
SC
1393 if ( style & wxFULLSCREEN_NOTOOLBAR )
1394 {
3c86150d
SC
1395 // TODO
1396 }
52c3df99 1397
3c86150d
SC
1398 if ( style & wxFULLSCREEN_NOSTATUSBAR )
1399 {
1400 // TODO
c5985061 1401 }
52c3df99 1402
c5985061 1403 SetSize( x , y , w, h ) ;
172da31f 1404 if ( data->m_wasResizable )
f3b2e2d7 1405 MacChangeWindowAttributes( kWindowNoAttributes , kWindowResizableAttribute ) ;
c5985061
SC
1406 }
1407 else
1408 {
1409 ShowMenuBar() ;
1410 FullScreenData *data = (FullScreenData *) m_macFullScreenData ;
172da31f 1411 if ( data->m_wasResizable )
f3b2e2d7 1412 MacChangeWindowAttributes( kWindowResizableAttribute , kWindowNoAttributes ) ;
c5985061
SC
1413 SetPosition( data->m_position ) ;
1414 SetSize( data->m_size ) ;
52c3df99 1415
c5985061
SC
1416 delete data ;
1417 m_macFullScreenData = NULL ;
1418 }
52c3df99 1419
902725ee 1420 return false;
c5985061
SC
1421}
1422
902725ee
WS
1423bool wxTopLevelWindowMac::IsFullScreen() const
1424{
1425 return m_macFullScreenData != NULL ;
c5985061
SC
1426}
1427
50f3c41d 1428
07880314 1429bool wxTopLevelWindowMac::SetTransparent(wxByte alpha)
50f3c41d 1430{
24fcd264 1431 OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, float(alpha)/255.0);
50f3c41d
RD
1432 return result == noErr;
1433}
1434
1435
07880314 1436bool wxTopLevelWindowMac::CanSetTransparent()
50f3c41d
RD
1437{
1438 return true;
1439}
1440
1441
30c23e74 1442void wxTopLevelWindowMac::SetExtraStyle(long exStyle)
8ec0a8fa
SC
1443{
1444 if ( GetExtraStyle() == exStyle )
1445 return ;
30c23e74 1446
8ec0a8fa 1447 wxTopLevelWindowBase::SetExtraStyle( exStyle ) ;
52c3df99 1448
8ec0a8fa 1449#if TARGET_API_MAC_OSX
f21449ae 1450 if ( m_macWindow != NULL )
8ec0a8fa
SC
1451 {
1452 bool metal = GetExtraStyle() & wxFRAME_EX_METAL ;
1453 if ( MacGetMetalAppearance() != metal )
1454 MacSetMetalAppearance( metal ) ;
1455 }
1456#endif
1457}
1458
30c23e74 1459// TODO: switch to structure bounds -
21e77aa1 1460// we are still using coordinates of the content view
21e77aa1 1461//
29281095
SC
1462void wxTopLevelWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1463{
21e77aa1
DS
1464 Rect content, structure ;
1465
29281095
SC
1466 GetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &structure ) ;
1467 GetWindowBounds( (WindowRef) m_macWindow, kWindowContentRgn , &content ) ;
1468
1469 left = content.left - structure.left ;
1470 top = content.top - structure.top ;
1471 right = structure.right - content.right ;
1472 bottom = structure.bottom - content.bottom ;
1473}
1474
5f0b2f22
SC
1475void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height)
1476{
c9698388 1477 m_cachedClippedRectValid = false ;
facd6764
SC
1478 Rect bounds = { y , x , y + height , x + width } ;
1479 verify_noerr(SetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ;
4817190d 1480 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
5f0b2f22
SC
1481}
1482
facd6764 1483void wxTopLevelWindowMac::DoGetPosition( int *x, int *y ) const
5f0b2f22 1484{
facd6764 1485 Rect bounds ;
52c3df99 1486
facd6764 1487 verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ;
52c3df99
DS
1488
1489 if (x)
1490 *x = bounds.left ;
1491 if (y)
1492 *y = bounds.top ;
facd6764 1493}
52c3df99 1494
facd6764
SC
1495void wxTopLevelWindowMac::DoGetSize( int *width, int *height ) const
1496{
1497 Rect bounds ;
52c3df99 1498
facd6764 1499 verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ;
52c3df99
DS
1500
1501 if (width)
1502 *width = bounds.right - bounds.left ;
1503 if (height)
1504 *height = bounds.bottom - bounds.top ;
facd6764 1505}
1542ea39 1506
facd6764
SC
1507void wxTopLevelWindowMac::DoGetClientSize( int *width, int *height ) const
1508{
1509 Rect bounds ;
52c3df99 1510
facd6764 1511 verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowContentRgn , &bounds )) ;
52c3df99
DS
1512
1513 if (width)
1514 *width = bounds.right - bounds.left ;
1515 if (height)
1516 *height = bounds.bottom - bounds.top ;
facd6764 1517}
1542ea39 1518
902725ee 1519void wxTopLevelWindowMac::MacSetMetalAppearance( bool set )
facd6764
SC
1520{
1521#if TARGET_API_MAC_OSX
902725ee 1522 MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes ,
facd6764
SC
1523 set ? kWindowNoAttributes : kWindowMetalAttribute ) ;
1524#endif
1525}
1542ea39 1526
902725ee 1527bool wxTopLevelWindowMac::MacGetMetalAppearance() const
6aab345b
SC
1528{
1529#if TARGET_API_MAC_OSX
1530 return MacGetWindowAttributes() & kWindowMetalAttribute ;
1531#else
1532 return false ;
1533#endif
1534}
1535
902725ee 1536void wxTopLevelWindowMac::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear )
facd6764 1537{
52c3df99 1538 ChangeWindowAttributes( (WindowRef)m_macWindow, attributesToSet, attributesToClear ) ;
facd6764 1539}
1542ea39 1540
902725ee 1541wxUint32 wxTopLevelWindowMac::MacGetWindowAttributes() const
facd6764
SC
1542{
1543 UInt32 attr = 0 ;
52c3df99
DS
1544 GetWindowAttributes( (WindowRef) m_macWindow, &attr ) ;
1545
facd6764 1546 return attr ;
5f0b2f22 1547}
a07c1212 1548
902725ee 1549void wxTopLevelWindowMac::MacPerformUpdates()
92346151 1550{
92346151 1551#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
f21449ae
SC
1552 // for composited windows this also triggers a redraw of all
1553 // invalid views in the window
1554 if ( UMAGetSystemVersion() >= 0x1030 )
1555 HIWindowFlush((WindowRef) m_macWindow) ;
92346151
SC
1556 else
1557#endif
1558 {
f21449ae
SC
1559 // the only way to trigger the redrawing on earlier systems is to call
1560 // ReceiveNextEvent
902725ee 1561
f21449ae
SC
1562 EventRef currentEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
1563 UInt32 currentEventClass = 0 ;
f21449ae 1564 if ( currentEvent != NULL )
902725ee 1565 {
f21449ae 1566 currentEventClass = ::GetEventClass( currentEvent ) ;
716d0327 1567 ::GetEventKind( currentEvent ) ;
902725ee 1568 }
52c3df99 1569
f21449ae
SC
1570 if ( currentEventClass != kEventClassMenu )
1571 {
1572 // when tracking a menu, strange redraw errors occur if we flush now, so leave..
1573 EventRef theEvent;
716d0327 1574 ReceiveNextEvent( 0 , NULL , kEventDurationNoWait , false , &theEvent ) ;
f21449ae 1575 }
92346151
SC
1576 }
1577}
1578
3feeb1e1
SC
1579// Attracts the users attention to this window if the application is
1580// inactive (should be called when a background event occurs)
1581
1582static pascal void wxMacNMResponse( NMRecPtr ptr )
1583{
1584 NMRemove( ptr ) ;
a979e444 1585 DisposePtr( (Ptr)ptr ) ;
3feeb1e1
SC
1586}
1587
3feeb1e1
SC
1588void wxTopLevelWindowMac::RequestUserAttention(int flags )
1589{
1590 NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ;
52c3df99
DS
1591 static wxMacNMUPP nmupp( wxMacNMResponse );
1592
3feeb1e1
SC
1593 memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ;
1594 notificationRequest->qType = nmType ;
1595 notificationRequest->nmMark = 1 ;
1596 notificationRequest->nmIcon = 0 ;
1597 notificationRequest->nmSound = 0 ;
1598 notificationRequest->nmStr = NULL ;
1599 notificationRequest->nmResp = nmupp ;
52c3df99 1600
3feeb1e1
SC
1601 verify_noerr( NMInstall( notificationRequest ) ) ;
1602}
1603
facd6764
SC
1604// ---------------------------------------------------------------------------
1605// Shape implementation
1606// ---------------------------------------------------------------------------
1607
6a7e6411 1608
1542ea39
RD
1609bool wxTopLevelWindowMac::SetShape(const wxRegion& region)
1610{
902725ee 1611 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false,
6a7e6411
RD
1612 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1613
a979e444
DS
1614 // The empty region signifies that the shape
1615 // should be removed from the window.
6a7e6411
RD
1616 if ( region.IsEmpty() )
1617 {
1618 wxSize sz = GetClientSize();
1619 wxRegion rgn(0, 0, sz.x, sz.y);
3c393c0a
SC
1620 if ( rgn.IsEmpty() )
1621 return false ;
1622 else
1623 return SetShape(rgn);
6a7e6411
RD
1624 }
1625
1626 // Make a copy of the region
1627 RgnHandle shapeRegion = NewRgn();
1628 CopyRgn( (RgnHandle)region.GetWXHRGN(), shapeRegion );
1629
1630 // Dispose of any shape region we may already have
1631 RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef)MacGetWindowRef() );
1632 if ( oldRgn )
1633 DisposeRgn(oldRgn);
1634
1635 // Save the region so we can use it later
7cd7bc23 1636 SetWRefCon((WindowRef)MacGetWindowRef(), (URefCon)shapeRegion);
6a7e6411 1637
52c3df99 1638 // inform the window manager that the window has changed shape
6a7e6411 1639 ReshapeCustomWindow((WindowRef)MacGetWindowRef());
52c3df99 1640
902725ee 1641 return true;
6a7e6411
RD
1642}
1643
6a7e6411
RD
1644// ---------------------------------------------------------------------------
1645// Support functions for shaped windows, based on Apple's CustomWindow sample at
1646// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm
1647// ---------------------------------------------------------------------------
1648
6a7e6411
RD
1649static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect)
1650{
1651 GetWindowPortBounds(window, inRect);
7cd7bc23
SC
1652 Point pt = { inRect->top ,inRect->left };
1653 wxMacLocalToGlobal( window, &pt ) ;
1654 inRect->bottom += pt.v - inRect->top;
1655 inRect->right += pt.h - inRect->left;
6a7e6411
RD
1656 inRect->top = pt.v;
1657 inRect->left = pt.h;
6a7e6411
RD
1658}
1659
6a7e6411
RD
1660static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param)
1661{
1662 /*------------------------------------------------------
1663 Define which options your custom window supports.
1664 --------------------------------------------------------*/
1665 //just enable everything for our demo
52c3df99
DS
1666 *(OptionBits*)param =
1667 //kWindowCanGrow |
1668 //kWindowCanZoom |
1669 //kWindowCanCollapse |
1670 //kWindowCanGetWindowRegion |
1671 //kWindowHasTitleBar |
1672 //kWindowSupportsDragHilite |
1673 kWindowCanDrawInCurrentPort |
1674 //kWindowCanMeasureTitle |
1675 kWindowWantsDisposeAtProcessDeath |
1676 kWindowSupportsGetGrowImageRegion |
1677 kWindowDefSupportsColorGrafPort;
1678
6a7e6411 1679 return 1;
1542ea39 1680}
6a7e6411
RD
1681
1682// The content region is left as a rectangle matching the window size, this is
1683// so the origin in the paint event, and etc. still matches what the
1684// programmer expects.
1685static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn)
1686{
1687 SetEmptyRgn(rgn);
1688 wxTopLevelWindowMac* win = wxFindWinFromMacWindow(window);
1689 if (win)
1690 {
b19bf058 1691 Rect r ;
52c3df99 1692 wxShapedMacWindowGetPos( window, &r ) ;
b19bf058 1693 RectRgn( rgn , &r ) ;
6a7e6411
RD
1694 }
1695}
1696
1697// The structure region is set to the shape given to the SetShape method.
1698static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn)
1699{
1700 RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window);
1701
1702 SetEmptyRgn(rgn);
1703 if (cachedRegion)
1704 {
1705 Rect windowRect;
902725ee
WS
1706 wxShapedMacWindowGetPos(window, &windowRect); // how big is the window
1707 CopyRgn(cachedRegion, rgn); // make a copy of our cached region
6a7e6411 1708 OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window
902725ee 1709 //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size
6a7e6411
RD
1710 }
1711}
1712
6a7e6411
RD
1713static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param)
1714{
52c3df99
DS
1715 GetWindowRegionPtr rgnRec = (GetWindowRegionPtr)param;
1716
1717 if (rgnRec == NULL)
1718 return paramErr;
6a7e6411 1719
52c3df99 1720 switch (rgnRec->regionCode)
6a7e6411
RD
1721 {
1722 case kWindowStructureRgn:
1723 wxShapedMacWindowStructureRegion(window, rgnRec->winRgn);
1724 break;
52c3df99 1725
6a7e6411
RD
1726 case kWindowContentRgn:
1727 wxShapedMacWindowContentRegion(window, rgnRec->winRgn);
1728 break;
52c3df99 1729
6a7e6411
RD
1730 default:
1731 SetEmptyRgn(rgnRec->winRgn);
52c3df99
DS
1732 break;
1733 }
6a7e6411
RD
1734
1735 return noErr;
1736}
1737
52c3df99
DS
1738// Determine the region of the window which was hit
1739//
1740static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param)
6a7e6411 1741{
6a7e6411 1742 Point hitPoint;
52c3df99 1743 static RgnHandle tempRgn = NULL;
6a7e6411 1744
52c3df99
DS
1745 if (tempRgn == NULL)
1746 tempRgn = NewRgn();
6a7e6411 1747
52c3df99
DS
1748 // get the point clicked
1749 SetPt( &hitPoint, LoWord(param), HiWord(param) );
6a7e6411 1750
52c3df99 1751 // Mac OS 8.5 or later
6a7e6411 1752 wxShapedMacWindowStructureRegion(window, tempRgn);
52c3df99 1753 if (PtInRgn( hitPoint, tempRgn )) //in window content region?
6a7e6411
RD
1754 return wInContent;
1755
52c3df99
DS
1756 // no significant area was hit
1757 return wNoHit;
6a7e6411
RD
1758}
1759
6a7e6411
RD
1760static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param)
1761{
52c3df99 1762 switch (message)
6a7e6411
RD
1763 {
1764 case kWindowMsgHitTest:
52c3df99 1765 return wxShapedMacWindowHitTest(window, param);
6a7e6411
RD
1766
1767 case kWindowMsgGetFeatures:
52c3df99 1768 return wxShapedMacWindowGetFeatures(window, param);
6a7e6411
RD
1769
1770 // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow
1771 case kWindowMsgGetRegion:
52c3df99
DS
1772 return wxShapedMacWindowGetRegion(window, param);
1773
1774 default:
1775 break;
6a7e6411
RD
1776 }
1777
1778 return 0;
1779}