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



LinkBack URL
About LinkBacks


