How do I get the dimensions of the inner and outer window using Xlib / XCB?
Is there a reliable way to get the inner and outer rectangle of a top-level window with XCB / Xlib? (IOW frame and client rectangle).
Here's what I've tried:
-
xcb_get_geometry always returns the initial dimensions even after the window is resized (what gives?)
-
I figured I would call xcb_query_tree several times until I find the window frame window - is this a way to do this? I believe ICCCM / EWMH should provide this, but couldn't find anything. Is there any other standard / non-standard for this? It won't work with compiz / ubuntu10 anyway, because xcb_query_tree reports the client window as with root = parent (with normal ubuntu wm the window gets the parent correctly).
-
xcb_translate_coordinates () seemed to be the only reliable way to get root-based coords [1] in 2007 - is that still the case? That is, is XCB_CONFIGURE_NOTIFY non-standard with WM?
[1] http://fixunix.com/xwindows/91652-finding-position-top-level-windows.html
source to share
This is a partial answer as it only explains how to find the internal dimensions of a window. Also I'm not sure if this is the canonical path, but it works for me.
You can subscribe to the event XCB_EVENT_MASK_RESIZE_REDIRECT
when the window is created:
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);
In the event loop, you can track size changes:
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);
}
Note that I am not sure if this event is emitted when you trigger an app code resize with xcb_configure_window
eg. I've never tested it and just updated width
and height
in the wrapper functions for xcb_configure_window
.
source to share