1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/nonownedwnd.cpp
3 // Purpose: implementation of wxNonOwnedWindow
4 // Author: Stefan Csomor
6 // RCS-ID: $Id: nonownedwnd.cpp 50329 2007-11-29 17:00:58Z VS $
7 // Copyright: (c) Stefan Csomor 2008
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #include "wx/hashmap.h"
19 #include "wx/evtloop.h"
20 #include "wx/tooltip.h"
21 #include "wx/nonownedwnd.h"
23 #include "wx/mac/private.h"
25 #if wxUSE_SYSTEM_OPTIONS
26 #include "wx/sysopt.h"
29 // ----------------------------------------------------------------------------
31 // ----------------------------------------------------------------------------
33 // unified title and toolbar constant - not in Tiger headers, so we duplicate it here
34 #define kWindowUnifiedTitleAndToolbarAttribute (1 << 7)
36 // trace mask for activation tracing messages
37 static const wxChar
*TRACE_ACTIVATE
= _T("activation");
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 // list of all frames and modeless dialogs
44 wxWindowList wxModelessWindows
;
46 static pascal long wxShapedMacWindowDef(short varCode
, WindowRef window
, SInt16 message
, SInt32 param
);
48 // ============================================================================
49 // wxNonOwnedWindow implementation
50 // ============================================================================
52 // ---------------------------------------------------------------------------
54 // ---------------------------------------------------------------------------
56 static const EventTypeSpec eventList
[] =
58 // TODO: remove control related event like key and mouse (except for WindowLeave events)
60 { kEventClassKeyboard
, kEventRawKeyDown
} ,
61 { kEventClassKeyboard
, kEventRawKeyRepeat
} ,
62 { kEventClassKeyboard
, kEventRawKeyUp
} ,
63 { kEventClassKeyboard
, kEventRawKeyModifiersChanged
} ,
65 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
66 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
68 { kEventClassWindow
, kEventWindowShown
} ,
69 { kEventClassWindow
, kEventWindowActivated
} ,
70 { kEventClassWindow
, kEventWindowDeactivated
} ,
71 { kEventClassWindow
, kEventWindowBoundsChanging
} ,
72 { kEventClassWindow
, kEventWindowBoundsChanged
} ,
73 { kEventClassWindow
, kEventWindowClose
} ,
74 { kEventClassWindow
, kEventWindowGetRegion
} ,
76 // we have to catch these events on the toplevel window level,
77 // as controls don't get the raw mouse events anymore
79 { kEventClassMouse
, kEventMouseDown
} ,
80 { kEventClassMouse
, kEventMouseUp
} ,
81 { kEventClassMouse
, kEventMouseWheelMoved
} ,
82 { kEventClassMouse
, kEventMouseMoved
} ,
83 { kEventClassMouse
, kEventMouseDragged
} ,
86 static pascal OSStatus
KeyboardEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
88 OSStatus result
= eventNotHandledErr
;
89 // call DoFindFocus instead of FindFocus, because for Composite Windows(like WxGenericListCtrl)
90 // FindFocus does not return the actual focus window, but the enclosing window
91 wxWindow
* focus
= wxWindow::DoFindFocus();
93 focus
= (wxNonOwnedWindow
*) data
;
95 unsigned char charCode
;
103 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
106 ByteCount dataSize
= 0 ;
107 if ( GetEventParameter( event
, kEventParamKeyUnicodes
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
110 int numChars
= dataSize
/ sizeof( UniChar
) + 1;
112 UniChar
* charBuf
= buf
;
114 if ( numChars
* 2 > 4 )
115 charBuf
= new UniChar
[ numChars
] ;
116 GetEventParameter( event
, kEventParamKeyUnicodes
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
117 charBuf
[ numChars
- 1 ] = 0;
119 #if SIZEOF_WCHAR_T == 2
120 uniChar
= charBuf
[0] ;
122 wxMBConvUTF16 converter
;
123 converter
.MB2WC( uniChar
, (const char*)charBuf
, 2 ) ;
126 if ( numChars
* 2 > 4 )
131 GetEventParameter( event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
132 GetEventParameter( event
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
133 GetEventParameter( event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
134 GetEventParameter( event
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
136 UInt32 message
= (keyCode
<< 8) + charCode
;
137 switch ( GetEventKind( event
) )
139 case kEventRawKeyRepeat
:
140 case kEventRawKeyDown
:
142 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
143 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
144 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
145 if ( /* focus && */ wxTheApp
->MacSendKeyDownEvent(
146 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChar
[0] ) )
150 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
154 case kEventRawKeyUp
:
155 if ( /* focus && */ wxTheApp
->MacSendKeyUpEvent(
156 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChar
[0] ) )
162 case kEventRawKeyModifiersChanged
:
164 wxKeyEvent
event(wxEVT_KEY_DOWN
);
166 event
.m_shiftDown
= modifiers
& shiftKey
;
167 event
.m_controlDown
= modifiers
& controlKey
;
168 event
.m_altDown
= modifiers
& optionKey
;
169 event
.m_metaDown
= modifiers
& cmdKey
;
174 event
.m_uniChar
= uniChar
[0] ;
177 event
.SetTimestamp(when
);
178 event
.SetEventObject(focus
);
180 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & controlKey
)
182 event
.m_keyCode
= WXK_CONTROL
;
183 event
.SetEventType( ( modifiers
& controlKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
184 focus
->HandleWindowEvent( event
) ;
186 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & shiftKey
)
188 event
.m_keyCode
= WXK_SHIFT
;
189 event
.SetEventType( ( modifiers
& shiftKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
190 focus
->HandleWindowEvent( event
) ;
192 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & optionKey
)
194 event
.m_keyCode
= WXK_ALT
;
195 event
.SetEventType( ( modifiers
& optionKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
196 focus
->HandleWindowEvent( event
) ;
198 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & cmdKey
)
200 event
.m_keyCode
= WXK_COMMAND
;
201 event
.SetEventType( ( modifiers
& cmdKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
202 focus
->HandleWindowEvent( event
) ;
205 wxApp::s_lastModifiers
= modifiers
;
216 // we don't interfere with foreign controls on our toplevel windows, therefore we always give back eventNotHandledErr
217 // for windows that we didn't create (like eg Scrollbars in a databrowser), or for controls where we did not handle the
220 // This handler can also be called from app level where data (ie target window) may be null or a non wx window
222 wxWindow
* g_MacLastWindow
= NULL
;
224 EventMouseButton g_lastButton
= 0 ;
225 bool g_lastButtonWasFakeRight
= false ;
227 void SetupMouseEvent( wxMouseEvent
&wxevent
, wxMacCarbonEvent
&cEvent
)
229 UInt32 modifiers
= cEvent
.GetParameter
<UInt32
>(kEventParamKeyModifiers
, typeUInt32
) ;
230 Point screenMouseLocation
= cEvent
.GetParameter
<Point
>(kEventParamMouseLocation
) ;
232 // these parameters are not given for all events
233 EventMouseButton button
= 0 ;
234 UInt32 clickCount
= 0 ;
235 UInt32 mouseChord
= 0;
237 cEvent
.GetParameter
<EventMouseButton
>( kEventParamMouseButton
, typeMouseButton
, &button
) ;
238 cEvent
.GetParameter
<UInt32
>( kEventParamClickCount
, typeUInt32
, &clickCount
) ;
239 // the chord is the state of the buttons pressed currently
240 cEvent
.GetParameter
<UInt32
>( kEventParamMouseChord
, typeUInt32
, &mouseChord
) ;
242 wxevent
.m_x
= screenMouseLocation
.h
;
243 wxevent
.m_y
= screenMouseLocation
.v
;
244 wxevent
.m_shiftDown
= modifiers
& shiftKey
;
245 wxevent
.m_controlDown
= modifiers
& controlKey
;
246 wxevent
.m_altDown
= modifiers
& optionKey
;
247 wxevent
.m_metaDown
= modifiers
& cmdKey
;
248 wxevent
.m_clickCount
= clickCount
;
249 wxevent
.SetTimestamp( cEvent
.GetTicks() ) ;
251 // a control click is interpreted as a right click
252 bool thisButtonIsFakeRight
= false ;
253 if ( button
== kEventMouseButtonPrimary
&& (modifiers
& controlKey
) )
255 button
= kEventMouseButtonSecondary
;
256 thisButtonIsFakeRight
= true ;
259 // otherwise we report double clicks by connecting a left click with a ctrl-left click
260 if ( clickCount
> 1 && button
!= g_lastButton
)
263 // we must make sure that our synthetic 'right' button corresponds in
264 // mouse down, moved and mouse up, and does not deliver a right down and left up
266 if ( cEvent
.GetKind() == kEventMouseDown
)
268 g_lastButton
= button
;
269 g_lastButtonWasFakeRight
= thisButtonIsFakeRight
;
275 g_lastButtonWasFakeRight
= false ;
277 else if ( g_lastButton
== kEventMouseButtonSecondary
&& g_lastButtonWasFakeRight
)
278 button
= g_lastButton
;
280 // Adjust the chord mask to remove the primary button and add the
281 // secondary button. It is possible that the secondary button is
282 // already pressed, e.g. on a mouse connected to a laptop, but this
283 // possibility is ignored here:
284 if( thisButtonIsFakeRight
&& ( mouseChord
& 1U ) )
285 mouseChord
= ((mouseChord
& ~1U) | 2U);
288 wxevent
.m_leftDown
= true ;
290 wxevent
.m_rightDown
= true ;
292 wxevent
.m_middleDown
= true ;
294 // translate into wx types
295 switch ( cEvent
.GetKind() )
297 case kEventMouseDown
:
300 case kEventMouseButtonPrimary
:
301 wxevent
.SetEventType( clickCount
> 1 ? wxEVT_LEFT_DCLICK
: wxEVT_LEFT_DOWN
) ;
304 case kEventMouseButtonSecondary
:
305 wxevent
.SetEventType( clickCount
> 1 ? wxEVT_RIGHT_DCLICK
: wxEVT_RIGHT_DOWN
) ;
308 case kEventMouseButtonTertiary
:
309 wxevent
.SetEventType( clickCount
> 1 ? wxEVT_MIDDLE_DCLICK
: wxEVT_MIDDLE_DOWN
) ;
320 case kEventMouseButtonPrimary
:
321 wxevent
.SetEventType( wxEVT_LEFT_UP
) ;
324 case kEventMouseButtonSecondary
:
325 wxevent
.SetEventType( wxEVT_RIGHT_UP
) ;
328 case kEventMouseButtonTertiary
:
329 wxevent
.SetEventType( wxEVT_MIDDLE_UP
) ;
337 case kEventMouseWheelMoved
:
339 wxevent
.SetEventType( wxEVT_MOUSEWHEEL
) ;
341 EventMouseWheelAxis axis
= cEvent
.GetParameter
<EventMouseWheelAxis
>(kEventParamMouseWheelAxis
, typeMouseWheelAxis
) ;
342 SInt32 delta
= cEvent
.GetParameter
<SInt32
>(kEventParamMouseWheelDelta
, typeSInt32
) ;
344 wxevent
.m_wheelRotation
= delta
;
345 wxevent
.m_wheelDelta
= 1;
346 wxevent
.m_linesPerAction
= 1;
347 if ( axis
== kEventMouseWheelAxisX
)
348 wxevent
.m_wheelAxis
= 1;
352 case kEventMouseEntered
:
353 case kEventMouseExited
:
354 case kEventMouseDragged
:
355 case kEventMouseMoved
:
356 wxevent
.SetEventType( wxEVT_MOTION
) ;
363 #define NEW_CAPTURE_HANDLING 1
366 wxMacTopLevelMouseEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
370 wxNonOwnedWindow
* toplevelWindow
= (wxNonOwnedWindow
*) data
;
372 OSStatus result
= eventNotHandledErr
;
374 wxMacCarbonEvent
cEvent( event
) ;
376 Point screenMouseLocation
= cEvent
.GetParameter
<Point
>(kEventParamMouseLocation
) ;
377 Point windowMouseLocation
= screenMouseLocation
;
379 WindowRef window
= NULL
;
380 short windowPart
= ::FindWindow(screenMouseLocation
, &window
);
382 wxWindow
* currentMouseWindow
= NULL
;
383 ControlRef control
= NULL
;
385 #if NEW_CAPTURE_HANDLING
386 if ( wxApp::s_captureWindow
)
388 window
= (WindowRef
) wxApp::s_captureWindow
->MacGetTopLevelWindowRef() ;
389 windowPart
= inContent
;
395 wxMacGlobalToLocal( window
, &windowMouseLocation
) ;
397 if ( wxApp::s_captureWindow
398 #if !NEW_CAPTURE_HANDLING
399 && wxApp::s_captureWindow
->MacGetTopLevelWindowRef() == (WXWindow
) window
&& windowPart
== inContent
403 currentMouseWindow
= wxApp::s_captureWindow
;
405 else if ( (IsWindowActive(window
) && windowPart
== inContent
) )
407 ControlPartCode part
;
408 control
= FindControlUnderMouse( windowMouseLocation
, window
, &part
) ;
409 // if there is no control below the mouse position, send the event to the toplevel window itself
412 currentMouseWindow
= (wxWindow
*) data
;
416 currentMouseWindow
= (wxWindow
*) wxFindControlFromMacControl( control
) ;
417 #ifndef __WXUNIVERSAL__
418 if ( currentMouseWindow
== NULL
&& cEvent
.GetKind() == kEventMouseMoved
)
421 // for wxToolBar to function we have to send certaint events to it
422 // instead of its children (wxToolBarTools)
424 GetSuperControl(control
, &parent
);
425 wxWindow
*wxParent
= (wxWindow
*) wxFindControlFromMacControl( parent
) ;
426 if ( wxParent
&& wxParent
->IsKindOf( CLASSINFO( wxToolBar
) ) )
427 currentMouseWindow
= wxParent
;
433 // disabled windows must not get any input messages
434 if ( currentMouseWindow
&& !currentMouseWindow
->MacIsReallyEnabled() )
435 currentMouseWindow
= NULL
;
439 wxMouseEvent
wxevent(wxEVT_LEFT_DOWN
);
440 SetupMouseEvent( wxevent
, cEvent
) ;
442 // handle all enter / leave events
444 if ( currentMouseWindow
!= g_MacLastWindow
)
446 if ( g_MacLastWindow
)
448 wxMouseEvent
eventleave(wxevent
);
449 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
);
450 g_MacLastWindow
->ScreenToClient( &eventleave
.m_x
, &eventleave
.m_y
);
451 eventleave
.SetEventObject( g_MacLastWindow
) ;
452 wxevent
.SetId( g_MacLastWindow
->GetId() ) ;
455 wxToolTip::RelayEvent( g_MacLastWindow
, eventleave
);
458 g_MacLastWindow
->HandleWindowEvent(eventleave
);
461 if ( currentMouseWindow
)
463 wxMouseEvent
evententer(wxevent
);
464 evententer
.SetEventType( wxEVT_ENTER_WINDOW
);
465 currentMouseWindow
->ScreenToClient( &evententer
.m_x
, &evententer
.m_y
);
466 evententer
.SetEventObject( currentMouseWindow
) ;
467 wxevent
.SetId( currentMouseWindow
->GetId() ) ;
470 wxToolTip::RelayEvent( currentMouseWindow
, evententer
);
473 currentMouseWindow
->HandleWindowEvent(evententer
);
476 g_MacLastWindow
= currentMouseWindow
;
479 if ( windowPart
== inMenuBar
)
481 // special case menu bar, as we are having a low-level runloop we must do it ourselves
482 if ( cEvent
.GetKind() == kEventMouseDown
)
484 ::MenuSelect( screenMouseLocation
) ;
489 else if ( currentMouseWindow
)
491 wxWindow
*currentMouseWindowParent
= currentMouseWindow
->GetParent();
493 currentMouseWindow
->ScreenToClient( &wxevent
.m_x
, &wxevent
.m_y
) ;
495 wxevent
.SetEventObject( currentMouseWindow
) ;
496 wxevent
.SetId( currentMouseWindow
->GetId() ) ;
498 // make tooltips current
501 if ( wxevent
.GetEventType() == wxEVT_MOTION
)
502 wxToolTip::RelayEvent( currentMouseWindow
, wxevent
);
505 if ( currentMouseWindow
->HandleWindowEvent(wxevent
) )
507 if ((currentMouseWindowParent
!= NULL
) &&
508 (currentMouseWindowParent
->GetChildren().Find(currentMouseWindow
) == NULL
))
509 currentMouseWindow
= NULL
;
515 // if the user code did _not_ handle the event, then perform the
516 // default processing
517 if ( wxevent
.GetEventType() == wxEVT_LEFT_DOWN
)
519 // ... that is set focus to this window
520 if (currentMouseWindow
->CanAcceptFocus() && wxWindow::FindFocus()!=currentMouseWindow
)
521 currentMouseWindow
->SetFocus();
525 if ( cEvent
.GetKind() == kEventMouseUp
&& wxApp::s_captureWindow
)
527 wxApp::s_captureWindow
= NULL
;
533 wxWindow
* cursorTarget
= currentMouseWindow
;
534 wxPoint
cursorPoint( wxevent
.m_x
, wxevent
.m_y
) ;
536 extern wxCursor gGlobalCursor
;
538 if (!gGlobalCursor
.IsOk())
540 while ( cursorTarget
&& !cursorTarget
->MacSetupCursor( cursorPoint
) )
542 cursorTarget
= cursorTarget
->GetParent() ;
544 cursorPoint
+= cursorTarget
->GetPosition();
549 else // currentMouseWindow == NULL
551 // don't mess with controls we don't know about
552 // for some reason returning eventNotHandledErr does not lead to the correct behaviour
553 // so we try sending them the correct control directly
554 if ( cEvent
.GetKind() == kEventMouseDown
&& toplevelWindow
&& control
)
556 EventModifiers modifiers
= cEvent
.GetParameter
<EventModifiers
>(kEventParamKeyModifiers
, typeUInt32
) ;
557 Point clickLocation
= windowMouseLocation
;
560 hiPoint
.x
= clickLocation
.h
;
561 hiPoint
.y
= clickLocation
.v
;
562 HIViewConvertPoint( &hiPoint
, (ControlRef
) toplevelWindow
->GetHandle() , control
) ;
563 clickLocation
.h
= (int)hiPoint
.x
;
564 clickLocation
.v
= (int)hiPoint
.y
;
566 HandleControlClick( control
, clickLocation
, modifiers
, (ControlActionUPP
) -1 ) ;
574 static pascal OSStatus
575 wxNonOwnedWindowEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
579 OSStatus result
= eventNotHandledErr
;
581 wxMacCarbonEvent
cEvent( event
) ;
583 // WindowRef windowRef = cEvent.GetParameter<WindowRef>(kEventParamDirectObject) ;
584 wxNonOwnedWindow
* toplevelWindow
= (wxNonOwnedWindow
*) data
;
586 switch ( GetEventKind( event
) )
588 case kEventWindowActivated
:
590 toplevelWindow
->MacActivate( cEvent
.GetTicks() , true) ;
591 wxActivateEvent
wxevent(wxEVT_ACTIVATE
, true , toplevelWindow
->GetId());
592 wxevent
.SetTimestamp( cEvent
.GetTicks() ) ;
593 wxevent
.SetEventObject(toplevelWindow
);
594 toplevelWindow
->HandleWindowEvent(wxevent
);
595 // we still sending an eventNotHandledErr in order to allow for default processing
599 case kEventWindowDeactivated
:
601 toplevelWindow
->MacActivate(cEvent
.GetTicks() , false) ;
602 wxActivateEvent
wxevent(wxEVT_ACTIVATE
, false , toplevelWindow
->GetId());
603 wxevent
.SetTimestamp( cEvent
.GetTicks() ) ;
604 wxevent
.SetEventObject(toplevelWindow
);
605 toplevelWindow
->HandleWindowEvent(wxevent
);
606 // we still sending an eventNotHandledErr in order to allow for default processing
610 case kEventWindowShown
:
611 toplevelWindow
->Refresh() ;
615 case kEventWindowClose
:
616 toplevelWindow
->Close() ;
620 case kEventWindowBoundsChanged
:
622 UInt32 attributes
= cEvent
.GetParameter
<UInt32
>(kEventParamAttributes
, typeUInt32
) ;
623 Rect newRect
= cEvent
.GetParameter
<Rect
>(kEventParamCurrentBounds
) ;
624 wxRect
r( newRect
.left
, newRect
.top
, newRect
.right
- newRect
.left
, newRect
.bottom
- newRect
.top
) ;
625 if ( attributes
& kWindowBoundsChangeSizeChanged
)
627 #ifndef __WXUNIVERSAL__
628 // according to the other ports we handle this within the OS level
629 // resize event, not within a wxSizeEvent
630 wxFrame
*frame
= wxDynamicCast( toplevelWindow
, wxFrame
) ;
633 frame
->PositionBars();
636 wxSizeEvent
event( r
.GetSize() , toplevelWindow
->GetId() ) ;
637 event
.SetEventObject( toplevelWindow
) ;
639 toplevelWindow
->HandleWindowEvent(event
) ;
640 toplevelWindow
->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
643 if ( attributes
& kWindowBoundsChangeOriginChanged
)
645 wxMoveEvent
event( r
.GetLeftTop() , toplevelWindow
->GetId() ) ;
646 event
.SetEventObject( toplevelWindow
) ;
647 toplevelWindow
->HandleWindowEvent(event
) ;
654 case kEventWindowBoundsChanging
:
656 UInt32 attributes
= cEvent
.GetParameter
<UInt32
>(kEventParamAttributes
,typeUInt32
) ;
657 Rect newRect
= cEvent
.GetParameter
<Rect
>(kEventParamCurrentBounds
) ;
659 if ( (attributes
& kWindowBoundsChangeSizeChanged
) || (attributes
& kWindowBoundsChangeOriginChanged
) )
661 // all (Mac) rects are in content area coordinates, all wxRects in structure coordinates
662 int left
, top
, right
, bottom
;
663 toplevelWindow
->MacGetContentAreaInset( left
, top
, right
, bottom
) ;
668 newRect
.right
- newRect
.left
+ left
+ right
,
669 newRect
.bottom
- newRect
.top
+ top
+ bottom
) ;
671 // this is a EVT_SIZING not a EVT_SIZE type !
672 wxSizeEvent
wxevent( r
, toplevelWindow
->GetId() ) ;
673 wxevent
.SetEventObject( toplevelWindow
) ;
675 if ( toplevelWindow
->HandleWindowEvent(wxevent
) )
676 adjustR
= wxevent
.GetRect() ;
678 if ( toplevelWindow
->GetMaxWidth() != -1 && adjustR
.GetWidth() > toplevelWindow
->GetMaxWidth() )
679 adjustR
.SetWidth( toplevelWindow
->GetMaxWidth() ) ;
680 if ( toplevelWindow
->GetMaxHeight() != -1 && adjustR
.GetHeight() > toplevelWindow
->GetMaxHeight() )
681 adjustR
.SetHeight( toplevelWindow
->GetMaxHeight() ) ;
682 if ( toplevelWindow
->GetMinWidth() != -1 && adjustR
.GetWidth() < toplevelWindow
->GetMinWidth() )
683 adjustR
.SetWidth( toplevelWindow
->GetMinWidth() ) ;
684 if ( toplevelWindow
->GetMinHeight() != -1 && adjustR
.GetHeight() < toplevelWindow
->GetMinHeight() )
685 adjustR
.SetHeight( toplevelWindow
->GetMinHeight() ) ;
686 const Rect adjustedRect
= { adjustR
.y
+ top
, adjustR
.x
+ left
, adjustR
.y
+ adjustR
.height
- bottom
, adjustR
.x
+ adjustR
.width
- right
} ;
687 if ( !EqualRect( &newRect
, &adjustedRect
) )
688 cEvent
.SetParameter
<Rect
>( kEventParamCurrentBounds
, &adjustedRect
) ;
689 toplevelWindow
->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
696 case kEventWindowGetRegion
:
698 if ( toplevelWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
700 WindowRegionCode windowRegionCode
;
702 // Fetch the region code that is being queried
703 GetEventParameter( event
,
704 kEventParamWindowRegionCode
,
705 typeWindowRegionCode
, NULL
,
706 sizeof windowRegionCode
, NULL
,
707 &windowRegionCode
) ;
709 // If it is the opaque region code then set the
710 // region to empty and return noErr to stop event
712 if ( windowRegionCode
== kWindowOpaqueRgn
) {
714 GetEventParameter( event
,
715 kEventParamRgnHandle
,
716 typeQDRgnHandle
, NULL
,
719 SetEmptyRgn(region
) ;
733 // mix this in from window.cpp
734 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
) ;
736 pascal OSStatus
wxNonOwnedEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
738 OSStatus result
= eventNotHandledErr
;
740 switch ( GetEventClass( event
) )
742 case kEventClassTextInput
:
743 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
746 case kEventClassKeyboard
:
747 result
= KeyboardEventHandler( handler
, event
, data
) ;
750 case kEventClassWindow
:
751 result
= wxNonOwnedWindowEventHandler( handler
, event
, data
) ;
754 case kEventClassMouse
:
755 result
= wxMacTopLevelMouseEventHandler( handler
, event
, data
) ;
765 DEFINE_ONE_SHOT_HANDLER_GETTER( wxNonOwnedEventHandler
)
767 // ---------------------------------------------------------------------------
768 // wxWindowMac utility functions
769 // ---------------------------------------------------------------------------
771 // Find an item given the Macintosh Window Reference
773 WX_DECLARE_HASH_MAP(WindowRef
, wxNonOwnedWindow
*, wxPointerHash
, wxPointerEqual
, MacWindowMap
);
775 static MacWindowMap wxWinMacWindowList
;
777 wxNonOwnedWindow
*wxFindWinFromMacWindow(WindowRef inWindowRef
)
779 MacWindowMap::iterator node
= wxWinMacWindowList
.find(inWindowRef
);
781 return (node
== wxWinMacWindowList
.end()) ? NULL
: node
->second
;
784 void wxAssociateWinWithMacWindow(WindowRef inWindowRef
, wxNonOwnedWindow
*win
) ;
785 void wxAssociateWinWithMacWindow(WindowRef inWindowRef
, wxNonOwnedWindow
*win
)
787 // adding NULL WindowRef is (first) surely a result of an error and
789 wxCHECK_RET( inWindowRef
!= (WindowRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
791 wxWinMacWindowList
[inWindowRef
] = win
;
794 void wxRemoveMacWindowAssociation(wxNonOwnedWindow
*win
) ;
795 void wxRemoveMacWindowAssociation(wxNonOwnedWindow
*win
)
797 MacWindowMap::iterator it
;
798 for ( it
= wxWinMacWindowList
.begin(); it
!= wxWinMacWindowList
.end(); ++it
)
800 if ( it
->second
== win
)
802 wxWinMacWindowList
.erase(it
);
808 // ----------------------------------------------------------------------------
809 // wxNonOwnedWindow creation
810 // ----------------------------------------------------------------------------
812 wxNonOwnedWindow
*wxNonOwnedWindow::s_macDeactivateWindow
= NULL
;
814 void wxNonOwnedWindow::Init()
817 m_macEventHandler
= NULL
;
820 wxMacDeferredWindowDeleter::wxMacDeferredWindowDeleter( WindowRef windowRef
)
822 m_macWindow
= windowRef
;
825 wxMacDeferredWindowDeleter::~wxMacDeferredWindowDeleter()
827 DisposeWindow( (WindowRef
) m_macWindow
) ;
830 bool wxNonOwnedWindow::Create(wxWindow
*parent
,
835 const wxString
& name
)
840 m_windowStyle
= style
;
844 m_windowId
= id
== -1 ? NewControlId() : id
;
846 DoMacCreateRealWindow( parent
, pos
, size
, style
, name
) ;
848 SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
));
850 if (GetExtraStyle() & wxFRAME_EX_METAL
)
851 MacSetMetalAppearance(true);
853 wxTopLevelWindows
.Append(this);
856 parent
->AddChild(this);
861 wxNonOwnedWindow::~wxNonOwnedWindow()
866 wxToolTip::NotifyWindowDelete(m_macWindow
) ;
868 wxPendingDelete
.Append( new wxMacDeferredWindowDeleter( (WindowRef
) m_macWindow
) ) ;
871 if ( m_macEventHandler
)
873 ::RemoveEventHandler((EventHandlerRef
) m_macEventHandler
);
874 m_macEventHandler
= NULL
;
877 wxRemoveMacWindowAssociation( this ) ;
879 if ( wxModelessWindows
.Find(this) )
880 wxModelessWindows
.DeleteObject(this);
882 // avoid dangling refs
883 if ( s_macDeactivateWindow
== this )
884 s_macDeactivateWindow
= NULL
;
887 // ----------------------------------------------------------------------------
888 // wxNonOwnedWindow misc
889 // ----------------------------------------------------------------------------
891 wxPoint
wxNonOwnedWindow::GetClientAreaOrigin() const
893 return wxPoint(0, 0) ;
896 bool wxNonOwnedWindow::SetBackgroundColour(const wxColour
& c
)
899 if ( col
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
900 col
= wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground
));
901 else if ( col
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
902 col
= wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive
));
904 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
907 if ( col
== wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground
)) )
909 SetThemeWindowBackground( (WindowRef
) m_macWindow
, kThemeBrushDocumentWindowBackground
, false ) ;
910 SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
912 else if ( col
== wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive
)) )
914 SetThemeWindowBackground( (WindowRef
) m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
915 SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
920 void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window
, EventHandlerRef
* handler
, void *ref
)
922 InstallWindowEventHandler(window
, GetwxNonOwnedEventHandlerUPP(),
923 GetEventTypeCount(eventList
), eventList
, ref
, handler
);
926 void wxNonOwnedWindow::MacInstallTopLevelWindowEventHandler()
928 if ( m_macEventHandler
!= NULL
)
930 verify_noerr( ::RemoveEventHandler( (EventHandlerRef
) m_macEventHandler
) ) ;
932 wxNonOwnedWindowInstallTopLevelWindowEventHandler(MAC_WXHWND(m_macWindow
),(EventHandlerRef
*)&m_macEventHandler
,this);
935 void wxNonOwnedWindow::MacCreateRealWindow(
939 const wxString
& name
)
941 DoMacCreateRealWindow( NULL
, pos
, size
, style
, name
);
944 void wxNonOwnedWindow::DoMacCreateRealWindow(
949 const wxString
& name
)
951 OSStatus err
= noErr
;
953 m_windowStyle
= style
;
961 wxRect display
= wxGetClientDisplayRect() ;
963 if ( x
== wxDefaultPosition
.x
)
966 if ( y
== wxDefaultPosition
.y
)
969 int w
= WidthDefault(size
.x
);
970 int h
= HeightDefault(size
.y
);
972 ::SetRect(&theBoundsRect
, x
, y
, x
+ w
, y
+ h
);
974 // translate the window attributes in the appropriate window class and attributes
975 WindowClass wclass
= 0;
976 WindowAttributes attr
= kWindowNoAttributes
;
977 WindowGroupRef group
= NULL
;
978 bool activationScopeSet
= false;
979 WindowActivationScope activationScope
= kWindowActivationScopeNone
;
981 if ( HasFlag( wxFRAME_TOOL_WINDOW
) )
984 HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) ||
985 HasFlag( wxSYSTEM_MENU
) || HasFlag( wxCAPTION
) ||
986 HasFlag(wxTINY_CAPTION_HORIZ
) || HasFlag(wxTINY_CAPTION_VERT
)
989 if ( HasFlag( wxSTAY_ON_TOP
) )
990 wclass
= kUtilityWindowClass
;
992 wclass
= kFloatingWindowClass
;
994 if ( HasFlag(wxTINY_CAPTION_VERT
) )
995 attr
|= kWindowSideTitlebarAttribute
;
999 wclass
= kPlainWindowClass
;
1000 activationScopeSet
= true;
1001 activationScope
= kWindowActivationScopeNone
;
1004 else if ( HasFlag( wxPOPUP_WINDOW
) )
1007 // Until we've got a real wxPopupWindow class on wxMac make it a
1008 // little easier for wxFrame to be used to emulate it and workaround
1009 // the lack of wxPopupWindow.
1010 if ( HasFlag( wxBORDER_NONE
) )
1011 wclass
= kHelpWindowClass
; // has no border
1013 wclass
= kPlainWindowClass
; // has a single line border, it will have to do for now
1014 //attr |= kWindowNoShadowAttribute; // turn off the shadow Should we??
1015 group
= GetWindowGroupOfClass( // float above other windows
1016 kFloatingWindowClass
) ;
1018 else if ( HasFlag( wxCAPTION
) )
1020 wclass
= kDocumentWindowClass
;
1021 attr
|= kWindowInWindowMenuAttribute
;
1023 else if ( HasFlag( wxFRAME_DRAWER
) )
1025 wclass
= kDrawerWindowClass
;
1029 if ( HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) ||
1030 HasFlag( wxCLOSE_BOX
) || HasFlag( wxSYSTEM_MENU
) )
1032 wclass
= kDocumentWindowClass
;
1034 else if ( HasFlag( wxNO_BORDER
) )
1036 wclass
= kSimpleWindowClass
;
1040 wclass
= kPlainWindowClass
;
1044 if ( wclass
!= kPlainWindowClass
)
1046 if ( HasFlag( wxMINIMIZE_BOX
) )
1047 attr
|= kWindowCollapseBoxAttribute
;
1049 if ( HasFlag( wxMAXIMIZE_BOX
) )
1050 attr
|= kWindowFullZoomAttribute
;
1052 if ( HasFlag( wxRESIZE_BORDER
) )
1053 attr
|= kWindowResizableAttribute
;
1055 if ( HasFlag( wxCLOSE_BOX
) )
1056 attr
|= kWindowCloseBoxAttribute
;
1058 attr
|= kWindowLiveResizeAttribute
;
1060 if ( HasFlag(wxSTAY_ON_TOP
) )
1061 group
= GetWindowGroupOfClass(kUtilityWindowClass
) ;
1063 if ( HasFlag( wxFRAME_FLOAT_ON_PARENT
) )
1064 group
= GetWindowGroupOfClass(kFloatingWindowClass
) ;
1066 if ( group
== NULL
&& parent
!= NULL
)
1068 WindowRef parenttlw
= (WindowRef
) parent
->MacGetTopLevelWindowRef();
1070 group
= GetWindowGroupParent( GetWindowGroup( parenttlw
) );
1073 attr
|= kWindowCompositingAttribute
;
1074 #if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale)
1075 attr
|= kWindowFrameworkScaledAttribute
;
1078 if ( HasFlag(wxFRAME_SHAPED
) )
1080 WindowDefSpec customWindowDefSpec
;
1081 customWindowDefSpec
.defType
= kWindowDefProcPtr
;
1082 customWindowDefSpec
.u
.defProc
=
1084 (WindowDefUPP
) wxShapedMacWindowDef
;
1086 NewWindowDefUPP(wxShapedMacWindowDef
);
1088 err
= ::CreateCustomWindow( &customWindowDefSpec
, wclass
,
1089 attr
, &theBoundsRect
,
1090 (WindowRef
*) &m_macWindow
);
1094 err
= ::CreateNewWindow( wclass
, attr
, &theBoundsRect
, (WindowRef
*)&m_macWindow
) ;
1097 if ( err
== noErr
&& m_macWindow
!= NULL
&& group
!= NULL
)
1098 SetWindowGroup( (WindowRef
) m_macWindow
, group
) ;
1100 wxCHECK_RET( err
== noErr
, wxT("Mac OS error when trying to create new window") );
1102 // setup a separate group for each window, so that overlays can be handled easily
1104 WindowGroupRef overlaygroup
= NULL
;
1105 verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether
| kWindowGroupAttrLayerTogether
| kWindowGroupAttrHideOnCollapse
, &overlaygroup
));
1106 verify_noerr( SetWindowGroupParent( overlaygroup
, GetWindowGroup( (WindowRef
) m_macWindow
)));
1107 verify_noerr( SetWindowGroup( (WindowRef
) m_macWindow
, overlaygroup
));
1109 if ( activationScopeSet
)
1111 verify_noerr( SetWindowActivationScope( (WindowRef
) m_macWindow
, activationScope
));
1114 // the create commands are only for content rect,
1115 // so we have to set the size again as structure bounds
1116 SetWindowBounds( (WindowRef
) m_macWindow
, kWindowStructureRgn
, &theBoundsRect
) ;
1118 wxAssociateWinWithMacWindow( (WindowRef
) m_macWindow
, this ) ;
1119 m_peer
= new wxMacControl(this , true /*isRootControl*/) ;
1121 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1122 // the content view, so we have to retrieve it explicitly
1123 HIViewFindByID( HIViewGetRoot( (WindowRef
) m_macWindow
) , kHIViewWindowContentID
,
1124 m_peer
->GetControlRefAddr() ) ;
1125 if ( !m_peer
->Ok() )
1127 // compatibility mode fallback
1128 GetRootControl( (WindowRef
) m_macWindow
, m_peer
->GetControlRefAddr() ) ;
1131 // the root control level handler
1132 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() ) ;
1134 // Causes the inner part of the window not to be metal
1135 // if the style is used before window creation.
1136 #if 0 // TARGET_API_MAC_OSX
1137 if ( m_macUsesCompositing
&& m_macWindow
!= NULL
)
1139 if ( GetExtraStyle() & wxFRAME_EX_METAL
)
1140 MacSetMetalAppearance( true ) ;
1144 if ( m_macWindow
!= NULL
)
1146 MacSetUnifiedAppearance( true ) ;
1149 HIViewRef growBoxRef
= 0 ;
1150 err
= HIViewFindByID( HIViewGetRoot( (WindowRef
)m_macWindow
), kHIViewWindowGrowBoxID
, &growBoxRef
);
1151 if ( err
== noErr
&& growBoxRef
!= 0 )
1152 HIGrowBoxViewSetTransparent( growBoxRef
, true ) ;
1154 // the frame window event handler
1155 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow
)) ) ;
1156 MacInstallTopLevelWindowEventHandler() ;
1158 DoSetWindowVariant( m_windowVariant
) ;
1162 if ( HasFlag(wxFRAME_SHAPED
) )
1164 // default shape matches the window size
1165 wxRegion
rgn( 0, 0, w
, h
);
1169 wxWindowCreateEvent
event(this);
1170 HandleWindowEvent(event
);
1173 // Raise the window to the top of the Z order
1174 void wxNonOwnedWindow::Raise()
1176 ::SelectWindow( (WindowRef
)m_macWindow
) ;
1179 // Lower the window to the bottom of the Z order
1180 void wxNonOwnedWindow::Lower()
1182 ::SendBehind( (WindowRef
)m_macWindow
, NULL
) ;
1185 void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp
)
1187 if (s_macDeactivateWindow
)
1189 wxLogTrace(TRACE_ACTIVATE
,
1190 wxT("Doing delayed deactivation of %p"),
1191 s_macDeactivateWindow
);
1193 s_macDeactivateWindow
->MacActivate(timestamp
, false);
1197 void wxNonOwnedWindow::MacActivate( long timestamp
, bool WXUNUSED(inIsActivating
) )
1199 wxLogTrace(TRACE_ACTIVATE
, wxT("TopLevel=%p::MacActivate"), this);
1201 if (s_macDeactivateWindow
== this)
1202 s_macDeactivateWindow
= NULL
;
1204 MacDelayedDeactivation(timestamp
);
1207 bool wxNonOwnedWindow::Show(bool show
)
1209 if ( !wxWindow::Show(show
) )
1212 bool plainTransition
= true;
1214 #if wxUSE_SYSTEM_OPTIONS
1215 if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION
) )
1216 plainTransition
= ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION
) == 1 ) ;
1221 if ( plainTransition
)
1222 ::ShowWindow( (WindowRef
)m_macWindow
);
1224 ::TransitionWindow( (WindowRef
)m_macWindow
, kWindowZoomTransitionEffect
, kWindowShowTransitionAction
, NULL
);
1226 ::SelectWindow( (WindowRef
)m_macWindow
) ;
1228 // because apps expect a size event to occur at this moment
1229 wxSizeEvent
event(GetSize() , m_windowId
);
1230 event
.SetEventObject(this);
1231 HandleWindowEvent(event
);
1235 if ( plainTransition
)
1236 ::HideWindow( (WindowRef
)m_macWindow
);
1238 ::TransitionWindow( (WindowRef
)m_macWindow
, kWindowZoomTransitionEffect
, kWindowHideTransitionAction
, NULL
);
1244 bool wxNonOwnedWindow::ShowWithEffect(wxShowEffect effect
,
1248 // TODO factor common code
1249 if ( !wxWindow::Show(true) )
1252 WindowTransitionEffect transition
= 0 ;
1255 case wxSHOW_EFFECT_ROLL
:
1256 case wxSHOW_EFFECT_SLIDE
:
1257 transition
= kWindowGenieTransitionEffect
;
1259 case wxSHOW_EFFECT_BLEND
:
1260 transition
= kWindowFadeTransitionEffect
;
1262 case wxSHOW_EFFECT_EXPAND
:
1264 // having sheets would be fine, but this might lead to a repositioning
1267 transition
= kWindowSheetTransitionEffect
;
1270 transition
= kWindowZoomTransitionEffect
;
1274 TransitionWindowOptions options
;
1275 options
.version
= 0;
1276 options
.duration
= timeout
/ 1000.0;
1277 options
.window
= transition
== kWindowSheetTransitionEffect
? (WindowRef
) GetParent()->MacGetTopLevelWindowRef() :0;
1278 options
.userData
= 0;
1280 wxSize size
= wxGetDisplaySize();
1282 GetWindowBounds( (WindowRef
)m_macWindow
, kWindowStructureRgn
, &bounds
);
1283 CGRect hiBounds
= CGRectMake( bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
);
1285 if ( dir
& wxRIGHT
)
1287 hiBounds
.origin
.x
= size
.x
;
1288 hiBounds
.size
.width
= 0;
1292 hiBounds
.origin
.y
= 0;
1293 hiBounds
.size
.height
= 0;
1297 hiBounds
.origin
.y
= size
.y
;
1298 hiBounds
.size
.height
= 0;
1302 hiBounds
.origin
.x
= 0;
1303 hiBounds
.size
.width
= 0;
1306 ::TransitionWindowWithOptions( (WindowRef
)m_macWindow
, transition
, kWindowShowTransitionAction
, transition
== kWindowGenieTransitionEffect
? &hiBounds
: NULL
,
1309 ::SelectWindow( (WindowRef
)m_macWindow
) ;
1311 // because apps expect a size event to occur at this moment
1312 wxSizeEvent
event(GetSize() , m_windowId
);
1313 event
.SetEventObject(this);
1314 HandleWindowEvent(event
);
1319 bool wxNonOwnedWindow::HideWithEffect(wxShowEffect effect
,
1323 if ( !wxWindow::Show(false) )
1326 WindowTransitionEffect transition
= 0 ;
1329 case wxSHOW_EFFECT_ROLL
:
1330 case wxSHOW_EFFECT_SLIDE
:
1331 transition
= kWindowGenieTransitionEffect
;
1333 case wxSHOW_EFFECT_BLEND
:
1334 transition
= kWindowFadeTransitionEffect
;
1336 case wxSHOW_EFFECT_EXPAND
:
1340 transition
= kWindowSheetTransitionEffect
;
1343 transition
= kWindowZoomTransitionEffect
;
1346 TransitionWindowOptions options
;
1347 options
.version
= 0;
1348 options
.duration
= timeout
/ 1000.0;
1349 options
.window
= transition
== kWindowSheetTransitionEffect
? (WindowRef
) GetParent()->MacGetTopLevelWindowRef() :0;
1350 options
.userData
= 0;
1352 wxSize size
= wxGetDisplaySize();
1354 GetWindowBounds( (WindowRef
)m_macWindow
, kWindowStructureRgn
, &bounds
);
1355 CGRect hiBounds
= CGRectMake( bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
);
1357 if ( dir
& wxRIGHT
)
1359 hiBounds
.origin
.x
= size
.x
;
1360 hiBounds
.size
.width
= 0;
1364 hiBounds
.origin
.y
= 0;
1365 hiBounds
.size
.height
= 0;
1369 hiBounds
.origin
.y
= size
.y
;
1370 hiBounds
.size
.height
= 0;
1374 hiBounds
.origin
.x
= 0;
1375 hiBounds
.size
.width
= 0;
1377 ::TransitionWindowWithOptions( (WindowRef
)m_macWindow
, transition
, kWindowHideTransitionAction
, transition
== kWindowGenieTransitionEffect
? &hiBounds
: NULL
,
1383 bool wxNonOwnedWindow::SetTransparent(wxByte alpha
)
1385 OSStatus result
= SetWindowAlpha((WindowRef
)m_macWindow
, (CGFloat
)((alpha
)/255.0));
1386 return result
== noErr
;
1390 bool wxNonOwnedWindow::CanSetTransparent()
1396 void wxNonOwnedWindow::SetExtraStyle(long exStyle
)
1398 if ( GetExtraStyle() == exStyle
)
1401 wxWindow::SetExtraStyle( exStyle
) ;
1403 if ( m_macWindow
!= NULL
)
1405 bool metal
= GetExtraStyle() & wxFRAME_EX_METAL
;
1407 if ( MacGetMetalAppearance() != metal
)
1409 if ( MacGetUnifiedAppearance() )
1410 MacSetUnifiedAppearance( !metal
) ;
1412 MacSetMetalAppearance( metal
) ;
1417 bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style
)
1419 if ( !wxWindow::SetBackgroundStyle(style
) )
1422 WindowRef windowRef
= HIViewGetWindow( (HIViewRef
)GetHandle() );
1424 if ( GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
1426 OSStatus err
= HIWindowChangeFeatures( windowRef
, 0, kWindowIsOpaque
);
1427 verify_noerr( err
);
1428 err
= ReshapeCustomWindow( windowRef
);
1429 verify_noerr( err
);
1435 // TODO: switch to structure bounds -
1436 // we are still using coordinates of the content view
1438 void wxNonOwnedWindow::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1440 Rect content
, structure
;
1442 GetWindowBounds( (WindowRef
) m_macWindow
, kWindowStructureRgn
, &structure
) ;
1443 GetWindowBounds( (WindowRef
) m_macWindow
, kWindowContentRgn
, &content
) ;
1445 left
= content
.left
- structure
.left
;
1446 top
= content
.top
- structure
.top
;
1447 right
= structure
.right
- content
.right
;
1448 bottom
= structure
.bottom
- content
.bottom
;
1451 void wxNonOwnedWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
1453 m_cachedClippedRectValid
= false ;
1454 Rect bounds
= { y
, x
, y
+ height
, x
+ width
} ;
1455 verify_noerr(SetWindowBounds( (WindowRef
) m_macWindow
, kWindowStructureRgn
, &bounds
)) ;
1456 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1459 void wxNonOwnedWindow::DoGetPosition( int *x
, int *y
) const
1463 verify_noerr(GetWindowBounds((WindowRef
) m_macWindow
, kWindowStructureRgn
, &bounds
)) ;
1471 void wxNonOwnedWindow::DoGetSize( int *width
, int *height
) const
1475 verify_noerr(GetWindowBounds((WindowRef
) m_macWindow
, kWindowStructureRgn
, &bounds
)) ;
1478 *width
= bounds
.right
- bounds
.left
;
1480 *height
= bounds
.bottom
- bounds
.top
;
1483 void wxNonOwnedWindow::DoGetClientSize( int *width
, int *height
) const
1487 verify_noerr(GetWindowBounds((WindowRef
) m_macWindow
, kWindowContentRgn
, &bounds
)) ;
1490 *width
= bounds
.right
- bounds
.left
;
1492 *height
= bounds
.bottom
- bounds
.top
;
1495 void wxNonOwnedWindow::MacSetMetalAppearance( bool set
)
1497 if ( MacGetUnifiedAppearance() )
1498 MacSetUnifiedAppearance( false ) ;
1500 MacChangeWindowAttributes( set
? kWindowMetalAttribute
: kWindowNoAttributes
,
1501 set
? kWindowNoAttributes
: kWindowMetalAttribute
) ;
1504 bool wxNonOwnedWindow::MacGetMetalAppearance() const
1506 return MacGetWindowAttributes() & kWindowMetalAttribute
;
1509 void wxNonOwnedWindow::MacSetUnifiedAppearance( bool set
)
1511 if ( MacGetMetalAppearance() )
1512 MacSetMetalAppearance( false ) ;
1514 MacChangeWindowAttributes( set
? kWindowUnifiedTitleAndToolbarAttribute
: kWindowNoAttributes
,
1515 set
? kWindowNoAttributes
: kWindowUnifiedTitleAndToolbarAttribute
) ;
1517 // For some reason, Tiger uses white as the background color for this appearance,
1518 // while most apps using it use the typical striped background. Restore that behavior
1520 // TODO: Determine if we need this on Leopard as well. (should be harmless either way,
1522 SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
) ) ;
1525 bool wxNonOwnedWindow::MacGetUnifiedAppearance() const
1527 return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute
;
1530 void wxNonOwnedWindow::MacChangeWindowAttributes( wxUint32 attributesToSet
, wxUint32 attributesToClear
)
1532 ChangeWindowAttributes( (WindowRef
)m_macWindow
, attributesToSet
, attributesToClear
) ;
1535 wxUint32
wxNonOwnedWindow::MacGetWindowAttributes() const
1538 GetWindowAttributes( (WindowRef
) m_macWindow
, &attr
) ;
1543 void wxNonOwnedWindow::MacPerformUpdates()
1545 // for composited windows this also triggers a redraw of all
1546 // invalid views in the window
1547 HIWindowFlush((WindowRef
) m_macWindow
) ;
1550 // ---------------------------------------------------------------------------
1551 // Shape implementation
1552 // ---------------------------------------------------------------------------
1555 bool wxNonOwnedWindow::SetShape(const wxRegion
& region
)
1557 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false,
1558 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1560 // The empty region signifies that the shape
1561 // should be removed from the window.
1562 if ( region
.IsEmpty() )
1564 wxSize sz
= GetClientSize();
1565 wxRegion
rgn(0, 0, sz
.x
, sz
.y
);
1566 if ( rgn
.IsEmpty() )
1569 return SetShape(rgn
);
1572 // Make a copy of the region
1573 RgnHandle shapeRegion
= NewRgn();
1574 HIShapeGetAsQDRgn( region
.GetWXHRGN(), shapeRegion
);
1576 // Dispose of any shape region we may already have
1577 RgnHandle oldRgn
= (RgnHandle
)GetWRefCon( (WindowRef
)MacGetWindowRef() );
1581 // Save the region so we can use it later
1582 SetWRefCon((WindowRef
)MacGetWindowRef(), (URefCon
)shapeRegion
);
1584 // inform the window manager that the window has changed shape
1585 ReshapeCustomWindow((WindowRef
)MacGetWindowRef());
1590 // ---------------------------------------------------------------------------
1591 // Support functions for shaped windows, based on Apple's CustomWindow sample at
1592 // http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm
1593 // ---------------------------------------------------------------------------
1595 static void wxShapedMacWindowGetPos(WindowRef window
, Rect
* inRect
)
1597 GetWindowPortBounds(window
, inRect
);
1598 Point pt
= { inRect
->top
,inRect
->left
};
1599 wxMacLocalToGlobal( window
, &pt
) ;
1600 inRect
->bottom
+= pt
.v
- inRect
->top
;
1601 inRect
->right
+= pt
.h
- inRect
->left
;
1603 inRect
->left
= pt
.h
;
1606 static SInt32
wxShapedMacWindowGetFeatures(WindowRef
WXUNUSED(window
), SInt32 param
)
1608 /*------------------------------------------------------
1609 Define which options your custom window supports.
1610 --------------------------------------------------------*/
1611 //just enable everything for our demo
1612 *(OptionBits
*)param
=
1615 kWindowCanCollapse
|
1616 //kWindowCanGetWindowRegion |
1617 //kWindowHasTitleBar |
1618 //kWindowSupportsDragHilite |
1619 kWindowCanDrawInCurrentPort
|
1620 //kWindowCanMeasureTitle |
1621 kWindowWantsDisposeAtProcessDeath
|
1622 kWindowSupportsGetGrowImageRegion
|
1623 kWindowDefSupportsColorGrafPort
;
1628 // The content region is left as a rectangle matching the window size, this is
1629 // so the origin in the paint event, and etc. still matches what the
1630 // programmer expects.
1631 static void wxShapedMacWindowContentRegion(WindowRef window
, RgnHandle rgn
)
1634 wxNonOwnedWindow
* win
= wxFindWinFromMacWindow(window
);
1638 wxShapedMacWindowGetPos( window
, &r
) ;
1639 RectRgn( rgn
, &r
) ;
1643 // The structure region is set to the shape given to the SetShape method.
1644 static void wxShapedMacWindowStructureRegion(WindowRef window
, RgnHandle rgn
)
1646 RgnHandle cachedRegion
= (RgnHandle
) GetWRefCon(window
);
1652 wxShapedMacWindowGetPos(window
, &windowRect
); // how big is the window
1653 CopyRgn(cachedRegion
, rgn
); // make a copy of our cached region
1654 OffsetRgn(rgn
, windowRect
.left
, windowRect
.top
); // position it over window
1655 //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size
1659 static SInt32
wxShapedMacWindowGetRegion(WindowRef window
, SInt32 param
)
1661 GetWindowRegionPtr rgnRec
= (GetWindowRegionPtr
)param
;
1666 switch (rgnRec
->regionCode
)
1668 case kWindowStructureRgn
:
1669 wxShapedMacWindowStructureRegion(window
, rgnRec
->winRgn
);
1672 case kWindowContentRgn
:
1673 wxShapedMacWindowContentRegion(window
, rgnRec
->winRgn
);
1677 SetEmptyRgn(rgnRec
->winRgn
);
1684 // Determine the region of the window which was hit
1686 static SInt32
wxShapedMacWindowHitTest(WindowRef window
, SInt32 param
)
1689 static RgnHandle tempRgn
= NULL
;
1691 if (tempRgn
== NULL
)
1694 // get the point clicked
1695 SetPt( &hitPoint
, LoWord(param
), HiWord(param
) );
1697 // Mac OS 8.5 or later
1698 wxShapedMacWindowStructureRegion(window
, tempRgn
);
1699 if (PtInRgn( hitPoint
, tempRgn
)) //in window content region?
1702 // no significant area was hit
1706 static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode
), WindowRef window
, SInt16 message
, SInt32 param
)
1710 case kWindowMsgHitTest
:
1711 return wxShapedMacWindowHitTest(window
, param
);
1713 case kWindowMsgGetFeatures
:
1714 return wxShapedMacWindowGetFeatures(window
, param
);
1716 // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow
1717 case kWindowMsgGetRegion
:
1718 return wxShapedMacWindowGetRegion(window
, param
);