Search code examples
cgtkxfcegnome-3

gtk_status_icon_is_embedded Always Returns False On Gnome3 and xfce4


I've been trying to figure out how *gtk_status_icon_is_embedded()* works recently and I've found a tutorial about GtkStatusIcon here. I tried the sample program on both Gnome3 and xfce4. The status icon can be seen on both DMs, but the method always returns FALSE no matter how hard I tried. Anyone can shed me some light please?

Thanks in advance!


Solution

  • It turned out that everything related to UI has better to be done in the main loop, not only updates. That said, here is the modified sample program with notification area detection which works.

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

    Now the program worked, but a question still remains. Why there is no way to check the availability of notification area without instantiating a status icon? A lot of works can be saved if we could have that piece of info when the program starts. Is it due to the specs of the freedesktop? Or is it an implementation problem?

    If you happened to know the reason(s) behind, it would be very appreciated if you could drop a line or two in the comments.