X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/64b788642dc8c3338a2230be35f50db28e117e3d..96943967a559f8251349899ff6a45ad898bdc669:/src/gtk/menu.cpp?ds=sidebyside diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index f0b8b6ff9e..fe3a0c1d68 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -30,6 +30,9 @@ #include "wx/gtk/private/gtk2-compat.h" #include "wx/gtk/private/mnemonics.h" +// Number of currently open modal dialogs, defined in src/gtk/toplevel.cpp. +extern int wxOpenModalDialogsCount; + // we use normal item but with a special id for the menu title static const int wxGTK_TITLE_ID = -3; @@ -45,6 +48,10 @@ static void wxGetGtkAccel(const wxMenuItem*, guint*, GdkModifierType*); static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event) { + // See the comment about Ubuntu Unity in menuitem_activate(). + if ( wxOpenModalDialogsCount ) + return; + event.SetEventObject( menu ); wxEvtHandler* handler = menu->GetEventHandler(); @@ -63,12 +70,14 @@ static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event) wxMenuBar::~wxMenuBar() { - if (m_widget) + if (m_widget && IsAttached()) { // Work around a probable bug in Ubuntu 12.04 which causes a warning if // gtk_widget_destroy() is called on a wxMenuBar attached to a frame GtkWidget* widget = m_widget; + m_focusWidget = m_widget = NULL; + GTKDisconnect(widget); g_object_unref(widget); } } @@ -478,6 +487,16 @@ 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 ) + return; + int id = item->GetId(); if (id == wxGTK_TITLE_ID) { @@ -747,7 +766,8 @@ wxMenu::~wxMenu() // Destroying a menu generates a "hide" signal even if it's not shown // currently, so disconnect it to avoid dummy wxEVT_MENU_CLOSE events // generation. - g_signal_handlers_disconnect_by_func(m_menu, (gpointer)menu_hide, this); + g_signal_handlers_disconnect_matched(m_menu, + GSignalMatchType(G_SIGNAL_MATCH_DATA), 0, 0, NULL, NULL, this); // see wxMenu::Init g_object_unref(m_menu); @@ -910,6 +930,10 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) return NULL; GtkWidget * const mitem = item->GetMenuItem(); + + g_signal_handlers_disconnect_matched(mitem, + GSignalMatchType(G_SIGNAL_MATCH_DATA), 0, 0, NULL, NULL, item); + #ifdef __WXGTK3__ gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), NULL); #else