X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2e6857fac2a88987fff1c63c8885252f679ac6ce..5eac771d0949d4696c7c29f2ead81a2d0b0b73c8:/src/mac/carbon/toplevel.cpp diff --git a/src/mac/carbon/toplevel.cpp b/src/mac/carbon/toplevel.cpp index 8db3f7e902..b9acd02cc0 100644 --- a/src/mac/carbon/toplevel.cpp +++ b/src/mac/carbon/toplevel.cpp @@ -39,6 +39,7 @@ #include "wx/mac/uma.h" #include "wx/mac/aga.h" +#include "wx/app.h" #include "wx/tooltip.h" #include "wx/dnd.h" @@ -52,7 +53,11 @@ // ---------------------------------------------------------------------------- // list of all frames and modeless dialogs -wxWindowList wxModelessWindows; +wxWindowList wxModelessWindows; + +// double click testing +static Point gs_lastWhere; +static long gs_lastWhen = 0; // ============================================================================ // wxTopLevelWindowMac implementation @@ -70,7 +75,7 @@ wxTopLevelWindowMac *wxFindWinFromMacWindow(WXWindow inWindowRef) wxNode *node = wxWinMacWindowList->Find((long)inWindowRef); if (!node) return NULL; - return (wxTopLevelWindowMac *)node->Data(); + return (wxTopLevelWindowMac *)node->GetData(); } void wxAssociateWinWithMacWindow(WXWindow inWindowRef, wxTopLevelWindowMac *win) @@ -102,8 +107,24 @@ void wxTopLevelWindowMac::Init() m_macNoEraseUpdateRgn = NewRgn() ; m_macNeedsErasing = false ; m_macWindow = NULL ; + m_macEventHandler = NULL ; } +class wxMacDeferredWindowDeleter : public wxObject +{ +public : + wxMacDeferredWindowDeleter( WindowRef windowRef ) + { + m_macWindow = windowRef ; + } + virtual ~wxMacDeferredWindowDeleter() + { + UMADisposeWindow( (WindowRef) m_macWindow ) ; + } + protected : + WindowRef m_macWindow ; +} ; + bool wxTopLevelWindowMac::Create(wxWindow *parent, wxWindowID id, const wxString& title, @@ -134,26 +155,21 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac() if ( m_macWindow ) { wxToolTip::NotifyWindowDelete(m_macWindow) ; - UMADisposeWindow( (WindowRef) m_macWindow ) ; + wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ; } - + +#if TARGET_CARBON + if ( m_macEventHandler ) + { + ::RemoveEventHandler((EventHandlerRef) m_macEventHandler); + m_macEventHandler = NULL ; + } +#endif wxRemoveMacWindowAssociation( this ) ; - wxTopLevelWindows.DeleteObject(this); - if ( wxModelessWindows.Find(this) ) wxModelessWindows.DeleteObject(this); - // If this is the last top-level window, exit. - if ( wxTheApp && (wxTopLevelWindows.Number() == 0) ) - { - wxTheApp->SetTopWindow(NULL); - - if ( wxTheApp->GetExitOnFrameDelete() ) - { - wxTheApp->ExitMainLoop() ; - } - } DisposeRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ; } @@ -198,6 +214,59 @@ void wxTopLevelWindowMac::SetIcon(const wxIcon& icon) wxTopLevelWindowBase::SetIcon(icon); } +#if TARGET_CARBON + +EventHandlerUPP wxMacWindowEventHandlerUPP = NULL ; + +extern long wxMacTranslateKey(unsigned char key, unsigned char code) ; + +pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +{ + OSStatus result = eventNotHandledErr ; + EventRecord rec ; + switch ( GetEventClass( event ) ) + { + case kEventClassTextInput : + if ( wxMacConvertEventToRecord( event , &rec ) ) + { + wxTheApp->m_macCurrentEvent = &rec ; + wxWindow* focus = wxWindow::FindFocus() ; + if ( (focus != NULL) && !UMAMenuEvent(&rec) && wxTheApp->MacSendKeyDownEvent( focus , rec.message , rec.modifiers , rec.when , rec.where.h , rec.where.v ) ) + { + // was handled internally + result = noErr ; + } + } + break ; + default : + break ; + } + return result ; +} + +#endif + +void wxTopLevelWindowMac::MacInstallEventHandler() +{ +#if TARGET_CARBON + if ( wxMacWindowEventHandlerUPP == NULL ) + { + wxMacWindowEventHandlerUPP = NewEventHandlerUPP( wxMacWindowEventHandler ) ; + } + + static const EventTypeSpec eventList[] = + { + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } + } ; + if ( m_macEventHandler ) + { + ::RemoveEventHandler((EventHandlerRef) m_macEventHandler); + m_macEventHandler = NULL ; + } + InstallWindowEventHandler(MAC_WXHWND(m_macWindow), wxMacWindowEventHandlerUPP, WXSIZEOF(eventList), eventList, this, &((EventHandlerRef)m_macEventHandler)); +#endif +} + void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, const wxPoint& pos, const wxSize& size, @@ -233,12 +302,27 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, WindowClass wclass = 0; WindowAttributes attr = kWindowNoAttributes ; - if ( HasFlag( wxFRAME_TOOL_WINDOW) || HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT) ) + if ( HasFlag( wxFRAME_TOOL_WINDOW) ) { - wclass = kFloatingWindowClass ; - if ( HasFlag(wxTINY_CAPTION_VERT) ) + if ( + HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || + HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) || + HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT) + ) { - attr |= kWindowSideTitlebarAttribute ; + wclass = kFloatingWindowClass ; + if ( HasFlag(wxTINY_CAPTION_VERT) ) + { + attr |= kWindowSideTitlebarAttribute ; + } + } + else + { +#if TARGET_CARBON + wclass = kPlainWindowClass ; +#else + wclass = kFloatingWindowClass ; +#endif } } else if ( HasFlag( wxCAPTION ) ) @@ -254,7 +338,19 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, } else { - wclass = kModalWindowClass ; + if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) || + HasFlag( wxSYSTEM_MENU ) ) + { + wclass = kDocumentWindowClass ; + } + else + { +#if TARGET_CARBON + wclass = kPlainWindowClass ; +#else + wclass = kModalWindowClass ; +#endif + } } if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ) @@ -280,6 +376,7 @@ void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title, label = title ; UMASetWTitleC( (WindowRef)m_macWindow , label ) ; ::CreateRootControl( (WindowRef)m_macWindow , (ControlHandle*)&m_macRootControl ) ; + MacInstallEventHandler() ; m_macFocus = NULL ; } @@ -347,10 +444,6 @@ void wxTopLevelWindowMac::Lower() ::SendBehind( (WindowRef)m_macWindow , NULL ) ; } -Point lastWhere ; -long lastWhen = 0 ; -extern int wxBusyCursorCount ; - void wxTopLevelWindowMac::MacFireMouseEvent( WXEVENTREF evr ) { EventRecord *ev = (EventRecord*) evr ; @@ -397,22 +490,25 @@ void wxTopLevelWindowMac::MacFireMouseEvent( WXEVENTREF evr ) if ( ev->what == mouseDown ) { - if ( ev->when - lastWhen <= GetDblTime() ) + if ( ev->when - gs_lastWhen <= GetDblTime() ) { - if ( abs( localwhere.h - lastWhere.h ) < 3 || abs( localwhere.v - lastWhere.v ) < 3 ) + if ( abs( localwhere.h - gs_lastWhere.h ) < 3 && abs( localwhere.v - gs_lastWhere.v ) < 3 ) { + // This is not right if the second mouse down + // event occured in a differen window. We + // correct this in MacDispatchMouseEvent. if ( controlDown ) event.SetEventType(wxEVT_RIGHT_DCLICK ) ; else event.SetEventType(wxEVT_LEFT_DCLICK ) ; } - lastWhen = 0 ; + gs_lastWhen = 0 ; } else { - lastWhen = ev->when ; + gs_lastWhen = ev->when ; } - lastWhere = localwhere ; + gs_lastWhere = localwhere ; } event.m_x = localwhere.h; @@ -435,7 +531,7 @@ void wxTopLevelWindowMac::MacFireMouseEvent( WXEVENTREF evr ) if ( ev->what == mouseUp ) { wxTheApp->s_captureWindow = NULL ; - if ( wxBusyCursorCount == 0 ) + if ( !wxIsBusy() ) { m_cursor.MacInstall() ; } @@ -485,7 +581,13 @@ void wxTopLevelWindowMac::MacActivate( WXEVENTREF ev , bool inIsActivating ) UMAHighlightAndActivateWindow( (WindowRef)m_macWindow , inIsActivating ) ; - MacSuperEnabled( inIsActivating ) ; + // Early versions of MacOS X don't refresh backgrounds properly, + // so refresh the whole window on activation and deactivation. + long osVersion = UMAGetSystemVersion(); + if (osVersion >= 0x1000 && osVersion < 0x1020) + Refresh(TRUE); + else + MacSuperEnabled( inIsActivating ) ; } void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev ) @@ -512,8 +614,8 @@ bool wxTopLevelWindowMac::Show(bool show) return FALSE; if (show) - { - ::ShowWindow( (WindowRef)m_macWindow ) ; + { + ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowShowTransitionAction,nil); ::SelectWindow( (WindowRef)m_macWindow ) ; // no need to generate events here, they will get them triggered by macos // actually they should be , but apparently they are not @@ -524,7 +626,7 @@ bool wxTopLevelWindowMac::Show(bool show) } else { - ::HideWindow( (WindowRef)m_macWindow ) ; + ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowHideTransitionAction,nil); } if ( !show ) @@ -583,9 +685,13 @@ void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height) if ( doResize ) ::SizeWindow((WindowRef)m_macWindow, m_width, m_height , true); + + // the OS takes care of invalidating and erasing the new area so we only have to + // take care of refreshing for full repaints + + if ( doResize && !HasFlag(wxNO_FULL_REPAINT_ON_RESIZE) ) + Refresh() ; - // the OS takes care of invalidating and erasing the new area - // we have erased the old one if ( IsKindOf( CLASSINFO( wxFrame ) ) ) {