diff --git a/src/common.h b/src/common.h index 4a4af280..79b9ee35 100644 --- a/src/common.h +++ b/src/common.h @@ -378,9 +378,11 @@ typedef struct session { // Cached blur convolution kernels. xcb_render_fixed_t *blur_kerns_cache[MAX_BLUR_PASS]; /// Reset program after next paint. - bool reset; + bool reset:1; /// If compton should quit - bool quit; + bool quit:1; + /// If new window has been added and not been handled + bool has_new_window:1; // === Expose event related === /// Pointer to an array of XRectangle-s of exposed region. diff --git a/src/compton.c b/src/compton.c index 8679af87..9f78afee 100644 --- a/src/compton.c +++ b/src/compton.c @@ -855,10 +855,9 @@ 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) - { + mw->g.height != ce->height || mw->g.border_width != ce->border_width) { factor_change = true; - } + } mw->g.x = ce->x; mw->g.y = ce->y; @@ -1412,6 +1411,7 @@ static void handle_new_windows(session_t *ps) { } } } + ps->has_new_window = false; } /** @@ -1429,24 +1429,31 @@ static void fade_timer_callback(EV_P_ ev_timer *w, int revents) { } static void _draw_callback(EV_P_ session_t *ps, int revents) { - auto e = xcb_request_check(ps->c, xcb_grab_server_checked(ps->c)); - if (e) { - log_fatal("failed to grab x server"); - x_print_error(e->full_sequence, e->major_code, e->minor_code, e->error_code); - return quit_compton(ps); - } + if (ps->has_new_window) { + log_debug("Delayed handling of new window events, entering critical " + "section"); + auto e = xcb_request_check(ps->c, xcb_grab_server_checked(ps->c)); + if (e) { + log_fatal("failed to grab x server"); + x_print_error(e->full_sequence, e->major_code, e->minor_code, + e->error_code); + return quit_compton(ps); + } - // Catching up with X server - handle_queued_x_events(ps->loop, &ps->event_check, 0); + // Catching up with X server + handle_queued_x_events(ps->loop, &ps->event_check, 0); - // Call fill_win on new windows - handle_new_windows(ps); + // Call fill_win on new windows + handle_new_windows(ps); - e = xcb_request_check(ps->c, xcb_ungrab_server_checked(ps->c)); - if (e) { - log_fatal("failed to ungrab x server"); - x_print_error(e->full_sequence, e->major_code, e->minor_code, e->error_code); - return quit_compton(ps); + e = xcb_request_check(ps->c, xcb_ungrab_server_checked(ps->c)); + if (e) { + log_fatal("failed to ungrab x server"); + x_print_error(e->full_sequence, e->major_code, e->minor_code, + e->error_code); + return quit_compton(ps); + } + log_debug("Exiting critical section"); } if (ps->o.benchmark) { diff --git a/src/win.c b/src/win.c index 31f08e56..d25abb8c 100644 --- a/src/win.c +++ b/src/win.c @@ -958,6 +958,7 @@ static struct win *add_win(session_t *ps, xcb_window_t id, struct list_node *pre new_w->destroyed = false; HASH_ADD_INT(ps->windows, id, new_w); + ps->has_new_window = true; return new_w; }