Thread: GTK+ Gnome desktop system tray app problem

  1. #1
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058

    GTK+ Gnome desktop system tray app problem

    I found the following sample code on the internet. It is supposed to create a system tray (notification area) icon. It compiles without any problem. Unfortunately, it does not display anything in the notification area. I would greatly appreciate any assistance offered in resolving this problem. It could be that I'm not using the app properly.

    Also, I would greatly appreciate any assistance offered in developing a Gnome desktop system tray base framework.

    Thanx

    Code:
    // gcc -Wall -g tray.c -o tray `pkg-config gtk+-2.0 --cflags --libs`
    #include <stdio.h>
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include <gdk/gdkx.h>
    
    typedef struct tray_struct * trayicon;
    
    void create_tray_and_dock (trayicon tray);
    
    #define SYSTEM_TRAY_REQUEST_DOCK 0
    
    struct tray_struct {
        Window manager_window;
        GdkWindow *manager_window_gdk;
        gint screen_height;
        GdkWindow *root_gdk;
        GdkWindow *plug_gdk;
        Window plug_xlib;
        GdkPixbuf *icon_pixbuf;
        Atom system_tray_opcode_atom;
        Atom manager_atom;
    };
    
    Window get_manager_window (void)
    {
        static gboolean first_call=TRUE;
        static Atom selection_atom;
        Window manager_window=None;
        if (first_call) {
            gchar *tmp=g_strdup_printf ("_NET_SYSTEM_TRAY_S%i",
                XScreenNumberOfScreen(XDefaultScreenOfDisplay(GDK_DISPLAY())));
            selection_atom = XInternAtom(GDK_DISPLAY(), tmp, False);
            g_free (tmp);
            first_call=FALSE;
        }
        gdk_error_trap_push();
        XGrabServer (GDK_DISPLAY());
        manager_window = XGetSelectionOwner (GDK_DISPLAY(), selection_atom);
        XUngrabServer (GDK_DISPLAY());
        XFlush (GDK_DISPLAY());
        if (gdk_error_trap_pop())
            return None;
        printf ("get manager window: %d\n", manager_window);
        return manager_window;
    }
    
    void dock_window(trayicon tray)
    {
        XClientMessageEvent ev;
        ev.type = ClientMessage;
        ev.window =tray->manager_window;
        ev.message_type =tray->system_tray_opcode_atom;
        ev.format = 32;
        ev.data.l[0] = CurrentTime;
        ev.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
        ev.data.l[2] = tray->plug_xlib;
        ev.data.l[3] =0;
        ev.data.l[4] = 0;
        gdk_error_trap_push ();
        XSendEvent (GDK_DISPLAY(), tray->manager_window, False, 
            NoEventMask, 
            (XEvent *)&ev);
        XSync (GDK_DISPLAY(), False);
        gdk_error_trap_pop ();
    }
    
    void reparent_notify  (trayicon tray)
    {
        XSetWindowBackgroundPixmap(GDK_DISPLAY(), tray->plug_xlib, 
            ParentRelative);
        XClearWindow (GDK_DISPLAY(), tray->plug_xlib);
        XFlush (GDK_DISPLAY());
    }
    
    void expose (trayicon tray)
    {
        GdkGC *gc =gdk_gc_new (tray->plug_gdk);
        XClearWindow (GDK_DISPLAY(), tray->plug_xlib);
        XFlush (GDK_DISPLAY());
        gdk_draw_pixbuf (tray->plug_gdk, gc, tray->icon_pixbuf,
            0, 0, 0, 0, 24, 24, GDK_RGB_DITHER_NONE, 0, 0);
    }
    
    static GdkFilterReturn filter (GdkXEvent *xevent,
        GdkEvent *event, gpointer user_data)
    {
        XEvent *xev = (XEvent *)xevent;
        trayicon tray = (trayicon) user_data;
        if (xev->xany.type == ReparentNotify) {
            printf ("reparen notify\n");
            reparent_notify(tray);
        }
        if (xev->xany.type == Expose) {
            printf ("expose notify\n");
            expose(tray);
        }
    
        return GDK_FILTER_CONTINUE;
    }
    
    void create_tray_and_dock (trayicon tray)
    {
        if (tray->manager_window==None)
            tray->manager_window=get_manager_window();
        if (tray->manager_window==None)
            return;
        tray->manager_window_gdk=NULL;
        tray->manager_window_gdk=gdk_window_foreign_new(tray->manager_window);
        tray->plug_xlib= XCreateSimpleWindow(GDK_DISPLAY(), 
            GDK_ROOT_WINDOW(), 0,
            0, 24, 24, 0, 0, 0);
        XSelectInput(GDK_DISPLAY(), tray->plug_xlib, StructureNotifyMask | 
            ExposureMask);
        tray->plug_gdk=gdk_window_foreign_new (tray->plug_xlib);
        gdk_window_add_filter (tray->plug_gdk, filter, (gpointer) tray);
        dock_window (tray);
    }
    
    void trayicon_show (trayicon tray)
    {
        g_assert (tray != NULL);
        tray->screen_height=gdk_screen_get_height (gdk_screen_get_default());
        tray->root_gdk =gdk_screen_get_root_window 
            (gdk_screen_get_default());
        tray->manager_window = get_manager_window ();
        tray->manager_window_gdk =NULL;
        create_tray_and_dock(tray);
    }
    
    trayicon trayicon_new(GdkPixbuf *default_icon)
    {
        g_assert (default_icon != NULL);
        trayicon tray;
        printf ("trayicon_new\n");
        tray =(trayicon)g_malloc(sizeof(struct tray_struct));
        tray->manager_atom = XInternAtom (GDK_DISPLAY(), "MANAGER", False);
        tray->system_tray_opcode_atom = XInternAtom (GDK_DISPLAY(),
            "_NET_SYSTEM_TRAY_OPCODE", False);
        tray->icon_pixbuf=g_object_ref (default_icon);
        return tray;
    }
    
    
    int main (int argc, char *argv[])
    {
        gtk_init (&argc, &argv);
        trayicon tray;
        GdkPixbuf *pixbuf=gdk_pixbuf_new_from_file ("/home/bob/Download/gaim.png", 
            NULL);
        tray=trayicon_new(pixbuf);
        g_object_unref (pixbuf);
        create_tray_and_dock(tray);
        //dock_window(tray);
        trayicon_show (tray);
        expose(tray);
        gtk_main ();
        return 0;
    }

  2. #2
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    Is there an error message when you run it?

    Do you have a notification area on your toolbar? </dumb-question>

  3. #3
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Yep, I have a notification area. But this app just doesn't show up in the notification area.

    There are no error messages when I execute this app. It also appears in the system monitor in a sleeping state.

    BTW, I'm using Fedora 5 and version 2.14.0 of Notification area.

    Thanx

    Bob
    Last edited by BobS0327; 04-02-2006 at 07:30 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-05-2009, 10:25 AM
  2. problem with console app
    By Jumper in forum Windows Programming
    Replies: 0
    Last Post: 07-03-2004, 04:48 PM
  3. BIOS system and memory allocation problem
    By beely in forum Tech Board
    Replies: 9
    Last Post: 11-25-2003, 07:12 AM
  4. Problem Reporting System. Need Advide!
    By brunomiranda in forum Tech Board
    Replies: 9
    Last Post: 09-25-2003, 09:21 PM
  5. system tray help
    By ZerOrDie in forum Windows Programming
    Replies: 5
    Last Post: 03-10-2003, 05:05 PM