diff --git a/src/common.h b/src/common.h index 542c31f..8a0dd5b 100644 --- a/src/common.h +++ b/src/common.h @@ -230,6 +230,10 @@ typedef struct session { bool tmout_unredir_hit; /// Whether we need to redraw the screen bool redraw_needed; + + /// Cache a xfixes region so we don't need to allocate it everytime. + /// A workaround for yshui/picom#301 + xcb_xfixes_region_t damaged_region; /// The region needs to painted on next paint. region_t *damage; /// The region damaged on the last paint. diff --git a/src/event.c b/src/event.c index 3be46e4..dbba814 100644 --- a/src/event.c +++ b/src/event.c @@ -590,11 +590,9 @@ static inline void repair_win(session_t *ps, struct managed_win *w) { set_ignore_cookie( ps, xcb_damage_subtract(ps->c, w->damage, XCB_NONE, XCB_NONE)); } else { - xcb_xfixes_region_t tmp = x_new_id(ps->c); - xcb_xfixes_create_region(ps->c, tmp, 0, NULL); - set_ignore_cookie(ps, xcb_damage_subtract(ps->c, w->damage, XCB_NONE, tmp)); - x_fetch_region(ps->c, tmp, &parts); - xcb_xfixes_destroy_region(ps->c, tmp); + set_ignore_cookie( + ps, xcb_damage_subtract(ps->c, w->damage, XCB_NONE, ps->damaged_region)); + x_fetch_region(ps->c, ps->damaged_region, &parts); pixman_region32_translate(&parts, w->g.x + w->g.border_width, w->g.y + w->g.border_width); } diff --git a/src/picom.c b/src/picom.c index cff2707..61be577 100644 --- a/src/picom.c +++ b/src/picom.c @@ -1742,6 +1742,12 @@ static session_t *session_init(int argc, char **argv, Display *dpy, XCB_XFIXES_MINOR_VERSION) .sequence); + ps->damaged_region = x_new_id(ps->c); + if (!XCB_AWAIT_VOID(xcb_xfixes_create_region, ps->c, ps->damaged_region, 0, NULL)) { + log_fatal("Failed to create a XFixes region"); + goto err; + } + ext_info = xcb_get_extension_data(ps->c, &xcb_glx_id); if (ext_info && ext_info->present) { ps->glx_exists = true; @@ -2268,6 +2274,11 @@ static void session_destroy(session_t *ps) { ps->debug_window = XCB_NONE; } + if (ps->damaged_region != XCB_NONE) { + xcb_xfixes_destroy_region(ps->c, ps->damaged_region); + ps->damaged_region = XCB_NONE; + } + if (ps->o.experimental_backends) { // backend is deinitialized in unredirect() assert(ps->backend_data == NULL);