freedesktop.xorg の「システム トレイ」プロトコル仕様を GNOME または KDE で動作させることはできません。どちらもサポートしていると思いますが。残念ながら、私はこの問題を古風な freedesktop.xorg Gmane ニュースグループ アーカイバに投稿しようとして同じようにイライラする失敗を経験しました (私の問題を説明するのに 80 文字しか許されませんでした)。その考え方だけに基づいて、次のことが失敗しても不思議ではありません。
これらは、私が試みた唯一の 2 つのウィンドウ/デスクトップ マネージャーです (どちらも Ubuntu 10.10)。私は使っている:
GNOME version 2.32.0
KDE version 4.5.1
GNOME の場合、以下のプログラムを実行すると、パンドラの「トレイ アイコン」の横に 2 ピクセル幅の小さなスライバーが表示されます。KDE の場合、灰色のアイコンが表示されます。 ピクセル値ではなく、以下のバッファー変数の幅と高さのみを初期化したため、不均一な色のアイコン、またはすべて黒のアイコンが表示されることが予想されます。
残念ながら、これに数時間を費やした後、あきらめて、この機能をサポートしないことにしました。私がばかげたことをしている場合に備えて、この情報をここに投稿して、他の人が私の過ちから学ぶことができるようにしたいと思いました. それ以外の場合、これがバグである場合は、後で解決されたときにこの機能を含める予定です。とにかく、他の人からの提案を試したり、あなたが学んだ教訓を試したりしたいと思います.
これを解決するためのガイダンスとして、次のサイトを参照しました (解決策なし)。
http://koberisk.de/files/doxygen/trayicon__x11_8cpp-source.html
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);
}