X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50f3c41d61bd9ae69f215bad923f562d509e063c..9b7835a516d1acdeb007bed0c5bb80cae1643416:/src/mac/carbon/toplevel.cpp?ds=sidebyside diff --git a/src/mac/carbon/toplevel.cpp b/src/mac/carbon/toplevel.cpp index 5d77fdc673..b0930420a0 100644 --- a/src/mac/carbon/toplevel.cpp +++ b/src/mac/carbon/toplevel.cpp @@ -81,8 +81,6 @@ END_EVENT_TABLE() // Carbon Events // --------------------------------------------------------------------------- -extern long wxMacTranslateKey(unsigned char key, unsigned char code) ; - static const EventTypeSpec eventList[] = { // TODO: remove control related event like key and mouse (except for WindowLeave events) @@ -132,7 +130,7 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; #if wxUSE_UNICODE - UInt32 dataSize = 0 ; + ByteCount dataSize = 0 ; if ( GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr ) { UniChar buf[2] ; @@ -250,9 +248,10 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event wxWindow* g_MacLastWindow = NULL ; -static EventMouseButton lastButton = 0 ; +EventMouseButton g_lastButton = 0 ; +bool g_lastButtonWasFakeRight = false ; -static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) +void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) { UInt32 modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; Point screenMouseLocation = cEvent.GetParameter(kEventParamMouseLocation) ; @@ -271,24 +270,33 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) wxevent.m_metaDown = modifiers & cmdKey; wxevent.SetTimestamp( cEvent.GetTicks() ) ; - // a control click is interpreted as a right click + // a control click is interpreted as a right click + bool thisButtonIsFakeRight = false ; if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) ) + { button = kEventMouseButtonSecondary ; - + thisButtonIsFakeRight = true ; + } // otherwise we report double clicks by connecting a left click with a ctrl-left click - if ( clickCount > 1 && button != lastButton ) + if ( clickCount > 1 && button != g_lastButton ) clickCount = 1 ; // 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 ; + { + g_lastButton = button ; + g_lastButtonWasFakeRight = thisButtonIsFakeRight ; + } if ( button == 0 ) - lastButton = 0 ; - else if ( lastButton ) - button = lastButton ; + { + g_lastButton = 0 ; + g_lastButtonWasFakeRight = false ; + } + else if ( g_lastButton == kEventMouseButtonSecondary && g_lastButtonWasFakeRight ) + button = g_lastButton ; // determine the correct down state, wx does not want a 'down' for a mouseUp event, // while mac delivers this button @@ -360,12 +368,14 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ) { wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ; - // EventMouseWheelAxis axis = cEvent.GetParameter(kEventParamMouseWheelAxis, typeMouseWheelAxis) ; - SInt32 delta = cEvent.GetParameter(kEventParamMouseWheelDelta, typeLongInteger) ; + EventMouseWheelAxis axis = cEvent.GetParameter(kEventParamMouseWheelAxis, typeMouseWheelAxis) ; + SInt32 delta = cEvent.GetParameter(kEventParamMouseWheelDelta, typeSInt32) ; wxevent.m_wheelRotation = delta; wxevent.m_wheelDelta = 1; wxevent.m_linesPerAction = 1; + if ( axis == kEventMouseWheelAxisX ) + wxevent.m_wheelAxis = 1; } break ; @@ -409,7 +419,7 @@ ControlRef wxMacFindSubControl( wxTopLevelWindowMac* toplevelWindow, const Point { Point testLocation = location ; - if ( toplevelWindow && toplevelWindow->MacUsesCompositing() ) + if ( toplevelWindow ) { testLocation.h -= r.left ; testLocation.v -= r.top ; @@ -430,7 +440,7 @@ ControlRef wxMacFindSubControl( wxTopLevelWindowMac* toplevelWindow, const Point ControlRef wxMacFindControlUnderMouse( wxTopLevelWindowMac* toplevelWindow , const Point& location , WindowRef window , ControlPartCode *outPart ) { #if TARGET_API_MAC_OSX - if ( UMAGetSystemVersion() >= 0x1030 && ( toplevelWindow == 0 || toplevelWindow->MacUsesCompositing() ) ) + if ( UMAGetSystemVersion() >= 0x1030 ) return FindControlUnderMouse( location , window , outPart ) ; #endif @@ -469,7 +479,7 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev if ( window ) { - QDGlobalToLocalPoint( UMAGetWindowPort(window ) , &windowMouseLocation ) ; + wxMacGlobalToLocal( window, &windowMouseLocation ) ; if ( wxApp::s_captureWindow #if !NEW_CAPTURE_HANDLING @@ -591,7 +601,7 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev if ( wxevent.GetEventType() == wxEVT_LEFT_DOWN ) { // ... that is set focus to this window - if (currentMouseWindow->AcceptsFocus() && wxWindow::FindFocus()!=currentMouseWindow) + if (currentMouseWindow->CanAcceptFocus() && wxWindow::FindFocus()!=currentMouseWindow) currentMouseWindow->SetFocus(); } @@ -612,8 +622,7 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev EventModifiers modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; Point clickLocation = windowMouseLocation ; - if ( toplevelWindow->MacUsesCompositing() ) - currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ; + currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ; HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation , modifiers , (ControlActionUPP ) -1 ) ; @@ -658,15 +667,12 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev EventModifiers modifiers = cEvent.GetParameter(kEventParamKeyModifiers, typeUInt32) ; Point clickLocation = windowMouseLocation ; #if TARGET_API_MAC_OSX - if ( toplevelWindow->MacUsesCompositing() ) - { - 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 ; - } + 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 // TARGET_API_MAC_OSX HandleControlClick( control , clickLocation , modifiers , (ControlActionUPP ) -1 ) ; @@ -888,8 +894,7 @@ typedef struct wxPoint m_position ; wxSize m_size ; bool m_wasResizable ; -} -FullScreenData ; +} FullScreenData ; void wxTopLevelWindowMac::Init() { @@ -897,12 +902,6 @@ void wxTopLevelWindowMac::Init() m_maximizeOnShow = false; m_macWindow = NULL ; -#if TARGET_API_MAC_OSX - m_macUsesCompositing = ( UMAGetSystemVersion() >= 0x1030 ); -#else - m_macUsesCompositing = false; -#endif - m_macEventHandler = NULL ; m_macFullScreenData = NULL ; } @@ -942,7 +941,7 @@ bool wxTopLevelWindowMac::Create(wxWindow *parent, m_windowId = id == -1 ? NewControlId() : id; wxWindow::SetLabel( title ) ; - MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ; + MacCreateRealWindow( title, pos , size , style , name ) ; SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); @@ -981,6 +980,10 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac() FullScreenData *data = (FullScreenData *) m_macFullScreenData ; delete data ; m_macFullScreenData = NULL ; + + // avoid dangling refs + if ( s_macDeactivateWindow == this ) + s_macDeactivateWindow = NULL; } @@ -990,32 +993,23 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac() void wxTopLevelWindowMac::Maximize(bool maximize) { - // TODO: check if this is still necessary -#if 0 - wxMacPortStateHelper help( (GrafPtr)GetWindowPort( (WindowRef)m_macWindow) ) ; - wxMacWindowClipper clip( this ); -#endif -#if 0 - if ( !IsWindowInStandardState( (WindowRef)m_macWindow, NULL, NULL ) ) - { - Rect rect; - - GetWindowBounds((WindowRef)m_macWindow, kWindowGlobalPortRgn, &rect); - SetWindowIdealUserState((WindowRef)m_macWindow, &rect); - SetWindowUserState((WindowRef)m_macWindow, &rect); - } - ZoomWindow( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , false ) ; -#else Point idealSize = { 0 , 0 } ; if ( maximize ) { +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + HIRect bounds ; + HIWindowGetAvailablePositioningBounds(kCGNullDirectDisplay,kHICoordSpace72DPIGlobal, + &bounds); + idealSize.h = bounds.size.width; + idealSize.v = bounds.size.height; +#else Rect rect ; GetAvailableWindowPositioningBounds(GetMainDevice(),&rect) ; idealSize.h = rect.right - rect.left ; idealSize.v = rect.bottom - rect.top ; +#endif } ZoomWindowIdeal( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , &idealSize ) ; -#endif } bool wxTopLevelWindowMac::IsMaximized() const @@ -1051,12 +1045,6 @@ wxPoint wxTopLevelWindowMac::GetClientAreaOrigin() const return wxPoint(0, 0) ; } -void wxTopLevelWindowMac::SetIcon(const wxIcon& icon) -{ - // this sets m_icon - wxTopLevelWindowBase::SetIcon(icon); -} - void wxTopLevelWindowMac::MacSetBackgroundBrush( const wxBrush &brush ) { wxTopLevelWindowBase::MacSetBackgroundBrush( brush ) ; @@ -1132,6 +1120,20 @@ void wxTopLevelWindowMac::MacCreateRealWindow( wclass = kPlainWindowClass ; } } + else if ( HasFlag( wxPOPUP_WINDOW ) ) + { + // TEMPORARY HACK! + // Until we've got a real wxPopupWindow class on wxMac make it a + // little easier for wxFrame to be used to emulate it and workaround + // the lack of wxPopupWindow. + if ( HasFlag( wxBORDER_NONE ) ) + wclass = kHelpWindowClass ; // has no border + else + wclass = kPlainWindowClass ; // has a single line border, it will have to do for now + //attr |= kWindowNoShadowAttribute; // turn off the shadow Should we?? + group = GetWindowGroupOfClass( // float above other windows + kFloatingWindowClass) ; + } else if ( HasFlag( wxCAPTION ) ) { wclass = kDocumentWindowClass ; @@ -1141,8 +1143,6 @@ void wxTopLevelWindowMac::MacCreateRealWindow( else if ( HasFlag( wxFRAME_DRAWER ) ) { wclass = kDrawerWindowClass; - // we must force compositing on a drawer - m_macUsesCompositing = true ; } #endif //10.2 and up else @@ -1180,17 +1180,24 @@ void wxTopLevelWindowMac::MacCreateRealWindow( if ( HasFlag(wxSTAY_ON_TOP) ) group = GetWindowGroupOfClass(kUtilityWindowClass) ; -#if TARGET_API_MAC_OSX - if ( m_macUsesCompositing ) - attr |= kWindowCompositingAttribute; + if ( HasFlag( wxFRAME_FLOAT_ON_PARENT ) ) + group = GetWindowGroupOfClass(kFloatingWindowClass) ; + + attr |= kWindowCompositingAttribute; +#if 0 // wxMAC_USE_CORE_GRAPHICS ; TODO : decide on overall handling of high dpi screens (pixel vs userscale) + attr |= kWindowFrameworkScaledAttribute; #endif if ( HasFlag(wxFRAME_SHAPED) ) { WindowDefSpec customWindowDefSpec; customWindowDefSpec.defType = kWindowDefProcPtr; - customWindowDefSpec.u.defProc = NewWindowDefUPP(wxShapedMacWindowDef); - + customWindowDefSpec.u.defProc = +#ifdef __LP64__ + (WindowDefUPP) wxShapedMacWindowDef; +#else + NewWindowDefUPP(wxShapedMacWindowDef); +#endif err = ::CreateCustomWindow( &customWindowDefSpec, wclass, attr, &theBoundsRect, (WindowRef*) &m_macWindow); @@ -1205,6 +1212,11 @@ void wxTopLevelWindowMac::MacCreateRealWindow( wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") ); + // setup a separate group for each window, so that overlays can be handled easily + verify_noerr( CreateWindowGroup( kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrHideOnCollapse, &group )); + verify_noerr( SetWindowGroupParent( group, GetWindowGroup( (WindowRef) m_macWindow ))); + verify_noerr( SetWindowGroup( (WindowRef) m_macWindow , group )); + // 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 ) ; @@ -1213,22 +1225,14 @@ void wxTopLevelWindowMac::MacCreateRealWindow( UMASetWTitle( (WindowRef) m_macWindow , title , m_font.GetEncoding() ) ; m_peer = new wxMacControl(this , true /*isRootControl*/) ; -#if TARGET_API_MAC_OSX - if ( m_macUsesCompositing ) + // 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 explicitly + HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID , + m_peer->GetControlRefAddr() ) ; + if ( !m_peer->Ok() ) { - // 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 explicitly - HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID , - m_peer->GetControlRefAddr() ) ; - if ( !m_peer->Ok() ) - { - // compatibility mode fallback - GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ; - } - } -#endif - { - ::CreateRootControl( (WindowRef)m_macWindow , m_peer->GetControlRefAddr() ) ; + // compatibility mode fallback + GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ; } // the root control level handler @@ -1432,15 +1436,14 @@ bool wxTopLevelWindowMac::IsFullScreen() const } -bool wxTopLevelWindowMac::SetTranslucency(int alpha) +bool wxTopLevelWindowMac::SetTransparent(wxByte alpha) { - WindowRef handle = GetControlOwner((OpaqueControlRef*)GetHandle()); - OSStatus result = SetWindowAlpha(handle, float(alpha)/255.0); + OSStatus result = SetWindowAlpha((WindowRef)m_macWindow, float(alpha)/255.0); return result == noErr; } -bool wxTopLevelWindowMac::CanSetTranslucency() +bool wxTopLevelWindowMac::CanSetTransparent() { return true; } @@ -1454,7 +1457,7 @@ void wxTopLevelWindowMac::SetExtraStyle(long exStyle) wxTopLevelWindowBase::SetExtraStyle( exStyle ) ; #if TARGET_API_MAC_OSX - if ( m_macUsesCompositing && m_macWindow != NULL ) + if ( m_macWindow != NULL ) { bool metal = GetExtraStyle() & wxFRAME_EX_METAL ; if ( MacGetMetalAppearance() != metal ) @@ -1526,9 +1529,6 @@ void wxTopLevelWindowMac::DoGetClientSize( int *width, int *height ) const void wxTopLevelWindowMac::MacSetMetalAppearance( bool set ) { #if TARGET_API_MAC_OSX - wxASSERT_MSG( m_macUsesCompositing , - wxT("Cannot set metal appearance on a non-compositing window") ) ; - MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes , set ? kWindowNoAttributes : kWindowMetalAttribute ) ; #endif @@ -1558,57 +1558,31 @@ wxUint32 wxTopLevelWindowMac::MacGetWindowAttributes() const 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 ) ; - } - } - } + // for composited windows this also triggers a redraw of all + // invalid views in the window + if ( UMAGetSystemVersion() >= 0x1030 ) + HIWindowFlush((WindowRef) m_macWindow) ; else #endif { - BeginUpdate( (WindowRef) m_macWindow ) ; + // the only way to trigger the redrawing on earlier systems is to call + // ReceiveNextEvent - RgnHandle updateRgn = NewRgn(); - if ( updateRgn ) + EventRef currentEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ; + UInt32 currentEventClass = 0 ; + if ( currentEvent != NULL ) { - GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn ); - UpdateControls( (WindowRef)m_macWindow , updateRgn ) ; - - // if ( !EmptyRgn( updateRgn ) ) - // MacDoRedraw( updateRgn , 0 , true) ; - - DisposeRgn( updateRgn ); + currentEventClass = ::GetEventClass( currentEvent ) ; + ::GetEventKind( currentEvent ) ; } - EndUpdate( (WindowRef)m_macWindow ) ; - QDFlushPortBuffer( GetWindowPort( (WindowRef)m_macWindow ) , NULL ) ; + if ( currentEventClass != kEventClassMenu ) + { + // when tracking a menu, strange redraw errors occur if we flush now, so leave.. + EventRef theEvent; + ReceiveNextEvent( 0 , NULL , kEventDurationNoWait , false , &theEvent ) ; + } } } @@ -1669,7 +1643,7 @@ bool wxTopLevelWindowMac::SetShape(const wxRegion& region) DisposeRgn(oldRgn); // Save the region so we can use it later - SetWRefCon((WindowRef)MacGetWindowRef(), (SInt32)shapeRegion); + SetWRefCon((WindowRef)MacGetWindowRef(), (URefCon)shapeRegion); // inform the window manager that the window has changed shape ReshapeCustomWindow((WindowRef)MacGetWindowRef()); @@ -1685,13 +1659,12 @@ bool wxTopLevelWindowMac::SetShape(const wxRegion& region) static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect) { GetWindowPortBounds(window, inRect); - Point pt = { inRect->left, inRect->top }; - - QDLocalToGlobalPoint( GetWindowPort(window), &pt ) ; + Point pt = { inRect->top ,inRect->left }; + wxMacLocalToGlobal( window, &pt ) ; + inRect->bottom += pt.v - inRect->top; + inRect->right += pt.h - inRect->left; inRect->top = pt.v; inRect->left = pt.h; - inRect->bottom += pt.v; - inRect->right += pt.h; } static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param)