通知区域协议在 GNOME 或 KDE 中不起作用(已尝试 Ubuntu 10.10)

发布于 2024-10-22 00:05:43 字数 5091 浏览 4 评论 0原文

我一生都无法获得 freedesktop.xorg“系统托盘”协议 与 GNOME 或 KDE 一起使用的规范,尽管我认为它们都支持 它。不幸的是,我在尝试将此问题发布到过时的 freedesktop.xorg Gmane 新闻组存档器时也遇到了同样令人沮丧的失败(只允许我使用 80 个字符来解释我的问题)。仅基于这种心态,我对以下失败并不感到惊讶。

这是我尝试过的仅有的两个窗口/桌面管理器(均为 Ubuntu 10.10)。我正在使用:

GNOME version 2.32.0
KDE version 4.5.1

对于 GNOME,我的 pandora“托盘图标”旁边有一个 2 像素宽的小条子 当我执行下面的程序时。对于 KDE,我看到一个灰色图标。我期望 看到一个不均匀的彩色图标,或一个全黑的图标,因为我只有 初始化了下面缓冲区变量的宽度和高度,而不是像素值。

不幸的是,在花了几个小时之后,我放弃了并决定 不支持此功能。万一我只是做了一些愚蠢的事情,我想要 在此发布此信息,以便其他人可以从我的错误中吸取教训。否则, 如果这是一个错误,也许我会在解决后添加此功能。无论如何,我很乐意尝试其他人的建议或尝试您可能学到的任何经验教训。

我已经参考了以下网站来获取解决此问题的指导(没有 解决方案):

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

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

我有更多超链接,但由于我是这个网站的新手,所以不允许我发布它们。

我很清楚还有其他库可以完成此任务,例如 gtk。对于我的场景,这不属于可接受的解决方案范围。

这是我使用的命令:

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

这是一个重现问题的通用程序(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 + WIDTH * 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);
}

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 + WIDTH * 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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文