]> code.delx.au - gnu-emacs/blobdiff - src/window.c
(change_frame_size): Handle FRAME_MENU_BAR_LINES.
[gnu-emacs] / src / window.c
index df8bd81bb4be989ae35a6e3f54f642ec7275b04c..ab81e806aba477e953f2b24aea0f187ad14b0663 100644 (file)
@@ -1,6 +1,6 @@
 /* Window creation, deletion and examination for GNU Emacs.
    Does not include redisplay.
-   Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -60,9 +60,6 @@ Lisp_Object Vminibuf_scroll_window;
 /* Non-nil means this is the buffer whose window C-M-v should scroll.  */
 Lisp_Object Vother_window_scroll_buffer;
 
-/* Window that the mouse is over (nil if no mouse support).  */
-Lisp_Object Vmouse_window;
-
 /* Last mouse click data structure (nil if no mouse support).  */
 Lisp_Object Vmouse_event;
 
@@ -225,9 +222,7 @@ POS defaults to point; WINDOW, to the selected window.")
 
       /* If that info is not correct, calculate afresh */
       posval = *compute_motion (top, 0, 0, posint, height, 0,
-                               XFASTINT (w->width) - 1
-                               - (XFASTINT (w->width) + XFASTINT (w->left)
-                                  != FRAME_WIDTH (XFRAME (w->frame))),
+                               window_internal_width (w) - 1,
                                XINT (w->hscroll), 0);
 
       return posval.vpos < height ? Qt : Qnil;
@@ -269,11 +264,7 @@ DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0,
   register struct window *w = decode_window (window);
   register int width = XFASTINT (w->width);
 
-  /* If this window does not end at the right margin,
-     must deduct one column for the border */
-  if ((width + XFASTINT (w->left)) == FRAME_WIDTH (XFRAME (WINDOW_FRAME (w))))
-    return make_number (width);
-  return make_number (width - 1);
+  return make_number (window_internal_width (w));
 }
 
 DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -433,12 +424,12 @@ window_from_coordinates (frame, x, y, part)
 }
 
 DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0,
-  "Return window containing row ROW, column COLUMN on FRAME.\n\
+  "Return window containing coordinates X and Y on FRAME.\n\
 If omitted, FRAME defaults to the currently selected frame.\n\
 The top left corner of the frame is considered to be row 0,\n\
 column 0.")
-  (row, column, frame)
-      Lisp_Object row, column, frame;
+  (x, y, frame)
+      Lisp_Object x, y, frame;
 {
   int part;
 
@@ -448,11 +439,11 @@ column 0.")
   else
     CHECK_LIVE_FRAME (frame, 2);
 #endif
-  CHECK_NUMBER (row, 0);
-  CHECK_NUMBER (column, 1);
+  CHECK_NUMBER (x, 0);
+  CHECK_NUMBER (y, 1);
 
   return window_from_coordinates (XFRAME (frame),
-                                 XINT (row), XINT (column),
+                                 XINT (x), XINT (y),
                                  &part);
 }
 
@@ -817,7 +808,12 @@ minibuffer does not count, only windows from WINDOW's frame count.\n\
 \n\
 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
-above.  If neither nil nor t, restrict to WINDOW's frame.")
+above.  If neither nil nor t, restrict to WINDOW's frame.\n\
+\n\
+If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
+`next-window' to iterate through the entire cycle of acceptable\n\
+windows, eventually ending up back at the window you started with.\n\
+`previous-window' traverses the same cycle, in the reverse order.")
   (window, minibuf, all_frames)
      register Lisp_Object window, minibuf, all_frames;
 {
@@ -914,7 +910,12 @@ count.\n\
 \n\
 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
-above.  If neither nil nor t, restrict to WINDOW's frame.")
+above.  If neither nil nor t, restrict to WINDOW's frame.\n\
+\n\
+If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
+`previous-window' to iterate through the entire cycle of acceptable\n\
+windows, eventually ending up back at the window you started with.\n\
+`next-window' traverses the same cycle, in the reverse order.")
   (window, minibuf, all_frames)
      register Lisp_Object window, minibuf, all_frames;
 {
@@ -961,7 +962,16 @@ above.  If neither nil nor t, restrict to WINDOW's frame.")
            tem = WINDOW_FRAME (XWINDOW (window));
 #ifdef MULTI_FRAME
            if (! NILP (all_frames))
-             tem = next_frame (tem, all_frames);
+             /* It's actually important that we use prev_frame here,
+                rather than next_frame.  All the windows acceptable
+                according to the given parameters should form a ring;
+                Fnext_window and Fprevious_window should go back and
+                forth around the ring.  If we use next_frame here,
+                then Fnext_window and Fprevious_window take different
+                paths through the set of acceptable windows.
+                window_loop assumes that these `ring' requirement are
+                met.  */
+             tem = prev_frame (tem, all_frames);
 #endif
            tem = FRAME_ROOT_WINDOW (XFRAME (tem));
 
@@ -1591,7 +1601,7 @@ DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 2,
 BUFFER can be a buffer or a buffer name.\n\
 If BUFFER is shown already in some window, just use that one,\n\
 unless the window is the selected window and the optional second\n\
-argument NOT_THIS_WINDOW is non-nil.\n\
+argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
 Returns the window displaying BUFFER.")
   (buffer, not_this_window)
      register Lisp_Object buffer, not_this_window;
@@ -1648,9 +1658,8 @@ Returns the window displaying BUFFER.")
 
       if (!NILP (window)
          && window_height (window) >= split_height_threshold
-         &&
-         (XFASTINT (XWINDOW (window)->width)
-          == FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (window))))))
+         && (XFASTINT (XWINDOW (window)->width)
+             == FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (window))))))
        window = Fsplit_window (window, Qnil, Qnil);
       else
        {
@@ -2027,6 +2036,36 @@ window_internal_height (w)
   return ht;
 }
 
+
+/* Return the number of columns in W.
+   Don't count columns occupied by scroll bars or the vertical bar
+   separating W from the sibling to its right.  */
+int
+window_internal_width (w)
+     struct window *w;
+{
+  FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
+  int left = XINT (w->left);
+  int width = XINT (w->width);
+
+  /* If this window is flush against the right edge of the frame, its
+     internal width is its full width.  */
+  if (left + width >= FRAME_WIDTH (f))
+    return width;
+
+  /* If we are not flush right, then our rightmost columns are
+     occupied by some sort of separator.  */
+
+  /* Scroll bars occupy a few columns.  */
+  if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+    return width - VERTICAL_SCROLL_BAR_WIDTH;
+
+  /* The column of `|' characters separating side-by-side windows
+     occupies one column only.  */
+  return width - 1;
+}
+
+
 /* Scroll contents of window WINDOW up N lines.  */
 
 void
@@ -2182,8 +2221,20 @@ showing that buffer, popping the buffer up if necessary.")
        window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt);
     }
   else
-    /* Nothing specified; pick a neighboring window.  */
-    window = Fnext_window (selected_window, Qnil, Qt);
+    {
+      /* Nothing specified; look for a neighboring window on the same
+        frame.  */
+      window = Fnext_window (selected_window, Qnil, Qnil);
+
+      if (EQ (window, selected_window))
+       /* That didn't get us anywhere; look for a window on another
+           visible frame.  */
+       do
+         window = Fnext_window (window, Qnil, Qt);
+       while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window))))
+              && ! EQ (window, selected_window));
+    }
+
   CHECK_LIVE_WINDOW (window, 0);
 
   if (EQ (window, selected_window))
@@ -2211,7 +2262,7 @@ showing that buffer, popping the buffer up if necessary.")
     }
 
   Fset_marker (w->pointm, make_number (point), Qnil);
-  unbind_to (count);
+  unbind_to (count, Qnil);
 
   return Qnil;
 }
@@ -2224,7 +2275,7 @@ Default for ARG is window width minus 2.")
 {
 
   if (NILP (arg))
-    XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2;
+    XFASTINT (arg) = window_internal_width (XWINDOW (selected_window)) - 2;
   else
     arg = Fprefix_numeric_value (arg);
 
@@ -2241,7 +2292,7 @@ Default for ARG is window width minus 2.")
      register Lisp_Object arg;
 {
   if (NILP (arg))
-    XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2;
+    XFASTINT (arg) = window_internal_width (XWINDOW (selected_window)) - 2;
   else
     arg = Fprefix_numeric_value (arg);
 
@@ -2553,7 +2604,10 @@ by `current-window-configuration' (which see).")
       Fselect_window (data->current_window);
 
 #ifdef MULTI_FRAME
-      Fredirect_frame_focus (frame, data->focus_frame);
+      if (NILP (data->focus_frame)
+         || (XTYPE (data->focus_frame) == Lisp_Frame
+             && FRAME_LIVE_P (XFRAME (data->focus_frame))))
+       Fredirect_frame_focus (frame, data->focus_frame);
 #endif
 
 #if 0 /* I don't understand why this is needed, and it causes problems
@@ -2578,7 +2632,7 @@ by `current-window-configuration' (which see).")
      Fselect_window above totally superfluous; it still sets f's
      selected window.  */
   if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
-    Fselect_frame (data->selected_frame);
+    Fselect_frame (data->selected_frame, Qnil);
 #endif
 
   if (!NILP (new_current_buffer))
@@ -2840,22 +2894,18 @@ Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
 work using this function.");
   Vdisplay_buffer_function = Qnil;
 
-  DEFVAR_LISP ("mouse-window", &Vmouse_window,
-     "Window that the last mouse click occurred on.");
-  Vmouse_window = Qnil;
-
   DEFVAR_LISP ("mouse-event", &Vmouse_event,
      "The last mouse-event object.  A list of four elements:\n\
   ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\
 KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\
 WINDOW is the window that the click applies do.\n\
-If FRAME-PART is non-nil, the event was on a scrollbar;\n\
-then Y-POS is really the total length of the scrollbar, while X-POS is\n\
-the relative position of the scrollbar's value within that total length.\n\
+If FRAME-PART is non-nil, the event was on a scroll bar;\n\
+then Y-POS is really the total length of the scroll bar, while X-POS is\n\
+the relative position of the scroll bar's value within that total length.\n\
 FRAME-PART is one of the following symbols:\n\
- `vertical-scrollbar', `vertical-slider',\n\
+ `vertical-scroll-bar', `vertical-slider',\n\
  `vertical-thumbup', `vertical-thumbdown',\n\
- `horizontal-scrollbar', `horizontal-slider',\n\
+ `horizontal-scroll-bar', `horizontal-slider',\n\
  `horizontal-thumbleft', `horizontal-thumbright'");
   Vmouse_event = Qnil;