X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/ad4a9a79d2e54ec59905eb42f5bd4fa190202dae..a1d58e5b6d80e4f724d0c13fffc9dc3a02194e14:/src/window.c diff --git a/src/window.c b/src/window.c index 12b15424c2..676156c221 100644 --- a/src/window.c +++ b/src/window.c @@ -79,6 +79,7 @@ static void decode_next_window_args P_ ((Lisp_Object *, Lisp_Object *, 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 @@ -337,7 +338,7 @@ POS defaults to point in WINDOW; WINDOW defaults to the selected window.") 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 @@ -350,7 +351,7 @@ POS defaults to point in WINDOW; WINDOW defaults to the selected window.") 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; @@ -494,6 +495,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) @@ -513,6 +519,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 @@ -520,19 +527,37 @@ 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; + 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. */ @@ -540,22 +565,21 @@ coordinates_in_window (w, x, y) /* 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, @@ -1549,9 +1573,35 @@ argument ALL_FRAMES is non-nil, cycle through all frames.") 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; @@ -1637,7 +1687,7 @@ window_loop (type, obj, mini, frames) 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; @@ -4351,7 +4401,8 @@ displayed_window_lines (w) 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; @@ -4437,8 +4488,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)]))) @@ -4500,7 +4552,6 @@ the return value is nil. Otherwise the value is t.") { if (XBUFFER (new_current_buffer) == current_buffer) old_point = PT; - } frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; @@ -4515,7 +4566,7 @@ the return value is nil. Otherwise the value is t.") 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 @@ -4631,6 +4682,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); @@ -4722,15 +4775,24 @@ the return value is nil. Otherwise the value is t.") #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); @@ -4887,6 +4949,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. @@ -4984,8 +5048,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); }