Понадобилось вызывать всплывающее меню. По “горячей клавише”. Из любого места. Есть для этого такая маленькая приятная либа – keybinder. И как отдельная либа хороша, и в свой код интегрируется легко, т.к. в либе всего один файл с кодом. В общем – прелесть. Вот только меню из обработчиков хоткеев всплывать не желает, хоть ты тресни. Любое другое действие – пожалуйста. Меню – хрен тебе на воротник, а не меню. Причем, тот же самый код для вызова меню прекрасно работает, если его дергать через механизмы GApplication. Такая вот омерзительность.
Забавно, что ситуация проявляется только с gtk3, аналогичные фокусы с gtk2 работают на ура. Испробовал различные варианты обходных путей. Заработал вот такой workaround
gtk_widget_realize (menu); do { gtk_menu_popup_at_widget (GTK_MENU (menu), win, GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER, fake_ev); gtk_main_iteration (); } while (!gtk_widget_get_visible (menu));
fake_ev
в данном примере – созданный руками GdkEvent
disp = gdk_display_get_default (); fake_ev = gdk_event_new (GDK_BUTTON_PRESS); ((GdkEventButton *) fake_ev)->button = 1; ((GdkEventButton *) fake_ev)->window = gtk_widget_get_window (win); ((GdkEventButton *) fake_ev)->send_event = TRUE; ((GdkEventButton *) fake_ev)->time = GDK_CURRENT_TIME; ((GdkEventButton *) fake_ev)->device = gdk_seat_get_pointer (gdk_display_get_default_seat (disp));
Вот такие вот перверции и прочие збочинства иногда приходится плодить