Оказалось, что все, что связано с пользовательским интерфейсом, лучше делать в основном цикле, а не только обновления. Тем не менее, вот модифицированный пример программы с обнаружением области уведомлений, которая работает.
#include <gtk/gtk.h>
static GtkWidget *my_menu = NULL;
static GtkStatusIcon *status_icon = NULL;
static void
destroy(GtkWidget *widget,
gpointer data)
{
gtk_main_quit ();
}
static void
on_blink_change(GtkStatusIcon *widget,
gpointer data)
{
gboolean blink = GPOINTER_TO_UINT(data);
g_debug("Set blinking %s", (blink) ? "on" : "off");
gtk_status_icon_set_blinking(GTK_STATUS_ICON(status_icon), blink);
}
static void
activate (GtkStatusIcon* status_icon,
gpointer user_data)
{
g_debug("'activate' signal triggered");
}
static void
popup(GtkStatusIcon *status_icon,
guint button,
guint activate_time,
gpointer user_data)
{
g_debug("'popup-menu' signal triggered");
if (!my_menu)
{
GtkWidget *item;
my_menu = gtk_menu_new();
item = gtk_menu_item_new_with_label("Let's blink!");
gtk_menu_append(my_menu, item);
g_signal_connect(G_OBJECT(item), "activate",
G_CALLBACK(on_blink_change),
GUINT_TO_POINTER(TRUE));
item = gtk_menu_item_new_with_label("Let's stop blinking!");
gtk_menu_append(my_menu, item);
g_signal_connect (G_OBJECT(item), "activate",
G_CALLBACK(on_blink_change),
GUINT_TO_POINTER(FALSE));
item = gtk_menu_item_new_with_label("Quit");
gtk_menu_append(my_menu, item);
g_signal_connect (G_OBJECT(item), "activate",
G_CALLBACK(destroy),
NULL);
}
gtk_widget_show_all(my_menu);
gtk_menu_popup(GTK_MENU(my_menu),
NULL,
NULL,
gtk_status_icon_position_menu,
status_icon,
button,
activate_time);
}
static gboolean chkStatusIcon(gpointer pIn)
{
g_debug
(
"embedded: %s"
, gtk_status_icon_is_embedded(status_icon) ? "yes" : "no"
);
return FALSE;
}
int main( int argc,
char* argv[] )
{
gtk_init( &argc, &argv );
status_icon = gtk_status_icon_new_from_stock(GTK_STOCK_QUIT);
gtk_status_icon_set_visible(status_icon, TRUE);
/* instead of doing it right here, we do it in the main event loop */
g_idle_add((GSourceFunc) chkStatusIcon, NULL);
gtk_status_icon_set_tooltip(status_icon, "This is a test");
/* Connect signals */
g_signal_connect (G_OBJECT (status_icon), "popup-menu",
G_CALLBACK (popup), NULL);
g_signal_connect (G_OBJECT (status_icon), "activate",
G_CALLBACK (activate), NULL);
gtk_main();
return 0;
}
Теперь программа работает, но вопрос все еще остается. Почему нет способа проверить доступность области уведомлений без создания иконки состояния? Многие работы могут быть сохранены, если бы мы могли иметь эту информацию при запуске программы. Это связано со спецификациями freedesktop? Или это проблема реализации?
Если бы вы узнали причину (и) позади, было бы очень признательно, если бы вы добавили одну или две строки в комментарии.