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 ||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
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
|
||||
.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,
|
||||
|
|
|
@ -165,9 +165,6 @@ struct win {
|
|||
region_t bounding_shape;
|
||||
/// Window flags. Definitions above.
|
||||
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.
|
||||
xcb_configure_notify_event_t queue_configure;
|
||||
/// The region of screen that will be obscured when windows above is painted,
|
||||
|
|
Loading…
Reference in New Issue