diff --git a/src/dispextern.h b/src/dispextern.h index 213032d4de8..33fcaa4c078 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1262,8 +1262,6 @@ extern struct glyph space_glyph; /* True means last display completed. False means it was preempted. */ extern bool display_completed; -extern bool delayed_size_change; - /************************************************************************ Glyph Strings diff --git a/src/dispnew.c b/src/dispnew.c index b3f7be67e0f..1378c34e984 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -102,7 +102,7 @@ bool display_completed; /* True means SIGWINCH happened when not safe. */ -bool delayed_size_change; +static bool delayed_size_change; /* A glyph for a space. */ @@ -5815,7 +5815,6 @@ deliver_window_change_signal (int sig) void do_pending_window_change (bool safe) { - /* If window change signal handler should have run before, run it now. */ if (redisplaying_p && !safe) return; @@ -5830,8 +5829,11 @@ do_pending_window_change (bool safe) struct frame *f = XFRAME (frame); /* Negative new_width or new_height values mean no change is - required (a native size can never drop below zero). */ - if (f->new_height >= 0 || f->new_width >= 0) + required (a native size can never drop below zero). If + new_size_p is not set, this means the size change was + requested by adjust_frame_size but has not been honored by + the window manager yet. */ + if (f->new_size_p && (f->new_height >= 0 || f->new_width >= 0)) change_frame_size (f, f->new_width, f->new_height, false, false, safe); } @@ -5858,14 +5860,17 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height, /* We can't deal with the change now, queue it for later. */ f->new_width = new_width; f->new_height = new_height; + f->new_size_p = true; delayed_size_change = true; } else { /* Storing -1 in the new_width/new_height slots means that no size - change is pending. Native sizes are always non-negative. */ + change is pending. Native sizes are always non-negative. + Reset the new_size_p slot as well. */ f->new_height = -1; f->new_width = -1; + f->new_size_p = false; /* adjust_frame_size wants its arguments in terms of text_width and text_height, so convert them here. For pathologically small frames, the resulting values may be negative though. */ diff --git a/src/frame.c b/src/frame.c index 4129a70aa5f..32110512e95 100644 --- a/src/frame.c +++ b/src/frame.c @@ -619,12 +619,8 @@ frame_size_history_extra (struct frame *f, Lisp_Object parameter, * must be preserved. The code for setting up window dividers and * that responsible for wrapping the (internal) tool bar use this. * - * 5 means to never call set_window_size_hook. change_frame_size uses - * this. - * - * Note that even when set_window_size_hook is not called, individual - * windows may have to be resized (via `window--sanitize-window-sizes') - * in order to support minimum size constraints. + * 5 means to never call set_window_size_hook. Usually this means to + * call resize_frame_windows. change_frame_size uses this. * * PRETEND is as for change_frame_size. PARAMETER, if non-nil, is the * symbol of the parameter changed (like `menu-bar-lines', `font', ...). @@ -716,6 +712,9 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height, if (FRAME_WINDOW_P (f) && f->can_set_window_size + /* For inhibit == 1 call the window_size_hook only if a native + size changes. For inhibit == 0 or inhibit == 2 always call + it. */ && ((!inhibit_horizontal && (new_native_width != old_native_width || inhibit == 0 || inhibit == 2)) @@ -761,6 +760,17 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height, min_inner_width, min_inner_height, inhibit_horizontal, inhibit_vertical); + if (inhibit == 0 || inhibit == 1) + { + f->new_width = new_native_width; + f->new_height = new_native_height; + /* Resetting f->new_size_p is controversial: It might cause + do_pending_window_change drop a previous request and we are + in troubles when the window manager does not honor the + request we issue here. */ + f->new_size_p = false; + } + if (FRAME_TERMINAL (f)->set_window_size_hook) FRAME_TERMINAL (f)->set_window_size_hook (f, 0, new_native_width, new_native_height); diff --git a/src/frame.h b/src/frame.h index 19ee6ac10e7..744b95e1e04 100644 --- a/src/frame.h +++ b/src/frame.h @@ -453,6 +453,11 @@ struct frame frame is in the process of being redisplayed. */ bool_bf inhibit_clear_image_cache : 1; + /* True when new_width or new_height were set by change_frame_size, + false when they were set by adjust_frame_size internally or not + set. */ + bool_bf new_size_p; + /* Bitfield area ends here. */ /* This frame's change stamp, set the last time window change diff --git a/src/gtkutil.c b/src/gtkutil.c index 4ad172bb486..ba506faf356 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -916,16 +916,18 @@ void xg_frame_resized (struct frame *f, int width, int height) { /* Ignore case where size of native rectangle didn't change. */ - if (width != FRAME_PIXEL_WIDTH (f) || height != FRAME_PIXEL_HEIGHT (f) - || (delayed_size_change - && (width != f->new_width || height != f->new_height))) + if (width != FRAME_PIXEL_WIDTH (f) + || height != FRAME_PIXEL_HEIGHT (f) + || (f->new_size_p + && ((f->new_width >= 0 && width != f->new_width) + || (f->new_height >= 0 && height != f->new_height)))) { if (CONSP (frame_size_history)) frame_size_history_extra (f, build_string ("xg_frame_resized, changed"), FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height, - delayed_size_change ? f->new_width : -1, - delayed_size_change ? f->new_height : -1); + f->new_size_p ? f->new_width : -1, + f->new_size_p ? f->new_height : -1); FRAME_RIF (f)->clear_under_internal_border (f); change_frame_size (f, width, height, false, true, false); @@ -936,8 +938,8 @@ xg_frame_resized (struct frame *f, int width, int height) frame_size_history_extra (f, build_string ("xg_frame_resized, unchanged"), FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height, - delayed_size_change ? f->new_width : -1, - delayed_size_change ? f->new_height : -1); + f->new_size_p ? f->new_width : -1, + f->new_size_p ? f->new_height : -1); } @@ -1026,17 +1028,17 @@ xg_frame_set_char_size (struct frame *f, int width, int height) the frame is mapped again we will (hopefully) get the correct size. */ if (FRAME_VISIBLE_P (f) && !was_visible) { - /* Must call this to flush out events */ - (void)gtk_events_pending (); - gdk_flush (); - x_wait_for_event (f, ConfigureNotify); - if (CONSP (frame_size_history)) frame_size_history_extra (f, build_string ("xg_frame_set_char_size, visible"), FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height, f->new_width, f->new_height); + /* Must call this to flush out events */ + (void)gtk_events_pending (); + gdk_flush (); + x_wait_for_event (f, ConfigureNotify); + if (!NILP (fullscreen)) /* Try to restore fullscreen state. */ { diff --git a/src/xterm.c b/src/xterm.c index 5049f72ca63..189e3a47eea 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9071,8 +9071,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, to check the pixel dimensions as well. */ if (width != FRAME_PIXEL_WIDTH (f) || height != FRAME_PIXEL_HEIGHT (f) - || (delayed_size_change - && (width != f->new_width || height != f->new_height))) + || (f->new_size_p + && ((f->new_width >= 0 && width != f->new_width) + || (f->new_height >= 0 && height != f->new_height)))) { change_frame_size (f, width, height, false, true, false); x_clear_under_internal_border (f);