X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f83b67612b28807e9628c66a25b47f92bb95c4b3..9a35701127e3e8d2c7fb433d85c7b3954ccbfc9f:/src/mac/carbon/toplevel.cpp diff --git a/src/mac/carbon/toplevel.cpp b/src/mac/carbon/toplevel.cpp index 64d7065dd5..d41ae760f0 100644 --- a/src/mac/carbon/toplevel.cpp +++ b/src/mac/carbon/toplevel.cpp @@ -49,6 +49,9 @@ #include +//For targeting OSX +#include "wx/mac/private.h" + // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- @@ -252,6 +255,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) ; @@ -275,6 +280,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 @@ -293,29 +309,39 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) break ; } } - // determinate the correct click button - if ( button == kEventMouseButtonSecondary ) + // translate into wx types + switch ( cEvent.GetKind() ) { - if (cEvent.GetKind() == kEventMouseDown ) - wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ; - else if ( cEvent.GetKind() == kEventMouseUp ) - wxevent.SetEventType(wxEVT_RIGHT_UP ) ; - } - else if ( button == kEventMouseButtonTertiary ) - { - 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) ; @@ -324,10 +350,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 ) @@ -351,7 +379,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 ) ; @@ -359,7 +387,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 ; } } @@ -372,7 +405,7 @@ ControlRef wxMacFindSubControl( Point location , ControlRef superControl , Contr ControlRef wxMacFindControlUnderMouse( Point location , WindowRef window , ControlPartCode *outPart ) { #if TARGET_API_MAC_OSX - if ( UMAGetSystemVersion() >= 1030 ) + if ( UMAGetSystemVersion() >= 0x1030 ) return FindControlUnderMouse( location , window , outPart ) ; #endif ControlRef rootControl = NULL ; @@ -394,14 +427,11 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev short windowPart = ::FindWindow(screenMouseLocation, &window); wxWindow* currentMouseWindow = NULL ; + ControlRef control = 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 ) { @@ -410,14 +440,27 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev else if ( (IsWindowActive(window) && windowPart == inContent) ) { ControlPartCode part ; - ControlRef control = wxMacFindControlUnderMouse( windowMouseLocation , window , &part ) ; + control = wxMacFindControlUnderMouse( windowMouseLocation , window , &part ) ; + // if there is no control below the mouse position, send the event to the toplevel window itself if ( control == 0 ) currentMouseWindow = (wxWindow*) data ; else + { currentMouseWindow = wxFindControlFromMacControl( control ) ; + if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved ) + { + // for wxToolBar to function we have to send certaint events to it + // instead of its children (wxToolBarTools) + ControlRef parent ; + GetSuperControl(control, &parent ); + wxWindow *wxParent = wxFindControlFromMacControl( parent ) ; + if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) ) + currentMouseWindow = wxParent ; + } + } } } - + wxMouseEvent wxevent(wxEVT_LEFT_DOWN); SetupMouseEvent( wxevent , cEvent ) ; @@ -507,9 +550,16 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev (FindControlUnderMouse(windowMouseLocation , window , &dummyPart) != wxMacFindControlUnderMouse( windowMouseLocation , window , &dummyPart ) ) ) { - EventModifiers modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; - HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , windowMouseLocation , - modifiers , (ControlActionUPP ) -1 ) ; + if ( currentMouseWindow->MacIsReallyEnabled() ) + { + 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 ; } } @@ -519,6 +569,29 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev // update cursor ? } } // else if ( currentMouseWindow ) + else + { + // don't mess with controls we don't know about + // for some reason returning eventNotHandledErr does not lead to the correct behaviour + // so we try sending them the correct control directly + wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ; + if ( cEvent.GetKind() == kEventMouseDown && toplevelWindow && control ) + { + EventModifiers modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; + Point clickLocation = windowMouseLocation ; +#if TARGET_API_MAC_OSX + HIPoint hiPoint ; + hiPoint.x = clickLocation.h ; + hiPoint.y = clickLocation.v ; + HIViewConvertPoint( &hiPoint , (ControlRef) toplevelWindow->GetHandle() , control ) ; + clickLocation.h = (int)hiPoint.x ; + clickLocation.v = (int)hiPoint.y ; +#endif + HandleControlClick( control , clickLocation , + modifiers , (ControlActionUPP ) -1 ) ; + result = noErr ; + } + } return result ; } @@ -622,9 +695,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 + top , adjustR.x + left , adjustR.y + adjustR.height - bottom , adjustR.x + adjustR.width - right } ; + 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 ; @@ -701,6 +774,12 @@ void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win) wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL; +typedef struct +{ + wxPoint m_position ; + wxSize m_size ; +} FullScreenData ; + void wxTopLevelWindowMac::Init() { m_iconized = @@ -712,6 +791,7 @@ void wxTopLevelWindowMac::Init() m_macUsesCompositing = FALSE; #endif m_macEventHandler = NULL ; + m_macFullScreenData = NULL ; } class wxMacDeferredWindowDeleter : public wxObject @@ -745,6 +825,7 @@ bool wxTopLevelWindowMac::Create(wxWindow *parent, SetName(name); m_windowId = id == -1 ? NewControlId() : id; + wxWindow::SetTitle( title ) ; MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ; @@ -776,6 +857,10 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac() if ( wxModelessWindows.Find(this) ) wxModelessWindows.DeleteObject(this); + + FullScreenData *data = (FullScreenData *) m_macFullScreenData ; + delete data ; + m_macFullScreenData = NULL ; } @@ -788,25 +873,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 @@ -920,6 +986,16 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, { wclass = kDocumentWindowClass ; } +#if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 ) + else if ( HasFlag( wxFRAME_DRAWER ) ) + { + wclass = kDrawerWindowClass; + // Should this be left for compositing check below? + // CreateNewWindow will fail without it, should wxDrawerWindow turn + // on compositing before calling MacCreateRealWindow? + attr |= kWindowCompositingAttribute;// | kWindowStandardHandlerAttribute; + } +#endif //10.2 and up else { if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || @@ -986,16 +1062,22 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, 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)) ) ; @@ -1099,6 +1181,72 @@ bool wxTopLevelWindowMac::Show(bool show) return TRUE ; } +bool wxTopLevelWindowMac::ShowFullScreen(bool show, long style) +{ + if ( show ) + { + FullScreenData *data = (FullScreenData *)m_macFullScreenData ; + delete data ; + data = new FullScreenData() ; + + m_macFullScreenData = data ; + data->m_position = GetPosition() ; + data->m_size = GetSize() ; + + if ( style & wxFULLSCREEN_NOMENUBAR ) + { + HideMenuBar() ; + } + int left , top , right , bottom ; + wxRect client = wxGetClientDisplayRect() ; + + int x, y, w, h ; + + x = client.x ; + y = client.y ; + w = client.width ; + h = client.height ; + + MacGetContentAreaInset( left , top , right , bottom ) ; + + if ( style & wxFULLSCREEN_NOCAPTION ) + { + y -= top ; + h += top ; + } + if ( style & wxFULLSCREEN_NOBORDER ) + { + x -= left ; + w += left + right ; + h += bottom ; + } + if ( style & wxFULLSCREEN_NOTOOLBAR ) + { + // TODO + } + if ( style & wxFULLSCREEN_NOSTATUSBAR ) + { + // TODO + } + SetSize( x , y , w, h ) ; + } + else + { + ShowMenuBar() ; + FullScreenData *data = (FullScreenData *) m_macFullScreenData ; + SetPosition( data->m_position ) ; + SetSize( data->m_size ) ; + delete data ; + m_macFullScreenData = NULL ; + } + return FALSE; +} + +bool wxTopLevelWindowMac::IsFullScreen() const +{ + return m_macFullScreenData != NULL ; +} + // 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 ) @@ -1222,8 +1370,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; @@ -1246,7 +1393,7 @@ static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param) kWindowCanDrawInCurrentPort| //kWindowCanMeasureTitle| kWindowWantsDisposeAtProcessDeath| - kWindowSupportsSetGrowImageRegion| + kWindowSupportsGetGrowImageRegion| kWindowDefSupportsColorGrafPort; return 1; }