diff --git a/src/common.h b/src/common.h index 9fc4a6d..08e972a 100644 --- a/src/common.h +++ b/src/common.h @@ -229,8 +229,8 @@ typedef struct session { bool reset:1; /// If compton should quit bool quit:1; - /// If new window has been added and not been handled - bool has_new_window:1; + /// Whether there are pending updates, like window creation, etc. + bool pending_updates:1; // === Expose event related === /// Pointer to an array of XRectangle-s of exposed region. diff --git a/src/compton.c b/src/compton.c index 366a85b..5023387 100644 --- a/src/compton.c +++ b/src/compton.c @@ -503,21 +503,6 @@ static struct managed_win *paint_preprocess(session_t *ps, bool *fade_running) { // log_trace("%s %d %d %d", w->name, to_paint, w->opacity, // w->paint_excluded); - if ((w->flags & WIN_FLAGS_IMAGE_STALE) != 0 && - (w->flags & WIN_FLAGS_IMAGE_ERROR) == 0 && to_paint) { - // Image needs to be updated, update it. - w->flags &= ~WIN_FLAGS_IMAGE_STALE; - if (w->state != WSTATE_UNMAPPING && - w->state != WSTATE_DESTROYING && ps->redirected) { - // Rebind image only when the window does have an image - // available - if (!win_try_rebind_image(ps, w)) { - w->flags |= WIN_FLAGS_IMAGE_ERROR; - to_paint = false; - } - } - } - // Add window to damaged area if its painting status changes // or opacity changes if (to_paint != was_painted) { @@ -1222,7 +1207,24 @@ static void handle_new_windows(session_t *ps) { } } } - ps->has_new_window = false; +} + +static void refresh_stale_images(session_t *ps) { + win_stack_foreach_managed(w, &ps->window_stack) { + if ((w->flags & WIN_FLAGS_IMAGE_STALE) != 0 && + (w->flags & WIN_FLAGS_IMAGE_ERROR) == 0) { + // Image needs to be updated, update it. + w->flags &= ~WIN_FLAGS_IMAGE_STALE; + if (w->state != WSTATE_UNMAPPING && + w->state != WSTATE_DESTROYING && ps->redirected) { + // Rebind image only when the window does have an image + // available + if (!win_try_rebind_image(ps, w)) { + w->flags |= WIN_FLAGS_IMAGE_ERROR; + } + } + } + } } /** @@ -1240,9 +1242,8 @@ static void fade_timer_callback(EV_P_ ev_timer *w, int revents) { } static void _draw_callback(EV_P_ session_t *ps, int revents) { - if (ps->has_new_window) { - log_debug("Delayed handling of new window events, entering critical " - "section"); + if (ps->pending_updates) { + log_debug("Delayed handling of events, entering critical section"); auto e = xcb_request_check(ps->c, xcb_grab_server_checked(ps->c)); if (e) { log_fatal("failed to grab x server"); @@ -1257,6 +1258,9 @@ static void _draw_callback(EV_P_ session_t *ps, int revents) { // Call fill_win on new windows handle_new_windows(ps); + // Refresh pixmaps + refresh_stale_images(ps); + e = xcb_request_check(ps->c, xcb_ungrab_server_checked(ps->c)); if (e) { log_fatal("failed to ungrab x server"); @@ -1264,6 +1268,8 @@ static void _draw_callback(EV_P_ session_t *ps, int revents) { e->error_code); return quit_compton(ps); } + + ps->pending_updates = false; log_debug("Exiting critical section"); } diff --git a/src/win.c b/src/win.c index 377b02a..712a052 100644 --- a/src/win.c +++ b/src/win.c @@ -796,6 +796,7 @@ void win_on_win_size_change(session_t *ps, struct managed_win *w) { if (w->state == WSTATE_MAPPED || w->state == WSTATE_MAPPING || w->state == WSTATE_FADING) { w->flags |= WIN_FLAGS_IMAGE_STALE; + ps->pending_updates = true; } else { assert(w->state == WSTATE_UNMAPPED); } @@ -966,7 +967,7 @@ static struct win *add_win(session_t *ps, xcb_window_t id, struct list_node *pre new_w->destroyed = false; HASH_ADD_INT(ps->windows, id, new_w); - ps->has_new_window = true; + ps->pending_updates = true; return new_w; } @@ -1462,6 +1463,7 @@ void win_update_bounding_shape(session_t *ps, struct managed_win *w) { // otherwise win_data is not valid assert(w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING); w->flags |= WIN_FLAGS_IMAGE_STALE; + ps->pending_updates = true; } free_paint(ps, &w->paint); free_paint(ps, &w->shadow_paint);