diff --git a/docs/changes.txt b/docs/changes.txt index 916824f6d7..2dec057820 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -654,6 +654,7 @@ All (GUI): - Add wxTextEntryDialog::SetMaxLength() (derEine). - Fix maximum width support in wxGridCellTextEditor (derEine). - Add more convenient wxFont(wxFontInfo) ctor. +- Pass menu events to the handler in the associated wxMenuBar. wxGTK: diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index 55daa81c38..7230bb103d 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -643,7 +643,8 @@ bool wxMenuBase::SendEvent(int itemid, int checked) event.SetEventObject(this); event.SetInt(checked); - wxWindow * const win = GetWindow(); + wxWindow* const win = GetWindow(); + wxMenuBar* const mb = GetMenuBar(); // Try the menu's event handler first wxEvtHandler *handler = GetEventHandler(); @@ -653,16 +654,21 @@ bool wxMenuBase::SendEvent(int itemid, int checked) // event to another handler if it's not processed here to prevent it // from passing the event to wxTheApp: this will be done below if we do // have the associated window. - if ( win ) + if ( win || mb ) event.SetWillBeProcessedAgain(); if ( handler->SafelyProcessEvent(event) ) return true; } - // Try the window the menu was popped up from or its menu bar belongs to - if ( win && win->HandleWindowEvent(event) ) - return true; + // If this menu is part of the menu bar, process the event there: this will + // also propagate it upwards to the window containing the menu bar. + if ( mb ) + return mb->HandleWindowEvent(event); + + // Try the window the menu was popped up from. + if ( win ) + return win->HandleWindowEvent(event); // Not processed. return false; diff --git a/tests/events/propagation.cpp b/tests/events/propagation.cpp index d0d2230dda..14457f7464 100644 --- a/tests/events/propagation.cpp +++ b/tests/events/propagation.cpp @@ -400,10 +400,18 @@ void EventPropagationTestCase::MenuEvent() CheckMenuEvent( menu, "aomA" ); + // Test that the event handler associated with the menu bar gets the event. + TestMenuEvtHandler hb('b'); // 'b' for "menu Bar" + mb->PushEventHandler(&hb); + wxON_BLOCK_EXIT_OBJ1( *mb, wxWindow::PopEventHandler, false ); + + CheckMenuEvent( menu, "aomobA" ); + + // Also test that the window to which the menu belongs gets the event. TestMenuEvtHandler hw('w'); // 'w' for "Window" frame->PushEventHandler(&hw); wxON_BLOCK_EXIT_OBJ1( *frame, wxWindow::PopEventHandler, false ); - CheckMenuEvent( menu, "aomowA" ); + CheckMenuEvent( menu, "aomobowA" ); }