From 1281af6d350a8ae34c34ac323c5febea215be526 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Sun, 23 Feb 2025 11:01:20 +0100 Subject: [PATCH] Optionally inhibit implied resizing while frame is made (Bug#76275) * src/frame.c (frame_inhibit_resize): Handle new value 'force' for 'frame-inhibit-implied-resize' (Bug#76275). (frame_inhibit_implied_resize): New value 'force' to inhibit implied resizing while a new frame is made. * lisp/cus-start.el (frame-inhibit-implied-resize): Make new value 'force' customizable. * doc/lispref/frames.texi (Implied Frame Resizing): Describe new value 'force' of 'frame-inhibit-implied-resize'. * etc/NEWS: Announce new value 'force' of 'frame-inhibit-implied-resize'. (cherry picked from commit 499da9e1a9f63d9a767a3cab1f7771799e1d3274) --- doc/lispref/frames.texi | 10 ++++--- lisp/cus-start.el | 3 ++- src/frame.c | 58 +++++++++++++++++++++++++---------------- 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 984f9bb597d..c6870f3ff28 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -1247,9 +1247,13 @@ resizing with the following option: @defopt frame-inhibit-implied-resize If this option is @code{nil}, changing a frame's font, menu bar, tool -bar, internal borders, fringes or scroll bars may resize its outer -frame in order to keep the number of columns or lines of its text area -unaltered. If this option is @code{t}, no such resizing is done. +bar, internal borders, fringes or scroll bars may resize its outer frame +in order to keep the number of columns or lines of its text area +unaltered. If this option is @code{t}, no such resizing is done once a +frame has obtained its initial size. If this is the symbol +@code{force}, no implicit resizing is done whenever a new frame is made. +The latter can be useful with tiling window managers where the initial +size of a frame is determined by external means. The value of this option can be also a list of frame parameters. In that case, implied resizing is inhibited for the change of a parameter diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 0ed7fbd7b9c..133f44c9fad 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -344,8 +344,9 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (choice (const :tag "Never" nil) (const :tag "Always" t) + (const :tag "Force" force) (repeat (symbol :tag "Parameter"))) - "27.1") + "31.1") (iconify-child-frame frames (choice (const :tag "Do nothing" nil) diff --git a/src/frame.c b/src/frame.c index ccd95b8bf4e..f3b76320cb4 100644 --- a/src/frame.c +++ b/src/frame.c @@ -172,27 +172,34 @@ get_frame_param (struct frame *frame, Lisp_Object prop) } -/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen - state of frame F would be affected by a vertical (horizontal if - HORIZONTAL is true) resize. PARAMETER is the symbol of the frame - parameter that is changed. */ +/* Return true if 'frame-inhibit-implied-resize' is non-nil or + fullscreen state of frame F would be affected by a vertical + (horizontal if HORIZONTAL is true) resize. PARAMETER is the symbol + of the frame parameter about to be changed. + + If 'frame-inhibit-implied-resize' equals 'force', unconditionally + return true (Bug#76275). Otherwise, return nil if F has not been + made yet and (on GTK) its tool bar has not been resized at least + once. Together these should ensure that F always gets its requested + initial size. */ bool frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter) { Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); - return (f->after_make_frame + return (EQ (frame_inhibit_implied_resize, Qforce) + || (f->after_make_frame #ifdef USE_GTK - && f->tool_bar_resized + && f->tool_bar_resized #endif - && (EQ (frame_inhibit_implied_resize, Qt) - || (CONSP (frame_inhibit_implied_resize) - && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))) - || (horizontal - && !NILP (fullscreen) && !EQ (fullscreen, Qfullheight)) - || (!horizontal - && !NILP (fullscreen) && !EQ (fullscreen, Qfullwidth)) - || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))); + && (EQ (frame_inhibit_implied_resize, Qt) + || (CONSP (frame_inhibit_implied_resize) + && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))) + || (horizontal + && !NILP (fullscreen) && !EQ (fullscreen, Qfullheight)) + || (!horizontal + && !NILP (fullscreen) && !EQ (fullscreen, Qfullwidth)) + || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)))); } @@ -6849,6 +6856,7 @@ syms_of_frame (void) DEFSYM (Qmake_invisible, "make-invisible"); DEFSYM (Quse_frame_synchronization, "use-frame-synchronization"); DEFSYM (Qfont_parameter, "font-parameter"); + DEFSYM (Qforce, "force"); for (int i = 0; i < ARRAYELTS (frame_parms); i++) { @@ -7102,12 +7110,14 @@ a non-nil value in your init file. */); DEFVAR_LISP ("frame-inhibit-implied-resize", frame_inhibit_implied_resize, doc: /* Whether frames should be resized implicitly. -If this option is nil, setting font, menu bar, tool bar, tab bar, internal -borders, fringes or scroll bars of a specific frame may resize the frame -in order to preserve the number of columns or lines it displays. If -this option is t, no such resizing is done. Note that the size of -fullscreen and maximized frames, the height of fullheight frames and the -width of fullwidth frames never change implicitly. +If this option is nil, setting font, menu bar, tool bar, tab bar, +internal borders, fringes or scroll bars of a specific frame may resize +the frame in order to preserve the number of columns or lines it +displays. If this option is t, no such resizing is done once a frame +has got its initial size. If this is the symbol `force', no implicit +resizing is done whenever a new frame is made. This can be useful with +tiling window managers where the initial size of a frame is determined +by external means. The value of this option can be also a list of frame parameters. In this case, resizing is inhibited when changing a parameter that @@ -7132,9 +7142,11 @@ adding/removing a tool bar or tab bar does not change the frame height. Otherwise it's t which means the frame size never changes implicitly when there's no window system support. -Note that when a frame is not large enough to accommodate a change of -any of the parameters listed above, Emacs may try to enlarge the frame -even if this option is non-nil. */); +Note that the size of fullscreen and maximized frames, the height of +fullheight frames and the width of fullwidth frames never change +implicitly. Note also that when a frame is not large enough to +accommodate a change of any of the parameters listed above, Emacs may +try to enlarge the frame even if this option is non-nil. */); #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_ANDROID) #if defined (USE_GTK) || defined (HAVE_NS) frame_inhibit_implied_resize = list1 (Qtab_bar_lines); -- 2.39.5