diff --git a/src/compton.c b/src/compton.c
index 02afb6c..23e58c1 100644
--- a/src/compton.c
+++ b/src/compton.c
@@ -825,17 +825,13 @@ void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
if (w->state == WSTATE_UNMAPPED || w->state == WSTATE_UNMAPPING ||
w->state == WSTATE_DESTROYING) {
- /* save the configure event for when the window maps */
- w->need_configure = true;
- w->queue_configure = *ce;
+ // Only restack the window to make sure we can handle future restack
+ // notification correctly
restack_win(ps, w, ce->above_sibling);
} else {
- if (!w->need_configure) {
- restack_win(ps, w, ce->above_sibling);
- }
+ restack_win(ps, w, ce->above_sibling);
bool factor_change = false;
- w->need_configure = false;
win_extents(w, &damage);
// If window geometry change, free old extents
@@ -848,6 +844,8 @@ void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
if (w->g.width != ce->width || w->g.height != ce->height ||
w->g.border_width != ce->border_width) {
+ log_trace("Window size changed, %dx%d -> %dx%d", w->g.width,
+ w->g.height, ce->width, ce->height);
w->g.width = ce->width;
w->g.height = ce->height;
w->g.border_width = ce->border_width;
diff --git a/src/win.c b/src/win.c
index 5dbdeee..01335b0 100644
--- a/src/win.c
+++ b/src/win.c
@@ -876,8 +876,6 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
.state = WSTATE_UNMAPPED, // updated by window state changes
.in_openclose = true, // set to false after first map is done,
// true here because window is just created
- .need_configure = false, // set to true when window is configured
- // while unmapped.
.queue_configure = {}, // same as above
.reg_ignore_valid = false, // set to true when damaged
.flags = 0, // updated by property/attributes/etc change
@@ -955,18 +953,15 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
log_debug("Adding window %#010x, prev %#010x", id, prev);
xcb_get_window_attributes_cookie_t acookie = xcb_get_window_attributes(ps->c, id);
- xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(ps->c, id);
xcb_get_window_attributes_reply_t *a =
xcb_get_window_attributes_reply(ps->c, acookie, NULL);
- xcb_get_geometry_reply_t *g = xcb_get_geometry_reply(ps->c, gcookie, NULL);
- if (!a || !g || a->map_state == XCB_MAP_STATE_UNVIEWABLE) {
+ if (!a || a->map_state == XCB_MAP_STATE_UNVIEWABLE) {
// Failed to get window attributes or geometry probably means
// the window is gone already. Unviewable means the window is
// already reparented elsewhere.
// BTW, we don't care about Input Only windows, except for stacking
// proposes, so we need to keep track of them still.
free(a);
- free(g);
return;
}
@@ -979,10 +974,8 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
*new = win_def;
new->id = id;
new->a = *a;
- new->g = *g;
pixman_region32_init(&new->bounding_shape);
- free(g);
free(a);
// Create Damage for window (if not Input Only)
@@ -1000,8 +993,6 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
new->pictfmt = x_get_pictform_for_visual(ps->c, new->a.visual);
}
- win_on_win_size_change(ps, new);
-
// Find window insertion point
win **p = NULL;
if (prev) {
@@ -1645,6 +1636,29 @@ void map_win(session_t *ps, win *w) {
return;
}
+ // We stopped processing window size change when we were unmapped, refresh the
+ // size of the window
+ xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(ps->c, w->id);
+ xcb_get_geometry_reply_t *g = xcb_get_geometry_reply(ps->c, gcookie, NULL);
+
+ if (!g) {
+ log_error("Failed to get the geometry of window %#010x", w->id);
+ return;
+ }
+
+ w->g = *g;
+ free(g);
+
+ win_on_win_size_change(ps, w);
+ log_trace("Window size: %dx%d", w->g.width, w->g.height);
+
+ // Rant: window size could change after we queried its geometry here and before
+ // we get its pixmap. Later, when we get back to the event processing loop, we
+ // will get the notification about size change from Xserver and try to refresh the
+ // pixmap, while the pixmap is actually already up-to-date (i.e. the notification
+ // is stale). There is basically no real way to prevent this, aside from grabbing
+ // the server.
+
// XXX ???
assert(!win_is_focused_real(ps, w));
@@ -1712,13 +1726,6 @@ void map_win(session_t *ps, win *w) {
w->ever_damaged = false;
- /* if any configure events happened while
- the window was unmapped, then configure
- the window to its correct place */
- if (w->need_configure) {
- configure_win(ps, &w->queue_configure);
- }
-
// We stopped listening on ShapeNotify events
// when the window is unmapped (XXX we shouldn't),
// so the shape of the window might have changed,
diff --git a/src/win.h b/src/win.h
index 4cba9eb..39f9e17 100644
--- a/src/win.h
+++ b/src/win.h
@@ -165,9 +165,6 @@ struct win {
region_t bounding_shape;
/// Window flags. Definitions above.
int_fast16_t flags;
- /// Whether there's a pending ConfigureNotify
happening
- /// when the window is unmapped.
- bool need_configure;
/// Queued ConfigureNotify
when the window is unmapped.
xcb_configure_notify_event_t queue_configure;
/// The region of screen that will be obscured when windows above is painted,