From 8a4081c396a47aa7593a6c25b1bad8a2b8b157b7 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Sun, 2 May 2021 10:33:22 +0200 Subject: [PATCH] Make adjust_frame_size set up frame's new_width/_height too (Bug#17120) The purpose of this change is to have implied frame size changes pick up sizes requested by previous explicit size changes not only after they have been confirmed by the WM but already when they are initially passed to adjust_frame_size (Bug#17120). * src/dispextern.h (delayed_size_change): Remove extern. * src/dispnew.c (delayed_size_change): Make static again. (do_pending_window_change): Call change_frame_size only if F's new_size_p flag is set. (change_frame_size_1): Set/reset F's new_size_p flag * src/frame.c (adjust_frame_size): Remove extra inhibit_horizontal/_vertical checks. Improve the implied resizes check with INHIBIT equals 2. Set F's new_width and new_height and reset F's new_size_p flag when we run set_window_size_hook with INHIBIT 0 or 1. * src/frame.h (struct frame): New bit slot new_size_p. * src/gtkutil.c (xg_frame_resized): Use F's new_size_p flag instead of delayed_size_change to decide whether to call change_frame_size. (xg_frame_set_char_size): Call frame_size_history_extra before waiting for the ConfigureNotify event. * src/xterm.c (handle_one_xevent): Use F's new_size_p flag instead of delayed_size_change to decide whether to call change_frame_size. --- src/dispextern.h | 2 -- src/dispnew.c | 15 ++++++++++----- src/frame.c | 22 ++++++++++++++++------ src/frame.h | 5 +++++ src/gtkutil.c | 26 ++++++++++++++------------ src/xterm.c | 5 +++-- 6 files changed, 48 insertions(+), 27 deletions(-) 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); -- 2.39.2