an untergeordnete Fenster abgeschnitten, unabhängig von der Art der Umleitung. Dies bedeutet, dass der Elternteil in der untergeordneten Region zeichnen kann, ohne den Modus
includeIneriors zu verwenden.#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
return -1;
}
xcb_window_t wid = (xcb_window_t)strtoul(argv[1], NULL, 0);
xcb_connection_t *conn = xcb_connect(NULL, NULL);
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, wid), NULL);
xcb_window_t parent;
{
xcb_query_tree_reply_t *r = xcb_query_tree_reply(conn, xcb_query_tree(conn, wid), NULL);
parent = r->parent;
free(r);
}
// track damage:
xcb_damage_query_version(conn, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
uint8_t DAMAGE_EVENT = xcb_get_extension_data(conn, &xcb_damage_id)->first_event;
xcb_damage_damage_t damage = xcb_generate_id(conn);
xcb_damage_create(conn, damage, wid, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
//track expose (for child windows):
{
xcb_query_tree_reply_t *r = xcb_query_tree_reply(conn, xcb_query_tree_unchecked(conn, parent), NULL);
xcb_window_t *w = xcb_query_tree_children(r);
for (int i = 0; i < r->children_len; ++i) {
xcb_change_window_attributes(conn, w, XCB_CW_EVENT_MASK, (const uint32_t[]){XCB_EVENT_MASK_EXPOSURE});
}
free(r);
}
xcb_composite_redirect_window(conn, wid, XCB_COMPOSITE_REDIRECT_MANUAL);
xcb_pixmap_t pixmap = xcb_generate_id(conn);
xcb_composite_name_window_pixmap(conn, wid, pixmap);
xcb_gcontext_t gc = xcb_generate_id(conn);
xcb_create_gc(conn, gc, parent, XCB_GC_SUBWINDOW_MODE, (const uint32_t[]){XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS});
xcb_generic_event_t *event;
while ((event = xcb_wait_for_event(conn))) {
uint8_t type = XCB_EVENT_RESPONSE_TYPE(event);
if (type == DAMAGE_EVENT + XCB_DAMAGE_NOTIFY) {
xcb_damage_notify_event_t *e = (xcb_damage_notify_event_t *)event;
// repainting:
xcb_copy_area(conn, pixmap, parent, gc, e->area.x, e->area.y, geom->x + e->area.x, geom->y + e->area.y,
e->area.width, e->area.height);
xcb_damage_subtract(conn, e->damage, XCB_NONE, XCB_NONE);
xcb_flush(conn);
//printf("damage %d,%d %dx%d\n", e->area.x, e->area.y, e->area.width, e->area.height);
} else if (type == XCB_EXPOSE) { // x, geom->y, geom->width, geom->height);
xcb_flush(conn);
printf("expose %d,%d %dx%d\n", e->x, e->y, e->width, e->height);
}
free(event);
}
return -1;
}
< /code>
cc main.c -o main -lxcb-composite -lxcb-damage -lxcb
< /code>
When I drag another window inside the redirected window, that other window leaves traces of its content and I don't get any EXPOSE events.

I am currently using really bad workarounds, like tracking all other windows geometries and do repainting whenever geometries overlap. But this does not work in every situation and consumes a lot of CPU resources.