]> code.delx.au - gnu-emacs/blobdiff - src/window.c
(Veven_window_heights): New variable.
[gnu-emacs] / src / window.c
index d3386c31a2a85d5ab3c1e6ba4a57d0e7670fb032..903688e2caacec32b391dd69c8d1c88bc5a54d52 100644 (file)
@@ -1,6 +1,7 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000 Free Software Foundation, Inc.
+   Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000
+   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -142,6 +143,10 @@ Lisp_Object Vpop_up_frame_function;
 
 Lisp_Object Vdisplay_buffer_function;
 
+/* Non-nil means that Fdisplay_buffer should even the heights of windows.  */
+
+Lisp_Object Veven_window_heights;
+
 /* List of buffer *names* for buffers that should have their own frames.  */
 
 Lisp_Object Vspecial_display_buffer_names;
@@ -495,6 +500,11 @@ coordinates_in_window (w, x, y)
   int left_x, right_x, top_y, bottom_y;
   int flags_area_width = FRAME_LEFT_FLAGS_AREA_WIDTH (f);
 
+  /* Let's make this a global enum later, instead of using numbers
+     everywhere.  */
+  enum {ON_NOTHING, ON_TEXT, ON_MODE_LINE, ON_VERTICAL_BORDER,
+       ON_HEADER_LINE, ON_LEFT_FRINGE, ON_RIGHT_FRINGE};
+
   /* In what's below, we subtract 1 when computing right_x because we
      want the rightmost pixel, which is given by left_pixel+width-1.  */
   if (w->pseudo_window_p)
@@ -514,6 +524,7 @@ coordinates_in_window (w, x, y)
       bottom_y = WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w);
     }
 
+  /* Completely outside anything interesting?  */
   if (*y < top_y
       || *y >= bottom_y
       || *x < (left_x
@@ -521,42 +532,83 @@ coordinates_in_window (w, x, y)
               - (FRAME_LEFT_SCROLL_BAR_WIDTH (f)
                  * CANON_X_UNIT (f)))
       || *x > right_x + flags_area_width)
-    /* Completely outside anything interesting.  */
-    return 0;
-  else if (WINDOW_WANTS_MODELINE_P (w)
-          && *y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w))
-    /* On the mode line.  */
-    return 2;
-  else if (WINDOW_WANTS_HEADER_LINE_P (w)
-          && *y < top_y + CURRENT_HEADER_LINE_HEIGHT (w))
-    /* On the top line.  */
-    return 4;
-  /* Need to say "*x > right_x" rather than >=, since on character
-     terminals, the vertical line's x coordinate is right_x.  */
-  else if (*x < left_x || *x > right_x)
+    return ON_NOTHING;
+  
+  /* On the mode line or header line?  If it's near the start of
+     the mode or header line of window that's has a horizontal
+     sibling, say it's on the vertical line.  That's to be able
+     to resize windows horizontally in case we're using toolkit
+     scroll bars.  */
+  
+  if (WINDOW_WANTS_MODELINE_P (w)
+      && *y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w))
+    {
+      if (!WINDOW_RIGHTMOST_P (w)
+         && (abs (*x - ((XFASTINT (w->left) + XFASTINT (w->width))
+                        * CANON_X_UNIT (f)))
+             < CANON_X_UNIT (f) / 2))
+       return ON_VERTICAL_BORDER;
+      return ON_MODE_LINE;
+    }
+  
+  if (WINDOW_WANTS_HEADER_LINE_P (w)
+      && *y < top_y + CURRENT_HEADER_LINE_HEIGHT (w))
+    {
+      if (!WINDOW_RIGHTMOST_P (w)
+         && (abs (*x - ((XFASTINT (w->left) + XFASTINT (w->width))
+                        * CANON_X_UNIT (f)))
+             < CANON_X_UNIT (f) / 2))
+       return ON_VERTICAL_BORDER;
+      return ON_HEADER_LINE;
+    }
+
+  if (FRAME_WINDOW_P (f))
     {
-      /* Other lines than the mode line don't include flags areas and
-        scroll bars on the left.  */
+      if (!w->pseudo_window_p
+         && !FRAME_HAS_VERTICAL_SCROLL_BARS (f)
+         && !WINDOW_RIGHTMOST_P (w)
+         && (abs (*x - right_x - flags_area_width) < CANON_X_UNIT (f) / 2))
+       return ON_VERTICAL_BORDER;
+
+      if (*x < left_x || *x > right_x)
+       {
+         /* Other lines than the mode line don't include flags areas and
+            scroll bars on the left.  */
       
-      /* Convert X and Y to window-relative pixel coordinates.  */
-      *x -= left_x;
-      *y -= top_y;
-      return *x < left_x ? 5 : 6;
+         /* Convert X and Y to window-relative pixel coordinates.  */
+         *x -= left_x;
+         *y -= top_y;
+         return *x < left_x ? ON_LEFT_FRINGE : ON_RIGHT_FRINGE;
+       }
     }
-  /* Here, too, "*x > right_x" is because of character terminals.  */
-  else if (!w->pseudo_window_p
-          && !WINDOW_RIGHTMOST_P (w)
-          && *x > right_x - CANON_X_UNIT (f))
-    /* On the border on the right side of the window?  Assume that
-       this area begins at RIGHT_X minus a canonical char width.  */
-    return 3;
   else
     {
-      /* Convert X and Y to window-relative pixel coordinates.  */
-      *x -= left_x;
-      *y -= top_y;
-      return 1;
+      /* Need to say "*x > right_x" rather than >=, since on character
+        terminals, the vertical line's x coordinate is right_x.  */
+      if (*x < left_x || *x > right_x)
+       {
+         /* Other lines than the mode line don't include flags areas and
+            scroll bars on the left.  */
+      
+         /* Convert X and Y to window-relative pixel coordinates.  */
+         *x -= left_x;
+         *y -= top_y;
+         return *x < left_x ? ON_LEFT_FRINGE : ON_RIGHT_FRINGE;
+       }
+  
+      /* Here, too, "*x > right_x" is because of character terminals.  */
+      if (!w->pseudo_window_p
+         && !WINDOW_RIGHTMOST_P (w)
+         && *x > right_x - CANON_X_UNIT (f))
+       /* On the border on the right side of the window?  Assume that
+          this area begins at RIGHT_X minus a canonical char width.  */
+       return ON_VERTICAL_BORDER;
     }
+  
+  /* Convert X and Y to window-relative pixel coordinates.  */
+  *x -= left_x;
+  *y -= top_y;
+  return ON_TEXT;
 }
 
 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
@@ -2796,7 +2848,11 @@ If FRAME is a frame, search only that frame.\n\
 If FRAME is nil, search only the selected frame\n\
  (actually the last nonminibuffer frame),\n\
  unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,\n\
- which means search visible and iconified frames.")
+ which means search visible and iconified frames.\n\
+\n\
+If `even-window-heights' is non-nil, window heights will be evened out\n\
+if displaying the buffer causes two vertically\ adjacent windows to be\n\
+displayed.")
   (buffer, not_this_window, frame)
      register Lisp_Object buffer, not_this_window, frame;
 {
@@ -2945,6 +3001,7 @@ If FRAME is nil, search only the selected frame\n\
          if (!NILP (XWINDOW (window)->next))
            other = lower = XWINDOW (window)->next, upper = window;
          if (!NILP (other)
+             && !NILP (Veven_window_heights)
              /* Check that OTHER and WINDOW are vertically arrayed.  */
              && !EQ (XWINDOW (other)->top, XWINDOW (window)->top)
              && (XFASTINT (XWINDOW (other)->height)
@@ -4465,8 +4522,9 @@ struct saved_window
     Lisp_Object parent, prev;
     Lisp_Object start_at_line_beg;
     Lisp_Object display_table;
+    Lisp_Object orig_top, orig_height;
   };
-#define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
+#define SAVED_WINDOW_VECTOR_SIZE 16 /* Arg to Fmake_vector */
 
 #define SAVED_WINDOW_N(swv,n) \
   ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
@@ -4658,6 +4716,8 @@ the return value is nil.  Otherwise the value is t.")
          w->height = p->height;
          w->hscroll = p->hscroll;
          w->display_table = p->display_table;
+         w->orig_top = p->orig_top;
+         w->orig_height = p->orig_height;
          XSETFASTINT (w->last_modified, 0);
          XSETFASTINT (w->last_overlay_modified, 0);
 
@@ -4923,6 +4983,8 @@ save_window_save (window, vector, i)
       p->height = w->height;
       p->hscroll = w->hscroll;
       p->display_table = w->display_table;
+      p->orig_top = w->orig_top;
+      p->orig_height = w->orig_height;
       if (!NILP (w->buffer))
        {
          /* Save w's value of point in the window configuration.
@@ -5020,8 +5082,7 @@ redirection (see `redirect-frame-focus').")
   for (i = 0; i < n_windows; i++)
     XVECTOR (tem)->contents[i]
       = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE), Qnil);
-  save_window_save (FRAME_ROOT_WINDOW (f),
-                   XVECTOR (tem), 0);
+  save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
   XSETWINDOW_CONFIGURATION (tem, data);
   return (tem);
 }
@@ -5440,6 +5501,11 @@ Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
 work using this function.");
   Vdisplay_buffer_function = Qnil;
 
+  DEFVAR_LISP ("even-window-heights", &Veven_window_heights,
+    "*If non-nil, `display-buffer' should even the window heights.\n\
+If nil, `display-buffer' will leave the window configuation alone.");
+  Veven_window_heights = Qt;
+
   DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window,
     "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
   Vminibuf_scroll_window = Qnil;