Почему GTK2 gtk_widget_add_accelerator иногда не добавляет ярлык? - PullRequest
0 голосов
/ 11 мая 2018

Я вижу эту проблему, когда gtk_widget_add_accelerator не работает периодически. Некоторые пункты меню имеют ярлык, а некоторые нет в приложении GTK2, работающем в Ubuntu 16.04. Я установил символы и источник, чтобы увидеть, что происходит, и проверка сигнала внутри gtk_widget_add_accelerator не удалась:

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;
}

Поэтому я скопировал этот блок кода непосредственно перед вызовом gtk_widget_add_accelerator, например 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
                        );

И печатается «Pre-cond ok». Это означает, что на моем уровне приложения есть действительный сигнал, но НЕ внутри библиотеки GTK2. Так есть ли проблемы со сборкой? Несоответствующие заголовки? ИДК.

Так что я начал смотреть именно на то, против чего я строю. make file использует следующие флаги:

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

Кажется, довольно стандартные вещи, верно?

Так что я несколько растерялся, почему это не работает. Есть идеи?

Для справки это код, который создает сигнал:

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);

А содержимое «запроса» в моем приложении:

(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}

А когда я захожу в библиотеку GTK2:

(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}

Но он достигает этой стадии только после строки g_warning. Возможно, это связано с оптимизацией компилятора.

1 Ответ

0 голосов
/ 18 мая 2018

Хорошо.Кажется, символы отладки для Gtk уводили меня по неверному пути.Я собрал и установил GTK2 из исходного кода, и это было намного лучше.

gtk_widget_add_accelerator на самом деле делает все правильно и не попадает в свой обработчик ошибок сигнала.Реальная проблема заключается в том, что я заменяю элемент меню другим объектом в LgiMenuItem :: Icon, когда преобразовываю элемент в объект, который также поддерживает значок.Это удаляет ускоритель, который я добавил ранее.Я заметил это, когда все отсутствующие ускорители имели значки.

Таким образом, «решение» как таковое заключается в том, чтобы повторно добавить ярлык после преобразования пункта меню в тот, который поддерживает значок.Возможно, в будущем я переформулирую код, чтобы сделать его более эффективным, но на данный момент я просто счастлив, что он работает.

...