次のように、ドックを画面の右側に配置するアプリケーションを作成しています。
_NET_WM_STRUT_PARTIAL
最大化されたウィンドウがドックに重ならないように、を使用して画面の横にスペースを確保できます。
画像では、トップパネルがあることがわかります。問題は、ドックがパネルに重なることです。パネルのサイズを確認する方法、またはパネルを縮小してドックにスペースを空ける方法を作成する方法はありますか?
ちなみに、私はXlibを使用しています。
自分のウィンドウを除いて自分で作業領域を計算するには、表示されるすべてのトップレベルウィンドウと、それらに_NET_WM_STRUT_PARTIALがあるかどうかを追跡する必要があると思います。すべてのトップレベルを追跡する方法についてはlibwnckコードを確認し、ウィンドウマネージャーが_NET_WORKAREAを計算する方法を確認してその方法を確認することができます。次に、その作業をやり直しますが、自分の支柱を差し引いてください。これに関する1つの問題は、すべてのパネルがそれを実行した場合、それらがすべて互いに動作する無限ループが発生することです。しかし、あなたはおそらく、人々がこれを行わないデフォルトのデスクトップパネルとあなたのものしか持っていないと仮定することができます。
別のオプションとして、パネルのウィンドウを常に全画面の高さにすることもできますが、ウィンドウが上にある場合は、描画したものを少しオフセットします(イベント処理をオフセットします)。問題は、ウィンドウがどのように重なっているのかを追跡するのが難しいことです。XVisibilityEventは少し役立ちますが、上部のウィンドウがいつ移動するかはわかりません。また、フルスクリーンの映画がパネル全体をカバーすることになった場合は、壊れないようにする必要があります。このアプローチでは、最初のアプローチと同じように、おそらくすべてのトップレベルでパネルをスキャンすることになります。
Havoc Pによって提供された優れたヒントを使用することで、上部ドッキングパネルの高さを返すこのコードを作成することができました。
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
static Display* display;
// looks for the maximum "docking height" of all children of this window
static int top_panel_height(Window window)
{
int height = 0; // maximum height
Window w;
Window* children;
unsigned int n_children;
XQueryTree(display, window, &w, &w, &children, &n_children);
// looks for each one of the children
int i;
for(i=0; i<n_children; i++)
{
// this is the property we're looking for
Atom strut = XInternAtom(display, "_NET_WM_STRUT_PARTIAL",
False);
Atom type_return;
int actual_type;
unsigned long nitems, bytes;
unsigned char* data = NULL;
// load window attributes (we only want to know about the
// windows where y = 0)
XWindowAttributes xwa;
XGetWindowAttributes(display, window, &xwa);
// load the property _NET_WM_STRUT_PARTIAL
int s = XGetWindowProperty(display, window, strut, 0, LONG_MAX,
False,
XA_CARDINAL, &type_return, &actual_type,
&nitems, &bytes, (unsigned char**)&data);
if(s == Success)
{
Atom *state = (Atom *) data;
// state[2] contains the "dock height"
if(xwa.y == 0 && nitems > 0 && state[2])
if(state[2] > height)
height = state[2];
}
// recursively, traverse the tree of all children of children
int children_max_height = top_panel_height(children[i]);
if(children_max_height > height)
height = children_max_height;
}
return height;
}
int main()
{
display = XOpenDisplay(NULL);
Window root = RootWindow(display, DefaultScreen(display));
printf("%d\n", top_panel_height(root));
return 0;
}
きれいではないかもしれませんが、うまくいきます:-)