我正在编写一个将停靠点放在屏幕右侧的应用程序,如下所示:
我可以使用_NET_WM_STRUT_PARTIAL
在屏幕一侧预留空间,以便最大化的窗口不会与底座重叠。
在图片中,您可以看到有一个顶部面板。问题是码头将与面板重叠。有没有办法找出面板的大小,或者让面板减少到开放空间到码头?
顺便说一句,我正在使用Xlib。
答案 0 :(得分:3)
我猜你必须跟踪出现的所有顶级窗口以及它们是否有_NET_WM_STRUT_PARTIAL以便自己计算工作区域,减去你自己的窗口。您可以查看libwnck代码以了解如何跟踪所有顶层,并查看窗口管理器如何计算_NET_WORKAREA,以了解如何执行此操作。然后重做那个工作,但减去你自己的支柱。这个问题的一个问题是,如果每个小组都这样做,就会有一个无限循环,它们都在相互作用。但是你可以假设人们只有一个默认的桌面面板不能这样做,加上你的。
另一种选择可能是让您的面板窗口始终为全屏高度,但如果任何窗口位于您上方,则将您绘制的内容(以及偏移事件处理)向下偏移一点。问题是很难跟踪窗户是如何重叠的。 XVisibilityEvent有点帮助,但没有告诉你什么时候顶部的窗口移动。如果全屏电影最终覆盖整个面板,你也必须确保不要破坏。我想用这种方法你可能仍然会扫描面板的所有顶层,就像第一种方法一样。
答案 1 :(得分:0)
通过使用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;
}
可能不太漂亮,但它有效: - )