X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/489468feaa08b8f504735eecca522fb8d0f825d2..bc5c09a3aa3662137da2d781c0b101a598d2650d:/src/osx/carbon/nonownedwnd.cpp diff --git a/src/osx/carbon/nonownedwnd.cpp b/src/osx/carbon/nonownedwnd.cpp index 4c8d95e72e..88aedf36be 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 @@ -20,7 +20,7 @@ #include "wx/tooltip.h" #include "wx/nonownedwnd.h" -#include "wx/mac/private.h" +#include "wx/osx/private.h" #include "wx/settings.h" #include "wx/frame.h" @@ -28,15 +28,232 @@ #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 ) ; +} + +void wxNonOwnedWindowCarbonImpl::ShowWithoutActivating() +{ + bool plainTransition = true; + +#if wxUSE_SYSTEM_OPTIONS + if ( wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) + plainTransition = ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1 ) ; +#endif + + if ( plainTransition ) + ::ShowWindow( (WindowRef)m_macWindow ); + else + ::TransitionWindow( (WindowRef)m_macWindow, kWindowZoomTransitionEffect, kWindowShowTransitionAction, 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) + { + ShowWithoutActivating(); + ::SelectWindow( (WindowRef)m_macWindow ) ; + } + 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 ); + } + else + { + OSStatus err = HIWindowChangeFeatures( m_macWindow, kWindowIsOpaque, 0 ); + 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 +261,7 @@ static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param); -// ============================================================================ -// wxNonOwnedWindow implementation -// ============================================================================ +void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ); // --------------------------------------------------------------------------- // Carbon Events @@ -89,7 +304,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 +433,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 ; @@ -332,8 +545,9 @@ void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) break ; } break ; - - case kEventMouseWheelMoved : + // TODO http://developer.apple.com/qa/qa2005/qa1453.html + // add declaration for 10.4 and change to kEventMouseScroll + case kEventMouseWheelMoved : { wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ; @@ -366,7 +580,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 +605,7 @@ wxMacTopLevelMouseEventHandler(EventHandlerCallRef WXUNUSED(handler), if ( window ) { - wxMacGlobalToLocal( window, &windowMouseLocation ) ; + QDGlobalToLocalPoint( GetWindowPort( window ), &windowMouseLocation ); if ( wxApp::s_captureWindow #if !NEW_CAPTURE_HANDLING @@ -408,11 +622,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 +635,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 +699,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 +773,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 +816,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 +851,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 +871,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 ; @@ -732,14 +937,19 @@ wxNonOwnedWindowEventHandler(EventHandlerCallRef WXUNUSED(handler), // mix this in from window.cpp pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ; -pascal OSStatus wxNonOwnedEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +static pascal OSStatus wxNonOwnedEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; 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 +974,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() +// The structure region is set to the shape given to the SetShape method. +static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn) { - m_macWindow = NULL ; - m_macEventHandler = NULL ; -} + RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window); -wxMacDeferredWindowDeleter::wxMacDeferredWindowDeleter( WindowRef windowRef ) -{ - m_macWindow = windowRef ; + 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 + } } -wxMacDeferredWindowDeleter::~wxMacDeferredWindowDeleter() +static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param) { - DisposeWindow( (WindowRef) m_macWindow ) ; -} + GetWindowRegionPtr rgnRec = (GetWindowRegionPtr)param; -bool wxNonOwnedWindow::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) -{ - // init our fields - Init(); + if (rgnRec == NULL) + return paramErr; - m_windowStyle = style; + switch (rgnRec->regionCode) + { + case kWindowStructureRgn: + wxShapedMacWindowStructureRegion(window, rgnRec->winRgn); + break; - SetName( name ); + case kWindowContentRgn: + wxShapedMacWindowContentRegion(window, rgnRec->winRgn); + break; - m_windowId = id == -1 ? NewControlId() : id; + default: + SetEmptyRgn(rgnRec->winRgn); + break; + } - DoMacCreateRealWindow( parent, pos , size , style , name ) ; + return noErr; +} - SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE )); +// Determine the region of the window which was hit +// +static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param) +{ + Point hitPoint; + static RgnHandle tempRgn = NULL; - if (GetExtraStyle() & wxFRAME_EX_METAL) - MacSetMetalAppearance(true); + if (tempRgn == NULL) + tempRgn = NewRgn(); - if ( parent ) - parent->AddChild(this); + // get the point clicked + SetPt( &hitPoint, LoWord(param), HiWord(param) ); - return true; + // 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,56 +1142,54 @@ wxNonOwnedWindow::~wxNonOwnedWindow() m_macEventHandler = NULL ; } - wxRemoveMacWindowAssociation( this ) ; + if ( m_macWindow && !m_wxPeer->IsNativeWindowWrapper()) + 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::WillBeDestroyed() { - 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; -} +} -void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window, EventHandlerRef* handler, void *ref) +static void wxNonOwnedWindowInstallTopLevelWindowEventHandler(WindowRef window, EventHandlerRef* handler, void *ref) { InstallWindowEventHandler(window, GetwxNonOwnedEventHandlerUPP(), 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,78 +1198,72 @@ 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 ) +void wxNonOwnedWindowCarbonImpl::Create( + wxWindow* parent, + WXWindow nativeWindow ) { - DoMacCreateRealWindow( NULL, pos, size, style, name ); + m_macWindow = nativeWindow; } -void wxNonOwnedWindow::DoMacCreateRealWindow( - wxWindow* parent, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name ) +void wxNonOwnedWindowCarbonImpl::Create( + wxWindow* parent, + const wxPoint& pos, + const wxSize& size, + long style, long extraStyle, + const wxString& WXUNUSED(name) ) { + OSStatus err = noErr ; - SetName(name); - m_windowStyle = style; - m_isShown = false; - - // create frame. + Rect theBoundsRect; + 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); - + // translate the window attributes in the appropriate window class and attributes WindowClass wclass = 0; WindowAttributes attr = kWindowNoAttributes ; WindowGroupRef group = NULL ; 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 +1277,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 ; } @@ -1039,97 +1302,81 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( wclass = kPlainWindowClass ; } } - + 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 ) { WindowRef parenttlw = (WindowRef) parent->MacGetTopLevelWindowRef(); if( parenttlw ) group = GetWindowGroupParent( GetWindowGroup( parenttlw ) ); } - + 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; customWindowDefSpec.u.defProc = #ifdef __LP64__ - (WindowDefUPP) wxShapedMacWindowDef; + (WindowDefUPP) wxShapedMacWindowDef; #else - NewWindowDefUPP(wxShapedMacWindowDef); + NewWindowDefUPP(wxShapedMacWindowDef); #endif err = ::CreateCustomWindow( &customWindowDefSpec, wclass, - attr, &theBoundsRect, - (WindowRef*) &m_macWindow); + attr, &theBoundsRect, + (WindowRef*) &m_macWindow); } else { err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ; } - + if ( err == noErr && m_macWindow != NULL && group != NULL ) SetWindowGroup( (WindowRef) m_macWindow , group ) ; - + wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") ); - + // setup a separate group for each window, so that overlays can be handled easily - + WindowGroupRef overlaygroup = NULL; verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrHideOnCollapse, &overlaygroup )); verify_noerr( SetWindowGroupParent( overlaygroup, GetWindowGroup( (WindowRef) m_macWindow ))); verify_noerr( SetWindowGroup( (WindowRef) m_macWindow , overlaygroup )); - + if ( activationScopeSet ) { verify_noerr( SetWindowActivationScope( (WindowRef) m_macWindow , activationScope )); } - + // 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. #if 0 // TARGET_API_MAC_OSX @@ -1139,114 +1386,36 @@ void wxNonOwnedWindow::DoMacCreateRealWindow( MacSetMetalAppearance( true ) ; } #endif - + if ( m_macWindow != NULL ) { MacSetUnifiedAppearance( true ) ; } - + 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 ( HasFlag(wxFRAME_SHAPED) ) + + if ( extraStyle & wxFRAME_EX_METAL) + MacSetMetalAppearance(true); + + 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 +1442,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 +1455,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 +1506,209 @@ 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) +void wxNonOwnedWindowCarbonImpl::SetTitle( const wxString& title, wxFontEncoding encoding ) { - OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, (CGFloat)((alpha)/255.0)); - return result == noErr; + SetWindowTitleWithCFString( m_macWindow , wxCFStringRef( title , encoding ) ) ; } - -bool wxNonOwnedWindow::CanSetTransparent() +bool wxNonOwnedWindowCarbonImpl::IsMaximized() const { - return true; + return IsWindowInStandardState( m_macWindow , NULL , NULL ) ; } - -void wxNonOwnedWindow::SetExtraStyle(long exStyle) +bool wxNonOwnedWindowCarbonImpl::IsIconized() const { - 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) -{ - 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 + return IsWindowCollapsed((WindowRef)GetWXWindow() ) ; } -void wxNonOwnedWindow::DoGetPosition( int *x, int *y ) const +void wxNonOwnedWindowCarbonImpl::Iconize( bool iconize ) { - Rect bounds ; - - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowStructureRgn , &bounds )) ; - - if (x) - *x = bounds.left ; - if (y) - *y = bounds.top ; -} - -void wxNonOwnedWindow::DoGetSize( int *width, int *height ) 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 ; + if ( IsWindowCollapsable( m_macWindow ) ) + CollapseWindow( m_macWindow , iconize ) ; } -void wxNonOwnedWindow::DoGetClientSize( int *width, int *height ) const +void wxNonOwnedWindowCarbonImpl::Maximize(bool maximize) { - Rect bounds ; - - verify_noerr(GetWindowBounds((WindowRef) m_macWindow, kWindowContentRgn , &bounds )) ; - - if (width) - *width = bounds.right - bounds.left ; - if (height) - *height = bounds.bottom - bounds.top ; -} - -void wxNonOwnedWindow::MacSetMetalAppearance( bool set ) -{ - 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) ; - - // 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) ) ; -} + 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 -bool wxNonOwnedWindow::MacGetUnifiedAppearance() const -{ - return MacGetWindowAttributes() & kWindowUnifiedTitleAndToolbarAttribute ; -} + wxRect client = wxGetClientDisplayRect() ; -void wxNonOwnedWindow::MacChangeWindowAttributes( wxUint32 attributesToSet , wxUint32 attributesToClear ) -{ - ChangeWindowAttributes( (WindowRef)m_macWindow, attributesToSet, attributesToClear ) ; -} + int left, top, width, height ; + int x, y, w, h ; -wxUint32 wxNonOwnedWindow::MacGetWindowAttributes() const -{ - UInt32 attr = 0 ; - GetWindowAttributes( (WindowRef) m_macWindow, &attr ) ; + x = client.x ; + y = client.y ; + w = client.width ; + h = client.height ; - return attr ; -} + GetContentArea( left, top, width, height ) ; + int outerwidth, outerheight; + GetSize( outerwidth, outerheight ); -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) +static pascal void wxMacNMResponse( NMRecPtr ptr ) { - 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; + NMRemove( ptr ) ; + DisposePtr( (Ptr)ptr ) ; } -static SInt32 wxShapedMacWindowGetFeatures(WindowRef WXUNUSED(window), SInt32 param) +void wxNonOwnedWindowCarbonImpl::RequestUserAttention(int WXUNUSED(flags)) { - /*------------------------------------------------------ - 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; + NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ; - return 1; + memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ; + notificationRequest->qType = nmType ; + notificationRequest->nmMark = 1 ; + notificationRequest->nmIcon = 0 ; + notificationRequest->nmSound = 0 ; + notificationRequest->nmStr = NULL ; + notificationRequest->nmResp = wxMacNMResponse ; + + verify_noerr( NMInstall( notificationRequest ) ) ; } -// 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::ScreenToWindow( int *x, int *y ) { - SetEmptyRgn(rgn); - wxNonOwnedWindow* win = wxFindWinFromMacWindow(window); - if (win) - { - Rect r ; - wxShapedMacWindowGetPos( window, &r ) ; - RectRgn( rgn , &r ) ; - } + 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; } -// The structure region is set to the shape given to the SetShape method. -static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn) +void wxNonOwnedWindowCarbonImpl::WindowToScreen( int *x, int *y ) { - RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window); - - 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 - } + 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 SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param) +bool wxNonOwnedWindowCarbonImpl::IsActive() { - 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; + return ActiveNonFloatingWindow() == m_macWindow; } -// Determine the region of the window which was hit -// -static SInt32 wxShapedMacWindowHitTest(WindowRef window, SInt32 param) +wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, const wxPoint& pos, const wxSize& size, + long style, long extraStyle, const wxString& name ) { - 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; + wxNonOwnedWindowImpl* now = new wxNonOwnedWindowCarbonImpl( wxpeer ); + now->Create( parent, pos, size, style , extraStyle, name ); + return now; } -static pascal long wxShapedMacWindowDef(short WXUNUSED(varCode), WindowRef window, SInt16 message, SInt32 param) +wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, WXWindow nativeWindow ) { - 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; + wxNonOwnedWindowCarbonImpl* now = new wxNonOwnedWindowCarbonImpl( wxpeer ); + now->Create( parent, nativeWindow ); + return now; } -