win: release window image before rebind

Previously we try to keep the image data until the rebind succeeds. This
way even if the rebind fails, we still have something to display.

But that triggers a NVIDIA driver bug. Basically you cannot have more
than one names (XIDs) of a window pixmap. NVIDIA driver doesn't like
that, and binding the pixmap with its aliases will fail. This can
sometimes happen if we name the new pixmap before freeing the old one during
rebind, and the pixmap doesn't actually change (i.e. the rebind is
unnecessary, could happen because of X event handling complications).

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-03-17 03:05:09 +00:00
parent 9bb2fa44d4
commit fed6ac5b09
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
2 changed files with 2 additions and 9 deletions

View File

@ -226,17 +226,10 @@ bool win_bind_image(session_t *ps, win *w) {
}
bool win_try_rebind_image(session_t *ps, win *w) {
void *new_image, *new_shadow;
if (!_win_bind_image(ps, w, &new_image, &new_shadow)) {
return false;
}
log_trace("Freeing old window image");
win_release_image(ps->backend_data, w);
w->shadow_image = new_shadow;
w->win_image = new_image;
return true;
return win_bind_image(ps, w);
}
/**

View File

@ -291,7 +291,7 @@ void win_release_image(backend_t *base, win *w);
bool must_use win_bind_image(session_t *ps, win *w);
/// Attempt a rebind of window's images. If that failed, the original images are kept.
bool win_try_rebind_image(session_t *ps, win *w);
bool must_use win_try_rebind_image(session_t *ps, win *w);
int win_get_name(session_t *ps, win *w);
int win_get_role(session_t *ps, win *w);
winmode_t attr_pure win_calc_mode(const win *w);