diff src/window.c @ 343:8bec6624d99b r21-1-1

Import from CVS: tag r21-1-1
author cvs
date Mon, 13 Aug 2007 10:52:53 +0200
parents 19dcec799385
children 7c94d56991e1
line wrap: on
line diff
--- a/src/window.c	Mon Aug 13 10:52:06 2007 +0200
+++ b/src/window.c	Mon Aug 13 10:52:53 2007 +0200
@@ -4621,8 +4621,8 @@
 struct window_config
 {
   struct lcrecord_header header;
-  int frame_width;
-  int frame_height;
+  /*  int frame_width; No longer needed, JV
+      int frame_height; */
 #if 0 /* FSFmacs */
   Lisp_Object selected_frame;
 #endif
@@ -4630,6 +4630,7 @@
   Lisp_Object current_buffer;
   Lisp_Object minibuffer_scroll_window;
   Lisp_Object root_window;
+  int minibuf_height; /* 0 = no minibuffer, <0, size in lines, >0 in pixels */
   /* Record the values of window-min-width and window-min-height
      so that window sizes remain consistent with them.  */
   int min_width, min_height;
@@ -4761,9 +4762,10 @@
 	EQ (fig1->current_window,	    fig2->current_window) &&
 	EQ (fig1->current_buffer,	    fig2->current_buffer) &&
 	EQ (fig1->root_window,		    fig2->root_window) &&
-	EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window) &&
+	EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window)))
+	/* &&
 	fig1->frame_width  == fig2->frame_width &&
-	fig1->frame_height == fig2->frame_height))
+	fig1->frame_height == fig2->frame_height)) */
     return 0;
 
   for (i = 0; i < fig1->saved_windows_count; i++)
@@ -4859,8 +4861,15 @@
   struct frame *f;
   struct gcpro gcpro1;
   Lisp_Object old_window_config;
-  int previous_frame_height;
-  int previous_frame_width;
+  /*  int previous_frame_height;
+      int previous_frame_width;*/
+  int previous_pixel_top;
+  int previous_pixel_height;
+  int previous_pixel_left;
+  int previous_pixel_width;
+  int previous_minibuf_height, previous_minibuf_top,previous_minibuf_width;
+  int real_font_height;
+  int converted_minibuf_height,target_minibuf_height; 
   int specpdl_count = specpdl_depth ();
 
   GCPRO1 (configuration);
@@ -4925,6 +4934,20 @@
 
       mark_windows_in_use (f, 1);
 
+#if 0
+      /* JV: This is bogus,
+	 First of all, the units are inconsistent. The frame sizes are measured
+	 in characters but the window sizes are stored in pixels. So if a 
+	 font size change happened between saving and restoring, the
+	 frame "sizes" maybe equal but the windows still should be
+	 resized. This is tickled alot by the new "character size
+	 stays constant" policy in 21.0. It leads to very wierd
+	 glitches (and possibly craches when asserts are tickled).
+
+	 Just changing the units doens't help because changing the
+	 toolbar configuration can also change the pixel positions.
+	 Luckily there is a much simpler way of doing this, see below.
+       */
       previous_frame_width = FRAME_WIDTH (f);
       previous_frame_height = FRAME_HEIGHT (f);
       /* If the frame has been resized since this window configuration was
@@ -4934,7 +4957,37 @@
       if (config->frame_height != FRAME_HEIGHT (f)
 	  || config->frame_width != FRAME_WIDTH (f))
 	change_frame_size (f, config->frame_height, config->frame_width, 0);
-
+#endif
+      
+      previous_pixel_top = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top;
+      previous_pixel_height = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_height;
+      previous_pixel_left = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left;
+      previous_pixel_width = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_width;
+
+      /* remember some properties of the minibuffer */
+
+      default_face_height_and_width (frame, &real_font_height, 0);
+      assert(real_font_height > 0);
+  
+      if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
+	{
+	  previous_minibuf_height
+	    = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
+	  previous_minibuf_top
+	    = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_top;
+	  previous_minibuf_width
+	    = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_width;
+	}
+      else
+	{
+	  previous_minibuf_height = 0;
+	  previous_minibuf_width = 0;
+	}
+      converted_minibuf_height =
+	(previous_minibuf_height % real_font_height) == 0 ?
+	- (previous_minibuf_height / real_font_height ) :    /* lines */
+	    previous_minibuf_height;   /* pixels */
+           
       /* Temporarily avoid any problems with windows that are smaller
 	 than they are supposed to be.  */
       window_min_height = 1;
@@ -5100,11 +5153,61 @@
 	 currently selected, or just set the selected window of the
 	 window config's frame. */
 
+#if 0
       /* Set the frame height to the value it had before this function.  */
       if (previous_frame_height != FRAME_HEIGHT (f)
 	  || previous_frame_width != FRAME_WIDTH (f))
 	change_frame_size (f, previous_frame_height, previous_frame_width, 0);
-
+#endif
+      /* We just reset the size and position of the minibuffer, to its old
+	 value, which needn't be valid. So we do some magic to see which value
+	 to actually take. Then we set it.
+
+	 The magic:
+	 We take the old value if is in the same units but differs from the
+	 current value.
+
+         #### Now we get more cases correct then ever before, but
+	 are we treating all? For instance what if the frames minibuf window
+	 is no longer the same one? 
+      */
+      target_minibuf_height = previous_minibuf_height;
+      if (converted_minibuf_height &&
+	  (converted_minibuf_height * config->minibuf_height) > 0 &&
+	  (converted_minibuf_height !=  config->minibuf_height))
+	{
+	  target_minibuf_height = config->minibuf_height < 0 ?
+	    - (config->minibuf_height * real_font_height) :
+	    config->minibuf_height;
+	  target_minibuf_height =
+	    max(target_minibuf_height,real_font_height);
+	}
+      if (previous_minibuf_height)
+	{
+	  XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top
+	    = previous_minibuf_top -
+	          (target_minibuf_height - previous_minibuf_height);
+	  set_window_pixheight (FRAME_MINIBUF_WINDOW (f),
+				target_minibuf_height, 0);
+	  set_window_pixwidth  (FRAME_MINIBUF_WINDOW (f),
+			    previous_minibuf_width, 0);
+	}
+	
+      /* This is a better way to deal with frame resizing, etc.
+	 What we _actually_ want is for the old (just restored)
+	 root window to fit
+	 into the place of the new one. So we just do that. Simple! */
+      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = previous_pixel_top;
+      /* Note that this function also updates the subwindow
+	 "pixel_top"s */
+      set_window_pixheight (FRAME_ROOT_WINDOW (f),
+	  previous_pixel_height -
+		  (target_minibuf_height - previous_minibuf_height), 0);
+      XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = previous_pixel_left;
+      /* Note that this function also updates the subwindow
+	 "pixel_left"s */
+      set_window_pixwidth (FRAME_ROOT_WINDOW (f), previous_pixel_width, 0);
+      
       /* If restoring in the current frame make the window current,
 	 otherwise just update the frame selected_window slot to be
 	 the restored current_window. */
@@ -5319,6 +5422,8 @@
   struct frame *f = decode_frame (frame);
   struct window_config *config;
   int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
+  int minibuf_height;
+  int real_font_height;
 
   if (n_windows <= countof (Vwindow_configuration_free_list))
     config = XWINDOW_CONFIGURATION (allocate_managed_lcrecord
@@ -5330,9 +5435,9 @@
       alloc_lcrecord (sizeof_window_config_for_n_windows (n_windows),
 		      lrecord_window_configuration);
   XSETWINDOW_CONFIGURATION (result, config);
-
+  /*
   config->frame_width = FRAME_WIDTH (f);
-  config->frame_height = FRAME_HEIGHT (f);
+  config->frame_height = FRAME_HEIGHT (f); */
   config->current_window = FRAME_SELECTED_WINDOW (f);
   XSETBUFFER (config->current_buffer, current_buffer);
   config->minibuffer_scroll_window = Vminibuffer_scroll_window;
@@ -5341,6 +5446,22 @@
   config->min_width = window_min_width;
   config->saved_windows_count = n_windows;
   save_window_save (FRAME_ROOT_WINDOW (f), config, 0);
+
+  /* save the minibuffer height using the heuristics from
+     change_frame_size_1 */
+  
+  XSETFRAME (frame, f); /* frame could have been nil ! */
+  default_face_height_and_width (frame, &real_font_height, 0);
+  assert(real_font_height > 0);
+  
+  if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
+    minibuf_height = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
+  else
+    minibuf_height = 0;
+  config->minibuf_height = (minibuf_height % real_font_height) == 0 ?
+    - (minibuf_height / real_font_height ) :    /* lines */
+    minibuf_height;   /* pixels */
+
   return result;
 }