From 6c71146f1cefbcf759c4ef26e5b77d52b4b052ab Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 21 Feb 2019 02:29:06 +0000 Subject: [PATCH] Don't call map_win() in add_win() Only case where you want to map window in add_win() is during compton startup, when compton is registering existing windows. Otherwise, add_win() is always called for newly created windows, so there will always be a MapNotify coming up for that window. If we map newly created windows in add_win(), we will try to map it a second time when the MapNotify arrives. So, just don't call map_win() from add_win(). For compton startup, we explicitly call map_win() after calling add_win() in session_init. Signed-off-by: Yuxuan Shui --- src/compton.c | 8 +++++++- src/compton.h | 2 -- src/win.c | 53 ++++++++++++++++++++++++++++----------------------- src/win.h | 3 +++ 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/compton.c b/src/compton.c index aa022ff..4627cd2 100644 --- a/src/compton.c +++ b/src/compton.c @@ -1240,7 +1240,7 @@ ev_destroy_notify(session_t *ps, xcb_destroy_notify_event_t *ev) { inline static void ev_map_notify(session_t *ps, xcb_map_notify_event_t *ev) { - map_win(ps, ev->window); + map_win_by_id(ps, ev->window); // FocusIn/Out may be ignored when the window is unmapped, so we must // recheck focus here if (ps->o.track_focus) { @@ -2771,6 +2771,12 @@ session_init(int argc, char **argv, Display *dpy, const char *config_file, add_win(ps, children[i], i ? children[i-1] : XCB_NONE); } + for (win *i = ps->list; i; i = i->next) { + if (i->a.map_state == XCB_MAP_STATE_VIEWABLE) { + map_win(ps, i); + } + } + free(reply); log_trace("Initial stack:"); for (win *c = ps->list; c; c = c->next) { diff --git a/src/compton.h b/src/compton.h index 2b445ab..fbde63d 100644 --- a/src/compton.h +++ b/src/compton.h @@ -41,8 +41,6 @@ find_client_win(session_t *ps, xcb_window_t w); win *find_toplevel2(session_t *ps, xcb_window_t wid); -void map_win(session_t *ps, xcb_window_t id); - /** * Subtract two unsigned long values. * diff --git a/src/win.c b/src/win.c index c5433d4..87cbcec 100644 --- a/src/win.c +++ b/src/win.c @@ -945,10 +945,6 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) { cdbus_ev_win_added(ps, new); } #endif - - if (new->a.map_state == XCB_MAP_STATE_VIEWABLE) { - map_win(ps, id); - } return; } @@ -1547,29 +1543,16 @@ void win_update_screen(session_t *ps, win *w) { void configure_win(session_t *, xcb_configure_notify_event_t *); /// Map an already registered window -void -map_win(session_t *ps, xcb_window_t id) { - // Unmap overlay window if it got mapped but we are currently not - // in redirected state. - if (ps->overlay && id == ps->overlay && !ps->redirected) { - log_debug("Overlay is mapped while we are not redirected"); - auto e = xcb_request_check(ps->c, xcb_unmap_window(ps->c, ps->overlay)); - if (e) { - log_error("Failed to unmap the overlay window"); - free(e); - } - // We don't track the overlay window, so we can return - return; - } +void map_win(session_t *ps, win *w) { + assert(w); - win *w = find_win(ps, id); // Don't care about window mapping if it's an InputOnly window // Also, try avoiding mapping a window twice - if (!w || w->a._class == XCB_WINDOW_CLASS_INPUT_ONLY) { + if (w->a._class == XCB_WINDOW_CLASS_INPUT_ONLY) { return; } - log_debug("Mapping (%#010x \"%s\")", id, w->name); + log_debug("Mapping (%#010x \"%s\")", w->id, w->name); if (w->state != WSTATE_UNMAPPED && w->state != WSTATE_UNMAPPING) { log_warn("Mapping an already mapped window"); @@ -1586,12 +1569,12 @@ map_win(session_t *ps, xcb_window_t id) { // Set window event mask before reading properties so that no property // changes are lost - xcb_change_window_attributes(ps->c, id, XCB_CW_EVENT_MASK, - (const uint32_t[]) { determine_evmask(ps, id, WIN_EVMODE_FRAME) }); + xcb_change_window_attributes(ps->c, w->id, XCB_CW_EVENT_MASK, + (const uint32_t[]) { determine_evmask(ps, w->id, WIN_EVMODE_FRAME) }); // Notify compton when the shape of a window changes if (ps->shape_exists) { - xcb_shape_select_input(ps->c, id, 1); + xcb_shape_select_input(ps->c, w->id, 1); } // Update window mode here to check for ARGB windows @@ -1659,5 +1642,27 @@ map_win(session_t *ps, xcb_window_t id) { } } +void map_win_by_id(session_t *ps, xcb_window_t id) { + // Unmap overlay window if it got mapped but we are currently not + // in redirected state. + if (ps->overlay && id == ps->overlay && !ps->redirected) { + log_debug("Overlay is mapped while we are not redirected"); + auto e = xcb_request_check(ps->c, xcb_unmap_window(ps->c, ps->overlay)); + if (e) { + log_error("Failed to unmap the overlay window"); + free(e); + } + // We don't track the overlay window, so we can return + return; + } + + win *w = find_win(ps, id); + if (!w) { + return; + } + + map_win(ps, w); +} + // vim: set et sw=2 : diff --git a/src/win.h b/src/win.h index ee3451f..c3a28b7 100644 --- a/src/win.h +++ b/src/win.h @@ -359,6 +359,9 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev); /// Unmap or destroy a window void unmap_win(session_t *ps, win **, bool destroy); +void map_win(session_t *ps, win *w); +void map_win_by_id(session_t *ps, xcb_window_t id); + /** * Execute fade callback of a window if fading finished. */