2010-10-11 4 views
3

Я хотел бы иметь ширину и высоту текущего фокусного окна. Выбор окна работает как шарм в то время как высота и ширина всегда возвращение 1.Xlib: XGetWindowAttributes всегда возвращает 1x1?

#include <X11/Xlib.h> 
#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    Display *display; 
    Window focus; 
    XWindowAttributes attr; 
    int revert; 

    display = XOpenDisplay(NULL); 
    XGetInputFocus(display, &focus, &revert); 
    XGetWindowAttributes(display, focus, &attr); 
    printf("[0x%x] %d x %d\n", (unsigned)focus, attr.width, attr.height); 

    return 0; 
} 

Разве это не «реальное» окно, но в настоящее время активный компонент (например, текстовое поле или кнопку?) И почему он должен иметь размер 1x1 в любом случае? Если это так, то как я могу получить главное окно приложения, содержащего этот элемент управления? Значит ... вид окна верхнего уровня, самого верхнего окна, кроме корневого окна.

PS: Не знаю, действительно ли это важно; Я использую Ubuntu 10.04 32 и 64 бит.

ответ

9

Вы правы - вы видите дочернее окно. Приложения GTK, в частности, создают дочернее окно под «реальным» окном, которое всегда 1x1, и всегда фокусируется, когда приложение имеет фокус. Если вы просто запускаете свою программу с помощью терминала GNOME, вы всегда будете видеть приложение GTK с фокусом (терминал).

Если вы запускаете свою программу таким образом, чтобы в программе, отличной от GTK, была фокус, тогда этого не происходит, но вы все равно можете найти дочернее окно с фокусом вместо верхнего уровня, уровня. (Один из способов сделать это, чтобы запустить sleep до вашей программы, как это: sleep 4; ./my_program - это дает вам шанс изменить фокус.)

Чтобы найти окно верхнего уровня, я думаю, что XQueryTree поможет - она ​​возвращает родительское окно.

Это работает для меня:

#include <X11/Xlib.h> 
#include <stdio.h> 
#include <stdlib.h> 

/* 
Returns the parent window of "window" (i.e. the ancestor of window 
that is a direct child of the root, or window itself if it is a direct child). 
If window is the root window, returns window. 
*/ 
Window get_toplevel_parent(Display * display, Window window) 
{ 
    Window parent; 
    Window root; 
    Window * children; 
    unsigned int num_children; 

    while (1) { 
     if (0 == XQueryTree(display, window, &root, 
        &parent, &children, &num_children)) { 
      fprintf(stderr, "XQueryTree error\n"); 
      abort(); //change to whatever error handling you prefer 
     } 
     if (children) { //must test for null 
      XFree(children); 
     } 
     if (window == root || parent == root) { 
      return window; 
     } 
     else { 
      window = parent; 
     } 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    Display *display; 
    Window focus, toplevel_parent_of_focus; 
    XWindowAttributes attr; 
    int revert; 

    display = XOpenDisplay(NULL); 
    XGetInputFocus(display, &focus, &revert); 
    toplevel_parent_of_focus = get_toplevel_parent(display, focus); 
    XGetWindowAttributes(display, toplevel_parent_of_focus, &attr); 
    printf("[0x%x] %d x %d\n", (unsigned)toplevel_parent_of_focus, 
     attr.width, attr.height); 

    return 0; 
} 
+0

принимает: спасибо Дуг. работает как шарм! :) С уважением – Atmocreations

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