X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bc2b0c1b2b44c597aa9fa9214cc4237a6c5740e1..aacd14428971b5e199f88597f76a895c68dd298f:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 07696993a6..ea45c04b31 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -222,6 +222,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl { if ( thisWindow->GetPeer()->IsCompositing() == false ) { +/* if ( thisWindow->GetPeer()->IsRootControl() == false ) { GetControlBounds( thisWindow->GetPeer()->GetControlRef() , &controlBounds ) ; @@ -230,6 +231,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl { thisWindow->GetPeer()->GetRect( &controlBounds ) ; } +*/ allocatedRgn = NewRgn() ; CopyRgn( updateRgn , allocatedRgn ) ; OffsetRgn( allocatedRgn , -controlBounds.left , -controlBounds.top ) ; @@ -574,6 +576,9 @@ void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part) { RgnHandle rgn = NewRgn() ; GetClip( rgn ) ; + int x = 0 , y = 0; + MacWindowToRootWindow( &x,&y ) ; + OffsetRgn( rgn , -x , -y ) ; wxMacWindowStateSaver sv( this ) ; SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ; MacDoRedraw( rgn , 0 ) ; @@ -748,6 +753,8 @@ void wxWindowMac::Init() #if wxMAC_USE_CORE_GRAPHICS m_cgContextRef = NULL ; #endif + m_clipChildren = false ; + m_cachedClippedRectValid = false ; // we need a valid font for the encodings wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); } @@ -1115,17 +1122,17 @@ void wxWindowMac::SetFocus() void wxWindowMac::DoCaptureMouse() { - wxTheApp->s_captureWindow = this ; + wxApp::s_captureWindow = this ; } wxWindow* wxWindowBase::GetCapture() { - return wxTheApp->s_captureWindow ; + return wxApp::s_captureWindow ; } void wxWindowMac::DoReleaseMouse() { - wxTheApp->s_captureWindow = NULL ; + wxApp::s_captureWindow = NULL ; } #if wxUSE_DRAG_AND_DROP @@ -1341,9 +1348,13 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const if ( !IsTopLevel() ) { - wxMacControl::Convert( &pt , MacGetTopLevelWindow()->m_peer , m_peer ) ; - pt.x += MacGetLeftBorderSize() ; - pt.y += MacGetTopBorderSize() ; + wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + if (top) + { + wxMacControl::Convert( &pt , top->m_peer , m_peer ) ; + pt.x += MacGetLeftBorderSize() ; + pt.y += MacGetTopBorderSize() ; + } } if ( x ) *x = (int) pt.x ; @@ -1432,11 +1443,11 @@ void wxWindowMac::DoGetClientSize(int *x, int *y) const if (m_hScrollBar && m_hScrollBar->IsShown() ) { - hh -= m_hScrollBar->GetSize().y ; // MAC_SCROLLBAR_SIZE ; + hh -= m_hScrollBar->GetSize().y ; } if (m_vScrollBar && m_vScrollBar->IsShown() ) { - ww -= m_vScrollBar->GetSize().x ; // MAC_SCROLLBAR_SIZE; + ww -= m_vScrollBar->GetSize().x ; } if(x) *x = ww; if(y) *y = hh; @@ -1741,10 +1752,10 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) MacInvalidateBorders() ; + m_cachedClippedRectValid = false ; m_peer->SetRect( &r ) ; - - if ( doMove ) - wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified + + wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified MacInvalidateBorders() ; @@ -2405,12 +2416,11 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) if( dx == 0 && dy ==0 ) return ; - - { - int width , height ; GetClientSize( &width , &height ) ; #if TARGET_API_MAC_OSX + if ( 1 /* m_peer->IsCompositing() */ ) + { // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control // area is scrolled, this does not occur if width and height are 2 pixels less, // TODO write optimal workaround @@ -2428,16 +2438,39 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) m_peer->SetNeedsDisplay() ; #else // this would be the preferred version for fast drawing controls - if( UMAGetSystemVersion() < 0x1030 ) - Update() ; - else + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 + if( UMAGetSystemVersion() >= 0x1030 && m_peer->IsCompositing() ) HIViewRender(m_peer->GetControlRef()) ; + else +#endif + Update() ; #endif } // as the native control might be not a 0/0 wx window coordinates, we have to offset scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; - m_peer->ScrollRect( scrollrect , dx , dy ) ; + m_peer->ScrollRect( (&scrollrect) , dx , dy ) ; + + // becuase HIViewScrollRect does not scroll the already invalidated area we have two options + // either immediate redraw or full invalidate +#if 0 + // is the better overall solution, as it does not slow down scrolling + m_peer->SetNeedsDisplay() ; #else + // this would be the preferred version for fast drawing controls + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 + if( UMAGetSystemVersion() >= 0x1030 && m_peer->IsCompositing() ) + HIViewRender(m_peer->GetControlRef()) ; + else +#endif + Update() ; + +#endif + } + else +#endif + { wxPoint pos; pos.x = pos.y = 0; @@ -2449,9 +2482,9 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) wxClientDC dc(this) ; wxMacPortSetter helper(&dc) ; - m_peer->GetRect( &scrollrect ) ; - scrollrect.top += MacGetTopBorderSize() ; - scrollrect.left += MacGetLeftBorderSize() ; + m_peer->GetRectInWindowCoords( &scrollrect ) ; + //scrollrect.top += MacGetTopBorderSize() ; + //scrollrect.left += MacGetLeftBorderSize() ; scrollrect.bottom = scrollrect.top + height ; scrollrect.right = scrollrect.left + width ; @@ -2485,7 +2518,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) DisposeRgn( formerUpdateRgn ) ; DisposeRgn( scrollRgn ) ; } -#endif + Update() ; } for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) @@ -2687,39 +2720,7 @@ void wxWindowMac::ClearBackground() void wxWindowMac::Update() { #if TARGET_API_MAC_OSX - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 - WindowRef window = (WindowRef)MacGetTopLevelWindowRef() ; - - // for composited windows this also triggers a redraw of all - // invalid views in the window - if( UMAGetSystemVersion() >= 0x1030 ) - HIWindowFlush(window) ; - else -#endif - { - // the only way to trigger the redrawing on earlier systems is to call - // ReceiveNextEvent - - EventRef currentEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ; - UInt32 currentEventClass = 0 ; - UInt32 currentEventKind = 0 ; - if ( currentEvent != NULL ) - { - currentEventClass = ::GetEventClass( currentEvent ) ; - currentEventKind = ::GetEventKind( currentEvent ) ; - } - if ( currentEventClass != kEventClassMenu ) - { - // when tracking a menu, strange redraw errors occur if we flush now, so leave.. - - EventRef theEvent; - OSStatus status = noErr ; - status = ReceiveNextEvent( 0 , NULL , kEventDurationNoWait , false , &theEvent ) ; - } - else - m_peer->SetNeedsDisplay() ; - } + MacGetTopLevelWindow()->MacPerformUpdates() ; #else ::Draw1Control( m_peer->GetControlRef() ) ; #endif @@ -2735,82 +2736,127 @@ wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const } return win ; } -wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) + +const wxRect& wxWindowMac::MacGetClippedClientRect() const +{ + MacUpdateClippedRects() ; + return m_cachedClippedClientRect ; +} + +const wxRect& wxWindowMac::MacGetClippedRect() const { + MacUpdateClippedRects() ; + return m_cachedClippedRect ; +} + +const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const +{ + MacUpdateClippedRects() ; + return m_cachedClippedRectWithOuterStructure ; +} + +const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) +{ + static wxRegion emptyrgn ; + if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ ) + { + MacUpdateClippedRects() ; + if ( includeOuterStructures ) + return m_cachedClippedRegionWithOuterStructure ; + else + return m_cachedClippedRegion ; + } + else + { + return emptyrgn ; + } +} + +void wxWindowMac::MacUpdateClippedRects() const +{ + if ( m_cachedClippedRectValid ) + return ; + // includeOuterStructures is true if we try to draw somthing like a focus ring etc. // also a window dc uses this, in this case we only clip in the hierarchy for hard // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having // to add focus borders everywhere Rect r ; - RgnHandle visRgn = NewRgn() ; - RgnHandle tempRgn = NewRgn() ; - if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ ) + Rect rIncludingOuterStructures ; + + m_peer->GetRect( &r ) ; + r.left -= MacGetLeftBorderSize() ; + r.top -= MacGetTopBorderSize() ; + r.bottom += MacGetBottomBorderSize() ; + r.right += MacGetRightBorderSize() ; + + r.right -= r.left ; + r.bottom -= r.top ; + r.left = 0 ; + r.top = 0 ; + + rIncludingOuterStructures = r ; + InsetRect( &rIncludingOuterStructures , -4 , -4 ) ; + + wxRect cl = GetClientRect() ; + Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ; + + const wxWindow* child = this ; + const wxWindow* parent = NULL ; + while( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL ) { - m_peer->GetRect( &r ) ; - r.left -= MacGetLeftBorderSize() ; - r.top -= MacGetTopBorderSize() ; - r.bottom += MacGetBottomBorderSize() ; - r.right += MacGetRightBorderSize() ; + int x , y ; + wxSize size ; - r.right -= r.left ; - r.bottom -= r.top ; - r.left = 0 ; - r.top = 0 ; + if ( parent->MacIsChildOfClientArea(child) ) + { + size = parent->GetClientSize() ; + wxPoint origin = parent->GetClientAreaOrigin() ; + x = origin.x ; + y = origin.y ; + } + else + { + // this will be true for scrollbars, toolbars etc. + size = parent->GetSize() ; + y = parent->MacGetTopBorderSize() ; + x = parent->MacGetLeftBorderSize() ; + size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ; + size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ; + } - if ( includeOuterStructures ) - InsetRect( &r , -4 , -4 ) ; - RectRgn( visRgn , &r ) ; + parent->MacWindowToRootWindow( &x, &y ) ; + MacRootWindowToWindow( &x , &y ) ; - if ( !IsTopLevel() ) - { - wxWindow* child = this ; - wxWindow* parent = child->GetParent() ; - while( parent ) - { - int x , y ; - wxSize size ; - // we have to find a better clipping algorithm here, in order not to clip things - // positioned like status and toolbar - if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ ) - { - size = parent->GetSize() ; - x = y = 0 ; - } - else - { - size = parent->GetClientSize() ; - wxPoint origin = parent->GetClientAreaOrigin() ; - x = origin.x ; - y = origin.y ; - } - parent->MacWindowToRootWindow( &x, &y ) ; - MacRootWindowToWindow( &x , &y ) ; + Rect rparent = { y , x , y + size.y , x + size.x } ; - if ( !includeOuterStructures || ( - parent->MacClipChildren() || - ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) - ) ) - { - SetRectRgn( tempRgn , - x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() , - x + size.x - parent->MacGetRightBorderSize(), - y + size.y - parent->MacGetBottomBorderSize()) ; + // the wxwindow and client rects will always be clipped + SectRect( &r , &rparent , &r ) ; + SectRect( &rClient , &rparent , &rClient ) ; - SectRgn( visRgn , tempRgn , visRgn ) ; - } - if ( parent->IsTopLevel() ) - break ; - child = parent ; - parent = child->GetParent() ; - } + // the structure only at 'hard' borders + if ( parent->MacClipChildren() || + ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) ) + { + SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ; } + child = parent ; } - - wxRegion vis = visRgn ; - DisposeRgn( visRgn ) ; - DisposeRgn( tempRgn ) ; - return vis ; + + m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ; + m_cachedClippedClientRect = wxRect( rClient.left , rClient.top , + rClient.right - rClient.left , rClient.bottom - rClient.top ) ; + m_cachedClippedRectWithOuterStructure = wxRect( + rIncludingOuterStructures.left , rIncludingOuterStructures.top , + rIncludingOuterStructures.right - rIncludingOuterStructures.left , + rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ; + + m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ; + m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ; + m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ; + + m_cachedClippedRectValid = true ; } /* @@ -2839,12 +2885,12 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) // for all the others only their client area, otherwise they // might be drawing with full alpha and eg put blue into // the grow-box area of a scrolled window (scroll sample) - wxDC* dc ; + wxDC* dc = new wxWindowDC(this); if ( IsTopLevel() ) - dc = new wxWindowDC(this); + dc->SetClippingRegion(wxRegion(updatergn)); else - dc = new wxClientDC(this); - dc->SetClippingRegion(wxRegion(updatergn)); + dc->SetClippingRegion(wxRegion(newupdate)); + wxEraseEvent eevent( GetId(), dc ); eevent.SetEventObject( this ); GetEventHandler()->ProcessEvent( eevent ); @@ -2978,6 +3024,14 @@ void wxWindowMac::MacCreateScrollBars( long style ) MacRepositionScrollBars() ; // we might have a real position shift } +bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const +{ + if ( child != NULL && ( child == m_hScrollBar || child == m_vScrollBar ) ) + return false ; + else + return true ; +} + void wxWindowMac::MacRepositionScrollBars() { if ( !m_hScrollBar && !m_vScrollBar ) @@ -2996,10 +3050,10 @@ void wxWindowMac::MacRepositionScrollBars() width -= MacGetLeftBorderSize() + MacGetRightBorderSize(); height -= MacGetTopBorderSize() + MacGetBottomBorderSize(); - wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ; - wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ; - wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ; - wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ; + wxPoint vPoint(width-scrlsize, 0) ; + wxSize vSize(scrlsize, height - adjust) ; + wxPoint hPoint(0 , height-scrlsize ) ; + wxSize hSize( width - adjust, scrlsize) ; /* int x = 0 ; int y = 0 ; @@ -3064,6 +3118,7 @@ bool wxWindowMac::AcceptsFocus() const void wxWindowMac::MacSuperChangedPosition() { + m_cachedClippedRectValid = false ; // only window-absolute structures have to be moved i.e. controls wxWindowList::compatibility_iterator node = GetChildren().GetFirst();