X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/94d1d0f447efe45e25520d2352a4fe13c1837608..23866d595f47f48356cc63890f80049fb0f1dd43:/src/mac/carbon/toplevel.cpp diff --git a/src/mac/carbon/toplevel.cpp b/src/mac/carbon/toplevel.cpp index 3d354239a4..896ede9fdb 100644 --- a/src/mac/carbon/toplevel.cpp +++ b/src/mac/carbon/toplevel.cpp @@ -35,6 +35,7 @@ #include "wx/string.h" #include "wx/log.h" #include "wx/intl.h" + #include "wx/settings.h" #endif //WX_PRECOMP #include "wx/mac/uma.h" @@ -157,6 +158,9 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event OSStatus result = eventNotHandledErr ; wxWindow* focus = wxWindow::FindFocus() ; + if ( focus == NULL ) + return result ; + char charCode ; UInt32 keyCode ; UInt32 modifiers ; @@ -248,6 +252,8 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event wxWindow* g_MacLastWindow = NULL ; +static EventMouseButton lastButton = 0 ; + static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) { UInt32 modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; @@ -271,6 +277,17 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) { button = kEventMouseButtonSecondary ; } + + // we must make sure that our synthetic 'right' button corresponds in + // mouse down, moved and mouse up, and does not deliver a right down and left up + + if ( cEvent.GetKind() == kEventMouseDown ) + lastButton = button ; + + if ( button == 0 ) + lastButton = 0 ; + else if ( lastButton ) + button = lastButton ; // determinate the correct down state, wx does not want a 'down' for a mouseUp event, while mac delivers // this button @@ -289,29 +306,39 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) break ; } } - // determinate the correct click button - if ( button == kEventMouseButtonSecondary ) - { - if (cEvent.GetKind() == kEventMouseDown ) - wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DOWN : wxEVT_RIGHT_DCLICK ) ; - else if ( cEvent.GetKind() == kEventMouseUp ) - wxevent.SetEventType(wxEVT_RIGHT_UP ) ; - } - else if ( button == kEventMouseButtonTertiary ) + // translate into wx types + switch ( cEvent.GetKind() ) { - if (cEvent.GetKind() == kEventMouseDown ) - wxevent.SetEventType(clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ; - else if ( cEvent.GetKind() == kEventMouseUp ) - wxevent.SetEventType(wxEVT_MIDDLE_UP ) ; - } - else - { - if (cEvent.GetKind() == kEventMouseDown ) - wxevent.SetEventType(clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ; - else if ( cEvent.GetKind() == kEventMouseUp ) - wxevent.SetEventType(wxEVT_LEFT_UP ) ; - else if ( cEvent.GetKind() == kEventMouseWheelMoved ) - { + case kEventMouseDown : + switch( button ) + { + case kEventMouseButtonPrimary : + wxevent.SetEventType(clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ; + break ; + case kEventMouseButtonSecondary : + wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ; + break ; + case kEventMouseButtonTertiary : + wxevent.SetEventType(clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ; + break ; + } + break ; + case kEventMouseUp : + switch( button ) + { + case kEventMouseButtonPrimary : + wxevent.SetEventType( wxEVT_LEFT_UP ) ; + break ; + case kEventMouseButtonSecondary : + wxevent.SetEventType( wxEVT_RIGHT_UP ) ; + break ; + case kEventMouseButtonTertiary : + wxevent.SetEventType( wxEVT_MIDDLE_UP ) ; + break ; + } + break ; + case kEventMouseWheelMoved : + { wxevent.SetEventType(wxEVT_MOUSEWHEEL ) ; // EventMouseWheelAxis axis = cEvent.GetParameter(kEventParamMouseWheelAxis, typeMouseWheelAxis) ; @@ -320,10 +347,12 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) wxevent.m_wheelRotation = delta; wxevent.m_wheelDelta = 1; wxevent.m_linesPerAction = 1; - } - else + break ; + } + default : wxevent.SetEventType(wxEVT_MOTION ) ; - } + break ; + } } ControlRef wxMacFindSubControl( Point location , ControlRef superControl , ControlPartCode *outPart ) @@ -347,7 +376,7 @@ ControlRef wxMacFindSubControl( Point location , ControlRef superControl , Contr if ( IsControlVisible( sibling ) ) { Rect r ; - GetControlBounds( sibling , &r ) ; + UMAGetControlBoundsInWindowCoords( sibling , &r ) ; if ( MacPtInRect( location , &r ) ) { ControlHandle child = wxMacFindSubControl( location , sibling , outPart ) ; @@ -355,7 +384,12 @@ ControlRef wxMacFindSubControl( Point location , ControlRef superControl , Contr return child ; else { - *outPart = TestControl( sibling , location ) ; + Point testLocation = location ; +#if TARGET_API_MAC_OSX + testLocation.h -= r.left ; + testLocation.v -= r.top ; +#endif + *outPart = TestControl( sibling , testLocation ) ; return sibling ; } } @@ -368,12 +402,13 @@ ControlRef wxMacFindSubControl( Point location , ControlRef superControl , Contr ControlRef wxMacFindControlUnderMouse( Point location , WindowRef window , ControlPartCode *outPart ) { #if TARGET_API_MAC_OSX - return FindControlUnderMouse( location , window , outPart ) ; -#else + if ( UMAGetSystemVersion() >= 0x1030 ) + return FindControlUnderMouse( location , window , outPart ) ; +#endif ControlRef rootControl = NULL ; verify_noerr( GetRootControl( window , &rootControl ) ) ; return wxMacFindSubControl( location , rootControl , outPart ) ; -#endif + } pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { @@ -389,14 +424,10 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev short windowPart = ::FindWindow(screenMouseLocation, &window); wxWindow* currentMouseWindow = NULL ; + if ( window ) { - // calculate window relative coordinates - GrafPtr port; - ::GetPort( &port ) ; - ::SetPort( UMAGetWindowPort(window ) ) ; - ::GlobalToLocal( &windowMouseLocation ) ; - ::SetPort( port ) ; + QDGlobalToLocalPoint( UMAGetWindowPort(window ) , &windowMouseLocation ) ; if ( wxTheApp->s_captureWindow && wxTheApp->s_captureWindow->MacGetTopLevelWindowRef() == (WXWindow) window && windowPart == inContent ) { @@ -492,6 +523,26 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev #endif // wxUSE_TOOLTIPS if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) ) result = noErr; + else + { + ControlPartCode dummyPart ; + // if built-in find control is finding the wrong control (ie static box instead of overlaid + // button, we cannot let the standard handler do its job, but must handle manually + + if ( ( cEvent.GetKind() == kEventMouseDown ) && + (FindControlUnderMouse(windowMouseLocation , window , &dummyPart) != + wxMacFindControlUnderMouse( windowMouseLocation , window , &dummyPart ) ) ) + { + EventModifiers modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; + Point clickLocation = windowMouseLocation ; +#if TARGET_API_MAC_OSX + currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ; +#endif + HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation , + modifiers , (ControlActionUPP ) -1 ) ; + result = noErr ; + } + } if ( cEvent.GetKind() == kEventMouseUp && wxTheApp->s_captureWindow ) { wxTheApp->s_captureWindow = NULL ; @@ -578,18 +629,21 @@ static pascal OSStatus wxMacTopLevelWindowEventHandler( EventHandlerCallRef hand { UInt32 attributes = cEvent.GetParameter(kEventParamAttributes,typeUInt32) ; Rect newRect = cEvent.GetParameter(kEventParamCurrentBounds) ; - wxRect r( newRect.left , newRect.top , newRect.right - newRect.left , newRect.bottom - newRect.top ) ; 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( 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->GetEventHandler()->ProcessEvent(wxevent) ) - { adjustR = wxevent.GetRect() ; - } + if ( toplevelWindow->GetMaxWidth() != -1 && adjustR.GetWidth() > toplevelWindow->GetMaxWidth() ) adjustR.SetWidth( toplevelWindow->GetMaxWidth() ) ; if ( toplevelWindow->GetMaxHeight() != -1 && adjustR.GetHeight() > toplevelWindow->GetMaxHeight() ) @@ -598,9 +652,9 @@ static pascal OSStatus wxMacTopLevelWindowEventHandler( EventHandlerCallRef hand adjustR.SetWidth( toplevelWindow->GetMinWidth() ) ; if ( toplevelWindow->GetMinHeight() != -1 && adjustR.GetHeight() < toplevelWindow->GetMinHeight() ) adjustR.SetHeight( toplevelWindow->GetMinHeight() ) ; - Rect adjustedRect = { adjustR.y , adjustR.x , adjustR.y + adjustR.height , adjustR.x + adjustR.width } ; + const Rect adjustedRect = { adjustR.y + top , adjustR.x + left , adjustR.y + adjustR.height - bottom , adjustR.x + adjustR.width - right } ; if ( !EqualRect( &newRect , &adjustedRect ) ) - cEvent.SetParameter( kEventParamCurrentBounds , &adjustedRect ) ; + cEvent.SetParameter( kEventParamCurrentBounds , &adjustedRect ) ; } result = noErr ; @@ -764,25 +818,6 @@ void wxTopLevelWindowMac::Maximize(bool maximize) wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ; wxMacWindowClipper clip (this); ZoomWindow( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , false ) ; -/* - Rect r ; - GDHandle device = NULL ; - verify_noerr( GetWindowGreatestAreaDevice( (WindowRef) m_macWindow , kWindowContentRgn , - &device , NULL ) ; - verify_noerr( GetAvailableWindowPositioningBounds( GetMainDevice() , &r ) ) ; - - Rect tempRect ; - GrafPtr port ; - GetPort( &port ) ; - Point pt = { 0, 0 } ; - SetPortWindowPort((WindowRef)m_macWindow) ; - LocalToGlobal( &pt ) ; - SetPort( port ) ; - - GetWindowPortBounds((WindowRef)m_macWindow, &tempRect ) ; - SetSize( pt.h , pt.v , tempRect.right-tempRect.left , - tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING); -*/ } bool wxTopLevelWindowMac::IsMaximized() const @@ -955,18 +990,29 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, } wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") ); + + // 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 ) ; UMASetWTitle( (WindowRef) m_macWindow , title , m_font.GetEncoding() ) ; - if ( m_macUsesCompositing ) - { - ::GetRootControl( (WindowRef)m_macWindow, (ControlRef*)&m_macControl ) ; - } - else + m_peer = new wxMacControl() ; +#if TARGET_API_MAC_OSX + // 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 explicitely + HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID , + m_peer->GetControlRefAddr() ) ; + if ( !m_peer->Ok() ) { - ::CreateRootControl( (WindowRef)m_macWindow , (ControlRef*)&m_macControl ) ; + // compatibility mode fallback + GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ; } +#else + ::CreateRootControl( (WindowRef)m_macWindow , m_peer->GetControlRefAddr() ) ; +#endif // the root control level handleer - MacInstallEventHandler() ; + MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ; // the frame window event handler InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ; @@ -1072,6 +1118,19 @@ bool wxTopLevelWindowMac::Show(bool show) // we are still using coordinates of the content view, todo switch to structure bounds +void wxTopLevelWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) +{ + Rect content ; + Rect 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 wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height) { Rect bounds = { y , x , y + height , x + width } ; @@ -1180,8 +1239,7 @@ static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect) { GetWindowPortBounds(window, inRect); Point pt = {inRect->left, inRect->top}; - SetPort((GrafPtr) GetWindowPort(window)); - LocalToGlobal(&pt); + QDLocalToGlobalPoint( GetWindowPort(window) , &pt ) ; inRect->top = pt.v; inRect->left = pt.h; inRect->bottom += pt.v;