X11 Compositing: So erhalten Sie, wie Sie Ereignisse für umgeleitete Windows entdecken könnenLinux

Linux verstehen
Anonymous
 X11 Compositing: So erhalten Sie, wie Sie Ereignisse für umgeleitete Windows entdecken können

Post by Anonymous »

Ich entwickle eine Anwendung, um Overlays auf anderen Fenstern zu zeichnen. Um Alpha-Mischung durchzuführen, verwende ich die zusammengesetzte Erweiterung, um den Fenstergehalt zu einem PixMap umzuleiten. /> Version 0.4 des Protokolls verändert die Semantik des Ausschneidens im Vorhandensein von Manual Redirect -Kindern. In Version 0.3 wurde ein Elternteil immer
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.
Image

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.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post