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"
24 #include "wx/settings.h"
27 #if wxUSE_SYSTEM_OPTIONS
28 #include "wx/sysopt.h"
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 // unified title and toolbar constant - not in Tiger headers, so we duplicate it here
36 #define kWindowUnifiedTitleAndToolbarAttribute (1 << 7)
38 // trace mask for activation tracing messages
39 #define TRACE_ACTIVATE "activation"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 // list of all frames and modeless dialogs
46 wxWindowList wxModelessWindows
;
48 static pascal long wxShapedMacWindowDef(short varCode
, WindowRef window
, SInt16 message
, SInt32 param
);
50 // ============================================================================
51 // wxNonOwnedWindow implementation
52 // ============================================================================
54 // ---------------------------------------------------------------------------
56 // ---------------------------------------------------------------------------
58 static const EventTypeSpec eventList
[] =
60 // TODO: remove control related event like key and mouse (except for WindowLeave events)
62 { kEventClassKeyboard
, kEventRawKeyDown
} ,
63 { kEventClassKeyboard
, kEventRawKeyRepeat
} ,
64 { kEventClassKeyboard
, kEventRawKeyUp
} ,
65 { kEventClassKeyboard
, kEventRawKeyModifiersChanged
} ,
67 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
68 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
70 { kEventClassWindow
, kEventWindowShown
} ,
71 { kEventClassWindow
, kEventWindowActivated
} ,
72 { kEventClassWindow
, kEventWindowDeactivated
} ,
73 { kEventClassWindow
, kEventWindowBoundsChanging
} ,
74 { kEventClassWindow
, kEventWindowBoundsChanged
} ,
75 { kEventClassWindow
, kEventWindowClose
} ,
76 { kEventClassWindow
, kEventWindowGetRegion
} ,
78 // we have to catch these events on the toplevel window level,
79 // as controls don't get the raw mouse events anymore
81 { kEventClassMouse
, kEventMouseDown
} ,
82 { kEventClassMouse
, kEventMouseUp
} ,
83 { kEventClassMouse
, kEventMouseWheelMoved
} ,
84 { kEventClassMouse
, kEventMouseMoved
} ,
85 { kEventClassMouse
, kEventMouseDragged
} ,
88 static pascal OSStatus
KeyboardEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
90 OSStatus result
= eventNotHandledErr
;
91 // call DoFindFocus instead of FindFocus, because for Composite Windows(like WxGenericListCtrl)
92 // FindFocus does not return the actual focus window, but the enclosing window
93 wxWindow
* focus
= wxWindow::DoFindFocus();
95 focus
= (wxNonOwnedWindow
*) data
;
97 unsigned char charCode
;
105 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
108 ByteCount dataSize
= 0 ;
109 if ( GetEventParameter( event
, kEventParamKeyUnicodes
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
112 int numChars
= dataSize
/ sizeof( UniChar
) + 1;
114 UniChar
* charBuf
= buf
;
116 if ( numChars
* 2 > 4 )
117 charBuf
= new UniChar
[ numChars
] ;
118 GetEventParameter( event
, kEventParamKeyUnicodes
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
119 charBuf
[ numChars
- 1 ] = 0;
121 #if SIZEOF_WCHAR_T == 2
122 uniChar
= charBuf
[0] ;
124 wxMBConvUTF16 converter
;
125 converter
.MB2WC( uniChar
, (const char*)charBuf
, 2 ) ;
128 if ( numChars
* 2 > 4 )
133 GetEventParameter( event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
134 GetEventParameter( event
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
135 GetEventParameter( event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
136 GetEventParameter( event
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
138 UInt32 message
= (keyCode
<< 8) + charCode
;
139 switch ( GetEventKind( event
) )
141 case kEventRawKeyRepeat
:
142 case kEventRawKeyDown
:
144 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
145 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
146 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
147 if ( /* focus && */ wxTheApp
->MacSendKeyDownEvent(
148 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChar
[0] ) )
152 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
156 case kEventRawKeyUp
:
157 if ( /* focus && */ wxTheApp
->MacSendKeyUpEvent(
158 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChar
[0] ) )
164 case kEventRawKeyModifiersChanged
:
166 wxKeyEvent
event(wxEVT_KEY_DOWN
);
168 event
.m_shiftDown
= modifiers
& shiftKey
;
169 event
.m_controlDown
= modifiers
& controlKey
;
170 event
.m_altDown
= modifiers
& optionKey
;
171 event
.m_metaDown
= modifiers
& cmdKey
;
176 event
.m_uniChar
= uniChar
[0] ;
179 event
.SetTimestamp(when
);
180 event
.SetEventObject(focus
);
182 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & controlKey
)
184 event
.m_keyCode
= WXK_CONTROL
;
185 event
.SetEventType( ( modifiers
& controlKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
186 focus
->HandleWindowEvent( event
) ;
188 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & shiftKey
)
190 event
.m_keyCode
= WXK_SHIFT
;
191 event
.SetEventType( ( modifiers
& shiftKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
192 focus
->HandleWindowEvent( event
) ;
194 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & optionKey
)
196 event
.m_keyCode
= WXK_ALT
;
197 event
.SetEventType( ( modifiers
& optionKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
198 focus
->HandleWindowEvent( event
) ;
200 if ( /* focus && */ (modifiers
^ wxApp::s_lastModifiers
) & cmdKey
)
202 event
.m_keyCode
= WXK_COMMAND
;
203 event
.SetEventType( ( modifiers
& cmdKey
) ? wxEVT_KEY_DOWN
: wxEVT_KEY_UP
) ;
204 focus
->HandleWindowEvent( event
) ;
207 wxApp::s_lastModifiers
= modifiers
;
218 // we don't interfere with foreign controls on our toplevel windows, therefore we always give back eventNotHandledErr
219 // for windows that we didn't create (like eg Scrollbars in a databrowser), or for controls where we did not handle the
222 // This handler can also be called from app level where data (ie target window) may be null or a non wx window
224 wxWindow
* g_MacLastWindow
= NULL
;
226 EventMouseButton g_lastButton
= 0 ;
227 bool g_lastButtonWasFakeRight
= false ;
229 void SetupMouseEvent( wxMouseEvent
&wxevent
, wxMacCarbonEvent
&cEvent
)
231 UInt32 modifiers
= cEvent
.GetParameter
<UInt32
>(kEventParamKeyModifiers
, typeUInt32
) ;
232 Point screenMouseLocation
= cEvent
.GetParameter
<Point
>(kEventParamMouseLocation
) ;
234 // these parameters are not given for all events
235 EventMouseButton button
= 0 ;
236 UInt32 clickCount
= 0 ;
237 UInt32 mouseChord
= 0;
239 cEvent
.GetParameter
<EventMouseButton
>( kEventParamMouseButton
, typeMouseButton
, &button
) ;
240 cEvent
.GetParameter
<UInt32
>( kEventParamClickCount
, typeUInt32
, &clickCount
) ;
241 // the chord is the state of the buttons pressed currently
242 cEvent
.GetParameter
<UInt32
>( kEventParamMouseChord
, typeUInt32
, &mouseChord
) ;
244 wxevent
.m_x
= screenMouseLocation
.h
;
245 wxevent
.m_y
= screenMouseLocation
.v
;
246 wxevent
.m_shiftDown
= modifiers
& shiftKey
;
247 wxevent
.m_controlDown
= modifiers
& controlKey
;
248 wxevent
.m_altDown
= modifiers
& optionKey
;
249 wxevent
.m_metaDown
= modifiers
& cmdKey
;
250 wxevent
.m_clickCount
= clickCount
;
251 wxevent
.SetTimestamp( cEvent
.GetTicks() ) ;
253 // a control click is interpreted as a right click
254 bool thisButtonIsFakeRight
= false ;
255 if ( button
== kEventMouseButtonPrimary
&& (modifiers
& controlKey
) )
257 button
= kEventMouseButtonSecondary
;
258 thisButtonIsFakeRight
= true ;
261 // otherwise we report double clicks by connecting a left click with a ctrl-left click
262 if ( clickCount
> 1 && button
!= g_lastButton
)
265 // we must make sure that our synthetic 'right' button corresponds in
266 // mouse down, moved and mouse up, and does not deliver a right down and left up
268 if ( cEvent
.GetKind() == kEventMouseDown
)
270 g_lastButton
= button
;
271 g_lastButtonWasFakeRight
= thisButtonIsFakeRight
;
277 g_lastButtonWasFakeRight
= false ;
279 else if ( g_lastButton
== kEventMouseButtonSecondary
&& g_lastButtonWasFakeRight
)
280 button
= g_lastButton
;
282 // Adjust the chord mask to remove the primary button and add the
283 // secondary button. It is possible that the secondary button is
284 // already pressed, e.g. on a mouse connected to a laptop, but this
285 // possibility is ignored here:
286 if( thisButtonIsFakeRight
&& ( mouseChord
& 1U ) )
287 mouseChord
= ((mouseChord
& ~1U) | 2U);
290 wxevent
.m_leftDown
= true ;
292 wxevent
.m_rightDown
= true ;
294 wxevent
.m_middleDown
= true ;
296 // translate into wx types
297 switch ( cEvent
.GetKind() )
299 case kEventMouseDown
:
302 case kEventMouseButtonPrimary
:
303 wxevent
.SetEventType( clickCount
> 1 ? wxEVT_LEFT_DCLICK
: wxEVT_LEFT_DOWN
) ;
306 case kEventMouseButtonSecondary
:
307 wxevent
.SetEventType( clickCount
> 1 ? wxEVT_RIGHT_DCLICK
: wxEVT_RIGHT_DOWN
) ;
310 case kEventMouseButtonTertiary
:
311 wxevent
.SetEventType( clickCount
> 1 ? wxEVT_MIDDLE_DCLICK
: wxEVT_MIDDLE_DOWN
) ;
322 case kEventMouseButtonPrimary
:
323 wxevent
.SetEventType( wxEVT_LEFT_UP
) ;
326 case kEventMouseButtonSecondary
:
327 wxevent
.SetEventType( wxEVT_RIGHT_UP
) ;
330 case kEventMouseButtonTertiary
:
331 wxevent
.SetEventType( wxEVT_MIDDLE_UP
) ;
339 case kEventMouseWheelMoved
:
341 wxevent
.SetEventType( wxEVT_MOUSEWHEEL
) ;
343 EventMouseWheelAxis axis
= cEvent
.GetParameter
<EventMouseWheelAxis
>(kEventParamMouseWheelAxis
, typeMouseWheelAxis
) ;
344 SInt32 delta
= cEvent
.GetParameter
<SInt32
>(kEventParamMouseWheelDelta
, typeSInt32
) ;
346 wxevent
.m_wheelRotation
= delta
;
347 wxevent
.m_wheelDelta
= 1;
348 wxevent
.m_linesPerAction
= 1;
349 if ( axis
== kEventMouseWheelAxisX
)
350 wxevent
.m_wheelAxis
= 1;
354 case kEventMouseEntered
:
355 case kEventMouseExited
:
356 case kEventMouseDragged
:
357 case kEventMouseMoved
:
358 wxevent
.SetEventType( wxEVT_MOTION
) ;
365 #define NEW_CAPTURE_HANDLING 1
368 wxMacTopLevelMouseEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
372 wxNonOwnedWindow
* toplevelWindow
= (wxNonOwnedWindow
*) data
;
374 OSStatus result
= eventNotHandledErr
;
376 wxMacCarbonEvent
cEvent( event
) ;
378 Point screenMouseLocation
= cEvent
.GetParameter
<Point
>(kEventParamMouseLocation
) ;
379 Point windowMouseLocation
= screenMouseLocation
;
381 WindowRef window
= NULL
;
382 short windowPart
= ::FindWindow(screenMouseLocation
, &window
);
384 wxWindow
* currentMouseWindow
= NULL
;
385 ControlRef control
= NULL
;
387 #if NEW_CAPTURE_HANDLING
388 if ( wxApp::s_captureWindow
)
390 window
= (WindowRef
) wxApp::s_captureWindow
->MacGetTopLevelWindowRef() ;
391 windowPart
= inContent
;
397 wxMacGlobalToLocal( window
, &windowMouseLocation
) ;
399 if ( wxApp::s_captureWindow
400 #if !NEW_CAPTURE_HANDLING
401 && wxApp::s_captureWindow
->MacGetTopLevelWindowRef() == (WXWindow
) window
&& windowPart
== inContent
405 currentMouseWindow
= wxApp::s_captureWindow
;
407 else if ( (IsWindowActive(window
) && windowPart
== inContent
) )
409 ControlPartCode part
;
410 control
= FindControlUnderMouse( windowMouseLocation
, window
, &part
) ;
411 // if there is no control below the mouse position, send the event to the toplevel window itself
414 currentMouseWindow
= (wxWindow
*) data
;
418 currentMouseWindow
= (wxWindow
*) wxFindControlFromMacControl( control
) ;
419 #ifndef __WXUNIVERSAL__
420 if ( currentMouseWindow
== NULL
&& cEvent
.GetKind() == kEventMouseMoved
)
423 // for wxToolBar to function we have to send certaint events to it
424 // instead of its children (wxToolBarTools)
426 GetSuperControl(control
, &parent
);
427 wxWindow
*wxParent
= (wxWindow
*) wxFindControlFromMacControl( parent
) ;
428 if ( wxParent
&& wxParent
->IsKindOf( CLASSINFO( wxToolBar
) ) )
429 currentMouseWindow
= wxParent
;
435 // disabled windows must not get any input messages
436 if ( currentMouseWindow
&& !currentMouseWindow
->MacIsReallyEnabled() )
437 currentMouseWindow
= NULL
;
441 wxMouseEvent
wxevent(wxEVT_LEFT_DOWN
);
442 SetupMouseEvent( wxevent
, cEvent
) ;
444 // handle all enter / leave events
446 if ( currentMouseWindow
!= g_MacLastWindow
)
448 if ( g_MacLastWindow
)
450 wxMouseEvent
eventleave(wxevent
);
451 eventleave
.SetEventType( wxEVT_LEAVE_WINDOW
);
452 g_MacLastWindow
->ScreenToClient( &eventleave
.m_x
, &eventleave
.m_y
);
453 eventleave
.SetEventObject( g_MacLastWindow
) ;
454 wxevent
.SetId( g_MacLastWindow
->GetId() ) ;
457 wxToolTip::RelayEvent( g_MacLastWindow
, eventleave
);
460 g_MacLastWindow
->HandleWindowEvent(eventleave
);
463 if ( currentMouseWindow
)
465 wxMouseEvent
evententer(wxevent
);
466 evententer
.SetEventType( wxEVT_ENTER_WINDOW
);
467 currentMouseWindow
->ScreenToClient( &evententer
.m_x
, &evententer
.m_y
);
468 evententer
.SetEventObject( currentMouseWindow
) ;
469 wxevent
.SetId( currentMouseWindow
->GetId() ) ;
472 wxToolTip::RelayEvent( currentMouseWindow
, evententer
);
475 currentMouseWindow
->HandleWindowEvent(evententer
);
478 g_MacLastWindow
= currentMouseWindow
;
481 if ( windowPart
== inMenuBar
)
483 // special case menu bar, as we are having a low-level runloop we must do it ourselves
484 if ( cEvent
.GetKind() == kEventMouseDown
)
486 ::MenuSelect( screenMouseLocation
) ;
491 else if ( currentMouseWindow
)
493 wxWindow
*currentMouseWindowParent
= currentMouseWindow
->GetParent();
495 currentMouseWindow
->ScreenToClient( &wxevent
.m_x
, &wxevent
.m_y
) ;
497 wxevent
.SetEventObject( currentMouseWindow
) ;
498 wxevent
.SetId( currentMouseWindow
->GetId() ) ;
500 // make tooltips current
503 if ( wxevent
.GetEventType() == wxEVT_MOTION
)
504 wxToolTip::RelayEvent( currentMouseWindow
, wxevent
);
507 if ( currentMouseWindow
->HandleWindowEvent(wxevent
) )
509 if ((currentMouseWindowParent
!= NULL
) &&
510 (currentMouseWindowParent
->GetChildren().Find(currentMouseWindow
) == NULL
))
511 currentMouseWindow
= NULL
;
517 // if the user code did _not_ handle the event, then perform the
518 // default processing
519 if ( wxevent
.GetEventType() == wxEVT_LEFT_DOWN
)
521 // ... that is set focus to this window
522 if (currentMouseWindow
->CanAcceptFocus() && wxWindow::FindFocus()!=currentMouseWindow
)
523 currentMouseWindow
->SetFocus();
527 if ( cEvent
.GetKind() == kEventMouseUp
&& wxApp::s_captureWindow
)
529 wxApp::s_captureWindow
= NULL
;
535 wxWindow
* cursorTarget
= currentMouseWindow
;
536 wxPoint
cursorPoint( wxevent
.m_x
, wxevent
.m_y
) ;
538 extern wxCursor gGlobalCursor
;
540 if (!gGlobalCursor
.IsOk())
542 while ( cursorTarget
&& !cursorTarget
->MacSetupCursor( cursorPoint
) )
544 cursorTarget
= cursorTarget
->GetParent() ;
546 cursorPoint
+= cursorTarget
->GetPosition();
551 else // currentMouseWindow == NULL
553 // don't mess with controls we don't know about
554 // for some reason returning eventNotHandledErr does not lead to the correct behaviour
555 // so we try sending them the correct control directly
556 if ( cEvent
.GetKind() == kEventMouseDown
&& toplevelWindow
&& control
)
558 EventModifiers modifiers
= cEvent
.GetParameter
<EventModifiers
>(kEventParamKeyModifiers
, typeUInt32
) ;
559 Point clickLocation
= windowMouseLocation
;
562 hiPoint
.x
= clickLocation
.h
;
563 hiPoint
.y
= clickLocation
.v
;
564 HIViewConvertPoint( &hiPoint
, (ControlRef
) toplevelWindow
->GetHandle() , control
) ;
565 clickLocation
.h
= (int)hiPoint
.x
;
566 clickLocation
.v
= (int)hiPoint
.y
;
568 HandleControlClick( control
, clickLocation
, modifiers
, (ControlActionUPP
) -1 ) ;
576 static pascal OSStatus
577 wxNonOwnedWindowEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
581 OSStatus result
= eventNotHandledErr
;
583 wxMacCarbonEvent
cEvent( event
) ;
585 // WindowRef windowRef = cEvent.GetParameter<WindowRef>(kEventParamDirectObject) ;
586 wxNonOwnedWindow
* toplevelWindow
= (wxNonOwnedWindow
*) data
;
588 switch ( GetEventKind( event
) )
590 case kEventWindowActivated
:
592 toplevelWindow
->MacActivate( cEvent
.GetTicks() , true) ;
593 wxActivateEvent
wxevent(wxEVT_ACTIVATE
, true , toplevelWindow
->GetId());
594 wxevent
.SetTimestamp( cEvent
.GetTicks() ) ;
595 wxevent
.SetEventObject(toplevelWindow
);
596 toplevelWindow
->HandleWindowEvent(wxevent
);
597 // we still sending an eventNotHandledErr in order to allow for default processing
601 case kEventWindowDeactivated
:
603 toplevelWindow
->MacActivate(cEvent
.GetTicks() , false) ;
604 wxActivateEvent
wxevent(wxEVT_ACTIVATE
, false , toplevelWindow
->GetId());
605 wxevent
.SetTimestamp( cEvent
.GetTicks() ) ;
606 wxevent
.SetEventObject(toplevelWindow
);
607 toplevelWindow
->HandleWindowEvent(wxevent
);
608 // we still sending an eventNotHandledErr in order to allow for default processing
612 case kEventWindowShown
:
613 toplevelWindow
->Refresh() ;
617 case kEventWindowClose
:
618 toplevelWindow
->Close() ;
622 case kEventWindowBoundsChanged
:
624 UInt32 attributes
= cEvent
.GetParameter
<UInt32
>(kEventParamAttributes
, typeUInt32
) ;
625 Rect newRect
= cEvent
.GetParameter
<Rect
>(kEventParamCurrentBounds
) ;
626 wxRect
r( newRect
.left
, newRect
.top
, newRect
.right
- newRect
.left
, newRect
.bottom
- newRect
.top
) ;
627 if ( attributes
& kWindowBoundsChangeSizeChanged
)
629 #ifndef __WXUNIVERSAL__
630 // according to the other ports we handle this within the OS level
631 // resize event, not within a wxSizeEvent
632 wxFrame
*frame
= wxDynamicCast( toplevelWindow
, wxFrame
) ;
635 frame
->PositionBars();
638 wxSizeEvent
event( r
.GetSize() , toplevelWindow
->GetId() ) ;
639 event
.SetEventObject( toplevelWindow
) ;
641 toplevelWindow
->HandleWindowEvent(event
) ;
642 toplevelWindow
->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
645 if ( attributes
& kWindowBoundsChangeOriginChanged
)
647 wxMoveEvent
event( r
.GetLeftTop() , toplevelWindow
->GetId() ) ;
648 event
.SetEventObject( toplevelWindow
) ;
649 toplevelWindow
->HandleWindowEvent(event
) ;
656 case kEventWindowBoundsChanging
:
658 UInt32 attributes
= cEvent
.GetParameter
<UInt32
>(kEventParamAttributes
,typeUInt32
) ;
659 Rect newRect
= cEvent
.GetParameter
<Rect
>(kEventParamCurrentBounds
) ;
661 if ( (attributes
& kWindowBoundsChangeSizeChanged
) || (attributes
& kWindowBoundsChangeOriginChanged
) )
663 // all (Mac) rects are in content area coordinates, all wxRects in structure coordinates
664 int left
, top
, right
, bottom
;
665 toplevelWindow
->MacGetContentAreaInset( left
, top
, right
, bottom
) ;
670 newRect
.right
- newRect
.left
+ left
+ right
,
671 newRect
.bottom
- newRect
.top
+ top
+ bottom
) ;
673 // this is a EVT_SIZING not a EVT_SIZE type !
674 wxSizeEvent
wxevent( r
, toplevelWindow
->GetId() ) ;
675 wxevent
.SetEventObject( toplevelWindow
) ;
677 if ( toplevelWindow
->HandleWindowEvent(wxevent
) )
678 adjustR
= wxevent
.GetRect() ;
680 if ( toplevelWindow
->GetMaxWidth() != -1 && adjustR
.GetWidth() > toplevelWindow
->GetMaxWidth() )
681 adjustR
.SetWidth( toplevelWindow
->GetMaxWidth() ) ;
682 if ( toplevelWindow
->GetMaxHeight() != -1 && adjustR
.GetHeight() > toplevelWindow
->GetMaxHeight() )
683 adjustR
.SetHeight( toplevelWindow
->GetMaxHeight() ) ;
684 if ( toplevelWindow
->GetMinWidth() != -1 && adjustR
.GetWidth() < toplevelWindow
->GetMinWidth() )
685 adjustR
.SetWidth( toplevelWindow
->GetMinWidth() ) ;
686 if ( toplevelWindow
->GetMinHeight() != -1 && adjustR
.GetHeight() < toplevelWindow
->GetMinHeight() )
687 adjustR
.SetHeight( toplevelWindow
->GetMinHeight() ) ;
688 const Rect adjustedRect
= { adjustR
.y
+ top
, adjustR
.x
+ left
, adjustR
.y
+ adjustR
.height
- bottom
, adjustR
.x
+ adjustR
.width
- right
} ;
689 if ( !EqualRect( &newRect
, &adjustedRect
) )
690 cEvent
.SetParameter
<Rect
>( kEventParamCurrentBounds
, &adjustedRect
) ;
691 toplevelWindow
->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
698 case kEventWindowGetRegion
:
700 if ( toplevelWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
702 WindowRegionCode windowRegionCode
;
704 // Fetch the region code that is being queried
705 GetEventParameter( event
,
706 kEventParamWindowRegionCode
,
707 typeWindowRegionCode
, NULL
,
708 sizeof windowRegionCode
, NULL
,
709 &windowRegionCode
) ;
711 // If it is the opaque region code then set the
712 // region to empty and return noErr to stop event
714 if ( windowRegionCode
== kWindowOpaqueRgn
) {
716 GetEventParameter( event
,
717 kEventParamRgnHandle
,
718 typeQDRgnHandle
, NULL
,
721 SetEmptyRgn(region
) ;
735 // mix this in from window.cpp
736 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
) ;
738 pascal OSStatus
wxNonOwnedEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
740 OSStatus result
= eventNotHandledErr
;
742 switch ( GetEventClass( event
) )
744 case kEventClassTextInput
:
745 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
748 case kEventClassKeyboard
:
749 result
= KeyboardEventHandler( handler
, event
, data
) ;
752 case kEventClassWindow
:
753 result
= wxNonOwnedWindowEventHandler( handler
, event
, data
) ;
756 case kEventClassMouse
:
757 result
= wxMacTopLevelMouseEventHandler( handler
, event
, data
) ;
767 DEFINE_ONE_SHOT_HANDLER_GETTER( wxNonOwnedEventHandler
)
769 // ---------------------------------------------------------------------------
770 // wxWindowMac utility functions
771 // ---------------------------------------------------------------------------
773 // Find an item given the Macintosh Window Reference
775 WX_DECLARE_HASH_MAP(WindowRef
, wxNonOwnedWindow
*, wxPointerHash
, wxPointerEqual
, MacWindowMap
);
777 static MacWindowMap wxWinMacWindowList
;
779 wxNonOwnedWindow
*wxFindWinFromMacWindow(WindowRef inWindowRef
)
781 MacWindowMap::iterator node
= wxWinMacWindowList
.find(inWindowRef
);
783 return (node
== wxWinMacWindowList
.end()) ? NULL
: node
->second
;
786 void wxAssociateWinWithMacWindow(WindowRef inWindowRef
, wxNonOwnedWindow
*win
) ;
787 void wxAssociateWinWithMacWindow(WindowRef inWindowRef
, wxNonOwnedWindow
*win
)
789 // adding NULL WindowRef is (first) surely a result of an error and
791 wxCHECK_RET( inWindowRef
!= (WindowRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
793 wxWinMacWindowList
[inWindowRef
] = win
;
796 void wxRemoveMacWindowAssociation(wxNonOwnedWindow
*win
) ;
797 void wxRemoveMacWindowAssociation(wxNonOwnedWindow
*win
)
799 MacWindowMap::iterator it
;
800 for ( it
= wxWinMacWindowList
.begin(); it
!= wxWinMacWindowList
.end(); ++it
)
802 if ( it
->second
== win
)
804 wxWinMacWindowList
.erase(it
);
810 // ----------------------------------------------------------------------------
811 // wxNonOwnedWindow creation
812 // ----------------------------------------------------------------------------
814 wxNonOwnedWindow
*wxNonOwnedWindow::s_macDeactivateWindow
= NULL
;
816 void wxNonOwnedWindow::Init()
819 m_macEventHandler
= NULL
;
822 wxMacDeferredWindowDeleter::wxMacDeferredWindowDeleter( WindowRef windowRef
)
824 m_macWindow
= windowRef
;
827 wxMacDeferredWindowDeleter::~wxMacDeferredWindowDeleter()
829 DisposeWindow( (WindowRef
) m_macWindow
) ;
832 bool wxNonOwnedWindow::Create(wxWindow
*parent
,
837 const wxString
& name
)
842 m_windowStyle
= style
;
846 m_windowId
= id
== -1 ? NewControlId() : id
;
848 DoMacCreateRealWindow( parent
, pos
, size
, style
, name
) ;
850 SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
));
852 if (GetExtraStyle() & wxFRAME_EX_METAL
)
853 MacSetMetalAppearance(true);
855 wxTopLevelWindows
.Append(this);
858 parent
->AddChild(this);
863 wxNonOwnedWindow::~wxNonOwnedWindow()
868 wxToolTip::NotifyWindowDelete(m_macWindow
) ;
870 wxPendingDelete
.Append( new wxMacDeferredWindowDeleter( (WindowRef
) m_macWindow
) ) ;
873 if ( m_macEventHandler
)
875 ::RemoveEventHandler((EventHandlerRef
) m_macEventHandler
);
876 m_macEventHandler
= NULL
;
879 wxRemoveMacWindowAssociation( this ) ;
881 if ( wxModelessWindows
.Find(this) )
882 wxModelessWindows
.DeleteObject(this);
884 // avoid dangling refs
885 if ( s_macDeactivateWindow
== this )
886 s_macDeactivateWindow
= NULL
;
889 // ----------------------------------------------------------------------------
890 // wxNonOwnedWindow misc
891 // ----------------------------------------------------------------------------
893 wxPoint
wxNonOwnedWindow::GetClientAreaOrigin() const
895 return wxPoint(0, 0) ;
898 bool wxNonOwnedWindow::SetBackgroundColour(const wxColour
& c
)
901 if ( col
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
902 col
= wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground
));
903 else if ( col
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
904 col
= wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive
));
906 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
909 if ( col
== wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground
)) )
911 SetThemeWindowBackground( (WindowRef
) m_macWindow
, kThemeBrushDocumentWindowBackground
, false ) ;
912 SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
914 else if ( col
== wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive
)) )
916 SetThemeWindowBackground( (WindowRef
) m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
917 SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
922 void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window
, EventHandlerRef
* handler
, void *ref
)
924 InstallWindowEventHandler(window
, GetwxNonOwnedEventHandlerUPP(),
925 GetEventTypeCount(eventList
), eventList
, ref
, handler
);
928 void wxNonOwnedWindow::MacInstallTopLevelWindowEventHandler()
930 if ( m_macEventHandler
!= NULL
)
932 verify_noerr( ::RemoveEventHandler( (EventHandlerRef
) m_macEventHandler
) ) ;
934 wxNonOwnedWindowInstallTopLevelWindowEventHandler(MAC_WXHWND(m_macWindow
),(EventHandlerRef
*)&m_macEventHandler
,this);
937 void wxNonOwnedWindow::MacCreateRealWindow(
941 const wxString
& name
)
943 DoMacCreateRealWindow( NULL
, pos
, size
, style
, name
);
946 void wxNonOwnedWindow::DoMacCreateRealWindow(
951 const wxString
& name
)
953 OSStatus err
= noErr
;
955 m_windowStyle
= style
;
963 wxRect display
= wxGetClientDisplayRect() ;
965 if ( x
== wxDefaultPosition
.x
)
968 if ( y
== wxDefaultPosition
.y
)
971 int w
= WidthDefault(size
.x
);
972 int h
= HeightDefault(size
.y
);
974 ::SetRect(&theBoundsRect
, x
, y
, x
+ w
, y
+ h
);
976 // translate the window attributes in the appropriate window class and attributes
977 WindowClass wclass
= 0;
978 WindowAttributes attr
= kWindowNoAttributes
;
979 WindowGroupRef group
= NULL
;
980 bool activationScopeSet
= false;
981 WindowActivationScope activationScope
= kWindowActivationScopeNone
;
983 if ( HasFlag( wxFRAME_TOOL_WINDOW
) )
986 HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) ||
987 HasFlag( wxSYSTEM_MENU
) || HasFlag( wxCAPTION
) ||
988 HasFlag(wxTINY_CAPTION_HORIZ
) || HasFlag(wxTINY_CAPTION_VERT
)
991 if ( HasFlag( wxSTAY_ON_TOP
) )
992 wclass
= kUtilityWindowClass
;
994 wclass
= kFloatingWindowClass
;
996 if ( HasFlag(wxTINY_CAPTION_VERT
) )
997 attr
|= kWindowSideTitlebarAttribute
;
1001 wclass
= kPlainWindowClass
;
1002 activationScopeSet
= true;
1003 activationScope
= kWindowActivationScopeNone
;
1006 else if ( HasFlag( wxPOPUP_WINDOW
) )
1009 // Until we've got a real wxPopupWindow class on wxMac make it a
1010 // little easier for wxFrame to be used to emulate it and workaround
1011 // the lack of wxPopupWindow.
1012 if ( HasFlag( wxBORDER_NONE
) )
1013 wclass
= kHelpWindowClass
; // has no border
1015 wclass
= kPlainWindowClass
; // has a single line border, it will have to do for now
1016 //attr |= kWindowNoShadowAttribute; // turn off the shadow Should we??
1017 group
= GetWindowGroupOfClass( // float above other windows
1018 kFloatingWindowClass
) ;
1020 else if ( HasFlag( wxCAPTION
) )
1022 wclass
= kDocumentWindowClass
;
1023 attr
|= kWindowInWindowMenuAttribute
;
1025 else if ( HasFlag( wxFRAME_DRAWER
) )
1027 wclass
= kDrawerWindowClass
;
1031 if ( HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) ||
1032 HasFlag( wxCLOSE_BOX
) || HasFlag( wxSYSTEM_MENU
) )
1034 wclass
= kDocumentWindowClass
;
1036 else if ( HasFlag( wxNO_BORDER
) )
1038 wclass
= kSimpleWindowClass
;
1042 wclass
= kPlainWindowClass
;
1046 if ( wclass
!= kPlainWindowClass
)
1048 if ( HasFlag( wxMINIMIZE_BOX
) )
1049 attr
|= kWindowCollapseBoxAttribute
;
1051 if ( HasFlag( wxMAXIMIZE_BOX
) )
1052 attr
|= kWindowFullZoomAttribute
;
1054 if ( HasFlag( wxRESIZE_BORDER
) )
1055 attr
|= kWindowResizableAttribute
;
1057 if ( HasFlag( wxCLOSE_BOX
) )
1058 attr
|= kWindowCloseBoxAttribute
;
1060 attr
|= kWindowLiveResizeAttribute
;
1062 if ( HasFlag(wxSTAY_ON_TOP
) )
1063 group
= GetWindowGroupOfClass(kUtilityWindowClass
) ;
1065 if ( HasFlag( wxFRAME_FLOAT_ON_PARENT
) )
1066 group
= GetWindowGroupOfClass(kFloatingWindowClass
) ;
1068 if ( group
== NULL
&& parent
!= NULL
)
1070 WindowRef parenttlw
= (WindowRef
) parent
->MacGetTopLevelWindowRef();
1072 group
= GetWindowGroupParent( GetWindowGroup( parenttlw
) );
1075 attr
|= kWindowCompositingAttribute
;
1076 #if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale)
1077 attr
|= kWindowFrameworkScaledAttribute
;
1080 if ( HasFlag(wxFRAME_SHAPED
) )
1082 WindowDefSpec customWindowDefSpec
;
1083 customWindowDefSpec
.defType
= kWindowDefProcPtr
;
1084 customWindowDefSpec
.u
.defProc
=
1086 (WindowDefUPP
) wxShapedMacWindowDef
;
1088 NewWindowDefUPP(wxShapedMacWindowDef
);
1090 err
= ::CreateCustomWindow( &customWindowDefSpec
, wclass
,
1091 attr
, &theBoundsRect
,
1092 (WindowRef
*) &m_macWindow
);
1096 err
= ::CreateNewWindow( wclass
, attr
, &theBoundsRect
, (WindowRef
*)&m_macWindow
) ;
1099 if ( err
== noErr
&& m_macWindow
!= NULL
&& group
!= NULL
)
1100 SetWindowGroup( (WindowRef
) m_macWindow
, group
) ;
1102 wxCHECK_RET( err
== noErr
, wxT("Mac OS error when trying to create new window") );
1104 // setup a separate group for each window, so that overlays can be handled easily
1106 WindowGroupRef overlaygroup
= NULL
;
1107 verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether
| kWindowGroupAttrLayerTogether
| kWindowGroupAttrHideOnCollapse
, &overlaygroup
));
1108 verify_noerr( SetWindowGroupParent( overlaygroup
, GetWindowGroup( (WindowRef
) m_macWindow
)));
1109 verify_noerr( SetWindowGroup( (WindowRef
) m_macWindow
, overlaygroup
));
1111 if ( activationScopeSet
)
1113 verify_noerr( SetWindowActivationScope( (WindowRef
) m_macWindow
, activationScope
));
1116 // the create commands are only for content rect,
1117 // so we have to set the size again as structure bounds
1118 SetWindowBounds( (WindowRef
) m_macWindow
, kWindowStructureRgn
, &theBoundsRect
) ;
1120 wxAssociateWinWithMacWindow( (WindowRef
) m_macWindow
, this ) ;
1121 m_peer
= new wxMacControl(this , true /*isRootControl*/) ;
1123 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1124 // the content view, so we have to retrieve it explicitly
1125 HIViewFindByID( HIViewGetRoot( (WindowRef
) m_macWindow
) , kHIViewWindowContentID
,
1126 m_peer
->GetControlRefAddr() ) ;
1127 if ( !m_peer
->Ok() )
1129 // compatibility mode fallback
1130 GetRootControl( (WindowRef
) m_macWindow
, m_peer
->GetControlRefAddr() ) ;
1133 // the root control level handler
1134 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() ) ;
1136 // Causes the inner part of the window not to be metal
1137 // if the style is used before window creation.
1138 #if 0 // TARGET_API_MAC_OSX
1139 if ( m_macUsesCompositing
&& m_macWindow
!= NULL
)
1141 if ( GetExtraStyle() & wxFRAME_EX_METAL
)
1142 MacSetMetalAppearance( true ) ;
1146 if ( m_macWindow
!= NULL
)
1148 MacSetUnifiedAppearance( true ) ;
1151 HIViewRef growBoxRef
= 0 ;
1152 err
= HIViewFindByID( HIViewGetRoot( (WindowRef
)m_macWindow
), kHIViewWindowGrowBoxID
, &growBoxRef
);
1153 if ( err
== noErr
&& growBoxRef
!= 0 )
1154 HIGrowBoxViewSetTransparent( growBoxRef
, true ) ;
1156 // the frame window event handler
1157 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow
)) ) ;
1158 MacInstallTopLevelWindowEventHandler() ;
1160 DoSetWindowVariant( m_windowVariant
) ;
1164 if ( HasFlag(wxFRAME_SHAPED
) )
1166 // default shape matches the window size
1167 wxRegion
rgn( 0, 0, w
, h
);
1171 wxWindowCreateEvent
event(this);
1172 HandleWindowEvent(event
);
1175 // Raise the window to the top of the Z order
1176 void wxNonOwnedWindow::Raise()
1178 ::SelectWindow( (WindowRef
)m_macWindow
) ;
1181 // Lower the window to the bottom of the Z order
1182 void wxNonOwnedWindow::Lower()
1184 ::SendBehind( (WindowRef
)m_macWindow
, NULL
) ;
1187 void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp
)
1189 if (s_macDeactivateWindow
)
1191 wxLogTrace(TRACE_ACTIVATE
,
1192 wxT("Doing delayed deactivation of %p"),
1193 s_macDeactivateWindow
);
1195 s_macDeactivateWindow
->MacActivate(timestamp
, false);
1199 void wxNonOwnedWindow::MacActivate( long timestamp
, bool WXUNUSED(inIsActivating
) )
1201 wxLogTrace(TRACE_ACTIVATE
, wxT("TopLevel=%p::MacActivate"), this);
1203 if (s_macDeactivateWindow
== this)
1204 s_macDeactivateWindow
= NULL
;
1206 MacDelayedDeactivation(timestamp
);
1209 bool wxNonOwnedWindow::Show(bool show
)
1211 if ( !wxWindow::Show(show
) )
1214 bool plainTransition
= true;
1216 #if wxUSE_SYSTEM_OPTIONS
1217 if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION
) )
1218 plainTransition
= ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION
) == 1 ) ;
1223 if ( plainTransition
)
1224 ::ShowWindow( (WindowRef
)m_macWindow
);
1226 ::TransitionWindow( (WindowRef
)m_macWindow
, kWindowZoomTransitionEffect
, kWindowShowTransitionAction
, NULL
);
1228 ::SelectWindow( (WindowRef
)m_macWindow
) ;
1230 // because apps expect a size event to occur at this moment
1231 wxSizeEvent
event(GetSize() , m_windowId
);
1232 event
.SetEventObject(this);
1233 HandleWindowEvent(event
);
1237 if ( plainTransition
)
1238 ::HideWindow( (WindowRef
)m_macWindow
);
1240 ::TransitionWindow( (WindowRef
)m_macWindow
, kWindowZoomTransitionEffect
, kWindowHideTransitionAction
, NULL
);
1246 bool wxNonOwnedWindow::ShowWithEffect(wxShowEffect effect
,
1250 // TODO factor common code
1251 if ( !wxWindow::Show(true) )
1254 WindowTransitionEffect transition
= 0 ;
1257 case wxSHOW_EFFECT_ROLL
:
1258 case wxSHOW_EFFECT_SLIDE
:
1259 transition
= kWindowGenieTransitionEffect
;
1261 case wxSHOW_EFFECT_BLEND
:
1262 transition
= kWindowFadeTransitionEffect
;
1264 case wxSHOW_EFFECT_EXPAND
:
1266 // having sheets would be fine, but this might lead to a repositioning
1269 transition
= kWindowSheetTransitionEffect
;
1272 transition
= kWindowZoomTransitionEffect
;
1276 TransitionWindowOptions options
;
1277 options
.version
= 0;
1278 options
.duration
= timeout
/ 1000.0;
1279 options
.window
= transition
== kWindowSheetTransitionEffect
? (WindowRef
) GetParent()->MacGetTopLevelWindowRef() :0;
1280 options
.userData
= 0;
1282 wxSize size
= wxGetDisplaySize();
1284 GetWindowBounds( (WindowRef
)m_macWindow
, kWindowStructureRgn
, &bounds
);
1285 CGRect hiBounds
= CGRectMake( bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
);
1287 if ( dir
& wxRIGHT
)
1289 hiBounds
.origin
.x
= size
.x
;
1290 hiBounds
.size
.width
= 0;
1294 hiBounds
.origin
.y
= 0;
1295 hiBounds
.size
.height
= 0;
1299 hiBounds
.origin
.y
= size
.y
;
1300 hiBounds
.size
.height
= 0;
1304 hiBounds
.origin
.x
= 0;
1305 hiBounds
.size
.width
= 0;
1308 ::TransitionWindowWithOptions( (WindowRef
)m_macWindow
, transition
, kWindowShowTransitionAction
, transition
== kWindowGenieTransitionEffect
? &hiBounds
: NULL
,
1311 ::SelectWindow( (WindowRef
)m_macWindow
) ;
1313 // because apps expect a size event to occur at this moment
1314 wxSizeEvent
event(GetSize() , m_windowId
);
1315 event
.SetEventObject(this);
1316 HandleWindowEvent(event
);
1321 bool wxNonOwnedWindow::HideWithEffect(wxShowEffect effect
,
1325 if ( !wxWindow::Show(false) )
1328 WindowTransitionEffect transition
= 0 ;
1331 case wxSHOW_EFFECT_ROLL
:
1332 case wxSHOW_EFFECT_SLIDE
:
1333 transition
= kWindowGenieTransitionEffect
;
1335 case wxSHOW_EFFECT_BLEND
:
1336 transition
= kWindowFadeTransitionEffect
;
1338 case wxSHOW_EFFECT_EXPAND
:
1342 transition
= kWindowSheetTransitionEffect
;
1345 transition
= kWindowZoomTransitionEffect
;
1348 TransitionWindowOptions options
;
1349 options
.version
= 0;
1350 options
.duration
= timeout
/ 1000.0;
1351 options
.window
= transition
== kWindowSheetTransitionEffect
? (WindowRef
) GetParent()->MacGetTopLevelWindowRef() :0;
1352 options
.userData
= 0;
1354 wxSize size
= wxGetDisplaySize();
1356 GetWindowBounds( (WindowRef
)m_macWindow
, kWindowStructureRgn
, &bounds
);
1357 CGRect hiBounds
= CGRectMake( bounds
.left
, bounds
.top
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
);
1359 if ( dir
& wxRIGHT
)
1361 hiBounds
.origin
.x
= size
.x
;
1362 hiBounds
.size
.width
= 0;
1366 hiBounds
.origin
.y
= 0;
1367 hiBounds
.size
.height
= 0;
1371 hiBounds
.origin
.y
= size
.y
;
1372 hiBounds
.size
.height
= 0;
1376 hiBounds
.origin
.x
= 0;
1377 hiBounds
.size
.width
= 0;
1379 ::TransitionWindowWithOptions( (WindowRef
)m_macWindow
, transition
, kWindowHideTransitionAction
, transition
== kWindowGenieTransitionEffect
? &hiBounds
: NULL
,
1385 bool wxNonOwnedWindow::SetTransparent(wxByte alpha
)
1387 OSStatus result
= SetWindowAlpha((WindowRef
)m_macWindow
, (CGFloat
)((alpha
)/255.0));
1388 return result
== noErr
;
1392 bool wxNonOwnedWindow::CanSetTransparent()
1398 void wxNonOwnedWindow::SetExtraStyle(long exStyle
)
1400 if ( GetExtraStyle() == exStyle
)
1403 wxWindow::SetExtraStyle( exStyle
) ;
1405 if ( m_macWindow
!= NULL
)
1407 bool metal
= GetExtraStyle() & wxFRAME_EX_METAL
;
1409 if ( MacGetMetalAppearance() != metal
)
1411 if ( MacGetUnifiedAppearance() )
1412 MacSetUnifiedAppearance( !metal
) ;
1414 MacSetMetalAppearance( metal
) ;
1419 bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style
)
1421 if ( !wxWindow::SetBackgroundStyle(style
) )
1424 WindowRef windowRef
= HIViewGetWindow( (HIViewRef
)GetHandle() );
1426 if ( GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
1428 OSStatus err
= HIWindowChangeFeatures( windowRef
, 0, kWindowIsOpaque
);
1429 verify_noerr( err
);
1430 err
= ReshapeCustomWindow( windowRef
);
1431 verify_noerr( err
);
1437 // TODO: switch to structure bounds -
1438 // we are still using coordinates of the content view
1440 void wxNonOwnedWindow::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1442 Rect content
, structure
;
1444 GetWindowBounds( (WindowRef
) m_macWindow
, kWindowStructureRgn
, &structure
) ;
1445 GetWindowBounds( (WindowRef
) m_macWindow
, kWindowContentRgn
, &content
) ;
1447 left
= content
.left
- structure
.left
;
1448 top
= content
.top
- structure
.top
;
1449 right
= structure
.right
- content
.right
;
1450 bottom
= structure
.bottom
- content
.bottom
;
1453 void wxNonOwnedWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
1455 m_cachedClippedRectValid
= false ;
1456 Rect bounds
= { y
, x
, y
+ height
, x
+ width
} ;
1457 verify_noerr(SetWindowBounds( (WindowRef
) m_macWindow
, kWindowStructureRgn
, &bounds
)) ;
1458 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1461 void wxNonOwnedWindow::DoGetPosition( int *x
, int *y
) const
1465 verify_noerr(GetWindowBounds((WindowRef
) m_macWindow
, kWindowStructureRgn
, &bounds
)) ;
1473 void wxNonOwnedWindow::DoGetSize( int *width
, int *height
) const
1477 verify_noerr(GetWindowBounds((WindowRef
) m_macWindow
, kWindowStructureRgn
, &bounds
)) ;
1480 *width
= bounds
.right
- bounds
.left
;
1482 *height
= bounds
.bottom
- bounds
.top
;
1485 void wxNonOwnedWindow::DoGetClientSize( int *width
, int *height
) const
1489 verify_noerr(GetWindowBounds((WindowRef
) m_macWindow
, kWindowContentRgn
, &bounds
)) ;
1492 *width
= bounds
.right
- bounds
.left
;
1494 *height
= bounds
.bottom
- bounds
.top
;
1497 void wxNonOwnedWindow::MacSetMetalAppearance( bool set
)
1499 if ( MacGetUnifiedAppearance() )
1500 MacSetUnifiedAppearance( false ) ;
1502 MacChangeWindowAttributes( set
? kWindowMetalAttribute
: kWindowNoAttributes
,
1503 set
? kWindowNoAttributes
: kWindowMetalAttribute
) ;
1506 bool wxNonOwnedWindow::MacGetMetalAppearance() const
1508 return MacGetWindowAttributes() & kWindowMetalAttribute
;
1511 void wxNonOwnedWindow::MacSetUnifiedAppearance( bool set
)
1513 if ( MacGetMetalAppearance() )
1514 MacSetMetalAppearance( false ) ;
1516 MacChangeWindowAttributes( set
? kWindowUnifiedTitleAndToolbarAttribute
: kWindowNoAttributes
,
1517 set
? kWindowNoAttributes
: kWindowUnifiedTitleAndToolbarAttribute
) ;
1519 // For some reason, Tiger uses white as the background color for this appearance,
1520 // while most apps using it use the typical striped background. Restore that behavior
1522 // TODO: Determine if we need this on Leopard as well. (should be harmless either way,
1524 SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
) ) ;
1527 bool wxNonOwnedWindow::MacGetUnifiedAppearance() const
1529 return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute
;
1532 void wxNonOwnedWindow::MacChangeWindowAttributes( wxUint32 attributesToSet
, wxUint32 attributesToClear
)
1534 ChangeWindowAttributes( (WindowRef
)m_macWindow
, attributesToSet
, attributesToClear
) ;
1537 wxUint32
wxNonOwnedWindow::MacGetWindowAttributes() const
1540 GetWindowAttributes( (WindowRef
) m_macWindow
, &attr
) ;
1545 void wxNonOwnedWindow::MacPerformUpdates()
1547 // for composited windows this also triggers a redraw of all
1548 // invalid views in the window
1549 HIWindowFlush((WindowRef
) m_macWindow
) ;
1552 // ---------------------------------------------------------------------------
1553 // Shape implementation
1554 // ---------------------------------------------------------------------------
1557 bool wxNonOwnedWindow::SetShape(const wxRegion
& region
)
1559 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false,
1560 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
1562 // The empty region signifies that the shape
1563 // should be removed from the window.
1564 if ( region
.IsEmpty() )
1566 wxSize sz
= GetClientSize();
1567 wxRegion
rgn(0, 0, sz
.x
, sz
.y
);
1568 if ( rgn
.IsEmpty() )
1571 return SetShape(rgn
);
1574 // Make a copy of the region
1575 RgnHandle shapeRegion
= NewRgn();
1576 HIShapeGetAsQDRgn( region
.GetWXHRGN(), shapeRegion
);
1578 // Dispose of any shape region we may already have
1579 RgnHandle oldRgn
= (RgnHandle
)GetWRefCon( (WindowRef
)MacGetWindowRef() );
1583 // Save the region so we can use it later
1584 SetWRefCon((WindowRef
)MacGetWindowRef(), (URefCon
)shapeRegion
);
1586 // inform the window manager that the window has changed shape
1587 ReshapeCustomWindow((WindowRef
)MacGetWindowRef());
1592 // ---------------------------------------------------------------------------
1593 // Support functions for shaped windows, based on Apple's CustomWindow sample at
1594 // http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm
1595 // ---------------------------------------------------------------------------
1597 static void wxShapedMacWindowGetPos(WindowRef window
, Rect
* inRect
)
1599 GetWindowPortBounds(window
, inRect
);
1600 Point pt
= { inRect
->top
,inRect
->left
};
1601 wxMacLocalToGlobal( window
, &pt
) ;
1602 inRect
->bottom
+= pt
.v
- inRect
->top
;
1603 inRect
->right
+= pt
.h
- inRect
->left
;
1605 inRect
->left
= pt
.h
;
1608 static SInt32
wxShapedMacWindowGetFeatures(WindowRef
WXUNUSED(window
), SInt32 param
)
1610 /*------------------------------------------------------
1611 Define which options your custom window supports.
1612 --------------------------------------------------------*/
1613 //just enable everything for our demo
1614 *(OptionBits
*)param
=
1617 kWindowCanCollapse
|
1618 //kWindowCanGetWindowRegion |
1619 //kWindowHasTitleBar |
1620 //kWindowSupportsDragHilite |
1621 kWindowCanDrawInCurrentPort
|
1622 //kWindowCanMeasureTitle |
1623 kWindowWantsDisposeAtProcessDeath
|
1624 kWindowSupportsGetGrowImageRegion
|
1625 kWindowDefSupportsColorGrafPort
;
1630 // The content region is left as a rectangle matching the window size, this is
1631 // so the origin in the paint event, and etc. still matches what the
1632 // programmer expects.
1633 static void wxShapedMacWindowContentRegion(WindowRef window
, RgnHandle rgn
)
1636 wxNonOwnedWindow
* win
= wxFindWinFromMacWindow(window
);
1640 wxShapedMacWindowGetPos( window
, &r
) ;
1641 RectRgn( rgn
, &r
) ;
1645 // The structure region is set to the shape given to the SetShape method.
1646 static void wxShapedMacWindowStructureRegion(WindowRef window
, RgnHandle rgn
)
1648 RgnHandle cachedRegion
= (RgnHandle
) GetWRefCon(window
);
1654 wxShapedMacWindowGetPos(window
, &windowRect
); // how big is the window
1655 CopyRgn(cachedRegion
, rgn
); // make a copy of our cached region
1656 OffsetRgn(rgn
, windowRect
.left
, windowRect
.top
); // position it over window
1657 //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size
1661 static SInt32
wxShapedMacWindowGetRegion(WindowRef window
, SInt32 param
)
1663 GetWindowRegionPtr rgnRec
= (GetWindowRegionPtr
)param
;
1668 switch (rgnRec
->regionCode
)
1670 case kWindowStructureRgn
:
1671 wxShapedMacWindowStructureRegion(window
, rgnRec
->winRgn
);
1674 case kWindowContentRgn
:
1675 wxShapedMacWindowContentRegion(window
, rgnRec
->winRgn
);
1679 SetEmptyRgn(rgnRec
->winRgn
);
1686 // Determine the region of the window which was hit
1688 static SInt32
wxShapedMacWindowHitTest(WindowRef window
, SInt32 param
)
1691 static RgnHandle tempRgn
= NULL
;
1693 if (tempRgn
== NULL
)
1696 // get the point clicked
1697 SetPt( &hitPoint
, LoWord(param
), HiWord(param
) );
1699 // Mac OS 8.5 or later
1700 wxShapedMacWindowStructureRegion(window
, tempRgn
);
1701 if (PtInRgn( hitPoint
, tempRgn
)) //in window content region?
1704 // no significant area was hit
1708 static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode
), WindowRef window
, SInt16 message
, SInt32 param
)
1712 case kWindowMsgHitTest
:
1713 return wxShapedMacWindowHitTest(window
, param
);
1715 case kWindowMsgGetFeatures
:
1716 return wxShapedMacWindowGetFeatures(window
, param
);
1718 // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow
1719 case kWindowMsgGetRegion
:
1720 return wxShapedMacWindowGetRegion(window
, param
);