Subject: Re: bug#21415: 25.0.50; Emacs Trunk -- pixelwise width/height for x-create-frame

From: martin rudalics <[email-masked]>
Date: Thu, 10 Sep 2015 08:57:25 +0200

> The patch of `nsterm.m` has repaired much of the functionality of
 > `frame-inhibit-implied-resize`.  The two tests that previously failed
 > now work as expected:
 >
 >       1.  From a maximized frame, I can change the `font` to Courier
 >           18 using `set-face-attribute` and there is no need to set
 >           `frame-inhibit-implied-resize` in that circumstance.

I'm afraid that setting ‘frame-inhibit-implied-resize’ would't have
helped anyway in that case.

 >       2.  From a frame that is smaller than the screen size, I can use
 >           `set-face-attribute` to change the font to Courier 18
 >           provided that `frame-inhibit-implied-resize` is set to `t`.

OK.  Together with the two I sent earlier I attach one additional
change, this time for the tool bar.  You don't use it, so it shouldn't
affect you.  Nevertheless keep it included, it might have side effects.

 > The problem I am having is with a situation where
 > `ns-auto-hide-menu-bar` is set to `t`.  As previously noted in this
 > thread, the `top` frame parameter is ignored when making a new frame
 > that is the size of the screen -- the new frame appears substantially
 > above the top of the display -- i.e., one-half out of sight.  When the
 > new frame is partially above the top of the screen,
 > `set-face-attribute` substantially enlarges the frame even though
 > `frame-inhibit-implied-resize` is set to `t`.  When the frame comes
 > back into full view (e.g., top 0, left 0), it is then possible to
 > apply `set-face-attribute` without altering the dimensions of the
 > frame.  The following are two examples -- one example works, the other
 > example is broken -- both rely upon `ns-auto-hide-menu-bar` being set
 > to `t`.
 >
 > (setq ns-auto-hide-menu-bar t)
 >
 > ;; WORKS
 > (let* (
 >      (frame-inhibit-implied-resize t)
 >      (frame
 >        (make-frame '(
 >           (vertical-scroll-bars)
 >           (left-fringe . 8)
 >           (right-fringe . 8)
 >           (width . 1259.0)
 >           (height . 771.0)
 >           (tool-bar-lines . 0)))) )
 >    (set-frame-position frame 0 0)
 >    (set-face-attribute 'default frame :font "-*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1"))
 >
 > ;; BROKEN
 > (let* (
 >      (frame-inhibit-implied-resize t)
 >      (frame
 >        (make-frame '(
 >          (font . "-*-Courier-normal-normal-normal-*-18-*-*-*-m-0-iso10646-1")
 >          (vertical-scroll-bars)
 >          (left-fringe . 8)
 >          (right-fringe . 8)
 >          (width . 1259.0)
 >          (height . 771.0)
 >          (tool-bar-lines . 0)))) )
 >    (set-frame-position frame 0 0))

I have no idea what this small segment in nsterm.m

   if (ns_menu_bar_should_be_hidden ())
     return frameRect;

is meant to accomplish.  Try to comment it out and see what happens.  If
you see a difference, we'll have to look into it.

martin
diff --git a/src/frame.c b/src/frame.c
index 6debcb8..f0c76ca 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -4582,20 +4582,40 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
     {
       if (!EQ (width, Qunbound))
 	{
-	  CHECK_NUMBER (width);
-	  if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
-	    xsignal1 (Qargs_out_of_range, width);
+	  if (FLOATP (width))
+	    {
+	      if (XFLOAT_DATA (width) < 0 || (int) XFLOAT_DATA (width) > INT_MAX)
+		xsignal1 (Qargs_out_of_range, width);
+	      else
+		SET_FRAME_WIDTH (f, (int) XFLOAT_DATA (width));
+	    }
+	  else
+	    {
+	      CHECK_NUMBER (width);
+	      if (! (0 <= XINT (width) && XINT (width) <= INT_MAX))
+		xsignal1 (Qargs_out_of_range, width);

-	  SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
+	      SET_FRAME_WIDTH (f, XINT (width) * FRAME_COLUMN_WIDTH (f));
+	    }
 	}

       if (!EQ (height, Qunbound))
 	{
-	  CHECK_NUMBER (height);
-	  if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
-	    xsignal1 (Qargs_out_of_range, height);
+	  if (FLOATP (height))
+	    {
+	      if (XFLOAT_DATA (height) < 0 || (int) XFLOAT_DATA (height) > INT_MAX)
+		xsignal1 (Qargs_out_of_range, height);
+	      else
+		SET_FRAME_HEIGHT (f, (int) XFLOAT_DATA (height));
+	    }
+	  else
+	    {
+	      CHECK_NUMBER (height);
+	      if (! (0 <= XINT (height) && XINT (height) <= INT_MAX))
+		xsignal1 (Qargs_out_of_range, height);

-	  SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
+	      SET_FRAME_HEIGHT (f, XINT (height) * FRAME_LINE_HEIGHT (f));
+	    }
 	}

       user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
diff --git a/src/nsfns.m b/src/nsfns.m
index 89b9f7c..4cb33be 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -679,7 +679,8 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
         }
     }

-  x_set_window_size (f, 0, f->text_cols, f->text_lines, 0);
+  frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
+  adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
 }

diff --git a/src/nsterm.m b/src/nsterm.m
index 2806f31..360e831 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7738,8 +7738,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)

   /* Now make the frame display the given font.  */
   if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
-    x_set_window_size (f, false, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
-                       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), true);
+    adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+		       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
+		       false, Qfont);

   return font_object;
 }