win: don't ignore SHADOW_STALE flag on unmapped windows
Previously all image stale flags are ignored when processing an unmapped window. If a window gains a shadow during its fading out transition, the shadow flag will be set, but shadow won't actually be generated, causing a NULL pointer dereference during render. Fixes #239 Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
c85c9ef1cc
commit
33a106e254
34
src/win.c
34
src/win.c
|
@ -324,6 +324,11 @@ void win_release_images(struct backend_base *backend, struct managed_win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void win_process_flags(session_t *ps, struct managed_win *w) {
|
void win_process_flags(session_t *ps, struct managed_win *w) {
|
||||||
|
// Make sure all pending window updates are processed before this. Making this
|
||||||
|
// assumption simplifies some checks (e.g. whether window is mapped)
|
||||||
|
auto iw = (struct managed_win_internal *)w;
|
||||||
|
assert(iw->pending_updates == 0);
|
||||||
|
|
||||||
if (!w->flags || (w->flags & WIN_FLAGS_IMAGE_ERROR) != 0) {
|
if (!w->flags || (w->flags & WIN_FLAGS_IMAGE_ERROR) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -331,19 +336,25 @@ void win_process_flags(session_t *ps, struct managed_win *w) {
|
||||||
// Not a loop
|
// Not a loop
|
||||||
while ((w->flags & WIN_FLAGS_IMAGES_STALE) != 0) {
|
while ((w->flags & WIN_FLAGS_IMAGES_STALE) != 0) {
|
||||||
// Image needs to be updated, update it.
|
// Image needs to be updated, update it.
|
||||||
if (w->state == WSTATE_UNMAPPING || w->state == WSTATE_DESTROYING ||
|
if (!ps->backend_data) {
|
||||||
!ps->backend_data) {
|
// We are using legacy backend, nothing to do here.
|
||||||
// Window is already gone, or we are using the legacy backend
|
|
||||||
// we cannot rebind image
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must release images first, otherwise breaks NVIDIA driver
|
|
||||||
if ((w->flags & WIN_FLAGS_PIXMAP_STALE) != 0) {
|
if ((w->flags & WIN_FLAGS_PIXMAP_STALE) != 0) {
|
||||||
if ((w->flags & WIN_FLAGS_PIXMAP_NONE) == 0) {
|
// Check to make sure the window is still mapped, otherwise we
|
||||||
win_release_pixmap(ps->backend_data, w);
|
// won't be able to rebind pixmap after releasing it, yet we might
|
||||||
|
// still need the pixmap for rendering.
|
||||||
|
if (w->state != WSTATE_UNMAPPING && w->state != WSTATE_DESTROYING) {
|
||||||
|
if ((w->flags & WIN_FLAGS_PIXMAP_NONE) == 0) {
|
||||||
|
// Must release images first, otherwise breaks
|
||||||
|
// NVIDIA driver
|
||||||
|
win_release_pixmap(ps->backend_data, w);
|
||||||
|
}
|
||||||
|
win_bind_pixmap(ps->backend_data, w);
|
||||||
|
} else {
|
||||||
|
assert(w->win_image);
|
||||||
}
|
}
|
||||||
win_bind_pixmap(ps->backend_data, w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((w->flags & WIN_FLAGS_SHADOW_STALE) != 0) {
|
if ((w->flags & WIN_FLAGS_SHADOW_STALE) != 0) {
|
||||||
|
@ -360,9 +371,12 @@ void win_process_flags(session_t *ps, struct managed_win *w) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flags are cleared here, loop always run only once
|
// break here, loop always run only once
|
||||||
w->flags &= ~WIN_FLAGS_IMAGES_STALE;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear stale image flags
|
||||||
|
w->flags &= ~WIN_FLAGS_IMAGES_STALE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue