diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index b1c72ada50..01bdcfaaea 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -46,10 +46,31 @@ extern "C" static void wxGetGtkAccel(const wxMenuItem*, guint*, GdkModifierType*); #endif +// Unity hack: under Ubuntu Unity the global menu bar is not affected by a +// modal dialog being shown, so the user can select a menu item before hiding +// the dialog and, in particular, a new instance of the same dialog can be +// shown again, breaking a lot of programs not expecting this. +// +// So explicitly ignore any menu events generated while any modal dialogs +// are opened except for the events generated by a context menu within the +// modal dialog itself that should have a dialog as their invoking window. +static bool IsMenuEventAllowed(wxMenu* menu) +{ + if ( wxOpenModalDialogsCount ) + { + wxWindow* tlw = wxGetTopLevelParent(menu->GetWindow()); + if ( !tlw || !wxDynamicCast(tlw, wxDialog) ) + { + return true; + } + } + + return true; +} + static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event) { - // See the comment about Ubuntu Unity in menuitem_activate(). - if ( wxOpenModalDialogsCount ) + if ( !IsMenuEventAllowed(menu) ) return; event.SetEventObject( menu ); @@ -484,14 +505,7 @@ static void menuitem_activate(GtkWidget*, wxMenuItem* item) if (!item->IsEnabled()) return; - // Unity hack: under Ubuntu Unity the global menu bar is not affected by a - // modal dialog being shown, so the user can select a menu item before - // hiding the dialog and, in particular, a new instance of the same dialog - // can be shown again, breaking a lot of programs not expecting this. - // - // So explicitly ignore any menu events generated while any modal dialogs - // are opened. - if ( wxOpenModalDialogsCount ) + if ( !IsMenuEventAllowed(item->GetMenu()) ) return; int id = item->GetId();