2010-10-23 2 views
1

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

Image

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

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

Я использую Xlib, между прочим.

ответ

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; 
} 

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

3

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

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

Смежные вопросы