]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/menu.cpp
containers don't always accept focus (patch 718913)
[wxWidgets.git] / src / gtk1 / menu.cpp
index dc12c62e984ac2fc13107a131765043ad70174fe..16a8f31d6ce319b39ace415a8dcf5e2f7a7d5a92 100644 (file)
@@ -701,36 +701,53 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
     if (!menu->IsEnabled(id))
         return;
 
-    if ( menu->IsAttached() ) // is this menu on a menubar?
-    {
-        wxFrame* frame = menu->GetMenuBar()->GetFrame();
-        frame->ProcessCommand(id);
-    }
-    else
+    wxMenuItem* item = menu->FindChildItem( id );
+    wxCHECK_RET( item, wxT("error in menu item callback") );
+
+    if (item->IsCheckable())
     {
-        wxMenuItem* item = menu->FindChildItem( id );
-        wxCHECK_RET( item, wxT("error in menu item callback") );
+        bool isReallyChecked = item->IsChecked(),
+            isInternallyChecked = item->wxMenuItemBase::IsChecked();
 
-        if (item->IsCheckable())
+        // ensure that the internal state is always consistent with what is
+        // shown on the screen
+        item->wxMenuItemBase::Check(isReallyChecked);
+
+        // we must not report the events for the radio button going up nor the
+        // events resulting from the calls to wxMenuItem::Check()
+        if ( (item->GetKind() == wxITEM_RADIO && !isReallyChecked) ||
+             (isInternallyChecked == isReallyChecked) )
         {
-            bool isReallyChecked = item->IsChecked(),
-                isInternallyChecked = item->wxMenuItemBase::IsChecked();
+            return;
+        }
+    }
 
-            // ensure that the internal state is always consistent with what is
-            // shown on the screen
-            item->wxMenuItemBase::Check(isReallyChecked);
 
-            // we must not report the events for the radio button going up nor the
-            // events resulting from the calls to wxMenuItem::Check()
-            if ( (item->GetKind() == wxITEM_RADIO && !isReallyChecked) ||
-                 (isInternallyChecked == isReallyChecked) )
-            {
-                return;
-            }
+    // Is this menu on a menubar?  (possibly nested)
+    wxFrame* frame = NULL;
+    wxMenu*  pm = menu;
+    while ( pm && !frame )
+    {
+        if ( pm->IsAttached() )
+            frame = pm->GetMenuBar()->GetFrame();
+        pm = pm->GetParent();
+    }
 
-            // the user pressed on the menu item: report the event below
-        }
+    if (frame)
+    {
+        // If it is attached then let the frame send the event.
+        // Don't call frame->ProcessCommand(id) because it toggles
+        // checkable items and we've already done that above.
+        wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
+        commandEvent.SetEventObject(frame);
+        if (item->IsCheckable())
+            commandEvent.SetInt(item->IsChecked());
 
+        frame->GetEventHandler()->ProcessEvent(commandEvent);
+    }
+    else
+    {
+        // otherwise let the menu have it
         menu->SendEvent(id, item->IsCheckable() ? item->IsChecked() : -1);
     }
 }