X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9dc44eff0235c5f30940f32ccc6d9d82a236e7d2..63a4b41eda9484b315e499a05aa718b113b20da1:/src/gtk/menu.cpp?ds=sidebyside diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index acd8d29e73..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); } } @@ -339,7 +348,8 @@ wxMenu *wxMenuBar::Remove(size_t pos) gtk_widget_destroy( menu->m_owner ); menu->m_owner = NULL; - DetachFromFrame( menu, m_menuBarFrame ); + if ( m_menuBarFrame ) + DetachFromFrame( menu, m_menuBarFrame ); return menu; } @@ -477,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) { @@ -684,6 +704,13 @@ static void menu_map(GtkWidget*, wxMenu* menu) // "hide" from m_menu static void menu_hide(GtkWidget*, wxMenu* menu) { + // When using Ubuntu Unity desktop environment we get "hide" signal even + // when the window is not shown yet because Unity hides all the menus to + // show them only in the global menu bar. Just ignore this even instead of + // crashing in DoCommonMenuCallbackCode(). + if ( !menu->GetWindow() ) + return; + wxMenuEvent event(wxEVT_MENU_CLOSE, menu->m_popupShown ? -1 : 0, menu); menu->m_popupShown = false; DoCommonMenuCallbackCode(menu, event); @@ -739,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); @@ -902,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 @@ -1231,12 +1263,6 @@ const char *wxGetStockGtkID(wxWindowID id) case wx: \ return gtk; - #if GTK_CHECK_VERSION(2,6,0) - #define STOCKITEM_26(wx,gtk) STOCKITEM(wx,gtk) - #else - #define STOCKITEM_26(wx,gtk) - #endif - #if GTK_CHECK_VERSION(2,8,0) #define STOCKITEM_28(wx,gtk) STOCKITEM(wx,gtk) #else @@ -1252,7 +1278,7 @@ const char *wxGetStockGtkID(wxWindowID id) switch (id) { - STOCKITEM_26(wxID_ABOUT, GTK_STOCK_ABOUT) + STOCKITEM(wxID_ABOUT, GTK_STOCK_ABOUT) STOCKITEM(wxID_ADD, GTK_STOCK_ADD) STOCKITEM(wxID_APPLY, GTK_STOCK_APPLY) STOCKITEM(wxID_BACKWARD, GTK_STOCK_GO_BACK) @@ -1267,10 +1293,10 @@ const char *wxGetStockGtkID(wxWindowID id) STOCKITEM(wxID_CUT, GTK_STOCK_CUT) STOCKITEM(wxID_DELETE, GTK_STOCK_DELETE) STOCKITEM(wxID_DOWN, GTK_STOCK_GO_DOWN) - STOCKITEM_26(wxID_EDIT, GTK_STOCK_EDIT) + STOCKITEM(wxID_EDIT, GTK_STOCK_EDIT) STOCKITEM(wxID_EXECUTE, GTK_STOCK_EXECUTE) STOCKITEM(wxID_EXIT, GTK_STOCK_QUIT) - STOCKITEM_26(wxID_FILE, GTK_STOCK_FILE) + STOCKITEM(wxID_FILE, GTK_STOCK_FILE) STOCKITEM(wxID_FIND, GTK_STOCK_FIND) STOCKITEM(wxID_FIRST, GTK_STOCK_GOTO_FIRST) STOCKITEM(wxID_FLOPPY, GTK_STOCK_FLOPPY)