开发者

Notification Area Protocol does not work in GNOME or KDE (Ubuntu 10.10 attempted)

I cannot for the life of me get the freedesktop.xorg "system tray" protocol specification to work with GNOME or KDE, even though I think they both support it. Unfortunately, I have had the same frustrating failure trying to post this issue to the archaic freedesktop.xorg Gmane newsgroup archiver (allowing me only 80 characters to explain my problem). Based alone on that mentality, I'm not surprised the following fails.

These are the only two window/desktop managers I have attempted (both Ubuntu 10.10). I am using:

GNOME version 2.32.0
KDE version 4.5.1

For GNOME, I get a little 2-pixel wide sliver next to my pandora "tray icon" when I execute the below program. For KDE, I get a gray icon. I would expect to see a non-uniform colored icon, or an all black icon, because I have only initialized the width and height of the buffer variable below, not the pixel values.

Unfortunately, after spending several hours on this, I have given up and decided not to support this feature. In case I'm just doing something stupid, I wanted to post this information here so others can learn from my mistake. Otherwise, if this is a bug, perhaps I will include this feature later when it is resolved. Regardless, I would be happy to try suggestions from others or attempt any lessons learned you may have.

I have referenced the following sites for guidance in resolving this (without solution):

http://kobelisk.de/files/doxygen/trayicon__x11_8cpp-source.html

http://libjdic-java.sourcearchive.com/documentation/0.9.5-6/Tray_8c-source.html

I have more hyperlinks, but since I'm new to this site I am un-allowed to post them.

I am well aware there are other libraries to accomplish this such as gtk. For my scenario, that is not in the domain of acceptable solutions.

Here is the command I used:

gcc -lX11 -lstdc++ -L/usr/X11/lib -o test test.cpp

And here is a generic program to re-create the problem (Ubuntu 10.10):

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#define WIDTH 16
#define HEIGHT 16

void send_message( Display* dpy, Window w,    long message, long data1 , long
data2 , long data3 )
{
    XEvent ev;

    memset (&ev, 0, sizeof (ev));
    ev.xclient.type = ClientMessage;
    ev.xclient.window = w;
    ev.xclient.message_type =
        XInternAtom (dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
    ev.xclient.format = 32;
    ev.xclient.data.l[0] = CurrentTime;
    ev.xclient.data.l[1] = message;
    ev.xclient.data.l[2] = data1;
    ev.xclient.data.l[3] = data2;
    ev.xclient.data.l[4] = data3;

    XSendEvent (dpy, w, False, NoEventMask, &ev);
    XSync (dpy, False);
}

int main( int argc, char **argv )
{

    unsigned int buffer[WIDTH * HEIGHT];
    Display *dis = XOpenDisplay(0);
    int s = DefaultScreen(dis);
    Atom net_wm_icon = XInternAtom(dis, "_NET_WM_ICON", False);
    Atom cardinal = XInternAtom(dis, "CARDINAL", False);
    Window win;
    XEvent e;
    XSizeHints *  size_hints;
    XWMHints   *  wm_hints;
    XClassHint *  class_hints;
    XTextProperty windowName, iconName;

    char *       window_name = "huh";
    char *       icon_name   = "huh";

    if ( !( size_hints  = XAllocSizeHints() ) || 
            !( wm_hints    = XAllocWMHints()   ) ||
            !( class_hints = XAllocClassHint() )    ) {
        fprintf(stderr, "Couldn't allocate memory.\n");
        return 0;
    }

    //win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, 0,
BlackPixel (dis, 0), BlackPixel(dis, 0));
    //w = XCreateWindow(d, RootWindow(d, s), 0, 0, 200, 200, 0,
    //                  CopyFromParent, InputOutput, CopyFromParent, 0, 0);

    win = XCreateWindow(dis,RootWindow(dis,0), 0,0,10,10,1, CopyFromParent,
CopyFromParent, CopyFromParent, 0, 0);   

    if ( XStringListToTextProperty(&window_name, 1, &windowName) == 0 ) {
        fprintf(stderr, "%s: structure allocation for windowName failed.\n",
                "yo");
        return 0;
    }

    if ( XStringListToTextProperty(&icon_name, 1, &iconName) == 0 ) {
        fprintf(stderr, "%s: structure allocation for iconName failed.\n",
                "yo");
        return 0;
    }

    size_hints->flags       = PPosition | PSize | PMinSize;
    size_hints->min_width   = 1;
    size_hints->min_height  = 1;

    wm_hints->flags         = StateHint | InputHint | IconPixmapHint |
IconMaskHint; // | WindowGroupHint;
    wm_hints->initial_state = NormalState;
    wm_hints->input         = True;
    wm_hints->icon_pixmap   = XCreatePixmap(dis, win, WIDTH, HEIGHT,
DefaultDepth(dis, s));
    wm_hints->icon_mask     = XCreatePixmap(dis, win, WIDTH, HEIGHT,
DefaultDepth(dis, s));
    //wm_hints->window_group  = bla;

    class_hints->res_name   = "huh";
    class_hints->res_class  = "huh";

    XSetWMProperties(dis, win, &windowName, &iconName, NULL, 0,
            size_hints, wm_hints, class_hints);

    int length = 2 + WID开发者_运维百科TH * HEIGHT + 2 + WIDTH * HEIGHT;
    buffer[0] = WIDTH;
    buffer[1] = HEIGHT;
    XChangeProperty(dis, win, net_wm_icon, cardinal, 32,
                     PropModeReplace, (const unsigned char*) buffer, length);


    XSync(dis, false);
    XFlush(dis);

    XMapWindow(dis, win);
    int data[2];
    data[0] = 0;
    data[1] = 1;

    Atom net_system_tray = XInternAtom(dis,"_NET_SYSTEM_TRAY_S0",False);
    Atom embed_type = XInternAtom(dis,"_XEMBED_INFO",False);

    Window tray_owner = XGetSelectionOwner(dis,net_system_tray);

    XChangeProperty(dis,win,embed_type,embed_type,32,PropModeReplace,(const
unsigned char *)data,2);
    send_message(dis,tray_owner,0,win,0,0);
    XSync(dis,False);

    while(1) XNextEvent(dis, &e);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜