Treat first frame after redirection differently
Because first frame no window has their pixmap bound, which doesn't happen in frames after the first. If a window is unmapped in that frame, the compositor will try to render a window with no pixmap bound if fading is enabled. Now we keep track if we are in the first frame, and if that's the case we skip fading in unmap/destroy. Fixes #239, bug number 2 Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
f493447b33
commit
a69ed89114
|
@ -210,6 +210,8 @@ typedef struct session {
|
|||
#endif
|
||||
/// Sync fence to sync draw operations
|
||||
xcb_sync_fence_t sync_fence;
|
||||
/// Whether we are rendering the first frame after screen is redirected
|
||||
bool first_frame;
|
||||
|
||||
// === Operation related ===
|
||||
/// Flags related to the root window
|
||||
|
|
|
@ -1212,6 +1212,7 @@ static bool redirect_start(session_t *ps) {
|
|||
x_sync(ps->c);
|
||||
|
||||
ps->redirected = true;
|
||||
ps->first_frame = true;
|
||||
|
||||
// Re-detect driver since we now have a backend
|
||||
ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root);
|
||||
|
@ -1378,6 +1379,20 @@ static void handle_pending_updates(EV_P_ struct session *ps) {
|
|||
static void _draw_callback(EV_P_ session_t *ps, int revents attr_unused) {
|
||||
handle_pending_updates(EV_A_ ps);
|
||||
|
||||
if (ps->first_frame) {
|
||||
// If we are still rendering the first frame, if some of the windows are
|
||||
// unmapped/destroyed during the above handle_pending_updates() call, they
|
||||
// won't have pixmap before we rendered it, causing us to crash.
|
||||
// But we will only render them if they are in fading. So we just skip
|
||||
// fading for all windows here.
|
||||
//
|
||||
// Using foreach_safe here since skipping fading can cause window to be
|
||||
// freed if it's destroyed.
|
||||
win_stack_foreach_managed_safe(w, &ps->window_stack) {
|
||||
auto _ attr_unused = win_skip_fading(ps, w);
|
||||
}
|
||||
}
|
||||
|
||||
if (ps->o.benchmark) {
|
||||
if (ps->o.benchmark_wid) {
|
||||
auto w = find_managed_win(ps, ps->o.benchmark_wid);
|
||||
|
@ -1428,6 +1443,7 @@ static void _draw_callback(EV_P_ session_t *ps, int revents attr_unused) {
|
|||
paint_all(ps, bottom, false);
|
||||
}
|
||||
|
||||
ps->first_frame = false;
|
||||
paint++;
|
||||
if (ps->o.benchmark && paint >= ps->o.benchmark)
|
||||
exit(0);
|
||||
|
|
Loading…
Reference in New Issue