Subject: bug#2401: 23.0.90; set-frame-width does not take effect immediately?

From: YAMAMOTO Mitsuharu <[email-masked]>
Date: Sun, 03 May 2009 16:07:23 +0900

>>>>> On Thu, 19 Feb 2009 23:05:53 -0500 (EST), Alex Khesin <[email-masked]> said:

> Consider the following function
> (defun test-split-window ()
>   (interactive)
>   (delete-other-windows)
>   (set-frame-width (selected-frame) 80)
>   (set-frame-width (selected-frame) 163)
>   (split-window-horizontally -80))

> Up to about a month ago, CVS emacs used to end up with a frame
> containing two 80-characters-wide windows after executing
> test-split-window.  I updated to the latest CVS earlier today, and I
> now get one of two behaviors: either the frame is made 80 wide but
> split in two, or the frame becomes 163 wide, but not split at all,
> with "Window width 0 (after splitting)" error message.  Adding short
> sleeps after set-frame-width fixes it:

> (defun test-split-window ()
>   (interactive)
>   (delete-other-windows)
>   (set-frame-width (selected-frame) 80)
>   (sleep-for 0 500)
>   (set-frame-width (selected-frame) 163)
>   (sleep-for 0 500)
>   (split-window-horizontally -80))

> Executing the set-frame-window and split-window-horizontally by
> hand, one after another, also has the desirable effect.

> It looks like set-frame-width does not take effect immediately anymore.

This seems to be related to Bug#2980(*1) and both can only be
observable with GTK+ frames for me.  Below is my experimental change
for Bug#2980, and it is included in an (also experimental) GTK+ print
dialog support (*2).  Because the printing support measures page
boundary with pos-visible-in-window-p in an invisible frame, it needs
to know its size before receiving ConfigureNotify and calling
xg_frame_resized.

As far as I tested, this patch also works for this bug.

*1: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=2980
*2: http://lists.gnu.org/archive/html/emacs-devel/2009-04/msg00390.html

				     YAMAMOTO Mitsuharu
				[email-masked]

RCS file: /cvsroot/emacs/emacs/src/gtkutil.c,v
retrieving revision 1.150
diff -c -p -r1.150 gtkutil.c
*** src/gtkutil.c	19 Apr 2009 10:53:19 -0000	1.150
--- src/gtkutil.c	3 May 2009 06:40:58 -0000
*************** xg_frame_set_char_size (f, cols, rows)
*** 736,741 ****
--- 736,767 ----
    x_wm_size_hint_off (f);
    gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
                       pixelwidth, pixelheight);
+ 
+ #if 1  /* XXX: experimental change for Bug#2980 */
+   /* Now, strictly speaking, we can't be sure that this is accurate,
+      but the window manager will get around to dealing with the size
+      change request eventually, and we'll hear how it went when the
+      ConfigureNotify event gets here.
+ 
+      We could just not bother storing any of this information here,
+      and let the ConfigureNotify event set everything up, but that
+      might be kind of confusing to the Lisp code, since size changes
+      wouldn't be reported in the frame parameters until some random
+      point in the future when the ConfigureNotify event arrives.
+ 
+      We pass 1 for DELAY since we can't run Lisp code inside of
+      a BLOCK_INPUT.  */
+   change_frame_size (f, rows, cols, 0, 1, 0);
+   FRAME_PIXEL_WIDTH (f) = pixelwidth;
+   FRAME_PIXEL_HEIGHT (f) = pixelheight;
+ 
+   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
+      receive in the ConfigureNotify event; if we get what we asked
+      for, then the event won't cause the screen to become garbaged, so
+      we have to make sure to do it here.  */
+   SET_FRAME_GARBAGED (f);
+ #endif
+ 
    flush_and_sync (f);
    x_wm_set_size_hint (f, 0, 0);
  }