X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/34a3ed019b89012199e1a88f540010653bec90d0..f7d2128f3c89b2d00fbac0d8c9798409ae23b408:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index a568f33d28..aa9503fb3b 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -171,6 +171,8 @@ static const EventTypeSpec eventList[] = static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; + static wxWindowMac* targetFocusWindow = NULL; + static wxWindowMac* formerFocusWindow = NULL; wxMacCarbonEvent cEvent( event ) ; @@ -209,7 +211,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl if ( thisWindow->MacIsUserPane() ) { static float color = 0.5 ; - static channel = 0 ; + static int channel = 0 ; HIRect bounds; CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; @@ -232,17 +234,21 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl bool created = false ; CGContextRef cgContext = NULL ; OSStatus err = cEvent.GetParameter(kEventParamCGContextRef, &cgContext) ; - wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ; + if ( err != noErr ) + { + wxFAIL_MSG("Unable to retrieve CGContextRef"); + } + thisWindow->MacSetCGContextRef( cgContext ) ; { wxMacCGContextStateSaver sg( cgContext ) ; - float alpha = 1.0 ; + CGFloat alpha = (CGFloat)1.0 ; { wxWindow* iter = thisWindow ; while ( iter ) { - alpha *= (float) iter->GetTransparent()/255.0 ; + alpha *= (CGFloat)( iter->GetTransparent()/255.0 ) ; if ( iter->IsTopLevel() ) iter = NULL ; else @@ -314,6 +320,11 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl case kEventControlFocusPartChanged : // the event is emulated by wxmac for systems lower than 10.5 { + if ( UMAGetSystemVersion() < 0x1050 ) + { + // as it is synthesized here, we have to manually avoid propagation + result = noErr; + } ControlPartCode previousControlPart = cEvent.GetParameter(kEventParamControlPreviousPart , typeControlPartCode ); ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlCurrentPart , typeControlPartCode ); @@ -340,8 +351,10 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl inKillFocusEvent = true ; wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); event.SetEventObject(thisWindow); + event.SetWindow(targetFocusWindow); thisWindow->HandleWindowEvent(event) ; inKillFocusEvent = false ; + targetFocusWindow = NULL; } } else if ( previousControlPart == 0 ) @@ -359,7 +372,9 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); event.SetEventObject(thisWindow); + event.SetWindow(formerFocusWindow); thisWindow->HandleWindowEvent(event) ; + formerFocusWindow = NULL; } } break; @@ -373,7 +388,17 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl } #endif ControlPartCode controlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); - + if ( controlPart != kControlFocusNoPart ) + { + targetFocusWindow = thisWindow; + wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), wx_static_cast(void*, thisWindow)); + } + else + { + formerFocusWindow = thisWindow; + wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), wx_static_cast(void*, thisWindow)); + } + ControlPartCode previousControlPart = 0; verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart)); @@ -390,27 +415,31 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl { // set back to 0 if problems arise #if 1 - ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); - // synthesize the event focus changed event - EventRef evRef = NULL ; - - OSStatus err = MacCreateEvent( - NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) , - kEventAttributeUserEvent , &evRef ); - verify_noerr( err ); - - wxMacCarbonEvent iEvent( evRef ) ; - iEvent.SetParameter( kEventParamDirectObject , controlRef ) ; - iEvent.SetParameter( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ) ; - iEvent.SetParameter( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ) ; - -#if 0 - // TODO test this first, avoid double posts etc... - PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh ); + if ( result == noErr ) + { + ControlPartCode currentControlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); + // synthesize the event focus changed event + EventRef evRef = NULL ; + + OSStatus err = MacCreateEvent( + NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) , + kEventAttributeUserEvent , &evRef ); + verify_noerr( err ); + + wxMacCarbonEvent iEvent( evRef ) ; + iEvent.SetParameter( kEventParamDirectObject , controlRef ); + iEvent.SetParameter( kEventParamPostTarget, typeEventTargetRef, GetControlEventTarget( controlRef ) ); + iEvent.SetParameter( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ); + iEvent.SetParameter( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ); + +#if 1 + // TODO test this first, avoid double posts etc... + PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh ); #else - wxMacWindowControlEventHandler( NULL , evRef , data ) ; + wxMacWindowControlEventHandler( NULL , evRef , data ) ; #endif - ReleaseEvent( evRef ) ; + ReleaseEvent( evRef ) ; + } #else // old implementation, to be removed if the new one works if ( controlPart == kControlFocusNoPart ) @@ -1177,9 +1206,14 @@ void wxWindowMac::SetFocus() // as we cannot rely on the control features to find out whether we are in full keyboard mode, // we can only leave in case of an error + wxLogTrace(_T("Focus"), _T("before wxWindow::SetFocus(%p) %d"), wx_static_cast(void*, this), GetName().c_str()); OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ; if ( err == errCouldntSetFocus ) + { + wxLogTrace(_T("Focus"), _T("in wxWindow::SetFocus(%p) errCouldntSetFocus"), wx_static_cast(void*, this)); return ; + } + wxLogTrace(_T("Focus"), _T("after wxWindow::SetFocus(%p)"), wx_static_cast(void*, this)); SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() ); } @@ -1402,7 +1436,7 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const if ( !IsTopLevel() ) { - wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + wxNonOwnedWindow* top = MacGetTopLevelWindow(); if (top) { pt.x -= MacGetLeftBorderSize() ; @@ -1445,7 +1479,7 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const if ( !IsTopLevel() ) { - wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + wxNonOwnedWindow* top = MacGetTopLevelWindow(); if (top) { wxMacControl::Convert( &pt , top->m_peer , m_peer ) ; @@ -1576,7 +1610,7 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) wxWindowMac *mouseWin = 0 ; { - wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ; + wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ; WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ; ControlPartCode part ; @@ -2026,8 +2060,12 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, int *descent, int *externalLeading, const wxFont *theFont ) const { const wxFont *fontToUse = theFont; + wxFont tempFont; if ( !fontToUse ) - fontToUse = &m_font; + { + tempFont = GetFont(); + fontToUse = &tempFont; + } wxClientDC dc( (wxWindowMac*) this ) ; wxCoord lx,ly,ld,le ; @@ -2115,6 +2153,12 @@ void wxWindowMac::OnEraseBackground(wxEraseEvent& event) { event.GetDC()->Clear() ; } + else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) + { + // don't skip the event here, custom background means that the app + // is drawing it itself in its OnPaint(), so don't draw it at all + // now to avoid flicker + } else { event.Skip() ; @@ -2241,7 +2285,7 @@ void wxWindowMac::MacPaintGrowBox() } else { - CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 ); + CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 ); } CGContextFillRect( cgContext, cgrect ); CGContextRestoreGState( cgContext ); @@ -2552,14 +2596,14 @@ void wxWindowMac::ClearBackground() void wxWindowMac::Update() { - wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + wxNonOwnedWindow* top = MacGetTopLevelWindow(); if (top) top->MacPerformUpdates() ; } -wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const +wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const { - wxTopLevelWindowMac* win = NULL ; + wxNonOwnedWindow* win = NULL ; WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; if ( window ) win = wxFindWinFromMacWindow( window ) ; @@ -2810,7 +2854,7 @@ WXWindow wxWindowMac::MacGetTopLevelWindowRef() const #if wxUSE_POPUPWIN wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); if ( popupwin ) - return popupwin->MacGetPopupWindowRef(); + return popupwin->MacGetWindowRef(); #endif } iter = iter->GetParent() ; @@ -3131,11 +3175,15 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) { - if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL - && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) - CallNextEventHandler( - (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , - (EventRef) wxTheApp->MacGetCurrentEvent() ) ; + // for native controls: call their native paint method + if ( !MacIsUserPane() || ( IsTopLevel() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) ) + { + if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL + && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) + CallNextEventHandler( + (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , + (EventRef) wxTheApp->MacGetCurrentEvent() ) ; + } } void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), @@ -3210,13 +3258,13 @@ bool wxWindowMac::IsShownOnScreen() const // CS : put a breakpoint here to investigate differences // between native an wx visibilities // the only place where I've encountered them until now - // are the hiding/showing sequences where the vis-changed event is + // are the hiding/showing sequences where the vis-changed event is // first sent to the innermost control, while wx does things // from the outmost control wxVis = wxWindowBase::IsShownOnScreen(); return wxVis; } - + return m_peer->IsVisible(); } #endif