From 9234615181cb1b63d509c2e16afb39b374d44987 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Wed, 30 Mar 2005 05:42:49 +0000 Subject: [PATCH] unifying redraw and scrolling calls between compositing and non-compositing modes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33168 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/mac/carbon/private.h | 3 +- include/wx/mac/carbon/toplevel.h | 1 + src/mac/carbon/toplevel.cpp | 52 ++++++++++++++++++++++++ src/mac/carbon/utils.cpp | 47 +++++++++++++++++++--- src/mac/carbon/window.cpp | 69 +++++++++++++------------------- 5 files changed, 123 insertions(+), 49 deletions(-) diff --git a/include/wx/mac/carbon/private.h b/include/wx/mac/carbon/private.h index 61860b319a..232f87af64 100644 --- a/include/wx/mac/carbon/private.h +++ b/include/wx/mac/carbon/private.h @@ -524,7 +524,8 @@ public : // where is in native window relative coordinates virtual void SetNeedsDisplay( Rect* where = NULL ) ; - virtual void ScrollRect( const wxRect &rect , int dx , int dy ) ; + // if rect = NULL, entire view + virtual void ScrollRect( wxRect *rect , int dx , int dy ) ; // in native parent window relative coordinates virtual void GetRect( Rect *r ) ; diff --git a/include/wx/mac/carbon/toplevel.h b/include/wx/mac/carbon/toplevel.h index e479a11c41..0abf5b1c0e 100644 --- a/include/wx/mac/carbon/toplevel.h +++ b/include/wx/mac/carbon/toplevel.h @@ -86,6 +86,7 @@ public: WXWindow MacGetWindowRef() { return m_macWindow ; } virtual void MacActivate( long timestamp , bool inIsActivating ) ; + virtual void MacPerformUpdates() ; virtual void Raise(); virtual void Lower(); diff --git a/src/mac/carbon/toplevel.cpp b/src/mac/carbon/toplevel.cpp index 82605e75ae..8d72ff0208 100644 --- a/src/mac/carbon/toplevel.cpp +++ b/src/mac/carbon/toplevel.cpp @@ -1437,6 +1437,58 @@ wxUint32 wxTopLevelWindowMac::MacGetWindowAttributes() const return attr ; } +void wxTopLevelWindowMac::MacPerformUpdates() +{ +#if TARGET_API_MAC_OSX + if ( m_macUsesCompositing ) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 + // for composited windows this also triggers a redraw of all + // invalid views in the window + if( UMAGetSystemVersion() >= 0x1030 ) + HIWindowFlush((WindowRef) m_macWindow) ; + 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 +#endif + { + BeginUpdate( (WindowRef) m_macWindow ) ; + + RgnHandle updateRgn = NewRgn(); + if ( updateRgn ) + { + GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn ); + UpdateControls( (WindowRef)m_macWindow , updateRgn ) ; + // if ( !EmptyRgn( updateRgn ) ) + // MacDoRedraw( updateRgn , 0 , true) ; + DisposeRgn( updateRgn ); + } + EndUpdate( (WindowRef)m_macWindow ) ; + QDFlushPortBuffer( GetWindowPort( (WindowRef)m_macWindow ) , NULL ) ; + } +} + // Attracts the users attention to this window if the application is // inactive (should be called when a background event occurs) diff --git a/src/mac/carbon/utils.cpp b/src/mac/carbon/utils.cpp index 4c829e6ca5..00a59e4527 100644 --- a/src/mac/carbon/utils.cpp +++ b/src/mac/carbon/utils.cpp @@ -1107,10 +1107,25 @@ void wxMacControl::SetDrawingEnabled( bool enable ) bool wxMacControl::GetNeedsDisplay() const { #if TARGET_API_MAC_OSX - return HIViewGetNeedsDisplay( m_controlRef ) ; -#else - return false ; + if ( m_isCompositing ) + { + return HIViewGetNeedsDisplay( m_controlRef ) ; + } + else #endif + { + if ( !IsVisible() ) + return false ; + + Rect controlBounds ; + GetControlBounds( m_controlRef, &controlBounds ) ; + RgnHandle rgn = NewRgn() ; + GetWindowRegion ( GetControlOwner( m_controlRef ) , kWindowUpdateRgn , rgn ) ; + Boolean intersect = RectInRgn ( &controlBounds , rgn ) ; + DisposeRgn( rgn ) ; + return intersect ; + } + } #endif @@ -1223,6 +1238,8 @@ void wxMacControl::SetRect( Rect *r ) Rect controlBounds = *r ; + // since the rect passed in is always (even in non-compositing) relative + // to the (native) parent, we have to adjust to window relative here wxMacControl* parent = m_peer->GetParent()->GetPeer() ; if( parent->m_isRootControl == false ) { @@ -1351,12 +1368,30 @@ void wxMacControl::InvalidateWithChildren() #endif } -void wxMacControl::ScrollRect( const wxRect &r , int dx , int dy ) +void wxMacControl::ScrollRect( wxRect *r , int dx , int dy ) { + wxASSERT( r != NULL ) ; #if TARGET_API_MAC_OSX - HIRect scrollarea = CGRectMake( r.x , r.y , r.width , r.height) ; - HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ) ; + if ( m_isCompositing ) + { + HIRect scrollarea = CGRectMake( r->x , r->y , r->width , r->height) ; + HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ) ; + } + else #endif + { + Rect bounds ; + GetControlBounds( m_controlRef , &bounds ) ; + Point topleft = { bounds.top , bounds.left } ; + bounds.left += r->x ; + bounds.top += r->y ; + bounds.bottom = bounds.top + r->height ; + bounds.right = bounds.left + r->width ; + wxMacWindowClipper clip( m_peer ) ; + RgnHandle updateRgn = NewRgn() ; + ::ScrollRect( &bounds , dx , dy , updateRgn ) ; + InvalWindowRgn( GetControlOwner( m_controlRef ) , updateRgn ) ; + } } diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 0f361b6d1e..625eabb20d 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -2405,12 +2405,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,7 +2427,8 @@ 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 ) + + if( UMAGetSystemVersion() < 0x1030 || !m_peer->IsCompositing() ) Update() ; else HIViewRender(m_peer->GetControlRef()) ; @@ -2436,8 +2436,25 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) } // 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( UMAGetSystemVersion() < 0x1030 || !m_peer->IsCompositing() ) + Update() ; + else + HIViewRender(m_peer->GetControlRef()) ; +#endif + } + else +#endif + { wxPoint pos; pos.x = pos.y = 0; @@ -2449,9 +2466,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 +2502,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 +2704,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 -- 2.45.2