From f476a78ad1860d65bbabfd686af9f0d988f50a8a Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Fri, 23 Oct 2020 04:11:52 +0100 Subject: [PATCH] event: don't eagerly add damage for configure notify If a window receives multiple configure notifies in between 2 frames, we add all the in between positions into damage, when we really just need the starting and the end position. Signed-off-by: Yuxuan Shui --- src/event.c | 41 ++++++++++++++++++++++++----------------- src/win.c | 14 ++++++++++++++ src/win_defs.h | 4 +++- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/event.c b/src/event.c index 7002183..f4defed 100644 --- a/src/event.c +++ b/src/event.c @@ -212,19 +212,33 @@ static void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) { // If window geometry change, free old extents if (mw->g.x != ce->x || mw->g.y != ce->y || mw->g.width != ce->width || mw->g.height != ce->height || mw->g.border_width != ce->border_width) { - region_t damage, new_extents; - pixman_region32_init(&damage); - pixman_region32_init(&new_extents); - - // Get the old window extents - win_extents(mw, &damage); + // We don't mark the old region as damaged if we have stale + // shape/size/position information. The old region should have + // already been add to damage when the information became stale. + if (!win_check_flags_any( + mw, WIN_FLAGS_SIZE_STALE | WIN_FLAGS_POSITION_STALE)) { + // Mark the old extents as damaged. + // The new extents will be marked damaged when processing + // window flags. + region_t damage; + pixman_region32_init(&damage); + win_extents(mw, &damage); + add_damage(ps, &damage); + pixman_region32_fini(&damage); + } // Queue pending updates win_set_flags(mw, WIN_FLAGS_FACTOR_CHANGED); ps->pending_updates = true; - mw->g.x = ce->x; - mw->g.y = ce->y; + // At least one of the following if's is true + if (mw->g.x != ce->x || mw->g.y != ce->y) { + log_trace("Window position changed, %dx%d -> %dx%d", + mw->g.x, mw->g.y, ce->x, ce->y); + mw->g.x = ce->x; + mw->g.y = ce->y; + win_set_flags(mw, WIN_FLAGS_POSITION_STALE); + } if (mw->g.width != ce->width || mw->g.height != ce->height || mw->g.border_width != ce->border_width) { @@ -236,14 +250,6 @@ static void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) { win_set_flags(mw, WIN_FLAGS_SIZE_STALE); } - win_extents(mw, &new_extents); - // Mark the union of the old and new extents as damaged - pixman_region32_union(&damage, &damage, &new_extents); - add_damage(ps, &damage); - - pixman_region32_fini(&damage); - pixman_region32_fini(&new_extents); - // Recalculate which screen this window is on win_update_screen(ps->xinerama_nscrs, ps->xinerama_scr_regs, mw); } @@ -611,8 +617,9 @@ static inline void repair_win(session_t *ps, struct managed_win *w) { } // Remove the part in the damage area that could be ignored - if (w->reg_ignore && win_is_region_ignore_valid(ps, w)) + if (w->reg_ignore && win_is_region_ignore_valid(ps, w)) { pixman_region32_subtract(&parts, &parts, w->reg_ignore); + } add_damage(ps, &parts); pixman_region32_fini(&parts); diff --git a/src/win.c b/src/win.c index e78e2d3..a290805 100644 --- a/src/win.c +++ b/src/win.c @@ -400,6 +400,7 @@ static void win_update_properties(session_t *ps, struct managed_win *w) { win_clear_all_properties_stale(w); } +/// Handle non-image flags. This phase might set IMAGES_STALE flags void win_process_update_flags(session_t *ps, struct managed_win *w) { if (win_check_flags_all(w, WIN_FLAGS_MAPPED)) { map_win_start(ps, w); @@ -413,12 +414,19 @@ void win_process_update_flags(session_t *ps, struct managed_win *w) { win_clear_flags(w, WIN_FLAGS_CLIENT_STALE); } + bool damaged = false; if (win_check_flags_all(w, WIN_FLAGS_SIZE_STALE)) { win_on_win_size_change(ps, w); win_update_bounding_shape(ps, w); + damaged = true; win_clear_flags(w, WIN_FLAGS_SIZE_STALE); } + if (win_check_flags_all(w, WIN_FLAGS_POSITION_STALE)) { + damaged = true; + win_clear_flags(w, WIN_FLAGS_POSITION_STALE); + } + if (win_check_flags_all(w, WIN_FLAGS_PROPERTY_STALE)) { win_update_properties(ps, w); win_clear_flags(w, WIN_FLAGS_PROPERTY_STALE); @@ -429,6 +437,12 @@ void win_process_update_flags(session_t *ps, struct managed_win *w) { win_on_factor_change(ps, w); win_clear_flags(w, WIN_FLAGS_FACTOR_CHANGED); } + + // Add damage, has to be done last so the window has the latest geometry + // information. + if (damaged) { + add_damage_from_win(ps, w); + } } void win_process_image_flags(session_t *ps, struct managed_win *w) { diff --git a/src/win_defs.h b/src/win_defs.h index 48ed651..6a95a66 100644 --- a/src/win_defs.h +++ b/src/win_defs.h @@ -89,8 +89,10 @@ enum win_flags { WIN_FLAGS_PROPERTY_STALE = 128, /// this window has an unhandled size/shape change WIN_FLAGS_SIZE_STALE = 256, + /// this window has an unhandled position (i.e. x and y) change + WIN_FLAGS_POSITION_STALE = 512, /// need better name for this, is set when some aspects of the window changed - WIN_FLAGS_FACTOR_CHANGED = 512, + WIN_FLAGS_FACTOR_CHANGED = 1024, }; static const uint64_t WIN_FLAGS_IMAGES_STALE =