X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f0c8f31f407ecfce909060464c0ea655221cdab..795dac4c866d89804e625fa1d04cb70aba320183:/src/osx/carbon/nonownedwnd.cpp diff --git a/src/osx/carbon/nonownedwnd.cpp b/src/osx/carbon/nonownedwnd.cpp index 6956f30700..cab04631f5 100644 --- a/src/osx/carbon/nonownedwnd.cpp +++ b/src/osx/carbon/nonownedwnd.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/mac/carbon/nonownedwnd.cpp +// Name: src/osx/carbon/nonownedwnd.cpp // Purpose: implementation of wxNonOwnedWindow // Author: Stefan Csomor // Created: 2008-03-24 @@ -28,15 +28,216 @@ #include "wx/sysopt.h" #endif -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- +// ============================================================================ +// wxNonOwnedWindow implementation +// ============================================================================ // unified title and toolbar constant - not in Tiger headers, so we duplicate it here #define kWindowUnifiedTitleAndToolbarAttribute (1 << 7) -// trace mask for activation tracing messages -#define TRACE_ACTIVATE "activation" +IMPLEMENT_DYNAMIC_CLASS( wxNonOwnedWindowCarbonImpl , wxNonOwnedWindowImpl ) + +WXWindow wxNonOwnedWindowCarbonImpl::GetWXWindow() const +{ + return (WXWindow) m_macWindow; +} +void wxNonOwnedWindowCarbonImpl::Raise() +{ + ::SelectWindow( m_macWindow ) ; +} + +void wxNonOwnedWindowCarbonImpl::Lower() +{ + ::SendBehind( m_macWindow , NULL ) ; +} + +bool wxNonOwnedWindowCarbonImpl::Show(bool show) +{ + bool plainTransition = true; + +#if wxUSE_SYSTEM_OPTIONS + if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) + plainTransition = ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1 ) ; +#endif + + if (show) + { +#if wxOSX_USE_CARBON + if ( plainTransition ) + ::ShowWindow( (WindowRef)m_macWindow ); + else + ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL ); + + ::SelectWindow( (WindowRef)m_macWindow ) ; +#endif + } + else + { +#if wxOSX_USE_CARBON + if ( plainTransition ) + ::HideWindow( (WindowRef)m_macWindow ); + else + ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowHideTransitionAction, NULL ); +#endif + } + return true; +} + +void wxNonOwnedWindowCarbonImpl::Update() +{ + HIWindowFlush(m_macWindow) ; +} + +bool wxNonOwnedWindowCarbonImpl::SetTransparent(wxByte alpha) +{ + OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, (CGFloat)((alpha)/255.0)); + return result == noErr; +} + +bool wxNonOwnedWindowCarbonImpl::SetBackgroundColour(const wxColour& col ) +{ + if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground)) ) + { + SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDocumentWindowBackground, false ) ; + m_wxPeer->SetBackgroundStyle(wxBG_STYLE_SYSTEM); + // call directly if object is not yet completely constructed + if ( m_wxPeer->GetNonOwnedPeer() == NULL ) + SetBackgroundStyle(wxBG_STYLE_SYSTEM); + } + else if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)) ) + { + SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDialogBackgroundActive, false ) ; + m_wxPeer->SetBackgroundStyle(wxBG_STYLE_SYSTEM); + // call directly if object is not yet completely constructed + if ( m_wxPeer->GetNonOwnedPeer() == NULL ) + SetBackgroundStyle(wxBG_STYLE_SYSTEM); + } + return true; +} + +void wxNonOwnedWindowCarbonImpl::SetExtraStyle( long exStyle ) +{ + if ( m_macWindow != NULL ) + { + bool metal = exStyle & wxFRAME_EX_METAL ; + + if ( MacGetMetalAppearance() != metal ) + { + if ( MacGetUnifiedAppearance() ) + MacSetUnifiedAppearance( !metal ) ; + + MacSetMetalAppearance( metal ) ; + } + } +} + +bool wxNonOwnedWindowCarbonImpl::SetBackgroundStyle(wxBackgroundStyle style) +{ + if ( style == wxBG_STYLE_TRANSPARENT ) + { + OSStatus err = HIWindowChangeFeatures( m_macWindow, 0, kWindowIsOpaque ); + verify_noerr( err ); + err = ReshapeCustomWindow( m_macWindow ); + verify_noerr( err ); + } + + return true ; +} + +bool wxNonOwnedWindowCarbonImpl::CanSetTransparent() +{ + return true; +} + +void wxNonOwnedWindowCarbonImpl::GetContentArea( int &left , int &top , int &width , int &height ) const +{ + Rect content, structure ; + + GetWindowBounds( m_macWindow, kWindowStructureRgn , &structure ) ; + GetWindowBounds( m_macWindow, kWindowContentRgn , &content ) ; + + left = content.left - structure.left ; + top = content.top - structure.top ; + width = content.right - content.left ; + height = content.bottom - content.top ; +} + +void wxNonOwnedWindowCarbonImpl::MoveWindow(int x, int y, int width, int height) +{ + Rect bounds = { y , x , y + height , x + width } ; + verify_noerr(SetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; +} + +void wxNonOwnedWindowCarbonImpl::GetPosition( int &x, int &y ) const +{ + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; + + x = bounds.left ; + y = bounds.top ; +} + +void wxNonOwnedWindowCarbonImpl::GetSize( int &width, int &height ) const +{ + Rect bounds ; + + verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; + + width = bounds.right - bounds.left ; + height = bounds.bottom - bounds.top ; +} + +bool wxNonOwnedWindowCarbonImpl::MacGetUnifiedAppearance() const +{ + return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute ; +} + +void wxNonOwnedWindowCarbonImpl::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear ) +{ + ChangeWindowAttributes( m_macWindow, attributesToSet, attributesToClear ) ; +} + +wxUint32 wxNonOwnedWindowCarbonImpl::MacGetWindowAttributes() const +{ + UInt32 attr = 0 ; + GetWindowAttributes( m_macWindow, &attr ) ; + return attr ; +} + +void wxNonOwnedWindowCarbonImpl::MacSetMetalAppearance( bool set ) +{ + if ( MacGetUnifiedAppearance() ) + MacSetUnifiedAppearance( false ) ; + + MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes , + set ? kWindowNoAttributes : kWindowMetalAttribute ) ; +} + +bool wxNonOwnedWindowCarbonImpl::MacGetMetalAppearance() const +{ + return MacGetWindowAttributes() & kWindowMetalAttribute ; +} + +void wxNonOwnedWindowCarbonImpl::MacSetUnifiedAppearance( bool set ) +{ + if ( MacGetMetalAppearance() ) + MacSetMetalAppearance( false ) ; + + MacChangeWindowAttributes( set ? kWindowUnifiedTitleAndToolbarAttribute : kWindowNoAttributes , + set ? kWindowNoAttributes : kWindowUnifiedTitleAndToolbarAttribute) ; + + // For some reason, Tiger uses white as the background color for this appearance, + // while most apps using it use the typical striped background. Restore that behavior + // for wx. + // TODO: Determine if we need this on Leopard as well. (should be harmless either way, + // though) + // since when creating the peering is not yet completely set-up we call both setters + // explicitely + m_wxPeer->SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ) ; + SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ) ; +} + // ---------------------------------------------------------------------------- // globals @@ -44,9 +245,6 @@ static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param); -// ============================================================================ -// wxNonOwnedWindow implementation -// ============================================================================ // --------------------------------------------------------------------------- // Carbon Events @@ -89,7 +287,7 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event // FindFocus does not return the actual focus window, but the enclosing window wxWindow* focus = wxWindow::DoFindFocus(); if ( focus == NULL ) - focus = (wxNonOwnedWindow*) data ; + focus = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL ; unsigned char charCode ; wxChar uniChar[2] ; @@ -218,8 +416,6 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event // // This handler can also be called from app level where data (ie target window) may be null or a non wx window -wxWindow* g_MacLastWindow = NULL ; - EventMouseButton g_lastButton = 0 ; bool g_lastButtonWasFakeRight = false ; @@ -366,7 +562,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), EventRef event, void *data) { - wxNonOwnedWindow* toplevelWindow = (wxNonOwnedWindow*) data ; + wxNonOwnedWindow* toplevelWindow = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL ; OSStatus result = eventNotHandledErr ; @@ -391,7 +587,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), if ( window ) { - wxMacGlobalToLocal( window, &windowMouseLocation ) ; + QDGlobalToLocalPoint( GetWindowPort( window ), &windowMouseLocation ); if ( wxApp::s_captureWindow #if !NEW_CAPTURE_HANDLING @@ -408,11 +604,11 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), // if there is no control below the mouse position, send the event to the toplevel window itself if ( control == 0 ) { - currentMouseWindow = (wxWindow*) data ; + currentMouseWindow = (wxWindow*) toplevelWindow ; } else { - currentMouseWindow = (wxWindow*) wxFindControlFromMacControl( control ) ; + currentMouseWindow = (wxWindow*) wxFindWindowFromWXWidget( (WXWidget) control ) ; #ifndef __WXUNIVERSAL__ if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved ) { @@ -421,9 +617,9 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), // instead of its children (wxToolBarTools) ControlRef parent ; GetSuperControl(control, &parent ); - wxWindow *wxParent = (wxWindow*) wxFindControlFromMacControl( parent ) ; - if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) ) - currentMouseWindow = wxParent ; + wxWindow *wxparent = (wxWindow*) wxFindWindowFromWXWidget((WXWidget) parent ) ; + if ( wxparent && wxparent->IsKindOf( CLASSINFO( wxToolBar ) ) ) + currentMouseWindow = wxparent ; #endif } #endif @@ -485,6 +681,18 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), result = noErr ; } } + else if ( window && windowPart == inProxyIcon ) + { + // special case proxy icon bar, as we are having a low-level runloop we must do it ourselves + if ( cEvent.GetKind() == kEventMouseDown ) + { + if ( ::TrackWindowProxyDrag( window, screenMouseLocation ) != errUserWantsToDragWindow ) + { + // TODO Track change of file path and report back + result = noErr ; + } + } + } else if ( currentMouseWindow ) { wxWindow *currentMouseWindowParent = currentMouseWindow->GetParent(); @@ -547,6 +755,16 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), } else // currentMouseWindow == NULL { + if (toplevelWindow && !control) + { + extern wxCursor gGlobalCursor; + if (!gGlobalCursor.IsOk()) + { + // update cursor when over toolbar and titlebar etc. + wxSTANDARD_CURSOR->MacInstall() ; + } + } + // don't mess with controls we don't know about // for some reason returning eventNotHandledErr does not lead to the correct behaviour // so we try sending them the correct control directly @@ -580,28 +798,20 @@ wxNonOwnedWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), wxMacCarbonEvent cEvent( event ) ; // WindowRef windowRef = cEvent.GetParameter(kEventParamDirectObject) ; - wxNonOwnedWindow* toplevelWindow = (wxNonOwnedWindow*) data ; + wxNonOwnedWindow* toplevelWindow = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL; switch ( GetEventKind( event ) ) { case kEventWindowActivated : { - toplevelWindow->MacActivate( cEvent.GetTicks() , true) ; - wxActivateEvent wxevent(wxEVT_ACTIVATE, true , toplevelWindow->GetId()); - wxevent.SetTimestamp( cEvent.GetTicks() ) ; - wxevent.SetEventObject(toplevelWindow); - toplevelWindow->HandleWindowEvent(wxevent); + toplevelWindow->HandleActivated( cEvent.GetTicks() , true) ; // we still sending an eventNotHandledErr in order to allow for default processing } break ; case kEventWindowDeactivated : { - toplevelWindow->MacActivate(cEvent.GetTicks() , false) ; - wxActivateEvent wxevent(wxEVT_ACTIVATE, false , toplevelWindow->GetId()); - wxevent.SetTimestamp( cEvent.GetTicks() ) ; - wxevent.SetEventObject(toplevelWindow); - toplevelWindow->HandleWindowEvent(wxevent); + toplevelWindow->HandleActivated( cEvent.GetTicks() , false) ; // we still sending an eventNotHandledErr in order to allow for default processing } break ; @@ -623,27 +833,12 @@ wxNonOwnedWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), wxRect r( newRect.left , newRect.top , newRect.right - newRect.left , newRect.bottom - newRect.top ) ; if ( attributes & kWindowBoundsChangeSizeChanged ) { -#ifndef __WXUNIVERSAL__ - // according to the other ports we handle this within the OS level - // resize event, not within a wxSizeEvent - wxFrame *frame = wxDynamicCast( toplevelWindow , wxFrame ) ; - if ( frame ) - { - frame->PositionBars(); - } -#endif - wxSizeEvent event( r.GetSize() , toplevelWindow->GetId() ) ; - event.SetEventObject( toplevelWindow ) ; - - toplevelWindow->HandleWindowEvent(event) ; - toplevelWindow->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified + toplevelWindow->HandleResized(cEvent.GetTicks() ) ; } if ( attributes & kWindowBoundsChangeOriginChanged ) { - wxMoveEvent event( r.GetLeftTop() , toplevelWindow->GetId() ) ; - event.SetEventObject( toplevelWindow ) ; - toplevelWindow->HandleWindowEvent(event) ; + toplevelWindow->HandleMoved(cEvent.GetTicks() ) ; } result = noErr ; @@ -658,34 +853,26 @@ wxNonOwnedWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), if ( (attributes & kWindowBoundsChangeSizeChanged) || (attributes & kWindowBoundsChangeOriginChanged) ) { // all (Mac) rects are in content area coordinates, all wxRects in structure coordinates - int left , top , right , bottom ; - toplevelWindow->MacGetContentAreaInset( left , top , right , bottom ) ; - - wxRect r( + int left , top , width , height ; + // structure width + int swidth, sheight; + + toplevelWindow->GetNonOwnedPeer()->GetContentArea(left, top, width, height); + toplevelWindow->GetNonOwnedPeer()->GetSize(swidth, sheight); + int deltawidth = swidth - width; + int deltaheight = sheight - height; + wxRect adjustR( newRect.left - left, newRect.top - top, - newRect.right - newRect.left + left + right, - newRect.bottom - newRect.top + top + bottom ) ; - - // this is a EVT_SIZING not a EVT_SIZE type ! - wxSizeEvent wxevent( r , toplevelWindow->GetId() ) ; - wxevent.SetEventObject( toplevelWindow ) ; - wxRect adjustR = r ; - if ( toplevelWindow->HandleWindowEvent(wxevent) ) - adjustR = wxevent.GetRect() ; - - if ( toplevelWindow->GetMaxWidth() != -1 && adjustR.GetWidth() > toplevelWindow->GetMaxWidth() ) - adjustR.SetWidth( toplevelWindow->GetMaxWidth() ) ; - if ( toplevelWindow->GetMaxHeight() != -1 && adjustR.GetHeight() > toplevelWindow->GetMaxHeight() ) - adjustR.SetHeight( toplevelWindow->GetMaxHeight() ) ; - if ( toplevelWindow->GetMinWidth() != -1 && adjustR.GetWidth() < toplevelWindow->GetMinWidth() ) - adjustR.SetWidth( toplevelWindow->GetMinWidth() ) ; - if ( toplevelWindow->GetMinHeight() != -1 && adjustR.GetHeight() < toplevelWindow->GetMinHeight() ) - adjustR.SetHeight( toplevelWindow->GetMinHeight() ) ; - const Rect adjustedRect = { adjustR.y + top , adjustR.x + left , adjustR.y + adjustR.height - bottom , adjustR.x + adjustR.width - right } ; + newRect.right - newRect.left + deltawidth, + newRect.bottom - newRect.top + deltaheight ) ; + + toplevelWindow->HandleResizing( cEvent.GetTicks(), &adjustR ); + + const Rect adjustedRect = { adjustR.y + top , adjustR.x + left , adjustR.y + top + adjustR.height - deltaheight , + adjustR.x + left + adjustR.width - deltawidth } ; if ( !EqualRect( &newRect , &adjustedRect ) ) cEvent.SetParameter( kEventParamCurrentBounds , &adjustedRect ) ; - toplevelWindow->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified } result = noErr ; @@ -739,7 +926,12 @@ pascal OSStatus wxNonOwnedEventHandler( EventHandlerCallRef handler , EventRef e switch ( GetEventClass( event ) ) { case kEventClassTextInput : - result = wxMacUnicodeTextEventHandler( handler, event , data ) ; + { + // TODO remove as soon as all events are on implementation classes only + wxNonOwnedWindow* toplevelWindow = data ? ((wxNonOwnedWindowImpl*) data)->GetWXPeer() : NULL; + + result = wxMacUnicodeTextEventHandler( handler, event , toplevelWindow ) ; + } break ; case kEventClassKeyboard : @@ -764,106 +956,167 @@ pascal OSStatus wxNonOwnedEventHandler( EventHandlerCallRef handler , EventRef e DEFINE_ONE_SHOT_HANDLER_GETTER( wxNonOwnedEventHandler ) // --------------------------------------------------------------------------- -// wxWindowMac utility functions +// Support functions for shaped windows, based on Apple's CustomWindow sample at +// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm // --------------------------------------------------------------------------- -// Find an item given the Macintosh Window Reference - -WX_DECLARE_HASH_MAP(WindowRef, wxNonOwnedWindow*, wxPointerHash, wxPointerEqual, MacWindowMap); - -static MacWindowMap wxWinMacWindowList; - -wxNonOwnedWindow *wxFindWinFromMacWindow(WindowRef inWindowRef) +static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect) { - MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef); - - return (node == wxWinMacWindowList.end()) ? NULL : node->second; + GetWindowPortBounds(window, inRect); + Point pt = { inRect->top ,inRect->left }; + QDLocalToGlobalPoint( GetWindowPort( window ), &pt ); + inRect->bottom += pt.v - inRect->top; + inRect->right += pt.h - inRect->left; + inRect->top = pt.v; + inRect->left = pt.h; } -void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxNonOwnedWindow *win) ; -void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxNonOwnedWindow *win) +static SInt32 wxShapedMacWindowGetFeatures(WindowRef WXUNUSED(window), SInt32 param) { - // adding NULL WindowRef is (first) surely a result of an error and - // nothing else :-) - wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") ); + /*------------------------------------------------------ + Define which options your custom window supports. + --------------------------------------------------------*/ + //just enable everything for our demo + *(OptionBits*)param = + //kWindowCanGrow | + //kWindowCanZoom | + kWindowCanCollapse | + //kWindowCanGetWindowRegion | + //kWindowHasTitleBar | + //kWindowSupportsDragHilite | + kWindowCanDrawInCurrentPort | + //kWindowCanMeasureTitle | + kWindowWantsDisposeAtProcessDeath | + kWindowSupportsGetGrowImageRegion | + kWindowDefSupportsColorGrafPort; - wxWinMacWindowList[inWindowRef] = win; + return 1; } -void wxRemoveMacWindowAssociation(wxNonOwnedWindow *win) ; -void wxRemoveMacWindowAssociation(wxNonOwnedWindow *win) +// The content region is left as a rectangle matching the window size, this is +// so the origin in the paint event, and etc. still matches what the +// programmer expects. +static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn) { - MacWindowMap::iterator it; - for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it ) + SetEmptyRgn(rgn); + wxNonOwnedWindow* win = wxNonOwnedWindow::GetFromWXWindow((WXWindow)window); + if (win) { - if ( it->second == win ) - { - wxWinMacWindowList.erase(it); - break; - } + Rect r ; + wxShapedMacWindowGetPos( window, &r ) ; + RectRgn( rgn , &r ) ; } } -// ---------------------------------------------------------------------------- -// wxNonOwnedWindow creation -// ---------------------------------------------------------------------------- - -wxNonOwnedWindow *wxNonOwnedWindow::s_macDeactivateWindow = NULL; - -void wxNonOwnedWindow::Init() -{ - m_macWindow = NULL ; - m_macEventHandler = NULL ; -} - -wxMacDeferredWindowDeleter::wxMacDeferredWindowDeleter( WindowRef windowRef ) +// The structure region is set to the shape given to the SetShape method. +static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn) { - m_macWindow = windowRef ; -} + RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window); -wxMacDeferredWindowDeleter::~wxMacDeferredWindowDeleter() -{ - DisposeWindow( (WindowRef) m_macWindow ) ; + SetEmptyRgn(rgn); + if (cachedRegion) + { + Rect windowRect; + wxShapedMacWindowGetPos(window, &windowRect); // how big is the window + CopyRgn(cachedRegion, rgn); // make a copy of our cached region + OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window + //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size + } } -bool wxNonOwnedWindow::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param) { - // init our fields - Init(); + GetWindowRegionPtr rgnRec = (GetWindowRegionPtr)param; - m_windowStyle = style; + if (rgnRec == NULL) + return paramErr; - SetName( name ); + switch (rgnRec->regionCode) + { + case kWindowStructureRgn: + wxShapedMacWindowStructureRegion(window, rgnRec->winRgn); + break; - m_windowId = id == -1 ? NewControlId() : id; + case kWindowContentRgn: + wxShapedMacWindowContentRegion(window, rgnRec->winRgn); + break; - DoMacCreateRealWindow( parent, pos , size , style , name ) ; + default: + SetEmptyRgn(rgnRec->winRgn); + break; + } - SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE )); + return noErr; +} - if (GetExtraStyle() & wxFRAME_EX_METAL) - MacSetMetalAppearance(true); +// Determine the region of the window which was hit +// +static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param) +{ + Point hitPoint; + static RgnHandle tempRgn = NULL; - if ( parent ) - parent->AddChild(this); + if (tempRgn == NULL) + tempRgn = NewRgn(); - return true; + // get the point clicked + SetPt( &hitPoint, LoWord(param), HiWord(param) ); + + // Mac OS 8.5 or later + wxShapedMacWindowStructureRegion(window, tempRgn); + if (PtInRgn( hitPoint, tempRgn )) //in window content region? + return wInContent; + + // no significant area was hit + return wNoHit; } -wxNonOwnedWindow::~wxNonOwnedWindow() +static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode), WindowRef window, SInt16 message, SInt32 param) { - if ( m_macWindow ) + switch (message) { + case kWindowMsgHitTest: + return wxShapedMacWindowHitTest(window, param); + + case kWindowMsgGetFeatures: + return wxShapedMacWindowGetFeatures(window, param); + + // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow + case kWindowMsgGetRegion: + return wxShapedMacWindowGetRegion(window, param); + + default: + break; + } + + return 0; +} + +// implementation + +typedef struct +{ + wxPoint m_position ; + wxSize m_size ; + bool m_wasResizable ; +} FullScreenData ; + +wxNonOwnedWindowCarbonImpl::wxNonOwnedWindowCarbonImpl() +{ +} + +wxNonOwnedWindowCarbonImpl::wxNonOwnedWindowCarbonImpl( wxNonOwnedWindow* nonownedwnd) : wxNonOwnedWindowImpl( nonownedwnd) +{ + m_macEventHandler = NULL; + m_macWindow = NULL; + m_macFullScreenData = NULL ; +} + +wxNonOwnedWindowCarbonImpl::~wxNonOwnedWindowCarbonImpl() +{ #if wxUSE_TOOLTIPS wxToolTip::NotifyWindowDelete(m_macWindow) ; #endif - wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ; - } if ( m_macEventHandler ) { @@ -871,48 +1124,27 @@ wxNonOwnedWindow::~wxNonOwnedWindow() m_macEventHandler = NULL ; } - wxRemoveMacWindowAssociation( this ) ; + if ( m_macWindow ) + DisposeWindow( m_macWindow ); - // avoid dangling refs - if ( s_macDeactivateWindow == this ) - s_macDeactivateWindow = NULL; -} + FullScreenData *data = (FullScreenData *) m_macFullScreenData ; + delete data ; + m_macFullScreenData = NULL ; -// ---------------------------------------------------------------------------- -// wxNonOwnedWindow misc -// ---------------------------------------------------------------------------- + m_macWindow = NULL; -wxPoint wxNonOwnedWindow::GetClientAreaOrigin() const -{ - return wxPoint(0, 0) ; } -bool wxNonOwnedWindow::SetBackgroundColour(const wxColour& c ) +void wxNonOwnedWindowCarbonImpl::Destroy() { - wxColour col = c; - if ( col == wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ) - col = wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground)); - else if ( col == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) ) - col = wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)); - - if ( !wxWindow::SetBackgroundColour(col) && m_hasBgCol ) - return false ; - - if ( GetBackgroundStyle() != wxBG_STYLE_CUSTOM ) + if ( m_macEventHandler ) { - if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDocumentWindowBackground)) ) - { - SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDocumentWindowBackground, false ) ; - SetBackgroundStyle(wxBG_STYLE_SYSTEM); - } - else if ( col == wxColour(wxMacCreateCGColorFromHITheme(kThemeBrushDialogBackgroundActive)) ) - { - SetThemeWindowBackground( (WindowRef) m_macWindow, kThemeBrushDialogBackgroundActive, false ) ; - SetBackgroundStyle(wxBG_STYLE_SYSTEM); - } + ::RemoveEventHandler((EventHandlerRef) m_macEventHandler); + m_macEventHandler = NULL ; } - return true; -} + + wxPendingDelete.Append( new wxDeferredObjectDeleter( this ) ) ; +} void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window, EventHandlerRef* handler, void *ref) { @@ -920,7 +1152,28 @@ void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window, EventHa GetEventTypeCount(eventList), eventList, ref, handler ); } -void wxNonOwnedWindow::MacInstallTopLevelWindowEventHandler() +bool wxNonOwnedWindowCarbonImpl::SetShape(const wxRegion& region) +{ + // Make a copy of the region + RgnHandle shapeRegion = NewRgn(); + HIShapeGetAsQDRgn( region.GetWXHRGN(), shapeRegion ); + + // Dispose of any shape region we may already have + RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef) m_wxPeer->GetWXWindow() ); + if ( oldRgn ) + DisposeRgn(oldRgn); + + // Save the region so we can use it later + SetWRefCon((WindowRef) m_wxPeer->GetWXWindow(), (URefCon)shapeRegion); + + // inform the window manager that the window has changed shape + ReshapeCustomWindow((WindowRef) m_wxPeer->GetWXWindow()); + + return true; +} + + +void wxNonOwnedWindowCarbonImpl::MacInstallTopLevelWindowEventHandler() { if ( m_macEventHandler != NULL ) { @@ -929,42 +1182,22 @@ void wxNonOwnedWindow::MacInstallTopLevelWindowEventHandler() wxNonOwnedWindowInstallTopLevelWindowEventHandler(MAC_WXHWND(m_macWindow),(EventHandlerRef *)&m_macEventHandler,this); } -void wxNonOwnedWindow::MacCreateRealWindow( - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name ) -{ - DoMacCreateRealWindow( NULL, pos, size, style, name ); -} - -void wxNonOwnedWindow::DoMacCreateRealWindow( +void wxNonOwnedWindowCarbonImpl::Create( wxWindow* parent, const wxPoint& pos, const wxSize& size, - long style, - const wxString& name ) + long style, long extraStyle, + const wxString& WXUNUSED(name) ) { + OSStatus err = noErr ; - SetName(name); - m_windowStyle = style; - m_isShown = false; + Rect theBoundsRect; - // create frame. int x = (int)pos.x; int y = (int)pos.y; - Rect theBoundsRect; - wxRect display = wxGetClientDisplayRect() ; - - if ( x == wxDefaultPosition.x ) - x = display.x ; - - if ( y == wxDefaultPosition.y ) - y = display.y ; - - int w = WidthDefault(size.x); - int h = HeightDefault(size.y); + int w = size.x; + int h = size.y; ::SetRect(&theBoundsRect, x, y , x + w, y + h); @@ -975,32 +1208,39 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( bool activationScopeSet = false; WindowActivationScope activationScope = kWindowActivationScopeNone; - if ( HasFlag( wxFRAME_TOOL_WINDOW) ) + if ( style & wxFRAME_TOOL_WINDOW ) { if ( - HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || - HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) || - HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT) + ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) || + ( style & wxSYSTEM_MENU ) || ( style & wxCAPTION ) || + ( style &wxTINY_CAPTION_HORIZ) || ( style &wxTINY_CAPTION_VERT) ) { - if ( HasFlag( wxSTAY_ON_TOP ) ) + if ( ( style & wxSTAY_ON_TOP ) ) wclass = kUtilityWindowClass; else wclass = kFloatingWindowClass ; - if ( HasFlag(wxTINY_CAPTION_VERT) ) + if ( ( style &wxTINY_CAPTION_VERT) ) attr |= kWindowSideTitlebarAttribute ; } else { - wclass = kPlainWindowClass ; + if ( style & wxNO_BORDER ) + { + wclass = kSimpleWindowClass ; + } + else + { + wclass = kPlainWindowClass ; + } activationScopeSet = true; activationScope = kWindowActivationScopeNone; } } - else if ( HasFlag( wxPOPUP_WINDOW ) ) + else if ( ( style & wxPOPUP_WINDOW ) ) { - if ( HasFlag( wxBORDER_NONE ) ) + if ( ( style & wxBORDER_NONE ) ) { wclass = kHelpWindowClass ; // has no border attr |= kWindowNoShadowAttribute; @@ -1014,23 +1254,23 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( activationScopeSet = true; activationScope = kWindowActivationScopeNone; } - else if ( HasFlag( wxCAPTION ) ) + else if ( ( style & wxCAPTION ) ) { wclass = kDocumentWindowClass ; attr |= kWindowInWindowMenuAttribute ; } - else if ( HasFlag( wxFRAME_DRAWER ) ) + else if ( ( style & wxFRAME_DRAWER ) ) { wclass = kDrawerWindowClass; } else { - if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || - HasFlag( wxCLOSE_BOX ) || HasFlag( wxSYSTEM_MENU ) ) + if ( ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) || + ( style & wxCLOSE_BOX ) || ( style & wxSYSTEM_MENU ) ) { wclass = kDocumentWindowClass ; } - else if ( HasFlag( wxNO_BORDER ) ) + else if ( ( style & wxNO_BORDER ) ) { wclass = kSimpleWindowClass ; } @@ -1042,24 +1282,24 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( if ( wclass != kPlainWindowClass ) { - if ( HasFlag( wxMINIMIZE_BOX ) ) + if ( ( style & wxMINIMIZE_BOX ) ) attr |= kWindowCollapseBoxAttribute ; - if ( HasFlag( wxMAXIMIZE_BOX ) ) + if ( ( style & wxMAXIMIZE_BOX ) ) attr |= kWindowFullZoomAttribute ; - if ( HasFlag( wxRESIZE_BORDER ) ) + if ( ( style & wxRESIZE_BORDER ) ) attr |= kWindowResizableAttribute ; - if ( HasFlag( wxCLOSE_BOX) ) + if ( ( style & wxCLOSE_BOX) ) attr |= kWindowCloseBoxAttribute ; } attr |= kWindowLiveResizeAttribute; - if ( HasFlag(wxSTAY_ON_TOP) ) + if ( ( style &wxSTAY_ON_TOP) ) group = GetWindowGroupOfClass(kUtilityWindowClass) ; - if ( HasFlag( wxFRAME_FLOAT_ON_PARENT ) ) + if ( ( style & wxFRAME_FLOAT_ON_PARENT ) ) group = GetWindowGroupOfClass(kFloatingWindowClass) ; if ( group == NULL && parent != NULL ) @@ -1070,11 +1310,11 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( } attr |= kWindowCompositingAttribute; -#if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale) +#if 0 // TODO : decide on overall handling of high dpi screens (pixel vs userscale) attr |= kWindowFrameworkScaledAttribute; #endif - if ( HasFlag(wxFRAME_SHAPED) ) + if ( ( style &wxFRAME_SHAPED) ) { WindowDefSpec customWindowDefSpec; customWindowDefSpec.defType = kWindowDefProcPtr; @@ -1112,23 +1352,7 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( // the create commands are only for content rect, // so we have to set the size again as structure bounds - SetWindowBounds( (WindowRef) m_macWindow , kWindowStructureRgn , &theBoundsRect ) ; - - wxAssociateWinWithMacWindow( (WindowRef) m_macWindow , this ) ; - m_peer = new wxMacControl(this , true /*isRootControl*/) ; - - // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of - // the content view, so we have to retrieve it explicitly - HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID , - m_peer->GetControlRefAddr() ) ; - if ( !m_peer->Ok() ) - { - // compatibility mode fallback - GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ; - } - - // the root control level handler - MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ; + SetWindowBounds( m_macWindow , kWindowStructureRgn , &theBoundsRect ) ; // Causes the inner part of the window not to be metal // if the style is used before window creation. @@ -1146,107 +1370,29 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( } HIViewRef growBoxRef = 0 ; - err = HIViewFindByID( HIViewGetRoot( (WindowRef)m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef ); + err = HIViewFindByID( HIViewGetRoot( m_macWindow ), kHIViewWindowGrowBoxID, &growBoxRef ); if ( err == noErr && growBoxRef != 0 ) HIGrowBoxViewSetTransparent( growBoxRef, true ) ; // the frame window event handler - InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ; + InstallStandardEventHandler( GetWindowEventTarget(m_macWindow) ) ; MacInstallTopLevelWindowEventHandler() ; - DoSetWindowVariant( m_windowVariant ) ; - - m_macFocus = NULL ; + if ( extraStyle & wxFRAME_EX_METAL) + MacSetMetalAppearance(true); - if ( HasFlag(wxFRAME_SHAPED) ) + if ( ( style &wxFRAME_SHAPED) ) { // default shape matches the window size wxRegion rgn( 0, 0, w, h ); SetShape( rgn ); } - - wxWindowCreateEvent event(this); - HandleWindowEvent(event); -} - -// Raise the window to the top of the Z order -void wxNonOwnedWindow::Raise() -{ - ::SelectWindow( (WindowRef)m_macWindow ) ; -} - -// Lower the window to the bottom of the Z order -void wxNonOwnedWindow::Lower() -{ - ::SendBehind( (WindowRef)m_macWindow , NULL ) ; -} - -void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp) -{ - if (s_macDeactivateWindow) - { - wxLogTrace(TRACE_ACTIVATE, - wxT("Doing delayed deactivation of %p"), - s_macDeactivateWindow); - - s_macDeactivateWindow->MacActivate(timestamp, false); - } -} - -void wxNonOwnedWindow::MacActivate( long timestamp , bool WXUNUSED(inIsActivating) ) -{ - wxLogTrace(TRACE_ACTIVATE, wxT("TopLevel=%p::MacActivate"), this); - - if (s_macDeactivateWindow == this) - s_macDeactivateWindow = NULL; - - MacDelayedDeactivation(timestamp); } -bool wxNonOwnedWindow::Show(bool show) -{ - if ( !wxWindow::Show(show) ) - return false; - - bool plainTransition = true; - -#if wxUSE_SYSTEM_OPTIONS - if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) - plainTransition = ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1 ) ; -#endif - - if (show) - { - if ( plainTransition ) - ::ShowWindow( (WindowRef)m_macWindow ); - else - ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL ); - - ::SelectWindow( (WindowRef)m_macWindow ) ; - - // because apps expect a size event to occur at this moment - wxSizeEvent event(GetSize() , m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); - } - else - { - if ( plainTransition ) - ::HideWindow( (WindowRef)m_macWindow ); - else - ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowHideTransitionAction, NULL ); - } - - return true ; -} - -bool wxNonOwnedWindow::MacShowWithEffect(bool show, +bool wxNonOwnedWindowCarbonImpl::ShowWithEffect(bool show, wxShowEffect effect, unsigned timeout) { - if ( !wxWindow::Show(show) ) - return false; - WindowTransitionEffect transition = 0 ; switch( effect ) { @@ -1273,6 +1419,11 @@ bool wxNonOwnedWindow::MacShowWithEffect(bool show, transition = kWindowZoomTransitionEffect; break; + case wxSHOW_EFFECT_NONE: + // wxNonOwnedWindow is supposed to call Show() itself in this case + wxFAIL_MSG( "ShowWithEffect() shouldn't be called" ); + return false; + case wxSHOW_EFFECT_MAX: wxFAIL_MSG( "invalid effect flag" ); return false; @@ -1281,7 +1432,7 @@ bool wxNonOwnedWindow::MacShowWithEffect(bool show, TransitionWindowOptions options; options.version = 0; options.duration = timeout / 1000.0; - options.window = transition == kWindowSheetTransitionEffect ? (WindowRef) GetParent()->MacGetTopLevelWindowRef() :0; + options.window = transition == kWindowSheetTransitionEffect ? (WindowRef) m_wxPeer->GetParent()->MacGetTopLevelWindowRef() :0; options.userData = 0; wxSize size = wxGetDisplaySize(); @@ -1332,358 +1483,196 @@ bool wxNonOwnedWindow::MacShowWithEffect(bool show, if ( show ) { ::SelectWindow( (WindowRef)m_macWindow ) ; - - // because apps expect a size event to occur at this moment - wxSizeEvent event(GetSize() , m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); } return true; } -bool wxNonOwnedWindow::SetTransparent(wxByte alpha) -{ - OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, (CGFloat)((alpha)/255.0)); - return result == noErr; -} - - -bool wxNonOwnedWindow::CanSetTransparent() -{ - return true; -} - - -void wxNonOwnedWindow::SetExtraStyle(long exStyle) -{ - if ( GetExtraStyle() == exStyle ) - return ; - - wxWindow::SetExtraStyle( exStyle ) ; - - if ( m_macWindow != NULL ) - { - bool metal = GetExtraStyle() & wxFRAME_EX_METAL ; - - if ( MacGetMetalAppearance() != metal ) - { - if ( MacGetUnifiedAppearance() ) - MacSetUnifiedAppearance( !metal ) ; - - MacSetMetalAppearance( metal ) ; - } - } -} - -bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style) -{ - if ( !wxWindow::SetBackgroundStyle(style) ) - return false ; - - WindowRef windowRef = HIViewGetWindow( (HIViewRef)GetHandle() ); - - if ( GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) - { - OSStatus err = HIWindowChangeFeatures( windowRef, 0, kWindowIsOpaque ); - verify_noerr( err ); - err = ReshapeCustomWindow( windowRef ); - verify_noerr( err ); - } - - return true ; -} - -// TODO: switch to structure bounds - -// we are still using coordinates of the content view -// -void wxNonOwnedWindow::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) -{ - Rect content, structure ; - - GetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &structure ) ; - GetWindowBounds( (WindowRef) m_macWindow, kWindowContentRgn , &content ) ; - - left = content.left - structure.left ; - top = content.top - structure.top ; - right = structure.right - content.right ; - bottom = structure.bottom - content.bottom ; -} - -void wxNonOwnedWindow::DoMoveWindow(int x, int y, int width, int height) +void wxNonOwnedWindowCarbonImpl::SetTitle( const wxString& title, wxFontEncoding encoding ) { - m_cachedClippedRectValid = false ; - Rect bounds = { y , x , y + height , x + width } ; - verify_noerr(SetWindowBounds( (WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; - wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified + SetWindowTitleWithCFString( m_macWindow , wxCFStringRef( title , encoding ) ) ; } -void wxNonOwnedWindow::DoGetPosition( int *x, int *y ) const +bool wxNonOwnedWindowCarbonImpl::IsMaximized() const { - Rect bounds ; - - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; - - if (x) - *x = bounds.left ; - if (y) - *y = bounds.top ; + return IsWindowInStandardState( m_macWindow , NULL , NULL ) ; } -void wxNonOwnedWindow::DoGetSize( int *width, int *height ) const +bool wxNonOwnedWindowCarbonImpl::IsIconized() const { - Rect bounds ; - - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; - - if (width) - *width = bounds.right - bounds.left ; - if (height) - *height = bounds.bottom - bounds.top ; + return IsWindowCollapsed((WindowRef)GetWXWindow() ) ; } -void wxNonOwnedWindow::DoGetClientSize( int *width, int *height ) const +void wxNonOwnedWindowCarbonImpl::Iconize( bool iconize ) { - Rect bounds ; - - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowContentRgn , &bounds )) ; - - if (width) - *width = bounds.right - bounds.left ; - if (height) - *height = bounds.bottom - bounds.top ; + if ( IsWindowCollapsable( m_macWindow ) ) + CollapseWindow( m_macWindow , iconize ) ; } -void wxNonOwnedWindow::MacSetMetalAppearance( bool set ) +void wxNonOwnedWindowCarbonImpl::Maximize(bool maximize) { - if ( MacGetUnifiedAppearance() ) - MacSetUnifiedAppearance( false ) ; - - MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes , - set ? kWindowNoAttributes : kWindowMetalAttribute ) ; + Point idealSize = { 0 , 0 } ; + if ( maximize ) + { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + HIRect bounds ; + HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal, + &bounds); + idealSize.h = bounds.size.width; + idealSize.v = bounds.size.height; +#else + Rect rect ; + GetAvailableWindowPositioningBounds(GetMainDevice(),&rect) ; + idealSize.h = rect.right - rect.left ; + idealSize.v = rect.bottom - rect.top ; +#endif + } + ZoomWindowIdeal( (WindowRef)GetWXWindow() , maximize ? inZoomOut : inZoomIn , &idealSize ) ; } -bool wxNonOwnedWindow::MacGetMetalAppearance() const +bool wxNonOwnedWindowCarbonImpl::IsFullScreen() const { - return MacGetWindowAttributes() & kWindowMetalAttribute ; + return m_macFullScreenData != NULL ; } -void wxNonOwnedWindow::MacSetUnifiedAppearance( bool set ) +bool wxNonOwnedWindowCarbonImpl::ShowFullScreen(bool show, long style) { - if ( MacGetMetalAppearance() ) - MacSetMetalAppearance( false ) ; - - MacChangeWindowAttributes( set ? kWindowUnifiedTitleAndToolbarAttribute : kWindowNoAttributes , - set ? kWindowNoAttributes : kWindowUnifiedTitleAndToolbarAttribute) ; + if ( show ) + { + FullScreenData *data = (FullScreenData *)m_macFullScreenData ; + delete data ; + data = new FullScreenData() ; + + m_macFullScreenData = data ; + data->m_position = m_wxPeer->GetPosition() ; + data->m_size = m_wxPeer->GetSize() ; +#if wxOSX_USE_CARBON + WindowAttributes attr = 0; + GetWindowAttributes((WindowRef) GetWXWindow(), &attr); + data->m_wasResizable = attr & kWindowResizableAttribute; + if ( style & wxFULLSCREEN_NOMENUBAR ) + HideMenuBar() ; +#endif - // For some reason, Tiger uses white as the background color for this appearance, - // while most apps using it use the typical striped background. Restore that behavior - // for wx. - // TODO: Determine if we need this on Leopard as well. (should be harmless either way, - // though) - SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ) ; -} + wxRect client = wxGetClientDisplayRect() ; -bool wxNonOwnedWindow::MacGetUnifiedAppearance() const -{ - return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute ; -} + int left, top, width, height ; + int x, y, w, h ; -void wxNonOwnedWindow::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear ) -{ - ChangeWindowAttributes( (WindowRef)m_macWindow, attributesToSet, attributesToClear ) ; -} + x = client.x ; + y = client.y ; + w = client.width ; + h = client.height ; -wxUint32 wxNonOwnedWindow::MacGetWindowAttributes() const -{ - UInt32 attr = 0 ; - GetWindowAttributes( (WindowRef) m_macWindow, &attr ) ; + GetContentArea( left, top, width, height ) ; + int outerwidth, outerheight; + GetSize( outerwidth, outerheight ); - return attr ; -} - -void wxNonOwnedWindow::MacPerformUpdates() -{ - // for composited windows this also triggers a redraw of all - // invalid views in the window - HIWindowFlush((WindowRef) m_macWindow) ; -} + if ( style & wxFULLSCREEN_NOCAPTION ) + { + y -= top ; + h += top ; + // avoid adding the caption twice to the height + outerheight -= top; + } -// --------------------------------------------------------------------------- -// Shape implementation -// --------------------------------------------------------------------------- + if ( style & wxFULLSCREEN_NOBORDER ) + { + x -= left ; + w += outerwidth - width; + h += outerheight - height; + } + if ( style & wxFULLSCREEN_NOTOOLBAR ) + { + // TODO + } -bool wxNonOwnedWindow::SetShape(const wxRegion& region) -{ - wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false, - _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); + if ( style & wxFULLSCREEN_NOSTATUSBAR ) + { + // TODO + } - // The empty region signifies that the shape - // should be removed from the window. - if ( region.IsEmpty() ) - { - wxSize sz = GetClientSize(); - wxRegion rgn(0, 0, sz.x, sz.y); - if ( rgn.IsEmpty() ) - return false ; - else - return SetShape(rgn); + m_wxPeer->SetSize( x , y , w, h ) ; + if ( data->m_wasResizable ) + { +#if wxOSX_USE_CARBON + ChangeWindowAttributes( (WindowRef) GetWXWindow() , kWindowNoAttributes , kWindowResizableAttribute ) ; +#endif + } } + else if ( m_macFullScreenData != NULL ) + { + FullScreenData *data = (FullScreenData *) m_macFullScreenData ; +#if wxOSX_USE_CARBON + ShowMenuBar() ; + if ( data->m_wasResizable ) + ChangeWindowAttributes( (WindowRef) GetWXWindow() , kWindowResizableAttribute , kWindowNoAttributes ) ; +#endif + m_wxPeer->SetPosition( data->m_position ) ; + m_wxPeer->SetSize( data->m_size ) ; - // Make a copy of the region - RgnHandle shapeRegion = NewRgn(); - HIShapeGetAsQDRgn( region.GetWXHRGN(), shapeRegion ); - - // Dispose of any shape region we may already have - RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef)MacGetWindowRef() ); - if ( oldRgn ) - DisposeRgn(oldRgn); - - // Save the region so we can use it later - SetWRefCon((WindowRef)MacGetWindowRef(), (URefCon)shapeRegion); - - // inform the window manager that the window has changed shape - ReshapeCustomWindow((WindowRef)MacGetWindowRef()); + delete data ; + m_macFullScreenData = NULL ; + } return true; } -// --------------------------------------------------------------------------- -// Support functions for shaped windows, based on Apple's CustomWindow sample at -// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm -// --------------------------------------------------------------------------- +// Attracts the users attention to this window if the application is +// inactive (should be called when a background event occurs) -static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect) -{ - GetWindowPortBounds(window, inRect); - Point pt = { inRect->top ,inRect->left }; - wxMacLocalToGlobal( window, &pt ) ; - inRect->bottom += pt.v - inRect->top; - inRect->right += pt.h - inRect->left; - inRect->top = pt.v; - inRect->left = pt.h; -} - -static SInt32 wxShapedMacWindowGetFeatures(WindowRef WXUNUSED(window), SInt32 param) +static pascal void wxMacNMResponse( NMRecPtr ptr ) { - /*------------------------------------------------------ - Define which options your custom window supports. - --------------------------------------------------------*/ - //just enable everything for our demo - *(OptionBits*)param = - //kWindowCanGrow | - //kWindowCanZoom | - kWindowCanCollapse | - //kWindowCanGetWindowRegion | - //kWindowHasTitleBar | - //kWindowSupportsDragHilite | - kWindowCanDrawInCurrentPort | - //kWindowCanMeasureTitle | - kWindowWantsDisposeAtProcessDeath | - kWindowSupportsGetGrowImageRegion | - kWindowDefSupportsColorGrafPort; - - return 1; + NMRemove( ptr ) ; + DisposePtr( (Ptr)ptr ) ; } -// The content region is left as a rectangle matching the window size, this is -// so the origin in the paint event, and etc. still matches what the -// programmer expects. -static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn) +void wxNonOwnedWindowCarbonImpl::RequestUserAttention(int WXUNUSED(flags)) { - SetEmptyRgn(rgn); - wxNonOwnedWindow* win = wxFindWinFromMacWindow(window); - if (win) - { - Rect r ; - wxShapedMacWindowGetPos( window, &r ) ; - RectRgn( rgn , &r ) ; - } -} + NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ; -// The structure region is set to the shape given to the SetShape method. -static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn) -{ - RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window); + memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ; + notificationRequest->qType = nmType ; + notificationRequest->nmMark = 1 ; + notificationRequest->nmIcon = 0 ; + notificationRequest->nmSound = 0 ; + notificationRequest->nmStr = NULL ; + notificationRequest->nmResp = wxMacNMResponse ; - SetEmptyRgn(rgn); - if (cachedRegion) - { - Rect windowRect; - wxShapedMacWindowGetPos(window, &windowRect); // how big is the window - CopyRgn(cachedRegion, rgn); // make a copy of our cached region - OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window - //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size - } + verify_noerr( NMInstall( notificationRequest ) ) ; } -static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param) +void wxNonOwnedWindowCarbonImpl::ScreenToWindow( int *x, int *y ) { - GetWindowRegionPtr rgnRec = (GetWindowRegionPtr)param; - - if (rgnRec == NULL) - return paramErr; - - switch (rgnRec->regionCode) - { - case kWindowStructureRgn: - wxShapedMacWindowStructureRegion(window, rgnRec->winRgn); - break; - - case kWindowContentRgn: - wxShapedMacWindowContentRegion(window, rgnRec->winRgn); - break; - - default: - SetEmptyRgn(rgnRec->winRgn); - break; - } - - return noErr; + HIPoint p = CGPointMake( (x ? *x : 0), (y ? *y : 0) ); + HIViewRef contentView ; + // TODO check toolbar offset + HIViewFindByID( HIViewGetRoot( m_macWindow ), kHIViewWindowContentID , &contentView) ; + HIPointConvert( &p, kHICoordSpace72DPIGlobal, NULL, kHICoordSpaceView, contentView ); + if ( x ) + *x = (int)p.x; + if ( y ) + *y = (int)p.y; } -// Determine the region of the window which was hit -// -static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param) +void wxNonOwnedWindowCarbonImpl::WindowToScreen( int *x, int *y ) { - Point hitPoint; - static RgnHandle tempRgn = NULL; - - if (tempRgn == NULL) - tempRgn = NewRgn(); - - // get the point clicked - SetPt( &hitPoint, LoWord(param), HiWord(param) ); - - // Mac OS 8.5 or later - wxShapedMacWindowStructureRegion(window, tempRgn); - if (PtInRgn( hitPoint, tempRgn )) //in window content region? - return wInContent; - - // no significant area was hit - return wNoHit; + HIPoint p = CGPointMake( (x ? *x : 0), (y ? *y : 0) ); + HIViewRef contentView ; + // TODO check toolbar offset + HIViewFindByID( HIViewGetRoot( m_macWindow ), kHIViewWindowContentID , &contentView) ; + HIPointConvert( &p, kHICoordSpaceView, contentView, kHICoordSpace72DPIGlobal, NULL ); + if ( x ) + *x = (int)p.x; + if ( y ) + *y = (int)p.y; } -static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode), WindowRef window, SInt16 message, SInt32 param) +wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, const wxPoint& pos, const wxSize& size, + long style, long extraStyle, const wxString& name ) { - switch (message) - { - case kWindowMsgHitTest: - return wxShapedMacWindowHitTest(window, param); - - case kWindowMsgGetFeatures: - return wxShapedMacWindowGetFeatures(window, param); - - // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow - case kWindowMsgGetRegion: - return wxShapedMacWindowGetRegion(window, param); - - default: - break; - } - - return 0; + wxNonOwnedWindowImpl* now = new wxNonOwnedWindowCarbonImpl( wxpeer ); + now->Create( parent, pos, size, style , extraStyle, name ); + return now; } - -