This program contains an application menu, a menubar and a toolbar.
Classes are derived from Gtk::Application
and
Gtk::ApplicationWindow
.
File: examplewindow.h
(For use with gtkmm 3, not gtkmm 2)
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::ApplicationWindow { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: void on_menu_others(); void on_menu_choices(const Glib::ustring& parameter); void on_menu_choices_other(int parameter); void on_menu_toggle(); //Child widgets: Gtk::Box m_Box; Glib::RefPtr<Gtk::Builder> m_refBuilder; //Two sets of choices: Glib::RefPtr<Gio::SimpleAction> m_refChoice; Glib::RefPtr<Gio::SimpleAction> m_refChoiceOther; Glib::RefPtr<Gio::SimpleAction> m_refToggle; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: exampleapplication.h
(For use with gtkmm 3, not gtkmm 2)
#ifndef GTKMM_EXAMPLEAPPLICATION_H #define GTKMM_EXAMPLEAPPLICATION_H #include <gtkmm.h> class ExampleApplication : public Gtk::Application { protected: ExampleApplication(); public: static Glib::RefPtr<ExampleApplication> create(); protected: //Overrides of default signal handlers: void on_startup() override; void on_activate() override; private: void create_window(); void on_window_hide(Gtk::Window* window); void on_menu_file_new_generic(); void on_menu_file_quit(); void on_menu_help_about(); Glib::RefPtr<Gtk::Builder> m_refBuilder; }; #endif /* GTKMM_EXAMPLEAPPLICATION_H */
File: exampleapplication.cc
(For use with gtkmm 3, not gtkmm 2)
#include "exampleapplication.h" #include "examplewindow.h" #include <iostream> ExampleApplication::ExampleApplication() : Gtk::Application("org.gtkmm.example.main_menu") { Glib::set_application_name("Main Menu Example"); } Glib::RefPtr<ExampleApplication> ExampleApplication::create() { return Glib::RefPtr<ExampleApplication>(new ExampleApplication()); } void ExampleApplication::on_startup() { //Call the base class's implementation: Gtk::Application::on_startup(); //Create actions for menus and toolbars. //We can use add_action() because Gtk::Application derives from Gio::ActionMap. //File|New sub menu: add_action("newstandard", sigc::mem_fun(*this, &ExampleApplication::on_menu_file_new_generic)); add_action("newfoo", sigc::mem_fun(*this, &ExampleApplication::on_menu_file_new_generic)); add_action("newgoo", sigc::mem_fun(*this, &ExampleApplication::on_menu_file_new_generic)); //File menu: add_action("quit", sigc::mem_fun(*this, &ExampleApplication::on_menu_file_quit)); //Help menu: add_action("about", sigc::mem_fun(*this, &ExampleApplication::on_menu_help_about)); m_refBuilder = Gtk::Builder::create(); //Layout the actions in a menubar and an application menu: Glib::ustring ui_info = "<interface>" " <!-- menubar -->" " <menu id='menu-example'>" " <submenu>" " <attribute name='label' translatable='yes'>_File</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>New _Standard</attribute>" " <attribute name='action'>app.newstandard</attribute>" " <attribute name='accel'><Primary>n</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>New _Foo</attribute>" " <attribute name='action'>app.newfoo</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>New _Goo</attribute>" " <attribute name='action'>app.newgoo</attribute>" " </item>" " </section>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_Quit</attribute>" " <attribute name='action'>app.quit</attribute>" " <attribute name='accel'><Primary>q</attribute>" " </item>" " </section>" " </submenu>" " <submenu>" " <attribute name='label' translatable='yes'>_Edit</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_Copy</attribute>" " <attribute name='action'>win.copy</attribute>" " <attribute name='accel'><Primary>c</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>_Paste</attribute>" " <attribute name='action'>win.paste</attribute>" " <attribute name='accel'><Primary>v</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>_Something</attribute>" " <attribute name='action'>win.something</attribute>" " </item>" " </section>" " </submenu>" " <submenu>" " <attribute name='label' translatable='yes'>_Choices</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>Choice _A</attribute>" " <attribute name='action'>win.choice</attribute>" " <attribute name='target'>a</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>Choice _B</attribute>" " <attribute name='action'>win.choice</attribute>" " <attribute name='target'>b</attribute>" " </item>" " </section>" " </submenu>" " <submenu>" " <attribute name='label' translatable='yes'>_Other Choices</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>Choice 1</attribute>" " <attribute name='action'>win.choiceother</attribute>" " <attribute name='target' type='i'>1</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>Choice 2</attribute>" " <attribute name='action'>win.choiceother</attribute>" " <attribute name='target' type='i'>2</attribute>" " </item>" " </section>" " <section>" " <item>" " <attribute name='label' translatable='yes'>Some Toggle</attribute>" " <attribute name='action'>win.sometoggle</attribute>" " </item>" " </section>" " </submenu>" " <submenu>" " <attribute name='label' translatable='yes'>_Help</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_About</attribute>" " <attribute name='action'>win.about</attribute>" " </item>" " </section>" " </submenu>" " </menu>" "" " <!-- application menu -->" " <menu id='appmenu'>" " <submenu>" " <attribute name='label' translatable='yes'>_File</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>New _Standard</attribute>" " <attribute name='action'>app.newstandard</attribute>" " <attribute name='accel'><Primary>n</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>New _Foo</attribute>" " <attribute name='action'>app.newfoo</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>New _Goo</attribute>" " <attribute name='action'>app.newgoo</attribute>" " </item>" " </section>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_Quit</attribute>" " <attribute name='action'>app.quit</attribute>" " <attribute name='accel'><Primary>q</attribute>" " </item>" " </section>" " </submenu>" " <submenu>" " <attribute name='label' translatable='yes'>_Help</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_About</attribute>" " <attribute name='action'>app.about</attribute>" " </item>" " </section>" " </submenu>" " </menu>" "</interface>"; try { m_refBuilder->add_from_string(ui_info); } catch (const Glib::Error& ex) { std::cerr << "Building menus failed: " << ex.what(); } //Get the menubar and the app menu, and add them to the application: auto object = m_refBuilder->get_object("menu-example"); auto gmenu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object); object = m_refBuilder->get_object("appmenu"); auto appMenu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object); if (!(gmenu && appMenu)) { g_warning("GMenu or AppMenu not found"); } else { set_app_menu(appMenu); set_menubar(gmenu); } } void ExampleApplication::on_activate() { //std::cout << "debug1: " << G_STRFUNC << std::endl; // The application has been started, so let's show a window. // A real application might want to reuse this window in on_open(), // when asked to open a file, if no changes have been made yet. create_window(); } void ExampleApplication::create_window() { auto win = new ExampleWindow(); //Make sure that the application runs for as long this window is still open: add_window(*win); //Delete the window when it is hidden. //That's enough for this simple example. win->signal_hide().connect(sigc::bind<Gtk::Window*>( sigc::mem_fun(*this, &ExampleApplication::on_window_hide), win)); win->show_all(); } void ExampleApplication::on_window_hide(Gtk::Window* window) { delete window; } void ExampleApplication::on_menu_file_new_generic() { std::cout << "A File|New menu item was selected." << std::endl; } void ExampleApplication::on_menu_file_quit() { std::cout << G_STRFUNC << std::endl; quit(); // Not really necessary, when Gtk::Widget::hide() is called. // Gio::Application::quit() will make Gio::Application::run() return, // but it's a crude way of ending the program. The window is not removed // from the application. Neither the window's nor the application's // destructors will be called, because there will be remaining reference // counts in both of them. If we want the destructors to be called, we // must remove the window from the application. One way of doing this // is to hide the window. std::vector<Gtk::Window*> windows = get_windows(); if (windows.size() > 0) windows[0]->hide(); // In this simple case, we know there is only one window. } void ExampleApplication::on_menu_help_about() { std::cout << "App|Help|About was selected." << std::endl; }
File: main.cc
(For use with gtkmm 3, not gtkmm 2)
#include "exampleapplication.h" int main(int argc, char* argv[]) { auto application = ExampleApplication::create(); // Start the application, showing the initial window, // and opening extra windows for any files that it is asked to open, // for instance as a command-line parameter. // run() will return when the last window has been closed by the user. const int status = application->run(argc, argv); return status; }
File: examplewindow.cc
(For use with gtkmm 3, not gtkmm 2)
#include "examplewindow.h" #include <iostream> ExampleWindow::ExampleWindow() : Gtk::ApplicationWindow(), m_Box(Gtk::ORIENTATION_VERTICAL) { set_title("Main menu example"); set_default_size(300, 100); // ExampleApplication displays the menubar. Other stuff, such as a toolbar, // is put into the box. add(m_Box); // Create actions for menus and toolbars. // We can use add_action() because Gtk::ApplicationWindow derives from Gio::ActionMap. // This Action Map uses a "win." prefix for the actions. // Therefore, for instance, "win.copy", is used in ExampleApplication::on_startup() // to layout the menu. //Edit menu: add_action("copy", sigc::mem_fun(*this, &ExampleWindow::on_menu_others)); add_action("paste", sigc::mem_fun(*this, &ExampleWindow::on_menu_others)); add_action("something", sigc::mem_fun(*this, &ExampleWindow::on_menu_others)); //Choices menus, to demonstrate Radio items, //using our convenience methods for string and int radio values: m_refChoice = add_action_radio_string("choice", sigc::mem_fun(*this, &ExampleWindow::on_menu_choices), "a"); m_refChoiceOther = add_action_radio_integer("choiceother", sigc::mem_fun(*this, &ExampleWindow::on_menu_choices_other), 1); m_refToggle = add_action_bool("sometoggle", sigc::mem_fun(*this, &ExampleWindow::on_menu_toggle), false); //Help menu: add_action("about", sigc::mem_fun(*this, &ExampleWindow::on_menu_others)); //Create the toolbar and add it to a container widget: m_refBuilder = Gtk::Builder::create(); Glib::ustring ui_info = "<!-- Generated with glade 3.18.3 -->" "<interface>" " <requires lib='gtk+' version='3.4'/>" " <object class='GtkToolbar' id='toolbar'>" " <property name='visible'>True</property>" " <property name='can_focus'>False</property>" " <child>" " <object class='GtkToolButton' id='toolbutton_new'>" " <property name='visible'>True</property>" " <property name='can_focus'>False</property>" " <property name='tooltip_text' translatable='yes'>New Standard</property>" " <property name='action_name'>app.newstandard</property>" " <property name='icon_name'>document-new</property>" " </object>" " <packing>" " <property name='expand'>False</property>" " <property name='homogeneous'>True</property>" " </packing>" " </child>" " <child>" " <object class='GtkToolButton' id='toolbutton_quit'>" " <property name='visible'>True</property>" " <property name='can_focus'>False</property>" " <property name='tooltip_text' translatable='yes'>Quit</property>" " <property name='action_name'>app.quit</property>" " <property name='icon_name'>application-exit</property>" " </object>" " <packing>" " <property name='expand'>False</property>" " <property name='homogeneous'>True</property>" " </packing>" " </child>" " </object>" "</interface>"; try { m_refBuilder->add_from_string(ui_info); } catch (const Glib::Error& ex) { std::cerr << "Building toolbar failed: " << ex.what(); } Gtk::Toolbar* toolbar = nullptr; m_refBuilder->get_widget("toolbar", toolbar); if (!toolbar) g_warning("GtkToolbar not found"); else m_Box.pack_start(*toolbar, Gtk::PACK_SHRINK); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_menu_others() { std::cout << "A menu item was selected." << std::endl; } void ExampleWindow::on_menu_choices(const Glib::ustring& parameter) { //The radio action's state does not change automatically: m_refChoice->change_state(parameter); Glib::ustring message; if (parameter == "a") message = "Choice a was selected."; else message = "Choice b was selected."; std::cout << message << std::endl; } void ExampleWindow::on_menu_choices_other(int parameter) { //The radio action's state does not change automatically: m_refChoiceOther->change_state(parameter); Glib::ustring message; if (parameter == 1) message = "Choice 1 was selected."; else message = "Choice 2 was selected."; std::cout << message << std::endl; } void ExampleWindow::on_menu_toggle() { bool active = false; m_refToggle->get_state(active); //The toggle action's state does not change automatically: active = !active; m_refToggle->change_state(active); Glib::ustring message; if (active) message = "Toggle is active."; else message = "Toggle is not active."; std::cout << message << std::endl; }
This program contains a menubar and a toolbar.
A class is derived from Gtk::Window
.
File: examplewindow.h
(For use with gtkmm 3, not gtkmm 2)
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(const Glib::RefPtr<Gtk::Application>& app); virtual ~ExampleWindow(); private: //Signal handlers: void on_action_file_new(); void on_action_file_quit(); void on_action_others(); void on_action_toggle(); //Child widgets: Gtk::Box m_Box; Glib::RefPtr<Gtk::Builder> m_refBuilder; Glib::RefPtr<Gio::SimpleActionGroup> m_refActionGroup; Glib::RefPtr<Gio::SimpleAction> m_refActionRain; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
(For use with gtkmm 3, not gtkmm 2)
#include <gtkmm.h> #include "examplewindow.h" int main(int argc, char *argv[]) { auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example"); ExampleWindow window(app); //Shows the window and returns when it is closed. return app->run(window); }
File: examplewindow.cc
(For use with gtkmm 3, not gtkmm 2)
#include "examplewindow.h" #include <gtkmm.h> #include <iostream> ExampleWindow::ExampleWindow(const Glib::RefPtr<Gtk::Application>& app) : m_Box(Gtk::ORIENTATION_VERTICAL) { set_title("main_menu example"); set_default_size(200, 200); add(m_Box); //We can put a MenuBar at the top of the box and other stuff below it. //Define the actions: m_refActionGroup = Gio::SimpleActionGroup::create(); m_refActionGroup->add_action("new", sigc::mem_fun(*this, &ExampleWindow::on_action_file_new) ); m_refActionGroup->add_action("open", sigc::mem_fun(*this, &ExampleWindow::on_action_others) ); m_refActionRain = m_refActionGroup->add_action_bool("rain", sigc::mem_fun(*this, &ExampleWindow::on_action_toggle), false); m_refActionGroup->add_action("quit", sigc::mem_fun(*this, &ExampleWindow::on_action_file_quit) ); m_refActionGroup->add_action("cut", sigc::mem_fun(*this, &ExampleWindow::on_action_others) ); m_refActionGroup->add_action("copy", sigc::mem_fun(*this, &ExampleWindow::on_action_others) ); m_refActionGroup->add_action("paste", sigc::mem_fun(*this, &ExampleWindow::on_action_others) ); insert_action_group("example", m_refActionGroup); //Define how the actions are presented in the menus and toolbars: m_refBuilder = Gtk::Builder::create(); //Layout the actions in a menubar and toolbar: const char* ui_info = "<interface>" " <menu id='menubar'>" " <submenu>" " <attribute name='label' translatable='yes'>_File</attribute>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_New</attribute>" " <attribute name='action'>example.new</attribute>" " <attribute name='accel'><Primary>n</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>_Open</attribute>" " <attribute name='action'>example.open</attribute>" " <attribute name='accel'><Primary>o</attribute>" " </item>" " </section>" " <section>" " <item>" " <attribute name='label' translatable='yes'>Rain</attribute>" " <attribute name='action'>example.rain</attribute>" " </item>" " </section>" " <section>" " <item>" " <attribute name='label' translatable='yes'>_Quit</attribute>" " <attribute name='action'>example.quit</attribute>" " <attribute name='accel'><Primary>q</attribute>" " </item>" " </section>" " </submenu>" " <submenu>" " <attribute name='label' translatable='yes'>_Edit</attribute>" " <item>" " <attribute name='label' translatable='yes'>_Cut</attribute>" " <attribute name='action'>example.cut</attribute>" " <attribute name='accel'><Primary>x</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>_Copy</attribute>" " <attribute name='action'>example.copy</attribute>" " <attribute name='accel'><Primary>c</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>_Paste</attribute>" " <attribute name='action'>example.paste</attribute>" " <attribute name='accel'><Primary>v</attribute>" " </item>" " </submenu>" " </menu>" "</interface>"; // When the menubar is a child of a Gtk::Window, keyboard accelerators are not // automatically fetched from the Gio::Menu. // See the examples/book/menus/main_menu example for an alternative way of // adding the menubar when using Gtk::ApplicationWindow. // Gtk::Application::set_accel_for_action() is new in gtkmm 3.11.9. app->set_accel_for_action("example.new", "<Primary>n"); app->set_accel_for_action("example.open", "<Primary>o"); app->set_accel_for_action("example.quit", "<Primary>q"); app->set_accel_for_action("example.cut", "<Primary>x"); app->set_accel_for_action("example.copy", "<Primary>c"); app->set_accel_for_action("example.paste", "<Primary>v"); try { m_refBuilder->add_from_string(ui_info); m_refBuilder->add_from_resource("/toolbar/toolbar.glade"); } catch(const Glib::Error& ex) { std::cerr << "Building menus and toolbar failed: " << ex.what(); } //Get the menubar: auto object = m_refBuilder->get_object("menubar"); auto gmenu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object); if (!gmenu) g_warning("GMenu not found"); else { auto pMenuBar = Gtk::make_managed<Gtk::MenuBar>(gmenu); //Add the MenuBar to the window: m_Box.pack_start(*pMenuBar, Gtk::PACK_SHRINK); } //Get the toolbar and add it to a container widget: Gtk::Toolbar* toolbar = nullptr; m_refBuilder->get_widget("toolbar", toolbar); if (!toolbar) g_warning("GtkToolbar not found"); else m_Box.pack_start(*toolbar, Gtk::PACK_SHRINK); show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_action_file_quit() { hide(); //Closes the main window to stop the app->run(). } void ExampleWindow::on_action_file_new() { std::cout << "A File|New menu item was selected." << std::endl; } void ExampleWindow::on_action_others() { std::cout << "A menu item was selected." << std::endl; } void ExampleWindow::on_action_toggle() { std::cout << "The toggle menu item was selected." << std::endl; bool active = false; m_refActionRain->get_state(active); //The toggle action's state does not change automatically: active = !active; m_refActionRain->change_state(active); Glib::ustring message; if(active) message = "Toggle is active."; else message = "Toggle is not active"; std::cout << message << std::endl; }
File: toolbar.gresource.xml
(For use with gtkmm 3, not gtkmm 2)
<?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/toolbar"> <file preprocess="xml-stripblanks">toolbar.glade</file> <file>rain.png</file> </gresource> </gresources>
File: examplewindow.h
(For use with gtkmm 3, not gtkmm 2)
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: bool on_button_press_event(GdkEventButton* button_event) override; void on_menu_file_popup_generic(); //Child widgets: Gtk::Box m_Box; Gtk::EventBox m_EventBox; Gtk::Label m_Label; Glib::RefPtr<Gtk::Builder> m_refBuilder; Gtk::Menu* m_pMenuPopup; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
(For use with gtkmm 3, not gtkmm 2)
#include "examplewindow.h" #include <gtkmm/application.h> int main(int argc, char *argv[]) { auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example"); ExampleWindow window; //Shows the window and returns when it is closed. return app->run(window); }
File: examplewindow.cc
(For use with gtkmm 3, not gtkmm 2)
#include "examplewindow.h" #include <iostream> ExampleWindow::ExampleWindow() : m_Box(Gtk::ORIENTATION_VERTICAL), m_Label("Right-click to see the popup menu."), m_pMenuPopup(nullptr) { set_title("popup example"); set_default_size(200, 200); add(m_Box); //Add an event box that can catch button_press events: m_Box.pack_start(m_EventBox); m_EventBox.signal_button_press_event().connect(sigc::mem_fun(*this, &ExampleWindow::on_button_press_event) ); m_EventBox.add(m_Label); //Create actions: //Fill menu: auto refActionGroup = Gio::SimpleActionGroup::create(); //File|New sub menu: //These menu actions would normally already exist for a main menu, because a //context menu should not normally contain menu items that are only available //via a context menu. refActionGroup->add_action("edit", sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic)); refActionGroup->add_action("process", //TODO: How to specify "<control>P" as an accelerator. sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic)); refActionGroup->add_action("remove", sigc::mem_fun(*this, &ExampleWindow::on_menu_file_popup_generic)); insert_action_group("examplepopup", refActionGroup); m_refBuilder = Gtk::Builder::create(); //Layout the actions in a menubar and toolbar: Glib::ustring ui_info = "<interface>" " <menu id='menu-examplepopup'>" " <section>" " <item>" " <attribute name='label' translatable='yes'>Edit</attribute>" " <attribute name='action'>examplepopup.edit</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>Process</attribute>" " <attribute name='action'>examplepopup.process</attribute>" " </item>" " <item>" " <attribute name='label' translatable='yes'>Remove</attribute>" " <attribute name='action'>examplepopup.remove</attribute>" " </item>" " </section>" " </menu>" "</interface>"; try { m_refBuilder->add_from_string(ui_info); } catch(const Glib::Error& ex) { std::cerr << "building menus failed: " << ex.what(); } //Get the menu: auto object = m_refBuilder->get_object("menu-examplepopup"); auto gmenu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object); if(!gmenu) g_warning("GMenu not found"); m_pMenuPopup = new Gtk::Menu(gmenu); show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_menu_file_popup_generic() { std::cout << "A popup menu item was selected." << std::endl; } bool ExampleWindow::on_button_press_event(GdkEventButton* button_event) { if( (button_event->type == GDK_BUTTON_PRESS) && (button_event->button == 3) ) { if(!m_pMenuPopup->get_attach_widget()) { m_pMenuPopup->attach_to_widget(*this); } if(m_pMenuPopup) m_pMenuPopup->popup_at_pointer((GdkEvent*)button_event); // Menu::popup_at_pointer() is new in gtkmm 3.22. // If you have an older revision, try this: //m_pMenuPopup->popup(button_event->button, button_event->time); return true; //It has been handled. } else return false; }