Search code examples
qtx11xlibxserver

Position toolbar on reserved desktop space obtained with _NET_WM_STRUT and _NET_WM_STRUT_PARTIAL


I am new to x11 calls.

I am developing a custom applications toolbar using QT 4.8 on a SLED11.

I have a problem with positioning my toolbar on a reserved space obtained with x11 call (_NET_WM_STRUT and _NET_WM_STRUT_PARTIAL)

Looking on some forums I understood that I have to reserve the toolbar area so other application windows cannot cover it. I used _NET_WM_STRUT and _NET_WM_STRUT_PARTIAL.

This is the code I use for reserving the space:

void ToolbarWindow::dock(int width, int height)
{
   Display *display  = QX11Info::display();

   int insets[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
   insets[2] = height;
   insets[8] = 0;
   insets[9] = width;

   XChangeProperty(display,
                winId(),
                XInternAtom(QX11Info::display(), "_NET_WM_STRUT", False),
                XA_CARDINAL ,
                32,
                PropModeReplace,
                (unsigned char *)&insets, 4);

   XChangeProperty(display,
                 winId(),
                XInternAtom(QX11Info::display(), "_NET_WM_STRUT_PARTIAL", False),
                XA_CARDINAL ,
                32,
                PropModeReplace,
                (unsigned char *)&insets, 12);

}

And this is my call on the GUI controller when i create the toolbar:

ToolbarWindow *toolbar = new ToolbarWindow(co);

toolbar->setGeometry(monitor->getX(), monitor->getY(), monitor->getWidth(), 170);
toolbar->show();

toolbar->dock(monitor->getWidth(), 170);

What I see is that the space is reserved, but my toolbar appear beneath the reserved area. But this is not what i want, I would like to have all the other windows to stay beneath (even when maximized) but not my toolbar...i reserved the space for it and I want it to fill that space...

Can anyone help me?

Thanks.


Solution

  • The n.m.' answer is correct.

    I have found that for this to work reliably, the window should be of type _NET_WM_TYPE_DOCK and you must first map it then move it to position, otherwise the WM may sometimes place it outside of it own strut. – n.m.

    This is the code I added:

    Atom tmp = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK", False);
    XChangeProperty(display,
                    winId(),
                    XInternAtom(display, "_NET_WM_WINDOW_TYPE", False),
                    XA_ATOM ,
                    32,
                    PropModeReplace,
                    (unsigned char *)&tmp, 1);
    

    Thanks a lot.