Work around Gtkmm3 issue where menu accelerators are not shown (#7)

There is a bug in Gtkmm3 when setting accelerator keys on a
Gtk::MenuItem, the accelerator keys work but are not displayed when the
menu is drawn.  This happens for Gtk::MenuItems, including derived
objects, that are constructed with a non-default constructor.

All non-default constructors of Gtk::MenuItem, and subclasses, work by
creating themselves a Gtk::AccelLabel and packing it inside the menu
item.  But in Gtk3 GtkMenuItem are created with a GtkAccelLabel already
packed in as a child and that accel label should be used instead.

To workaround the issue we only use the default constructor for
Gtk::MenuItem and subclasses.  This is easy to do because we only have
to change the wrappers in MenuHelpers.cc.

This bug affects Gtkmm version 3.0.0 to 3.22.2 and was fixed in
Gtkmm 3.22.3.

 * Gtkmm 3.0.0 was released in April 2011
 * Gtkmm 3.22.3 was released in November 2018

References:

[1] Bug Report on the Gtkmm mailing list
    https://mail.gnome.org/archives/gtkmm-list/2018-February/msg00006.html

[2] Commit - Gtk::MenuItem: Fix add_accel_label()
    e5c8c2df67

Closes #7 - Port to Gtk3
This commit is contained in:
Luca Bacci 2018-11-21 15:28:14 +01:00 committed by Mike Fleetwood
parent 244f4bcd22
commit 392bbba534
1 changed files with 53 additions and 11 deletions

View File

@ -19,6 +19,7 @@
#include <gtkmm/imagemenuitem.h>
#include <gtkmm/checkmenuitem.h>
#include <gtkmm/separatormenuitem.h>
#include <gtkmm/stock.h>
namespace GParted
{
@ -29,34 +30,43 @@ namespace Menu_Helpers
MenuElem::MenuElem(const Glib::ustring& label,
const Gtk::AccelKey& key,
const CallSlot& slot)
: Gtk::MenuItem(label, true)
: Gtk::MenuItem()
{
if (slot)
signal_activate().connect(slot);
set_accel_key(key);
set_label(label);
set_use_underline(true);
show_all();
}
MenuElem::MenuElem(const Glib::ustring & label,
const CallSlot & slot)
: Gtk::MenuItem(label, true)
: Gtk::MenuItem()
{
if (slot)
signal_activate().connect(slot);
set_label(label);
set_use_underline(true);
show_all();
}
MenuElem::MenuElem(const Glib::ustring & label,
Gtk::Menu & submenu)
: Gtk::MenuItem(label, true)
: Gtk::MenuItem()
{
set_submenu(submenu);
set_label(label);
set_use_underline(true);
show_all();
}
@ -65,13 +75,17 @@ ImageMenuElem::ImageMenuElem(const Glib::ustring& label,
const Gtk::AccelKey& key,
Gtk::Widget& image_widget,
const CallSlot& slot)
: ImageMenuItem(image_widget, label, true)
: ImageMenuItem()
{
if (slot)
signal_activate().connect(slot);
set_accel_key(key);
set_image(image_widget);
set_label(label);
set_use_underline(true);
show_all();
}
@ -79,11 +93,15 @@ ImageMenuElem::ImageMenuElem(const Glib::ustring& label,
ImageMenuElem::ImageMenuElem(const Glib::ustring& label,
Gtk::Widget& image_widget,
const CallSlot& slot)
: ImageMenuItem(image_widget, label, true)
: ImageMenuItem()
{
if (slot)
signal_activate().connect(slot);
set_image(image_widget);
set_label(label);
set_use_underline(true);
show_all();
}
@ -91,10 +109,14 @@ ImageMenuElem::ImageMenuElem(const Glib::ustring& label,
ImageMenuElem::ImageMenuElem(const Glib::ustring& label,
Gtk::Widget& image_widget,
Gtk::Menu& submenu)
: ImageMenuItem(image_widget, label, true)
: ImageMenuItem()
{
set_submenu(submenu);
set_image(image_widget);
set_label(label);
set_use_underline(true);
show_all();
}
@ -109,34 +131,48 @@ SeparatorElem::SeparatorElem()
StockMenuElem::StockMenuElem(const Gtk::StockID& stock_id,
const Gtk::AccelKey& key,
const CallSlot& slot)
: Gtk::ImageMenuItem(stock_id)
: Gtk::ImageMenuItem()
{
if (slot)
signal_activate().connect(slot);
set_accel_key(key);
set_use_stock();
set_label(stock_id.get_string());
show_all();
}
StockMenuElem::StockMenuElem(const Gtk::StockID& stock_id,
const CallSlot& slot)
: Gtk::ImageMenuItem(stock_id)
: Gtk::ImageMenuItem()
{
if (slot)
signal_activate().connect(slot);
Gtk::StockItem stock;
if (Gtk::Stock::lookup(stock_id, stock))
set_accel_key(Gtk::AccelKey(stock.get_keyval(),
stock.get_modifier()));
set_use_stock();
set_label(stock_id.get_string());
show_all();
}
StockMenuElem::StockMenuElem(const Gtk::StockID& stock_id,
Gtk::Menu& submenu)
: Gtk::ImageMenuItem(stock_id)
: Gtk::ImageMenuItem()
{
set_submenu(submenu);
set_use_stock();
set_label(stock_id.get_string());
show_all();
}
@ -144,24 +180,30 @@ StockMenuElem::StockMenuElem(const Gtk::StockID& stock_id,
CheckMenuElem::CheckMenuElem(const Glib::ustring& label,
const Gtk::AccelKey& key,
const CallSlot& slot)
: Gtk::CheckMenuItem(label, true)
: Gtk::CheckMenuItem()
{
if (slot)
signal_activate().connect(slot);
set_accel_key(key);
set_label(label);
set_use_underline(true);
show_all();
}
CheckMenuElem::CheckMenuElem(const Glib::ustring& label,
const CallSlot& slot)
: Gtk::CheckMenuItem(label, true)
: Gtk::CheckMenuItem()
{
if (slot)
signal_activate().connect(slot);
set_label(label);
set_use_underline(true);
show_all();
}