I'm seeing this issue where gtk_widget_add_accelerator doesn't work intermittently. Some menu items have a short cut and some don't on a GTK2 application running on Ubuntu 16.04. I installed the symbols and source to see what is going on and the signal check inside gtk_widget_add_accelerator is failing:
g_signal_query (g_signal_lookup (accel_signal, G_OBJECT_TYPE (widget)), &query);
if (!query.signal_id ||
!(query.signal_flags & G_SIGNAL_ACTION) ||
query.return_type != G_TYPE_NONE ||
query.n_params)
{
/* hmm, should be elaborate enough */
g_warning (G_STRLOC ": widget `%s' has no activatable signal \"%s\" without arguments",
G_OBJECT_TYPE_NAME (widget), accel_signal);
return;
}
So I copied that block of code to just before I call gtk_widget_add_accelerator like this:
const char *Signal = "activate";
GSignalQuery query;
g_signal_query (g_signal_lookup (Signal, G_OBJECT_TYPE (w)), &query);
if (!stricmp(Sc, "Ctrl+C")) // This is the short cut that doesn't work
{
if (!query.signal_id)
printf("Bad sig id\n");
else if (!(query.signal_flags & G_SIGNAL_ACTION))
printf("No sig act\n");
else if (query.return_type != G_TYPE_NONE)
printf("Ret type err\n");
else if (query.n_params)
printf("Param err.\n");
else
printf("Pre-cond ok.\n");
}
gtk_widget_add_accelerator( w,
Signal,
Menu->AccelGrp,
GtkKey,
mod,
Gtk::GTK_ACCEL_VISIBLE
);
And it prints 'Pre-cond ok.' which means there is a valid signal at my application level but NOT inside the GTK2 library. So is there a build problem? Mismatched headers? IDK.
So I started looking at exactly what I'm building against. The make file uses these flags:
Libs = \
-lmagic \
-static-libgcc \
`pkg-config --libs gtk+-2.0`
Inc = \
-I./include/common \
-I./include/linux/Gtk \
-I/usr/include/gstreamer-1.0 \
-I/usr/lib/x86_64-linux-gnu/gstreamer-1.0/include \
`pkg-config --cflags gtk+-2.0` \
-Iinclude/common \
-Iinclude/linux \
-Iinclude/linux/Gtk
Seems pretty standard stuff right?
So I'm somewhat at a loss as to why this isn't working. Any ideas?
For reference this is the code that creates the signal:
Info = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(Txt));
Gtk::gulong ret = Gtk::g_signal_connect_data(Info,
"activate",
(Gtk::GCallback) MenuItemCallback,
this,
NULL,
Gtk::G_CONNECT_SWAPPED);
And the contents of 'query' in my app:
(gdb) p query
$1 = {signal_id = 132, signal_name = 0x7ffff76c4859 "activate",
itype = 17714704,
signal_flags = (Gtk::G_SIGNAL_RUN_FIRST | Gtk::G_SIGNAL_ACTION),
return_type = 4, n_params = 0, param_types = 0x0}
And when I step into the GTK2 library:
(gdb) p query
$3 = {signal_id = 132, signal_name = 0x7ffff76c4859 "activate",
itype = 17714704, signal_flags = (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
return_type = 4, n_params = 0, param_types = 0x0}
But it only gets to that stage after the g_warning line. Maybe that's due to compiler optimization though.
Ok. It seems the debug symbols for Gtk were leading me down the wrong path. I built and installed GTK2 from source and it was much better.
gtk_widget_add_accelerator is actually doing the right thing and not falling into it's signal error handler. The real issue is that I'm replacing the menu item with a different object in LgiMenuItem::Icon when I convert the item to one that supports an icon as well. This deletes the accelerator that I added earlier. I noticed this when all the missing accelerators had icons.
So the "solution" as such is to re-add the shortcut after converting the menu item to one that supports an icon. Maybe down the track I'll re-factor the code to be more efficient but at this point I'm just happy it works.