]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/toplevel.cpp
synching down and up events for the synthetic right mouse handling
[wxWidgets.git] / src / mac / carbon / toplevel.cpp
CommitLineData
a15eb0a5
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: mac/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
20#ifdef __GNUG__
21 #pragma implementation "toplevel.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/toplevel.h"
422644a3 34 #include "wx/frame.h"
a15eb0a5
SC
35 #include "wx/string.h"
36 #include "wx/log.h"
37 #include "wx/intl.h"
37ec2bd3 38 #include "wx/settings.h"
a15eb0a5
SC
39#endif //WX_PRECOMP
40
5f0b2f22 41#include "wx/mac/uma.h"
422644a3 42#include "wx/mac/aga.h"
7c091673 43#include "wx/app.h"
5f0b2f22 44#include "wx/tooltip.h"
a07c1212 45#include "wx/dnd.h"
1f90939c
SC
46#if wxUSE_SYSTEM_OPTIONS
47 #include "wx/sysopt.h"
48#endif
5f0b2f22 49
7f0c3a63 50#include <ToolUtils.h>
dd49c691 51
a15eb0a5
SC
52// ----------------------------------------------------------------------------
53// globals
54// ----------------------------------------------------------------------------
55
56// list of all frames and modeless dialogs
32b5be3d
RR
57wxWindowList wxModelessWindows;
58
6a7e6411
RD
59static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param);
60
a15eb0a5
SC
61// ============================================================================
62// wxTopLevelWindowMac implementation
63// ============================================================================
64
facd6764
SC
65BEGIN_EVENT_TABLE(wxTopLevelWindowMac, wxTopLevelWindowBase)
66END_EVENT_TABLE()
67
68
851b3a88
SC
69// ---------------------------------------------------------------------------
70// Carbon Events
71// ---------------------------------------------------------------------------
72
851b3a88
SC
73extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
74
1542ea39 75static const EventTypeSpec eventList[] =
851b3a88 76{
facd6764 77 // TODO remove control related event like key and mouse (except for WindowLeave events)
949cb163 78#if 1
851b3a88 79 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
c5c9378c 80
e40298d5 81 { kEventClassKeyboard, kEventRawKeyDown } ,
c5c9378c
SC
82 { kEventClassKeyboard, kEventRawKeyRepeat } ,
83 { kEventClassKeyboard, kEventRawKeyUp } ,
84 { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
facd6764 85#endif
c5c9378c 86
16a76184 87 { kEventClassWindow , kEventWindowShown } ,
851b3a88
SC
88 { kEventClassWindow , kEventWindowActivated } ,
89 { kEventClassWindow , kEventWindowDeactivated } ,
90 { kEventClassWindow , kEventWindowBoundsChanging } ,
91 { kEventClassWindow , kEventWindowBoundsChanged } ,
92 { kEventClassWindow , kEventWindowClose } ,
93
facd6764
SC
94 // we have to catch these events on the toplevel window level, as controls don't get the
95 // raw mouse events anymore
96
851b3a88
SC
97 { kEventClassMouse , kEventMouseDown } ,
98 { kEventClassMouse , kEventMouseUp } ,
de127c69 99 { kEventClassMouse , kEventMouseWheelMoved } ,
851b3a88
SC
100 { kEventClassMouse , kEventMouseMoved } ,
101 { kEventClassMouse , kEventMouseDragged } ,
851b3a88
SC
102} ;
103
104static pascal OSStatus TextInputEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
105{
106 OSStatus result = eventNotHandledErr ;
851b3a88 107
c5c9378c 108 wxWindow* focus = wxWindow::FindFocus() ;
e40298d5 109 char charCode ;
1542ea39 110 UInt32 keyCode ;
c5c9378c 111 UInt32 modifiers ;
e40298d5 112 Point point ;
c5c9378c
SC
113
114 EventRef rawEvent ;
1542ea39 115
c5c9378c 116 GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
1542ea39 117
e40298d5
JS
118 GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
119 GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
120 GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
121 GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL,
122 sizeof( Point ), NULL, &point );
123
e40298d5
JS
124 switch ( GetEventKind( event ) )
125 {
126 case kEventTextInputUnicodeForKeyEvent :
ace07c80 127 // this is only called when no default handler has jumped in, eg a wxControl on a floater window does not
5d2e69e8 128 // get its own kEventTextInputUnicodeForKeyEvent, so we route back the
ace07c80
SC
129 wxControl* control = wxDynamicCast( focus , wxControl ) ;
130 if ( control )
131 {
facd6764 132 ControlRef macControl = (ControlRef) control->GetHandle() ;
ace07c80
SC
133 if ( macControl )
134 {
135 ::HandleControlKey( macControl , keyCode , charCode , modifiers ) ;
136 result = noErr ;
137 }
138 }
139 /*
140 // this may lead to double events sent to a window in case all handlers have skipped the key down event
77a4354e
VZ
141 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
142 UInt32 message = (keyCode << 8) + charCode;
143
1542ea39 144 if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
e40298d5
JS
145 focus , message , modifiers , when , point.h , point.v ) )
146 {
147 result = noErr ;
148 }
ace07c80 149 */
e40298d5
JS
150 break ;
151 }
c5c9378c
SC
152
153 return result ;
154}
155
156static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
157{
158 OSStatus result = eventNotHandledErr ;
159
160 wxWindow* focus = wxWindow::FindFocus() ;
92a7272f
SC
161 if ( focus == NULL )
162 return result ;
163
e40298d5 164 char charCode ;
1542ea39 165 UInt32 keyCode ;
c5c9378c 166 UInt32 modifiers ;
e40298d5
JS
167 Point point ;
168 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
169
170 GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
171 GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
172 GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
173 GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
174 sizeof( Point ), NULL, &point );
175
176 UInt32 message = (keyCode << 8) + charCode;
177 switch( GetEventKind( event ) )
178 {
179 case kEventRawKeyRepeat :
180 case kEventRawKeyDown :
e40298d5 181 {
404f1d80
SC
182 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
183 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
184 wxTheApp->MacSetCurrentEvent( event , handler ) ;
185 if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
186 focus , message , modifiers , when , point.h , point.v ) )
187 {
188 result = noErr ;
189 }
190 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
e40298d5
JS
191 }
192 break ;
193 case kEventRawKeyUp :
1542ea39 194 if ( (focus != NULL) && wxTheApp->MacSendKeyUpEvent(
e40298d5
JS
195 focus , message , modifiers , when , point.h , point.v ) )
196 {
197 result = noErr ;
198 }
199 break ;
200 case kEventRawKeyModifiersChanged :
201 {
202 wxKeyEvent event(wxEVT_KEY_DOWN);
203
204 event.m_shiftDown = modifiers & shiftKey;
205 event.m_controlDown = modifiers & controlKey;
206 event.m_altDown = modifiers & optionKey;
207 event.m_metaDown = modifiers & cmdKey;
208
209 event.m_x = point.h;
210 event.m_y = point.v;
211 event.m_timeStamp = when;
212 wxWindow* focus = wxWindow::FindFocus() ;
213 event.SetEventObject(focus);
214
8d60dc8a 215 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & controlKey )
e40298d5
JS
216 {
217 event.m_keyCode = WXK_CONTROL ;
218 event.SetEventType( ( modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
219 focus->GetEventHandler()->ProcessEvent( event ) ;
220 }
8d60dc8a 221 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & shiftKey )
e40298d5
JS
222 {
223 event.m_keyCode = WXK_SHIFT ;
224 event.SetEventType( ( modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
225 focus->GetEventHandler()->ProcessEvent( event ) ;
226 }
8d60dc8a 227 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & optionKey )
e40298d5
JS
228 {
229 event.m_keyCode = WXK_ALT ;
230 event.SetEventType( ( modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
231 focus->GetEventHandler()->ProcessEvent( event ) ;
232 }
b7aec135
SC
233 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & cmdKey )
234 {
235 event.m_keyCode = WXK_COMMAND ;
236 event.SetEventType( ( modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
237 focus->GetEventHandler()->ProcessEvent( event ) ;
238 }
e40298d5
JS
239 wxTheApp->s_lastModifiers = modifiers ;
240 }
241 break ;
242 }
851b3a88
SC
243
244 return result ;
245}
246
facd6764
SC
247// we don't interfere with foreign controls on our toplevel windows, therefore we always give back eventNotHandledErr
248// for windows that we didn't create (like eg Scrollbars in a databrowser) , or for controls where we did not handle the
249// mouse down at all
851b3a88 250
facd6764 251// This handler can also be called from app level where data (ie target window) may be null or a non wx window
1542ea39 252
facd6764 253wxWindow* g_MacLastWindow = NULL ;
a3195b73 254
86a9144f
SC
255static EventMouseButton lastButton = 0 ;
256
facd6764
SC
257static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent )
258{
259 UInt32 modifiers = cEvent.GetParameter<UInt32>(kEventParamKeyModifiers, typeUInt32) ;
260 Point screenMouseLocation = cEvent.GetParameter<Point>(kEventParamMouseLocation) ;
67245665 261
facd6764
SC
262 // this parameter are not given for all events
263 EventMouseButton button = 0 ;
264 UInt32 clickCount = 0 ;
265 cEvent.GetParameter<EventMouseButton>(kEventParamMouseButton, typeMouseButton , &button) ;
266 cEvent.GetParameter<UInt32>(kEventParamClickCount, typeUInt32 , &clickCount ) ;
267
268 wxevent.m_x = screenMouseLocation.h;
269 wxevent.m_y = screenMouseLocation.v;
270 wxevent.m_shiftDown = modifiers & shiftKey;
271 wxevent.m_controlDown = modifiers & controlKey;
272 wxevent.m_altDown = modifiers & optionKey;
273 wxevent.m_metaDown = modifiers & cmdKey;
274 wxevent.SetTimestamp( cEvent.GetTicks() ) ;
275 // a control click is interpreted as a right click
276 if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) )
851b3a88 277 {
facd6764
SC
278 button = kEventMouseButtonSecondary ;
279 }
86a9144f
SC
280
281 // we must make sure that our synthetic 'right' button corresponds in
282 // mouse down, moved and mouse up, and does not deliver a right down and left up
283
284 if ( cEvent.GetKind() == kEventMouseDown )
285 lastButton = button ;
286 else if ( lastButton )
287 button = lastButton ;
facd6764
SC
288
289 // determinate the correct down state, wx does not want a 'down' for a mouseUp event, while mac delivers
290 // this button
291 if ( button != 0 && cEvent.GetKind() != kEventMouseUp )
292 {
293 switch( button )
e40298d5 294 {
facd6764
SC
295 case kEventMouseButtonPrimary :
296 wxevent.m_leftDown = true ;
e40298d5 297 break ;
facd6764
SC
298 case kEventMouseButtonSecondary :
299 wxevent.m_rightDown = true ;
e40298d5 300 break ;
facd6764
SC
301 case kEventMouseButtonTertiary :
302 wxevent.m_middleDown = true ;
e40298d5 303 break ;
facd6764
SC
304 }
305 }
306 // determinate the correct click button
307 if ( button == kEventMouseButtonSecondary )
308 {
309 if (cEvent.GetKind() == kEventMouseDown )
92a7272f 310 wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ;
facd6764
SC
311 else if ( cEvent.GetKind() == kEventMouseUp )
312 wxevent.SetEventType(wxEVT_RIGHT_UP ) ;
313 }
314 else if ( button == kEventMouseButtonTertiary )
315 {
316 if (cEvent.GetKind() == kEventMouseDown )
317 wxevent.SetEventType(clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ;
318 else if ( cEvent.GetKind() == kEventMouseUp )
319 wxevent.SetEventType(wxEVT_MIDDLE_UP ) ;
320 }
321 else
322 {
323 if (cEvent.GetKind() == kEventMouseDown )
324 wxevent.SetEventType(clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ;
325 else if ( cEvent.GetKind() == kEventMouseUp )
326 wxevent.SetEventType(wxEVT_LEFT_UP ) ;
327 else if ( cEvent.GetKind() == kEventMouseWheelMoved )
328 {
329 wxevent.SetEventType(wxEVT_MOUSEWHEEL ) ;
330
331 // EventMouseWheelAxis axis = cEvent.GetParameter<EventMouseWheelAxis>(kEventParamMouseWheelAxis, typeMouseWheelAxis) ;
332 SInt32 delta = cEvent.GetParameter<SInt32>(kEventParamMouseWheelDelta, typeLongInteger) ;
333
334 wxevent.m_wheelRotation = delta;
335 wxevent.m_wheelDelta = 1;
336 wxevent.m_linesPerAction = 1;
337 }
338 else
339 wxevent.SetEventType(wxEVT_MOTION ) ;
340 }
86a9144f
SC
341 if ( cEvent.GetKind() == kEventMouseUp )
342 lastButton = 0 ;
facd6764
SC
343}
344
345ControlRef wxMacFindSubControl( Point location , ControlRef superControl , ControlPartCode *outPart )
346{
347 if ( superControl )
348 {
349 UInt16 childrenCount = 0 ;
350 OSStatus err = CountSubControls( superControl , &childrenCount ) ;
351 if ( err == errControlIsNotEmbedder )
352 return NULL ;
353 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
354
355 for ( UInt16 i = childrenCount ; i >=1 ; --i )
356 {
357 ControlHandle sibling ;
358 err = GetIndexedSubControl( superControl , i , & sibling ) ;
359 if ( err == errControlIsNotEmbedder )
360 return NULL ;
361
362 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
363 if ( IsControlVisible( sibling ) )
364 {
365 Rect r ;
d6fd667b 366 UMAGetControlBoundsInWindowCoords( sibling , &r ) ;
facd6764 367 if ( MacPtInRect( location , &r ) )
de127c69 368 {
facd6764
SC
369 ControlHandle child = wxMacFindSubControl( location , sibling , outPart ) ;
370 if ( child )
371 return child ;
372 else
de127c69 373 {
d6fd667b
SC
374 Point testLocation = location ;
375#if TARGET_API_MAC_OSX
376 testLocation.h -= r.left ;
377 testLocation.v -= r.top ;
378#endif
379 *outPart = TestControl( sibling , testLocation ) ;
facd6764 380 return sibling ;
de127c69
GD
381 }
382 }
facd6764 383 }
e40298d5
JS
384 }
385 }
facd6764
SC
386 return NULL ;
387}
1542ea39 388
facd6764
SC
389ControlRef wxMacFindControlUnderMouse( Point location , WindowRef window , ControlPartCode *outPart )
390{
391#if TARGET_API_MAC_OSX
7741dfb1 392 if ( UMAGetSystemVersion() >= 0x1030 )
30e0b1c9
SC
393 return FindControlUnderMouse( location , window , outPart ) ;
394#endif
facd6764
SC
395 ControlRef rootControl = NULL ;
396 verify_noerr( GetRootControl( window , &rootControl ) ) ;
397 return wxMacFindSubControl( location , rootControl , outPart ) ;
30e0b1c9 398
facd6764
SC
399}
400pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
401{
402
403 OSStatus result = eventNotHandledErr ;
404
405 wxMacCarbonEvent cEvent( event ) ;
406
407 Point screenMouseLocation = cEvent.GetParameter<Point>(kEventParamMouseLocation) ;
408 Point windowMouseLocation = screenMouseLocation ;
409
410 WindowRef window ;
411 short windowPart = ::FindWindow(screenMouseLocation, &window);
412
413 wxWindow* currentMouseWindow = NULL ;
7741dfb1 414
facd6764
SC
415 if ( window )
416 {
d6fd667b 417 QDGlobalToLocalPoint( UMAGetWindowPort(window ) , &windowMouseLocation ) ;
facd6764
SC
418
419 if ( wxTheApp->s_captureWindow && wxTheApp->s_captureWindow->MacGetTopLevelWindowRef() == (WXWindow) window && windowPart == inContent )
420 {
421 currentMouseWindow = wxTheApp->s_captureWindow ;
422 }
423 else if ( (IsWindowActive(window) && windowPart == inContent) )
424 {
425 ControlPartCode part ;
426 ControlRef control = wxMacFindControlUnderMouse( windowMouseLocation , window , &part ) ;
b19bf058
SC
427 if ( control == 0 )
428 currentMouseWindow = (wxWindow*) data ;
429 else
430 currentMouseWindow = wxFindControlFromMacControl( control ) ;
facd6764
SC
431 }
432 }
433
434 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
435 SetupMouseEvent( wxevent , cEvent ) ;
436
437 // handle all enter / leave events
438
439 if ( currentMouseWindow != g_MacLastWindow )
440 {
441 if ( g_MacLastWindow )
442 {
443 wxMouseEvent eventleave(wxevent);
444 eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
445 g_MacLastWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
446 eventleave.SetEventObject( g_MacLastWindow ) ;
447
448#if wxUSE_TOOLTIPS
449 wxToolTip::RelayEvent( g_MacLastWindow , eventleave);
450#endif // wxUSE_TOOLTIPS
451 g_MacLastWindow->GetEventHandler()->ProcessEvent(eventleave);
452 }
453 if ( currentMouseWindow )
454 {
455 wxMouseEvent evententer(wxevent);
456 evententer.SetEventType( wxEVT_ENTER_WINDOW );
457 currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
458 evententer.SetEventObject( currentMouseWindow ) ;
459#if wxUSE_TOOLTIPS
460 wxToolTip::RelayEvent( currentMouseWindow , evententer);
461#endif // wxUSE_TOOLTIPS
462 currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
463 }
464 g_MacLastWindow = currentMouseWindow ;
465 }
466
467 if ( windowPart == inMenuBar )
468 {
469 // special case menu bar, as we are having a low-level runloop we must do it ourselves
470 if ( cEvent.GetKind() == kEventMouseDown )
471 {
472 ::MenuSelect( screenMouseLocation ) ;
473 result = noErr ;
474 }
475 } // if ( windowPart == inMenuBar )
476 else if ( currentMouseWindow )
477 {
478 currentMouseWindow->ScreenToClient( &wxevent.m_x , &wxevent.m_y ) ;
479
480 wxevent.SetEventObject( currentMouseWindow ) ;
481
482 // update cursor
483
484 wxWindow* cursorTarget = currentMouseWindow ;
485 wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
486
487 while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
488 {
489 cursorTarget = cursorTarget->GetParent() ;
490 if ( cursorTarget )
491 cursorPoint += cursorTarget->GetPosition() ;
492 }
1542ea39 493
facd6764 494 // update focus
851b3a88 495
facd6764
SC
496 if ( wxevent.GetEventType() == wxEVT_LEFT_DOWN )
497 {
498 // set focus to this window
499 if (currentMouseWindow->AcceptsFocus() && wxWindow::FindFocus()!=currentMouseWindow)
500 currentMouseWindow->SetFocus();
501 }
502
503 // make tooltips current
504
505 #if wxUSE_TOOLTIPS
506 if ( wxevent.GetEventType() == wxEVT_MOTION
507 || wxevent.GetEventType() == wxEVT_ENTER_WINDOW
508 || wxevent.GetEventType() == wxEVT_LEAVE_WINDOW )
509 wxToolTip::RelayEvent( currentMouseWindow , wxevent);
510 #endif // wxUSE_TOOLTIPS
511 if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) )
512 result = noErr;
30e0b1c9
SC
513 else
514 {
515 ControlPartCode dummyPart ;
516 // if built-in find control is finding the wrong control (ie static box instead of overlaid
517 // button, we cannot let the standard handler do its job, but must handle manually
518
519 if ( ( cEvent.GetKind() == kEventMouseDown ) &&
520 (FindControlUnderMouse(windowMouseLocation , window , &dummyPart) !=
521 wxMacFindControlUnderMouse( windowMouseLocation , window , &dummyPart ) ) )
522 {
523 EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
3a9dc061
SC
524 Point clickLocation = windowMouseLocation ;
525#if TARGET_API_MAC_OSX
526 currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
527#endif
528 HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
30e0b1c9
SC
529 modifiers , (ControlActionUPP ) -1 ) ;
530 result = noErr ;
531 }
532 }
facd6764
SC
533 if ( cEvent.GetKind() == kEventMouseUp && wxTheApp->s_captureWindow )
534 {
535 wxTheApp->s_captureWindow = NULL ;
536 // update cursor ?
537 }
538 } // else if ( currentMouseWindow )
539 return result ;
851b3a88 540}
facd6764
SC
541
542static pascal OSStatus wxMacTopLevelWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
851b3a88
SC
543{
544 OSStatus result = eventNotHandledErr ;
851b3a88 545
facd6764
SC
546 wxMacCarbonEvent cEvent( event ) ;
547
548 // WindowRef windowRef = cEvent.GetParameter<WindowRef>(kEventParamDirectObject) ;
e40298d5 549 wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
1542ea39 550
e40298d5
JS
551 switch( GetEventKind( event ) )
552 {
e40298d5 553 case kEventWindowActivated :
facd6764
SC
554 {
555 toplevelWindow->MacActivate( cEvent.GetTicks() , true) ;
facd6764
SC
556 wxActivateEvent wxevent(wxEVT_ACTIVATE, true , toplevelWindow->GetId());
557 wxevent.SetTimestamp( cEvent.GetTicks() ) ;
558 wxevent.SetEventObject(toplevelWindow);
559 toplevelWindow->GetEventHandler()->ProcessEvent(wxevent);
73fe67bd 560 // we still sending an eventNotHandledErr in order to allow for default processing
e40298d5 561 break ;
facd6764 562 }
e40298d5 563 case kEventWindowDeactivated :
facd6764
SC
564 {
565 toplevelWindow->MacActivate(cEvent.GetTicks() , false) ;
566 wxActivateEvent wxevent(wxEVT_ACTIVATE, false , toplevelWindow->GetId());
567 wxevent.SetTimestamp( cEvent.GetTicks() ) ;
568 wxevent.SetEventObject(toplevelWindow);
569 toplevelWindow->GetEventHandler()->ProcessEvent(wxevent);
73fe67bd 570 // we still sending an eventNotHandledErr in order to allow for default processing
e40298d5 571 break ;
facd6764 572 }
16a76184
SC
573 case kEventWindowShown :
574 toplevelWindow->Refresh() ;
575 result = noErr ;
576 break ;
e40298d5
JS
577 case kEventWindowClose :
578 toplevelWindow->Close() ;
579 result = noErr ;
580 break ;
581 case kEventWindowBoundsChanged :
facd6764
SC
582 {
583 UInt32 attributes = cEvent.GetParameter<UInt32>(kEventParamAttributes,typeUInt32) ;
584 Rect newRect = cEvent.GetParameter<Rect>(kEventParamCurrentBounds) ;
585 wxRect r( newRect.left , newRect.top , newRect.right - newRect.left , newRect.bottom - newRect.top ) ;
586 if ( attributes & kWindowBoundsChangeSizeChanged )
e40298d5 587 {
facd6764
SC
588 // according to the other ports we handle this within the OS level
589 // resize event, not within a wxSizeEvent
590 wxFrame *frame = wxDynamicCast( toplevelWindow , wxFrame ) ;
591 if ( frame )
592 {
593 #if wxUSE_STATUSBAR
594 frame->PositionStatusBar();
595 #endif
596 #if wxUSE_TOOLBAR
597 frame->PositionToolBar();
598 #endif
599 }
1542ea39 600
facd6764
SC
601 wxSizeEvent event( r.GetSize() , toplevelWindow->GetId() ) ;
602 event.SetEventObject( toplevelWindow ) ;
851b3a88 603
facd6764 604 toplevelWindow->GetEventHandler()->ProcessEvent(event) ;
e40298d5 605 }
facd6764
SC
606 if ( attributes & kWindowBoundsChangeOriginChanged )
607 {
608 wxMoveEvent event( r.GetLeftTop() , toplevelWindow->GetId() ) ;
609 event.SetEventObject( toplevelWindow ) ;
610 toplevelWindow->GetEventHandler()->ProcessEvent(event) ;
611 }
612 result = noErr ;
e40298d5 613 break ;
facd6764 614 }
f81bfef9 615 case kEventWindowBoundsChanging :
facd6764
SC
616 {
617 UInt32 attributes = cEvent.GetParameter<UInt32>(kEventParamAttributes,typeUInt32) ;
618 Rect newRect = cEvent.GetParameter<Rect>(kEventParamCurrentBounds) ;
83901ec2 619
facd6764
SC
620 if ( (attributes & kWindowBoundsChangeSizeChanged) || (attributes & kWindowBoundsChangeOriginChanged) )
621 {
29281095
SC
622 // all (Mac) rects are in content area coordinates, all wxRects in structure coordinates
623 int left , top , right , bottom ;
624 toplevelWindow->MacGetContentAreaInset( left , top , right , bottom ) ;
625 wxRect r( newRect.left - left , newRect.top - top ,
626 newRect.right - newRect.left + left + right , newRect.bottom - newRect.top + top + bottom ) ;
facd6764
SC
627 // this is a EVT_SIZING not a EVT_SIZE type !
628 wxSizeEvent wxevent( r , toplevelWindow->GetId() ) ;
629 wxevent.SetEventObject( toplevelWindow ) ;
630 wxRect adjustR = r ;
631 if ( toplevelWindow->GetEventHandler()->ProcessEvent(wxevent) )
facd6764 632 adjustR = wxevent.GetRect() ;
29281095 633
facd6764
SC
634 if ( toplevelWindow->GetMaxWidth() != -1 && adjustR.GetWidth() > toplevelWindow->GetMaxWidth() )
635 adjustR.SetWidth( toplevelWindow->GetMaxWidth() ) ;
2c25bd55 636 if ( toplevelWindow->GetMaxHeight() != -1 && adjustR.GetHeight() > toplevelWindow->GetMaxHeight() )
facd6764
SC
637 adjustR.SetHeight( toplevelWindow->GetMaxHeight() ) ;
638 if ( toplevelWindow->GetMinWidth() != -1 && adjustR.GetWidth() < toplevelWindow->GetMinWidth() )
639 adjustR.SetWidth( toplevelWindow->GetMinWidth() ) ;
2c25bd55 640 if ( toplevelWindow->GetMinHeight() != -1 && adjustR.GetHeight() < toplevelWindow->GetMinHeight() )
facd6764 641 adjustR.SetHeight( toplevelWindow->GetMinHeight() ) ;
4a5f2351 642 const Rect adjustedRect = { adjustR.y + top , adjustR.x + left , adjustR.y + adjustR.height - bottom , adjustR.x + adjustR.width - right } ;
facd6764 643 if ( !EqualRect( &newRect , &adjustedRect ) )
1f919f38 644 cEvent.SetParameter<Rect>( kEventParamCurrentBounds , &adjustedRect ) ;
f81bfef9 645 }
facd6764
SC
646
647 result = noErr ;
f81bfef9 648 break ;
facd6764 649 }
e40298d5
JS
650 default :
651 break ;
652 }
653 return result ;
851b3a88
SC
654}
655
facd6764 656pascal OSStatus wxMacTopLevelEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
851b3a88
SC
657{
658 OSStatus result = eventNotHandledErr ;
659
660 switch ( GetEventClass( event ) )
661 {
c5c9378c 662 case kEventClassKeyboard :
e40298d5 663 result = KeyboardEventHandler( handler, event , data ) ;
c5c9378c 664 break ;
851b3a88 665 case kEventClassTextInput :
e40298d5 666 result = TextInputEventHandler( handler, event , data ) ;
851b3a88
SC
667 break ;
668 case kEventClassWindow :
facd6764 669 result = wxMacTopLevelWindowEventHandler( handler, event , data ) ;
e40298d5 670 break ;
851b3a88 671 case kEventClassMouse :
facd6764 672 result = wxMacTopLevelMouseEventHandler( handler, event , data ) ;
e40298d5 673 break ;
851b3a88
SC
674 default :
675 break ;
676 }
677 return result ;
678}
679
facd6764 680DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTopLevelEventHandler )
851b3a88 681
5f0b2f22
SC
682// ---------------------------------------------------------------------------
683// wxWindowMac utility functions
684// ---------------------------------------------------------------------------
685
686// Find an item given the Macintosh Window Reference
687
facd6764
SC
688wxList wxWinMacWindowList(wxKEY_INTEGER);
689wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
5f0b2f22 690{
facd6764 691 wxNode *node = wxWinMacWindowList.Find((long)inWindowRef);
5f0b2f22
SC
692 if (!node)
693 return NULL;
eb22f2a6 694 return (wxTopLevelWindowMac *)node->GetData();
5f0b2f22
SC
695}
696
facd6764
SC
697void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win) ;
698void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win)
5f0b2f22
SC
699{
700 // adding NULL WindowRef is (first) surely a result of an error and
701 // (secondly) breaks menu command processing
427ff662 702 wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
5f0b2f22 703
facd6764
SC
704 if ( !wxWinMacWindowList.Find((long)inWindowRef) )
705 wxWinMacWindowList.Append((long)inWindowRef, win);
5f0b2f22
SC
706}
707
facd6764 708void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win) ;
5f0b2f22
SC
709void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
710{
facd6764 711 wxWinMacWindowList.DeleteObject(win);
5f0b2f22
SC
712}
713
714
a15eb0a5
SC
715// ----------------------------------------------------------------------------
716// wxTopLevelWindowMac creation
717// ----------------------------------------------------------------------------
718
245f3581 719wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL;
5f0b2f22 720
a15eb0a5
SC
721void wxTopLevelWindowMac::Init()
722{
723 m_iconized =
724 m_maximizeOnShow = FALSE;
6a17ca35 725 m_macWindow = NULL ;
facd6764
SC
726#if TARGET_API_MAC_OSX
727 m_macUsesCompositing = TRUE;
728#else
729 m_macUsesCompositing = FALSE;
730#endif
7c091673 731 m_macEventHandler = NULL ;
a15eb0a5
SC
732}
733
118f012e
SC
734class wxMacDeferredWindowDeleter : public wxObject
735{
736public :
1542ea39
RD
737 wxMacDeferredWindowDeleter( WindowRef windowRef )
738 {
739 m_macWindow = windowRef ;
118f012e 740 }
1542ea39
RD
741 virtual ~wxMacDeferredWindowDeleter()
742 {
743 UMADisposeWindow( (WindowRef) m_macWindow ) ;
118f012e
SC
744 }
745 protected :
746 WindowRef m_macWindow ;
747} ;
748
a15eb0a5
SC
749bool wxTopLevelWindowMac::Create(wxWindow *parent,
750 wxWindowID id,
751 const wxString& title,
752 const wxPoint& pos,
753 const wxSize& size,
754 long style,
755 const wxString& name)
756{
757 // init our fields
758 Init();
759
760 m_windowStyle = style;
761
762 SetName(name);
763
764 m_windowId = id == -1 ? NewControlId() : id;
765
facd6764
SC
766 MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
767
94d1d0f4
SC
768 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
769
a15eb0a5
SC
770 wxTopLevelWindows.Append(this);
771
772 if ( parent )
773 parent->AddChild(this);
774
775 return TRUE;
776}
777
778wxTopLevelWindowMac::~wxTopLevelWindowMac()
779{
6a17ca35
SC
780 if ( m_macWindow )
781 {
782 wxToolTip::NotifyWindowDelete(m_macWindow) ;
118f012e 783 wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
6a17ca35 784 }
1542ea39 785
7c091673
SC
786 if ( m_macEventHandler )
787 {
788 ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
789 m_macEventHandler = NULL ;
790 }
851b3a88 791
5f0b2f22
SC
792 wxRemoveMacWindowAssociation( this ) ;
793
a15eb0a5
SC
794 if ( wxModelessWindows.Find(this) )
795 wxModelessWindows.DeleteObject(this);
a15eb0a5
SC
796}
797
798
799// ----------------------------------------------------------------------------
800// wxTopLevelWindowMac maximize/minimize
801// ----------------------------------------------------------------------------
802
803void wxTopLevelWindowMac::Maximize(bool maximize)
804{
1f90939c
SC
805 wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ;
806 wxMacWindowClipper clip (this);
b7aec135 807 ZoomWindow( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , false ) ;
a15eb0a5
SC
808}
809
810bool wxTopLevelWindowMac::IsMaximized() const
811{
b7aec135 812 return IsWindowInStandardState( (WindowRef)m_macWindow , NULL , NULL ) ;
a15eb0a5
SC
813}
814
815void wxTopLevelWindowMac::Iconize(bool iconize)
816{
b7aec135
SC
817 if ( IsWindowCollapsable((WindowRef)m_macWindow) )
818 CollapseWindow((WindowRef)m_macWindow , iconize ) ;
a15eb0a5
SC
819}
820
821bool wxTopLevelWindowMac::IsIconized() const
822{
b7aec135 823 return IsWindowCollapsed((WindowRef)m_macWindow ) ;
a15eb0a5
SC
824}
825
826void wxTopLevelWindowMac::Restore()
827{
828 // not available on mac
829}
830
831// ----------------------------------------------------------------------------
832// wxTopLevelWindowMac misc
833// ----------------------------------------------------------------------------
834
facd6764
SC
835wxPoint wxTopLevelWindowMac::GetClientAreaOrigin() const
836{
837 return wxPoint(0,0) ;
838}
839
a15eb0a5
SC
840void wxTopLevelWindowMac::SetIcon(const wxIcon& icon)
841{
842 // this sets m_icon
843 wxTopLevelWindowBase::SetIcon(icon);
844}
5f0b2f22 845
facd6764
SC
846void wxTopLevelWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
847{
848 wxTopLevelWindowBase::MacSetBackgroundBrush( brush ) ;
849
850 if ( m_macBackgroundBrush.Ok() && m_macBackgroundBrush.GetStyle() != wxTRANSPARENT && m_macBackgroundBrush.MacGetBrushKind() == kwxMacBrushTheme )
851 {
852 SetThemeWindowBackground( (WindowRef) m_macWindow , m_macBackgroundBrush.MacGetTheme() , false ) ;
853 }
854}
855
949cb163
SC
856void wxTopLevelWindowMac::MacInstallTopLevelWindowEventHandler()
857{
858 if ( m_macEventHandler != NULL )
859 {
860 verify_noerr( ::RemoveEventHandler( (EventHandlerRef) m_macEventHandler ) ) ;
861 }
862 InstallWindowEventHandler(MAC_WXHWND(m_macWindow), GetwxMacTopLevelEventHandlerUPP(),
863 GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macEventHandler);
864}
865
5f0b2f22
SC
866void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
867 const wxPoint& pos,
868 const wxSize& size,
869 long style,
1542ea39 870 const wxString& name )
5f0b2f22 871{
47ac4f9b 872 OSStatus err = noErr ;
e40298d5
JS
873 SetName(name);
874 m_windowStyle = style;
875 m_isShown = FALSE;
1542ea39 876
e40298d5 877 // create frame.
1542ea39 878
5f0b2f22 879 Rect theBoundsRect;
1542ea39 880
facd6764
SC
881 int x = (int)pos.x;
882 int y = (int)pos.y;
883 if ( y < 50 )
884 y = 50 ;
885 if ( x < 20 )
886 x = 20 ;
1542ea39 887
facd6764
SC
888 int w = WidthDefault(size.x);
889 int h = HeightDefault(size.y);
1542ea39 890
facd6764 891 ::SetRect(&theBoundsRect, x, y , x + w, y + h);
1542ea39 892
5f0b2f22 893 // translate the window attributes in the appropriate window class and attributes
1542ea39 894
5f0b2f22
SC
895 WindowClass wclass = 0;
896 WindowAttributes attr = kWindowNoAttributes ;
1542ea39 897
f5744893 898 if ( HasFlag( wxFRAME_TOOL_WINDOW) )
5f0b2f22 899 {
1542ea39 900 if (
f5744893
SC
901 HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
902 HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) ||
903 HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT)
e40298d5 904 )
5f0b2f22 905 {
f5744893
SC
906 wclass = kFloatingWindowClass ;
907 if ( HasFlag(wxTINY_CAPTION_VERT) )
908 {
909 attr |= kWindowSideTitlebarAttribute ;
910 }
911 }
912 else
913 {
914 wclass = kPlainWindowClass ;
5f0b2f22
SC
915 }
916 }
917 else if ( HasFlag( wxCAPTION ) )
918 {
1542ea39 919 wclass = kDocumentWindowClass ;
5f0b2f22
SC
920 }
921 else
922 {
f5744893 923 if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
47ac4f9b 924 HasFlag( wxCLOSE_BOX ) || HasFlag( wxSYSTEM_MENU ) )
f5744893
SC
925 {
926 wclass = kDocumentWindowClass ;
927 }
928 else
929 {
930 wclass = kPlainWindowClass ;
931 }
5f0b2f22 932 }
1542ea39 933
47ac4f9b 934 if ( HasFlag( wxMINIMIZE_BOX ) )
5f0b2f22 935 {
5f0b2f22
SC
936 attr |= kWindowCollapseBoxAttribute ;
937 }
47ac4f9b
SC
938 if ( HasFlag( wxMAXIMIZE_BOX ) )
939 {
940 attr |= kWindowFullZoomAttribute ;
941 }
5f0b2f22
SC
942 if ( HasFlag( wxRESIZE_BORDER ) )
943 {
944 attr |= kWindowResizableAttribute ;
945 }
47ac4f9b 946 if ( HasFlag( wxCLOSE_BOX) )
5f0b2f22
SC
947 {
948 attr |= kWindowCloseBoxAttribute ;
949 }
1542ea39 950
eb630bf1
DS
951 if (UMAGetSystemVersion() >= 0x1000)
952 {
facd6764 953 // turn on live resizing (OS X only)
eb630bf1
DS
954 attr |= kWindowLiveResizeAttribute;
955 }
956
6a7e6411 957 if (HasFlag(wxSTAY_ON_TOP))
eb630bf1 958 wclass = kUtilityWindowClass;
6a7e6411 959
facd6764
SC
960#if TARGET_API_MAC_OSX
961 attr |= kWindowCompositingAttribute;
d66c3960 962#endif
1f90939c 963
6a7e6411
RD
964 if ( HasFlag(wxFRAME_SHAPED) )
965 {
966 WindowDefSpec customWindowDefSpec;
967 customWindowDefSpec.defType = kWindowDefProcPtr;
968 customWindowDefSpec.u.defProc = NewWindowDefUPP(wxShapedMacWindowDef);
969
47ac4f9b 970 err = ::CreateCustomWindow( &customWindowDefSpec, wclass,
6a7e6411
RD
971 attr, &theBoundsRect,
972 (WindowRef*) &m_macWindow);
973 }
974 else
975 {
47ac4f9b 976 err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
6a7e6411
RD
977 }
978
47ac4f9b 979 wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") );
f83b6761
SC
980
981 // the create commands are only for content rect, so we have to set the size again as
982 // structure bounds
983 SetWindowBounds( (WindowRef) m_macWindow , kWindowStructureRgn , &theBoundsRect ) ;
984
facd6764
SC
985 wxAssociateWinWithMacWindow( (WindowRef) m_macWindow , this ) ;
986 UMASetWTitle( (WindowRef) m_macWindow , title , m_font.GetEncoding() ) ;
21fd5529 987 m_peer = new wxMacControl() ;
3a9dc061
SC
988#if TARGET_API_MAC_OSX
989 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
990 // the content view, so we have to retrieve it explicitely
991 HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID ,
21fd5529 992 *m_peer ) ;
3a9dc061 993#else
21fd5529 994 ::CreateRootControl( (WindowRef)m_macWindow , *m_peer ) ;
3a9dc061 995#endif
73fe67bd 996 // the root control level handleer
949cb163 997 MacInstallEventHandler() ;
facd6764 998
73fe67bd 999 // the frame window event handler
e40298d5 1000 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ;
949cb163 1001 MacInstallTopLevelWindowEventHandler() ;
b19bf058 1002
facd6764 1003 m_macFocus = NULL ;
6a7e6411
RD
1004
1005 if ( HasFlag(wxFRAME_SHAPED) )
1006 {
1007 // default shape matches the window size
facd6764 1008 wxRegion rgn(0, 0, w, h);
6a7e6411
RD
1009 SetShape(rgn);
1010 }
3dfafdb9
RD
1011
1012 wxWindowCreateEvent event(this);
1013 GetEventHandler()->ProcessEvent(event);
5f0b2f22
SC
1014}
1015
5d2e69e8 1016void wxTopLevelWindowMac::ClearBackground()
5f0b2f22 1017{
5d2e69e8 1018 wxWindow::ClearBackground() ;
5f0b2f22
SC
1019}
1020
5f0b2f22
SC
1021// Raise the window to the top of the Z order
1022void wxTopLevelWindowMac::Raise()
1023{
7f3c339c 1024 ::SelectWindow( (WindowRef)m_macWindow ) ;
5f0b2f22
SC
1025}
1026
1027// Lower the window to the bottom of the Z order
1028void wxTopLevelWindowMac::Lower()
1029{
76a5e5d2 1030 ::SendBehind( (WindowRef)m_macWindow , NULL ) ;
5f0b2f22
SC
1031}
1032
851b3a88 1033
245f3581
DE
1034void wxTopLevelWindowMac::MacDelayedDeactivation(long timestamp)
1035{
1036 if(s_macDeactivateWindow)
1037 {
365796b1 1038 wxLogDebug(wxT("Doing delayed deactivation of %p"),s_macDeactivateWindow);
245f3581
DE
1039 s_macDeactivateWindow->MacActivate(timestamp, false);
1040 }
1041}
1042
851b3a88 1043void wxTopLevelWindowMac::MacActivate( long timestamp , bool inIsActivating )
5f0b2f22 1044{
17f8d2a7
VZ
1045 // wxLogDebug(wxT("TopLevel=%p::MacActivate"),this);
1046
245f3581
DE
1047 if(s_macDeactivateWindow==this)
1048 s_macDeactivateWindow=NULL;
1049 MacDelayedDeactivation(timestamp);
8ab50549 1050 MacPropagateHiliteChanged() ;
5f0b2f22
SC
1051}
1052
1053void wxTopLevelWindowMac::SetTitle(const wxString& title)
1054{
1055 wxWindow::SetTitle( title ) ;
16a76184 1056 UMASetWTitle( (WindowRef)m_macWindow , title , m_font.GetEncoding() ) ;
5f0b2f22
SC
1057}
1058
1059bool wxTopLevelWindowMac::Show(bool show)
1060{
facd6764 1061 if ( !wxTopLevelWindowBase::Show(show) )
5f0b2f22
SC
1062 return FALSE;
1063
1064 if (show)
1542ea39 1065 {
1f90939c
SC
1066 #if wxUSE_SYSTEM_OPTIONS //code contributed by Ryan Wilcox December 18, 2003
1067 if ( (wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) && ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1) )
1068 {
1069 ::ShowWindow( (WindowRef)m_macWindow );
1070 }
1071 else
1072 #endif
1073 {
1074 ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowShowTransitionAction,nil);
1075 }
1076 ::SelectWindow( (WindowRef)m_macWindow ) ;
facd6764
SC
1077 // as apps expect a size event to occur at this moment
1078 wxSizeEvent event( GetSize() , m_windowId);
1f90939c
SC
1079 event.SetEventObject(this);
1080 GetEventHandler()->ProcessEvent(event);
5f0b2f22
SC
1081 }
1082 else
1083 {
1f90939c
SC
1084 #if wxUSE_SYSTEM_OPTIONS
1085 if ( (wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) && ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1) )
1086 {
1087 ::HideWindow((WindowRef) m_macWindow );
1088 }
1089 else
1090 #endif
1091 {
1092 ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowHideTransitionAction,nil);
1093 }
5f0b2f22
SC
1094 }
1095
facd6764 1096 MacPropagateVisibilityChanged() ;
5f0b2f22 1097
facd6764 1098 return TRUE ;
5f0b2f22
SC
1099}
1100
facd6764
SC
1101// we are still using coordinates of the content view, todo switch to structure bounds
1102
29281095
SC
1103void wxTopLevelWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1104{
1105 Rect content ;
1106 Rect structure ;
1107 GetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &structure ) ;
1108 GetWindowBounds( (WindowRef) m_macWindow, kWindowContentRgn , &content ) ;
1109
1110 left = content.left - structure.left ;
1111 top = content.top - structure.top ;
1112 right = structure.right - content.right ;
1113 bottom = structure.bottom - content.bottom ;
1114}
1115
5f0b2f22
SC
1116void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height)
1117{
facd6764
SC
1118 Rect bounds = { y , x , y + height , x + width } ;
1119 verify_noerr(SetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ;
5f0b2f22
SC
1120}
1121
facd6764 1122void wxTopLevelWindowMac::DoGetPosition( int *x, int *y ) const
5f0b2f22 1123{
facd6764
SC
1124 Rect bounds ;
1125 verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ;
1126 if(x) *x = bounds.left ;
1127 if(y) *y = bounds.top ;
1128}
1129void wxTopLevelWindowMac::DoGetSize( int *width, int *height ) const
1130{
1131 Rect bounds ;
1132 verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ;
1133 if(width) *width = bounds.right - bounds.left ;
1134 if(height) *height = bounds.bottom - bounds.top ;
1135}
1542ea39 1136
facd6764
SC
1137void wxTopLevelWindowMac::DoGetClientSize( int *width, int *height ) const
1138{
1139 Rect bounds ;
1140 verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowContentRgn , &bounds )) ;
1141 if(width) *width = bounds.right - bounds.left ;
1142 if(height) *height = bounds.bottom - bounds.top ;
1143}
1542ea39 1144
facd6764
SC
1145void wxTopLevelWindowMac::MacSetMetalAppearance( bool set )
1146{
1147#if TARGET_API_MAC_OSX
1148 UInt32 attr = 0 ;
1149 GetWindowAttributes((WindowRef) m_macWindow , &attr ) ;
1150 wxASSERT_MSG( attr & kWindowCompositingAttribute ,
1151 wxT("Cannot set metal appearance on a non-compositing window") ) ;
1152
1153 MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes ,
1154 set ? kWindowNoAttributes : kWindowMetalAttribute ) ;
1155#endif
1156}
1542ea39 1157
6aab345b
SC
1158bool wxTopLevelWindowMac::MacGetMetalAppearance() const
1159{
1160#if TARGET_API_MAC_OSX
1161 return MacGetWindowAttributes() & kWindowMetalAttribute ;
1162#else
1163 return false ;
1164#endif
1165}
1166
facd6764
SC
1167void wxTopLevelWindowMac::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear )
1168{
1169 ChangeWindowAttributes ( (WindowRef) m_macWindow , attributesToSet, attributesToClear ) ;
1170}
1542ea39 1171
facd6764
SC
1172wxUint32 wxTopLevelWindowMac::MacGetWindowAttributes() const
1173{
1174 UInt32 attr = 0 ;
1175 GetWindowAttributes((WindowRef) m_macWindow , &attr ) ;
1176 return attr ;
5f0b2f22 1177}
a07c1212 1178
facd6764
SC
1179// ---------------------------------------------------------------------------
1180// Shape implementation
1181// ---------------------------------------------------------------------------
1182
6a7e6411 1183
1542ea39
RD
1184bool wxTopLevelWindowMac::SetShape(const wxRegion& region)
1185{
6a7e6411
RD
1186 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), FALSE,
1187 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1188
1189 // The empty region signifies that the shape should be removed from the
1190 // window.
1191 if ( region.IsEmpty() )
1192 {
1193 wxSize sz = GetClientSize();
1194 wxRegion rgn(0, 0, sz.x, sz.y);
1195 return SetShape(rgn);
1196 }
1197
1198 // Make a copy of the region
1199 RgnHandle shapeRegion = NewRgn();
1200 CopyRgn( (RgnHandle)region.GetWXHRGN(), shapeRegion );
1201
1202 // Dispose of any shape region we may already have
1203 RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef)MacGetWindowRef() );
1204 if ( oldRgn )
1205 DisposeRgn(oldRgn);
1206
1207 // Save the region so we can use it later
1208 SetWRefCon((WindowRef)MacGetWindowRef(), (SInt32)shapeRegion);
1209
1210 // Tell the window manager that the window has changed shape
1211 ReshapeCustomWindow((WindowRef)MacGetWindowRef());
1212 return TRUE;
1213}
1214
6a7e6411
RD
1215// ---------------------------------------------------------------------------
1216// Support functions for shaped windows, based on Apple's CustomWindow sample at
1217// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm
1218// ---------------------------------------------------------------------------
1219
6a7e6411
RD
1220static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect)
1221{
1222 GetWindowPortBounds(window, inRect);
1223 Point pt = {inRect->left, inRect->top};
d6fd667b 1224 QDLocalToGlobalPoint( GetWindowPort(window) , &pt ) ;
6a7e6411
RD
1225 inRect->top = pt.v;
1226 inRect->left = pt.h;
1227 inRect->bottom += pt.v;
1228 inRect->right += pt.h;
1229}
1230
1231
1232static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param)
1233{
1234 /*------------------------------------------------------
1235 Define which options your custom window supports.
1236 --------------------------------------------------------*/
1237 //just enable everything for our demo
1238 *(OptionBits*)param=//kWindowCanGrow|
1239 //kWindowCanZoom|
1240 //kWindowCanCollapse|
1241 //kWindowCanGetWindowRegion|
1242 //kWindowHasTitleBar|
1243 //kWindowSupportsDragHilite|
1244 kWindowCanDrawInCurrentPort|
1245 //kWindowCanMeasureTitle|
1246 kWindowWantsDisposeAtProcessDeath|
1247 kWindowSupportsSetGrowImageRegion|
1248 kWindowDefSupportsColorGrafPort;
1249 return 1;
1542ea39 1250}
6a7e6411
RD
1251
1252// The content region is left as a rectangle matching the window size, this is
1253// so the origin in the paint event, and etc. still matches what the
1254// programmer expects.
1255static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn)
1256{
1257 SetEmptyRgn(rgn);
1258 wxTopLevelWindowMac* win = wxFindWinFromMacWindow(window);
1259 if (win)
1260 {
b19bf058
SC
1261 Rect r ;
1262 wxShapedMacWindowGetPos(window, &r ) ;
1263 RectRgn( rgn , &r ) ;
6a7e6411
RD
1264 }
1265}
1266
1267// The structure region is set to the shape given to the SetShape method.
1268static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn)
1269{
1270 RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window);
1271
1272 SetEmptyRgn(rgn);
1273 if (cachedRegion)
1274 {
1275 Rect windowRect;
1276 wxShapedMacWindowGetPos(window, &windowRect); //how big is the window
1277 CopyRgn(cachedRegion, rgn); //make a copy of our cached region
1278 OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window
1279 //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size
1280 }
1281}
1282
1283
1284
1285static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param)
1286{
1287 GetWindowRegionPtr rgnRec=(GetWindowRegionPtr)param;
1288
1289 switch(rgnRec->regionCode)
1290 {
1291 case kWindowStructureRgn:
1292 wxShapedMacWindowStructureRegion(window, rgnRec->winRgn);
1293 break;
1294 case kWindowContentRgn:
1295 wxShapedMacWindowContentRegion(window, rgnRec->winRgn);
1296 break;
1297 default:
1298 SetEmptyRgn(rgnRec->winRgn);
1299 } //switch
1300
1301 return noErr;
1302}
1303
1304
1305static SInt32 wxShapedMacWindowHitTest(WindowRef window,SInt32 param)
1306{
1307 /*------------------------------------------------------
1308 Determine the region of the window which was hit
1309 --------------------------------------------------------*/
1310 Point hitPoint;
1311 static RgnHandle tempRgn=nil;
1312
1313 if(!tempRgn)
1314 tempRgn=NewRgn();
1315
1316 SetPt(&hitPoint,LoWord(param),HiWord(param));//get the point clicked
1317
1318 //Mac OS 8.5 or later
1319 wxShapedMacWindowStructureRegion(window, tempRgn);
1320 if (PtInRgn(hitPoint, tempRgn)) //in window content region?
1321 return wInContent;
1322
1323 return wNoHit;//no significant area was hit.
1324}
1325
1326
1327static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param)
1328{
1329 switch(message)
1330 {
1331 case kWindowMsgHitTest:
1332 return wxShapedMacWindowHitTest(window,param);
1333
1334 case kWindowMsgGetFeatures:
1335 return wxShapedMacWindowGetFeatures(window,param);
1336
1337 // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow
1338 case kWindowMsgGetRegion:
1339 return wxShapedMacWindowGetRegion(window,param);
1340 }
1341
1342 return 0;
1343}
1925be65 1344
6a7e6411 1345// ---------------------------------------------------------------------------
1925be65 1346