2015-07-03 10 views
3

Есть ли надежный способ получить внутренний и внешний прямоугольник верхнего окна с XCB/Xlib? (Кадр IOW и клиентский прямоугольник).Как получить размеры внутреннего и внешнего окна с помощью Xlib/XCB?

Вот что я пробовал:

  • xcb_get_geometry всегда возвращает первоначальные размеры, даже после того, как окно получает Отмасштабированные (что дает?)

  • Я полагал, что я бы назвал xcb_query_tree нескольких раз, пока я не найти Окно окна окна - это способ сделать это? Я полагаю, что ICCCM/EWMH должен предоставить это, но ничего не мог найти. Есть ли какой-либо другой стандарт/нестандарт для этого? Во всяком случае, это не работает с compiz/ubuntu10, потому что xcb_query_tree сообщает клиентскому окну как с корнем = родительский (при нормальном ubuntu wm окно правильно получается ).

  • xcb_translate_coordinates(), казалось, был единственным надежным способом для получить root-based coords [1] в 2007 году - это все еще так? То есть XCB_CONFIGURE_NOTIFY нестандартный с WM?

[1] http://fixunix.com/xwindows/91652-finding-position-top-level-windows.html

ответ

2

Это частичный ответ, как это только объясняет, как найти внутренние размеры окна. Также я не уверен, что это канонический путь, но он работает для меня.

Вы можете подписаться на XCB_EVENT_MASK_RESIZE_REDIRECT события при создании окна:

xcb_window_t   window = xcb_generate_id   (connection); 
const xcb_setup_t  *setup  = xcb_get_setup   (connection); 
xcb_screen_t   *screen = xcb_setup_roots_iterator (setup).data; 
uint32_t    mask  = XCB_CW_EVENT_MASK; 
uint32_t    valwin[1] = { XCB_EVENT_MASK_EXPOSURE 
            | XCB_EVENT_MASK_RESIZE_REDIRECT }; 

xcb_create_window(
    connection, 
    XCB_COPY_FROM_PARENT, 
    window, 
    screen->root, 
    0, 0, 
    800, 600, 
    0, 
    XCB_WINDOW_CLASS_INPUT_OUTPUT, 
    screen->root_visual, 
    mask, valwin); 
xcb_map_window(connection, window); 
xcb_flush(connection); 

В цикле событий, то вы можете отслеживать изменяет размеры:

xcb_generic_event_t *event; 
uint16_t width = 0, height = 0; 
while ((event = xcb_wait_for_event(connection)) != NULL) { 
    switch (event->response_type & ~0x80) { 
    case XCB_EXPOSE: { 
     /* ... */ 
     break; 
    } 
    case XCB_RESIZE_REQUEST: { 
     auto resize = (xcb_resize_request_event_t*) event; 
     if (resize->width > 0) width = resize->width; 
     if (resize->height > 0) height = resize->height; 
     break; 
    } 
    default: 
     break; 
    } 
    free(event); 
    xcb_flush(connection); 
} 

Обратите внимание, что я не уверен, является ли это событие выдается, когда вы инициируете изменение размера из вашего кода приложения, например, с помощью xcb_configure_window. Я никогда не тестировал его и просто обновлял width и height в функции обертки для xcb_configure_window.