win: always refresh window size in map_win
Instead queue up configure notification while the window is unmapped, just update the window geometry when the window is mapped. Simplify the logic a little bit. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
8dc250a415
commit
b10f0bbc67
|
@ -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 ||
|
if (w->state == WSTATE_UNMAPPED || w->state == WSTATE_UNMAPPING ||
|
||||||
w->state == WSTATE_DESTROYING) {
|
w->state == WSTATE_DESTROYING) {
|
||||||
/* save the configure event for when the window maps */
|
// Only restack the window to make sure we can handle future restack
|
||||||
w->need_configure = true;
|
// notification correctly
|
||||||
w->queue_configure = *ce;
|
|
||||||
restack_win(ps, w, ce->above_sibling);
|
restack_win(ps, w, ce->above_sibling);
|
||||||
} else {
|
} else {
|
||||||
if (!w->need_configure) {
|
restack_win(ps, w, ce->above_sibling);
|
||||||
restack_win(ps, w, ce->above_sibling);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool factor_change = false;
|
bool factor_change = false;
|
||||||
w->need_configure = false;
|
|
||||||
win_extents(w, &damage);
|
win_extents(w, &damage);
|
||||||
|
|
||||||
// If window geometry change, free old extents
|
// 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 ||
|
if (w->g.width != ce->width || w->g.height != ce->height ||
|
||||||
w->g.border_width != ce->border_width) {
|
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.width = ce->width;
|
||||||
w->g.height = ce->height;
|
w->g.height = ce->height;
|
||||||
w->g.border_width = ce->border_width;
|
w->g.border_width = ce->border_width;
|
||||||
|
|
41
src/win.c
41
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
|
.state = WSTATE_UNMAPPED, // updated by window state changes
|
||||||
.in_openclose = true, // set to false after first map is done,
|
.in_openclose = true, // set to false after first map is done,
|
||||||
// true here because window is just created
|
// true here because window is just created
|
||||||
.need_configure = false, // set to true when window is configured
|
|
||||||
// while unmapped.
|
|
||||||
.queue_configure = {}, // same as above
|
.queue_configure = {}, // same as above
|
||||||
.reg_ignore_valid = false, // set to true when damaged
|
.reg_ignore_valid = false, // set to true when damaged
|
||||||
.flags = 0, // updated by property/attributes/etc change
|
.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);
|
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_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_t *a =
|
||||||
xcb_get_window_attributes_reply(ps->c, acookie, NULL);
|
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 || a->map_state == XCB_MAP_STATE_UNVIEWABLE) {
|
||||||
if (!a || !g || a->map_state == XCB_MAP_STATE_UNVIEWABLE) {
|
|
||||||
// Failed to get window attributes or geometry probably means
|
// Failed to get window attributes or geometry probably means
|
||||||
// the window is gone already. Unviewable means the window is
|
// the window is gone already. Unviewable means the window is
|
||||||
// already reparented elsewhere.
|
// already reparented elsewhere.
|
||||||
// BTW, we don't care about Input Only windows, except for stacking
|
// BTW, we don't care about Input Only windows, except for stacking
|
||||||
// proposes, so we need to keep track of them still.
|
// proposes, so we need to keep track of them still.
|
||||||
free(a);
|
free(a);
|
||||||
free(g);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,10 +974,8 @@ void add_win(session_t *ps, xcb_window_t id, xcb_window_t prev) {
|
||||||
*new = win_def;
|
*new = win_def;
|
||||||
new->id = id;
|
new->id = id;
|
||||||
new->a = *a;
|
new->a = *a;
|
||||||
new->g = *g;
|
|
||||||
pixman_region32_init(&new->bounding_shape);
|
pixman_region32_init(&new->bounding_shape);
|
||||||
|
|
||||||
free(g);
|
|
||||||
free(a);
|
free(a);
|
||||||
|
|
||||||
// Create Damage for window (if not Input Only)
|
// 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);
|
new->pictfmt = x_get_pictform_for_visual(ps->c, new->a.visual);
|
||||||
}
|
}
|
||||||
|
|
||||||
win_on_win_size_change(ps, new);
|
|
||||||
|
|
||||||
// Find window insertion point
|
// Find window insertion point
|
||||||
win **p = NULL;
|
win **p = NULL;
|
||||||
if (prev) {
|
if (prev) {
|
||||||
|
@ -1645,6 +1636,29 @@ void map_win(session_t *ps, win *w) {
|
||||||
return;
|
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 ???
|
// XXX ???
|
||||||
assert(!win_is_focused_real(ps, w));
|
assert(!win_is_focused_real(ps, w));
|
||||||
|
|
||||||
|
@ -1712,13 +1726,6 @@ void map_win(session_t *ps, win *w) {
|
||||||
|
|
||||||
w->ever_damaged = false;
|
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
|
// We stopped listening on ShapeNotify events
|
||||||
// when the window is unmapped (XXX we shouldn't),
|
// when the window is unmapped (XXX we shouldn't),
|
||||||
// so the shape of the window might have changed,
|
// so the shape of the window might have changed,
|
||||||
|
|
|
@ -165,9 +165,6 @@ struct win {
|
||||||
region_t bounding_shape;
|
region_t bounding_shape;
|
||||||
/// Window flags. Definitions above.
|
/// Window flags. Definitions above.
|
||||||
int_fast16_t flags;
|
int_fast16_t flags;
|
||||||
/// Whether there's a pending <code>ConfigureNotify</code> happening
|
|
||||||
/// when the window is unmapped.
|
|
||||||
bool need_configure;
|
|
||||||
/// Queued <code>ConfigureNotify</code> when the window is unmapped.
|
/// Queued <code>ConfigureNotify</code> when the window is unmapped.
|
||||||
xcb_configure_notify_event_t queue_configure;
|
xcb_configure_notify_event_t queue_configure;
|
||||||
/// The region of screen that will be obscured when windows above is painted,
|
/// The region of screen that will be obscured when windows above is painted,
|
||||||
|
|
Loading…
Reference in New Issue