unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Proposing changes to adjust_frame_size
@ 2021-04-25 17:11 martin rudalics
  2021-04-27  8:22 ` martin rudalics
  2021-05-01 18:59 ` Alan Third
  0 siblings, 2 replies; 65+ messages in thread
From: martin rudalics @ 2021-04-25 17:11 UTC (permalink / raw)
  To: emacs-devel; +Cc: Alan Third, Yuuki Harano

[-- Attachment #1: Type: text/plain, Size: 1166 bytes --]

Unless there are objections, I intend to apply the attached changes in
the next days.  Their purpose is to restrain the handling of the text
area size of a frame to the function adjust_frame_size and have the
various front/backends setting frame sizes or receiving notifications
about them work with native frame sizes only.  This has the advantage
that storing the history of frame size changes and consequently tracking
bugs in the frame sizing code become much simpler.

The patch should fix Bug#46827 and I intend to add further bug fixes in
the following days.  Some of these fixes are controversial and I'd like
to push them separately in order to make bisecting easier.  Other than
that, there should be no user noticeable changes, so if you observe any
strange frame sizing behavior, please tell me.

I've tested the patch with xfwm4, gnome shell, kde plasma and Windows XP
but have given it only light testing with GNUstep.  Alan, if you see
anything fishy with the NS build, please tell me.  Yuuki, if you see any
problems with the pgtk build, please tell me too so we can resolve them
without causing greater conflicts.

Thanks for your attention, martin

[-- Attachment #2: adjust_frame_size_ChangeLog --]
[-- Type: text/plain, Size: 9057 bytes --]

Have adjust_frame_size pass native frame sizes to backends
instead of text sizes.  Expand frame size history management.
Drop PIXELWISE argument from change_frame_size and convert
native to text sizes only when calling adjust_frame_size.  Use
convention in arguments that -1 instead of 0 means that no size
change is required.  When adjusting frame sizes pick up delayed
size changes (Bug#46827).

* lisp/frame.el (frame-notice-user-settings, make-frame): Don't
set frame size history.
(frame--size-history): Rewrite doc-string.  Handle new formats
of `frame-size-history' entries.
* src/dispextern.h (delayed_size_change): Extern it.
(change_frame_size): Drop last argument from extern.
* src/dispnew.c (delayed_size_change): Make it global.
(handle_window_change_signal): Reformat.  Drop last argument
from change_frame_size call.
(do_pending_window_change, init_display_interactive): Drop last
argument from change_frame_size call.
(change_frame_size_1): NEW_WIDTH and NEW_HEIGHT now specify
native sizes.  Drop last argument PIXELWISE.  Queue a change
when it either differs from F's current pixel sizes or F's
previously queued sizes.  Inject frame_size_history_extra call
when queuing.  Adopt convention that for queued sizes -1 means
that no size change is required.  Convert from native to text
sizes when calling adjust_frame_size.
(change_frame_size): Drop last argument PIXELWISE and drop it
also in change_frame_size_1 calls.
* src/frame.c (frame_size_history_add): Remove.
(frame_inhibit_resize): Remove call to frame_size_history_add.
(set_menu_bar_lines, set_tab_bar_lines): Simplify.  Drop last
argument from change_frame_size call.
(frame_windows_min_size): No more static.
(keep_ratio): Minor rewrite using macros.
(frame_size_history_adjust, frame_size_history_plain)
(frame_size_history_extra): New functions.
(adjust_frame_size): Major rewrite.  Adopt new convention that
negative values for new sizes mean no change.  Pick up delayed
size changes from F's new_width and new_height slots
(Bug#46827).  Call set_window_size_hook with native instead of
text sizes.  Do not sanitize window sizes any more.  Call
frame_size_history_adjust instead of frame_size_history_add.
Always set F's resized_p slot to true.
(make_frame): Initialize new_width and new_height slots to -1.
Simplify setup of initial sizes and an adjust_frame_size call.
(Fframe_parameters): Drop processing F's new_pixelwise slot.
(check_frame_pixels): Reorder to make declarations appear first.
(Fset_frame_height, Fset_frame_width, Fset_frame_size): Pass
explicit width and height values to adjust_frame_size instead of
-1.
(gui_set_frame_parameters): Minor rewrite making sure that
explicit sizes and the corresponding parameter are passed to
adjust_frame_size.  Remove frame_size_history_add call.
(gui_figure_window_size): Drop last two arguments.  Simplify
assignment of initial size.  Set new_height and new_width slots
to -1.  Use adjust_frame_size to set sizes instead of returning
them to caller.
(syms_of_frame): Drop symbols used by frame size history; these
are now built on-the-fly.  Also drop some menu bar related
symbols in favor of Qmenu_bar_lines.
* src/frame.h (struct frame): Remove new_pixelwise.
(SET_FRAME_COLS, SET_FRAME_LINES, SET_FRAME_WIDTH)
(SET_FRAME_HEIGHT): Remove macros.
(frame_size_history_add): Remove externs.
(frame_windows_min_size, frame_size_history_plain)
(frame_size_history_extra): Add externs.
(FRAME_WINDOWS_WIDTH, FRAME_WINDOWS_HEIGHT): Rename to
FRAME_INNER_WIDTH and FRAME_INNER_HEIGHT.
(gui_figure_window_size): Drop last two arguments from
extern.
* src/gtkutil.c (xg_frame_resized): Rename arguments to WIDTH
and HEIGHT.  Consult delayed_size_change to handle case where
WIDTH and HEIGHT do not match F's new_width and new_height
values.  Call change_frame_size with native sizes and without
PIXELWISE argument.  Instead of frame_size_history_add call
frame_size_history_extra.
(xg_frame_set_char_size): WIDTH and HEIGHT are native sizes now;
fix adjust_frame_size call accordingly.  Instead of
frame_size_history_add call frame_size_history_extra.
(style_changed_cb): Call xg_frame_set_char_size with native
instead of text sizes.
(tb_size_cb): Remove frame_size_history_add call.  Call
adjust_frame_size with INHIBIT 5.
(free_frame_tool_bar, xg_change_toolbar_position): Remove
frame_size_history_add call.
(update_frame_tool_bar): Call adjust_frame_size with INHIBIT 2
and let it handle frame_inhibit_implied_resize and
fullheight/-width.  Remove frame_size_history_add call.
* src/keyboard.c (Fsuspend_emacs): Call change_frame_size with
native sizes.
* src/nsfns.m (ns_set_tool_bar_lines): Call adjust_frame_size
with INHIBIT 2 and let it handle frame_inhibit_implied_resize
and fullheight/-width.  Remove frame_size_history_add call.
(Fx_create_frame): Drop two last arguments in
gui_figure_window_size call.  Do not SET_FRAME_WIDTH and
SET_FRAME_HEIGHT, the adjust_frame_size in
gui_figure_window_size did that already.
* src/nsterm.m (ns_set_window_size): Drop PIXELWISE argument and
its processing; WIDTH and HEIGHT represent native pixel sizes
now.  Call change_frame_size with native sizes.  Remove call to
frame_size_history_add.
([EmacsView viewDidResize:]): Call change_frame_size with native
sizes.
* src/term.c (Fresume_tty): Call change_frame_size with native
sizes.
* src/termhooks.h (*set_window_size_hook): Drop last argument
PIXELWISE.
* src/w32fns.c (w32_change_tab_bar_height)
(w32_change_tool_bar_height): Fix handling of these in the initial
phase before they have been resized at least once.
(Fx_create_frame, w32_create_tip_frame): Drop two last arguments
in gui_figure_window_size call.  Do not SET_FRAME_WIDTH and
SET_FRAME_HEIGHT (or SET_FRAME_COLS and SET_FRAME_LINES), the
adjust_frame_size in gui_figure_window_size did that already.
* src/w32inevt.c (resize_event, maybe_generate_resize_event):
Pass native sizes to change_frame_size.
* src/w32term.c (w32_read_socket): When WM_WINDOWPOSCHANGED pass
native sizes to change_frame_size.
(w32_new_font): Recalculate FRAME_TAB_BAR_HEIGHT.  Simplify
code.
(w32fullscreen_hook): Call change_frame_size with native sizes.
(w32_set_window_size): Drop argument PIXELWISE and its
processing; WIDTH and HEIGHT are native sizes now.  Remove
frame_size_history_add calls.  Pass native sizes to
change_frame_size.
* src/widget.c (set_frame_size): Set width and height of widget
directly.  Call frame_size_history_plain instead of
frame_size_history_add.
(update_from_various_frame_slots): Call
frame_size_history_extra.
(EmacsFrameRealize): Call frame_size_history_plain.
(EmacsFrameResize): Call change_frame_size with native sizes.
Call frame_size_history_extra instead of frame_size_history_add.
(EmacsFrameSetCharSize): Call frame_size_history_extra.  Drop
PIXELWISE argument in x_set_window_size call and specify pixels.
(pixel_to_text_size): Remove function.
* src/xdisp.c (resize_mini_window): Replace FRAME_WINDOWS_HEIGHT
with FRAME_INNER_HEIGHT.
(redisplay_tab_bar): Don't set tab_bar_redisplayed when we did
not redisplay it.
(redisplay_tool_bar): Don't call it for external tool bar.
Don't set tool_bar_redisplayed when we did not redisplay it.
(redisplay_window): When the tool bar is external call
update_frame_tool_bar directly.
* src/xfns.c (x_set_menu_bar_lines): Call adjust_frame_size only
if number of menu bar lines changed and fix 6th argument.
(x_change_tab_bar_height, x_change_tool_bar_height): Fix
handling of these in the initial phase before they have been
resized at least once.
(Fx_create_frame, x_create_tip_frame): Drop two last arguments
in gui_figure_window_size call.  Do not SET_FRAME_WIDTH and
SET_FRAME_HEIGHT (or SET_FRAME_COLS and SET_FRAME_LINES), the
adjust_frame_size in gui_figure_window_size did that already.
* src/xmenu.c (update_frame_menubar): Fix 6th arg of
adjust_frame_size call.
(free_frame_menubar): For Motif frames fix fullscreen and
`frame-inhibit-implied-resize' handling.  Fix 6th arg of
adjust_frame_size calls.
* src/xterm.c (x_net_wm_state): Remove call to
frame_size_history_add.
(handle_one_xevent): For PropertyNotify and UnmapNotify events
add frame_size_history_plain calls.  For MapNotify and
ConfigureNotify events add a frame_size_history_extra call.  For
ConfigureNotify events also handle delayed size changes and call
change_frame_size with native sizes.
(x_new_font): Recalculate FRAME_TAB_BAR_HEIGHT.  Simplify code.
(x_handle_net_wm_state): Remove frame_size_history_add call.
(x_check_fullscreen): Remove frame_size_history_add call.  Call
change_frame_size with native height.
(x_set_window_size_1): WIDTH and HEIGHT are now native.  Remove
some frame_size_history_add calls and add frame_size_history_extra
calls instead.  If the frame is not visible call adjust_frame_size
directly instead of calling change_frame_size.
(x_set_window_size): Drop PIXELWISE argument.  WIDTH and HEIGHT
represent native sizes now.
(x_make_frame_visible, x_make_frame_invisible): Call
frame_size_history_plain.
* src/xterm.h (x_set_window_size): Drop last argument from
extern declaration.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: adjust_frame_size.diff --]
[-- Type: text/x-patch; name="adjust_frame_size.diff", Size: 157689 bytes --]

diff --git a/lisp/frame.el b/lisp/frame.el
index bca160175a..aff1d479ec 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -615,15 +615,6 @@ frame-notice-user-settings
 	      (face-set-after-frame-default frame-initial-frame)
 	      (setq newparms (delq new-bg newparms)))
 
-	    (when (numberp (car frame-size-history))
-	      (setq frame-size-history
-		    (cons (1- (car frame-size-history))
-			  (cons
-			   (list frame-initial-frame
-				 "FRAME-NOTICE-USER"
-				 nil newparms)
-			   (cdr frame-size-history)))))
-
 	    (modify-frame-parameters frame-initial-frame newparms)))))
 
     ;; Restore the original buffer.
@@ -926,12 +917,6 @@ make-frame
         (let ((val (frame-parameter oldframe param)))
           (when val (set-frame-parameter frame param val)))))
 
-    (when (numberp (car frame-size-history))
-      (setq frame-size-history
-	    (cons (1- (car frame-size-history))
-		  (cons (list frame "MAKE-FRAME")
-			(cdr frame-size-history)))))
-
     ;; We can run `window-configuration-change-hook' for this frame now.
     (frame-after-make-frame frame t)
     (run-hook-with-args 'after-make-frame-functions frame)
@@ -1695,26 +1680,104 @@ frame-geometry
 
 (defun frame--size-history (&optional frame)
   "Print history of resize operations for FRAME.
-Print prettified version of `frame-size-history' into a buffer
-called *frame-size-history*.  Optional argument FRAME denotes the
-frame whose history will be printed.  FRAME defaults to the
-selected frame."
+This function dumps a prettified version of `frame-size-history'
+into a buffer called *frame-size-history*.  The optional argument
+FRAME denotes the frame whose history will be dumped; it defaults
+to the selected frame.
+
+Storing information about resize operations is off by default.
+If you set the variable `frame-size-history' like this
+
+(setq frame-size-history '(100))
+
+then Emacs will save information about the next 100 significant
+operations affecting any frame's size in that variable.  This
+function prints the entries for FRAME stored in that variable in
+a more legible way.
+
+All lines start with an indication of the requested action.  An
+entry like `menu-bar-lines' or `scroll-bar-width' indicates that
+a change of the corresponding frame parameter or Lisp variable
+was requested.  An entry like gui_figure_window_size indicates
+that that C function was executed, an entry like ConfigureNotify
+indicates that that event was received.
+
+In long entries, a number in parentheses displays the INHIBIT
+parameter passed to the C function adjust_frame_size.  Such
+entries may also display changes of frame rectangles in a form
+like R=n1xn2~>n3xn4 where R denotes the rectangle type (TS for
+text, NS for native and IS for inner frame rectangle sizes, all
+in pixels, TC for text rectangle sizes in frame columns and
+lines), n1 and n2 denote the old width and height and n3 and n4
+the new width and height in the according units.  MS stands for
+the minimum inner frame size in pixels, IH and IV, if present,
+indicate that resizing horizontally and/or vertically was
+inhibited (either by `frame-inhibit-implied-resize' or because of
+the frame's fullscreen state).
+
+Shorter entries represent C functions that process width and
+height changes of the native rectangle where PS stands for the
+frame's present pixel width and height, XS for a requested pixel
+width and height and DS for some earlier requested but so far
+delayed pixel width and height.
+
+Very short entries represent calls of C functions that do not
+directly ask for size changes but may indirectly affect the size
+of frames like calls to map a frame or change its visibility."
   (let ((history (reverse frame-size-history))
-	entry)
+	entry item)
     (setq frame (window-normalize-frame frame))
     (with-current-buffer (get-buffer-create "*frame-size-history*")
       (erase-buffer)
       (insert (format "Frame size history of %s\n" frame))
       (while (consp (setq entry (pop history)))
-	(when (eq (car entry) frame)
-          (pop entry)
-          (insert (format "%s" (pop entry)))
-          (move-to-column 24 t)
-          (while entry
-            (insert (format " %s" (pop entry))))
-          (insert "\n")))
-      (unless frame-size-history
-        (insert "Frame size history is nil.\n")))))
+        (setq item (car entry))
+	(cond
+         ((not (consp item))
+          ;; An item added quickly for debugging purposes.
+          (insert (format "%s\n" entry)))
+         ((and (eq (nth 0 item) frame) (= (nth 1 item) 1))
+          ;; Length 1 is a "plain event".
+          (insert (format "%s\n" (nth 2 item))))
+         ((and (eq (nth 0 item) frame) (= (nth 1 item) 2))
+          ;; Length 2 is an "extra" item.
+          (insert (format "%s" (nth 2 item)))
+          (setq item (nth 0 (cdr entry)))
+          (insert (format ", PS=%sx%s" (nth 0 item) (nth 1 item)))
+          (when (or (>= (nth 2 item) 0) (>= (nth 3 item) 0))
+            (insert (format ", XS=%sx%s" (nth 2 item) (nth 3 item))))
+          (setq item (nth 1 (cdr entry)))
+          (when (or (>= (nth 0 item) 0) (>= (nth 1 item) 0))
+            (insert (format ", DS=%sx%s" (nth 0 item) (nth 1 item))))
+          (insert "\n"))
+         ((and (eq (nth 0 item) frame) (= (nth 1 item) 5))
+          ;; Length 5 is an `adjust-frame-size' item.
+          (insert (format "%s (%s)" (nth 3 item) (nth 2 item)))
+          (setq item (nth 0 (cdr entry)))
+          (unless (and (= (nth 0 item) (nth 2 item))
+                       (= (nth 1 item) (nth 3 item)))
+            (insert (format ", TS=%sx%s~>%sx%s"
+                            (nth 0 item) (nth 1 item) (nth 2 item) (nth 3 item))))
+          (setq item (nth 1 (cdr entry)))
+          (unless (and (= (nth 0 item) (nth 2 item))
+                       (= (nth 1 item) (nth 3 item)))
+            (insert (format ", TC=%sx%s~>%sx%s"
+                            (nth 0 item) (nth 1 item) (nth 2 item) (nth 3 item))))
+          (setq item (nth 2 (cdr entry)))
+          (unless (and (= (nth 0 item) (nth 2 item))
+                       (= (nth 1 item) (nth 3 item)))
+            (insert (format ", NS=%sx%s~>%sx%s"
+                            (nth 0 item) (nth 1 item) (nth 2 item) (nth 3 item))))
+          (setq item (nth 3 (cdr entry)))
+          (unless (and (= (nth 0 item) (nth 2 item))
+                       (= (nth 1 item) (nth 3 item)))
+            (insert (format ", IS=%sx%s~>%sx%s"
+                            (nth 0 item) (nth 1 item) (nth 2 item) (nth 3 item))))
+          (setq item (nth 4 (cdr entry)))
+          (insert (format ", MS=%sx%s" (nth 0 item) (nth 1 item)))
+          (when (nth 2 item) (insert " IH"))
+          (when (nth 3 item) (insert " IV"))
+          (insert "\n")))))))
 
 (declare-function x-frame-edges "xfns.c" (&optional frame type))
 (declare-function w32-frame-edges "w32fns.c" (&optional frame type))
diff --git a/src/dispextern.h b/src/dispextern.h
index a2ebd04f23..213032d4de 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1262,7 +1262,7 @@ #define MATRIX_ROW_OVERLAPS_SUCC_P(ROW)		\
 /* True means last display completed.  False means it was preempted.  */
 
 extern bool display_completed;
-
+extern bool delayed_size_change;
 
 \f
 /************************************************************************
@@ -3641,7 +3641,7 @@ #define IMAGE_BACKGROUND_TRANSPARENT(img, f, mask)			      \
 extern void gui_update_window_end (struct window *, bool, bool);
 #endif
 void do_pending_window_change (bool);
-void change_frame_size (struct frame *, int, int, bool, bool, bool, bool);
+void change_frame_size (struct frame *, int, int, bool, bool, bool);
 void init_display (void);
 void syms_of_display (void);
 extern void spec_glyph_lookup_face (struct window *, GLYPH *);
diff --git a/src/dispnew.c b/src/dispnew.c
index f613f7b656..b3f7be67e0 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -102,7 +102,7 @@ Copyright (C) 1985-1988, 1993-1995, 1997-2021 Free Software Foundation,
 
 /* True means SIGWINCH happened when not safe.  */
 
-static bool delayed_size_change;
+bool delayed_size_change;
 
 /* A glyph for a space.  */
 
@@ -5770,32 +5770,34 @@ handle_window_change_signal (int sig)
      termcap-controlled terminal, but we can't decide which.
      Therefore, we resize the frames corresponding to each tty.
   */
-  for (tty = tty_list; tty; tty = tty->next) {
+  for (tty = tty_list; tty; tty = tty->next)
+    {
+      if (! tty->term_initted)
+	continue;
 
-    if (! tty->term_initted)
-      continue;
+      /* Suspended tty frames have tty->input == NULL avoid trying to
+	 use it.  */
+      if (!tty->input)
+	continue;
 
-    /* Suspended tty frames have tty->input == NULL avoid trying to
-       use it.  */
-    if (!tty->input)
-      continue;
+      get_tty_size (fileno (tty->input), &width, &height);
 
-    get_tty_size (fileno (tty->input), &width, &height);
+      if (width > 5 && height > 2)
+	{
+	  Lisp_Object tail, frame;
 
-    if (width > 5 && height > 2) {
-      Lisp_Object tail, frame;
+	  FOR_EACH_FRAME (tail, frame)
+	    {
+	      struct frame *f = XFRAME (frame);
 
-      FOR_EACH_FRAME (tail, frame)
-        if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
-          /* Record the new sizes, but don't reallocate the data
-             structures now.  Let that be done later outside of the
-             signal handler.  */
-          change_frame_size (XFRAME (frame), width,
-			     height - FRAME_MENU_BAR_LINES (XFRAME (frame))
-			     - FRAME_TAB_BAR_LINES (XFRAME (frame)),
-			     0, 1, 0, 0);
+	      if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty)
+		/* Record the new sizes, but don't reallocate the data
+		   structures now.  Let that be done later outside of the
+		   signal handler.  */
+		change_frame_size (f, width, height, false, true, false);
+	    }
+	}
     }
-  }
 }
 
 static void
@@ -5821,15 +5823,17 @@ do_pending_window_change (bool safe)
     {
       Lisp_Object tail, frame;
 
-      delayed_size_change = 0;
+      delayed_size_change = false;
 
       FOR_EACH_FRAME (tail, frame)
 	{
 	  struct frame *f = XFRAME (frame);
 
-	  if (f->new_height != 0 || f->new_width != 0)
+	  /* 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)
 	    change_frame_size (f, f->new_width, f->new_height,
-			       0, 0, safe, f->new_pixelwise);
+			       false, false, safe);
 	}
     }
 }
@@ -5837,47 +5841,43 @@ do_pending_window_change (bool safe)
 
 static void
 change_frame_size_1 (struct frame *f, int new_width, int new_height,
-		     bool pretend, bool delay, bool safe, bool pixelwise)
+		     bool pretend, bool delay, bool safe)
 {
-  /* If we can't deal with the change now, queue it for later.  */
   if (delay || (redisplaying_p && !safe))
     {
+      if (CONSP (frame_size_history)
+	  && ((new_width != f->new_width
+	       || new_height != f->new_height
+	       || new_width != FRAME_PIXEL_WIDTH (f)
+	       || new_height != FRAME_PIXEL_HEIGHT (f))))
+	frame_size_history_extra
+	  (f, build_string ("change_frame_size_1, delayed"),
+	   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+	   new_width, new_height, f->new_width, f->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_pixelwise = pixelwise;
-      delayed_size_change = 1;
+      delayed_size_change = true;
     }
   else
     {
-      /* This size-change overrides any pending one for this frame.  */
-      f->new_height = 0;
-      f->new_width = 0;
-      f->new_pixelwise = 0;
-
-      /* If an argument is zero, set it to the current value.  */
-      if (pixelwise)
-	{
-	  new_width = (new_width <= 0) ? FRAME_TEXT_WIDTH (f) : new_width;
-	  new_height = (new_height <= 0) ? FRAME_TEXT_HEIGHT (f) : new_height;
-	}
-      else
-	{
-	  new_width = (((new_width <= 0) ? FRAME_COLS (f) : new_width)
-		       * FRAME_COLUMN_WIDTH (f));
-	  new_height = (((new_height <= 0) ? FRAME_LINES (f) : new_height)
-			* FRAME_LINE_HEIGHT (f));
-	}
-
-      /* Adjust frame size but make sure set_window_size_hook does not
-	 get called.  */
-      adjust_frame_size (f, new_width, new_height, 5, pretend,
-			 Qchange_frame_size);
+      /* Storing -1 in the new_width/new_height slots means that no size
+	 change is pending.  Native sizes are always non-negative.  */
+      f->new_height = -1;
+      f->new_width = -1;
+      /* 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.  */
+      adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, new_width),
+			 FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_height), 5,
+			 pretend, Qchange_frame_size);
     }
 }
 
 
-/* Change text height/width of frame F.  Values may be given as zero to
-   indicate that no change is needed.
+/* Change native height/width of frame F to NEW_WIDTH/NEW_HEIGHT pixels.
+   Values may be given as -1 to indicate that no change is needed.
 
    If DELAY, assume we're being called from a signal handler, and queue
    the change for later - perhaps the next redisplay.  Since this tries
@@ -5887,7 +5887,7 @@ change_frame_size_1 (struct frame *f, int new_width, int new_height,
    change frame sizes while a redisplay is in progress.  */
 void
 change_frame_size (struct frame *f, int new_width, int new_height,
-		   bool pretend, bool delay, bool safe, bool pixelwise)
+		   bool pretend, bool delay, bool safe)
 {
   Lisp_Object tail, frame;
 
@@ -5897,13 +5897,12 @@ change_frame_size (struct frame *f, int new_width, int new_height,
          size affects all frames.  Termcap now supports multiple
          ttys. */
       FOR_EACH_FRAME (tail, frame)
-	if (! FRAME_WINDOW_P (XFRAME (frame)))
+	if (!FRAME_WINDOW_P (XFRAME (frame)))
 	  change_frame_size_1 (XFRAME (frame), new_width, new_height,
-			       pretend, delay, safe, pixelwise);
+			       pretend, delay, safe);
     }
   else
-    change_frame_size_1 (f, new_width, new_height, pretend, delay, safe,
-			 pixelwise);
+    change_frame_size_1 (f, new_width, new_height, pretend, delay, safe);
 }
 \f
 /***********************************************************************
@@ -6492,9 +6491,8 @@ init_display_interactive (void)
     t->display_info.tty->top_frame = selected_frame;
     change_frame_size (XFRAME (selected_frame),
                        FrameCols (t->display_info.tty),
-                       FrameRows (t->display_info.tty)
-		       - FRAME_MENU_BAR_LINES (f)
-		       - FRAME_TAB_BAR_LINES (f), 0, 0, 1, 0);
+                       FrameRows (t->display_info.tty),
+		       false, false, true);
 
     /* Delete the initial terminal. */
     if (--initial_terminal->reference_count == 0
diff --git a/src/frame.c b/src/frame.c
index 097cd555c6..4129a70aa5 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -150,29 +150,6 @@ get_frame_param (struct frame *frame, Lisp_Object prop)
 }
 
 
-void
-frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
-			int width, int height, Lisp_Object rest)
-{
-  Lisp_Object frame;
-
-  XSETFRAME (frame, f);
-  if (CONSP (frame_size_history)
-      && FIXNUMP (XCAR (frame_size_history))
-      && 0 < XFIXNUM (XCAR (frame_size_history)))
-    frame_size_history =
-      Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
-	     Fcons (list4
-		    (frame, fun_symbol,
-		     ((width > 0)
-		      ? list4i (FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
-				width, height)
-		      : Qnil),
-		     rest),
-		    XCDR (frame_size_history)));
-}
-
-
 /* 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
@@ -193,78 +170,54 @@ frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
 	  || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
        : ((horizontal && f->inhibit_horizontal_resize)
 	  || (!horizontal && f->inhibit_vertical_resize)));
-  if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
-    frame_size_history_add
-      (f, Qframe_inhibit_resize, 0, 0,
-       list5 (horizontal ? Qt : Qnil, parameter,
-	      f->after_make_frame ? Qt : Qnil,
-	      frame_inhibit_implied_resize,
-	      fullscreen));
 
   return inhibit;
 }
 
+
+/** Set menu bar lines for a TTY frame.  */
 static void
 set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
-  int nlines;
   int olines = FRAME_MENU_BAR_LINES (f);
+  int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
 
   /* Right now, menu bars don't work properly in minibuf-only frames;
      most of the commands try to apply themselves to the minibuffer
      frame itself, and get an error because you can't switch buffers
      in or split the minibuffer window.  */
-  if (FRAME_MINIBUF_ONLY_P (f))
-    return;
-
-  if (TYPE_RANGED_FIXNUMP (int, value))
-    nlines = XFIXNUM (value);
-  else
-    nlines = 0;
-
-  if (nlines != olines)
+  if (!FRAME_MINIBUF_ONLY_P (f) && nlines != olines)
     {
       windows_or_buffers_changed = 14;
-      FRAME_MENU_BAR_LINES (f) = nlines;
-      FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
-      change_frame_size (f, FRAME_COLS (f),
-			 FRAME_LINES (f) + olines - nlines,
-			 0, 1, 0, 0);
+      FRAME_MENU_BAR_LINES (f) = FRAME_MENU_BAR_HEIGHT (f) = nlines;
+      change_frame_size (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+			 false, true, false);
     }
 }
 
+
+/** Set tab bar lines for a TTY frame.  */
 static void
 set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 {
-  int nlines;
   int olines = FRAME_TAB_BAR_LINES (f);
+  int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
 
   /* Right now, tab bars don't work properly in minibuf-only frames;
      most of the commands try to apply themselves to the minibuffer
      frame itself, and get an error because you can't switch buffers
      in or split the minibuffer window.  */
-  if (FRAME_MINIBUF_ONLY_P (f))
-    return;
-
-  if (TYPE_RANGED_FIXNUMP (int, value))
-    nlines = XFIXNUM (value);
-  else
-    nlines = 0;
-
-  if (nlines != olines)
+  if (!FRAME_MINIBUF_ONLY_P (f) && nlines != olines)
     {
       windows_or_buffers_changed = 14;
-      FRAME_TAB_BAR_LINES (f) = nlines;
-      FRAME_TAB_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
-      change_frame_size (f, FRAME_COLS (f),
-			 FRAME_LINES (f) + olines - nlines,
-			 0, 1, 0, 0);
+      FRAME_TAB_BAR_LINES (f) = FRAME_TAB_BAR_HEIGHT (f) = nlines;
+      change_frame_size (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+			 false, true, false);
     }
 }
 \f
 Lisp_Object Vframe_list;
 
-\f
 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
        doc: /* Return non-nil if OBJECT is a frame.
 Value is:
@@ -366,14 +319,15 @@ DEFUN ("frame-windows-min-size", Fframe_windows_min_size,
  *
  * If `frame-windows-min-size' is called, it will make sure that the
  * return value accommodates all windows of FRAME respecting the values
- * of `window-min-height' (`window-min-width' if HORIZONTAL is non-nil).
- * With IGNORE non-nil the values of these variables are ignored.
+ * of `window-min-height' (`window-min-width' if HORIZONTAL is
+ * non-nil) and `window-safe-min-height' (`window-safe-min-width')
+ * according to IGNORE (see `window-min-size').
  *
  * In either case, never return a value less than 1.  For TTY frames,
  * additionally limit the minimum frame height to a value large enough
- * to support the menu bar, the mode line, and the echo area.
+ * to support menu bar, tab bar, mode line and echo area.
  */
-static int
+int
 frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
 			Lisp_Object ignore, Lisp_Object pixelwise)
 {
@@ -405,6 +359,7 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
   else
     retval = XFIXNUM (call4 (Qframe_windows_min_size, frame, horizontal,
 			  ignore, pixelwise));
+
   /* Don't allow too small height of text-mode frames, or else cm.c
      might abort in cmcheckmagic.  */
   if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) && NILP (horizontal))
@@ -413,6 +368,7 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
 			+ FRAME_TAB_BAR_LINES (f)
 			+ FRAME_WANTS_MODELINE_P (f)
 			+ 2);	/* one text line and one echo-area line */
+
       if (retval < min_height)
 	retval = min_height;
     }
@@ -474,9 +430,10 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
 	      if (CONSP (keep_ratio)
 		  && (NILP (Fcar (keep_ratio))
 		      || EQ (Fcar (keep_ratio), Qheight_only))
-		  && p->pixel_width - f->pixel_width < pos_x)
+		  && FRAME_PIXEL_WIDTH (p) - FRAME_PIXEL_WIDTH (f) < pos_x)
 		{
-		  int p_f_width = p->pixel_width - f->pixel_width;
+		  int p_f_width
+		    = FRAME_PIXEL_WIDTH (p) - FRAME_PIXEL_WIDTH (f);
 
 		  if (p_f_width <= 0)
 		    pos_x = 0;
@@ -496,14 +453,15 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
 	      if (CONSP (keep_ratio)
 		  && (NILP (Fcar (keep_ratio))
 		      || EQ (Fcar (keep_ratio), Qwidth_only))
-		  && p->pixel_height - f->pixel_height < pos_y)
+		  && FRAME_PIXEL_HEIGHT (p) - FRAME_PIXEL_HEIGHT (f) < pos_y)
 		/* When positional adjustment was requested and the
 		   width of F should remain unaltered, try to constrain
 		   F to its parent.  This means that when the parent
 		   frame is enlarged later the child's original position
 		   won't get restored.  */
 		{
-		  int p_f_height = p->pixel_height - f->pixel_height;
+		  int p_f_height
+		    = FRAME_PIXEL_HEIGHT (p) - FRAME_PIXEL_HEIGHT (f);
 
 		  if (p_f_height <= 0)
 		    pos_y = 0;
@@ -523,60 +481,143 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
 	  if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qheight_only))
 	    pixel_width = -1;
 	  else
-	    {
-	      pixel_width = (int)(f->pixel_width * width_factor + 0.5);
-	      pixel_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width);
-	    }
+	    pixel_width
+	      = (int)(FRAME_PIXEL_WIDTH (f) * width_factor + 0.5);
 
 	  if (CONSP (keep_ratio) && EQ (Fcar (keep_ratio), Qwidth_only))
 	    pixel_height = -1;
 	  else
-	    {
-	      pixel_height = (int)(f->pixel_height * height_factor + 0.5);
-	      pixel_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height);
-	    }
+	    pixel_height
+	      = (int)(FRAME_PIXEL_HEIGHT (f) * height_factor + 0.5);
 
-	  adjust_frame_size (f, pixel_width, pixel_height, 1, 0,
-			     Qkeep_ratio);
+	  adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixel_width),
+			     FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixel_height), 1,
+			     false, Qkeep_ratio);
 	}
     }
 }
 #endif
 
 
+static void
+frame_size_history_adjust (struct frame *f, int inhibit, Lisp_Object parameter,
+			   int old_text_width, int old_text_height,
+			   int new_text_width, int new_text_height,
+			   int old_text_cols, int old_text_lines,
+			   int new_text_cols, int new_text_lines,
+			   int old_native_width, int old_native_height,
+			   int new_native_width, int new_native_height,
+			   int old_inner_width, int old_inner_height,
+			   int new_inner_width, int new_inner_height,
+			   int min_inner_width, int min_inner_height,
+			   bool inhibit_horizontal, bool inhibit_vertical)
+{
+  Lisp_Object frame;
+
+  XSETFRAME (frame, f);
+  if (CONSP (frame_size_history)
+      && FIXNUMP (XCAR (frame_size_history))
+      && 0 < XFIXNUM (XCAR (frame_size_history)))
+    frame_size_history =
+      Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
+	     Fcons (Fcons (list4 (frame, make_fixnum (5),
+				  make_fixnum (inhibit), parameter),
+			   list5 (list4i (old_text_width, old_text_height,
+					  new_text_width, new_text_height),
+				  list4i (old_text_cols, old_text_lines,
+					  new_text_cols, new_text_lines),
+				  list4i (old_native_width, old_native_height,
+					  new_native_width, new_native_height),
+				  list4i (old_inner_width, old_inner_height,
+					  new_inner_width,  new_inner_height),
+				  list4 (make_fixnum (min_inner_width),
+					 make_fixnum (min_inner_height),
+					 inhibit_horizontal ? Qt : Qnil,
+					 inhibit_vertical ? Qt : Qnil))),
+		    XCDR (frame_size_history)));
+}
+
+
+void
+frame_size_history_plain (struct frame *f, Lisp_Object parameter)
+{
+  Lisp_Object frame;
+
+  XSETFRAME (frame, f);
+  if (CONSP (frame_size_history)
+      && FIXNUMP (XCAR (frame_size_history))
+      && 0 < XFIXNUM (XCAR (frame_size_history)))
+    frame_size_history =
+      Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
+	     Fcons (Fcons (list3 (frame, make_fixnum (1), parameter), Qt),
+		    XCDR (frame_size_history)));
+}
+
+
+void
+frame_size_history_extra (struct frame *f, Lisp_Object parameter,
+			  int pixel_width, int pixel_height,
+			  int extra_width, int extra_height,
+			  int delayed_width, int delayed_height)
+{
+  Lisp_Object frame;
+
+  XSETFRAME (frame, f);
+  if (CONSP (frame_size_history)
+      && FIXNUMP (XCAR (frame_size_history))
+      && 0 < XFIXNUM (XCAR (frame_size_history)))
+    frame_size_history =
+      Fcons (make_fixnum (XFIXNUM (XCAR (frame_size_history)) - 1),
+	     Fcons (Fcons (list3 (frame, make_fixnum (2), parameter),
+			   list2 (list4i (pixel_width, pixel_height,
+					  extra_width, extra_height),
+				  list2i (delayed_width, delayed_height))),
+		    XCDR (frame_size_history)));
+}
+
+
 /**
  * adjust_frame_size:
  *
- * Adjust size of frame F.  NEW_WIDTH and NEW_HEIGHT specify the new
- * text size of F in pixels.  A value of -1 means no change is requested
- * for that direction (but the frame may still have to be resized to
- * accommodate windows with their minimum sizes).  This can either issue
- * a request to resize the frame externally (via set_window_size_hook), to
- * resize the frame internally (via resize_frame_windows) or do nothing
- * at all.
+ * Adjust size of frame F.  NEW_TEXT_WIDTH and NEW_TEXT_HEIGHT specify
+ * the new text size of F in pixels.  When INHIBIT equals 2, 3 or 4, a
+ * value of -1 means to leave the text size of F unchanged and adjust,
+ * if necessary and possible, F's native size accordingly.  When INHIBIT
+ * equals 0, 1 or 5, a negative value means that the frame has been (or
+ * should be) made pathologically small which usually means that parts
+ * of the frame's windows may not be entirely visible.
  *
- * The argument INHIBIT can assume the following values:
+ * The effect of calling this function can be to either issue a request
+ * to resize the frame externally (via set_window_size_hook), to resize
+ * the frame internally (via resize_frame_windows) or to do nothing.
+ *
+ * The argument INHIBIT controls whether set_window_size_hook may be
+ * called and can assume the following values:
  *
  * 0 means to unconditionally call set_window_size_hook even if sizes
  *   apparently do not change.  Fx_create_frame uses this to pass the
  *   initial size to the window manager.
  *
- * 1 means to call set_window_size_hook if the native frame size really
- *   changes.  Fset_frame_size, Fset_frame_height, ... use this.
+ * 1 means to call set_window_size_hook if the native frame size should
+ *   change.  Fset_frame_size and friends and width and height parameter
+ *   changes use this.
  *
  * 2 means to call set_window_size_hook provided frame_inhibit_resize
- *   allows it.  The menu and tool bar code use this ("3" won't work
- *   here in general because menu and tool bar are often not counted in
- *   the frame's text height).
+ *   allows it.  The code updating external menu and tool bars uses this
+ *   to keep the height of the native frame unaltered when one of these
+ *   bars is added or removed.  This means that Emacs has to work
+ *   against the window manager which usually tries to keep the combined
+ *   height (native frame plus bar) unaltered.
  *
- * 3 means call set_window_size_hook if window minimum sizes must be
- *   preserved or frame_inhibit_resize allows it.
- *   gui_set_left_fringe, gui_set_scroll_bar_width, gui_new_font
- *   ... use (or should use) this.
+ * 3 means to call set_window_size_hook if window minimum sizes must be
+ *   preserved or frame_inhibit_resize allows it.  This is the default
+ *   for parameters accounted for in a frame's text size like fringes,
+ *   scroll bars, internal border, tab bar, internal tool and menu bars.
+ *   It's also used when the frame's default font changes.
  *
- * 4 means call set_window_size_hook only if window minimum sizes must
- *   be preserved.  x_set_right_divider_width, x_set_border_width and
- *   the code responsible for wrapping the tool bar use this.
+ * 4 means to call set_window_size_hook only if window minimum sizes
+ *   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.
@@ -588,146 +629,172 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
  * PRETEND is as for change_frame_size.  PARAMETER, if non-nil, is the
  * symbol of the parameter changed (like `menu-bar-lines', `font', ...).
  * This is passed on to frame_inhibit_resize to let the latter decide on
- * a case-by-case basis whether the frame may be resized externally.
+ * a case-by-case basis whether set_window_size_hook should be called.
  */
 void
-adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
-		   bool pretend, Lisp_Object parameter)
+adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
+		   int inhibit, bool pretend, Lisp_Object parameter)
 {
   int unit_width = FRAME_COLUMN_WIDTH (f);
   int unit_height = FRAME_LINE_HEIGHT (f);
-  int old_pixel_width = FRAME_PIXEL_WIDTH (f);
-  int old_pixel_height = FRAME_PIXEL_HEIGHT (f);
-  int old_cols = FRAME_COLS (f);
-  int old_lines = FRAME_LINES (f);
-  int new_pixel_width, new_pixel_height;
-  /* The following two values are calculated from the old frame pixel
-     sizes and any "new" settings for tool bar, menu bar and internal
-     borders.  We do it this way to detect whether we have to call
-     set_window_size_hook as consequence of the new settings.  */
-  int windows_width = FRAME_WINDOWS_WIDTH (f);
-  int windows_height = FRAME_WINDOWS_HEIGHT (f);
-  int min_windows_width, min_windows_height;
-  /* These are a bit tedious, maybe we should use a macro.  */
+  int old_native_width = FRAME_PIXEL_WIDTH (f);
+  int old_native_height = FRAME_PIXEL_HEIGHT (f);
+  int new_native_width, new_native_height;
+  /* The desired minimum inner width and height of the frame calculated
+     via 'frame-windows-min-size'.  */
+  int min_inner_width, min_inner_height;
+  /* Get the "old" inner width, height and position of F via its root
+     window and the minibuffer window.  We cannot use FRAME_INNER_WIDTH
+     and FRAME_INNER_HEIGHT here since the internal border and the top
+     margin may have been already set to new values.  */
   struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
-  int old_windows_width = WINDOW_PIXEL_WIDTH (r);
-  int old_windows_height
+  int old_inner_width = WINDOW_PIXEL_WIDTH (r);
+  int old_inner_height
     = (WINDOW_PIXEL_HEIGHT (r)
        + ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
 	  ? WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_MINIBUF_WINDOW (f)))
 	  : 0));
-  int new_windows_width, new_windows_height;
+  int new_inner_width, new_inner_height;
+  int old_text_cols = FRAME_COLS (f);
+  int old_text_lines = FRAME_LINES (f);
+  int new_text_cols, new_text_lines;
   int old_text_width = FRAME_TEXT_WIDTH (f);
   int old_text_height = FRAME_TEXT_HEIGHT (f);
-  /* If a size is < 0 use the old value.  */
-  int new_text_width = (new_width >= 0) ? new_width : old_text_width;
-  int new_text_height = (new_height >= 0) ? new_height : old_text_height;
-  int new_cols, new_lines;
   bool inhibit_horizontal, inhibit_vertical;
   Lisp_Object frame;
 
   XSETFRAME (frame, f);
 
-  frame_size_history_add
-    (f, Qadjust_frame_size_1, new_text_width, new_text_height,
-     list2 (parameter, make_fixnum (inhibit)));
-
-  /* The following two values are calculated from the old window body
-     sizes and any "new" settings for scroll bars, dividers, fringes and
-     margins (though the latter should have been processed already).  */
-  min_windows_width
-    = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qt : Qnil, Qt);
-  min_windows_height
-    = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
+  min_inner_width
+    = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qsafe : Qnil, Qt);
+  min_inner_height
+    = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qsafe : Qnil, Qt);
 
   if (inhibit >= 2 && inhibit <= 4)
     /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
        within the limits and either resizing is inhibited or INHIBIT
        equals 4.  */
     {
-      inhibit_horizontal = (windows_width >= min_windows_width
+      if (new_text_width == -1)
+	new_text_width = FRAME_TEXT_WIDTH (f);
+      if (new_text_height == -1)
+	new_text_height = FRAME_TEXT_HEIGHT (f);
+
+      inhibit_horizontal = (FRAME_INNER_WIDTH (f) >= min_inner_width
                             && (inhibit == 4
                                 || frame_inhibit_resize (f, true, parameter)));
-      inhibit_vertical = (windows_height >= min_windows_height
+      inhibit_vertical = (FRAME_INNER_HEIGHT (f) >= min_inner_height
                           && (inhibit == 4
                               || frame_inhibit_resize (f, false, parameter)));
     }
   else
-    /* Otherwise inhibit if INHIBIT equals 5.  */
+    /* Otherwise inhibit if INHIBIT equals 5.  If we wanted to overrule
+       the WM do that here (could lead to some sort of eternal fight
+       with the WM).  */
     inhibit_horizontal = inhibit_vertical = inhibit == 5;
 
-  new_pixel_width = ((inhibit_horizontal && (inhibit < 5))
-		     ? old_pixel_width
-		     : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
-			    min_windows_width
-			    + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
-  new_windows_width = new_pixel_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
-  new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_pixel_width);
-  new_cols = new_text_width / unit_width;
-
-  new_pixel_height = ((inhibit_vertical && (inhibit < 5))
-		      ? old_pixel_height
-		      : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
-			     min_windows_height
-			     + FRAME_TOP_MARGIN_HEIGHT (f)
+  new_native_width = ((inhibit_horizontal && inhibit < 5)
+		      ? old_native_width
+		      : max (FRAME_TEXT_TO_PIXEL_WIDTH (f, new_text_width),
+			     min_inner_width
 			     + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
-  new_windows_height = (new_pixel_height
-			- FRAME_TOP_MARGIN_HEIGHT (f)
-			- 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
-  new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_pixel_height);
-  new_lines = new_text_height / unit_height;
+  new_inner_width = new_native_width - 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
+  new_text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, new_native_width);
+  new_text_cols = new_text_width / unit_width;
+
+  new_native_height = ((inhibit_vertical && inhibit < 5)
+		       ? old_native_height
+		       : max (FRAME_TEXT_TO_PIXEL_HEIGHT (f, new_text_height),
+			      min_inner_height
+			      + FRAME_TOP_MARGIN_HEIGHT (f)
+			      + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)));
+  new_inner_height = (new_native_height
+		      - FRAME_TOP_MARGIN_HEIGHT (f)
+		      - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+  new_text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_native_height);
+  new_text_lines = new_text_height / unit_height;
 
-#ifdef HAVE_WINDOW_SYSTEM
   if (FRAME_WINDOW_P (f)
       && f->can_set_window_size
       && ((!inhibit_horizontal
-	   && (new_pixel_width != old_pixel_width
+	   && (new_native_width != old_native_width
 	       || inhibit == 0 || inhibit == 2))
 	  || (!inhibit_vertical
-	      && (new_pixel_height != old_pixel_height
+	      && (new_native_height != old_native_height
 		  || inhibit == 0 || inhibit == 2))))
-    /* We are either allowed to change the frame size or the minimum
-       sizes request such a change.  Do not care for fixing minimum
-       sizes here, we do that eventually when we're called from
-       change_frame_size.  */
     {
       /* Make sure we respect fullheight and fullwidth.  */
       if (inhibit_horizontal)
-	new_text_width = old_text_width;
+	new_native_width = old_native_width;
       else if (inhibit_vertical)
-	new_text_height = old_text_height;
+	new_native_height = old_native_height;
+
+      if (inhibit == 2 && f->new_width > 0 && f->new_height > 0)
+	/* For implied resizes with inhibit 2 (external menu and tool
+	   bar) pick up any new sizes the display engine has not
+	   processed yet.  Otherwsie, we would request the old sizes
+	   which will make this request appear as a request to set new
+	   sizes and have the WM react accordingly which is not TRT.  */
+	{
+	  /* But don't that for the external menu bar on Motif.
+	     Otherwise, switching off the menu bar will shrink the frame
+	     and switching it on will not enlarge it.  */
+#ifdef USE_MOTIF
+	  if (!EQ (parameter, Qmenu_bar_lines))
+#endif
+	    {
+	      new_native_width = f->new_width;
+	      new_native_height = f->new_height;
+	    }
+	}
 
-      frame_size_history_add
-	(f, Qadjust_frame_size_2, new_text_width, new_text_height,
-	 list2 (inhibit_horizontal ? Qt : Qnil,
-		inhibit_vertical ? Qt : Qnil));
+      if (CONSP (frame_size_history))
+	frame_size_history_adjust (f, inhibit, parameter,
+				   old_text_width, old_text_height,
+				   new_text_width, new_text_height,
+				   old_text_cols, old_text_lines,
+				   new_text_cols, new_text_lines,
+				   old_native_width, old_native_height,
+				   new_native_width, new_native_height,
+				   old_inner_width, old_inner_height,
+				   new_inner_width, new_inner_height,
+				   min_inner_width, min_inner_height,
+				   inhibit_horizontal, inhibit_vertical);
 
       if (FRAME_TERMINAL (f)->set_window_size_hook)
         FRAME_TERMINAL (f)->set_window_size_hook
-	  (f, 0, new_text_width, new_text_height, 1);
+	  (f, 0, new_native_width, new_native_height);
       f->resized_p = true;
 
       return;
     }
-#endif
+
+  if (CONSP (frame_size_history))
+    frame_size_history_adjust (f, inhibit, parameter,
+			       old_text_width, old_text_height,
+			       new_text_width, new_text_height,
+			       old_text_cols, old_text_lines,
+			       new_text_cols, new_text_lines,
+			       old_native_width, old_native_height,
+			       new_native_width, new_native_height,
+			       old_inner_width, old_inner_height,
+			       new_inner_width, new_inner_height,
+			       min_inner_width, min_inner_height,
+			       inhibit_horizontal, inhibit_vertical);
 
   if ((XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top
        == FRAME_TOP_MARGIN_HEIGHT (f))
       && new_text_width == old_text_width
       && new_text_height == old_text_height
-      && new_windows_width == old_windows_width
-      && new_windows_height == old_windows_height
-      && new_pixel_width == old_pixel_width
-      && new_pixel_height == old_pixel_height
-      && new_cols == old_cols
-      && new_lines == old_lines)
-    /* No change.  Sanitize window sizes and return.  */
-    {
-      sanitize_window_sizes (Qt);
-      sanitize_window_sizes (Qnil);
-
-      return;
-    }
+      && new_inner_width == old_inner_width
+      && new_inner_height == old_inner_height
+      /* We might be able to drop these but some doubts remain.  */
+      && new_native_width == old_native_width
+      && new_native_height == old_native_height
+      && new_text_cols == old_text_cols
+      && new_text_lines == old_text_lines)
+    /* No change.  */
+    return;
 
   block_input ();
 
@@ -736,69 +803,67 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
      our video hardware.  Try to find the smallest size greater or
      equal to the requested dimensions, while accounting for the fact
      that the menu-bar lines are not counted in the frame height.  */
-  int dos_new_lines = new_lines + FRAME_TOP_MARGIN (f);
-  dos_set_window_size (&dos_new_lines, &new_cols);
-  new_lines = dos_new_lines - FRAME_TOP_MARGIN (f);
+  int dos_new_text_lines = new_text_lines + FRAME_TOP_MARGIN (f);
+
+  dos_set_window_size (&dos_new_text_lines, &new_text_cols);
+  new_text_lines = dos_new_text_lines - FRAME_TOP_MARGIN (f);
 #endif
 
-  if (new_windows_width != old_windows_width)
+  if (new_inner_width != old_inner_width)
     {
-      resize_frame_windows (f, new_windows_width, true);
+      resize_frame_windows (f, new_inner_width, true);
 
       /* MSDOS frames cannot PRETEND, as they change frame size by
 	 manipulating video hardware.  */
       if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
-	FrameCols (FRAME_TTY (f)) = new_cols;
+	FrameCols (FRAME_TTY (f)) = new_text_cols;
 
 #if defined (HAVE_WINDOW_SYSTEM)
       if (WINDOWP (f->tab_bar_window))
 	{
-	  XWINDOW (f->tab_bar_window)->pixel_width = new_windows_width;
+	  XWINDOW (f->tab_bar_window)->pixel_width = new_inner_width;
 	  XWINDOW (f->tab_bar_window)->total_cols
-	    = new_windows_width / unit_width;
+	    = new_inner_width / unit_width;
 	}
 #endif
 
 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
       if (WINDOWP (f->tool_bar_window))
 	{
-	  XWINDOW (f->tool_bar_window)->pixel_width = new_windows_width;
+	  XWINDOW (f->tool_bar_window)->pixel_width = new_inner_width;
 	  XWINDOW (f->tool_bar_window)->total_cols
-	    = new_windows_width / unit_width;
+	    = new_inner_width / unit_width;
 	}
 #endif
     }
-  else if (new_cols != old_cols)
+  else if (new_text_cols != old_text_cols)
     call2 (Qwindow__pixel_to_total, frame, Qt);
 
-  if (new_windows_height != old_windows_height
+  if (new_inner_height != old_inner_height
       /* When the top margin has changed we have to recalculate the top
 	 edges of all windows.  No such calculation is necessary for the
 	 left edges.  */
       || WINDOW_TOP_PIXEL_EDGE (r) != FRAME_TOP_MARGIN_HEIGHT (f))
     {
-      resize_frame_windows (f, new_windows_height, false);
+      resize_frame_windows (f, new_inner_height, false);
 
       /* MSDOS frames cannot PRETEND, as they change frame size by
 	 manipulating video hardware.  */
       if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
-	FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
+	FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f);
     }
-  else if (new_lines != old_lines)
+  else if (new_text_lines != old_text_lines)
     call2 (Qwindow__pixel_to_total, frame, Qnil);
 
-  frame_size_history_add
-    (f, Qadjust_frame_size_3, new_text_width, new_text_height,
-     list4i (old_pixel_width, old_pixel_height,
-	     new_pixel_width, new_pixel_height));
-
   /* Assign new sizes.  */
+  FRAME_COLS (f) = new_text_cols;
+  FRAME_LINES (f) = new_text_lines;
   FRAME_TEXT_WIDTH (f) = new_text_width;
   FRAME_TEXT_HEIGHT (f) = new_text_height;
-  FRAME_PIXEL_WIDTH (f) = new_pixel_width;
-  FRAME_PIXEL_HEIGHT (f) = new_pixel_height;
-  SET_FRAME_COLS (f, new_cols);
-  SET_FRAME_LINES (f, new_lines);
+  FRAME_PIXEL_WIDTH (f) = new_native_width;
+  FRAME_PIXEL_HEIGHT (f) = new_native_height;
+  FRAME_TOTAL_COLS (f) = FRAME_PIXEL_WIDTH (f) / FRAME_COLUMN_WIDTH (f);
+  FRAME_TOTAL_LINES (f) = FRAME_PIXEL_HEIGHT (f) / FRAME_LINE_HEIGHT (f);
 
   {
     struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
@@ -812,18 +877,18 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
       w->cursor.vpos = w->cursor.y = 0;
   }
 
-  /* Sanitize window sizes.  */
-  sanitize_window_sizes (Qt);
-  sanitize_window_sizes (Qnil);
-
   adjust_frame_glyphs (f);
   calculate_costs (f);
   SET_FRAME_GARBAGED (f);
+  /* We now say here that F was resized instead of using the old
+     condition below.  Some resizing must have taken place and if it was
+     only shifting the root window's position (paranoia?).  */
+  f->resized_p = true;
 
-  /* A frame was "resized" if one of its pixelsizes changed, even if its
-     X window wasn't resized at all.  */
-  f->resized_p = (new_pixel_width != old_pixel_width
-		  || new_pixel_height != old_pixel_height);
+/**   /\* A frame was "resized" if its native size changed, even if its X **/
+/**      window wasn't resized at all.  *\/ **/
+/**   f->resized_p = (new_native_width != old_native_width **/
+/** 		  || new_native_height != old_native_height); **/
 
   unblock_input ();
 
@@ -834,8 +899,8 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
 
     FOR_EACH_FRAME (frames, frame1)
       if (FRAME_PARENT_FRAME (XFRAME (frame1)) == f)
-	keep_ratio (XFRAME (frame1), f, old_pixel_width, old_pixel_height,
-		    new_pixel_width, new_pixel_height);
+	keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height,
+		    new_native_width, new_native_height);
   }
 #endif
 }
@@ -884,6 +949,8 @@ make_frame (bool mini_p)
   f->tool_bar_resized = false;
   f->column_width = 1;  /* !FRAME_WINDOW_P value.  */
   f->line_height = 1;  /* !FRAME_WINDOW_P value.  */
+  f->new_width = -1;
+  f->new_height = -1;
 #ifdef HAVE_WINDOW_SYSTEM
   f->vertical_scroll_bar_type = vertical_scroll_bar_none;
   f->horizontal_scroll_bars = false;
@@ -932,17 +999,14 @@ make_frame (bool mini_p)
 
   wset_frame (rw, frame);
 
-  /* 80/25 is arbitrary,
-     just so that there is "something there."
+  /* 80/25 is arbitrary, just so that there is "something there."
      Correct size will be set up later with adjust_frame_size.  */
+  FRAME_COLS (f) = FRAME_TOTAL_COLS (f) = rw->total_cols = 80;
+  FRAME_TEXT_WIDTH (f) = FRAME_PIXEL_WIDTH (f) = rw->pixel_width
+    = 80 * FRAME_COLUMN_WIDTH (f);
+  FRAME_LINES (f) = FRAME_TOTAL_LINES (f) = 25;
+  FRAME_TEXT_HEIGHT (f) = FRAME_PIXEL_HEIGHT (f) = 25 * FRAME_LINE_HEIGHT (f);
 
-  SET_FRAME_COLS (f, 80);
-  SET_FRAME_LINES (f, 25);
-  SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
-  SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
-
-  rw->total_cols = FRAME_COLS (f);
-  rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
   rw->total_lines = FRAME_LINES (f) - (mini_p ? 1 : 0);
   rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
 
@@ -1316,8 +1380,8 @@ DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
   {
     int width, height;
     get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
-    adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f)
-		       - FRAME_TAB_BAR_LINES (f),
+    /* With INHIBIT 5 pass correct text height to adjust_frame_size.  */
+    adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f),
 		       5, 0, Qterminal_frame);
   }
 
@@ -3220,21 +3284,23 @@ DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
 				    : FRAME_W32_P (f) ? "w32term"
 				    :"tty"));
     }
+
   store_in_alist (&alist, Qname, f->name);
-  height = (f->new_height
-	    ? (f->new_pixelwise
-	       ? (f->new_height / FRAME_LINE_HEIGHT (f))
-	       : f->new_height)
+  /* It's questionable whether here we should report the value of
+     f->new_height (and f->new_width below) but we've done that in the
+     past, so let's keep it.  Note that a value of -1 for either of
+     these means that no new size was requested.  */
+  height = (f->new_height >= 0
+	    ? f->new_height / FRAME_LINE_HEIGHT (f)
 	    : FRAME_LINES (f));
   store_in_alist (&alist, Qheight, make_fixnum (height));
-  width = (f->new_width
-	   ? (f->new_pixelwise
-	      ? (f->new_width / FRAME_COLUMN_WIDTH (f))
-	      : f->new_width)
-	   : FRAME_COLS (f));
+  width = (f->new_width >= 0
+	   ? f->new_width / FRAME_COLUMN_WIDTH (f)
+	   : FRAME_COLS(f));
   store_in_alist (&alist, Qwidth, make_fixnum (width));
-  store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
-  store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
+
+  store_in_alist (&alist, Qmodeline, FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil);
+  store_in_alist (&alist, Qunsplittable, FRAME_NO_SPLIT_P (f) ? Qt : Qnil);
   store_in_alist (&alist, Qbuffer_list, f->buffer_list);
   store_in_alist (&alist, Qburied_buffer_list, f->buried_buffer_list);
 
@@ -3247,6 +3313,7 @@ DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
     {
       /* This ought to be correct in f->param_alist for an X frame.  */
       Lisp_Object lines;
+
       XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
       store_in_alist (&alist, Qmenu_bar_lines, lines);
       XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
@@ -3593,15 +3660,18 @@ DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_widt
 static int
 check_frame_pixels (Lisp_Object size, Lisp_Object pixelwise, int item_size)
 {
+  intmax_t sz;
+  int pixel_size; /* size * item_size */
+
   CHECK_INTEGER (size);
   if (!NILP (pixelwise))
     item_size = 1;
-  intmax_t sz;
-  int pixel_size; /* size * item_size */
-  if (! integer_to_intmax (size, &sz)
+
+  if (!integer_to_intmax (size, &sz)
       || INT_MULTIPLY_WRAPV (sz, item_size, &pixel_size))
     args_out_of_range_3 (size, make_int (INT_MIN / item_size),
 			 make_int (INT_MAX / item_size));
+
   return pixel_size;
 }
 
@@ -3624,9 +3694,13 @@ DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4,
   (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
 {
   struct frame *f = decode_live_frame (frame);
-  int pixel_height = check_frame_pixels (height, pixelwise,
-					 FRAME_LINE_HEIGHT (f));
-  adjust_frame_size (f, -1, pixel_height, 1, !NILP (pretend), Qheight);
+  int text_height
+    = check_frame_pixels (height, pixelwise, FRAME_LINE_HEIGHT (f));
+
+  /* With INHIBIT 1 pass correct text width to adjust_frame_size.  */
+  adjust_frame_size
+    (f, FRAME_TEXT_WIDTH (f), text_height, 1, !NILP (pretend), Qheight);
+
   return Qnil;
 }
 
@@ -3649,9 +3723,13 @@ DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4,
   (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
 {
   struct frame *f = decode_live_frame (frame);
-  int pixel_width = check_frame_pixels (width, pixelwise,
-					FRAME_COLUMN_WIDTH (f));
-  adjust_frame_size (f, pixel_width, -1, 1, !NILP (pretend), Qwidth);
+  int text_width
+    = check_frame_pixels (width, pixelwise, FRAME_COLUMN_WIDTH (f));
+
+  /* With INHIBIT 1 pass correct text height to adjust_frame_size.  */
+  adjust_frame_size
+    (f, text_width, FRAME_TEXT_HEIGHT (f), 1, !NILP (pretend), Qwidth);
+
   return Qnil;
 }
 
@@ -3667,11 +3745,14 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
   (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
 {
   struct frame *f = decode_live_frame (frame);
-  int pixel_width = check_frame_pixels (width, pixelwise,
-					FRAME_COLUMN_WIDTH (f));
-  int pixel_height = check_frame_pixels (height, pixelwise,
-					 FRAME_LINE_HEIGHT (f));
-  adjust_frame_size (f, pixel_width, pixel_height, 1, 0, Qsize);
+  int text_width
+    = check_frame_pixels (width, pixelwise, FRAME_COLUMN_WIDTH (f));
+  int text_height
+    = check_frame_pixels (height, pixelwise, FRAME_LINE_HEIGHT (f));
+
+  /* PRETEND is always false here.  */
+  adjust_frame_size (f, text_width, text_height, 1, false, Qsize);
+
   return Qnil;
 }
 
@@ -4035,11 +4116,9 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
 {
   Lisp_Object tail, frame;
 
-
-  /* If both of these parameters are present, it's more efficient to
-     set them both at once.  So we wait until we've looked at the
-     entire list before we set them.  */
-  int width = -1, height = -1;  /* -1 denotes they were not changed. */
+  /* Neither of these values should be used.  */
+  int width = -1, height = -1;
+  bool width_change = false, height_change = false;
 
   /* Same here.  */
   Lisp_Object left, top;
@@ -4117,6 +4196,8 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
 
       if (EQ (prop, Qwidth))
         {
+	  width_change = true;
+
 	  if (RANGED_FIXNUMP (0, val, INT_MAX))
 	    width = XFIXNAT (val) * FRAME_COLUMN_WIDTH (f) ;
 	  else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
@@ -4125,9 +4206,13 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
 	  else if (FLOATP (val))
 	    width = frame_float (f, val, FRAME_FLOAT_WIDTH, &parent_done,
 				 &outer_done, -1);
+	  else
+	    width_change = false;
         }
       else if (EQ (prop, Qheight))
         {
+	  height_change = true;
+
 	  if (RANGED_FIXNUMP (0, val, INT_MAX))
 	    height = XFIXNAT (val) * FRAME_LINE_HEIGHT (f);
 	  else if (CONSP (val) && EQ (XCAR (val), Qtext_pixels)
@@ -4136,6 +4221,8 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
 	  else if (FLOATP (val))
 	    height = frame_float (f, val, FRAME_FLOAT_HEIGHT, &parent_done,
 				 &outer_done, -1);
+	  else
+	    height_change = false;
         }
       else if (EQ (prop, Qtop))
 	top = val;
@@ -4204,23 +4291,28 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
 	XSETINT (icon_top, 0);
     }
 
-  /* Don't set these parameters unless they've been explicitly
-     specified.  The window might be mapped or resized while we're in
-     this function, and we don't want to override that unless the lisp
-     code has asked for it.
-
-     Don't set these parameters unless they actually differ from the
-     window's current parameters; the window may not actually exist
-     yet.  */
-  if ((width != -1 && width != FRAME_TEXT_WIDTH (f))
-      || (height != -1 && height != FRAME_TEXT_HEIGHT (f)))
-    /* We could consider checking f->after_make_frame here, but I
-       don't have the faintest idea why the following is needed at
-       all.  With the old setting it can get a Heisenbug when
-       EmacsFrameResize intermittently provokes a delayed
-       change_frame_size in the middle of adjust_frame_size.  */
-    /** 	|| (f->can_set_window_size && (f->new_height || f->new_width))) **/
-    adjust_frame_size (f, width, height, 1, 0, Qx_set_frame_parameters);
+  if (width_change || height_change)
+    {
+      Lisp_Object parameter;
+
+      if (width_change)
+	{
+	  if (height_change)
+	    parameter = Qsize;
+	  else
+	    {
+	      height = FRAME_TEXT_HEIGHT (f);
+	      parameter = Qwidth;
+	    }
+	}
+      else
+	{
+	  width = FRAME_TEXT_WIDTH (f);
+	  parameter = Qheight;
+	}
+
+      adjust_frame_size (f, width, height, 1, 0, parameter);
+    }
 
   if ((!NILP (left) || !NILP (top))
       && ! (left_no_change && top_no_change)
@@ -4293,9 +4385,6 @@ gui_set_frame_parameters (struct frame *f, Lisp_Object alist)
     {
       Lisp_Object old_value = get_frame_param (f, Qfullscreen);
 
-      frame_size_history_add
-	(f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
-
       store_frame_param (f, Qfullscreen, fullscreen);
       if (!EQ (fullscreen, old_value))
 	gui_set_fullscreen (f, fullscreen, old_value);
@@ -5504,25 +5593,16 @@ DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
 
    This function does not make the coordinates positive.  */
 
-#define DEFAULT_ROWS 36
-#define DEFAULT_COLS 80
-
 long
 gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
-                        bool toolbar_p, int *x_width, int *x_height)
+                        bool toolbar_p)
 {
   Lisp_Object height, width, user_size, top, left, user_position;
   long window_prompting = 0;
   Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
   int parent_done = -1, outer_done = -1;
-
-  /* Default values if we fall through.
-     Actually, if that happens we should get
-     window manager prompting.  */
-  SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
-  SET_FRAME_COLS (f, DEFAULT_COLS);
-  SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
-  SET_FRAME_LINES (f, DEFAULT_ROWS);
+  int text_width = 80 * FRAME_COLUMN_WIDTH (f);
+  int text_height = 36 * FRAME_LINE_HEIGHT (f);
 
   /* Window managers expect that if program-specified
      positions are not (0,0), they're intentional, not defaults.  */
@@ -5537,8 +5617,12 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
   if (tabbar_p && FRAME_TAB_BAR_LINES (f))
     {
       if (frame_default_tab_bar_height)
+	/* A default tab bar height was already set by the display code
+	   for some other frame, use that.  */
 	FRAME_TAB_BAR_HEIGHT (f) = frame_default_tab_bar_height;
       else
+	/* Calculate the height from various other settings.  For some
+	   reason, these are usually off by 2 hence of no use.  */
 	{
 	  int margin, relief;
 
@@ -5591,7 +5675,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 
   /* Ensure that earlier new_width and new_height settings won't
      override what we specify below.  */
-  f->new_width = f->new_height = 0;
+  f->new_width = f->new_height = -1;
 
   height = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
   width = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
@@ -5605,9 +5689,8 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 	      if ((XFIXNUM (XCDR (width)) < 0 || XFIXNUM (XCDR (width)) > INT_MAX))
 		xsignal1 (Qargs_out_of_range, XCDR (width));
 
-	      SET_FRAME_WIDTH (f, XFIXNUM (XCDR (width)));
+	      text_width = XFIXNUM (XCDR (width));
 	      f->inhibit_horizontal_resize = true;
-	      *x_width = XFIXNUM (XCDR (width));
 	    }
 	  else if (FLOATP (width))
 	    {
@@ -5621,7 +5704,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 					       &parent_done, &outer_done, -1);
 
 		  if (new_width > -1)
-		    SET_FRAME_WIDTH (f, new_width);
+		    text_width = new_width;
 		}
 	    }
 	  else
@@ -5630,7 +5713,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 	      if ((XFIXNUM (width) < 0 || XFIXNUM (width) > INT_MAX))
 		xsignal1 (Qargs_out_of_range, width);
 
-	      SET_FRAME_WIDTH (f, XFIXNUM (width) * FRAME_COLUMN_WIDTH (f));
+	      text_width = XFIXNUM (width) * FRAME_COLUMN_WIDTH (f);
 	    }
 	}
 
@@ -5642,9 +5725,8 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 	      if ((XFIXNUM (XCDR (height)) < 0 || XFIXNUM (XCDR (height)) > INT_MAX))
 		xsignal1 (Qargs_out_of_range, XCDR (height));
 
-	      SET_FRAME_HEIGHT (f, XFIXNUM (XCDR (height)));
+	      text_height = XFIXNUM (XCDR (height));
 	      f->inhibit_vertical_resize = true;
-	      *x_height = XFIXNUM (XCDR (height));
 	    }
 	  else if (FLOATP (height))
 	    {
@@ -5658,7 +5740,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 						&parent_done, &outer_done, -1);
 
 		  if (new_height > -1)
-		    SET_FRAME_HEIGHT (f, new_height);
+		    text_height = new_height;
 		}
 	    }
 	  else
@@ -5667,7 +5749,7 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 	      if ((XFIXNUM (height) < 0) || (XFIXNUM (height) > INT_MAX))
 		xsignal1 (Qargs_out_of_range, height);
 
-	      SET_FRAME_HEIGHT (f, XFIXNUM (height) * FRAME_LINE_HEIGHT (f));
+	      text_height = XFIXNUM (height) * FRAME_LINE_HEIGHT (f);
 	    }
 	}
 
@@ -5679,6 +5761,9 @@ gui_figure_window_size (struct frame *f, Lisp_Object parms, bool tabbar_p,
 	window_prompting |= PSize;
     }
 
+  adjust_frame_size (f, text_width, text_height, 5, false,
+		     Qgui_figure_window_size);
+
   top = gui_display_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
   left = gui_display_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
   user_position = gui_display_get_arg (dpyinfo, parms, Quser_position, 0, 0,
@@ -5986,39 +6071,17 @@ syms_of_frame (void)
   DEFSYM (Qtab_bar_size, "tab-bar-size");
   DEFSYM (Qtool_bar_external, "tool-bar-external");
   DEFSYM (Qtool_bar_size, "tool-bar-size");
-  /* The following are used for frame_size_history.  */
-  DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1");
-  DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2");
-  DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3");
-  DEFSYM (Qx_set_frame_parameters, "x-set-frame-parameters");
-  DEFSYM (QEmacsFrameResize, "EmacsFrameResize");
-  DEFSYM (Qset_frame_size, "set-frame-size");
-  DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize");
-  DEFSYM (Qx_set_fullscreen, "x-set-fullscreen");
-  DEFSYM (Qx_check_fullscreen, "x-check-fullscreen");
-  DEFSYM (Qxg_frame_resized, "xg-frame-resized");
-  DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
-  DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
-  DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
-  DEFSYM (Qxg_frame_set_char_size_4, "xg-frame-set-char-size-4");
-  DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
-  DEFSYM (Qx_set_window_size_2, "x-set-window-size-2");
-  DEFSYM (Qx_set_window_size_3, "x-set-window-size-3");
-  DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position");
-  DEFSYM (Qx_net_wm_state, "x-net-wm-state");
-  DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state");
-  DEFSYM (Qtb_size_cb, "tb-size-cb");
-  DEFSYM (Qupdate_frame_tab_bar, "update-frame-tab-bar");
-  DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar");
-  DEFSYM (Qfree_frame_tab_bar, "free-frame-tab-bar");
-  DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar");
-  DEFSYM (Qx_set_menu_bar_lines, "x-set-menu-bar-lines");
-  DEFSYM (Qchange_frame_size, "change-frame-size");
-  DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
-  DEFSYM (Qset_window_configuration, "set-window-configuration");
-  DEFSYM (Qx_create_frame_1, "x-create-frame-1");
-  DEFSYM (Qx_create_frame_2, "x-create-frame-2");
-  DEFSYM (Qterminal_frame, "terminal-frame");
+  /* The following are passed to adjust_frame_size.  */
+  DEFSYM (Qx_set_menu_bar_lines, "x_set_menu_bar_lines");
+  DEFSYM (Qchange_frame_size, "change_frame_size");
+  DEFSYM (Qxg_frame_set_char_size, "xg_frame_set_char_size");
+  DEFSYM (Qx_set_window_size_1, "x_set_window_size_1");
+  DEFSYM (Qset_window_configuration, "set_window_configuration");
+  DEFSYM (Qx_create_frame_1, "x_create_frame_1");
+  DEFSYM (Qx_create_frame_2, "x_create_frame_2");
+  DEFSYM (Qgui_figure_window_size, "gui_figure_window_size");
+  DEFSYM (Qtip_frame, "tip_frame");
+  DEFSYM (Qterminal_frame, "terminal_frame");
 
 #ifdef HAVE_NS
   DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
@@ -6047,9 +6110,7 @@ syms_of_frame (void)
   DEFSYM (Qleft_fringe, "left-fringe");
   DEFSYM (Qline_spacing, "line-spacing");
   DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
-  DEFSYM (Qupdate_frame_menubar, "update-frame-menubar");
-  DEFSYM (Qfree_frame_menubar_1, "free-frame-menubar-1");
-  DEFSYM (Qfree_frame_menubar_2, "free-frame-menubar-2");
+  DEFSYM (Qtab_bar_lines, "tab-bar-lines");
   DEFSYM (Qmouse_color, "mouse-color");
   DEFSYM (Qname, "name");
   DEFSYM (Qright_divider_width, "right-divider-width");
@@ -6061,7 +6122,6 @@ syms_of_frame (void)
   DEFSYM (Qscroll_bar_width, "scroll-bar-width");
   DEFSYM (Qsticky, "sticky");
   DEFSYM (Qtitle, "title");
-  DEFSYM (Qtab_bar_lines, "tab-bar-lines");
   DEFSYM (Qtool_bar_lines, "tool-bar-lines");
   DEFSYM (Qtool_bar_position, "tool-bar-position");
   DEFSYM (Qunsplittable, "unsplittable");
diff --git a/src/frame.h b/src/frame.h
index 0fd95e4dd3..19ee6ac10e 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -256,8 +256,8 @@ #define EMACS_FRAME_H
      be used for output.  */
   bool_bf glyphs_initialized_p : 1;
 
-  /* Set to true in change_frame_size when size of frame changed
-     Clear the frame in clear_garbaged_frames if set.  */
+  /* Set to true in adjust_frame_size when one of the frame's sizes
+     changed.  Clear the frame in clear_garbaged_frames if set.  */
   bool_bf resized_p : 1;
 
   /* Set to true if the default face for the frame has been
@@ -415,10 +415,6 @@ #define EMACS_FRAME_H
   bool_bf no_special_glyphs : 1;
 #endif /* HAVE_WINDOW_SYSTEM */
 
-  /* Whether new_height and new_width shall be interpreted
-     in pixels.  */
-  bool_bf new_pixelwise : 1;
-
   /* True means set_window_size_hook requests can be processed for
      this frame.  */
   bool_bf can_set_window_size : 1;
@@ -426,11 +422,23 @@ #define EMACS_FRAME_H
   /* Set to true after this frame was made by `make-frame'.  */
   bool_bf after_make_frame : 1;
 
-  /* Whether the tab bar height change should be taken into account.  */
+  /* Two sticky flags, that are both false when a frame is created.
+     'display_tab_bar' sets the former to true the first time it
+     displays the tab bar.  When the former is true, the next call of
+     'x_change_tab_bar_height' and associates sets the latter true and
+     tries to adjust the frame height in a way that the now valid pixel
+     height of the tab bar is taken into account by the frame's native
+     height.  */
   bool_bf tab_bar_redisplayed : 1;
   bool_bf tab_bar_resized : 1;
 
-  /* Whether the tool bar height change should be taken into account.  */
+  /* Two sticky flags, that are both false when a frame is created.
+     'redisplay_tool_bar' sets the former to true the first time it
+     displays the tool bar.  When the former is true, the next call of
+     'x_change_tool_bar_height' and associates sets the latter true and
+     tries to adjust the frame height in a way that the now valid pixel
+     height of the tool bar is taken into account by the frame's native
+     height.  */
   bool_bf tool_bar_redisplayed : 1;
   bool_bf tool_bar_resized : 1;
 
@@ -461,7 +469,7 @@ #define EMACS_FRAME_H
      last time run_window_change_functions was called on it.  */
   ptrdiff_t number_of_windows;
 
-  /* Number of lines (rounded up) of tab bar.  REMOVE THIS  */
+  /* Number of frame lines (rounded up) of tab bar.  */
   int tab_bar_lines;
 
   /* Height of frame internal tab bar in pixels.  */
@@ -470,7 +478,7 @@ #define EMACS_FRAME_H
   int n_tab_bar_rows;
   int n_tab_bar_items;
 
-  /* Number of lines (rounded up) of tool bar.  REMOVE THIS  */
+  /* Number of frame lines (rounded up) of tool bar.  */
   int tool_bar_lines;
 
   /* Height of frame internal tool bar in pixels.  */
@@ -492,39 +500,24 @@ #define EMACS_FRAME_H
   /* Cost of deleting n lines on this frame.  */
   int *delete_n_lines_cost;
 
-  /* Text width of this frame (excluding fringes, vertical scroll bar
-     and internal border widths) and text height (excluding menu bar,
-     tool bar, horizontal scroll bar and internal border widths) in
-     units of canonical characters.  */
+  /* Text width and height of this frame in (and maybe rounded to) frame
+     columns and lines.  */
   int text_cols, text_lines;
-
-  /* Total width of this frame (including fringes, vertical scroll bar
-     and internal border widths) and total height (including menu bar,
-     tool bar, horizontal scroll bar and internal border widths) in
-     units of canonical characters.  */
-  int total_cols, total_lines;
-
-  /* Text width of this frame (excluding fringes, vertical scroll bar
-     and internal border widths) and text height (excluding menu bar,
-     tool bar, horizontal scroll bar and internal border widths) in
-     pixels.  */
+  /* Text width and height of this frame in pixels.  */
   int text_width, text_height;
 
-  /* New text height and width for pending size change.  0 if no change
-     pending.  These values represent pixels or canonical character units
-     according to the value of new_pixelwise and correlate to the
-     text width/height of the frame.  */
+  /* Native width of this frame in (and maybe rounded to) frame columns
+     and lines.  */
+  int total_cols, total_lines;
+  /* Native width and height of this frame in pixels.  */
+  int pixel_width, pixel_height;
+  /* New native width and height of this frame for pending size change,
+     in pixels.  -1 if no change pending.  */
   int new_width, new_height;
 
   /* Pixel position of the frame window (x and y offsets in root window).  */
   int left_pos, top_pos;
 
-  /* Total width of this frame (including fringes, vertical scroll bar
-     and internal border widths) and total height (including internal
-     menu and tool bars, horizontal scroll bar and internal border
-     widths) in pixels.  */
-  int pixel_width, pixel_height;
-
   /* This is the gravity value for the specified window position.  */
   int win_gravity;
 
@@ -848,7 +841,6 @@ #define FRAME_NS_P(f) ((f)->output_method == output_ns)
 
 /* FRAME_WINDOW_P tests whether the frame is a graphical window system
    frame.  */
-
 #ifdef HAVE_X_WINDOWS
 #define FRAME_WINDOW_P(f) FRAME_X_P (f)
 #endif
@@ -914,45 +906,36 @@ #define FRAME_HAS_MINIBUF_P(f)					\
 # define FRAME_SCALE_FACTOR(f) 1
 #endif
 
-/* Pixel width of frame F.  */
+/* Native width and height of frame F, in pixels and frame
+   columns/lines.  */
 #define FRAME_PIXEL_WIDTH(f) ((f)->pixel_width)
-
-/* Pixel height of frame F.  */
 #define FRAME_PIXEL_HEIGHT(f) ((f)->pixel_height)
+#define FRAME_TOTAL_COLS(f) ((f)->total_cols)
+#define FRAME_TOTAL_LINES(f) ((f)->total_lines)
 
-/* Width of frame F, measured in canonical character columns,
-   not including scroll bars if any.  */
-#define FRAME_COLS(f) (f)->text_cols
-
-/* Height of frame F, measured in canonical lines, including
-   non-toolkit menu bar and non-toolkit tool bar lines.  */
-#define FRAME_LINES(f) (f)->text_lines
-
-/* Width of frame F, measured in pixels not including the width for
-   fringes, scroll bar, and internal borders.  */
+/* Text width and height of frame F, in pixels and frame
+   columns/lines.  */
 #define FRAME_TEXT_WIDTH(f) (f)->text_width
-
-/* Height of frame F, measured in pixels not including the height
-   for scroll bar and internal borders.  */
 #define FRAME_TEXT_HEIGHT(f) (f)->text_height
+#define FRAME_COLS(f) ((f)->text_cols)
+#define FRAME_LINES(f) ((f)->text_lines)
 
-/* Number of lines of frame F used for menu bar.
-   This is relevant on terminal frames and on
-   X Windows when not using the X toolkit.
-   These lines are counted in FRAME_LINES.  */
-#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
+/* True if this frame should display an external menu bar.  */
+#ifdef HAVE_EXT_MENU_BAR
+#define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar
+#else
+#define FRAME_EXTERNAL_MENU_BAR(f) false
+#endif
 
-/* Pixel height of frame F's menu bar.  */
+/* Size of frame F's internal menu bar in frame lines and pixels.  */
+#define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
 #define FRAME_MENU_BAR_HEIGHT(f) (f)->menu_bar_height
 
-/* Number of lines of frame F used for the tab-bar.  */
+/* Size of frame F's tab bar in frame lines and pixels.  */
 #define FRAME_TAB_BAR_LINES(f) (f)->tab_bar_lines
-
-/* Pixel height of frame F's tab-bar.  */
 #define FRAME_TAB_BAR_HEIGHT(f) (f)->tab_bar_height
 
-/* True if this frame should display a tool bar
-   in a way that does not use any text lines.  */
+/* True if this frame should display an external tool bar.  */
 #ifdef HAVE_EXT_TOOL_BAR
 #define FRAME_EXTERNAL_TOOL_BAR(f) (f)->external_tool_bar
 #else
@@ -966,27 +949,21 @@ #define FRAME_TOOL_BAR_POSITION(f) (f)->tool_bar_position
 #define FRAME_TOOL_BAR_POSITION(f) ((void) (f), Qtop)
 #endif
 
-/* Number of lines of frame F used for the tool-bar.  */
+/* Size of frame F's internal tool bar in frame lines and pixels.  */
 #define FRAME_TOOL_BAR_LINES(f) (f)->tool_bar_lines
-
-/* Pixel height of frame F's tool-bar.  */
 #define FRAME_TOOL_BAR_HEIGHT(f) (f)->tool_bar_height
 
-/* Lines above the top-most window in frame F.  */
-#define FRAME_TOP_MARGIN(F) \
-  (FRAME_MENU_BAR_LINES (F) + FRAME_TAB_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F))
+/* Height of frame F's top margin in frame lines.  */
+#define FRAME_TOP_MARGIN(F)			\
+  (FRAME_MENU_BAR_LINES (F)			\
+   + FRAME_TAB_BAR_LINES (F)			\
+   + FRAME_TOOL_BAR_LINES (F))
 
 /* Pixel height of frame F's top margin.  */
-#define FRAME_TOP_MARGIN_HEIGHT(F)				\
-  (FRAME_MENU_BAR_HEIGHT (F) + FRAME_TAB_BAR_HEIGHT (F) + FRAME_TOOL_BAR_HEIGHT (F))
-
-/* True if this frame should display a menu bar
-   in a way that does not use any text lines.  */
-#ifdef HAVE_EXT_MENU_BAR
-#define FRAME_EXTERNAL_MENU_BAR(f) (f)->external_menu_bar
-#else
-#define FRAME_EXTERNAL_MENU_BAR(f) false
-#endif
+#define FRAME_TOP_MARGIN_HEIGHT(F)		\
+  (FRAME_MENU_BAR_HEIGHT (F)			\
+   + FRAME_TAB_BAR_HEIGHT (F)			\
+   + FRAME_TOOL_BAR_HEIGHT (F))
 
 /* True if frame F is currently visible.  */
 #define FRAME_VISIBLE_P(f) (f)->visible
@@ -1183,48 +1160,6 @@ #define FRAME_SCROLL_BAR_LINES(f)	\
    ? FRAME_CONFIG_SCROLL_BAR_LINES (f)	\
    : 0)
 
-/* Total width of frame F, in columns (characters),
-   including the width used by scroll bars if any.  */
-#define FRAME_TOTAL_COLS(f) ((f)->total_cols)
-
-/* Total height of frame F, in lines (characters),
-   including the height used by scroll bars if any.  */
-#define FRAME_TOTAL_LINES(f) ((f)->total_lines)
-
-/* Set the character widths of frame F.  WIDTH specifies a nominal
-   character text width.  */
-#define SET_FRAME_COLS(f, width)					\
-  ((f)->text_cols = (width),						\
-   (f)->total_cols = ((width)						\
-		      + FRAME_SCROLL_BAR_COLS (f)			\
-		      + FRAME_FRINGE_COLS (f)))
-
-/* Set the character heights of frame F.  HEIGHT specifies a nominal
-   character text height.  */
-#define SET_FRAME_LINES(f, height)					\
-  ((f)->text_lines = (height),						\
-   (f)->total_lines = ((height)						\
-		       + FRAME_TOP_MARGIN (f)				\
-		       + FRAME_SCROLL_BAR_LINES (f)))
-
-/* Set the widths of frame F.  WIDTH specifies a nominal pixel text
-   width.  */
-#define SET_FRAME_WIDTH(f, width)					\
-  ((f)->text_width = (width),						\
-   (f)->pixel_width = ((width)						\
-		       + FRAME_SCROLL_BAR_AREA_WIDTH (f)		\
-		       + FRAME_TOTAL_FRINGE_WIDTH (f)			\
-		       + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
-
-/* Set the heights of frame F.  HEIGHT specifies a nominal pixel text
-   height.  */
-#define SET_FRAME_HEIGHT(f, height)					\
-  ((f)->text_height = (height),						\
-   (f)->pixel_height = ((height)					\
-    			+ FRAME_TOP_MARGIN_HEIGHT (f)			\
-			+ FRAME_SCROLL_BAR_AREA_HEIGHT (f)		\
-			+ 2 * FRAME_INTERNAL_BORDER_WIDTH (f)))
-
 /* Maximum + 1 legitimate value for FRAME_CURSOR_X.  */
 #define FRAME_CURSOR_X_LIMIT(f) \
   (FRAME_COLS (f) + FRAME_LEFT_SCROLL_BAR_COLS (f))
@@ -1245,7 +1180,6 @@ #define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel)
 #define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel)
 
 /* Return a pointer to the face cache of frame F.  */
-
 #define FRAME_FACE_CACHE(F)	(F)->face_cache
 
 /* Return the size of message_buf of the frame F.  We multiply the
@@ -1271,15 +1205,13 @@ #define CHECK_LIVE_FRAME(x) \
    This macro is a holdover from a time when multiple frames weren't always
    supported.  An alternate definition of the macro would expand to
    something which executes the statement once.  */
-
-#define FOR_EACH_FRAME(list_var, frame_var)	\
-  for ((list_var) = Vframe_list;		\
-       (CONSP (list_var)			\
+#define FOR_EACH_FRAME(list_var, frame_var)	 \
+  for ((list_var) = Vframe_list;		 \
+       (CONSP (list_var)			 \
 	&& (frame_var = XCAR (list_var), true)); \
        list_var = XCDR (list_var))
 
 /* Reflect mouse movement when a complete frame update is performed.  */
-
 #define FRAME_MOUSE_UPDATE(frame)				\
   do {								\
     Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (frame);		\
@@ -1294,8 +1226,7 @@ #define FRAME_MOUSE_UPDATE(frame)				\
   } while (false)
 
 /* Handy macro to construct an argument to Fmodify_frame_parameters.  */
-
-#define AUTO_FRAME_ARG(name, parameter, value)	\
+#define AUTO_FRAME_ARG(name, parameter, value)		\
   AUTO_LIST1 (name, AUTO_CONS_EXPR (parameter, value))
 
 /* False means there are no visible garbaged frames.  */
@@ -1305,7 +1236,6 @@ #define AUTO_FRAME_ARG(name, parameter, value)	\
    We call redisplay_other_windows to make sure the frame gets redisplayed
    if some changes were applied to it while it wasn't visible (and hence
    wasn't redisplayed).  */
-
 INLINE void
 SET_FRAME_VISIBLE (struct frame *f, int v)
 {
@@ -1320,9 +1250,8 @@ SET_FRAME_VISIBLE (struct frame *f, int v)
   f->visible = v;
 }
 
-/* Set iconify of frame F.  */
-
-#define SET_FRAME_ICONIFIED(f, i)			\
+/* Set iconified status of frame F.  */
+#define SET_FRAME_ICONIFIED(f, i)				\
   (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i))
 
 extern Lisp_Object selected_frame;
@@ -1369,11 +1298,14 @@ window_system_available (struct frame *f)
 extern void frame_make_pointer_visible (struct frame *);
 extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
 extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object);
-extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object);
-extern void frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
-				    int width, int height, Lisp_Object rest);
+extern void adjust_frame_size (struct frame *, int, int, int, bool,
+			       Lisp_Object);
 extern Lisp_Object mouse_position (bool);
-
+extern int frame_windows_min_size (Lisp_Object, Lisp_Object, Lisp_Object,
+				   Lisp_Object);
+extern void frame_size_history_plain (struct frame *, Lisp_Object);
+extern void frame_size_history_extra (struct frame *, Lisp_Object,
+				      int, int, int, int, int, int);
 extern Lisp_Object Vframe_list;
 
 /* Value is a pointer to the selected frame.  If the selected frame
@@ -1652,12 +1584,11 @@ #define FRAME_PIXEL_TO_TEXT_HEIGHT(f, height)		\
    - FRAME_SCROLL_BAR_AREA_HEIGHT (f)			\
    - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
 
-/* Return the width/height reserved for the windows of frame F.  */
-#define FRAME_WINDOWS_WIDTH(f)			\
+#define FRAME_INNER_WIDTH(f)			\
   (FRAME_PIXEL_WIDTH (f)			\
    - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
 
-#define FRAME_WINDOWS_HEIGHT(f)			\
+#define FRAME_INNER_HEIGHT(f)			\
   (FRAME_PIXEL_HEIGHT (f)			\
    - FRAME_TOP_MARGIN_HEIGHT (f)		\
    - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
@@ -1701,7 +1632,7 @@ #define EMACS_CLASS "Emacs"
 extern void gui_set_scroll_bar_width (struct frame *, Lisp_Object, Lisp_Object);
 extern void gui_set_scroll_bar_height (struct frame *, Lisp_Object, Lisp_Object);
 
-extern long gui_figure_window_size (struct frame *, Lisp_Object, bool, bool, int *, int *);
+extern long gui_figure_window_size (struct frame *, Lisp_Object, bool, bool);
 
 extern void gui_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
 extern void gui_set_no_special_glyphs (struct frame *, Lisp_Object, Lisp_Object);
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 4634c35dd4..4ad172bb48 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -910,70 +910,58 @@ xg_set_geometry (struct frame *f)
     }
 }
 
-/* Function to handle resize of our frame.  As we have a Gtk+ tool bar
-   and a Gtk+ menu bar, we get resize events for the edit part of the
-   frame only.  We let Gtk+ deal with the Gtk+ parts.
-   F is the frame to resize.
-   PIXELWIDTH, PIXELHEIGHT is the new size in pixels.  */
-
+/** Function to handle resize of native frame F to WIDTH and HEIGHT
+    pixels after we got a ConfigureNotify event.  */
 void
-xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
+xg_frame_resized (struct frame *f, int width, int height)
 {
-  int width, height;
-
-  if (pixelwidth == -1 && pixelheight == -1)
+  /* 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 (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f)))
-	gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
-				 0, 0, &pixelwidth, &pixelheight);
-      else
-	return;
-    }
+      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);
 
-  width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth);
-  height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight);
-
-  frame_size_history_add
-    (f, Qxg_frame_resized, width, height, Qnil);
-
-  if (width != FRAME_TEXT_WIDTH (f)
-      || height != FRAME_TEXT_HEIGHT (f)
-      || pixelwidth != FRAME_PIXEL_WIDTH (f)
-      || pixelheight != FRAME_PIXEL_HEIGHT (f))
-    {
       FRAME_RIF (f)->clear_under_internal_border (f);
-      change_frame_size (f, width, height, 0, 1, 0, 1);
+      change_frame_size (f, width, height, false, true, false);
       SET_FRAME_GARBAGED (f);
       cancel_mouse_face (f);
     }
+  else if (CONSP (frame_size_history))
+    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);
+
 }
 
 /** Resize the outer window of frame F.  WIDTH and HEIGHT are the new
-    pixel sizes of F's text area.  */
+    native pixel sizes of F.  */
 void
 xg_frame_set_char_size (struct frame *f, int width, int height)
 {
-  int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
-  int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
   Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
   gint gwidth, gheight;
-  int totalheight
-    = pixelheight + FRAME_TOOLBAR_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
-  int totalwidth = pixelwidth + FRAME_TOOLBAR_WIDTH (f);
+  int outer_height
+    = height + FRAME_TOOLBAR_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
+  int outer_width = width + FRAME_TOOLBAR_WIDTH (f);
   bool was_visible = false;
   bool hide_child_frame;
 
-  if (FRAME_PIXEL_HEIGHT (f) == 0)
-    return;
-
   gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 		       &gwidth, &gheight);
 
   /* Do this before resize, as we don't know yet if we will be resized.  */
   FRAME_RIF (f)->clear_under_internal_border (f);
 
-  totalheight /= xg_get_scale (f);
-  totalwidth /= xg_get_scale (f);
+  outer_height /= xg_get_scale (f);
+  outer_width /= xg_get_scale (f);
 
   x_wm_set_size_hint (f, 0, 0);
 
@@ -986,35 +974,19 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
      manager will abolish it.  At least the respective size should
      remain unchanged but giving the frame back its normal size will
      be broken ... */
-  if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
-    {
-      frame_size_history_add
-	(f, Qxg_frame_set_char_size_1, width, height,
-	 list2i (gheight, totalheight));
-
-      gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-			 gwidth, totalheight);
-    }
-  else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
-    {
-      frame_size_history_add
-	(f, Qxg_frame_set_char_size_2, width, height,
-	 list2i (gwidth, totalwidth));
-
-      gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-			 totalwidth, gheight);
-    }
+  if (EQ (fullscreen, Qfullwidth) && width == FRAME_PIXEL_WIDTH (f))
+    gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+		       gwidth, outer_height);
+  else if (EQ (fullscreen, Qfullheight) && height == FRAME_PIXEL_HEIGHT (f))
+    gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+		       outer_width, gheight);
   else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f))
     {
       was_visible = true;
       hide_child_frame = EQ (x_gtk_resize_child_frames, Qhide);
 
-      if (totalwidth != gwidth || totalheight != gheight)
+      if (outer_width != gwidth || outer_height != gheight)
 	{
-	  frame_size_history_add
-	    (f, Qxg_frame_set_char_size_4, width, height,
-	     list2i (totalwidth, totalheight));
-
           if (hide_child_frame)
             {
               block_input ();
@@ -1023,7 +995,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
             }
 
 	  gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-			     totalwidth, totalheight);
+			     outer_width, outer_height);
 
           if (hide_child_frame)
             {
@@ -1037,11 +1009,8 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
     }
   else
     {
-      frame_size_history_add
-	(f, Qxg_frame_set_char_size_3, width, height,
-	 list2i (totalwidth, totalheight));
       gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-			 totalwidth, totalheight);
+			 outer_width, outer_height);
       fullscreen = Qnil;
     }
 
@@ -1062,6 +1031,12 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
       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);
+
       if (!NILP (fullscreen))
 	/* Try to restore fullscreen state.  */
 	{
@@ -1070,8 +1045,17 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
 	}
     }
   else
-    adjust_frame_size (f, width, height, 5, 0, Qxg_frame_set_char_size);
-
+    {
+      if (CONSP (frame_size_history))
+	frame_size_history_extra
+	  (f, build_string ("xg_frame_set_char_size, invisible"),
+	   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
+	   f->new_width, f->new_height);
+
+      adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
+			 FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
+			 5, 0, Qxg_frame_set_char_size);
+    }
 }
 
 /* Handle height/width changes (i.e. add/remove/move menu/toolbar).
@@ -1186,7 +1170,8 @@ style_changed_cb (GObject *go,
             {
               FRAME_TERMINAL (f)->set_scroll_bar_default_width_hook (f);
               FRAME_TERMINAL (f)->set_scroll_bar_default_height_hook (f);
-              xg_frame_set_char_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f));
+              xg_frame_set_char_size (f, FRAME_PIXEL_WIDTH (f),
+				      FRAME_PIXEL_HEIGHT (f));
             }
         }
     }
@@ -4589,10 +4574,7 @@ tb_size_cb (GtkWidget    *widget,
   struct frame *f = user_data;
 
   if (xg_update_tool_bar_sizes (f))
-    {
-      frame_size_history_add (f, Qtb_size_cb, 0, 0, Qnil);
-      adjust_frame_size (f, -1, -1, 5, 0, Qtool_bar_lines);
-    }
+    adjust_frame_size (f, -1, -1, 2, false, Qtool_bar_lines);
 }
 
 /* Create a tool bar for frame F.  */
@@ -5219,23 +5201,10 @@ update_frame_tool_bar (struct frame *f)
         xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f));
       gtk_widget_show_all (x->toolbar_widget);
       if (xg_update_tool_bar_sizes (f))
-	{
-	  int inhibit
-	    = ((f->after_make_frame
-		&& !f->tool_bar_resized
-		&& (EQ (frame_inhibit_implied_resize, Qt)
-		    || (CONSP (frame_inhibit_implied_resize)
-			&& !NILP (Fmemq (Qtool_bar_lines,
-					 frame_inhibit_implied_resize))))
-		/* This will probably fail to DTRT in the
-		   fullheight/-width cases.  */
-		&& NILP (get_frame_param (f, Qfullscreen)))
-	       ? 0
-	       : 2);
-
-	  frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
-	  adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
-	}
+	/* It's not entirely clear whether here we want a treatment
+	   similar to that for frames with internal tool bar.  */
+	adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
+
       f->tool_bar_resized = f->tool_bar_redisplayed;
     }
 
@@ -5284,7 +5253,6 @@ free_frame_tool_bar (struct frame *f)
                              NULL);
         }
 
-      frame_size_history_add (f, Qfree_frame_tool_bar, 0, 0, Qnil);
       adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
 
       unblock_input ();
@@ -5316,11 +5284,7 @@ xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
   g_object_unref (top_widget);
 
   if (xg_update_tool_bar_sizes (f))
-    {
-      frame_size_history_add (f, Qxg_change_toolbar_position, 0, 0, Qnil);
-      adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
-    }
-
+    adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
 
   unblock_input ();
 }
diff --git a/src/keyboard.c b/src/keyboard.c
index 5db45ce8e5..7f0342b00c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -10665,10 +10665,7 @@ DEFUN ("suspend-emacs", Fsuspend_emacs, Ssuspend_emacs, 0, 1, "",
      with a window system; but suspend should be disabled in that case.  */
   get_tty_size (fileno (CURTTY ()->input), &width, &height);
   if (width != old_width || height != old_height)
-    change_frame_size (SELECTED_FRAME (), width,
-		       height - FRAME_MENU_BAR_LINES (SELECTED_FRAME ())
-		       - FRAME_TAB_BAR_LINES (SELECTED_FRAME ()),
-		       0, 0, 0, 0);
+    change_frame_size (SELECTED_FRAME (), width, height, false, false, false);
 
   run_hook (intern ("suspend-resume-hook"));
 
diff --git a/src/nsfns.m b/src/nsfns.m
index 5c4cc915e7..054777aa66 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -669,21 +669,9 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
     }
 
   {
-    int inhibit
-      = ((f->after_make_frame
-	  && !f->tool_bar_resized
-	  && (EQ (frame_inhibit_implied_resize, Qt)
-	      || (CONSP (frame_inhibit_implied_resize)
-		  && !NILP (Fmemq (Qtool_bar_lines,
-				   frame_inhibit_implied_resize))))
-	  && NILP (get_frame_param (f, Qfullscreen)))
-	 ? 0
-	 : 2);
-
     NSTRACE_MSG ("inhibit:%d", inhibit);
 
-    frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
-    adjust_frame_size (f, -1, -1, inhibit, 0, Qtool_bar_lines);
+    adjust_frame_size (f, -1, -1, 2, false, Qtool_bar_lines);
   }
 }
 
@@ -1332,8 +1320,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
                          RES_TYPE_STRING);
 
   parms = get_geometry_from_preferences (dpyinfo, parms);
-  window_prompting = gui_figure_window_size (f, parms, false, true,
-                                             &x_width, &x_height);
+  window_prompting = gui_figure_window_size (f, parms, false, true);
 
   tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
                              RES_TYPE_BOOLEAN);
@@ -1400,13 +1387,8 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   /* Allow set_window_size_hook, now.  */
   f->can_set_window_size = true;
 
-  if (x_width > 0)
-    SET_FRAME_WIDTH (f, x_width);
-  if (x_height > 0)
-    SET_FRAME_HEIGHT (f, x_height);
-
-  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1,
-		     Qx_create_frame_2);
+  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+		     0, true, Qx_create_frame_2);
 
   if (! f->output_data.ns->explicit_parent)
     {
diff --git a/src/nsterm.m b/src/nsterm.m
index a6501100ca..b135e359f5 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1876,10 +1876,9 @@ Hide the window (X11 semantics)
 ns_set_window_size (struct frame *f,
                     bool change_gravity,
                     int width,
-                    int height,
-                    bool pixelwise)
+                    int height)
 /* --------------------------------------------------------------------------
-     Adjust window pixel size based on given character grid size
+     Adjust window pixel size based on native sizes WIDTH and HEIGHT.
      Impl is a bit more complex than other terms, need to do some
      internal clipping.
    -------------------------------------------------------------------------- */
@@ -1887,7 +1886,6 @@ Hide the window (X11 semantics)
   EmacsView *view = FRAME_NS_VIEW (f);
   NSWindow *window = [view window];
   NSRect wr = [window frame];
-  int pixelwidth, pixelheight;
   int orig_height = wr.size.height;
 
   NSTRACE ("ns_set_window_size");
@@ -1896,24 +1894,13 @@ Hide the window (X11 semantics)
     return;
 
   NSTRACE_RECT ("current", wr);
-  NSTRACE_MSG ("Width:%d Height:%d Pixelwise:%d", width, height, pixelwise);
+  NSTRACE_MSG ("Width:%d Height:%d", width, height);
   NSTRACE_MSG ("Font %d x %d", FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f));
 
   block_input ();
 
-  if (pixelwise)
-    {
-      pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
-      pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
-    }
-  else
-    {
-      pixelwidth =  FRAME_TEXT_COLS_TO_PIXEL_WIDTH   (f, width);
-      pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
-    }
-
-  wr.size.width = pixelwidth + f->border_width;
-  wr.size.height = pixelheight;
+  wr.size.width = width + f->border_width;
+  wr.size.height = height;
   if (! [view isFullscreen])
     wr.size.height += FRAME_NS_TITLEBAR_HEIGHT (f)
       + FRAME_TOOLBAR_HEIGHT (f);
@@ -1926,21 +1913,10 @@ Hide the window (X11 semantics)
  else
    wr.origin.y += orig_height - wr.size.height;
 
- frame_size_history_add
-   (f, Qx_set_window_size_1, width, height,
-    list5 (Fcons (make_fixnum (pixelwidth), make_fixnum (pixelheight)),
-	   Fcons (make_fixnum (wr.size.width), make_fixnum (wr.size.height)),
-	   make_fixnum (f->border_width),
-	   make_fixnum (FRAME_NS_TITLEBAR_HEIGHT (f)),
-	   make_fixnum (FRAME_TOOLBAR_HEIGHT (f))));
-
  /* Usually it seems safe to delay changing the frame size, but when a
     series of actions are taken with no redisplay between them then we
     can end up using old values so don't delay here.  */
- change_frame_size (f,
-                    FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth),
-                    FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight),
-                    0, NO, 0, 1);
+ change_frame_size (f, width, height, false, NO, false);
 
   [window setFrame:wr display:NO];
 
@@ -7359,10 +7335,7 @@ - (void)viewDidResize:(NSNotification *)notification
      changes size, as Emacs may already know about the change.
      Unfortunately there doesn't seem to be a bullet-proof method of
      determining whether we need to call it or not.  */
-  change_frame_size (emacsframe,
-                     FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww),
-                     FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh),
-                     0, YES, 0, 1);
+  change_frame_size (emacsframe, neww, newh, false, YES, false);
 
   SET_FRAME_GARBAGED (emacsframe);
   cancel_mouse_face (emacsframe);
diff --git a/src/term.c b/src/term.c
index 1059b0669a..c995a4499c 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2356,9 +2356,7 @@ DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
 	     was suspended.  */
 	  get_tty_size (fileno (t->display_info.tty->input), &width, &height);
 	  if (width != old_width || height != old_height)
-	    change_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f)
-			       - FRAME_TAB_BAR_LINES (f),
-			       0, 0, 0, 0);
+	    change_frame_size (f, width, height, false, false, false);
 	  SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
 	}
 
diff --git a/src/termhooks.h b/src/termhooks.h
index 3800679e80..1d3cdc8fe8 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -583,7 +583,7 @@ #define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event))
    window gravity for this size change and subsequent size changes.
    Otherwise we leave the window gravity unchanged.  */
   void (*set_window_size_hook) (struct frame *f, bool change_gravity,
-                                int width, int height, bool pixelwise);
+                                int width, int height);
 
   /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
    to really change the position, and 0 when calling from
diff --git a/src/w32fns.c b/src/w32fns.c
index c07f32ab0c..66baeaecbd 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1701,7 +1701,7 @@ w32_change_tab_bar_height (struct frame *f, int height)
   int unit = FRAME_LINE_HEIGHT (f);
   int old_height = FRAME_TAB_BAR_HEIGHT (f);
   int lines = (height + unit - 1) / unit;
-  Lisp_Object fullscreen;
+  Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
 
   /* Make sure we redisplay all windows in this frame.  */
   fset_redisplay (f);
@@ -1728,25 +1728,21 @@ w32_change_tab_bar_height (struct frame *f, int height)
   if ((height < old_height) && WINDOWP (f->tab_bar_window))
     clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
 
-  /* Recalculate tabbar height.  */
-  f->n_tab_bar_rows = 0;
-  if (old_height == 0
-      && (!f->after_make_frame
-	  || NILP (frame_inhibit_implied_resize)
-	  || (CONSP (frame_inhibit_implied_resize)
-	      && NILP (Fmemq (Qtab_bar_lines, frame_inhibit_implied_resize)))))
-    f->tab_bar_redisplayed = f->tab_bar_resized = false;
-
-  adjust_frame_size (f, -1, -1,
-		     ((!f->tab_bar_resized
-		       && (NILP (fullscreen =
-				 get_frame_param (f, Qfullscreen))
-			   || EQ (fullscreen, Qfullwidth))) ? 1
-		      : (old_height == 0 || height == 0) ? 2
-		      : 4),
-		     false, Qtab_bar_lines);
-
-  f->tab_bar_resized = f->tab_bar_redisplayed;
+  if (!f->tab_bar_resized)
+    {
+      /* As long as tab_bar_resized is false, effectively try to change
+	 F's native height.  */
+      if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+	adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+			   1, false, Qtab_bar_lines);
+      else
+	adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
+
+      f->tab_bar_resized = f->tab_bar_redisplayed;
+    }
+  else
+    /* Any other change may leave the native size of F alone.  */
+    adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
 
   /* adjust_frame_size might not have done anything, garbage frame
      here.  */
@@ -1790,7 +1786,7 @@ w32_change_tool_bar_height (struct frame *f, int height)
   int unit = FRAME_LINE_HEIGHT (f);
   int old_height = FRAME_TOOL_BAR_HEIGHT (f);
   int lines = (height + unit - 1) / unit;
-  Lisp_Object fullscreen;
+  Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
 
   /* Make sure we redisplay all windows in this frame.  */
   windows_or_buffers_changed = 23;
@@ -1811,25 +1807,21 @@ w32_change_tool_bar_height (struct frame *f, int height)
   if ((height < old_height) && WINDOWP (f->tool_bar_window))
     clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
 
-  /* Recalculate toolbar height.  */
-  f->n_tool_bar_rows = 0;
-  if (old_height == 0
-      && (!f->after_make_frame
-	  || NILP (frame_inhibit_implied_resize)
-	  || (CONSP (frame_inhibit_implied_resize)
-	      && NILP (Fmemq (Qtool_bar_lines, frame_inhibit_implied_resize)))))
-    f->tool_bar_redisplayed = f->tool_bar_resized = false;
-
-  adjust_frame_size (f, -1, -1,
-		     ((!f->tool_bar_resized
-		       && (NILP (fullscreen =
-				 get_frame_param (f, Qfullscreen))
-			   || EQ (fullscreen, Qfullwidth))) ? 1
-		      : (old_height == 0 || height == 0) ? 2
-		      : 4),
-		     false, Qtool_bar_lines);
-
-  f->tool_bar_resized = f->tool_bar_redisplayed;
+  if (!f->tool_bar_resized)
+    {
+      /* As long as tool_bar_resized is false, effectively try to change
+	 F's native height.  */
+      if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+	adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+			   1, false, Qtool_bar_lines);
+      else
+	adjust_frame_size (f, -1, -1, 4, false, Qtool_bar_lines);
+
+      f->tool_bar_resized =  f->tool_bar_redisplayed;
+    }
+  else
+    /* Any other change may leave the native size of F alone.  */
+    adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_lines);
 
   /* adjust_frame_size might not have done anything, garbage frame
      here.  */
@@ -5718,7 +5710,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   struct w32_display_info *dpyinfo = NULL;
   Lisp_Object parent, parent_frame;
   struct kboard *kb;
-  int x_width = 0, x_height = 0;
 
   if (!FRAME_W32_P (SELECTED_FRAME ())
       && !FRAME_INITIAL_P (SELECTED_FRAME ()))
@@ -6045,8 +6036,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
   f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
 
-  window_prompting = gui_figure_window_size (f, parameters, true, true,
-                                             &x_width, &x_height);
+  window_prompting = gui_figure_window_size (f, parameters, true, true);
 
   tem = gui_display_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0,
                              RES_TYPE_BOOLEAN);
@@ -6081,11 +6071,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   /* Allow set_window_size_hook, now.  */
   f->can_set_window_size = true;
 
-  if (x_width > 0)
-    SET_FRAME_WIDTH (f, x_width);
-  if (x_height > 0)
-    SET_FRAME_HEIGHT (f, x_height);
-
   /* Tell the server what size and position, etc, we want, and how
      badly we want them.  This should be done after we have the menu
      bar so that its size can be taken into account.  */
@@ -6093,8 +6078,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   w32_wm_set_size_hint (f, window_prompting, false);
   unblock_input ();
 
-  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, true,
-		     Qx_create_frame_2);
+  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+		     0, true, Qx_create_frame_2);
 
   /* Process fullscreen parameter here in the hope that normalizing a
      fullheight/fullwidth frame will produce the size set by the last
@@ -6888,11 +6873,9 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
   struct frame *f;
   Lisp_Object frame;
   Lisp_Object name;
-  int width, height;
   ptrdiff_t count = SPECPDL_INDEX ();
   struct kboard *kb;
   bool face_change_before = face_change;
-  int x_width = 0, x_height = 0;
 
   /* Use this general default value to start with until we know if
      this frame has a specified name.  */
@@ -7013,7 +6996,7 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
   f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
   f->output_data.w32->explicit_parent = false;
 
-  gui_figure_window_size (f, parms, true, true, &x_width, &x_height);
+  gui_figure_window_size (f, parms, true, true);
 
   /* No fringes on tip frame.  */
   f->fringe_cols = 0;
@@ -7039,15 +7022,6 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
 
-  /* Dimensions, especially FRAME_LINES (f), must be done via
-     change_frame_size.  Change will not be effected unless different
-     from the current FRAME_LINES (f).  */
-  width = FRAME_COLS (f);
-  height = FRAME_LINES (f);
-  SET_FRAME_COLS (f, 0);
-  SET_FRAME_LINES (f, 0);
-  adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
-		     height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame);
   /* Add `tooltip' frame parameter's default value. */
   if (NILP (Fframe_parameter (frame, Qtooltip)))
     Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
@@ -7088,6 +7062,8 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
      visible won't work.  */
   Vframe_list = Fcons (frame, Vframe_list);
   f->can_set_window_size = true;
+  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+		     0, true, Qtip_frame);
 
   /* Setting attributes of faces of the tooltip frame from resources
      and similar will set face_change, which leads to the
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 1a80a00197..1255072b7f 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -608,9 +608,7 @@ resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
 {
   struct frame *f = get_frame ();
 
-  change_frame_size (f, event->dwSize.X, event->dwSize.Y
-		     - FRAME_MENU_BAR_LINES (f)
-		     - FRAME_TAB_BAR_LINES (f), 0, 1, 0, 0);
+  change_frame_size (f, event->dwSize.X, event->dwSize.Y, false, true, false);
   SET_FRAME_GARBAGED (f);
 }
 
@@ -624,11 +622,9 @@ maybe_generate_resize_event (void)
 
   /* It is okay to call this unconditionally, since it will do nothing
      if the size hasn't actually changed.  */
-  change_frame_size (f,
-		     1 + info.srWindow.Right - info.srWindow.Left,
-		     1 + info.srWindow.Bottom - info.srWindow.Top
-		     - FRAME_MENU_BAR_LINES (f)
-		     - FRAME_TAB_BAR_LINES (f), 0, 1, 0, 0);
+  change_frame_size (f, 1 + info.srWindow.Right - info.srWindow.Left,
+		     1 + info.srWindow.Bottom - info.srWindow.Top,
+		     false, true, false);
 }
 
 #if HAVE_W32NOTIFY
diff --git a/src/w32term.c b/src/w32term.c
index 361cf33c02..4f910296ec 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5352,7 +5352,7 @@ w32_read_socket (struct terminal *terminal,
 	  if (f)
 	    {
 	      RECT rect;
-	      int /* rows, columns, */ width, height, text_width, text_height;
+	      int /* rows, columns, */ width, height;
 
 	      if (GetClientRect (msg.msg.hwnd, &rect)
 		  /* GetClientRect evidently returns (0, 0, 0, 0) if
@@ -5365,23 +5365,11 @@ w32_read_socket (struct terminal *terminal,
 		{
 		  height = rect.bottom - rect.top;
 		  width = rect.right - rect.left;
-		  text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
-		  text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
-		  /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
-		  /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
-
-		  /* TODO: Clip size to the screen dimensions.  */
-
-		  /* Even if the number of character rows and columns
-		     has not changed, the font size may have changed,
-		     so we need to check the pixel dimensions as well.  */
-
 		  if (width != FRAME_PIXEL_WIDTH (f)
-		      || height != FRAME_PIXEL_HEIGHT (f)
-		      || text_width != FRAME_TEXT_WIDTH (f)
-		      || text_height != FRAME_TEXT_HEIGHT (f))
+		      || height != FRAME_PIXEL_HEIGHT (f))
 		    {
-		      change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
+		      change_frame_size
+			(f, width, height, false, true, false);
 		      SET_FRAME_GARBAGED (f);
 		      cancel_mouse_face (f);
 		      f->win_gravity = NorthWestGravity;
@@ -5565,7 +5553,7 @@ w32_read_socket (struct terminal *terminal,
 	  if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
 	    {
 	      RECT rect;
-	      int /* rows, columns, */ width, height, text_width, text_height;
+	      int /* rows, columns, */ width, height;
 
 	      if (GetClientRect (msg.msg.hwnd, &rect)
 		  /* GetClientRect evidently returns (0, 0, 0, 0) if
@@ -5578,23 +5566,12 @@ w32_read_socket (struct terminal *terminal,
 		{
 		  height = rect.bottom - rect.top;
 		  width = rect.right - rect.left;
-		  text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, width);
-		  text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, height);
-		  /* rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); */
-		  /* columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); */
-
-		  /* TODO: Clip size to the screen dimensions.  */
-
-		  /* Even if the number of character rows and columns
-		     has not changed, the font size may have changed,
-		     so we need to check the pixel dimensions as well.  */
 
 		  if (width != FRAME_PIXEL_WIDTH (f)
-		      || height != FRAME_PIXEL_HEIGHT (f)
-		      || text_width != FRAME_TEXT_WIDTH (f)
-		      || text_height != FRAME_TEXT_HEIGHT (f))
+		      || height != FRAME_PIXEL_HEIGHT (f))
 		    {
-		      change_frame_size (f, text_width, text_height, 0, 1, 0, 1);
+		      change_frame_size
+			(f, width, height, false, true, false);
 		      SET_FRAME_GARBAGED (f);
 		      cancel_mouse_face (f);
 		      f->win_gravity = NorthWestGravity;
@@ -6267,17 +6244,15 @@ w32_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 	FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
     }
 
-  /* Now make the frame display the given font.  */
-  if (FRAME_NATIVE_WINDOW (f) != 0)
-    {
-      /* Don't change the size of a tip frame; there's no point in
-	 doing it because it's done in Fx_show_tip, and it leads to
-	 problems because the tip frame has no widget.  */
-      if (!FRAME_TOOLTIP_P (f))
-	adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-			   FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
-			   false, Qfont);
-    }
+  FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
+
+/* Don't change the size of a tip frame; there's no point in
+   doing it because it's done in Fx_show_tip, and it leads to
+   problems because the tip frame has no widget.  */
+  if (FRAME_NATIVE_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
+    adjust_frame_size
+      (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
 
   /* X version sets font of input methods here also.  */
 
@@ -6490,7 +6465,8 @@ w32fullscreen_hook (struct frame *f)
 	ShowWindow (hwnd, SW_SHOWNORMAL);
       else if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
 	{
-	  if (prev_fsmode == FULLSCREEN_BOTH || prev_fsmode == FULLSCREEN_WIDTH
+	  if (prev_fsmode == FULLSCREEN_BOTH
+	      || prev_fsmode == FULLSCREEN_WIDTH
 	      || prev_fsmode == FULLSCREEN_HEIGHT)
 	    /* Make window normal since otherwise the subsequent
 	       maximization might fail in some cases.  */
@@ -6499,52 +6475,31 @@ w32fullscreen_hook (struct frame *f)
 	}
       else if (f->want_fullscreen == FULLSCREEN_BOTH)
         {
-	  int menu_bar_height = GetSystemMetrics (SM_CYMENU);
-
-	  w32_fullscreen_rect (hwnd, f->want_fullscreen,
-			       FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
+	  w32_fullscreen_rect
+	    (hwnd, f->want_fullscreen,
+	     FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
 	  if (!FRAME_UNDECORATED (f))
 	    SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
           SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
                         rect.right - rect.left, rect.bottom - rect.top,
                         SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
 	  change_frame_size
-	    (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left),
-	     FRAME_PIXEL_TO_TEXT_HEIGHT (f, (rect.bottom - rect.top
-					     - menu_bar_height)),
-	     0, 1, 0, 1);
+	    (f, rect.right - rect.left, rect.bottom - rect.top,
+	     false, true, false);
         }
       else
         {
 	  ShowWindow (hwnd, SW_SHOWNORMAL);
-	  w32_fullscreen_rect (hwnd, f->want_fullscreen,
-			       FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
+	  w32_fullscreen_rect
+	    (hwnd, f->want_fullscreen,
+	     FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
           SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
                         rect.right - rect.left, rect.bottom - rect.top, 0);
 
-	  if (f->want_fullscreen == FULLSCREEN_WIDTH)
-	    {
-	      int border_width = GetSystemMetrics (SM_CXFRAME);
-
-	      change_frame_size
-		(f, (FRAME_PIXEL_TO_TEXT_WIDTH
-		     (f, rect.right - rect.left - 2 * border_width)),
-		 0, 0, 1, 0, 1);
-	    }
-	  else
-	    {
-	      int border_height = GetSystemMetrics (SM_CYFRAME);
-	      /* Won't work for wrapped menu bar.  */
-	      int menu_bar_height = GetSystemMetrics (SM_CYMENU);
-	      int title_height = GetSystemMetrics (SM_CYCAPTION);
-
-	      change_frame_size
-		(f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT
-			(f, rect.bottom - rect.top - 2 * border_height
-			 - title_height - menu_bar_height)),
-		 0, 1, 0, 1);
-	    }
-        }
+	  change_frame_size
+	    (f, rect.right - rect.left, rect.bottom - rect.top,
+	     false, true, false);
+	}
 
       f->want_fullscreen = FULLSCREEN_NONE;
       unblock_input ();
@@ -6559,16 +6514,14 @@ w32fullscreen_hook (struct frame *f)
     f->want_fullscreen |= FULLSCREEN_WAIT;
 }
 
-/* Call this to change the size of frame F's native window.
-   If CHANGE_GRAVITY, change to top-left-corner window gravity
-   for this size change and subsequent size changes.
-   Otherwise we leave the window gravity unchanged.  */
-
+/* Change the size of frame F's Windows window to WIDTH and HEIGHT
+   pixels.  If CHANGE_GRAVITY, change to top-left-corner window gravity
+   for this size change and subsequent size changes.  Otherwise leave
+   the window gravity unchanged.  */
 static void
 w32_set_window_size (struct frame *f, bool change_gravity,
-		   int width, int height, bool pixelwise)
+		     int width, int height)
 {
-  int pixelwidth, pixelheight;
   Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
   RECT rect;
   MENUBARINFO info;
@@ -6584,17 +6537,6 @@ w32_set_window_size (struct frame *f, bool change_gravity,
   GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info);
   menu_bar_height = info.rcBar.bottom - info.rcBar.top;
 
-  if (pixelwise)
-    {
-      pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
-      pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
-    }
-  else
-    {
-      pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
-      pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
-    }
-
   if (w32_add_wrapped_menu_bar_lines)
     {
       /* When the menu bar wraps sending a SetWindowPos shrinks the
@@ -6610,15 +6552,15 @@ w32_set_window_size (struct frame *f, bool change_gravity,
       if ((default_menu_bar_height > 0)
 	  && (menu_bar_height > default_menu_bar_height)
 	  && ((menu_bar_height % default_menu_bar_height) == 0))
-	pixelheight = pixelheight + menu_bar_height - default_menu_bar_height;
+	height = height + menu_bar_height - default_menu_bar_height;
     }
 
   f->win_gravity = NorthWestGravity;
   w32_wm_set_size_hint (f, (long) 0, false);
 
   rect.left = rect.top = 0;
-  rect.right = pixelwidth;
-  rect.bottom = pixelheight;
+  rect.right = width;
+  rect.bottom = height;
 
   AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0);
 
@@ -6636,7 +6578,7 @@ w32_set_window_size (struct frame *f, bool change_gravity,
 	{
 	  rect.left = window_rect.left;
 	  rect.right = window_rect.right;
-	  pixelwidth = 0;
+	  width = -1;
 	}
       if (EQ (fullscreen, Qmaximized)
 	  || EQ (fullscreen, Qfullboth)
@@ -6644,19 +6586,12 @@ w32_set_window_size (struct frame *f, bool change_gravity,
 	{
 	  rect.top = window_rect.top;
 	  rect.bottom = window_rect.bottom;
-	  pixelheight = 0;
+	  height = -1;
 	}
     }
 
-  if (pixelwidth > 0 || pixelheight > 0)
+  if (width > 0 || height > 0)
     {
-      frame_size_history_add
-	(f, Qx_set_window_size_1, width, height,
-	 list2 (Fcons (make_fixnum (pixelwidth),
-		       make_fixnum (pixelheight)),
-		Fcons (make_fixnum (rect.right - rect.left),
-		       make_fixnum (rect.bottom - rect.top))));
-
       if (!FRAME_PARENT_FRAME (f))
 	my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
 			   0, 0,
@@ -6670,12 +6605,7 @@ w32_set_window_size (struct frame *f, bool change_gravity,
 			   rect.bottom - rect.top,
 			   SWP_NOMOVE | SWP_NOACTIVATE);
 
-      change_frame_size (f,
-			 ((pixelwidth == 0)
-			     ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)),
-			 ((pixelheight == 0)
-			  ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)),
-			 0, 1, 0, 1);
+      change_frame_size (f, width, height, false, true, false);
       SET_FRAME_GARBAGED (f);
 
       /* If cursor was outside the new size, mark it as off.  */
diff --git a/src/widget.c b/src/widget.c
index 43f0307b4e..dd43fd1c46 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -168,14 +168,6 @@ pixel_to_char_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height
   *char_height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (int) pixel_height);
 }
 
-static void
-pixel_to_text_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height, int *text_width, int *text_height)
-{
-  struct frame *f = ew->emacs_frame.frame;
-  *text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, (int) pixel_width);
-  *text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, (int) pixel_height);
-}
-
 static void
 char_to_pixel_size (EmacsFrame ew, int char_width, int char_height, Dimension *pixel_width, Dimension *pixel_height)
 {
@@ -257,27 +249,14 @@ set_frame_size (EmacsFrame ew)
 
    */
 
-  /* Hairily merged geometry */
   struct frame *f = ew->emacs_frame.frame;
-  int w = FRAME_COLS (f);
-  int h = FRAME_LINES (f);
-  Widget wmshell = get_wm_shell ((Widget) ew);
-  Dimension pixel_width, pixel_height;
-  /* Each Emacs shell is now independent and top-level.  */
-
-  if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort ();
-
-  char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
-  ew->core.width = (frame_resize_pixelwise
-		    ? FRAME_PIXEL_WIDTH (f)
-		    : pixel_width);
-  ew->core.height = (frame_resize_pixelwise
-		     ? FRAME_PIXEL_HEIGHT (f)
-		     : pixel_height);
-
-  frame_size_history_add
-    (f, Qset_frame_size, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
-     list2i (ew->core.width, ew->core.height));
+
+  ew->core.width = FRAME_PIXEL_WIDTH (f);
+  ew->core.height = FRAME_PIXEL_HEIGHT (f);
+
+  if (CONSP (frame_size_history))
+    frame_size_history_plain
+      (f, build_string ("set_frame_size"));
 }
 
 static void
@@ -350,6 +329,13 @@ update_from_various_frame_slots (EmacsFrame ew)
   ew->emacs_frame.foreground_pixel = FRAME_FOREGROUND_PIXEL (f);
   ew->emacs_frame.cursor_color = x->cursor_pixel;
   ew->core.border_pixel = x->border_pixel;
+
+  if (CONSP (frame_size_history))
+    frame_size_history_extra
+      (f, build_string ("update_from_various_frame_slots"),
+       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+       ew->core.width, ew->core.height,
+       f->new_width, f->new_height);
 }
 
 static void
@@ -381,6 +367,7 @@ resize_cb (Widget widget,
 EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs)
 {
   EmacsFrame ew = (EmacsFrame) widget;
+  struct frame *f = ew->emacs_frame.frame;
 
   /* This used to contain SubstructureRedirectMask, but this turns out
      to be a problem with XIM on Solaris, and events from that mask
@@ -394,6 +381,11 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs
   /* Some ConfigureNotify events does not end up in EmacsFrameResize so
      make sure we get them all.  Seen with xfcwm4 for example.  */
   XtAddRawEventHandler (widget, StructureNotifyMask, False, resize_cb, NULL);
+
+  if (CONSP (frame_size_history))
+    frame_size_history_plain
+      (f, build_string ("EmacsFrameRealize"));
+
   update_wm_hints (ew);
 }
 
@@ -408,18 +400,15 @@ EmacsFrameResize (Widget widget)
 {
   EmacsFrame ew = (EmacsFrame) widget;
   struct frame *f = ew->emacs_frame.frame;
-  int width, height;
-
-  pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
 
-  frame_size_history_add
-    (f, QEmacsFrameResize, width, height,
-     list5 (make_fixnum (ew->core.width), make_fixnum (ew->core.height),
-	    make_fixnum (FRAME_TOP_MARGIN_HEIGHT (f)),
-	    make_fixnum (FRAME_SCROLL_BAR_AREA_HEIGHT (f)),
-	    make_fixnum (2 * FRAME_INTERNAL_BORDER_WIDTH (f))));
+  if (CONSP (frame_size_history))
+    frame_size_history_extra
+      (f, build_string ("EmacsFrameResize"),
+       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+       ew->core.width, ew->core.height,
+       f->new_width, f->new_height);
 
-  change_frame_size (f, width, height, 0, 1, 0, 1);
+  change_frame_size (f, ew->core.width, ew->core.height, false, true, false);
 
   update_wm_hints (ew);
   update_various_frame_slots (ew);
@@ -463,9 +452,17 @@ EmacsFrameSetCharSize (Widget widget, int columns, int rows)
   EmacsFrame ew = (EmacsFrame) widget;
   struct frame *f = ew->emacs_frame.frame;
 
+  if (CONSP (frame_size_history))
+    frame_size_history_extra
+      (f, build_string ("EmacsFrameSetCharSize"),
+       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+       columns, rows,
+       f->new_width, f->new_height);
+
   if (!frame_inhibit_resize (f, 0, Qfont)
       && !frame_inhibit_resize (f, 1, Qfont))
-    x_set_window_size (f, 0, columns, rows, 0);
+    x_set_window_size (f, 0, columns * FRAME_COLUMN_WIDTH (f),
+		       rows * FRAME_LINE_HEIGHT (f));
 }
 
 \f
diff --git a/src/xdisp.c b/src/xdisp.c
index 7a89089958..23b4ba5c39 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11860,7 +11860,7 @@ resize_mini_window (struct window *w, bool exact_p)
       int height, max_height;
       struct text_pos start;
       struct buffer *old_current_buffer = NULL;
-      int windows_height = FRAME_WINDOWS_HEIGHT (f);
+      int windows_height = FRAME_INNER_HEIGHT (f);
 
       if (current_buffer != XBUFFER (w->contents))
 	{
@@ -13477,8 +13477,6 @@ DEFUN ("tab-bar-height", Ftab_bar_height, Stab_bar_height,
 static bool
 redisplay_tab_bar (struct frame *f)
 {
-  f->tab_bar_redisplayed = true;
-
   struct window *w;
   struct it it;
   struct glyph_row *row;
@@ -13492,6 +13490,8 @@ redisplay_tab_bar (struct frame *f)
           WINDOW_TOTAL_LINES (w) == 0))
     return false;
 
+  f->tab_bar_redisplayed = true;
+
   /* Set up an iterator for the tab-bar window.  */
   init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TAB_BAR_FACE_ID);
   it.first_visible_x = 0;
@@ -14402,21 +14402,13 @@ DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
   return make_fixnum (height);
 }
 
+#ifndef HAVE_EXT_TOOL_BAR
 
-/* Display the tool-bar of frame F.  Value is true if tool-bar's
-   height should be changed.  */
+/* Display the internal tool-bar of frame F.  Value is true if
+   tool-bar's height should be changed.  */
 static bool
 redisplay_tool_bar (struct frame *f)
 {
-  f->tool_bar_redisplayed = true;
-#ifdef HAVE_EXT_TOOL_BAR
-
-  if (FRAME_EXTERNAL_TOOL_BAR (f))
-    update_frame_tool_bar (f);
-  return false;
-
-#else /* ! (HAVE_EXT_TOOL_BAR) */
-
   struct window *w;
   struct it it;
   struct glyph_row *row;
@@ -14430,6 +14422,8 @@ redisplay_tool_bar (struct frame *f)
           WINDOW_TOTAL_LINES (w) == 0))
     return false;
 
+  f->tool_bar_redisplayed = true;
+
   /* Set up an iterator for the tool-bar window.  */
   init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
   it.first_visible_x = 0;
@@ -14565,13 +14559,10 @@ redisplay_tool_bar (struct frame *f)
     }
 
   f->minimize_tool_bar_window_p = false;
-  return false;
 
-#endif /* HAVE_EXT_TOOL_BAR */
+  return false;
 }
 
-#ifndef HAVE_EXT_TOOL_BAR
-
 /* Get information about the tool-bar item which is displayed in GLYPH
    on frame F.  Return in *PROP_IDX the index where tool-bar item
    properties start in F->tool_bar_items.  Value is false if
@@ -19334,7 +19325,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
 
 #ifdef HAVE_EXT_TOOL_BAR
 	  if (FRAME_EXTERNAL_TOOL_BAR (f))
-	    redisplay_tool_bar (f);
+	    update_frame_tool_bar (f);
 #else
 	  if (WINDOWP (f->tool_bar_window)
 	      && (FRAME_TOOL_BAR_LINES (f) > 0
diff --git a/src/xfns.c b/src/xfns.c
index f120653ee7..2c95065d3e 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1563,7 +1563,6 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
 #else /* not USE_X_TOOLKIT && not USE_GTK */
   FRAME_MENU_BAR_LINES (f) = nlines;
   FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
-  adjust_frame_size (f, -1, -1, 2, true, Qx_set_menu_bar_lines);
   if (FRAME_X_WINDOW (f))
     x_clear_under_internal_border (f);
 
@@ -1577,6 +1576,8 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       int width = FRAME_PIXEL_WIDTH (f);
       int y;
 
+      adjust_frame_size (f, -1, -1, 3, true, Qmenu_bar_lines);
+
       /* height can be zero here. */
       if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
 	{
@@ -1637,7 +1638,7 @@ x_change_tab_bar_height (struct frame *f, int height)
   int unit = FRAME_LINE_HEIGHT (f);
   int old_height = FRAME_TAB_BAR_HEIGHT (f);
   int lines = (height + unit - 1) / unit;
-  Lisp_Object fullscreen;
+  Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
 
   /* Make sure we redisplay all windows in this frame.  */
   fset_redisplay (f);
@@ -1645,16 +1646,8 @@ x_change_tab_bar_height (struct frame *f, int height)
   /* Recalculate tab bar and frame text sizes.  */
   FRAME_TAB_BAR_HEIGHT (f) = height;
   FRAME_TAB_BAR_LINES (f) = lines;
-  /* Store the `tab-bar-lines' and `height' frame parameters.  */
   store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
-  store_frame_param (f, Qheight, make_fixnum (FRAME_LINES (f)));
-
-  /* We also have to make sure that the internal border at the top of
-     the frame, below the menu bar or tab bar, is redrawn when the
-     tab bar disappears.  This is so because the internal border is
-     below the tab bar if one is displayed, but is below the menu bar
-     if there isn't a tab bar.  The tab bar draws into the area
-     below the menu bar.  */
+
   if (FRAME_X_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
     {
       clear_frame (f);
@@ -1664,25 +1657,21 @@ x_change_tab_bar_height (struct frame *f, int height)
   if ((height < old_height) && WINDOWP (f->tab_bar_window))
     clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
 
-  /* Recalculate tabbar height.  */
-  f->n_tab_bar_rows = 0;
-  if (old_height == 0
-      && (!f->after_make_frame
-	  || NILP (frame_inhibit_implied_resize)
-	  || (CONSP (frame_inhibit_implied_resize)
-	      && NILP (Fmemq (Qtab_bar_lines, frame_inhibit_implied_resize)))))
-    f->tab_bar_redisplayed = f->tab_bar_resized = false;
-
-  adjust_frame_size (f, -1, -1,
-		     ((!f->tab_bar_resized
-		       && (NILP (fullscreen =
-				 get_frame_param (f, Qfullscreen))
-			   || EQ (fullscreen, Qfullwidth))) ? 1
-		      : (old_height == 0 || height == 0) ? 2
-		      : 4),
-		     false, Qtab_bar_lines);
-
-  f->tab_bar_resized = f->tab_bar_redisplayed;
+  if (!f->tab_bar_resized)
+    {
+      /* As long as tab_bar_resized is false, effectively try to change
+	 F's native height.  */
+      if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+	adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+			   1, false, Qtab_bar_lines);
+      else
+	adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
+
+      f->tab_bar_resized = f->tab_bar_redisplayed;
+    }
+  else
+    /* Any other change may leave the native size of F alone.  */
+    adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
 
   /* adjust_frame_size might not have done anything, garbage frame
      here.  */
@@ -1743,24 +1732,15 @@ x_change_tool_bar_height (struct frame *f, int height)
   int unit = FRAME_LINE_HEIGHT (f);
   int old_height = FRAME_TOOL_BAR_HEIGHT (f);
   int lines = (height + unit - 1) / unit;
-  Lisp_Object fullscreen;
+  Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
 
   /* Make sure we redisplay all windows in this frame.  */
   fset_redisplay (f);
 
-  /* Recalculate tool bar and frame text sizes.  */
   FRAME_TOOL_BAR_HEIGHT (f) = height;
   FRAME_TOOL_BAR_LINES (f) = lines;
-  /* Store the `tool-bar-lines' and `height' frame parameters.  */
   store_frame_param (f, Qtool_bar_lines, make_fixnum (lines));
-  store_frame_param (f, Qheight, make_fixnum (FRAME_LINES (f)));
-
-  /* We also have to make sure that the internal border at the top of
-     the frame, below the menu bar or tool bar, is redrawn when the
-     tool bar disappears.  This is so because the internal border is
-     below the tool bar if one is displayed, but is below the menu bar
-     if there isn't a tool bar.  The tool bar draws into the area
-     below the menu bar.  */
+
   if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
     {
       clear_frame (f);
@@ -1770,25 +1750,21 @@ x_change_tool_bar_height (struct frame *f, int height)
   if ((height < old_height) && WINDOWP (f->tool_bar_window))
     clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
 
-  /* Recalculate toolbar height.  */
-  f->n_tool_bar_rows = 0;
-  if (old_height == 0
-      && (!f->after_make_frame
-	  || NILP (frame_inhibit_implied_resize)
-	  || (CONSP (frame_inhibit_implied_resize)
-	      && NILP (Fmemq (Qtool_bar_lines, frame_inhibit_implied_resize)))))
-    f->tool_bar_redisplayed = f->tool_bar_resized = false;
-
-  adjust_frame_size (f, -1, -1,
-		     ((!f->tool_bar_resized
-		       && (NILP (fullscreen =
-				 get_frame_param (f, Qfullscreen))
-			   || EQ (fullscreen, Qfullwidth))) ? 1
-		      : (old_height == 0 || height == 0) ? 2
-		      : 4),
-		     false, Qtool_bar_lines);
-
-  f->tool_bar_resized = f->tool_bar_redisplayed;
+  if (!f->tool_bar_resized)
+    {
+      /* As long as tool_bar_resized is false, effectively try to change
+	 F's native height.  */
+      if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
+	adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+			   1, false, Qtool_bar_lines);
+      else
+	adjust_frame_size (f, -1, -1, 4, false, Qtool_bar_lines);
+
+      f->tool_bar_resized =  f->tool_bar_redisplayed;
+    }
+  else
+    /* Any other change may leave the native size of F alone.  */
+    adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_lines);
 
   /* adjust_frame_size might not have done anything, garbage frame
      here.  */
@@ -3687,7 +3663,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   struct x_display_info *dpyinfo = NULL;
   Lisp_Object parent, parent_frame;
   struct kboard *kb;
-  int x_width = 0, x_height = 0;
 
   parms = Fcopy_alist (parms);
 
@@ -3999,18 +3974,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
      init_iterator with a null face cache, which should not happen.  */
   init_frame_faces (f);
 
-  /* We have to call adjust_frame_size here since otherwise
-     x_set_tool_bar_lines will already work with the character sizes
-     installed by init_frame_faces while the frame's pixel size is still
-     calculated from a character size of 1 and we subsequently hit the
-     (height >= 0) assertion in window_box_height.
-
-     The non-pixelwise code apparently worked around this because it
-     had one frame line vs one toolbar line which left us with a zero
-     root window height which was obviously wrong as well ...
-
-     Also process `min-width' and `min-height' parameters right here
-     because `frame-windows-min-size' needs them.  */
   tem = gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
                              RES_TYPE_NUMBER);
   if (FIXNUMP (tem))
@@ -4019,6 +3982,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
                              RES_TYPE_NUMBER);
   if (FIXNUMP (tem))
     store_frame_param (f, Qmin_height, tem);
+
   adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
 		     FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
 		     Qx_create_frame_1);
@@ -4055,8 +4019,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
                          RES_TYPE_BOOLEAN);
 
   /* Compute the size of the X window.  */
-  window_prompting = gui_figure_window_size (f, parms, true, true,
-                                             &x_width, &x_height);
+  window_prompting = gui_figure_window_size (f, parms, true, true);
 
   tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
                              RES_TYPE_BOOLEAN);
@@ -4140,11 +4103,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   /* Consider frame official, now.  */
   f->can_set_window_size = true;
 
-  if (x_width > 0)
-    SET_FRAME_WIDTH (f, x_width);
-  if (x_height > 0)
-    SET_FRAME_HEIGHT (f, x_height);
-
   /* Tell the server what size and position, etc, we want, and how
      badly we want them.  This should be done after we have the menu
      bar so that its size can be taken into account.  */
@@ -6291,10 +6249,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
   struct frame *f;
   Lisp_Object frame;
   Lisp_Object name;
-  int width, height;
   ptrdiff_t count = SPECPDL_INDEX ();
   bool face_change_before = face_change;
-  int x_width = 0, x_height = 0;
 
   if (!dpyinfo->terminal->name)
     error ("Terminal is not live, can't create new frames on it");
@@ -6418,7 +6374,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
   gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
                          "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
 
-  /* This defaults to 2 in order to match xterm.  We recognize either
+  /* This defaults to 1 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
      it).  */
   if (NILP (Fassq (Qinternal_border_width, parms)))
@@ -6466,7 +6422,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
                          "inhibitDoubleBuffering", "InhibitDoubleBuffering",
                          RES_TYPE_BOOLEAN);
 
-  gui_figure_window_size (f, parms, false, false, &x_width, &x_height);
+  gui_figure_window_size (f, parms, false, false);
 
   {
     XSetWindowAttributes attrs;
@@ -6518,15 +6474,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
   gui_default_parameter (f, parms, Qalpha, Qnil,
                          "alpha", "Alpha", RES_TYPE_NUMBER);
 
-  /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
-     Change will not be effected unless different from the current
-     FRAME_LINES (f).  */
-  width = FRAME_COLS (f);
-  height = FRAME_LINES (f);
-  SET_FRAME_COLS (f, 0);
-  SET_FRAME_LINES (f, 0);
-  change_frame_size (f, width, height, true, false, false, false);
-
   /* Add `tooltip' frame parameter's default value. */
   if (NILP (Fframe_parameter (frame, Qtooltip)))
     {
@@ -6588,6 +6535,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
      visible won't work.  */
   Vframe_list = Fcons (frame, Vframe_list);
   f->can_set_window_size = true;
+  adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+		     0, true, Qtip_frame);
 
   /* Setting attributes of faces of the tooltip frame from resources
      and similar will set face_change, which leads to the clearing of
diff --git a/src/xmenu.c b/src/xmenu.c
index a83fffbf1c..a6762236bc 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -641,7 +641,7 @@ update_frame_menubar (struct frame *f)
   lw_refigure_widget (x->column_widget, True);
 
   /* Force the pane widget to resize itself.  */
-  adjust_frame_size (f, -1, -1, 2, false, Qupdate_frame_menubar);
+  adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
   unblock_input ();
 #endif /* USE_GTK */
 }
@@ -1044,6 +1044,7 @@ free_frame_menubar (struct frame *f)
   /* Motif automatically shrinks the frame in lw_destroy_all_widgets.
      If we want to preserve the old height, calculate it now so we can
      restore it below.  */
+  int old_width = FRAME_TEXT_WIDTH (f);
   int old_height = FRAME_TEXT_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
 #endif
 
@@ -1077,26 +1078,43 @@ free_frame_menubar (struct frame *f)
       lw_destroy_all_widgets ((LWLIB_ID) f->output_data.x->id);
       f->output_data.x->menubar_widget = NULL;
 
+      /* When double-buffering is enabled and the frame shall not be
+	 resized either because resizing is inhibited or the frame is
+	 fullheight, some (usually harmless) display artifacts like a
+	 doubled mode line may show up.  Sometimes the configuration
+	 gets messed up in a more serious fashion though and you may
+	 have to resize the frame to get it back in a normal state.  */
       if (f->output_data.x->widget)
 	{
 #ifdef USE_MOTIF
 	  XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL);
 	  if (x1 == 0 && y1 == 0)
 	    XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL);
-	  if (frame_inhibit_resize (f, false, Qmenu_bar_lines))
-	    adjust_frame_size (f, -1, old_height, 1, false, Qfree_frame_menubar_1);
+	  /* When resizing is inhibited and a normal Motif frame is not
+	     fullheight, we have to explicitly request its old sizes
+	     here since otherwise turning off the menu bar will shrink
+	     the frame but turning them on again will not resize it
+	     back.  For a fullheight frame we let the window manager
+	     deal with this problem.  */
+	  if (frame_inhibit_resize (f, false, Qmenu_bar_lines)
+	      && !EQ (get_frame_param (f, Qfullscreen), Qfullheight))
+	    adjust_frame_size (f, old_width, old_height, 1, false,
+			       Qmenu_bar_lines);
 	  else
-	    adjust_frame_size (f, -1, -1, 2, false, Qfree_frame_menubar_1);
+	    adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
 #else
-	  adjust_frame_size (f, -1, -1, 2, false, Qfree_frame_menubar_1);
+	  adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
 #endif /* USE_MOTIF */
 	}
       else
 	{
 #ifdef USE_MOTIF
 	  if (WINDOWP (FRAME_ROOT_WINDOW (f))
-	      && frame_inhibit_resize (f, false, Qmenu_bar_lines))
-	    adjust_frame_size (f, -1, old_height, 1, false, Qfree_frame_menubar_2);
+	      /* See comment above.  */
+	      && frame_inhibit_resize (f, false, Qmenu_bar_lines)
+	      && !EQ (get_frame_param (f, Qfullscreen), Qfullheight))
+	    adjust_frame_size (f, old_width, old_height, 1, false,
+			       Qmenu_bar_lines);
 #endif
 	}
 
diff --git a/src/xterm.c b/src/xterm.c
index 744b80c68a..220d611b78 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -7833,10 +7833,6 @@ x_net_wm_state (struct frame *f, Window window)
       break;
     }
 
-  frame_size_history_add
-    (f, Qx_net_wm_state, 0, 0,
-     list2 (get_frame_param (f, Qfullscreen), lval));
-
   store_frame_param (f, Qfullscreen, lval);
 /**   store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/
 }
@@ -8167,19 +8163,29 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state)
 	{
           bool not_hidden = x_handle_net_wm_state (f, &event->xproperty);
+
 	  if (not_hidden && FRAME_ICONIFIED_P (f))
 	    {
+	      if (CONSP (frame_size_history))
+		frame_size_history_plain
+		  (f, build_string ("PropertyNotify, not hidden & iconified"));
+
 	      /* Gnome shell does not iconify us when C-z is pressed.
 		 It hides the frame.  So if our state says we aren't
 		 hidden anymore, treat it as deiconified.  */
 	      SET_FRAME_VISIBLE (f, 1);
 	      SET_FRAME_ICONIFIED (f, false);
+
 	      f->output_data.x->has_been_visible = true;
 	      inev.ie.kind = DEICONIFY_EVENT;
 	      XSETFRAME (inev.ie.frame_or_window, f);
 	    }
-	  else if (! not_hidden && ! FRAME_ICONIFIED_P (f))
+	  else if (!not_hidden && !FRAME_ICONIFIED_P (f))
 	    {
+	      if (CONSP (frame_size_history))
+		frame_size_history_plain
+		  (f, build_string ("PropertyNotify, hidden & not iconified"));
+
 	      SET_FRAME_VISIBLE (f, 0);
 	      SET_FRAME_ICONIFIED (f, true);
 	      inev.ie.kind = ICONIFY_EVENT;
@@ -8357,10 +8363,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              and that way, we know the window is not iconified now.  */
           if (visible || FRAME_ICONIFIED_P (f))
             {
+	      if (CONSP (frame_size_history))
+		frame_size_history_plain
+		  (f, build_string ("UnmapNotify, visible | iconified"));
+
               SET_FRAME_ICONIFIED (f, true);
-              inev.ie.kind = ICONIFY_EVENT;
+	      inev.ie.kind = ICONIFY_EVENT;
               XSETFRAME (inev.ie.frame_or_window, f);
             }
+	  else if (CONSP (frame_size_history))
+	    frame_size_history_plain
+	      (f, build_string ("UnmapNotify, not visible & not iconified"));
         }
       goto OTHER;
 
@@ -8372,8 +8385,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       if (f)
         {
 	  bool iconified = FRAME_ICONIFIED_P (f);
-
-          /* Check if fullscreen was specified before we where mapped the
+	  int value;
+	  bool sticky;
+          bool not_hidden = x_get_current_wm_state (f, event->xmap.window, &value, &sticky);
+
+	  if (CONSP (frame_size_history))
+	    frame_size_history_extra
+	      (f,
+	       iconified
+	       ? (not_hidden
+		  ? build_string ("MapNotify, not hidden & iconified")
+		  : build_string ("MapNotify, hidden & iconified"))
+	       : (not_hidden
+		  ? build_string ("MapNotify, not hidden & not iconified")
+		  : build_string ("MapNotify, hidden & not iconified")),
+	       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+	       -1, -1, f->new_width, f->new_height);
+
+	  /* Check if fullscreen was specified before we where mapped the
              first time, i.e. from the command line.  */
           if (!f->output_data.x->has_been_visible)
 	    {
@@ -8974,7 +9003,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 	      || !(configureEvent.xconfigure.width <= 1
 		   && configureEvent.xconfigure.height <= 1)))
         {
-          block_input ();
+
+	  if (CONSP (frame_size_history))
+	    frame_size_history_extra
+	      (f, build_string ("ConfigureNotify"),
+	       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+	       configureEvent.xconfigure.width,
+	       configureEvent.xconfigure.height,
+	       f->new_width, f->new_height);
+
+	  block_input ();
           if (FRAME_X_DOUBLE_BUFFERED_P (f))
             font_drop_xrender_surfaces (f);
           unblock_input ();
@@ -9015,24 +9053,28 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
 #ifndef USE_X_TOOLKIT
 #ifndef USE_GTK
-          int width =
-	    FRAME_PIXEL_TO_TEXT_WIDTH (f, configureEvent.xconfigure.width);
-          int height =
-	    FRAME_PIXEL_TO_TEXT_HEIGHT (f, configureEvent.xconfigure.height);
+          int width = configureEvent.xconfigure.width;
+          int height = configureEvent.xconfigure.height;
+
+	  if (CONSP (frame_size_history))
+	    frame_size_history_extra
+	      (f, build_string ("ConfigureNotify"),
+	       FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
+	       width, height, f->new_width, f->new_height);
 
-          /* In the toolkit version, change_frame_size
+	  /* In the toolkit version, change_frame_size
              is called by the code that handles resizing
              of the EmacsFrame widget.  */
 
           /* Even if the number of character rows and columns has
              not changed, the font size may have changed, so we need
              to check the pixel dimensions as well.  */
-          if (width != FRAME_TEXT_WIDTH (f)
-              || height != FRAME_TEXT_HEIGHT (f)
-              || configureEvent.xconfigure.width != FRAME_PIXEL_WIDTH (f)
-              || configureEvent.xconfigure.height != FRAME_PIXEL_HEIGHT (f))
+          if (width != FRAME_PIXEL_WIDTH (f)
+              || height != FRAME_PIXEL_HEIGHT (f)
+	      || (delayed_size_change
+		  && (width != f->new_width || height != f->new_height)))
             {
-              change_frame_size (f, width, height, false, true, false, true);
+              change_frame_size (f, width, height, false, true, false);
               x_clear_under_internal_border (f);
               SET_FRAME_GARBAGED (f);
               cancel_mouse_face (f);
@@ -10217,11 +10259,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 {
   struct font *font = XFONT_OBJECT (font_object);
   int unit, font_ascent, font_descent;
-#ifndef USE_X_TOOLKIT
-  int old_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
-  int old_tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
-  Lisp_Object fullscreen;
-#endif
 
   if (fontset < 0)
     fontset = fontset_from_font (font_object);
@@ -10239,8 +10276,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 
 #ifndef USE_X_TOOLKIT
   FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
-  FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 #endif
+  /* We could use a more elaborate calculation here.  */
+  FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 
   /* Compute character columns occupied by scrollbar.
 
@@ -10253,34 +10291,14 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
   else
     FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
 
-  if (FRAME_X_WINDOW (f) != 0)
-    {
-      /* Don't change the size of a tip frame; there's no point in
-	 doing it because it's done in Fx_show_tip, and it leads to
-	 problems because the tip frame has no widget.  */
-      if (!FRAME_TOOLTIP_P (f))
-	{
-	  adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-			     FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
-			     false, Qfont);
-#ifndef USE_X_TOOLKIT
-	  if ((FRAME_MENU_BAR_HEIGHT (f) != old_menu_bar_height
-	       || FRAME_TAB_BAR_HEIGHT (f) != old_tab_bar_height)
-	      && !f->after_make_frame
-	      && (EQ (frame_inhibit_implied_resize, Qt)
-		  || (CONSP (frame_inhibit_implied_resize)
-		      && NILP (Fmemq (Qfont, frame_inhibit_implied_resize))))
-	      && (NILP (fullscreen = get_frame_param (f, Qfullscreen))
-		  || EQ (fullscreen, Qfullwidth)))
-	    /* If the menu/tab bar height changes, try to keep text height
-	       constant.  */
-	    adjust_frame_size
-	      (f, -1, FRAME_TEXT_HEIGHT (f) + FRAME_MENU_BAR_HEIGHT (f)
-	       + FRAME_TAB_BAR_HEIGHT (f)
-	       - old_menu_bar_height - old_tab_bar_height, 1, false, Qfont);
-#endif /* USE_X_TOOLKIT  */
-	}
-    }
+
+  /* Don't change the size of a tip frame; there's no point in doing it
+     because it's done in Fx_show_tip, and it leads to problems because
+     the tip frame has no widget.  */
+  if (FRAME_X_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
+    adjust_frame_size
+      (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
 
 #ifdef HAVE_X_I18N
   if (FRAME_XIC (f)
@@ -11164,10 +11182,6 @@ x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
       break;
     }
 
-  frame_size_history_add
-    (f, Qx_handle_net_wm_state, 0, 0,
-     list2 (get_frame_param (f, Qfullscreen), lval));
-
   store_frame_param (f, Qfullscreen, lval);
   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 
@@ -11222,9 +11236,6 @@ x_check_fullscreen (struct frame *f)
 	  emacs_abort ();
         }
 
-      frame_size_history_add
-	(f, Qx_check_fullscreen, width, height, Qnil);
-
       x_wm_set_size_hint (f, 0, false);
 
       XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
@@ -11234,8 +11245,7 @@ x_check_fullscreen (struct frame *f)
 	x_wait_for_event (f, ConfigureNotify);
       else
 	{
-	  change_frame_size (f, width, height - FRAME_MENUBAR_HEIGHT (f),
-			     false, true, false, true);
+	  change_frame_size (f, width, height, false, true, false);
 	  x_sync (f);
 	}
     }
@@ -11389,57 +11399,12 @@ x_wait_for_event (struct frame *f, int eventtype)
 x_set_window_size_1 (struct frame *f, bool change_gravity,
 		     int width, int height)
 {
-  int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
-  int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
-  int old_width = FRAME_PIXEL_WIDTH (f);
-  int old_height = FRAME_PIXEL_HEIGHT (f);
-  Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
-
   if (change_gravity)
     f->win_gravity = NorthWestGravity;
   x_wm_set_size_hint (f, 0, false);
 
-  /* When the frame is fullheight and we only want to change the width
-     or it is fullwidth and we only want to change the height we should
-     be able to preserve the fullscreen property.  However, due to the
-     fact that we have to send a resize request anyway, the window
-     manager will abolish it.  At least the respective size should
-     remain unchanged but giving the frame back its normal size will
-     be broken ... */
-  if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
-    {
-      frame_size_history_add
-	(f, Qx_set_window_size_1, width, height,
-	 list2i (old_height, pixelheight + FRAME_MENUBAR_HEIGHT (f)));
-
-      XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
-		     old_width, pixelheight + FRAME_MENUBAR_HEIGHT (f));
-    }
-  else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
-    {
-      frame_size_history_add
-	(f, Qx_set_window_size_2, width, height,
-	 list2i (old_width, pixelwidth));
-
-      XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
-		     pixelwidth, old_height);
-    }
-
-  else
-    {
-      frame_size_history_add
-	(f, Qx_set_window_size_3, width, height,
-	 list3i (pixelwidth + FRAME_TOOLBAR_WIDTH (f),
-		 (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
-		  + FRAME_MENUBAR_HEIGHT (f)),
-		 FRAME_MENUBAR_HEIGHT (f)));
-
-      XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
-		     pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f));
-      fullscreen = Qnil;
-    }
-
-
+  XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+		 width, height + FRAME_MENUBAR_HEIGHT (f));
 
   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
      receive in the ConfigureNotify event; if we get what we asked
@@ -11468,66 +11433,42 @@ x_set_window_size_1 (struct frame *f, bool change_gravity,
     {
       x_wait_for_event (f, ConfigureNotify);
 
-      if (!NILP (fullscreen))
-	/* Try to restore fullscreen state.  */
-	{
-	  store_frame_param (f, Qfullscreen, fullscreen);
-	  gui_set_fullscreen (f, fullscreen, fullscreen);
-	}
+      if (CONSP (frame_size_history))
+	frame_size_history_extra
+	  (f, build_string ("x_set_window_size_1, visible"),
+	   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
+	   f->new_width, f->new_height);
     }
   else
     {
-      change_frame_size (f, width, height, false, true, false, true);
+      if (CONSP (frame_size_history))
+	frame_size_history_extra
+	  (f, build_string ("x_set_window_size_1, invisible"),
+	   FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
+	   f->new_width, f->new_height);
+
+      /* Call adjust_frame_size right away as with GTK.  It might be
+	 tempting to clear out f->new_width and f->new_height here.  */
+      adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
+			 FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
+			 5, 0, Qx_set_window_size_1);
+
       x_sync (f);
     }
 }
 
 
-/* Call this to change the size of frame F's x-window.
-   If CHANGE_GRAVITY, change to top-left-corner window gravity
-   for this size change and subsequent size changes.
-   Otherwise we leave the window gravity unchanged.  */
+/* Change the size of frame F's X window to WIDTH and HEIGHT pixels.  If
+   CHANGE_GRAVITY, change to top-left-corner window gravity for this
+   size change and subsequent size changes.  Otherwise we leave the
+   window gravity unchanged.  */
 
 void
 x_set_window_size (struct frame *f, bool change_gravity,
-		   int width, int height, bool pixelwise)
+		   int width, int height)
 {
   block_input ();
 
-  /* The following breaks our calculations.  If it's really needed,
-     think of something else.  */
-#if false
-  if (!FRAME_TOOLTIP_P (f))
-    {
-      int text_width, text_height;
-
-      /* When the frame is maximized/fullscreen or running under for
-         example Xmonad, x_set_window_size_1 will be a no-op.
-         In that case, the right thing to do is extend rows/width to
-         the current frame size.  We do that first if x_set_window_size_1
-         turns out to not be a no-op (there is no way to know).
-         The size will be adjusted again if the frame gets a
-         ConfigureNotify event as a result of x_set_window_size.  */
-      int pixelh = FRAME_PIXEL_HEIGHT (f);
-#ifdef USE_X_TOOLKIT
-      /* The menu bar is not part of text lines.  The tool bar
-         is however.  */
-      pixelh -= FRAME_MENUBAR_HEIGHT (f);
-#endif
-      text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, FRAME_PIXEL_WIDTH (f));
-      text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelh);
-
-      change_frame_size (f, text_width, text_height, false, true, false, true);
-    }
-#endif
-
-  /* Pixelize width and height, if necessary.  */
-  if (! pixelwise)
-    {
-      width = width * FRAME_COLUMN_WIDTH (f);
-      height = height * FRAME_LINE_HEIGHT (f);
-    }
-
 #ifdef USE_GTK
   if (FRAME_GTK_WIDGET (f))
     xg_frame_set_char_size (f, width, height);
@@ -11880,6 +11821,11 @@ x_make_frame_visible (struct frame *f)
     poll_for_input_1 ();
     poll_suppress_count = old_poll_suppress_count;
 #endif
+
+    if (CONSP (frame_size_history))
+      frame_size_history_plain
+	(f, build_string ("x_make_frame_visible"));
+
     if (! FRAME_VISIBLE_P (f))
       x_wait_for_event (f, MapNotify);
   }
@@ -11937,6 +11883,10 @@ x_make_frame_invisible (struct frame *f)
   SET_FRAME_VISIBLE (f, 0);
   SET_FRAME_ICONIFIED (f, false);
 
+  if (CONSP (frame_size_history))
+    frame_size_history_plain
+      (f, build_string ("x_make_frame_invisible"));
+
   unblock_input ();
 }
 
diff --git a/src/xterm.h b/src/xterm.h
index ebc42b7dd5..de6ea50385 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1079,7 +1079,7 @@ #define SELECTION_EVENT_TIME(eventp)	\
 extern void x_uncatch_errors (void);
 extern void x_uncatch_errors_after_check (void);
 extern void x_clear_errors (Display *);
-extern void x_set_window_size (struct frame *f, bool, int, int, bool);
+extern void x_set_window_size (struct frame *f, bool, int, int);
 extern void x_make_frame_visible (struct frame *f);
 extern void x_make_frame_invisible (struct frame *f);
 extern void x_iconify_frame (struct frame *f);

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-04-25 17:11 Proposing changes to adjust_frame_size martin rudalics
@ 2021-04-27  8:22 ` martin rudalics
  2021-04-27 14:16   ` Yuuki Harano
  2021-05-01 18:59 ` Alan Third
  1 sibling, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-04-27  8:22 UTC (permalink / raw)
  To: emacs-devel; +Cc: Alan Third, Yuuki Harano

 > Unless there are objections, I intend to apply the attached changes in
 > the next days.  Their purpose is to restrain the handling of the text
 > area size of a frame to the function adjust_frame_size and have the
 > various front/backends setting frame sizes or receiving notifications
 > about them work with native frame sizes only.  This has the advantage
 > that storing the history of frame size changes and consequently tracking
 > bugs in the frame sizing code become much simpler.
 >
 > The patch should fix Bug#46827 and I intend to add further bug fixes in
 > the following days.  Some of these fixes are controversial and I'd like
 > to push them separately in order to make bisecting easier.  Other than
 > that, there should be no user noticeable changes, so if you observe any
 > strange frame sizing behavior, please tell me.
 >
 > I've tested the patch with xfwm4, gnome shell, kde plasma and Windows XP
 > but have given it only light testing with GNUstep.  Alan, if you see
 > anything fishy with the NS build, please tell me.  Yuuki, if you see any
 > problems with the pgtk build, please tell me too so we can resolve them
 > without causing greater conflicts.

Done.  If frames resize strangely now, please complain immediately.

Thanks, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-04-27  8:22 ` martin rudalics
@ 2021-04-27 14:16   ` Yuuki Harano
  2021-05-02  8:46     ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-04-27 14:16 UTC (permalink / raw)
  To: rudalics; +Cc: alan, emacs-devel


On Tue, 27 Apr 2021 10:22:47 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
> Done.  If frames resize strangely now, please complain immediately.

Thank you for cc'ing me.
I merged it into feature/pgtk, and it is working.

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-04-25 17:11 Proposing changes to adjust_frame_size martin rudalics
  2021-04-27  8:22 ` martin rudalics
@ 2021-05-01 18:59 ` Alan Third
  2021-05-02  7:38   ` martin rudalics
  1 sibling, 1 reply; 65+ messages in thread
From: Alan Third @ 2021-05-01 18:59 UTC (permalink / raw)
  To: martin rudalics; +Cc: Yuuki Harano, emacs-devel

On Sun, Apr 25, 2021 at 07:11:47PM +0200, martin rudalics wrote:
> Alan, if you see anything fishy with the NS build, please tell me.

Sorry for the delay in responding. I don't see any problems.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-01 18:59 ` Alan Third
@ 2021-05-02  7:38   ` martin rudalics
  0 siblings, 0 replies; 65+ messages in thread
From: martin rudalics @ 2021-05-02  7:38 UTC (permalink / raw)
  To: Alan Third, emacs-devel, Yuuki Harano

 > Sorry for the delay in responding. I don't see any problems.

Thanks for checking.  And many thanks for fixing the tool bar on
GNUstep.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-04-27 14:16   ` Yuuki Harano
@ 2021-05-02  8:46     ` martin rudalics
  2021-05-02 11:21       ` Alan Third
  2021-05-05  8:51       ` martin rudalics
  0 siblings, 2 replies; 65+ messages in thread
From: martin rudalics @ 2021-05-02  8:46 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: alan, emacs-devel

 > Thank you for cc'ing me.
 > I merged it into feature/pgtk, and it is working.

Fine.  I now checked in the first of a few minor changes, each intended
to fix a bug reported years ago.  Please have a look.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-02  8:46     ` martin rudalics
@ 2021-05-02 11:21       ` Alan Third
  2021-05-02 16:17         ` martin rudalics
  2021-05-05  8:51       ` martin rudalics
  1 sibling, 1 reply; 65+ messages in thread
From: Alan Third @ 2021-05-02 11:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: Yuuki Harano, emacs-devel

On Sun, May 02, 2021 at 10:46:57AM +0200, martin rudalics wrote:
> > Thank you for cc'ing me.
> > I merged it into feature/pgtk, and it is working.
> 
> Fine.  I now checked in the first of a few minor changes, each intended
> to fix a bug reported years ago.  Please have a look.

All looks good here with NS.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-02 11:21       ` Alan Third
@ 2021-05-02 16:17         ` martin rudalics
  0 siblings, 0 replies; 65+ messages in thread
From: martin rudalics @ 2021-05-02 16:17 UTC (permalink / raw)
  To: Alan Third, Yuuki Harano, emacs-devel

 > All looks good here with NS.

I had to amend it slightly.  Please see also the patch I proposed for
Bug#48157 and Bug#48162.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-02  8:46     ` martin rudalics
  2021-05-02 11:21       ` Alan Third
@ 2021-05-05  8:51       ` martin rudalics
  2021-05-05 10:47         ` Yuuki Harano
  1 sibling, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-05  8:51 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: alan, emacs-devel

I now checked in two further GTK3 related changes.  Yuuki please have a
look.  It's mainly about how to to change frame sizes while a frame is
invisible or iconified and get them applied when the frame is made
normally visible.  I'd be interested in how these behave(d) on the pgtk
build (maybe you can also have a look at Bug#24526 for this purpose).

These frame changes will be the last for the moment - a major rewrite of
the size hints code will follow as soon as I have implemented some more
important window related changes.

Thanks, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05  8:51       ` martin rudalics
@ 2021-05-05 10:47         ` Yuuki Harano
  2021-05-05 11:24           ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-05 10:47 UTC (permalink / raw)
  To: rudalics; +Cc: alan, emacs-devel


On Wed, 5 May 2021 10:51:50 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
> I now checked in two further GTK3 related changes.  Yuuki please
> have a
> look.  It's mainly about how to to change frame sizes while a frame
> is
> invisible or iconified and get them applied when the frame is made
> normally visible.  I'd be interested in how these behave(d) on the
> pgtk
> build (maybe you can also have a look at Bug#24526 for this
> purpose).

Pgtk doesn't use:
- X Property event and functions
- Expose event
- UnmapNotify event

So I didn't port changes of xterm.c in 483c5e9 into pgtkterm.c.

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 10:47         ` Yuuki Harano
@ 2021-05-05 11:24           ` martin rudalics
  2021-05-05 14:07             ` Yuuki Harano
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-05 11:24 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: alan, emacs-devel

 > Pgtk doesn't use:
 > - X Property event and functions
 > - Expose event
 > - UnmapNotify event
 >
 > So I didn't port changes of xterm.c in 483c5e9 into pgtkterm.c.

Good.  Is there any way with pgtk to start out with an invisible frame,
size it in some queer way, make it visible and see the sizes applied in
a correct way?

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 11:24           ` martin rudalics
@ 2021-05-05 14:07             ` Yuuki Harano
  2021-05-05 15:01               ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-05 14:07 UTC (permalink / raw)
  To: rudalics; +Cc: alan, emacs-devel


On Wed, 5 May 2021 13:24:39 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
> Good.  Is there any way with pgtk to start out with an invisible
> frame,
> size it in some queer way, make it visible and see the sizes
> applied in
> a correct way?

I don't understand your words..
What is "some queer way"?  Do you mean something like "-geometry"?
What is "a correct way"?  Do you mean something like "xwininfo"?

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 14:07             ` Yuuki Harano
@ 2021-05-05 15:01               ` martin rudalics
  2021-05-05 16:45                 ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-05 15:01 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: alan, emacs-devel

 > I don't understand your words..

Sorry.  I apologize.

 > What is "some queer way"?  Do you mean something like "-geometry"?
 > What is "a correct way"?  Do you mean something like "xwininfo"?

Start Emacs with the iconic switch on like

emacs -Q -iconic --load foo.el

where foo.el contains

(set-frame-height nil 20)
(set-frame-width nil 90)
(set-frame-parameter nil 'toolbar-lines 0)

After that deiconify the frame.  What are the frame's height and width
now - 20 and 90?

Thanks, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 15:01               ` martin rudalics
@ 2021-05-05 16:45                 ` martin rudalics
  2021-05-05 18:54                   ` Tassilo Horn
  2021-05-06 14:41                   ` Yuuki Harano
  0 siblings, 2 replies; 65+ messages in thread
From: martin rudalics @ 2021-05-05 16:45 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: alan, emacs-devel

 > Start Emacs with the iconic switch on like
 >
 > emacs -Q -iconic --load foo.el
 >
 > where foo.el contains
 >
 > (set-frame-height nil 20)
 > (set-frame-width nil 90)
 > (set-frame-parameter nil 'toolbar-lines 0)
 >
 > After that deiconify the frame.  What are the frame's height and width
 > now - 20 and 90?

And after fixing my latest thinko in Fframe_parameters as in commit
e9baa733b8cac00e008cb834abc8712c8c00beed please try with

emacs -Q

in *scratch* evaluate first

(setq frame (make-frame '((width . 60) (height . 20) (tool-bar-lines . 0) (visibility . nil))))

then

(make-frame-visible frame)

and tell me what

(frame-width) and (frame-height) give for that frame.

Thanks again, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 16:45                 ` martin rudalics
@ 2021-05-05 18:54                   ` Tassilo Horn
  2021-05-06  7:44                     ` martin rudalics
  2021-05-06 14:41                   ` Yuuki Harano
  1 sibling, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-05 18:54 UTC (permalink / raw)
  To: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

Hi Martin,

> And after fixing my latest thinko in Fframe_parameters as in commit
> e9baa733b8cac00e008cb834abc8712c8c00beed

Is it possible that this broke some things?  When I do "emacs -Q" I get
a frame with menubar but no toolbar.  Only when I resize the frame the
toolbar appears.  When I turn both of them off using `M-x tool-bar-mode'
and `M-x menu-bar-mode', they also won't vanish before I resize the
frame.

I have to say that I use sway, a tiling window manager, so it might be
that this behavior is not observable with a "normal" WM where windows
may define their own size.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 18:54                   ` Tassilo Horn
@ 2021-05-06  7:44                     ` martin rudalics
  2021-05-06  7:59                       ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-06  7:44 UTC (permalink / raw)
  To: Tassilo Horn, emacs-devel

 >> And after fixing my latest thinko in Fframe_parameters as in commit
 >> e9baa733b8cac00e008cb834abc8712c8c00beed
 >
 > Is it possible that this broke some things?

Do you mean this specific commit or one of my preceding ones?  That
latest one should affect you only if you have some special code in your
init file that uses `frame-parameter', `frame-height' or `frame-width'.

 > When I do "emacs -Q" I get
 > a frame with menubar but no toolbar.

Which build, GTK3?

 > Only when I resize the frame the
 > toolbar appears.  When I turn both of them off using `M-x tool-bar-mode'
 > and `M-x menu-bar-mode', they also won't vanish before I resize the
 > frame.

We can trace these behaviors but please answer the two questions above
first.

 > I have to say that I use sway, a tiling window manager, so it might be
 > that this behavior is not observable with a "normal" WM where windows
 > may define their own size.

By design, my commits should not have changed anything for you.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06  7:44                     ` martin rudalics
@ 2021-05-06  7:59                       ` Tassilo Horn
  2021-05-06  8:39                         ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-06  7:59 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

Hi Martin,

>>> And after fixing my latest thinko in Fframe_parameters as in commit
>>> e9baa733b8cac00e008cb834abc8712c8c00beed
>>
>> Is it possible that this broke some things?
>
> Do you mean this specific commit or one of my preceding ones?

I'm not sure.  It's just that I've noticed when that commit was the HEAD
and not the day before.  I update my checkout every morning CEST, so we
can restrict the issue to at least the commits in, say, 36 hours before
my message.

If you want, I can bisect when I find some time, maybe this evening.

> That latest one should affect you only if you have some special code
> in your init file that uses `frame-parameter', `frame-height' or
> `frame-width'.

I have

(setq default-frame-alist '((width . 90)
                            (height . 50)))

which is basically a relict of the times where I've not used a tiling
WM.

>> When I do "emacs -Q" I get a frame with menubar but no toolbar.
>
> Which build, GTK3?

Yes.

>> Only when I resize the frame the toolbar appears.  When I turn both
>> of them off using `M-x tool-bar-mode' and `M-x menu-bar-mode', they
>> also won't vanish before I resize the frame.
>
> We can trace these behaviors but please answer the two questions above
> first.
>
>> I have to say that I use sway, a tiling window manager, so it might be
>> that this behavior is not observable with a "normal" WM where windows
>> may define their own size.
>
> By design, my commits should not have changed anything for you.

Ok, great.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06  7:59                       ` Tassilo Horn
@ 2021-05-06  8:39                         ` martin rudalics
  2021-05-06  8:49                           ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-06  8:39 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

 >> Do you mean this specific commit or one of my preceding ones?
 >
 > I'm not sure.  It's just that I've noticed when that commit was the HEAD
 > and not the day before.  I update my checkout every morning CEST, so we
 > can restrict the issue to at least the commits in, say, 36 hours before
 > my message.

This would include commit 483c5e953c12a95382bef4a3b6769a680c32fe86 in
addition to e9baa733b8cac00e008cb834abc8712c8c00beed but no other ones.

 > If you want, I can bisect when I find some time, maybe this evening.

Try to revert just these two commits first.

 > I have
 >
 > (setq default-frame-alist '((width . 90)
 >                              (height . 50)))
 >
 > which is basically a relict of the times where I've not used a tiling
 > WM.

Does anything change when you remove this?  I'd doubt it.

 >> By design, my commits should not have changed anything for you.
 >
 > Ok, great.

Not really.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06  8:39                         ` martin rudalics
@ 2021-05-06  8:49                           ` Tassilo Horn
  2021-05-06 12:10                             ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-06  8:49 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> This would include commit 483c5e953c12a95382bef4a3b6769a680c32fe86 in
> addition to e9baa733b8cac00e008cb834abc8712c8c00beed but no other
> ones.
>
>> If you want, I can bisect when I find some time, maybe this evening.
>
> Try to revert just these two commits first.

I did so, and indeed, the issue vanishes.

>> I have
>>
>> (setq default-frame-alist '((width . 90)
>>                              (height . 50)))
>>
>> which is basically a relict of the times where I've not used a tiling
>> WM.
>
> Does anything change when you remove this?  I'd doubt it.

No.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06  8:49                           ` Tassilo Horn
@ 2021-05-06 12:10                             ` martin rudalics
  2021-05-06 12:31                               ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-06 12:10 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

 >> This would include commit 483c5e953c12a95382bef4a3b6769a680c32fe86 in
 >> addition to e9baa733b8cac00e008cb834abc8712c8c00beed but no other
 >> ones.
 >>
 >>> If you want, I can bisect when I find some time, maybe this evening.
 >>
 >> Try to revert just these two commits first.
 >
 > I did so, and indeed, the issue vanishes.

OK.  So I conclude that the problem is due to
483c5e953c12a95382bef4a3b6769a680c32fe86.  So with a now up-to-date
master in xterm.c please remove the two occurrences of

#if defined USE_GTK && defined HAVE_GTK3
	      /* If GTK3 wants to impose some old size here (Bug#24526),
		 tell it that the current size is what we want.  */
	      xg_frame_set_char_size
		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
#endif

and tell me whether the problem persists.

Thanks, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06 12:10                             ` martin rudalics
@ 2021-05-06 12:31                               ` Tassilo Horn
  2021-05-06 14:10                                 ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-06 12:31 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> OK.  So I conclude that the problem is due to
> 483c5e953c12a95382bef4a3b6769a680c32fe86.  So with a now up-to-date
> master in xterm.c please remove the two occurrences of
>
> #if defined USE_GTK && defined HAVE_GTK3
> 	      /* If GTK3 wants to impose some old size here (Bug#24526),
> 		 tell it that the current size is what we want.  */
> 	      xg_frame_set_char_size
> 		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
> #endif
>
> and tell me whether the problem persists.

Nope, then the problem is gone and also toggling the toolbar and menubar
has immediate effect without need for resizing the frame.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06 12:31                               ` Tassilo Horn
@ 2021-05-06 14:10                                 ` martin rudalics
  2021-05-06 14:47                                   ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-06 14:10 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 720 bytes --]

 >> in xterm.c please remove the two occurrences of
 >>
 >> #if defined USE_GTK && defined HAVE_GTK3
 >> 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 >> 		 tell it that the current size is what we want.  */
 >> 	      xg_frame_set_char_size
 >> 		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 >> #endif
 >>
 >> and tell me whether the problem persists.
 >
 > Nope, then the problem is gone and also toggling the toolbar and menubar
 > has immediate effect without need for resizing the frame.

Please tell me whether it's necessary to remove both of these to make
the problem go away.  If removing the second one suffices, please try
the attached patch and tell me whether it helps.

martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: xterm.c.diff --]
[-- Type: text/x-patch; name="xterm.c.diff", Size: 817 bytes --]

diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9a34..b7958f0cd6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8436,7 +8436,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		x_set_z_group (f, Qbelow, Qnil);
 	    }

-	  if (not_hidden)
+          if (not_hidden && iconified)
 	    {
 	      SET_FRAME_VISIBLE (f, 1);
 	      SET_FRAME_ICONIFIED (f, false);
@@ -8447,11 +8447,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 #endif
 	      f->output_data.x->has_been_visible = true;
-	    }

-          if (not_hidden && iconified)
-            {
-              inev.ie.kind = DEICONIFY_EVENT;
+	      inev.ie.kind = DEICONIFY_EVENT;
               XSETFRAME (inev.ie.frame_or_window, f);
             }
         }

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-05 16:45                 ` martin rudalics
  2021-05-05 18:54                   ` Tassilo Horn
@ 2021-05-06 14:41                   ` Yuuki Harano
  2021-05-09  9:32                     ` Yuuki Harano
  1 sibling, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-06 14:41 UTC (permalink / raw)
  To: rudalics; +Cc: alan, emacs-devel


On Wed, 5 May 2021 18:45:16 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
>> Start Emacs with the iconic switch on like
>>
>> emacs -Q -iconic --load foo.el
>>
>> where foo.el contains
>>
>> (set-frame-height nil 20)
>> (set-frame-width nil 90)
>> (set-frame-parameter nil 'toolbar-lines 0)
>>
>> After that deiconify the frame.  What are the frame's height and
>> width
>> now - 20 and 90?

I tested on GNOME(Xorg) before merging master.

(frame-width)
86
(frame-height)
20

> And after fixing my latest thinko in Fframe_parameters as in commit
> e9baa733b8cac00e008cb834abc8712c8c00beed please try with
> 
> emacs -Q
> 
> in *scratch* evaluate first
> 
> (setq frame (make-frame '((width . 60) (height . 20)
> (tool-bar-lines . 0) (visibility . nil))))
> 
> then
> 
> (make-frame-visible frame)
> 
> and tell me what
> 
> (frame-width) and (frame-height) give for that frame.

I tested on GNOME(Xorg) after merging master.

(frame-width frame)
56
(frame-height frame)
20


Note:
I tested on Xorg because pgtk didn't start with iconified state
even if I specify -iconic on Wayland.
Also, make-frame worked but make-frame-visible didn't work. So
I executed frame-width and frame-height on the first frame while
the second was invisible.
I'm going to debug those issues.

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06 14:10                                 ` martin rudalics
@ 2021-05-06 14:47                                   ` Tassilo Horn
  2021-05-07  8:03                                     ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-06 14:47 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1272 bytes --]

martin rudalics <rudalics@gmx.at> writes:

>>> in xterm.c please remove the two occurrences of
>>>
>>> #if defined USE_GTK && defined HAVE_GTK3
>>> 	      /* If GTK3 wants to impose some old size here (Bug#24526),
>>> 		 tell it that the current size is what we want.  */
>>> 	      xg_frame_set_char_size
>>> 		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
>>> #endif
>>>
>>> and tell me whether the problem persists.
>>
>> Nope, then the problem is gone and also toggling the toolbar and
>> menubar has immediate effect without need for resizing the frame.
>
> Please tell me whether it's necessary to remove both of these to make
> the problem go away.  If removing the second one suffices,

It does suffice.

> please try the attached patch and tell me whether it helps.

When I apply the patch to an unmodified xterm.c, emacs -Q has a menubar
but no toolbar, and the complete UI except for the menubar is just black
screen with no text, no modeline, no nothing!  Even resizing or typing
won't make anything appear.  The menubar works, though.  I can expand it
and press entries, and it seems it reacts to that.

When I apply your patch and also remove the second ifdef, that doesn't
change.  Just a menubar with blackness on the rest of the frame.

Screenshot:

[-- Attachment #2: Screenshot-2021-05-06_165751.png --]
[-- Type: image/png, Size: 33839 bytes --]

[-- Attachment #3: Type: text/plain, Size: 14 bytes --]


Bye,
Tassilo

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06 14:47                                   ` Tassilo Horn
@ 2021-05-07  8:03                                     ` martin rudalics
  2021-05-08  7:02                                       ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-07  8:03 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 844 bytes --]

 >> please try the attached patch and tell me whether it helps.
 >
 > When I apply the patch to an unmodified xterm.c, emacs -Q has a menubar
 > but no toolbar, and the complete UI except for the menubar is just black
 > screen with no text, no modeline, no nothing!  Even resizing or typing
 > won't make anything appear.  The menubar works, though.  I can expand it
 > and press entries, and it seems it reacts to that.
 >
 > When I apply your patch and also remove the second ifdef, that doesn't
 > change.  Just a menubar with blackness on the rest of the frame.

Thanks.  That was a misguided attempt that didn't work here either.
Please try the patch I attach now, it at least doesn't break anything
here.  If this still doesn't get us anywhere, I'd like to look into your
frame size history and will tell you how to set that up.

martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: xterm.c.diff --]
[-- Type: text/x-patch; name="xterm.c.diff", Size: 838 bytes --]

diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9a34..153089c1dc 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8438,14 +8438,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,

 	  if (not_hidden)
 	    {
-	      SET_FRAME_VISIBLE (f, 1);
-	      SET_FRAME_ICONIFIED (f, false);
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (!FRAME_VISIBLE_P (f) || iconified)
+		xg_frame_set_char_size
+		  (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 #endif
+	      SET_FRAME_VISIBLE (f, 1);
+	      SET_FRAME_ICONIFIED (f, false);
+
 	      f->output_data.x->has_been_visible = true;
 	    }


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-07  8:03                                     ` martin rudalics
@ 2021-05-08  7:02                                       ` Tassilo Horn
  2021-05-08  7:16                                         ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-08  7:02 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

Hi Martin,

> Thanks.  That was a misguided attempt that didn't work here either.
> Please try the patch I attach now, it at least doesn't break anything
> here.  If this still doesn't get us anywhere, I'd like to look into
> your frame size history and will tell you how to set that up.

With emacs -Q, I still get a frame where only the menubar but not
toolbar is shown.  The latter only appears when minimally resizing the
frame.

But on the plus side, after that initial resizing, now toggling menubar
and toolbar makes them (dis)appear immediately without the need for
another frame resize.

Oh, wait, sorry, that's the very same behavior I also have on the
current master, so no difference with your patch.  And additionally, I
don't actually need to resize the emacs frame.  It's also enough to
switch focus to some other WM window [1] and back again to make the
toolbar appear, and from that time on, toggling menu/toolbar have
immediate effect.

Bye,
Tassilo

[1] Interestingly, I have to switch focus to some other _tiling_ window
and back again.  Switching to a floating window and back to emacs
doesn't help.  Not sure if that information has any value for you.



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-08  7:02                                       ` Tassilo Horn
@ 2021-05-08  7:16                                         ` martin rudalics
  2021-05-08 14:03                                           ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-08  7:16 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

 > Oh, wait, sorry, that's the very same behavior I also have on the
 > current master, so no difference with your patch.  And additionally, I
 > don't actually need to resize the emacs frame.  It's also enough to
 > switch focus to some other WM window [1] and back again to make the
 > toolbar appear, and from that time on, toggling menu/toolbar have
 > immediate effect.

OK.  Meanwhile we also have a bug report for this (Bug#48268).

Can you please do the following: In frame.c change the initial value
of frame_size_history from Qnil to

   frame_size_history = list1 (make_fixnum (100));

recompile and then start emacs -Q.  In the, hopefully useful, frame you
now have evaluate

(frame--size-history)

and post the contents of the buffer "*frame-size-history*" that function
should have produced.

Thank you, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-08  7:16                                         ` martin rudalics
@ 2021-05-08 14:03                                           ` Tassilo Horn
  2021-05-08 15:17                                             ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-08 14:03 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

> Can you please do the following: In frame.c change the initial value
> of frame_size_history from Qnil to
>
>   frame_size_history = list1 (make_fixnum (100));
>
> recompile and then start emacs -Q.  In the, hopefully useful, frame
> you now have evaluate
>
> (frame--size-history)
>
> and post the contents of the buffer "*frame-size-history*" that
> function should have produced.

Here it is.  What I did:

  1. emacs -Q ;; frame with menubar but no toolbar
  2. switch to the emacs frame, the toolbar appeared
  3. evaluate (frame--size-history) in *scratch*

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x5630772204d8>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
xg_frame_set_char_size, visible, PS=672x756, XS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=789x845, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=789x845
change_frame_size_1, delayed, PS=672x756, XS=789x845, DS=672x756
change_frame_size (5), TS=640x756~>757x845, TC=80x36~>94x40, NS=672x756~>789x845, IS=672x756~>789x845, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
ConfigureNotify, PS=789x845, XS=789x804
xg_frame_resized, changed, PS=789x845, XS=789x804
change_frame_size_1, delayed, PS=789x845, XS=789x804
change_frame_size (5), TS=757x845~>757x804, TC=94x40~>94x38, NS=789x845~>789x804, IS=789x845~>789x804, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-08 14:03                                           ` Tassilo Horn
@ 2021-05-08 15:17                                             ` martin rudalics
  2021-05-08 20:32                                               ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-08 15:17 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

 > Here it is.  What I did:
 >
 >    1. emacs -Q ;; frame with menubar but no toolbar
 >    2. switch to the emacs frame, the toolbar appeared
 >    3. evaluate (frame--size-history) in *scratch*

Thank you.

 > Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x5630772204d8>
 > x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
 > gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
 > scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
 > scroll-bar-height (3), MS=80x105
 > menu-bar-lines (2), MS=80x105
 > x_create_frame_2 (0), MS=80x105
 > xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
 > xg_frame_set_char_size (5), MS=16x42 IH IV
 > MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
 > xg_frame_set_char_size, visible, PS=672x756, XS=672x756, DS=672x756

This is the only xg_frame_set_char_size added by my change and it
shouldn't cause any difference.

 > ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
 > xg_frame_resized, unchanged, PS=672x756, XS=672x756
 > ConfigureNotify, PS=672x756, XS=789x845, DS=672x756

But thhis last ConfigureNotify event is not explicable to me, values
like 789x845 are unprecedented so far.  Does your WM deliberately resize
the frame?

 > xg_frame_resized, changed, PS=672x756, XS=789x845
 > change_frame_size_1, delayed, PS=672x756, XS=789x845, DS=672x756
 > change_frame_size (5), TS=640x756~>757x845, TC=80x36~>94x40, NS=672x756~>789x845, IS=672x756~>789x845, MS=16x42 IH IV
 > tool-bar-lines (2), MS=80x105 IH IV
 > ConfigureNotify, PS=789x845, XS=789x804
 > xg_frame_resized, changed, PS=789x845, XS=789x804

Here the native height shrinks from 845 to 804 which should be the tool
bar, now incorporated.

 > change_frame_size_1, delayed, PS=789x845, XS=789x804
 > change_frame_size (5), TS=757x845~>757x804, TC=94x40~>94x38, NS=789x845~>789x804, IS=789x845~>789x804, MS=16x42 IH IV

Can you please do the same but with the two instances that cause the bad
behavior removed?

And can you try to run a build with the bad behavior and a "floating"
frame?

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-08 15:17                                             ` martin rudalics
@ 2021-05-08 20:32                                               ` Tassilo Horn
  2021-05-09  8:41                                                 ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-08 20:32 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel


>> ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
>> xg_frame_resized, unchanged, PS=672x756, XS=672x756
>> ConfigureNotify, PS=672x756, XS=789x845, DS=672x756
>
> But thhis last ConfigureNotify event is not explicable to me, values
> like 789x845 are unprecedented so far.  Does your WM deliberately
> resize the frame?

Yes, pretty much like Emacs splits windows into two balanced halves.  I
have a 1600 pixel wide screen, 3 pixels gap between WM windows, and 3
pixel window borders.  That makes 1579 pixels width for actual WM
windows, divided by two (I've had a terminal at the left and emacs at
the right), makes 789.5 pixels per window.

>> xg_frame_resized, changed, PS=672x756, XS=789x845
>> change_frame_size_1, delayed, PS=672x756, XS=789x845, DS=672x756
>> change_frame_size (5), TS=640x756~>757x845, TC=80x36~>94x40, NS=672x756~>789x845, IS=672x756~>789x845, MS=16x42 IH IV
>> tool-bar-lines (2), MS=80x105 IH IV
>> ConfigureNotify, PS=789x845, XS=789x804
>> xg_frame_resized, changed, PS=789x845, XS=789x804
>
> Here the native height shrinks from 845 to 804 which should be the
> tool bar, now incorporated.
>
>> change_frame_size_1, delayed, PS=789x845, XS=789x804
>> change_frame_size (5), TS=757x845~>757x804, TC=94x40~>94x38, NS=789x845~>789x804, IS=789x845~>789x804, MS=16x42 IH IV
>
> Can you please do the same but with the two instances that cause the
> bad behavior removed?

Sure.

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x555db3e1b6d8>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=789x845, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=789x845
change_frame_size_1, delayed, PS=672x756, XS=789x845, DS=672x756
change_frame_size (5), TS=640x756~>757x845, TC=80x36~>94x40, NS=672x756~>789x845, IS=672x756~>789x845, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
ConfigureNotify, PS=789x845, XS=789x804
xg_frame_resized, changed, PS=789x845, XS=789x804
change_frame_size_1, delayed, PS=789x845, XS=789x804
change_frame_size (5), TS=757x845~>757x804, TC=94x40~>94x38, NS=789x845~>789x804, IS=789x845~>789x804, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

> And can you try to run a build with the bad behavior and a "floating"
> frame?

Yes.

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x5564209990d8>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
xg_frame_set_char_size, visible, PS=672x756, XS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
tool-bar-lines (2), MS=80x105
xg_frame_set_char_size, visible, PS=672x756, XS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
set_window_configuration (4), MS=80x105 IH IV
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-08 20:32                                               ` Tassilo Horn
@ 2021-05-09  8:41                                                 ` martin rudalics
  2021-05-09 10:09                                                   ` Garjola Dindi
                                                                     ` (2 more replies)
  0 siblings, 3 replies; 65+ messages in thread
From: martin rudalics @ 2021-05-09  8:41 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1224 bytes --]

 >> But thhis last ConfigureNotify event is not explicable to me, values
 >> like 789x845 are unprecedented so far.  Does your WM deliberately
 >> resize the frame?
 >
 > Yes, pretty much like Emacs splits windows into two balanced halves.  I
 > have a 1600 pixel wide screen, 3 pixels gap between WM windows, and 3
 > pixel window borders.  That makes 1579 pixels width for actual WM
 > windows, divided by two (I've had a terminal at the left and emacs at
 > the right), makes 789.5 pixels per window.

Elementary.  But why should it react so allergically to our resize
request?  Basically, we have no choice: For some "normal" WMs we have to
tell them the size we want when the frame is mapped because before that
they may ignore our resize requests and after that the frame has already
appeared with its wrong size.  For a tiling WM requesting a size when
the frame is mapped is apparently a mortal sin.

Whatever it be, I attach a patch to address this issue.  It basically
means that on a tiling WM you cannot start with an iconic frame (but
doing so should not make sense anyway).  If people still want to do
that, we probably need a customizable variable where users tell Emacs
what kind of WM they use.

martin





[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Tassilo.diff --]
[-- Type: text/x-patch; name="Tassilo.diff", Size: 2844 bytes --]

diff --git a/src/frame.h b/src/frame.h
index 744b95e1e0..75a0b184c1 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -456,7 +456,11 @@ #define EMACS_FRAME_H
   /* 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;
+  bool_bf new_size_p : 1;
+
+  /* True when frame was invisible before first MapNotify event.  Used
+     in X builds only.  */
+  bool_bf was_invisible : 1;

   /* Bitfield area ends here.  */

diff --git a/src/nsfns.m b/src/nsfns.m
index 1f281f75fd..d14f7b51ea 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1404,6 +1404,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
       else
         {
 	  /* Must have been Qnil.  */
+	  f->was_invisible = true;
         }
     }

diff --git a/src/w32fns.c b/src/w32fns.c
index 66baeaecbd..e5edd62abb 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6107,6 +6107,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,

 	  if (!NILP (visibility))
 	    w32_make_frame_visible (f);
+	  else
+	    f->was_invisible = true;
 	}

       store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xfns.c b/src/xfns.c
index 782e0a483c..82ad15c52c 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4140,6 +4140,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,

 	  if (!NILP (visibility))
 	    x_make_frame_visible (f);
+	  else
+	    f->was_invisible = true;
 	}

       store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9a34..a663a0f184 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8181,8 +8181,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (f->was_invisible)
+		{
+		  xg_frame_set_char_size
+		    (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+		  f->was_invisible = false;
+		}
 #endif
 	      XSETFRAME (inev.ie.frame_or_window, f);
 	    }
@@ -8443,8 +8447,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (f->was_invisible)
+		{
+		  xg_frame_set_char_size
+		    (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+		  f->was_invisible = false;
+		}
 #endif
 	      f->output_data.x->has_been_visible = true;
 	    }

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-06 14:41                   ` Yuuki Harano
@ 2021-05-09  9:32                     ` Yuuki Harano
  2021-05-09 13:47                       ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-09  9:32 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel


On Thu, 06 May 2021 23:41:38 +0900 (JST),
	Yuuki Harano <masm+emacs@masm11.me> wrote:
>> And after fixing my latest thinko in Fframe_parameters as in commit
>> e9baa733b8cac00e008cb834abc8712c8c00beed please try with
>> 
>> emacs -Q
>> 
>> in *scratch* evaluate first
>> 
>> (setq frame (make-frame '((width . 60) (height . 20)
>> (tool-bar-lines . 0) (visibility . nil))))
>> 
>> then
>> 
>> (make-frame-visible frame)
>> 
>> and tell me what
>> 
>> (frame-width) and (frame-height) give for that frame.

I fixed pgtk_make_frame_visible issue, and tested again.

----
(frame-width)
56

(frame-height)
20
----

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09  8:41                                                 ` martin rudalics
@ 2021-05-09 10:09                                                   ` Garjola Dindi
  2021-05-09 10:12                                                   ` Garjola Dindi
  2021-05-09 18:48                                                   ` Tassilo Horn
  2 siblings, 0 replies; 65+ messages in thread
From: Garjola Dindi @ 2021-05-09 10:09 UTC (permalink / raw)
  To: emacs-devel; +Cc: martin rudalics

On Sun 09-May-2021 at 10:41:00 +02, martin rudalics <rudalics@gmx.at>
wrote: 
>>> But thhis last ConfigureNotify event is not explicable to me, values
>>> like 789x845 are unprecedented so far.  Does your WM deliberately
>>> resize the frame?
>>
>> Yes, pretty much like Emacs splits windows into two balanced halves.  I
>> have a 1600 pixel wide screen, 3 pixels gap between WM windows, and 3
>> pixel window borders.  That makes 1579 pixels width for actual WM
>> windows, divided by two (I've had a terminal at the left and emacs at
>> the right), makes 789.5 pixels per window.
>
> Elementary.  But why should it react so allergically to our resize
> request?  Basically, we have no choice: For some "normal" WMs we have to
> tell them the size we want when the frame is mapped because before that
> they may ignore our resize requests and after that the frame has already
> appeared with its wrong size.  For a tiling WM requesting a size when
> the frame is mapped is apparently a mortal sin.
>
> Whatever it be, I attach a patch to address this issue.  It basically
> means that on a tiling WM you cannot start with an iconic frame (but
> doing so should not make sense anyway).  If people still want to do
> that, we probably need a customizable variable where users tell Emacs
> what kind of WM they use.
>
> martin

Hi,

I have been following this issue since commit
30d974bf5c02a1367291fbb6fa17a182bb7974b7 breaks EXWM (the Emacs X WM),
since the first operation is resizing the frame to full screen.

From this last message I understand that the issue is not going to be
addressed, which means that EXWM users can't use Emacs master branch.

Is my interpretation correct?

Thanks.

Garjola

-- 




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09  8:41                                                 ` martin rudalics
  2021-05-09 10:09                                                   ` Garjola Dindi
@ 2021-05-09 10:12                                                   ` Garjola Dindi
  2021-05-09 18:48                                                   ` Tassilo Horn
  2 siblings, 0 replies; 65+ messages in thread
From: Garjola Dindi @ 2021-05-09 10:12 UTC (permalink / raw)
  To: emacs-devel

On Sun 09-May-2021 at 10:41:00 +02, martin rudalics <rudalics@gmx.at>
wrote: 
>>> But thhis last ConfigureNotify event is not explicable to me, values
>>> like 789x845 are unprecedented so far.  Does your WM deliberately
>>> resize the frame?
>>
>> Yes, pretty much like Emacs splits windows into two balanced halves.  I
>> have a 1600 pixel wide screen, 3 pixels gap between WM windows, and 3
>> pixel window borders.  That makes 1579 pixels width for actual WM
>> windows, divided by two (I've had a terminal at the left and emacs at
>> the right), makes 789.5 pixels per window.
>
> Elementary.  But why should it react so allergically to our resize
> request?  Basically, we have no choice: For some "normal" WMs we have to
> tell them the size we want when the frame is mapped because before that
> they may ignore our resize requests and after that the frame has already
> appeared with its wrong size.  For a tiling WM requesting a size when
> the frame is mapped is apparently a mortal sin.
>
> Whatever it be, I attach a patch to address this issue.  It basically
> means that on a tiling WM you cannot start with an iconic frame (but
> doing so should not make sense anyway).  If people still want to do
> that, we probably need a customizable variable where users tell Emacs
> what kind of WM they use.
>
> martin
>
>


Hi,

I have been following this issue since commit
30d974bf5c02a1367291fbb6fa17a182bb7974b7 breaks EXWM (the Emacs X WM),
since the first operation is resizing the frame to full screen.

From this last message I understand that the issue is not going to be
addressed, which means that EXWM users can't use Emacs master branch.

Is my interpretation correct?

Thanks.

Garjola

>
>
>

-- 




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09  9:32                     ` Yuuki Harano
@ 2021-05-09 13:47                       ` martin rudalics
  2021-05-09 15:30                         ` Yuuki Harano
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-09 13:47 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: emacs-devel

 >>> (setq frame (make-frame '((width . 60) (height . 20)
 >>> (tool-bar-lines . 0) (visibility . nil))))
 >>>
 >>> then
 >>>
 >>> (make-frame-visible frame)
 >>>
 >>> and tell me what
 >>>
 >>> (frame-width) and (frame-height) give for that frame.
 >
 > I fixed pgtk_make_frame_visible issue, and tested again.
 >
 > ----
 > (frame-width)
 > 56

Do you have any ideas why this misses 4 character widths ...

 > (frame-height)
 > 20

...  while the usually more complicated height is right?

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09 13:47                       ` martin rudalics
@ 2021-05-09 15:30                         ` Yuuki Harano
  2021-05-10  8:24                           ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-09 15:30 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel


On Sun, 9 May 2021 15:47:55 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
>> (frame-width)
>> 56
> 
> Do you have any ideas why this misses 4 character widths ...
> 
>> (frame-height)
>> 20
> 
> ...  while the usually more complicated height is right?

I tried:

----
(setq frame (make-frame '((width . 60) (height . 20)
			  (tool-bar-lines . 0)
			  (left-fringe . 0) (right-fringe . 0)
			  (vertical-scroll-bars . nil)
			  (visibility . nil))))

(make-frame-visible frame)
----

Then, I got:

----
(frame-width)
60

(frame-height)
20
----

So I think the difference is by fringes and scrollbar.

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09  8:41                                                 ` martin rudalics
  2021-05-09 10:09                                                   ` Garjola Dindi
  2021-05-09 10:12                                                   ` Garjola Dindi
@ 2021-05-09 18:48                                                   ` Tassilo Horn
  2021-05-10  8:25                                                     ` martin rudalics
  2 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-09 18:48 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>> Yes, pretty much like Emacs splits windows into two balanced halves.
>> I have a 1600 pixel wide screen, 3 pixels gap between WM windows, and
>> 3 pixel window borders.  That makes 1579 pixels width for actual WM
>> windows, divided by two (I've had a terminal at the left and emacs at
>> the right), makes 789.5 pixels per window.
>
> Elementary.  But why should it react so allergically to our resize
> request?

Sorry, I'm a layman in WMs.  What does or doesn't it do?

> Basically, we have no choice: For some "normal" WMs we have to tell
> them the size we want when the frame is mapped because before that
> they may ignore our resize requests and after that the frame has
> already appeared with its wrong size.  For a tiling WM requesting a
> size when the frame is mapped is apparently a mortal sin.

If you think that the window manager does something wrong or could at
least so something better, I'm happy to file a sway bug report or ask
the sway devs on IRC.

> Whatever it be, I attach a patch to address this issue.

Hm, I can see no difference with your patch applied.  Still emacs -Q has
just a menubar and the toolbar is not shown until I move focus to
another WM window and back to the emacs frame.

That's the frame size history with your patch applied.

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x55598075aca8>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
xg_frame_set_char_size, visible, PS=672x756, XS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=794x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=794x851
change_frame_size_1, delayed, PS=672x756, XS=794x851, DS=672x756
change_frame_size (5), TS=640x756~>762x851, TC=80x36~>95x40, NS=672x756~>794x851, IS=672x756~>794x851, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
ConfigureNotify, PS=794x851, XS=794x810
xg_frame_resized, changed, PS=794x851, XS=794x810
change_frame_size_1, delayed, PS=794x851, XS=794x810
change_frame_size (5), TS=762x851~>762x810, TC=95x40~>95x38, NS=794x851~>794x810, IS=794x851~>794x810, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

The numbers are slightly different (the frame is a bit larger) because
I've deactivated gaps between windows.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09 15:30                         ` Yuuki Harano
@ 2021-05-10  8:24                           ` martin rudalics
  2021-05-10 13:18                             ` Yuuki Harano
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-10  8:24 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: emacs-devel

 > I tried:
 >
 > ----
 > (setq frame (make-frame '((width . 60) (height . 20)
 > 			  (tool-bar-lines . 0)
 > 			  (left-fringe . 0) (right-fringe . 0)
 > 			  (vertical-scroll-bars . nil)
 > 			  (visibility . nil))))
 >
 > (make-frame-visible frame)
 > ----
 >
 > Then, I got:
 >
 > ----
 > (frame-width)
 > 60
 >
 > (frame-height)
 > 20
 > ----
 >
 > So I think the difference is by fringes and scrollbar.

Hmmm...  did you try the above without the (tool-bar-lines . 0)?

And how does a normal, visible pgtk frame behave when you toggle scroll
bars or fringes on and off?  Here it expands and shrinks.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-09 18:48                                                   ` Tassilo Horn
@ 2021-05-10  8:25                                                     ` martin rudalics
  2021-05-10 12:27                                                       ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-10  8:25 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel

 >> Elementary.  But why should it react so allergically to our resize
 >> request?
 >
 > Sorry, I'm a layman in WMs.  What does or doesn't it do?

If I only knew.  From what I've been able to understand till now, a
tiling WM on X that sends Emacs a MapNotify event when displaying a
frame, doesn't like to be told by Emacs that the size it allots to the
Emacs frame is not the size Emacs actually wants (with emacs -Q that's
the default 80 columns 36 lines frame).

 >> Basically, we have no choice: For some "normal" WMs we have to tell
 >> them the size we want when the frame is mapped because before that
 >> they may ignore our resize requests and after that the frame has
 >> already appeared with its wrong size.  For a tiling WM requesting a
 >> size when the frame is mapped is apparently a mortal sin.
 >
 > If you think that the window manager does something wrong or could at
 > least so something better, I'm happy to file a sway bug report or ask
 > the sway devs on IRC.

That would not help because IIUC XMonad and EXWM do the same.

 >> Whatever it be, I attach a patch to address this issue.
 >
 > Hm, I can see no difference with your patch applied.  Still emacs -Q has
 > just a menubar and the toolbar is not shown until I move focus to
 > another WM window and back to the emacs frame.

Darn.  It could not have worked because `x-create-frame-with-faces'
removes any visibility spec, creates the frame as invisible and re-adds
the visibility spec later on

   (let* (...
	 (visibility-spec (assq 'visibility parameters))
     ...
     (setq frame (x-create-frame `((visibility . nil) . ,params)))
     ...
	  (if (null visibility-spec)
	      (make-frame-visible frame)
	    (modify-frame-parameters frame (list visibility-spec)))

so I could never have caught this anyway and the entire

       if (EQ (visibility, Qicon))
	x_iconify_frame (f);
       else
	{
	  if (EQ (visibility, Qunbound))
	    visibility = Qt;

	  if (!NILP (visibility))
	    x_make_frame_visible (f);
	  else
	    f->was_invisible = true;
	}

       store_frame_param (f, Qvisibility, visibility);

block in Fx_create_frame is for the birds when this is called from
`x-create-frame-with-faces'.  This kludge needs additional surgery in
the Lisp part so please bear with me.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10  8:25                                                     ` martin rudalics
@ 2021-05-10 12:27                                                       ` martin rudalics
  2021-05-10 19:05                                                         ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-10 12:27 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 111 bytes --]

I attach a new patch.  Maybe we're more lucky this time.  Dindi, maybe
you can try it as well.

Thanks, martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: frame-was-visible.diff --]
[-- Type: text/x-patch; name="frame-was-visible.diff", Size: 5446 bytes --]

diff --git a/lisp/faces.el b/lisp/faces.el
index 68bfbbae38..0719816320 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2118,6 +2118,10 @@ x-create-frame-with-faces
 	  (x-handle-reverse-video frame parameters)
 	  (frame-set-background-mode frame t)
 	  (face-set-after-frame-default frame parameters)
+          (set-frame-was-invisible
+           frame
+           (and visibility-spec
+                (memq (cdr visibility-spec) '(nil icon))))
 	  (if (null visibility-spec)
 	      (make-frame-visible frame)
 	    (modify-frame-parameters frame (list visibility-spec)))
diff --git a/src/frame.c b/src/frame.c
index 738bfe9a5c..21c078c23e 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -971,6 +971,7 @@ make_frame (bool mini_p)
   f->no_accept_focus = false;
   f->z_group = z_group_none;
   f->tooltip = false;
+  f->was_invisible = false;
   f->child_frame_border_width = -1;
   f->last_tab_bar_item = -1;
 #ifndef HAVE_EXT_TOOL_BAR
@@ -5907,7 +5908,18 @@ DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p,
   return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
 }
 
+DEFUN ("set-frame-was-invisible", Fset_frame_was_invisible,
+       Sset_frame_was_invisible, 2, 2, 0,
+       doc: /* Set frame's was-invisible flag.
+For internal use only.  */)
+  (Lisp_Object frame, Lisp_Object was_invisible)
+{
+  struct frame *f = decode_live_frame (frame);
+
+  f->was_invisible = NILP (was_invisible) ? false : true;
 
+  return Qnil;
+}
 \f
 /***********************************************************************
 			Multimonitor data
@@ -6547,6 +6559,7 @@ focus (where a frame immediately loses focus when it's left by the mouse
   defsubr (&Sframe_position);
   defsubr (&Sset_frame_position);
   defsubr (&Sframe_pointer_visible_p);
+  defsubr (&Sset_frame_was_invisible);
   defsubr (&Sframe_window_state_change);
   defsubr (&Sset_frame_window_state_change);
   defsubr (&Sframe_scale_factor);
diff --git a/src/frame.h b/src/frame.h
index 744b95e1e0..75a0b184c1 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -456,7 +456,11 @@ #define EMACS_FRAME_H
   /* 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;
+  bool_bf new_size_p : 1;
+
+  /* True when frame was invisible before first MapNotify event.  Used
+     in X builds only.  */
+  bool_bf was_invisible : 1;
 
   /* Bitfield area ends here.  */
 
diff --git a/src/nsfns.m b/src/nsfns.m
index 1f281f75fd..d14f7b51ea 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1404,6 +1404,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
       else
         {
 	  /* Must have been Qnil.  */
+	  f->was_invisible = true;
         }
     }
 
diff --git a/src/w32fns.c b/src/w32fns.c
index 66baeaecbd..e5edd62abb 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6107,6 +6107,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
 	  if (!NILP (visibility))
 	    w32_make_frame_visible (f);
+	  else
+	    f->was_invisible = true;
 	}
 
       store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xfns.c b/src/xfns.c
index 782e0a483c..fa95a57ce2 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4127,12 +4127,17 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
      cannot control visibility, so don't try.  */
   if (!f->output_data.x->explicit_parent)
     {
+      /* When called from `x-create-frame-with-faces' visibility is
+	 always explicitly nil.  */
       Lisp_Object visibility
 	= gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
                                RES_TYPE_SYMBOL);
 
       if (EQ (visibility, Qicon))
-	x_iconify_frame (f);
+	{
+	  f->was_invisible = true;
+	  x_iconify_frame (f);
+	}
       else
 	{
 	  if (EQ (visibility, Qunbound))
@@ -4140,6 +4145,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
 	  if (!NILP (visibility))
 	    x_make_frame_visible (f);
+	  else
+	    f->was_invisible = true;
 	}
 
       store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9a34..a663a0f184 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8181,8 +8181,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (f->was_invisible)
+		{
+		  xg_frame_set_char_size
+		    (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+		  f->was_invisible = false;
+		}
 #endif
 	      XSETFRAME (inev.ie.frame_or_window, f);
 	    }
@@ -8443,8 +8447,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (f->was_invisible)
+		{
+		  xg_frame_set_char_size
+		    (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+		  f->was_invisible = false;
+		}
 #endif
 	      f->output_data.x->has_been_visible = true;
 	    }

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10  8:24                           ` martin rudalics
@ 2021-05-10 13:18                             ` Yuuki Harano
  2021-05-10 14:16                               ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-10 13:18 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel


On Mon, 10 May 2021 10:24:26 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
> Hmmm...  did you try the above without the (tool-bar-lines . 0)?

----------------
(setq frame (make-frame '((width . 60) (height . 20)
			  (left-fringe . 0) (right-fringe . 0)
			  (vertical-scroll-bars . nil)
			  (visibility . nil))))
#<frame emacs@luna 0x558a98460d78>

(make-frame-visible frame)
#<frame emacs@luna 0x558a98460d78>

(frame-width frame)
60

(frame-height frame)
20
----------------

But sometimes:

----------------
(frame-width frame)
40

(frame-height frame)
5
----------------

> And how does a normal, visible pgtk frame behave when you toggle
> scroll
> bars or fringes on and off?  Here it expands and shrinks.

Shrinks and shrinks.

----------------
(frame-width)
81

(modify-frame-parameters nil '((right-fringe . 0)))
nil

(frame-width)
79

(modify-frame-parameters nil '((right-fringe . 1)))
nil

(frame-width)
76

(modify-frame-parameters nil '((right-fringe . 0)))
nil

(frame-width)
74

(modify-frame-parameters nil '((right-fringe . 1)))
nil

(frame-width)
71
----------------

It is the same when I toggle vertical-scroll-bars.

I'll debug...
-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 13:18                             ` Yuuki Harano
@ 2021-05-10 14:16                               ` martin rudalics
  2021-05-10 15:41                                 ` Yuuki Harano
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-10 14:16 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: emacs-devel

 > ----------------
 > (setq frame (make-frame '((width . 60) (height . 20)
 > 			  (left-fringe . 0) (right-fringe . 0)
 > 			  (vertical-scroll-bars . nil)
 > 			  (visibility . nil))))
 > #<frame emacs@luna 0x558a98460d78>
 >
 > (make-frame-visible frame)
 > #<frame emacs@luna 0x558a98460d78>
 >
 > (frame-width frame)
 > 60
 >
 > (frame-height frame)
 > 20
 > ----------------

This would indicate that the toolbar lines implied resize is the culprit
but this

 > But sometimes:
 >
 > ----------------
 > (frame-width frame)
 > 40
 >
 > (frame-height frame)
 > 5
 > ----------------

is very strange.

 >> And how does a normal, visible pgtk frame behave when you toggle
 >> scroll
 >> bars or fringes on and off?  Here it expands and shrinks.
 >
 > Shrinks and shrinks.

I had this when toggling menu bar lines on Motif builds.

 > ----------------
 > (frame-width)
 > 81
 >
 > (modify-frame-parameters nil '((right-fringe . 0)))
 > nil
 >
 > (frame-width)
 > 79
 >
 > (modify-frame-parameters nil '((right-fringe . 1)))
 > nil
 >
 > (frame-width)
 > 76
 >
 > (modify-frame-parameters nil '((right-fringe . 0)))
 > nil
 >
 > (frame-width)
 > 74
 >
 > (modify-frame-parameters nil '((right-fringe . 1)))
 > nil
 >
 > (frame-width)
 > 71
 > ----------------
 >
 > It is the same when I toggle vertical-scroll-bars.
 >
 > I'll debug...

Please try (if those work on your system) with

- frame-resize-pixelwise t initially

- a pgtk build using GTK2

- a normal "non-pgtk" GTK3 build

and also do initialize

frame_size_history = list1 (make_fixnum (100));

and post the contents of the file displayed by

   (frame--size-history)
   (pop-to-buffer "*frame-size-history*"))

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 14:16                               ` martin rudalics
@ 2021-05-10 15:41                                 ` Yuuki Harano
  2021-05-10 19:20                                   ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-10 15:41 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel


On Mon, 10 May 2021 16:16:27 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
> Please try (if those work on your system) with

Thanks for the hints.

I fixed the bug.  I was passing text size to xg_frame_set_char_size().
It should be pixel size.

Now, I tested with fringes/scrollbar/toolbar on/off and toggling them
like:
----
(setq frame (make-frame '((width . 60) (height . 20)
                          (left-fringe . 0) (right-fringe . 0) )))
(modify-frame-parameters frame '((left-fringe . 8)))
----
and (frame-width) and (frame-height) were always 60 and 20.

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 12:27                                                       ` martin rudalics
@ 2021-05-10 19:05                                                         ` Tassilo Horn
  2021-05-10 19:21                                                           ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-10 19:05 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

Hi Martin,

> I attach a new patch.  Maybe we're more lucky this time.

Yes, that one does the trick!

Thanks,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 15:41                                 ` Yuuki Harano
@ 2021-05-10 19:20                                   ` martin rudalics
  2021-05-11 14:32                                     ` Yuuki Harano
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-10 19:20 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: emacs-devel

 > Now, I tested with fringes/scrollbar/toolbar on/off and toggling them
 > like:
 > ----
 > (setq frame (make-frame '((width . 60) (height . 20)
 >                            (left-fringe . 0) (right-fringe . 0) )))
 > (modify-frame-parameters frame '((left-fringe . 8)))
 > ----
 > and (frame-width) and (frame-height) were always 60 and 20.

Good.  Can you also test the earlier


(setq frame (make-frame '((width . 60) (height . 20)
			  (tool-bar-lines . 0)
			  (visibility . nil))))

(make-frame-visible frame)


now?

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 19:05                                                         ` Tassilo Horn
@ 2021-05-10 19:21                                                           ` martin rudalics
  2021-05-10 19:28                                                             ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-10 19:21 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 >> I attach a new patch.  Maybe we're more lucky this time.
 >
 > Yes, that one does the trick!

OK.  Now please start with emacs -Q -iconic and tell me how it looks
like when you deiconify it.  Also please do a

(setq frame (make-frame '((visibility . icon))))

followed by (make-frame-visible frame)

and a

(setq frame (make-frame '((visibility . nil))))

followed by a

(make-frame-visible frame)

and tell me how these look like.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 19:21                                                           ` martin rudalics
@ 2021-05-10 19:28                                                             ` Tassilo Horn
  2021-05-11  8:29                                                               ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-10 19:28 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>>> I attach a new patch.  Maybe we're more lucky this time.
>>
>> Yes, that one does the trick!
>
> OK.  Now please start with emacs -Q -iconic and tell me how it looks
> like when you deiconify it.

Iconified frames/windows are nothing supported by sway.  If you don't
need a window but don't want to close it, you can send it to the
scratchpad workspace.  Anyway, emacs -Q -iconic results in a frame where
only the menubar is shown and the toolbar is missing until I switch
focus back and forth, so just like a normal, non-iconic frame without
your latest patch.

> Also please do a
>
> (setq frame (make-frame '((visibility . icon))))

I get a new frame with a menubar but no toolbar (unless I'd resize it or
swith focus back and forth).

> followed by (make-frame-visible frame)

No observable change.

> and a
>
> (setq frame (make-frame '((visibility . nil))))

Nothing happens which I guess is expected.

> (make-frame-visible frame)

The frame appears with again a menubar but no toolbar (until I apply one
of my workarounds as above).

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 19:28                                                             ` Tassilo Horn
@ 2021-05-11  8:29                                                               ` martin rudalics
  2021-05-11  9:25                                                                 ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-11  8:29 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1512 bytes --]

 >> OK.  Now please start with emacs -Q -iconic and tell me how it looks
 >> like when you deiconify it.
 >
 > Iconified frames/windows are nothing supported by sway.  If you don't
 > need a window but don't want to close it, you can send it to the
 > scratchpad workspace.

If there were an API for that we could support it.  I still don't get a
couple of things with sway: Does it support resize requests?  What
happens when you make an already visible frame invisible or iconified?
Does it support size hints?

 > Anyway, emacs -Q -iconic results in a frame where
 > only the menubar is shown and the toolbar is missing until I switch
 > focus back and forth, so just like a normal, non-iconic frame without
 > your latest patch.
 >
 >> Also please do a
 >>
 >> (setq frame (make-frame '((visibility . icon))))
 >
 > I get a new frame with a menubar but no toolbar (unless I'd resize it or
 > swith focus back and forth).

While here we could say "don't do that, then" ...

 >> followed by (make-frame-visible frame)
 >
 > No observable change.
 >
 >> and a
 >>
 >> (setq frame (make-frame '((visibility . nil))))
 >
 > Nothing happens which I guess is expected.

... this one looks like valid behavior ...

 >> (make-frame-visible frame)
 >
 > The frame appears with again a menubar but no toolbar (until I apply one
 > of my workarounds as above).

... and this is our usual annoyance.  I attached a new patch which
should handle these cases as well.  If there's anything else left,
please tell me.

martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: frame-was-visible.diff --]
[-- Type: text/x-patch; name="frame-was-visible.diff", Size: 6825 bytes --]

diff --git a/lisp/faces.el b/lisp/faces.el
index 68bfbbae38..9969140f0c 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2118,7 +2118,23 @@ x-create-frame-with-faces
 	  (x-handle-reverse-video frame parameters)
 	  (frame-set-background-mode frame t)
 	  (face-set-after-frame-default frame parameters)
-	  (if (null visibility-spec)
+          ;; Mark frame as 'was-invisible' when it was created as
+          ;; invisible or iconified and PARAMETERS contains either a
+          ;; width or height specification.  This should be sufficient
+          ;; to handle Bug#24526 (where a frame is initially iconified
+          ;; to allow manipulating its size in a non-obtrusive way) and
+          ;; avoid that a tiling window manager for GTK3 gets a resize
+          ;; request it cannot handle (Bug#48268).  The 'was-invisible'
+          ;; flag is eventually processed in xterm.c after we receive a
+          ;; MapNotify event; non-X builds ignore it.
+          (frame--set-was-invisible
+           frame
+           (and visibility-spec
+                (memq (cdr visibility-spec) '(nil icon))
+                (or (assq 'width parameters)
+                    (assq 'height parameters))))
+
+          (if (null visibility-spec)
 	      (make-frame-visible frame)
 	    (modify-frame-parameters frame (list visibility-spec)))
 	  (setq success t))
diff --git a/src/frame.c b/src/frame.c
index 738bfe9a5c..15988a6c30 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -971,6 +971,7 @@ make_frame (bool mini_p)
   f->no_accept_focus = false;
   f->z_group = z_group_none;
   f->tooltip = false;
+  f->was_invisible = false;
   f->child_frame_border_width = -1;
   f->last_tab_bar_item = -1;
 #ifndef HAVE_EXT_TOOL_BAR
@@ -5907,7 +5908,18 @@ DEFUN ("frame-pointer-visible-p", Fframe_pointer_visible_p,
   return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
 }
 
+DEFUN ("frame--set-was-invisible", Fframe__set_was_invisible,
+       Sframe__set_was_invisible, 2, 2, 0,
+       doc: /* Set FRAME's was-invisible flag if WAS-INVISIBLE is non-nil.
+This function is for internal use only.  */)
+  (Lisp_Object frame, Lisp_Object was_invisible)
+{
+  struct frame *f = decode_live_frame (frame);
 
+  f->was_invisible = !NILP (was_invisible);
+
+  return f->was_invisible ? Qt : Qnil;
+}
 \f
 /***********************************************************************
 			Multimonitor data
@@ -6547,6 +6559,7 @@ focus (where a frame immediately loses focus when it's left by the mouse
   defsubr (&Sframe_position);
   defsubr (&Sset_frame_position);
   defsubr (&Sframe_pointer_visible_p);
+  defsubr (&Sframe__set_was_invisible);
   defsubr (&Sframe_window_state_change);
   defsubr (&Sset_frame_window_state_change);
   defsubr (&Sframe_scale_factor);
diff --git a/src/frame.h b/src/frame.h
index 744b95e1e0..75a0b184c1 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -456,7 +456,11 @@ #define EMACS_FRAME_H
   /* 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;
+  bool_bf new_size_p : 1;
+
+  /* True when frame was invisible before first MapNotify event.  Used
+     in X builds only.  */
+  bool_bf was_invisible : 1;
 
   /* Bitfield area ends here.  */
 
diff --git a/src/nsfns.m b/src/nsfns.m
index 1f281f75fd..d14f7b51ea 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -1404,6 +1404,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
       else
         {
 	  /* Must have been Qnil.  */
+	  f->was_invisible = true;
         }
     }
 
diff --git a/src/w32fns.c b/src/w32fns.c
index 66baeaecbd..e5edd62abb 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6107,6 +6107,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
 	  if (!NILP (visibility))
 	    w32_make_frame_visible (f);
+	  else
+	    f->was_invisible = true;
 	}
 
       store_frame_param (f, Qvisibility, visibility);
diff --git a/src/xfns.c b/src/xfns.c
index 782e0a483c..e46616e6d6 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4127,12 +4127,21 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
      cannot control visibility, so don't try.  */
   if (!f->output_data.x->explicit_parent)
     {
+      /* When called from `x-create-frame-with-faces' visibility is
+	 always explicitly nil.  */
       Lisp_Object visibility
 	= gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
                                RES_TYPE_SYMBOL);
+      Lisp_Object height
+	= gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
+      Lisp_Object width
+	= gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
 
       if (EQ (visibility, Qicon))
-	x_iconify_frame (f);
+	{
+	  f->was_invisible = true;
+	  x_iconify_frame (f);
+	}
       else
 	{
 	  if (EQ (visibility, Qunbound))
@@ -4140,8 +4149,17 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
 	  if (!NILP (visibility))
 	    x_make_frame_visible (f);
+	  else
+	    f->was_invisible = true;
 	}
 
+      /* Leave f->was_invisible true only if height or width were
+	 specified too.  This takes effect only when we are not called
+	 from `x-create-frame-with-faces' (see above comment).  */
+      f->was_invisible
+	= (f->was_invisible
+	   && (!EQ (height, Qunbound) || !EQ (width, Qunbound)));
+
       store_frame_param (f, Qvisibility, visibility);
     }
 
diff --git a/src/xterm.c b/src/xterm.c
index 9edaed9a34..a663a0f184 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8181,8 +8181,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (f->was_invisible)
+		{
+		  xg_frame_set_char_size
+		    (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+		  f->was_invisible = false;
+		}
 #endif
 	      XSETFRAME (inev.ie.frame_or_window, f);
 	    }
@@ -8443,8 +8447,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #if defined USE_GTK && defined HAVE_GTK3
 	      /* If GTK3 wants to impose some old size here (Bug#24526),
 		 tell it that the current size is what we want.  */
-	      xg_frame_set_char_size
-		(f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+	      if (f->was_invisible)
+		{
+		  xg_frame_set_char_size
+		    (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+		  f->was_invisible = false;
+		}
 #endif
 	      f->output_data.x->has_been_visible = true;
 	    }

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-11  8:29                                                               ` martin rudalics
@ 2021-05-11  9:25                                                                 ` Tassilo Horn
  2021-05-12  8:44                                                                   ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-11  9:25 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

Hi Martin,

> If there were an API for that we could support it.  I still don't get
> a couple of things with sway: Does it support resize requests?  What
> happens when you make an already visible frame invisible or iconified?
> Does it support size hints?

I've asked on #sway-devel.  Here's the transcript:

--8<---------------cut here---------------start------------->8---
11:14 <tsdh> I'm currently debugging some windowing issue with some emacs
             dev, and he has some questions regarding sway which probably
             someone here can comment on:
11:15 <tsdh> Does it support resize requests?  What happens when you make an
             already visible frame invisible or iconified?  Does it support
             size hints?
11:15 <tsdh> "it" is sway, and frame = WM window.
11:16 <emersion> resize requests: yes
11:16 <emersion> size hints: yes
11:16 <emersion> iconified: iirc that does nothing
11:16 <emersion> but not sure
11:16 <emersion> all of this assumes an x11 client
11:17 <tsdh> emersion: Yes, right now, emacs is an x11 client (GTK3 built).
11:18 <tsdh> What does sway when a new emacs frame should be mapped and
             requests a certain size?  It's at least not honored in tiling
             mode which is obviously fine.
11:25 <emersion> https://github.com/swaywm/sway/blob/31b4b96ebf2af88630752d8518fd360ff84cf3e5/sway/desktop/xwayland.c#L584
11:28 <tsdh> Thanks!
--8<---------------cut here---------------end--------------->8---

> ... and this is our usual annoyance.  I attached a new patch which
> should handle these cases as well.  If there's anything else left,
> please tell me.

The new version handles all cases we've had so far.  Thanks!

If I encounter another case, I'll come back to you.  But that's very
unlikely, I usually have just one single frame plus the ones spawned by
emacsclient -c.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-10 19:20                                   ` martin rudalics
@ 2021-05-11 14:32                                     ` Yuuki Harano
  2021-05-12  8:47                                       ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Yuuki Harano @ 2021-05-11 14:32 UTC (permalink / raw)
  To: rudalics; +Cc: emacs-devel


On Mon, 10 May 2021 21:20:46 +0200,
	martin rudalics <rudalics@gmx.at> wrote:
> Good.  Can you also test the earlier
> 
> 
> (setq frame (make-frame '((width . 60) (height . 20)
> 			  (tool-bar-lines . 0)
> 			  (visibility . nil))))
> 
> (make-frame-visible frame)
> 
> 
> now?

----------------
(setq frame (make-frame '((width . 60) (height . 20)
			  (tool-bar-lines . 0)
			  (visibility . nil))))
#<frame emacs@luna 0x5559f25c1898>


(make-frame-visible frame)
#<frame emacs@luna 0x5559f25c1898>

(frame-width frame)
60

(frame-height frame)
20
----------------

-- 
Yuuki Harano



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-11  9:25                                                                 ` Tassilo Horn
@ 2021-05-12  8:44                                                                   ` martin rudalics
  2021-05-12 14:53                                                                     ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-12  8:44 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 > 11:15 <tsdh> Does it support resize requests?  What happens when you make an
 >               already visible frame invisible or iconified?  Does it support
 >               size hints?
 > 11:15 <tsdh> "it" is sway, and frame = WM window.
 > 11:16 <emersion> resize requests: yes

Funny.  I would say that

if (!container_is_floating(view->container)) {
		return;
	}

from the URL below should say "no" but maybe I'm missing something.  Can
you change the size of a frame by setting its 'width' or 'height'
parameter?  Does your frame resize when you toggle the vertical scroll
bar on/off?

 > 11:16 <emersion> size hints: yes

We'll look into that, eventually.

 > 11:16 <emersion> iconified: iirc that does nothing
 > 11:16 <emersion> but not sure
 > 11:16 <emersion> all of this assumes an x11 client
 > 11:17 <tsdh> emersion: Yes, right now, emacs is an x11 client (GTK3 built).
 > 11:18 <tsdh> What does sway when a new emacs frame should be mapped and
 >               requests a certain size?  It's at least not honored in tiling
 >               mode which is obviously fine.
 > 11:25 <emersion> https://github.com/swaywm/sway/blob/31b4b96ebf2af88630752d8518fd360ff84cf3e5/sway/desktop/xwayland.c#L584
 > 11:28 <tsdh> Thanks!
 > --8<---------------cut here---------------end--------------->8---
 >
 >> ... and this is our usual annoyance.  I attached a new patch which
 >> should handle these cases as well.  If there's anything else left,
 >> please tell me.
 >
 > The new version handles all cases we've had so far.  Thanks!

I've pushed it now.  It should fail in the usual manner with

(setq frame (make-frame '((visibility . nil) (width . 80))))
(make-frame-visible frame)

Please verify.

And many thanks for testing, martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-11 14:32                                     ` Yuuki Harano
@ 2021-05-12  8:47                                       ` martin rudalics
  2021-05-13  8:48                                         ` Garjola Dindi
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-12  8:47 UTC (permalink / raw)
  To: Yuuki Harano; +Cc: emacs-devel

 > ----------------
 > (setq frame (make-frame '((width . 60) (height . 20)
 > 			  (tool-bar-lines . 0)
 > 			  (visibility . nil))))
 > #<frame emacs@luna 0x5559f25c1898>
 >
 >
 > (make-frame-visible frame)
 > #<frame emacs@luna 0x5559f25c1898>
 >
 > (frame-width frame)
 > 60
 >
 > (frame-height frame)
 > 20
 > ----------------

Thanks.  Let's hope it stays this way for a while.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-12  8:44                                                                   ` martin rudalics
@ 2021-05-12 14:53                                                                     ` Tassilo Horn
  2021-05-12 16:40                                                                       ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-12 14:53 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>> 11:15 <tsdh> Does it support resize requests?  What happens when you make an
>>               already visible frame invisible or iconified?  Does it support
>>               size hints?
>> 11:15 <tsdh> "it" is sway, and frame = WM window.
>> 11:16 <emersion> resize requests: yes
>
> Funny.  I would say that
>
> if (!container_is_floating(view->container)) {
> 		return;
> 	}
>
> from the URL below should say "no" but maybe I'm missing something.
> Can you change the size of a frame by setting its 'width' or 'height'
> parameter?

I can when my emacs frame is floating.  If it is tiling, nothing changes
(which is expected).  But if I make it floating afterwards, it'll have
the height/width as specified by the frame parameters.

> Does your frame resize when you toggle the vertical scroll bar on/off?

Again, yes when floating, no when tiling.

> I've pushed it now.  It should fail in the usual manner with
>
> (setq frame (make-frame '((visibility . nil) (width . 80))))
> (make-frame-visible frame)
>
> Please verify.

I'm happy not to disappoint you. ;-)

> And many thanks for testing, martin

I'm happy to have helped.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-12 14:53                                                                     ` Tassilo Horn
@ 2021-05-12 16:40                                                                       ` martin rudalics
  2021-05-12 19:06                                                                         ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-12 16:40 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 > I can when my emacs frame is floating.  If it is tiling, nothing changes
 > (which is expected).  But if I make it floating afterwards, it'll have
 > the height/width as specified by the frame parameters.
 >
 >> Does your frame resize when you toggle the vertical scroll bar on/off?
 >
 > Again, yes when floating, no when tiling.

Is everything redisplayed as expected in the tiled case when you do
either of that?  For example, try to turn off vertical scroll bar -> put
it on the left -> turn it off again -> put it back on the right.

 >> I've pushed it now.  It should fail in the usual manner with
 >>
 >> (setq frame (make-frame '((visibility . nil) (width . 80))))
 >> (make-frame-visible frame)
 >>
 >> Please verify.
 >
 > I'm happy not to disappoint you. ;-)

OK.  So people who do that on a tiling WM will be punished.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-12 16:40                                                                       ` martin rudalics
@ 2021-05-12 19:06                                                                         ` Tassilo Horn
  2021-05-13  7:55                                                                           ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-12 19:06 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>> I can when my emacs frame is floating.  If it is tiling, nothing changes
>> (which is expected).  But if I make it floating afterwards, it'll have
>> the height/width as specified by the frame parameters.
>>
>>> Does your frame resize when you toggle the vertical scroll bar
>>> on/off?
>>
>> Again, yes when floating, no when tiling.
>
> Is everything redisplayed as expected in the tiled case when you do
> either of that?

Yes, I think so.

> For example, try to turn off vertical scroll bar -> put it on the left
> -> turn it off again -> put it back on the right.

Yes, looks all right with emacs -Q.  But with my normal config which
includes (scroll-bar-mode -1), when I do `C-x 5 2' the new frame has a
scrollbar on the right which won't vanish when resizing or switching
focus.  That happens with a freshly started emacs reproducibly but not
with the longer running instance I'm writing this mail in.

I'll see if I can reduce my config to the essentials triggering this
behavior...

... Oh, that was easier as expected.

--8<---------------cut here---------------start------------->8---
(tool-bar-mode -1)
(menu-bar-mode -1)
(when (fboundp 'scroll-bar-mode)
  (scroll-bar-mode -1))
(when (fboundp 'horizontal-scroll-bar-mode)
  (horizontal-scroll-bar-mode -1))

(setq default-frame-alist '((width . 90)
                            (height . 50)))
--8<---------------cut here---------------end--------------->8---

With "emacs -Q --load repro.el" where repro.el contains just the above
listing, I get an initial frame with the usual annoyance (a menubar
which vanishes on focus/resize), and in addition C-x 5 2 gives me a new
frame which has a scrollbar which won't vanish except by M-x
scroll-bar-mode RET twice.  (The first makes the scrollbars appear also
on the initial frame, the second turns it off in both frames).

>>> I've pushed it now.  It should fail in the usual manner with
>>>
>>> (setq frame (make-frame '((visibility . nil) (width . 80))))
>>> (make-frame-visible frame)
>>>
>>> Please verify.
>>
>> I'm happy not to disappoint you. ;-)
>
> OK.  So people who do that on a tiling WM will be punished.

It's not a hard punishment, and I guess tiling WM users usually won't
specify a width anyway, so the issue is present at most when some
package does that.  (Without width, it works just fine.)

Also interestingly, with just emacs -Q, C-x 5 2 exhibits the "toolbar is
missing in the new frame" issue.  When I load the repro.el from above
before C-x 5 2, the new frame has no toolbar or menubar but the
scrollbar is there in the new frame.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-12 19:06                                                                         ` Tassilo Horn
@ 2021-05-13  7:55                                                                           ` martin rudalics
  2021-05-13  8:08                                                                             ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-13  7:55 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 > --8<---------------cut here---------------start------------->8---
 > (tool-bar-mode -1)
 > (menu-bar-mode -1)
 > (when (fboundp 'scroll-bar-mode)
 >    (scroll-bar-mode -1))
 > (when (fboundp 'horizontal-scroll-bar-mode)
 >    (horizontal-scroll-bar-mode -1))
 >
 > (setq default-frame-alist '((width . 90)
 >                              (height . 50)))
 > --8<---------------cut here---------------end--------------->8---
 >
 > With "emacs -Q --load repro.el" where repro.el contains just the above
 > listing, I get an initial frame with the usual annoyance (a menubar
 > which vanishes on focus/resize), and in addition C-x 5 2 gives me a new
 > frame which has a scrollbar which won't vanish except by M-x
 > scroll-bar-mode RET twice.  (The first makes the scrollbars appear also
 > on the initial frame, the second turns it off in both frames).

Can you reproduce any of these problems without the
`default-frame-alist' setting?  In either case, please do the

   frame_size_history = list1 (make_fixnum (100));

assignment and tell me what calling `frame--size-history' gives after
the initial frame has appeared.  After that do

(setq frame-size-history '(100))

run C-x 5 2 and again post what `frame--size-history' returns.

 > Also interestingly, with just emacs -Q, C-x 5 2 exhibits the "toolbar is
 > missing in the new frame" issue.

Again, I'd need to know what `frame--size-history' tells about this.  Is
this behavior new or did it already occur in Emacs 27?

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-13  7:55                                                                           ` martin rudalics
@ 2021-05-13  8:08                                                                             ` Tassilo Horn
  2021-05-16  8:29                                                                               ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-13  8:08 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel


martin rudalics <rudalics@gmx.at> writes:

>> --8<---------------cut here---------------start------------->8---
>> (tool-bar-mode -1)
>> (menu-bar-mode -1)
>> (when (fboundp 'scroll-bar-mode)
>>    (scroll-bar-mode -1))
>> (when (fboundp 'horizontal-scroll-bar-mode)
>>    (horizontal-scroll-bar-mode -1))
>>
>> (setq default-frame-alist '((width . 90)
>>                              (height . 50)))
>> --8<---------------cut here---------------end--------------->8---
>>
>> With "emacs -Q --load repro.el" where repro.el contains just the above
>> listing, I get an initial frame with the usual annoyance (a menubar
>> which vanishes on focus/resize), and in addition C-x 5 2 gives me a new
>> frame which has a scrollbar which won't vanish except by M-x
>> scroll-bar-mode RET twice.  (The first makes the scrollbars appear also
>> on the initial frame, the second turns it off in both frames).
>
> Can you reproduce any of these problems without the
> `default-frame-alist' setting?  In either case, please do the
>
>   frame_size_history = list1 (make_fixnum (100));
>
> assignment and tell me what calling `frame--size-history' gives after
> the initial frame has appeared.

With --load repro.el the initial frame has:

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x555ace1cfc60>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=1594x851
change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
menu-bar-lines (2), MS=80x105 IH IV
vertical-scroll-bars (3), TS=1562x851~>1578x851, TC=195x40~>197x40, MS=80x105 IH IV
size (1), TS=1578x851~>720x1050, TC=197x40~>90x50, NS=1594x851~>736x1050, IS=1594x851~>736x1050, MS=80x105
xg_frame_set_char_size, visible, PS=1594x851, XS=736x1050, DS=736x1050
ConfigureNotify, PS=1594x851, XS=1594x878, DS=736x1050
xg_frame_resized, changed, PS=1594x851, XS=1594x878
change_frame_size_1, delayed, PS=1594x851, XS=1594x878, DS=736x1050
change_frame_size (5), TS=1578x851~>1578x878, TC=197x40~>197x41, NS=1594x851~>1594x878, IS=1594x851~>1594x878, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

> After that do
>
> (setq frame-size-history '(100))
>
> run C-x 5 2 and again post what `frame--size-history' returns.

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* 0x555ace358480>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>720x1050, TC=80x25~>90x50, NS=656x525~>736x1050, IS=656x525~>736x1050, MS=16x42 IH IV
scroll-bar-width (3), NS=736x1050~>752x1050, IS=736x1050~>752x1050, MS=80x105
scroll-bar-height (3), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=752x1050, XS=752x1050, DS=752x1050
xg_frame_set_char_size (5), MS=16x42 IH IV
x_make_frame_visible
MapNotify, not hidden & not iconified, PS=752x1050, DS=752x1050
ConfigureNotify, PS=752x1050, XS=752x1050, DS=752x1050
xg_frame_resized, unchanged, PS=752x1050, XS=752x1050
ConfigureNotify, PS=752x1050, XS=794x878, DS=752x1050
xg_frame_resized, changed, PS=752x1050, XS=794x878
change_frame_size_1, delayed, PS=752x1050, XS=794x878, DS=752x1050
change_frame_size (5), TS=720x1050~>762x878, TC=90x50~>95x41, NS=752x1050~>794x878, IS=752x1050~>794x878, MS=16x42 IH IV
set_window_configuration (4), MS=80x105 IH IV
--8<---------------cut here---------------end--------------->8---

And now the same with the repro.el where the default-frame-alist setting
is commented out, and thereby it works all fine, i.e., the initial frame
has tool/menu/scrollbars disabled and the second frame has, too.

Initial frame:

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x55dd691fa0c0>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=1594x851
change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
menu-bar-lines (2), MS=80x105 IH IV
vertical-scroll-bars (3), TS=1562x851~>1578x851, TC=195x40~>197x40, MS=80x105 IH IV
ConfigureNotify, PS=1594x851, XS=1594x878
xg_frame_resized, changed, PS=1594x851, XS=1594x878
change_frame_size_1, delayed, PS=1594x851, XS=1594x878
change_frame_size (5), TS=1578x851~>1578x878, TC=197x40~>197x41, NS=1594x851~>1594x878, IS=1594x851~>1594x878, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

C-x 5 2 frame:

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* 0x55dd69b9b830>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), MS=80x105
scroll-bar-height (3), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=656x756, XS=656x756, DS=656x756
xg_frame_set_char_size (5), MS=16x42 IH IV
x_make_frame_visible
MapNotify, not hidden & not iconified, PS=656x756, DS=656x756
ConfigureNotify, PS=656x756, XS=656x756, DS=656x756
xg_frame_resized, unchanged, PS=656x756, XS=656x756
ConfigureNotify, PS=656x756, XS=794x878, DS=656x756
xg_frame_resized, changed, PS=656x756, XS=794x878
change_frame_size_1, delayed, PS=656x756, XS=794x878, DS=656x756
change_frame_size (5), TS=640x756~>778x878, TC=80x36~>97x41, NS=656x756~>794x878, IS=656x756~>794x878, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

>> Also interestingly, with just emacs -Q, C-x 5 2 exhibits the "toolbar
>> is missing in the new frame" issue.
>
> Again, I'd need to know what `frame--size-history' tells about this.

Initial frame:

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x564daeb04e40>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=1594x851
change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
ConfigureNotify, PS=1594x851, XS=1594x810
xg_frame_resized, changed, PS=1594x851, XS=1594x810
change_frame_size_1, delayed, PS=1594x851, XS=1594x810
change_frame_size (5), TS=1562x851~>1562x810, TC=195x40~>195x38, NS=1594x851~>1594x810, IS=1594x851~>1594x810, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

C-x 5 2 frame: Oh, too bad, that doesn't happen anymore.  The new frame
has a toolbar immediately.  Anyway, I'll post the history anyway...

--8<---------------cut here---------------start------------->8---
Frame size history of #<frame *scratch* 0x55ba5a491a08>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
x_make_frame_visible
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=794x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=794x851
change_frame_size_1, delayed, PS=672x756, XS=794x851, DS=672x756
tool-bar-lines (2), MS=80x105 IH IV
ConfigureNotify, PS=672x756, XS=794x810, DS=794x851
xg_frame_resized, changed, PS=672x756, XS=794x810, DS=794x851
change_frame_size_1, delayed, PS=672x756, XS=794x810, DS=794x851
change_frame_size (5), TS=640x756~>762x810, TC=80x36~>95x38, NS=672x756~>794x810, IS=672x756~>794x810, MS=16x42 IH IV
--8<---------------cut here---------------end--------------->8---

> Is this behavior new or did it already occur in Emacs 27?

Yes, with my repro.el containing the `default-frame-alist' setting, the
initial frame has a menubar (until resize/focus), and the new frame
after C-x 5 2 has a scrollbar.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-12  8:47                                       ` martin rudalics
@ 2021-05-13  8:48                                         ` Garjola Dindi
  0 siblings, 0 replies; 65+ messages in thread
From: Garjola Dindi @ 2021-05-13  8:48 UTC (permalink / raw)
  To: emacs-devel


Hi,

I just recompiled master, and EXWM is still broken. Everything seems OK
while loading the init file, but just after emacs has finished loading,
the frame gets resized when I launch a panel (I use polybar). From that
point on, the contents of the frame are ivisible. I can get to the menus
with F10 and I can type commands (although I don't see anything on the
screen).

It is difficult for me to give more information, since I can't interact
with emacs this way.

I can do other tests if you give me some guidance.

Thanks.

Garjola


-- 




^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-13  8:08                                                                             ` Tassilo Horn
@ 2021-05-16  8:29                                                                               ` martin rudalics
  2021-05-16  8:33                                                                                 ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-16  8:29 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 > With --load repro.el the initial frame has:
 >
 > --8<---------------cut here---------------start------------->8---
 > Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x555ace1cfc60>
 > x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
 > gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
 > scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105

16 pixels for the scroll bar, we don't know yet that it will be turned
off.

 > scroll-bar-height (3), MS=80x105
 > menu-bar-lines (2), MS=80x105
 > x_create_frame_2 (0), MS=80x105
 > xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
 > xg_frame_set_char_size (5), MS=16x42 IH IV
 > MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
 > ConfigureNotify, PS=672x756, XS=672x756, DS=672x756

This was a ConfigureNotify for the frame size we asked for.  We don't
pass it on to change_frame_size since it's the size we have set already.

 > xg_frame_resized, unchanged, PS=672x756, XS=672x756
 > ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756

And this was a ConfigureNotify for the frame size the WM allots to us.
This time it gives you the entire display - 1594x851 native pixels,
right?.

 > xg_frame_resized, changed, PS=672x756, XS=1594x851
 > change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
 > change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV

Here Emacs should have dealt with the size we got from the WM resulting
in 195x40 characters.

 > tool-bar-lines (2), MS=80x105 IH IV
 > menu-bar-lines (2), MS=80x105 IH IV
 > vertical-scroll-bars (3), TS=1562x851~>1578x851, TC=195x40~>197x40, MS=80x105 IH IV

Here we presumably processed the removal of the various bars.

 > size (1), TS=1578x851~>720x1050, TC=197x40~>90x50, NS=1594x851~>736x1050, IS=1594x851~>736x1050, MS=80x105

And here the 90x50 characters size request from `default-frame-alist'
kicked in.

 > xg_frame_set_char_size, visible, PS=1594x851, XS=736x1050, DS=736x1050
 > ConfigureNotify, PS=1594x851, XS=1594x878, DS=736x1050

Here we got a ConfigureNotify of 1594x878 native pixels.  These are 17
pixels more than before, probably from the recovered menu bar pixels
(leaving the outer frame size unchanged).

 > xg_frame_resized, changed, PS=1594x851, XS=1594x878
 > change_frame_size_1, delayed, PS=1594x851, XS=1594x878, DS=736x1050
 > change_frame_size (5), TS=1578x851~>1578x878, TC=197x40~>197x41, NS=1594x851~>1594x878, IS=1594x851~>1594x878, MS=16x42 IH IV

And here we processed the ConfigureNotify, resulting in 197x41
characters.

 > --8<---------------cut here---------------end--------------->8---

The problem with this history is that the focus/resize is somewhere
processed in it but I cannot tell where.  I suppose that at the time the
1594x878 pixels appear in the history, everything looks good, that is
the menu bar has disappeared probably after the frame has got focus.

 >> After that do
 >>
 >> (setq frame-size-history '(100))
 >>
 >> run C-x 5 2 and again post what `frame--size-history' returns.
 >
 > --8<---------------cut here---------------start------------->8---
 > Frame size history of #<frame *scratch* 0x555ace358480>
 > x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
 > gui_figure_window_size (5), TS=640x525~>720x1050, TC=80x25~>90x50, NS=656x525~>736x1050, IS=656x525~>736x1050, MS=16x42 IH IV
 > scroll-bar-width (3), NS=736x1050~>752x1050, IS=736x1050~>752x1050, MS=80x105

16 pixels for the scroll bar with `scroll-bar-mode' turned off?  Looks
silly and is probably the cause of the "scrollbar which won't vanish
except by M-x scroll-bar-mode RET twice".

 > scroll-bar-height (3), MS=80x105
 > x_create_frame_2 (0), MS=80x105
 > xg_frame_set_char_size, invisible, PS=752x1050, XS=752x1050, DS=752x1050
 > xg_frame_set_char_size (5), MS=16x42 IH IV
 > x_make_frame_visible
 > MapNotify, not hidden & not iconified, PS=752x1050, DS=752x1050
 > ConfigureNotify, PS=752x1050, XS=752x1050, DS=752x1050
 > xg_frame_resized, unchanged, PS=752x1050, XS=752x1050
 > ConfigureNotify, PS=752x1050, XS=794x878, DS=752x1050
 > xg_frame_resized, changed, PS=752x1050, XS=794x878
 > change_frame_size_1, delayed, PS=752x1050, XS=794x878, DS=752x1050
 > change_frame_size (5), TS=720x1050~>762x878, TC=90x50~>95x41, NS=752x1050~>794x878, IS=752x1050~>794x878, MS=16x42 IH IV

This looks normal again just that I don't have any idea where this

 > set_window_configuration (4), MS=80x105 IH IV

comes from.

 > --8<---------------cut here---------------end--------------->8---
 >
 > And now the same with the repro.el where the default-frame-alist setting
 > is commented out, and thereby it works all fine, i.e., the initial frame
 > has tool/menu/scrollbars disabled and the second frame has, too.
 >
 > Initial frame:
 >
 > --8<---------------cut here---------------start------------->8---
 > Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x55dd691fa0c0>
 > x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
 > gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
 > scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
 > scroll-bar-height (3), MS=80x105
 > menu-bar-lines (2), MS=80x105
 > x_create_frame_2 (0), MS=80x105
 > xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
 > xg_frame_set_char_size (5), MS=16x42 IH IV
 > MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
 > ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
 > xg_frame_resized, unchanged, PS=672x756, XS=672x756
 > ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
 > xg_frame_resized, changed, PS=672x756, XS=1594x851
 > change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
 > change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV
 > tool-bar-lines (2), MS=80x105 IH IV
 > menu-bar-lines (2), MS=80x105 IH IV
 > vertical-scroll-bars (3), TS=1562x851~>1578x851, TC=195x40~>197x40, MS=80x105 IH IV

No 90x50 request here.

 > ConfigureNotify, PS=1594x851, XS=1594x878
 > xg_frame_resized, changed, PS=1594x851, XS=1594x878
 > change_frame_size_1, delayed, PS=1594x851, XS=1594x878
 > change_frame_size (5), TS=1578x851~>1578x878, TC=197x40~>197x41, NS=1594x851~>1594x878, IS=1594x851~>1594x878, MS=16x42 IH IV

And everything looks like above.

 > --8<---------------cut here---------------end--------------->8---

 >> Is this behavior new or did it already occur in Emacs 27?
 >
 > Yes, with my repro.el containing the `default-frame-alist' setting, the
 > initial frame has a menubar (until resize/focus), and the new frame
 > after C-x 5 2 has a scrollbar.

And with Emacs 27 the initial frame did not have a menu bar initially
and the new frame after C-x 5 2 did not have a scroll bar initially.
Right?

Did my latest commit (c18403302df3f07a7f94c3984d65b808fb40e8c1) in this
area change anything in this regard?

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-16  8:29                                                                               ` martin rudalics
@ 2021-05-16  8:33                                                                                 ` Tassilo Horn
  2021-05-16  9:14                                                                                   ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-16  8:33 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1483 bytes --]

martin rudalics <rudalics@gmx.at> writes:

>> ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
>
> And this was a ConfigureNotify for the frame size the WM allots to us.
> This time it gives you the entire display - 1594x851 native pixels,
> right?.

The width seems right.  Not sure how much space my WM bar on top and
emacs' menubar have but I guess 851 pixel height is reasonable.

>>> Is this behavior new or did it already occur in Emacs 27?
>>
>> Yes, with my repro.el containing the `default-frame-alist' setting,
>> the initial frame has a menubar (until resize/focus), and the new
>> frame after C-x 5 2 has a scrollbar.
>
> And with Emacs 27 the initial frame did not have a menu bar initially
> and the new frame after C-x 5 2 did not have a scroll bar initially.
> Right?

No, what I've written above as answer to your question was with emacs
27.2.

> Did my latest commit (c18403302df3f07a7f94c3984d65b808fb40e8c1) in this
> area change anything in this regard?

Nope, "emacs -Q --load repro.el" (including `default-frame-alist'
setting) still results in

  1. initial frame has a menubar (fsh1.txt)
  2. C-x 5 2 frame has a scrollbar (fsh2.txt)

When commenting the `default-frame-alist' setting, all works as expected
(fsh3.txt for the initial frame and fsh4.txt for the new one created by
C-x 5 2).

When comparing fsh1 vs. fsh3, and fsh2 vs. fsh4, one can see that the
set_window_configuration calls are only there if `default-frame-alist'
is set.

Bye,
Tassilo

[-- Attachment #2: fsh1.txt --]
[-- Type: text/plain, Size: 1727 bytes --]

Frame size history of #<frame  *Minibuf-1* - GNU Emacs at thinkpad-t440p 0x55b351c34ed8>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=1594x851
change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
menu-bar-lines (2), MS=80x105 IH IV
vertical-scroll-bars (3), TS=1562x851~>1578x851, TC=195x40~>197x40, MS=80x105 IH IV
size (1), TS=1578x851~>720x1050, TC=197x40~>90x50, NS=1594x851~>736x1050, IS=1594x851~>736x1050, MS=80x105
xg_frame_set_char_size, visible, PS=1594x851, XS=736x1050, DS=736x1050
ConfigureNotify, PS=1594x851, XS=1594x878, DS=736x1050
xg_frame_resized, changed, PS=1594x851, XS=1594x878
change_frame_size_1, delayed, PS=1594x851, XS=1594x878, DS=736x1050
change_frame_size (5), TS=1578x851~>1578x878, TC=197x40~>197x41, NS=1594x851~>1594x878, IS=1594x851~>1594x878, MS=16x42 IH IV
set_window_configuration (4), MS=80x105 IH IV

[-- Attachment #3: fsh2.txt --]
[-- Type: text/plain, Size: 1071 bytes --]

Frame size history of #<frame  *Minibuf-1* 0x55b35265efe0>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>720x1050, TC=80x25~>90x50, NS=656x525~>736x1050, IS=656x525~>736x1050, MS=16x42 IH IV
scroll-bar-width (3), NS=736x1050~>752x1050, IS=736x1050~>752x1050, MS=80x105
scroll-bar-height (3), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=752x1050, XS=752x1050, DS=752x1050
xg_frame_set_char_size (5), MS=16x42 IH IV
x_make_frame_visible
MapNotify, not hidden & not iconified, PS=752x1050, DS=752x1050
ConfigureNotify, PS=752x1050, XS=752x1050, DS=752x1050
xg_frame_resized, unchanged, PS=752x1050, XS=752x1050
ConfigureNotify, PS=752x1050, XS=794x878, DS=752x1050
xg_frame_resized, changed, PS=752x1050, XS=794x878
change_frame_size_1, delayed, PS=752x1050, XS=794x878, DS=752x1050
change_frame_size (5), TS=720x1050~>762x878, TC=90x50~>95x41, NS=752x1050~>794x878, IS=752x1050~>794x878, MS=16x42 IH IV
set_window_configuration (4), MS=80x105 IH IV

[-- Attachment #4: fsh3.txt --]
[-- Type: text/plain, Size: 1474 bytes --]

Frame size history of #<frame *scratch* - GNU Emacs at thinkpad-t440p 0x55f38508e4d8>
x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), NS=656x756~>672x756, IS=656x756~>672x756, MS=80x105
scroll-bar-height (3), MS=80x105
menu-bar-lines (2), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=672x756, XS=672x756, DS=672x756
xg_frame_set_char_size (5), MS=16x42 IH IV
MapNotify, not hidden & not iconified, PS=672x756, DS=672x756
ConfigureNotify, PS=672x756, XS=672x756, DS=672x756
xg_frame_resized, unchanged, PS=672x756, XS=672x756
ConfigureNotify, PS=672x756, XS=1594x851, DS=672x756
xg_frame_resized, changed, PS=672x756, XS=1594x851
change_frame_size_1, delayed, PS=672x756, XS=1594x851, DS=672x756
change_frame_size (5), TS=640x756~>1562x851, TC=80x36~>195x40, NS=672x756~>1594x851, IS=672x756~>1594x851, MS=16x42 IH IV
tool-bar-lines (2), MS=80x105 IH IV
menu-bar-lines (2), MS=80x105 IH IV
vertical-scroll-bars (3), TS=1562x851~>1578x851, TC=195x40~>197x40, MS=80x105 IH IV
ConfigureNotify, PS=1594x851, XS=1594x878
xg_frame_resized, changed, PS=1594x851, XS=1594x878
change_frame_size_1, delayed, PS=1594x851, XS=1594x878
change_frame_size (5), TS=1578x851~>1578x878, TC=197x40~>197x41, NS=1594x851~>1594x878, IS=1594x851~>1594x878, MS=16x42 IH IV

[-- Attachment #5: fsh4.txt --]
[-- Type: text/plain, Size: 955 bytes --]

x_create_frame_1 (5), TS=80x25~>640x525, NS=80x25~>656x525, IS=80x25~>656x525, MS=16x42 IH IV
Frame size history of #<frame *scratch* 0x55f385b35cb0>
gui_figure_window_size (5), TS=640x525~>640x756, TC=80x25~>80x36, NS=656x525~>656x756, IS=656x525~>656x756, MS=16x42 IH IV
scroll-bar-width (3), MS=80x105
scroll-bar-height (3), MS=80x105
x_create_frame_2 (0), MS=80x105
xg_frame_set_char_size, invisible, PS=656x756, XS=656x756, DS=656x756
xg_frame_set_char_size (5), MS=16x42 IH IV
x_make_frame_visible
MapNotify, not hidden & not iconified, PS=656x756, DS=656x756
ConfigureNotify, PS=656x756, XS=656x756, DS=656x756
xg_frame_resized, unchanged, PS=656x756, XS=656x756
ConfigureNotify, PS=656x756, XS=794x878, DS=656x756
xg_frame_resized, changed, PS=656x756, XS=794x878
change_frame_size_1, delayed, PS=656x756, XS=794x878, DS=656x756
change_frame_size (5), TS=640x756~>778x878, TC=80x36~>97x41, NS=656x756~>794x878, IS=656x756~>794x878, MS=16x42 IH IV

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-16  8:33                                                                                 ` Tassilo Horn
@ 2021-05-16  9:14                                                                                   ` martin rudalics
  2021-05-16  9:16                                                                                     ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-16  9:14 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 >>>> Is this behavior new or did it already occur in Emacs 27?
 >>>
 >>> Yes, with my repro.el containing the `default-frame-alist' setting,
 >>> the initial frame has a menubar (until resize/focus), and the new
 >>> frame after C-x 5 2 has a scrollbar.
 >>
 >> And with Emacs 27 the initial frame did not have a menu bar initially
 >> and the new frame after C-x 5 2 did not have a scroll bar initially.
 >> Right?
 >
 > No, what I've written above as answer to your question was with emacs
 > 27.2.

So can I conclude that the bad behavior was already there with Emacs 27?
I really should try to ask questions in a less ambiguous way.

 >> Did my latest commit (c18403302df3f07a7f94c3984d65b808fb40e8c1) in this
 >> area change anything in this regard?
 >
 > Nope, "emacs -Q --load repro.el" (including `default-frame-alist'
 > setting) still results in
 >
 >    1. initial frame has a menubar (fsh1.txt)
 >    2. C-x 5 2 frame has a scrollbar (fsh2.txt)
 >
 > When commenting the `default-frame-alist' setting, all works as expected
 > (fsh3.txt for the initial frame and fsh4.txt for the new one created by
 > C-x 5 2).
 >
 > When comparing fsh1 vs. fsh3, and fsh2 vs. fsh4, one can see that the
 > set_window_configuration calls are only there if `default-frame-alist'
 > is set.

Thanks, I have to study that now.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-16  9:14                                                                                   ` martin rudalics
@ 2021-05-16  9:16                                                                                     ` Tassilo Horn
  2021-05-16 12:24                                                                                       ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-16  9:16 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>>>>> Is this behavior new or did it already occur in Emacs 27?
>>>>
>>>> Yes, with my repro.el containing the `default-frame-alist' setting,
>>>> the initial frame has a menubar (until resize/focus), and the new
>>>> frame after C-x 5 2 has a scrollbar.
>>>
>>> And with Emacs 27 the initial frame did not have a menu bar initially
>>> and the new frame after C-x 5 2 did not have a scroll bar initially.
>>> Right?
>>
>> No, what I've written above as answer to your question was with emacs
>> 27.2.
>
> So can I conclude that the bad behavior was already there with Emacs 27?

Yes.

> I really should try to ask questions in a less ambiguous way.

Or just remember, when you ask, I'll answer immediately below to exactly
that question.  When I switch context, I'll make that clear. :-)

>>> Did my latest commit (c18403302df3f07a7f94c3984d65b808fb40e8c1) in this
>>> area change anything in this regard?
>>
>> Nope, "emacs -Q --load repro.el" (including `default-frame-alist'
>> setting) still results in
>>
>>    1. initial frame has a menubar (fsh1.txt)
>>    2. C-x 5 2 frame has a scrollbar (fsh2.txt)
>>
>> When commenting the `default-frame-alist' setting, all works as expected
>> (fsh3.txt for the initial frame and fsh4.txt for the new one created by
>> C-x 5 2).
>>
>> When comparing fsh1 vs. fsh3, and fsh2 vs. fsh4, one can see that the
>> set_window_configuration calls are only there if `default-frame-alist'
>> is set.
>
> Thanks, I have to study that now.

Have fun (if possible).

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-16  9:16                                                                                     ` Tassilo Horn
@ 2021-05-16 12:24                                                                                       ` martin rudalics
  2021-05-16 19:08                                                                                         ` Tassilo Horn
  0 siblings, 1 reply; 65+ messages in thread
From: martin rudalics @ 2021-05-16 12:24 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 > Have fun (if possible).

At least the scroll bar mis-appearance has a simple explanation.  Try
with


(setq default-frame-alist '((width . 90)
                             (height . 50)))
(tool-bar-mode -1)
(menu-bar-mode -1)
(when (fboundp 'scroll-bar-mode)
   (scroll-bar-mode -1))
(when (fboundp 'horizontal-scroll-bar-mode)
   (horizontal-scroll-bar-mode -1))


I can't explain the menu bar mishap yet.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-16 12:24                                                                                       ` martin rudalics
@ 2021-05-16 19:08                                                                                         ` Tassilo Horn
  2021-05-17  7:33                                                                                           ` martin rudalics
  0 siblings, 1 reply; 65+ messages in thread
From: Tassilo Horn @ 2021-05-16 19:08 UTC (permalink / raw)
  To: martin rudalics; +Cc: Garjola Dindi, emacs-devel

martin rudalics <rudalics@gmx.at> writes:

>> Have fun (if possible).
>
> At least the scroll bar mis-appearance has a simple explanation.  Try
> with
>
> (setq default-frame-alist '((width . 90)
>                             (height . 50)))
> (tool-bar-mode -1)
> (menu-bar-mode -1)
> (when (fboundp 'scroll-bar-mode)
>   (scroll-bar-mode -1))
> (when (fboundp 'horizontal-scroll-bar-mode)
>   (horizontal-scroll-bar-mode -1))

Yes, with this order of settings the new frame after C-x 5 2 has no
scrollbar as it should.  I don't see a self-evident reason that I need
to set default-frame-alist before deactivating bars in my ~/.emacs, so I
guess you need to state that simple explanation explicitly.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: Proposing changes to adjust_frame_size
  2021-05-16 19:08                                                                                         ` Tassilo Horn
@ 2021-05-17  7:33                                                                                           ` martin rudalics
  0 siblings, 0 replies; 65+ messages in thread
From: martin rudalics @ 2021-05-17  7:33 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Garjola Dindi, emacs-devel

 >> At least the scroll bar mis-appearance has a simple explanation.  Try
 >> with
 >>
 >> (setq default-frame-alist '((width . 90)
 >>                              (height . 50)))
 >> (tool-bar-mode -1)
 >> (menu-bar-mode -1)
 >> (when (fboundp 'scroll-bar-mode)
 >>    (scroll-bar-mode -1))
 >> (when (fboundp 'horizontal-scroll-bar-mode)
 >>    (horizontal-scroll-bar-mode -1))
 >
 > Yes, with this order of settings the new frame after C-x 5 2 has no
 > scrollbar as it should.  I don't see a self-evident reason that I need
 > to set default-frame-alist before deactivating bars in my ~/.emacs, so I
 > guess you need to state that simple explanation explicitly.

Here we go: To fulfill its "This command applies to all frames that
exist and frames to be created in the future" obligation and because
`scroll-bar-mode-explicit' is by default t, `set-scroll-bar-mode' adds a
(vertical-scroll-bars) element to your `default-frame-alist' which,
however, gets annihilated by your later

(setq default-frame-alist '((width . 90)
                             (height . 50)))

so Emacs will use the default value (here 'right') when deciding whether
to put a scroll bar on your new frame and where.

If, however, you move the `default-frame-alist' setting in front of the
`scroll-bar-mode' toggling, the (vertical-scroll-bars) entry persists.

The situation with the menu bar is different because toggling
`menu-bar-mode' changes `default-frame-alist' only if the latter already
contains a `menu-bar-lines' entry.  In Fx_create_frame you can find

   gui_default_parameter (f, parms, Qmenu_bar_lines,
                          make_fixnum (NILP (Vmenu_bar_mode) ? 0 : 1),
                          NULL, NULL, RES_TYPE_NUMBER);

which makes a menu bar appear (or not appear) on a new frame respecting
the current value of `menu-bar-mode'.

So while the scroll bar behavior you reported is expected and can be
observed here too, the phenomenon of the vanishing menu bar is something
I can neither observe nor explain.

martin



^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2021-05-17  7:33 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-25 17:11 Proposing changes to adjust_frame_size martin rudalics
2021-04-27  8:22 ` martin rudalics
2021-04-27 14:16   ` Yuuki Harano
2021-05-02  8:46     ` martin rudalics
2021-05-02 11:21       ` Alan Third
2021-05-02 16:17         ` martin rudalics
2021-05-05  8:51       ` martin rudalics
2021-05-05 10:47         ` Yuuki Harano
2021-05-05 11:24           ` martin rudalics
2021-05-05 14:07             ` Yuuki Harano
2021-05-05 15:01               ` martin rudalics
2021-05-05 16:45                 ` martin rudalics
2021-05-05 18:54                   ` Tassilo Horn
2021-05-06  7:44                     ` martin rudalics
2021-05-06  7:59                       ` Tassilo Horn
2021-05-06  8:39                         ` martin rudalics
2021-05-06  8:49                           ` Tassilo Horn
2021-05-06 12:10                             ` martin rudalics
2021-05-06 12:31                               ` Tassilo Horn
2021-05-06 14:10                                 ` martin rudalics
2021-05-06 14:47                                   ` Tassilo Horn
2021-05-07  8:03                                     ` martin rudalics
2021-05-08  7:02                                       ` Tassilo Horn
2021-05-08  7:16                                         ` martin rudalics
2021-05-08 14:03                                           ` Tassilo Horn
2021-05-08 15:17                                             ` martin rudalics
2021-05-08 20:32                                               ` Tassilo Horn
2021-05-09  8:41                                                 ` martin rudalics
2021-05-09 10:09                                                   ` Garjola Dindi
2021-05-09 10:12                                                   ` Garjola Dindi
2021-05-09 18:48                                                   ` Tassilo Horn
2021-05-10  8:25                                                     ` martin rudalics
2021-05-10 12:27                                                       ` martin rudalics
2021-05-10 19:05                                                         ` Tassilo Horn
2021-05-10 19:21                                                           ` martin rudalics
2021-05-10 19:28                                                             ` Tassilo Horn
2021-05-11  8:29                                                               ` martin rudalics
2021-05-11  9:25                                                                 ` Tassilo Horn
2021-05-12  8:44                                                                   ` martin rudalics
2021-05-12 14:53                                                                     ` Tassilo Horn
2021-05-12 16:40                                                                       ` martin rudalics
2021-05-12 19:06                                                                         ` Tassilo Horn
2021-05-13  7:55                                                                           ` martin rudalics
2021-05-13  8:08                                                                             ` Tassilo Horn
2021-05-16  8:29                                                                               ` martin rudalics
2021-05-16  8:33                                                                                 ` Tassilo Horn
2021-05-16  9:14                                                                                   ` martin rudalics
2021-05-16  9:16                                                                                     ` Tassilo Horn
2021-05-16 12:24                                                                                       ` martin rudalics
2021-05-16 19:08                                                                                         ` Tassilo Horn
2021-05-17  7:33                                                                                           ` martin rudalics
2021-05-06 14:41                   ` Yuuki Harano
2021-05-09  9:32                     ` Yuuki Harano
2021-05-09 13:47                       ` martin rudalics
2021-05-09 15:30                         ` Yuuki Harano
2021-05-10  8:24                           ` martin rudalics
2021-05-10 13:18                             ` Yuuki Harano
2021-05-10 14:16                               ` martin rudalics
2021-05-10 15:41                                 ` Yuuki Harano
2021-05-10 19:20                                   ` martin rudalics
2021-05-11 14:32                                     ` Yuuki Harano
2021-05-12  8:47                                       ` martin rudalics
2021-05-13  8:48                                         ` Garjola Dindi
2021-05-01 18:59 ` Alan Third
2021-05-02  7:38   ` martin rudalics

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).