Окно GTK настраивает события, которые не распространяются

#c #c #events #gtk

#c #c #Мероприятия #gtk

Вопрос:

Я пытаюсь зафиксировать событие в окне GTK при перемещении окна. Я делаю это с помощью чего-то, что выглядит следующим образом:

 void mycallback(GtkWindow* parentWindow, GdkEvent* event, gpointer data)
{
    // do something...
}

...
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);    

gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE);
g_signal_connect_(G_OBJECT(window), "configure-event", G_CALLBACK(mycallback), NULL);
...
  

Это работает — событие правильно вызывается при перемещении окна… но это также вызывается при изменении размера окна. Это имеет побочный эффект, заключающийся в том, что подэлементы окна не изменяются, как это было бы, если бы я не подключал событие.

Согласно этой таблице в документах GTK, событие GDK_CONFIGURE не распространяется. Если событие не распространяется, как я могу по-прежнему определять движение окна, позволяя ему изменять размер должным образом?

примечание: я использую GTK версии 2.12.9

Ответ №1:

Люк, как вы обнаружили, возврат FALSE позволяет событию распространяться. Это объясняется в руководстве по gtk здесь

Ответ №2:

Neuro- Я не верил, что это сработает, потому что сигнатура функции возвращала void, а не gboolean. Для усмешек я изменил:

 void mycallback(GtkWindow* parentWindow, GdkEvent* event, gpointer data)
  

Для

 gboolean mycallback(GtkWindow* parentWindow, GdkEvent* event, gpointer data)
  

Я бы подумал, что это приведет к несоответствию типов типам обратного вызова, но это не так. Возврат TRUE, как вы предложили, не работает … но, как ни странно, возвращает FALSE. В этом случае кажется, что событие может распространяться.


Редактировать:

В соответствии с руководством по GTK (спасибо Мэтту):

Значение, возвращаемое этой функцией, указывает, следует ли распространять событие дальше с помощью механизма обработки событий GTK. Возвращаемое значение TRUE указывает, что событие было обработано и что оно не должно распространяться дальше. Возврат FALSE продолжает обычную обработку событий.

Комментарии:

1. Это не вызовет несоответствия типов из-за приведения к G_CALLBACK , но должно быть возвращаемое значение, поскольку я думаю, что здесь лучше вызвать void функцию и не указывать ожидаемое возвращаемое значение, что означает, что поддельное логическое значение будет считано из какой-то несвязанной части стека и т.д.

Ответ №3:

вы не получите ошибку несоответствия типов для обработчиков сигналов, потому что в gtk вы приводите их все к одному типу, используя G_CALLBACK, независимо от их фактической подписи. Подпись объявляется динамически во время выполнения в функции class_init объекта GObject, поэтому нет способа ввести check их статически. Вы ДОЛЖНЫ ознакомиться с документацией по интересующему вас сигналу и убедиться, что сигнатура обработчиков совпадает с сигнатурой сигнала.

Комментарии:

1. И интересно, и раздражает. Я уверен, что у них есть причина для такого нарушения безопасности типов, но я не могу сказать, что для меня это звучит как хорошая идея.

2. Это должен был быть комментарий к ответу Люка, а не сообщение. @luke Конечно, причина, по которой они используют стирание типов, заключается в том, что в противном случае им пришлось бы объявлять и реализовывать произвольное количество перегрузок, структур хранения и т.д. Для каждого возможного указателя на функцию. В лучшем случае непрактично.

Ответ №4:

Ну, я в основном использую gtkmm (C оболочку GTK). Но, если я правильно помню, если вы хотите распространить сигнал на родительский сервер, ваш обработчик должен вернуть FALSE (gint), что означает «Я НЕ обрабатывал это событие». Поэтому я думаю, что если вы вернете (gint)FALSE в mycallback, это должно сработать.