X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0f29501b663574dc6f5f43dfb8a7f16fb5a8e4ea..14722c43c30918cd8fbba956b50ac3426d2fe339:/src/gtk/menu.cpp diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp index ae2d4df832..fe3ebb03a3 100644 --- a/src/gtk/menu.cpp +++ b/src/gtk/menu.cpp @@ -24,7 +24,10 @@ #include "wx/accel.h" #include "wx/stockitem.h" + +#include #include "wx/gtk/private.h" +#include "wx/gtk/private/gtk2-compat.h" #include "wx/gtk/private/mnemonics.h" // we use normal item but with a special id for the menu title @@ -58,6 +61,18 @@ static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event) // wxMenuBar //----------------------------------------------------------------------------- +wxMenuBar::~wxMenuBar() +{ + if (m_widget) + { + // 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_widget = NULL; + g_object_unref(widget); + } +} + void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long style) { #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 @@ -91,7 +106,7 @@ void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long st GTKApplyWidgetStyle(); #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2 - g_object_ref(m_widget); + g_object_ref_sink(m_widget); for (size_t i = 0; i < n; ++i ) Append(menus[i], titles[i]); @@ -126,7 +141,7 @@ DetachFromFrame(wxMenu* menu, wxFrame* frame) // Note that wxGetTopLevelParent() is really needed because this frame // can be an MDI child frame which is a fake frame and not a TLW at all GtkWindow * const tlw = GTK_WINDOW(wxGetTopLevelParent(frame)->m_widget); - if (g_slist_find(menu->m_accel->acceleratables, tlw)) + if (g_slist_find(gtk_accel_groups_from_object(G_OBJECT(tlw)), menu->m_accel)) gtk_window_remove_accel_group(tlw, menu->m_accel); } @@ -147,7 +162,7 @@ AttachToFrame(wxMenu* menu, wxFrame* frame) if (menu->m_accel) { GtkWindow * const tlw = GTK_WINDOW(wxGetTopLevelParent(frame)->m_widget); - if (!g_slist_find(menu->m_accel->acceleratables, tlw)) + if (!g_slist_find(gtk_accel_groups_from_object(G_OBJECT(tlw)), menu->m_accel)) gtk_window_add_accel_group(tlw, menu->m_accel); } @@ -416,6 +431,15 @@ void wxMenuBar::EnableTop( size_t pos, bool flag ) gtk_widget_set_sensitive( menu->m_owner, flag ); } +bool wxMenuBar::IsEnabledTop(size_t pos) const +{ + wxMenuList::compatibility_iterator node = m_menus.Item( pos ); + wxCHECK_MSG( node, false, wxS("invalid index in IsEnabledTop") ); + wxMenu* const menu = node->GetData(); + wxCHECK_MSG( menu->m_owner, true, wxS("no menu owner?") ); + return gtk_widget_get_sensitive( menu->m_owner ) != 0; +} + wxString wxMenuBar::GetMenuLabel( size_t pos ) const { wxMenuList::compatibility_iterator node = m_menus.Item( pos ); @@ -660,6 +684,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); @@ -878,7 +909,25 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) return NULL; GtkWidget * const mitem = item->GetMenuItem(); +#ifdef __WXGTK3__ gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), NULL); +#else + if (!gtk_check_version(2,12,0)) + { + // gtk_menu_item_remove_submenu() is deprecated since 2.12, but + // gtk_menu_item_set_submenu() can now be used with NULL submenu now so + // just do use it. + gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), NULL); + } + else // GTK+ < 2.12 + { + // In 2.10 calling gtk_menu_item_set_submenu() with NULL submenu + // results in critical GTK+ error messages so use the old function + // instead. + gtk_menu_item_remove_submenu(GTK_MENU_ITEM(mitem)); + } +#endif + gtk_widget_destroy(mitem); item->SetMenuItem(NULL); @@ -1189,12 +1238,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 @@ -1210,7 +1253,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) @@ -1225,10 +1268,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)