Узнайте размер панели с помощью Xlib - PullRequest
1 голос
/ 23 октября 2010

Я пишу приложение, которое ставит доки в правой части экрана, например:

image

Я могу зарезервировать пространство в боковой части экрана, используя_NET_WM_STRUT_PARTIAL, чтобы развернутые окна не перекрывали доки.

На изображении видно, что есть верхняя панель.Проблема в том, что доки будут перекрывать панель .Есть ли способ узнать размер панели или сделать так, чтобы панель уменьшала пространство, открываемое докам?

Кстати, я использую Xlib.

Ответы [ 2 ]

3 голосов
/ 24 октября 2010

Полагаю, вам придется отслеживать все окна верхнего уровня, которые появляются и имеют ли они _NET_WM_STRUT_PARTIAL, чтобы самостоятельно вычислять рабочую область, за исключением ваших собственных окон.Вы можете посмотреть в коде libwnck, как отслеживать все верхние уровни, и посмотреть, как оконные менеджеры вычисляют _NET_WORKAREA, чтобы увидеть, как это сделать.Затем повторите эту работу, но минус ваши собственные распорки.Одна из проблем заключается в том, что если бы каждая панель делала это, был бы бесконечный цикл, когда все они работали друг вокруг друга.Но вы можете предположить, что у людей есть только панель рабочего стола по умолчанию, которая этого не делает, плюс ваша.

Другой вариант может состоять в том, чтобы просто сделать окно вашей панели всегда полной высоты экрана, но если какое-либо окно находится вышеВы смещаете то, что рисуете (и смещаете обработку событий), на немного.Проблема в том, что трудно отследить, как окна перекрывают вас.XVisibilityEvent немного помогает, но не говорит вам, когда окно сверху просто перемещается.Также вы должны быть уверены, что не сломаетесь, если, скажем, полноэкранный фильм в конечном итоге охватит всю панель.Я полагаю, что при таком подходе вы все равно будете сканировать все верхние уровни для панелей, как при первом подходе.

0 голосов
/ 26 октября 2010

Используя хороший совет, данный 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;
}

Может бытькрасиво, но работает: -)

...