GNOME Bugzilla – Bug 111084
Deleted menu item's signal handler still called.
Last modified: 2004-12-22 21:47:04 UTC
Deleting an item using Gtk::Menu_Helpers::MenuList::insert() or Gtk::Menu_Helpers::MenuList::remove() does not completely remove it. The item is still available through its keyboard shortcut. Example code: #include <gtkmm.h> #include <iostream> class TestWindow : public Gtk::Window { public: TestWindow(); private: Gtk::VBox windowVBox; Gtk::MenuBar menuBar; Gtk::Menu menu_Test1; Gtk::Menu menu_Test2; void delete_with_erase_test(); void delete_with_remove_test(); }; TestWindow::TestWindow() { set_title("MenuList erase() and remove() bug"); set_resizable(false); set_border_width(5); menu_Test1.items().push_back(Gtk::Menu_Helpers::MenuElem("Delete this using erase()", Gtk::Menu::AccelKey("<control>e"), SigC::slot(*this, &TestWindow::delete_with_erase_test))); menu_Test1.items().push_back(Gtk::Menu_Helpers::SeparatorElem()); menu_Test1.items().push_back(Gtk::Menu_Helpers::MenuElem("Quit", SigC::slot(*this, &Gtk::Widget::hide))); menu_Test2.items().push_back(Gtk::Menu_Helpers::MenuElem("Delete this using remove()", Gtk::Menu::AccelKey("<control>r"), SigC::slot (*this, &TestWindow::delete_with_remove_test))); menu_Test2.items().push_back(Gtk::Menu_Helpers::SeparatorElem()); menu_Test2.items().push_back(Gtk::Menu_Helpers::MenuElem("Quit", SigC::slot(*this, &Gtk::Widget::hide))); menuBar.items().push_back(Gtk::Menu_Helpers::MenuElem("Test 1", menu_Test1)); menuBar.items().push_back(Gtk::Menu_Helpers::MenuElem("Test 2", menu_Test2)); windowVBox.pack_start(menuBar); add(windowVBox); show_all(); } void TestWindow::delete_with_erase_test() { Gtk::Menu_Helpers::MenuList::iterator i = menu_Test1.items().begin(); menu_Test1.items().erase(i); std::cout << "Test 1 > 'Delete this using erase()' deleted." << std::endl; std::cout << "Bug: try to press Ctrl+e" << std::endl; } void TestWindow::delete_with_remove_test() { menu_Test2.items().remove(menu_Test2.items()[0]); std::cout << "Test 2 > 'Delete this using remove()' deleted." << std::endl; std::cout << "Bug: try to press Ctrl+r" << std::endl; } int main(int argc, char* argv[]) { Gtk::Main kit(argc, argv); TestWindow testWindow; Gtk::Main::run(testWindow); return 0; }
Please _attach_ test code in future. Please simplify this test case as much as possible. Please show us one bug, not two.
Created attachment 16372 [details] old_accel.cc simplified test case
You were right - The MenuItem is not really being deleted. It's probably because something is referencing it but not unreferencing - a GTK+ bug, I suspect. We've seen and fixed similar bugs before. The next step is to to the same thing in GTK+ C code, and then, if the problem is still there, find out exactly what is refing/unrefing it.
This should be fixed in cvs now: 2003-05-09 Murray Cumming <murrayc@usa.net> * gtk/src/menushell.[hg|ccg] replace GP_LIST_CONTAINER_REMOVE() with custom-written remove() and erase() MenuList methods, to ensure that we unset the accel widget that we might have set in the MenuItem() constructor. This avoids a memory leak due to the extra reference. The attached old_accel_gtk.c shows what the problem was.
Created attachment 16433 [details] [review] old_accel_gtk.c