diff --git a/src/compton.c b/src/compton.c index ffa68844..fb7bb8cc 100644 --- a/src/compton.c +++ b/src/compton.c @@ -91,6 +91,11 @@ void set_root_flags(session_t *ps, uint64_t flags) { ps->root_flags |= flags; } +static inline void quit_compton(session_t *ps) { + ps->quit = true; + ev_break(ps->loop, EVBREAK_ALL); +} + /** * Free Xinerama screen info. * @@ -1365,6 +1370,14 @@ static void handle_queued_x_events(EV_P_ ev_prepare *w, int revents) { } } +static void handle_new_windows(session_t *ps) { + list_foreach_safe(struct win, w, &ps->window_stack, stack_neighbour) { + if (w->is_new) { + fill_win(ps, w); + } + } +} + /** * Unredirection timeout callback. */ @@ -1380,6 +1393,26 @@ 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); + } + + // 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); + + 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); + } + if (ps->o.benchmark) { if (ps->o.benchmark_wid) { auto w = find_managed_win(ps, ps->o.benchmark_wid); diff --git a/src/event.c b/src/event.c index c0c8a049..9a43751b 100644 --- a/src/event.c +++ b/src/event.c @@ -170,7 +170,7 @@ static inline void ev_focus_out(session_t *ps, xcb_focus_out_event_t *ev) { static inline void ev_create_notify(session_t *ps, xcb_create_notify_event_t *ev) { assert(ev->parent == ps->root); // TODO delay fill_win - fill_win(ps, add_win_top(ps, ev->window)); + add_win_top(ps, ev->window); } static inline void ev_configure_notify(session_t *ps, xcb_configure_notify_event_t *ev) { @@ -216,8 +216,7 @@ static inline void ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t if (ev->parent == ps->root) { // new window - // TODO delay fill_win - fill_win(ps, add_win_top(ps, ev->window)); + add_win_top(ps, ev->window); } else { // otherwise, find and destroy the window first auto w = find_win(ps, ev->window);