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

From: martin rudalics <[email-masked]>
Date: Sat, 05 Sep 2015 11:59:00 +0200

> In my opinion, it would be useful to set the frame specifications
 > exactly at the time of creation -- rather than fix it after the fact
 > with `set-frame-size` using the pixelwise argument.

Agreed.

 > My particular immediate use case is to simply fill the screen exactly
 > (on OSX, XP, and Windows 7).  In my testing, `toggle-frame-maximized`
 > was never as accurate as `set-frame-size` using the pixelwise
 > argument.

I was afraid that would be your concern.  ‘toggle-frame-maximized’
should work precisely.  Can you provide me more details wrt how it
doesn't achieve its goal?

 > I would imagine there are other situations where a user may
 > wish to create a frame with exact specifications to fit precisely into
 > a specific location on the screen, without the need to fix it after
 > the fact.

Basically a tiling window manager should do that.  But I'm not against
providing such a service.

 > I have a test that identifies the current operating system and screen
 > sizes on my different machines, and I have already determined exactly
 > how many Emacs frame pixels fill the screen based on other factors
 > such as font, fringe widths, no scroll bars, and no menu-bar.

The problem is that with Emacs it's pretty hard to do that reliably.
Knowing the exact sizes of each and every component on the various
platforms is a pain.  For example, I doubt that you are able to
calculate the height of your tool bar beforehand - I never was.  Or, do
you know the size of the external border of a frame on OS X?

I try to address most of these in the function ‘frame-geometry’.  Does
that return good results on OS X?  Also note that you have to subtract
one default scroll bar width/height, the fringe widths and the internal
border width in order to convert the frame's outer width (the one you
see on the screen) to its native width (the one you set via frame
parameters).

 > The
 > general approach has been to take the initial frame or subsequently
 > created frames and use `set-frame-size` with the pixelwise argument to
 > blow it up to the preferred size.  It sure would be nice, however, to
 > set the pixel width/height along with the other frame parameters both
 > programmatically (passing as parameters to `make-frame`), and as part
 > of the `initial-frame-alist` and `default-frame-alist`.

OK.

 > I don't fully understand the floating point because the pixels are
 > whole numbers, rather than decimals -- this is probably because I'm
 > just a hobbyist, not a real programmer.  But yes, a frame-parameter
 > for pixel width and pixel height would be awesome.

You would simply specify something like (height . 100.0) to get a 100
pixels high frame instead of (height . 6) to get a 6 columns high frame.
The advantage of the floating point idea over a separate ‘pixel-width’ /
‘pixel-height’ approach would be twofold:

(1) Technically, Emacs wouldn't have to care about whether a ‘width’
entry in ‘initial-frame-alist’ should override a ‘pixel-width’ entry in
‘default-frame-alist’.

(2) The user doesn't have to investigate these lists to check for the
presence of another entry.

I attach a simple patch based on this kludge so if you can build Emacs
you can try it with something like

(make-frame '((width . 400.0) (height . 200.0)))

 > Last weekend, I learned how to build Emacs from any point in time
 > based on a particular commit; and, I also learned the layman's way to
 > download prebuilt nightlies from http://emacsformacosx.com/ I'd be
 > happy to work on pinpointing when the intermittent flickering began,
 > and will spend a little time on that project each day.

That would be fine.

Thanks, martin
diff --git a/src/frame.c b/src/frame.c
index 4a526e2..bac2b24 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -537,6 +537,8 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
 	}
 #endif
     }
+  else if (new_cols != old_cols)
+    call2 (Qwindow_pixel_to_total, frame, Qt);
 
   if (new_windows_height != old_windows_height
       /* When the top margin has changed we have to recalculate the top
@@ -551,6 +553,8 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
       if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
 	FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
     }
+  else if (new_lines != old_lines)
+    call2 (Qwindow_pixel_to_total, frame, Qnil);
 
   frame_size_history_add
     (f, Qadjust_frame_size_3, new_text_width, new_text_height,
@@ -4831,6 +4835,7 @@ syms_of_frame (void)
   DEFSYM (Qframep, "framep");
   DEFSYM (Qframe_live_p, "frame-live-p");
   DEFSYM (Qframe_windows_min_size, "frame-windows-min-size");
+  DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
   DEFSYM (Qexplicit_name, "explicit-name");
   DEFSYM (Qheight, "height");
   DEFSYM (Qicon, "icon");