static int foreach_window_1 P_ ((struct window *,
int (* fn) (struct window *, void *),
void *));
+static Lisp_Object window_list_1 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
/* This is the window in which the terminal's cursor should
be left when nothing is being done with it. This must
char in the window. */
if (!NILP (fully))
{
- pos_visible_p (w, posint, &fully_p);
+ pos_visible_p (w, posint, &fully_p, !NILP (fully));
in_window = fully_p ? Qt : Qnil;
}
else
in_window = Qnil;
else
{
- if (pos_visible_p (w, posint, &fully_p))
+ if (pos_visible_p (w, posint, &fully_p, !NILP (fully)))
in_window = NILP (fully) || fully_p ? Qt : Qnil;
else
in_window = Qnil;
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)
bottom_y = WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w);
}
+ /* Completely outside anything interesting? */
if (*y < top_y
|| *y >= bottom_y
|| *x < (left_x
- (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;
+ 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 (XFASTINT (w->left) > 0
+ && (abs (*x - XFASTINT (w->left) * 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 (XFASTINT (w->left) > 0
+ && (abs (*x - XFASTINT (w->left) * CANON_X_UNIT (f))
+ < CANON_X_UNIT (f) / 2))
+ return ON_VERTICAL_BORDER;
+ return ON_HEADER_LINE;
+ }
+
/* 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)
+ 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;
+ 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))
+ 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;
- }
+ 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,
DEFUN ("window-list", Fwindow_list, Swindow_list, 0, 3, 0,
- "Return a list of windows in canonical ordering.\n\
-Arguments are like for `next-window'.")
- (window, minibuf, all_frames)
+ "Return a list of windows on FRAME, starting with WINDOW.\n\
+FRAME nil or omitted means use the selected frame.\n\
+WINDOW nil or omitted means use the selected window.\n\
+MINIBUF t means include the minibuffer window, even if it isn't active.\n\
+MINIBUF nil or omitted means include the minibuffer window only\n\
+if it's active.\n\
+MINIBUF neither nil nor t means never include the minibuffer window.")
+ (frame, minibuf, window)
+ Lisp_Object frame, minibuf, window;
+{
+ Lisp_Object list;
+
+ if (NILP (window))
+ window = selected_window;
+ if (NILP (frame))
+ frame = selected_frame;
+
+ if (!EQ (frame, XWINDOW (window)->frame))
+ error ("Window is on a different frame");
+
+ return window_list_1 (window, minibuf, frame);
+}
+
+
+/* Return a list of windows in canonical ordering. Arguments are like
+ for `next-window'. */
+
+static Lisp_Object
+window_list_1 (window, minibuf, all_frames)
Lisp_Object window, minibuf, all_frames;
{
Lisp_Object tail, list;
We can't just wait until we hit the first window again, because
it might be deleted. */
- windows = Fwindow_list (window, mini ? Qt : Qnil, frame_arg);
+ windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
GCPRO1 (windows);
best_window = Qnil;
int lines = (rest + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
it.vpos += lines;
}
- else if (bottom_y > height)
+ else if (it.current_y < height && bottom_y > height)
+ /* Partially visible line at the bottom. */
++it.vpos;
return it.vpos;
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)])))
{
if (XBUFFER (new_current_buffer) == current_buffer)
old_point = PT;
-
}
frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
struct window *root_window;
struct window **leaf_windows;
int n_leaf_windows;
- int k, i;
+ int k, i, n;
/* If the frame has been resized since this window configuration was
made, we change the frame to the size specified in the
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);
#endif
/* Now, free glyph matrices in windows that were not reused. */
- for (i = 0; i < n_leaf_windows; ++i)
- if (NILP (leaf_windows[i]->buffer))
- {
- /* Assert it's not reused as a combination. */
- xassert (NILP (leaf_windows[i]->hchild)
- && NILP (leaf_windows[i]->vchild));
- free_window_matrices (leaf_windows[i]);
- SET_FRAME_GARBAGED (f);
- }
+ for (i = n = 0; i < n_leaf_windows; ++i)
+ {
+ if (NILP (leaf_windows[i]->buffer))
+ {
+ /* Assert it's not reused as a combination. */
+ xassert (NILP (leaf_windows[i]->hchild)
+ && NILP (leaf_windows[i]->vchild));
+ free_window_matrices (leaf_windows[i]);
+ SET_FRAME_GARBAGED (f);
+ }
+ else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
+ ++n;
+ }
+
+ /* If more than one window shows the new and old current buffer,
+ don't try to preserve point in that buffer. */
+ if (old_point > 0 && n > 1)
+ old_point = -1;
adjust_glyphs (f);
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.
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);
}