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 <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2020-10-23 04:11:52 +01:00
parent 35b4e82085
commit f476a78ad1
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
3 changed files with 41 additions and 18 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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 =