文字列プロパティ
NetWM において、クライアントウィンドウに設定する文字列プロパティには、以下のものがあります。
ICCCM では、プロパティの文字列は基本的に TEXT タイプでしたが、NetWM では、UTF-8 文字列で設定します。
(type = "UTF8_STRING", format = 8)。
※UTF-8 文字列も含め、プロパティに文字列を設定する場合、終端のヌル文字は必要ありません。
_NET_WM_NAME | ウィンドウタイトルとして表示されます。 WM_NAME より優先されます。 |
---|---|
_NET_WM_ICON | アイコン化状態のタイトルとして表示されます。 WM_ICON_NAME より優先されます。 |
_NET_WM_VISIBLE_NAME | _NET_WM_NAME とは異なるタイトルを表示したい場合。 |
_NET_WM_VISIBLE_ICON_NAME | _NET_WM_ICON とは異なるアイコンタイトルを表示したい場合。 |
ICCCM では、プロパティの文字列は基本的に TEXT タイプでしたが、NetWM では、UTF-8 文字列で設定します。
(type = "UTF8_STRING", format = 8)。
※UTF-8 文字列も含め、プロパティに文字列を設定する場合、終端のヌル文字は必要ありません。
装飾フレームの幅を取得
ウィンドウの最初のマップ後、ウィンドウマネージャによって装飾フレームウィンドウが作成された後に、クライアントウィンドウの _NET_FRAME_EXTENTS プロパティを読み込むと、その装飾フレームの各幅を取得することができます。
(type = "CARDINAL", format = 32)
※CARDINAL は、整数を意味しています。
4個の数値の配列になっており、left, right, top, bottom の順で、各辺の幅 (px) が入っています。
この値を使うと、クライアントウィンドウの左上のルート座標から、フレームウィンドウの左上のルート座標を計算できます。
(type = "CARDINAL", format = 32)
※CARDINAL は、整数を意味しています。
4個の数値の配列になっており、left, right, top, bottom の順で、各辺の幅 (px) が入っています。
この値を使うと、クライアントウィンドウの左上のルート座標から、フレームウィンドウの左上のルート座標を計算できます。
ウィンドウのアイコン
タイトルバーやタスクバーに表示されるような、ウィンドウのアイコン画像を、ARGB イメージで設定できます。
クライアントウィンドウの _NET_WM_ICON プロパティに、type = "CARDIAL", format = 32 で、イメージデータの配列を設定します。
アイコンは、複数のサイズ (幅&高さ) のイメージを、複数個設定できます。
このプロパティを読み込むウィンドウマネージャなどは、このアイコンデータの中から、適切なサイズのアイコンを取得して、表示することができます。
※必要なサイズに合うアイコンがない場合は、拡大縮小して表示される場合があります。
通常は、16〜128 px 程度の複数のアイコンをセットしますが、一つのサイズでも構いません。
クライアントウィンドウの _NET_WM_ICON プロパティに、type = "CARDIAL", format = 32 で、イメージデータの配列を設定します。
アイコンは、複数のサイズ (幅&高さ) のイメージを、複数個設定できます。
このプロパティを読み込むウィンドウマネージャなどは、このアイコンデータの中から、適切なサイズのアイコンを取得して、表示することができます。
※必要なサイズに合うアイコンがない場合は、拡大縮小して表示される場合があります。
通常は、16〜128 px 程度の複数のアイコンをセットしますが、一つのサイズでも構いません。
一つのリクエスト (XChangeProperty) で送信できるデータサイズは制限されています。
X.Org 実装では、65535 x 4 byte までです (format = 32 のデータは、4 byte として扱います)。
つまり、256 x 256 px のアイコンイメージは、一度の XChangeProperty 関数では送れないので、注意してください。
X.Org 実装では、65535 x 4 byte までです (format = 32 のデータは、4 byte として扱います)。
つまり、256 x 256 px のアイコンイメージは、一度の XChangeProperty 関数では送れないので、注意してください。
データ
format = 32 なので、long 型の配列で、データを用意します。
※64bit OS の場合、実際に必要なデータは 32bit で十分ですが、プロパティに値をセットする時は、64bit の数値配列としてデータを用意する必要があります。
一つのサイズのアイコンごとに、以下の値をセットします。
複数のアイコンがある場合は、続けて2つ目以降のデータを追加します。
※64bit OS の場合、実際に必要なデータは 32bit で十分ですが、プロパティに値をセットする時は、64bit の数値配列としてデータを用意する必要があります。
一つのサイズのアイコンごとに、以下の値をセットします。
- 最初の値は、イメージの幅 (px)
- 2番目の値は、イメージの高さ (px)
- 3番目以降は、幅 x 高さのイメージデータ (ARGB)。
32bit の 0xAARRGGBB 形式で、1px ごとに、左上から右下の順で ARGB 値を並べます。
複数のアイコンがある場合は、続けて2つ目以降のデータを追加します。
プログラム
ウィンドウタイトルとアイコンをセットします。
マップ時に、装飾フレームの幅を表示します。
アイコンを表示する時のサイズが 16x16 に近い方は赤いアイコンになり、それより大きい場合 (Alt+Tab 時など) は、青いアイコンになるのを確認してください。
<d09-winprop.c>
マップ時に、装飾フレームの幅を表示します。
アイコンを表示する時のサイズが 16x16 に近い方は赤いアイコンになり、それより大きい場合 (Alt+Tab 時など) は、青いアイコンになるのを確認してください。
$ cc -o run d09-winprop.c util.c -lX11
<d09-winprop.c>
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include "util.h" /* UTF8_STRING プロパティセット */ static void _setprop_utf8(Display *disp,Window win,Atom prop,const char *str) { XChangeProperty(disp, win, prop, GET_ATOM("UTF8_STRING"), 8, PropModeReplace, (unsigned char *)str, strlen(str)); } /* アイコンイメージセット */ static void _set_icon(Display *disp,Window win) { unsigned long *buf,*pd; int i; Atom prop; prop = GET_ATOM("_NET_WM_ICON"); buf = (unsigned long *)malloc((2 + 32 * 32) * sizeof(long)); //16x16 (赤) buf[0] = buf[1] = 16; pd = buf + 2; for(i = 0; i < 16 * 16; i++) *(pd++) = 0xffff0000; XChangeProperty(disp, win, prop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)buf, 2 + 16 * 16); //32x32 を追加 (青、半透明) buf[0] = buf[1] = 32; pd = buf + 2; for(i = 0; i < 32 * 32; i++) *(pd++) = 0x800000ff; XChangeProperty(disp, win, prop, XA_CARDINAL, 32, PropModeAppend, (unsigned char *)buf, 2 + 32 * 32); free(buf); } int main(int argc,char **argv) { Display *disp; Window win; XEvent ev; long *buf; int num; disp = XOpenDisplay(NULL); if(!disp) return 1; set_display(disp); win = create_test_window2(disp, 200, 200, 0, ButtonPressMask | StructureNotifyMask); _setprop_utf8(disp, win, GET_ATOM("_NET_WM_NAME"), "タイトル"); _setprop_utf8(disp, win, GET_ATOM("_NET_WM_ICON_NAME"), "ICONタイトル"); _setprop_utf8(disp, win, GET_ATOM("_NET_WM_VISIBLE_NAME"), "タイトル[1]"); _setprop_utf8(disp, win, GET_ATOM("_NET_WM_VISIBLE_ICON_NAME"), "ICONタイトル[1]"); _set_icon(disp, win); //イベント XMapWindow(disp, win); while(1) { XNextEvent(disp, &ev); if(event_quit(&ev)) break; switch(ev.type) { case MapNotify: buf = (long *)read_prop32(win, GET_ATOM("_NET_FRAME_EXTENTS"), XA_CARDINAL, &num); if(buf) { printf("[_NET_FRAME_EXTENTS] left:%ld, right:%ld, top:%ld, bottom:%ld\n", buf[0], buf[1], buf[2], buf[3]); XFree(buf); } break; } } XCloseDisplay(disp); return 0; }
_NET_WM_STRUT/_NET_WM_STRUT_PARTIAL
タスクバーやランチャなど、画面の一部を占領するようなアプリケーションを作りたい場合は、そのウィンドウに _NET_WM_STRUT または _NET_WM_STRUT_PARTIAL プロパティを設定して、ウィンドウが画面内で占領する領域を指定する必要があります。
(type = "CARDINAL", format = 32)
_NET_WM_STRUT_PARTIAL は、_NET_WM_STRUT よりも後に定義されており、追加の値を指定することができます。
_NET_WM_STRUT_PARTIAL をサポートしていないウィンドウマネージャのために、_NET_WM_STRUT も同時に設定することができます。
left, right, top, bottom は、画面のそれぞれの端で確保する幅です。
*_x, *_y は、それぞれの端で、どの位置からどの位置までを占領するかの座標です。
(type = "CARDINAL", format = 32)
_NET_WM_STRUT_PARTIAL は、_NET_WM_STRUT よりも後に定義されており、追加の値を指定することができます。
_NET_WM_STRUT_PARTIAL をサポートしていないウィンドウマネージャのために、_NET_WM_STRUT も同時に設定することができます。
_NET_WM_STRUT | 4個の配列。 left, right, top, bottom |
---|---|
_NET_WM_STRUT_PARTIAL | 12個の配列。 left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x |
left, right, top, bottom は、画面のそれぞれの端で確保する幅です。
*_x, *_y は、それぞれの端で、どの位置からどの位置までを占領するかの座標です。