]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/toplevel.cpp
Applied [ 1059554 ] patch for [1028659] fixes a couple of bugs with menus
[wxWidgets.git] / src / mac / carbon / toplevel.cpp
index a459279ecc332ee2b3f7f4c4aad56a5c3326317c..d4f3e31c9712b8ece44f3b536cca021f038aa468 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "toplevel.h"
 #endif
 
@@ -159,8 +159,9 @@ static pascal OSStatus TextInputEventHandler( EventHandlerCallRef handler , Even
 static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
 {
     OSStatus result = eventNotHandledErr ;
-
-    wxWindow* focus = wxWindow::FindFocus() ;
+    // call DoFindFocus instead of FindFocus, because for Composite Windows(like WxGenericListCtrl)
+    // FindFocus does not return the actual focus window,but the enclosing window
+    wxWindow* focus = wxWindow::DoFindFocus();
     if ( focus == NULL )
         return result ;
         
@@ -211,8 +212,7 @@ static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , Event
 
                 event.m_x = point.h;
                 event.m_y = point.v;
-                event.m_timeStamp = when;
-                wxWindow* focus = wxWindow::FindFocus() ;
+                event.SetTimestamp(when);
                 event.SetEventObject(focus);
 
                 if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & controlKey )
@@ -505,22 +505,12 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
     } // if ( windowPart == inMenuBar )
     else if ( currentMouseWindow )
     {
+        wxWindow *currentMouseWindowParent = currentMouseWindow->GetParent();
+
         currentMouseWindow->ScreenToClient( &wxevent.m_x , &wxevent.m_y ) ;
         
         wxevent.SetEventObject( currentMouseWindow ) ;
 
-        // update cursor
-        
-        wxWindow* cursorTarget = currentMouseWindow ;
-        wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
-
-        while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
-        {
-            cursorTarget = cursorTarget->GetParent() ;
-            if ( cursorTarget )
-                cursorPoint += cursorTarget->GetPosition() ;
-        }
-
         // make tooltips current
         
     #if wxUSE_TOOLTIPS
@@ -530,7 +520,13 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
             wxToolTip::RelayEvent( currentMouseWindow , wxevent);
     #endif // wxUSE_TOOLTIPS                
         if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) )
+        {
+            if ((currentMouseWindowParent != NULL) && 
+                (currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
+                currentMouseWindow = NULL;
+                
             result = noErr;
+        }
         else
         {
             // if the user code did _not_ handle the event, then perform the
@@ -559,6 +555,10 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
     #endif
                     HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
                         modifiers , (ControlActionUPP ) -1 ) ;
+                        
+                    if ((currentMouseWindowParent != NULL) && 
+                        (currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
+                        currentMouseWindow = NULL;
                 }
                 result = noErr ;
             }
@@ -568,6 +568,19 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
             wxTheApp->s_captureWindow = NULL ;
             // update cursor ?
          }
+
+        // update cursor
+        
+        wxWindow* cursorTarget = currentMouseWindow ;
+        wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
+
+        while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
+        {
+            cursorTarget = cursorTarget->GetParent() ;
+            if ( cursorTarget )
+                cursorPoint += cursorTarget->GetPosition();
+        }
+
     } // else if ( currentMouseWindow )
     else
     {
@@ -741,6 +754,7 @@ DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTopLevelEventHandler )
 
 // Find an item given the Macintosh Window Reference
 
+#if KEY_wxList_DEPRECATED
 wxList wxWinMacWindowList(wxKEY_INTEGER);
 wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
 {
@@ -766,7 +780,43 @@ void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
 {
     wxWinMacWindowList.DeleteObject(win);
 }
+#else
+
+WX_DECLARE_HASH_MAP(WindowRef, wxTopLevelWindowMac*, wxPointerHash, wxPointerEqual, MacWindowMap);
 
+static MacWindowMap wxWinMacWindowList;
+
+wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
+{
+    MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef);
+
+    return (node == wxWinMacWindowList.end()) ? NULL : node->second;
+}
+
+void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win) ;
+void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win)
+{
+    // adding NULL WindowRef is (first) surely a result of an error and
+    // nothing else :-)
+    wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
+
+    wxWinMacWindowList[inWindowRef] = win;
+}
+
+void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win) ;
+void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
+{
+    MacWindowMap::iterator it;
+    for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it )
+    {
+        if ( it->second == win )
+        {
+            wxWinMacWindowList.erase(it);
+            break;
+        }
+    }
+}
+#endif // deprecated wxList
 
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowMac creation
@@ -966,6 +1016,7 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
 
     WindowClass wclass = 0;
     WindowAttributes attr = kWindowNoAttributes ;
+    WindowGroupRef group = NULL ;
 
     if ( HasFlag( wxFRAME_TOOL_WINDOW) )
     {
@@ -1036,8 +1087,10 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
         attr |= kWindowLiveResizeAttribute;
     }
 
-    if (HasFlag(wxSTAY_ON_TOP))
-        wclass = kUtilityWindowClass;
+    if ( HasFlag(wxSTAY_ON_TOP) )
+    {
+        group = GetWindowGroupOfClass(kUtilityWindowClass) ;
+    }
 
 #if TARGET_API_MAC_OSX 
     attr |= kWindowCompositingAttribute;
@@ -1058,6 +1111,9 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
         err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
     }
 
+    if ( err == noErr && m_macWindow != NULL && group != NULL )
+        SetWindowGroup( (WindowRef) m_macWindow , group ) ;
+
     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
@@ -1329,6 +1385,31 @@ wxUint32 wxTopLevelWindowMac::MacGetWindowAttributes() const
     return attr ;
 }
 
+// Attracts the users attention to this window if the application is
+// inactive (should be called when a background event occurs)
+
+static pascal void wxMacNMResponse( NMRecPtr ptr )
+{
+    NMRemove( ptr ) ;
+    DisposePtr( (Ptr) ptr ) ;
+}
+
+
+void wxTopLevelWindowMac::RequestUserAttention(int flags )
+{
+    NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ;
+    static wxMacNMUPP nmupp( wxMacNMResponse )
+     ;
+    memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ;
+    notificationRequest->qType = nmType ;
+    notificationRequest->nmMark = 1 ;
+    notificationRequest->nmIcon = 0 ;
+    notificationRequest->nmSound = 0 ;
+    notificationRequest->nmStr = NULL ;
+    notificationRequest->nmResp = nmupp ;
+    verify_noerr( NMInstall( notificationRequest ) ) ;
+}
+
 // ---------------------------------------------------------------------------
 // Shape implementation
 // ---------------------------------------------------------------------------