X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/793921582e924133aa0712d780d04b9a87ce2450..09155be84e2240da3977cf3629c42d412177a570:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index c30e7a0467..773b9a2391 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -66,7 +66,6 @@ #include extern wxList wxPendingDelete; -wxWindowMac* gFocusWindow = NULL ; #ifdef __WXUNIVERSAL__ IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) @@ -82,7 +81,7 @@ BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) // TODO EVT_PAINT(wxWindowMac::OnPaint) EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged) EVT_INIT_DIALOG(wxWindowMac::OnInitDialog) - EVT_SET_FOCUS(wxWindowMac::OnSetFocus) +// EVT_SET_FOCUS(wxWindowMac::OnSetFocus) EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) END_EVENT_TABLE() @@ -102,25 +101,27 @@ END_EVENT_TABLE() extern long wxMacTranslateKey(unsigned char key, unsigned char code) ; pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ; -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3 +#if TARGET_API_MAC_OSX + +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3 enum { kEventControlVisibilityChanged = 157 }; #endif +#endif + static const EventTypeSpec eventList[] = { + { kEventClassControl , kEventControlHit } , #if TARGET_API_MAC_OSX { kEventClassControl , kEventControlDraw } , { kEventClassControl , kEventControlVisibilityChanged } , { kEventClassControl , kEventControlEnabledStateChanged } , { kEventClassControl , kEventControlHiliteChanged } , + { kEventClassControl , kEventControlSetFocusPart } , // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only // { kEventClassControl , kEventControlBoundsChanged } , - - {} -#else - {} #endif } ; @@ -137,6 +138,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl switch( GetEventKind( event ) ) { +#if TARGET_API_MAC_OSX case kEventControlDraw : { RgnHandle updateRgn = NULL ; @@ -149,7 +151,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl // GrafPtr myport = cEvent.GetParameter(kEventParamGrafPort,typeGrafPtr) ; #if 0 - // in case we would need a coregraphics compliant background erase first + // in case we would need a coregraphics compliant background erase first // now usable to track redraws CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; if ( thisWindow->MacIsUserPane() ) @@ -184,6 +186,50 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl case kEventControlHiliteChanged : thisWindow->MacHiliteChanged() ; break ; + case kEventControlSetFocusPart : + { + Boolean focusEverything = false ; + ControlPartCode controlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); + if ( cEvent.GetParameter(kEventParamControlFocusEverything , &focusEverything ) == noErr ) + { + } + if ( controlPart == kControlFocusNoPart ) + { + #if wxUSE_CARET + if ( thisWindow->GetCaret() ) + { + thisWindow->GetCaret()->OnKillFocus(); + } + #endif // wxUSE_CARET + wxFocusEvent event(wxEVT_KILL_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + thisWindow->GetEventHandler()->ProcessEvent(event) ; + } + else + { + // panel wants to track the window which was the last to have focus in it + wxChildFocusEvent eventFocus(thisWindow); + thisWindow->GetEventHandler()->ProcessEvent(eventFocus); + + #if wxUSE_CARET + if ( thisWindow->GetCaret() ) + { + thisWindow->GetCaret()->OnSetFocus(); + } + #endif // wxUSE_CARET + + wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + thisWindow->GetEventHandler()->ProcessEvent(event) ; + } + } + break ; +#endif + case kEventControlHit : + { + result = thisWindow->MacControlHit( handler , event ) ; + } + break ; default : break ; } @@ -426,7 +472,9 @@ pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode p void wxWindowMac::Init() { m_frozenness = 0 ; +#if WXWIN_COMPATIBILITY_2_4 m_backgroundTransparent = FALSE; +#endif // as all windows are created with WS_VISIBLE style... m_isShown = TRUE; @@ -519,11 +567,6 @@ wxWindowMac::~wxWindowMac() frame->SetLastFocus( NULL ) ; } - if ( gFocusWindow == this ) - { - gFocusWindow = NULL ; - } - DestroyChildren(); // delete our drop target if we've got one @@ -540,6 +583,7 @@ wxWindowMac::~wxWindowMac() void wxWindowMac::MacInstallEventHandler() { + wxAssociateControlWithMacControl( (ControlRef) m_macControl , this ) ; InstallControlEventHandler( (ControlRef) m_macControl, GetwxMacWindowEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macControlEventHandler); @@ -566,10 +610,18 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, { Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ; - UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback | kControlHasSpecialBackground | - kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle; - - ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, kControlSupportsEmbedding , (ControlRef*) &m_macControl); + UInt32 features = 0 + | kControlSupportsEmbedding +// | kControlSupportsLiveFeedback +// | kControlHasSpecialBackground +// | kControlSupportsCalcBestRect +// | kControlHandlesTracking + | kControlSupportsFocus +// | kControlWantsActivate +// | kControlWantsIdle + ; + + ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , (ControlRef*) &m_macControl); MacPostControlCreate(pos,size) ; #if !TARGET_API_MAC_OSX @@ -610,7 +662,6 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) { wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ; - wxAssociateControlWithMacControl( (ControlRef) m_macControl , this ) ; ::SetControlReference( (ControlRef) m_macControl , (long) this ) ; MacInstallEventHandler(); @@ -650,9 +701,14 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) { - wxASSERT( m_macControl != NULL ) ; + // Don't assert, in case we set the window variant before + // the window is created + // wxASSERT( m_macControl != NULL ) ; + + m_windowVariant = variant ; - m_windowVariant = variant ; + if (!m_macControl) + return; ControlSize size ; ThemeFontID themeFont = kThemeSystemFont ; @@ -783,73 +839,59 @@ bool wxWindowMac::SetBackgroundColour(const wxColour& col ) bool wxWindowMac::MacCanFocus() const { - wxASSERT( m_macControl != NULL ) ; - - return true ; +#if 0 + // there is currently no way to determinate whether the window is running in full keyboard + // access mode, therefore we cannot rely on these features yet + UInt32 features = 0 ; + GetControlFeatures( (ControlRef) m_macControl , &features ) ; + return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; +#endif + return true ; } void wxWindowMac::SetFocus() { - if ( gFocusWindow == this ) - return ; - if ( AcceptsFocus() ) { - if (gFocusWindow ) - { -#if wxUSE_CARET - // Deal with caret - if ( gFocusWindow->m_caret ) - { - gFocusWindow->m_caret->OnKillFocus(); - } -#endif // wxUSE_CARET -#ifndef __WXUNIVERSAL__ - wxWindow* control = wxDynamicCast( gFocusWindow , wxWindow ) ; - // TODO we must use the built-in focusing - if ( control && control->GetHandle() /* && control->MacIsReallyShown() */ ) - { - UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetTopLevelWindowRef() , (ControlRef) control->GetHandle() , kControlFocusNoPart ) ; - control->MacRedrawControl() ; - } +#if !TARGET_API_MAC_OSX + wxWindow* former = FindFocus() ; #endif - // Without testing the window id, for some reason - // a kill focus event can still be sent to - // the control just being focussed. - int thisId = this->m_windowId; - int gFocusWindowId = gFocusWindow->m_windowId; - if (gFocusWindowId != thisId) - { - wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId); - event.SetEventObject(gFocusWindow); - gFocusWindow->GetEventHandler()->ProcessEvent(event) ; - } + OSStatus err = SetKeyboardFocus( (WindowRef) MacGetTopLevelWindowRef() , (ControlRef) GetHandle() , kControlFocusNextPart ) ; + // 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 + if ( err == errCouldntSetFocus ) + return ; + +#if !TARGET_API_MAC_OSX + // emulate carbon events when running under carbonlib where they are not natively available + if ( former ) + { + EventRef evRef = NULL ; + verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent , + &evRef ) ); + + wxMacCarbonEvent cEvent( evRef ) ; + cEvent.SetParameter( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ; + cEvent.SetParameter(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ; + + wxMacWindowEventHandler( NULL , evRef , former ) ; + ReleaseEvent(evRef) ; } - gFocusWindow = this ; + // send new focus event { - #if wxUSE_CARET - // Deal with caret - if ( m_caret ) - { - m_caret->OnSetFocus(); - } - #endif // wxUSE_CARET - // panel wants to track the window which was the last to have focus in it - wxChildFocusEvent eventFocus(this); - GetEventHandler()->ProcessEvent(eventFocus); - - #ifndef __WXUNIVERSAL__ - wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ; - if ( control && control->GetHandle() ) - { - UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetTopLevelWindowRef() , (ControlRef) control->GetHandle() , kControlFocusNextPart ) ; - } - #endif - wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event) ; + EventRef evRef = NULL ; + verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent , + &evRef ) ); + + wxMacCarbonEvent cEvent( evRef ) ; + cEvent.SetParameter( kEventParamDirectObject , (ControlRef) GetHandle() ) ; + cEvent.SetParameter(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ; + + wxMacWindowEventHandler( NULL , evRef , this ) ; + ReleaseEvent(evRef) ; } +#endif } } @@ -909,10 +951,10 @@ void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y, { Point tlworigin = { 0 , 0 } ; GrafPtr port ; - ::GetPort( &port ) ; - ::SetPort( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) ) ; + bool swapped = QDSwapPort( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) , &port ) ; ::LocalToGlobal( &tlworigin ) ; - ::SetPort( port ) ; + if ( swapped ) + ::SetPort( port ) ; x = tlworigin.h ; y = tlworigin.v ; } @@ -1068,7 +1110,8 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const if ( x ) pt.x = *x ; if ( y ) pt.y = *y ; - HIViewConvertPoint( &pt , (ControlRef) m_macControl , (ControlRef) MacGetTopLevelWindow()->GetHandle() ) ; + if ( !IsTopLevel() ) + HIViewConvertPoint( &pt , (ControlRef) m_macControl , (ControlRef) MacGetTopLevelWindow()->GetHandle() ) ; if ( x ) *x = (int) pt.x ; if ( y ) *y = (int) pt.y ; @@ -1100,7 +1143,8 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const if ( x ) pt.x = *x ; if ( y ) pt.y = *y ; - HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , (ControlRef) m_macControl ) ; + if ( !IsTopLevel() ) + HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , (ControlRef) m_macControl ) ; if ( x ) *x = (int) pt.x ; if ( y ) *y = (int) pt.y ; @@ -1125,6 +1169,30 @@ void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const if ( y ) *y = y1 ; } +void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) +{ + RgnHandle rgn = NewRgn() ; + Rect content ; + if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr ) + { + GetRegionBounds( rgn , &content ) ; + DisposeRgn( rgn ) ; + } + else + { + GetControlBounds( (ControlRef) m_macControl , &content ) ; + } + Rect structure ; + GetControlBounds( (ControlRef) m_macControl , &structure ) ; +#if !TARGET_API_MAC_OSX + OffsetRect( &content , -structure.left , -structure.top ) ; +#endif + left = content.left - structure.left ; + top = content.top - structure.top ; + right = structure.right - content.right ; + bottom = structure.bottom - content.bottom ; +} + wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const { wxSize sizeTotal = size; @@ -1374,13 +1442,9 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) if ( vis ) SetControlVisibility( (ControlRef)m_macControl , true , true ) ; #else -// TODO TEST SetControlBounds( (ControlRef) m_macControl , &r ) ; if ( vis ) SetControlVisibility( (ControlRef)m_macControl , false , true ) ; - if ( doMove ) - MoveControl( (ControlRef) m_macControl , r.left , r.top ) ; - if ( doSize ) - SizeControl( (ControlRef) m_macControl , r.right-r.left , r.bottom-r.top ) ; + SetControlBounds( (ControlRef) m_macControl , &r ) ; if ( vis ) SetControlVisibility( (ControlRef)m_macControl , true , true ) ; #endif @@ -1523,9 +1587,14 @@ wxPoint wxWindowMac::GetClientAreaOrigin() const GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; #if !TARGET_API_MAC_OSX - Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; - OffsetRect( &content , -structure.left , -structure.top ) ; + // if the content rgn is empty / not supported + // don't attempt to correct the coordinates to wxWindow relative ones + if (!::EmptyRect( &content ) ) + { + Rect structure ; + GetControlBounds( (ControlRef) m_macControl , &structure ) ; + OffsetRect( &content , -structure.left , -structure.top ) ; + } #endif return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) ); @@ -1583,10 +1652,17 @@ bool wxWindowMac::Enable(bool enable) return FALSE; bool former = MacIsReallyEnabled() ; +#if TARGET_API_MAC_OSX if ( enable ) EnableControl( (ControlRef) m_macControl ) ; else DisableControl( (ControlRef) m_macControl ) ; +#else + if ( enable ) + ActivateControl( (ControlRef) m_macControl ) ; + else + DeactivateControl( (ControlRef) m_macControl ) ; +#endif if ( former != MacIsReallyEnabled() ) MacPropagateEnabledStateChanged() ; @@ -1688,7 +1764,11 @@ bool wxWindowMac::MacIsReallyShown() bool wxWindowMac::MacIsReallyEnabled() { +#if TARGET_API_MAC_OSX return IsControlEnabled( (ControlRef) m_macControl ) ; +#else + return IsControlActive( (ControlRef) m_macControl ) ; +#endif } bool wxWindowMac::MacIsReallyHilited() @@ -1824,6 +1904,27 @@ void wxWindowMac::Freeze() #endif } +#if TARGET_API_MAC_OSX +static void InvalidateControlAndChildren( HIViewRef control ) +{ + HIViewSetNeedsDisplay( control , true ) ; + UInt16 childrenCount = 0 ; + OSStatus err = CountSubControls( control , &childrenCount ) ; + if ( err == errControlIsNotEmbedder ) + return ; + wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ; + + for ( UInt16 i = childrenCount ; i >=1 ; --i ) + { + HIViewRef child ; + err = GetIndexedSubControl( control , i , & child ) ; + if ( err == errControlIsNotEmbedder ) + return ; + InvalidateControlAndChildren( child ) ; + } +} +#endif + void wxWindowMac::Thaw() { #if TARGET_API_MAC_OSX @@ -1832,7 +1933,8 @@ void wxWindowMac::Thaw() if ( !--m_frozenness ) { HIViewSetDrawingEnabled( (HIViewRef) m_macControl , true ) ; - HIViewSetNeedsDisplay( (HIViewRef) m_macControl , true ) ; + InvalidateControlAndChildren( (HIViewRef) m_macControl ) ; + // HIViewSetNeedsDisplay( (HIViewRef) m_macControl , true ) ; } #endif } @@ -2206,7 +2308,9 @@ void wxWindowMac::MacOnScroll(wxScrollEvent &event ) // Get the window with the focus wxWindowMac *wxWindowBase::FindFocus() { - return gFocusWindow ; + ControlRef control ; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; + return wxFindControlFromMacControl( control ) ; } void wxWindowMac::OnSetFocus(wxFocusEvent& event) @@ -2236,11 +2340,17 @@ void wxWindowMac::OnInternalIdle() // Raise the window to the top of the Z order void wxWindowMac::Raise() { +#if TARGET_API_MAC_OSX + HIViewSetZOrder((ControlRef)m_macControl,kHIViewZOrderAbove, NULL) ; +#endif } // Lower the window to the bottom of the Z order void wxWindowMac::Lower() { +#if TARGET_API_MAC_OSX + HIViewSetZOrder((ControlRef)m_macControl,kHIViewZOrderBelow, NULL) ; +#endif } @@ -2390,10 +2500,6 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) */ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) { - // we let the OS handle root control redraws - if ( m_macControl == MacGetTopLevelWindow()->GetHandle() ) - return false ; - RgnHandle updatergn = (RgnHandle) updatergnr ; bool handled = false ; @@ -2714,62 +2820,6 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) if ( ! GetEventHandler()->ProcessEvent(evtCtx) ) event.Skip() ; } - else if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK ) - { - - int x = event.m_x ; - int y = event.m_y ; - - if ( MacGetTopLevelWindow()->MacUsesCompositing() == false ) - { - // OS Needs it in tlw content area coordinates - MacClientToRootWindow( &x , &y ) ; - } - else - { - // OS Needs it in window not client coordinates - wxPoint origin = GetClientAreaOrigin() ; - x += origin.x ; - y += origin.y ; - } - Point localwhere ; - SInt16 controlpart ; - - localwhere.h = x ; - localwhere.v = y ; - - short modifiers = 0; - - if ( !event.m_leftDown && !event.m_rightDown ) - modifiers |= btnState ; - - if ( event.m_shiftDown ) - modifiers |= shiftKey ; - - if ( event.m_controlDown ) - modifiers |= controlKey ; - - if ( event.m_altDown ) - modifiers |= optionKey ; - - if ( event.m_metaDown ) - modifiers |= cmdKey ; - - bool handled = false ; - - if ( ::IsControlActive( (ControlRef) m_macControl ) ) - { - controlpart = ::HandleControlClick( (ControlRef) m_macControl , localwhere , modifiers , (ControlActionUPP) -1 ) ; - wxTheApp->s_lastMouseDown = 0 ; - if ( controlpart != kControlNoPart ) - { - MacHandleControlClick((WXWidget) (ControlRef) m_macControl , controlpart , false /* mouse not down anymore */ ) ; - handled = true ; - } - } - if ( !handled ) - event.Skip() ; - } else { event.Skip() ; @@ -2778,7 +2828,6 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) ) { - wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ; } Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) @@ -2790,4 +2839,9 @@ Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxS return bounds ; } +wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) +{ + return eventNotHandledErr ; +} +