X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f1baa156503f089d6627171e0e9ad73bbdbb7268..b57076929f0e904864e1457d5789f2fe6652fc84:/src/window.c diff --git a/src/window.c b/src/window.c index ad5ac79bd8..733cf75d13 100644 --- a/src/window.c +++ b/src/window.c @@ -1,14 +1,14 @@ /* Window creation, deletion and examination for GNU Emacs. Does not include redisplay. - Copyright (C) 1985-1987, 1993-1998, 2000-2015 Free Software + Copyright (C) 1985-1987, 1993-1998, 2000-2016 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,11 +23,9 @@ along with GNU Emacs. If not, see . */ #include #include "lisp.h" -#include "character.h" #include "buffer.h" #include "keyboard.h" #include "keymap.h" -#include "menu.h" #include "frame.h" #include "window.h" #include "commands.h" @@ -36,8 +34,8 @@ along with GNU Emacs. If not, see . */ #include "disptab.h" #include "dispextern.h" #include "blockinput.h" -#include "intervals.h" #include "termhooks.h" /* For FRAME_TERMINAL. */ +#include "xwidget.h" #ifdef HAVE_WINDOW_SYSTEM #include TERM_HEADER #endif /* HAVE_WINDOW_SYSTEM */ @@ -208,6 +206,20 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val) w->horizontal = horflag; } +static void +wset_update_mode_line (struct window *w) +{ + /* If this window is the selected window on its frame, set the + global variable update_mode_lines, so that x_consider_frame_title + will consider this frame's title for redisplay. */ + Lisp_Object fselected_window = XFRAME (WINDOW_FRAME (w))->selected_window; + + if (WINDOWP (fselected_window) && XWINDOW (fselected_window) == w) + update_mode_lines = 42; + else + w->update_mode_line = true; +} + /* True if leaf window W doesn't reflect the actual state of displayed buffer due to its text or overlays change. */ @@ -641,7 +653,7 @@ DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combinatio WINDOW must be a valid window used in horizontal or vertical combination. If the return value is nil, child windows of WINDOW can be recombined with WINDOW's siblings. A return value of t means that child windows of -WINDOW are never \(re-)combined with WINDOW's siblings. */) +WINDOW are never (re-)combined with WINDOW's siblings. */) (Lisp_Object window) { struct window *w; @@ -1101,186 +1113,6 @@ end-trigger value is reset to nil. */) return value; } -DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0, - doc: /* Return a list of the edge coordinates of WINDOW. -WINDOW must be a valid window and defaults to the selected one. - -The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM -count by lines, and LEFT and RIGHT count by columns, all relative to 0, -0 at top left corner of frame. - -RIGHT is one more than the rightmost column occupied by WINDOW. BOTTOM -is one more than the bottommost row occupied by WINDOW. The edges -include the space used by WINDOW's scroll bar, display margins, fringes, -header line, and/or mode line. For the edges of just the text area, use -`window-inside-edges'. */) - (Lisp_Object window) -{ - register struct window *w = decode_valid_window (window); - - return list4i (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w), - WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w)); -} - -DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0, - doc: /* Return a list of the edge pixel coordinates of WINDOW. -WINDOW must be a valid window and defaults to the selected one. - -The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to -0, 0 at the top left corner of the frame. - -RIGHT is one more than the rightmost x position occupied by WINDOW. -BOTTOM is one more than the bottommost y position occupied by WINDOW. -The pixel edges include the space used by WINDOW's scroll bar, display -margins, fringes, header line, and/or mode line. For the pixel edges -of just the text area, use `window-inside-pixel-edges'. */) - (Lisp_Object window) -{ - register struct window *w = decode_valid_window (window); - - return list4i (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w), - WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w)); -} - -static void -calc_absolute_offset (struct window *w, int *add_x, int *add_y) -{ - struct frame *f = XFRAME (w->frame); - *add_y = f->top_pos; -#ifdef FRAME_MENUBAR_HEIGHT - *add_y += FRAME_MENUBAR_HEIGHT (f); -#endif -#ifdef FRAME_TOOLBAR_TOP_HEIGHT - *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f); -#elif defined (FRAME_TOOLBAR_HEIGHT) - *add_y += FRAME_TOOLBAR_HEIGHT (f); -#endif -#ifdef FRAME_NS_TITLEBAR_HEIGHT - *add_y += FRAME_NS_TITLEBAR_HEIGHT (f); -#endif - *add_x = f->left_pos; -#ifdef FRAME_TOOLBAR_LEFT_WIDTH - *add_x += FRAME_TOOLBAR_LEFT_WIDTH (f); -#endif -} - -DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges, - Swindow_absolute_pixel_edges, 0, 1, 0, - doc: /* Return a list of the edge pixel coordinates of WINDOW. -WINDOW must be a valid window and defaults to the selected one. - -The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to -0, 0 at the top left corner of the display. - -RIGHT is one more than the rightmost x position occupied by WINDOW. -BOTTOM is one more than the bottommost y position occupied by WINDOW. -The pixel edges include the space used by WINDOW's scroll bar, display -margins, fringes, header line, and/or mode line. For the pixel edges -of just the text area, use `window-inside-absolute-pixel-edges'. */) - (Lisp_Object window) -{ - register struct window *w = decode_valid_window (window); - int add_x, add_y; - - calc_absolute_offset (w, &add_x, &add_y); - - return list4i (WINDOW_LEFT_EDGE_X (w) + add_x, - WINDOW_TOP_EDGE_Y (w) + add_y, - WINDOW_RIGHT_EDGE_X (w) + add_x, - WINDOW_BOTTOM_EDGE_Y (w) + add_y); -} - -DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0, - doc: /* Return a list of the edge coordinates of WINDOW. -WINDOW must be a live window and defaults to the selected one. - -The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM -count by lines, and LEFT and RIGHT count by columns, all relative to 0, -0 at top left corner of frame. - -RIGHT is one more than the rightmost column of WINDOW's text area. -BOTTOM is one more than the bottommost row of WINDOW's text area. The -inside edges do not include the space used by the WINDOW's scroll bar, -display margins, fringes, header line, and/or mode line. */) - (Lisp_Object window) -{ - register struct window *w = decode_live_window (window); - - return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w) - + WINDOW_LEFT_MARGIN_COLS (w) - + ((WINDOW_LEFT_FRINGE_WIDTH (w) - + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) - / WINDOW_FRAME_COLUMN_WIDTH (w))), - (WINDOW_TOP_EDGE_LINE (w) - + WINDOW_HEADER_LINE_LINES (w)), - (WINDOW_BOX_RIGHT_EDGE_COL (w) - - WINDOW_RIGHT_MARGIN_COLS (w) - - ((WINDOW_RIGHT_FRINGE_WIDTH (w) - + WINDOW_FRAME_COLUMN_WIDTH (w) - 1) - / WINDOW_FRAME_COLUMN_WIDTH (w))), - (WINDOW_BOTTOM_EDGE_LINE (w) - - WINDOW_MODE_LINE_LINES (w))); -} - -DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0, - doc: /* Return a list of the edge pixel coordinates of WINDOW's text area. -WINDOW must be a live window and defaults to the selected one. - -The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to -(0,0) at the top left corner of the frame's window area. - -RIGHT is one more than the rightmost x position of WINDOW's text area. -BOTTOM is one more than the bottommost y position of WINDOW's text area. -The inside edges do not include the space used by WINDOW's scroll bar, -display margins, fringes, header line, and/or mode line. */) - (Lisp_Object window) -{ - register struct window *w = decode_live_window (window); - - return list4i ((WINDOW_BOX_LEFT_EDGE_X (w) - + WINDOW_LEFT_MARGIN_WIDTH (w) - + WINDOW_LEFT_FRINGE_WIDTH (w)), - (WINDOW_TOP_EDGE_Y (w) - + WINDOW_HEADER_LINE_HEIGHT (w)), - (WINDOW_BOX_RIGHT_EDGE_X (w) - - WINDOW_RIGHT_MARGIN_WIDTH (w) - - WINDOW_RIGHT_FRINGE_WIDTH (w)), - (WINDOW_BOTTOM_EDGE_Y (w) - - WINDOW_MODE_LINE_HEIGHT (w))); -} - -DEFUN ("window-inside-absolute-pixel-edges", - Fwindow_inside_absolute_pixel_edges, - Swindow_inside_absolute_pixel_edges, 0, 1, 0, - doc: /* Return a list of the edge pixel coordinates of WINDOW's text area. -WINDOW must be a live window and defaults to the selected one. - -The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to -(0,0) at the top left corner of the frame's window area. - -RIGHT is one more than the rightmost x position of WINDOW's text area. -BOTTOM is one more than the bottommost y position of WINDOW's text area. -The inside edges do not include the space used by WINDOW's scroll bar, -display margins, fringes, header line, and/or mode line. */) - (Lisp_Object window) -{ - register struct window *w = decode_live_window (window); - int add_x, add_y; - - calc_absolute_offset (w, &add_x, &add_y); - - return list4i ((WINDOW_BOX_LEFT_EDGE_X (w) - + WINDOW_LEFT_MARGIN_WIDTH (w) - + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x), - (WINDOW_TOP_EDGE_Y (w) - + WINDOW_HEADER_LINE_HEIGHT (w) + add_y), - (WINDOW_BOX_RIGHT_EDGE_X (w) - - WINDOW_RIGHT_MARGIN_WIDTH (w) - - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x), - (WINDOW_BOTTOM_EDGE_Y (w) - - WINDOW_MODE_LINE_HEIGHT (w) + add_y)); -} - /* Test if the character at column X, row Y is within window W. If it is not, return ON_NOTHING; if it is on the window's vertical divider, return @@ -1471,10 +1303,18 @@ window_relative_x_coord (struct window *w, enum window_part part, int x) + window_box_width (w, RIGHT_MARGIN_AREA) + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) ? WINDOW_RIGHT_FRINGE_WIDTH (w) : 0)); - } - /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */ - return 0; + case ON_NOTHING: + case ON_VERTICAL_BORDER: + case ON_VERTICAL_SCROLL_BAR: + case ON_HORIZONTAL_SCROLL_BAR: + case ON_RIGHT_DIVIDER: + case ON_BOTTOM_DIVIDER: + return 0; + + default: + emacs_abort (); + } } @@ -1841,7 +1681,7 @@ overriding motion of point in order to display at this exact start. */) w->start_at_line_beg = false; if (NILP (noforce)) w->force_start = true; - w->update_mode_line = true; + wset_update_mode_line (w); /* Bug#15957. */ w->window_end_valid = false; wset_redisplay (w); @@ -1858,8 +1698,10 @@ Return nil if that position is scrolled vertically out of view. If a character is only partially visible, nil is returned, unless the optional argument PARTIALLY is non-nil. If POS is only out of view because of horizontal scrolling, return non-nil. If POS is t, it -specifies the position of the last visible glyph in WINDOW. POS -defaults to point in WINDOW; WINDOW defaults to the selected window. +specifies either the first position displayed on the last visible +screen line in WINDOW, or the end-of-buffer position, whichever comes +first. POS defaults to point in WINDOW; WINDOW defaults to the +selected window. If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]), @@ -2813,7 +2655,6 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini, Lisp_Object window, windows, best_window, frame_arg; bool frame_best_window_flag = false; struct frame *f; - struct gcpro gcpro1; /* If we're only looping through windows on a particular frame, frame points to that frame. If we're looping through windows @@ -2847,7 +2688,6 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini, window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ()); windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg); - GCPRO1 (windows); best_window = Qnil; for (; CONSP (windows); windows = XCDR (windows)) @@ -2875,7 +2715,7 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini, { if (EQ (window, selected_window)) /* Preferably return the selected window. */ - RETURN_UNGCPRO (window); + return window; else if (EQ (XWINDOW (window)->frame, selected_frame) && !frame_best_window_flag) /* Prefer windows on the current frame (but don't @@ -2941,7 +2781,6 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini, } } - UNGCPRO; return best_window; } @@ -3447,7 +3286,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, /* Maybe we could move this into the `if' but it's not obviously safe and I doubt it's worth the trouble. */ wset_redisplay (w); - w->update_mode_line = true; + + wset_update_mode_line (w); /* We must select BUFFER to run the window-scroll-functions and to look up the buffer-local value of Vwindow_point_insertion_type. */ @@ -4131,9 +3971,11 @@ values. */) } -/* Resize frame F's windows when number of lines of F is set to SIZE. - HORFLAG means resize windows when number of columns of F is set to - SIZE. PIXELWISE means to interpret SIZE as pixels. */ +/* Resize frame F's windows when F's width or height is set to SIZE. + If HORFLAG is zero, F's width was set to SIZE, otherwise its height + was set. SIZE is interpreted in F's canonical character units + (a.k.a. "columns" or "lines"), unless PIXELWISE is non-zero, which + means to interpret SIZE in pixel units. */ void resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) { @@ -4144,7 +3986,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) /* old_size is the old size of the frame's root window. */ int old_size = horflag ? r->total_cols : r->total_lines; int old_pixel_size = horflag ? r->pixel_width : r->pixel_height; - int old_pixel_top = r->pixel_top; /* new_size is the new size of the frame's root window. */ int new_size, new_pixel_size; int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f); @@ -4174,11 +4015,8 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) new_pixel_size = new_size * unit; } - r->top_line = FRAME_TOP_MARGIN (f); - r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); - if (new_pixel_size == old_pixel_size - && r->pixel_top == old_pixel_top) + && (horflag || r->pixel_top == FRAME_TOP_MARGIN_HEIGHT (f))) ; else if (WINDOW_LEAF_P (r)) /* For a leaf root window just set the size. */ @@ -4189,6 +4027,9 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) } else { + r->top_line = FRAME_TOP_MARGIN (f); + r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); + r->total_lines = new_size; r->pixel_height = new_pixel_size; } @@ -4196,6 +4037,12 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) { Lisp_Object delta; + if (!horflag) + { + r->top_line = FRAME_TOP_MARGIN (f); + r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); + } + if (pixelwise) XSETINT (delta, new_pixel_size - old_pixel_size); else @@ -4220,37 +4067,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) { window_resize_apply (r, horflag); window_pixel_to_total (r->frame, horflag ? Qt : Qnil); -#if false /* Let's try without safe sizes and/or killing other windows. */ - } - else - { - /* Finally, try with "safe" minimum sizes. */ - resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe, - pixelwise ? Qt : Qnil); - if (window_resize_check (r, horflag) - && new_pixel_size == XINT (r->new_pixel)) - { - window_resize_apply (r, horflag); - window_pixel_to_total (r->frame, horflag ? Qt : Qnil); - } - else - { - /* We lost. Delete all windows but the frame's - selected one. */ - root = f->selected_window; - Fdelete_other_windows_internal (root, Qnil); - if (horflag) - { - XWINDOW (root)->total_cols = new_size; - XWINDOW (root)->pixel_width = new_pixel_size; - } - else - { - XWINDOW (root)->total_lines = new_size; - XWINDOW (root)->pixel_height = new_pixel_size; - } - } -#endif /* false */ } } } @@ -4260,7 +4076,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) m = XWINDOW (mini); if (horflag) { - m->total_cols = size; + m->total_cols = new_size; m->pixel_width = new_pixel_size; } else @@ -4273,6 +4089,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) } } + FRAME_WINDOW_SIZES_CHANGED (f) = true; fset_redisplay (f); } @@ -4554,6 +4371,7 @@ Signal an error when WINDOW is the only window on its frame. */) /* Block input. */ block_input (); + xwidget_view_delete_all_in_window (w); window_resize_apply (p, horflag); /* If this window is referred to by the dpyinfo's mouse highlight, invalidate that slot to be safe (Bug#9904). */ @@ -4711,6 +4529,7 @@ grow_mini_window (struct window *w, int delta, bool pixelwise) /* Enforce full redisplay of the frame. */ /* FIXME: Shouldn't window--resize-root-window-vertically do it? */ fset_redisplay (f); + FRAME_WINDOW_SIZES_CHANGED (f) = true; adjust_frame_glyphs (f); unblock_input (); } @@ -4750,6 +4569,7 @@ shrink_mini_window (struct window *w, bool pixelwise) /* Enforce full redisplay of the frame. */ /* FIXME: Shouldn't window--resize-root-window-vertically do it? */ fset_redisplay (f); + FRAME_WINDOW_SIZES_CHANGED (f) = true; adjust_frame_glyphs (f); unblock_input (); } @@ -4993,7 +4813,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) set_marker_restricted (w->start, make_number (spos), w->contents); w->start_at_line_beg = true; - w->update_mode_line = true; + wset_update_mode_line (w); /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = true; @@ -5141,7 +4961,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) IT_BYTEPOS (it)); bytepos = marker_byte_position (w->start); w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); - w->update_mode_line = true; + wset_update_mode_line (w); /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = true; @@ -5163,27 +4983,34 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) if (n > 0) { + int last_y = it.last_visible_y - this_scroll_margin - 1; + /* We moved the window start towards ZV, so PT may be now in the scroll margin at the top. */ move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); - if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin + if (IT_CHARPOS (it) == PT + && it.current_y >= this_scroll_margin + && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w) && (NILP (Vscroll_preserve_screen_position) || EQ (Vscroll_preserve_screen_position, Qt))) /* We found PT at a legitimate height. Leave it alone. */ ; - else if (window_scroll_pixel_based_preserve_y >= 0) - { - /* If we have a header line, take account of it. - This is necessary because we set it.current_y to 0, above. */ - move_it_to (&it, -1, - window_scroll_pixel_based_preserve_x, - (window_scroll_pixel_based_preserve_y - - WINDOW_WANTS_HEADER_LINE_P (w)), - -1, MOVE_TO_Y | MOVE_TO_X); - SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); - } else { + if (window_scroll_pixel_based_preserve_y >= 0) + { + /* Don't enter the scroll margin at the end of the window. */ + int goal_y = min (last_y, window_scroll_pixel_based_preserve_y); + + /* If we have a header line, take account of it. This + is necessary because we set it.current_y to 0, above. */ + move_it_to (&it, -1, + window_scroll_pixel_based_preserve_x, + goal_y - WINDOW_HEADER_LINE_HEIGHT (w), + -1, MOVE_TO_Y | MOVE_TO_X); + } + + /* Get out of the scroll margin at the top of the window. */ while (it.current_y < this_scroll_margin) { int prev = it.current_y; @@ -5207,7 +5034,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) /* We moved the window start towards BEGV, so PT may be now in the scroll margin at the bottom. */ move_it_to (&it, PT, -1, - (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w) + (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w) - this_scroll_margin - 1), -1, MOVE_TO_POS | MOVE_TO_Y); @@ -5258,14 +5085,20 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) ; else if (window_scroll_pixel_based_preserve_y >= 0) { + int goal_y = min (it.last_visible_y - this_scroll_margin - 1, + window_scroll_pixel_based_preserve_y); + + /* Don't let the preserved screen Y coordinate put us inside + any of the two margins. */ + if (goal_y < this_scroll_margin) + goal_y = this_scroll_margin; SET_TEXT_POS_FROM_MARKER (start, w->start); start_display (&it, w, start); /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT here because we called start_display again and did not alter it.current_y this time. */ move_it_to (&it, -1, window_scroll_pixel_based_preserve_x, - window_scroll_pixel_based_preserve_y, -1, - MOVE_TO_Y | MOVE_TO_X); + goal_y, -1, MOVE_TO_Y | MOVE_TO_X); SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); } else @@ -5375,12 +5208,13 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) set_marker_restricted_both (w->start, w->contents, pos, pos_byte); w->start_at_line_beg = !NILP (bolp); - w->update_mode_line = true; + wset_update_mode_line (w); /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = true; if (!NILP (Vscroll_preserve_screen_position) + && this_scroll_margin == 0 && (whole || !EQ (Vscroll_preserve_screen_position, Qt))) { SET_PT_BOTH (pos, pos_byte); @@ -5406,8 +5240,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) marker_byte_position (opoint_marker)); else if (!NILP (Vscroll_preserve_screen_position)) { + int nlines = window_scroll_preserve_vpos; + SET_PT_BOTH (pos, pos_byte); - Fvertical_motion (original_pos, window, Qnil); + if (window_scroll_preserve_vpos < this_scroll_margin) + nlines = this_scroll_margin; + else if (window_scroll_preserve_vpos + >= w->total_lines - this_scroll_margin) + nlines = w->total_lines - this_scroll_margin - 1; + Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos), + make_number (nlines)), window, Qnil); } else SET_PT (top_margin); @@ -5433,8 +5275,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) { if (!NILP (Vscroll_preserve_screen_position)) { + int nlines = window_scroll_preserve_vpos; + SET_PT_BOTH (pos, pos_byte); - Fvertical_motion (original_pos, window, Qnil); + if (window_scroll_preserve_vpos < this_scroll_margin) + nlines = this_scroll_margin; + else if (window_scroll_preserve_vpos + >= ht - this_scroll_margin) + nlines = ht - this_scroll_margin - 1; + Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos), + make_number (nlines)), window, Qnil); } else Fvertical_motion (make_number (-1), window, Qnil); @@ -6782,7 +6632,6 @@ apply_window_adjustment (struct window *w) eassert (w); clear_glyph_matrix (w->current_matrix); w->window_end_valid = false; - windows_or_buffers_changed = 30; wset_redisplay (w); adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w))); } @@ -7414,7 +7263,7 @@ resizing a window preferably resizes one adjacent window only. If this variable is t, splitting a window tries to get the space proportionally from all windows in the same combination. This also -allows to split a window that is otherwise too small or of fixed size. +allows splitting a window that is otherwise too small or of fixed size. Resizing and deleting a window proportionally resize all windows in the same combination. @@ -7548,18 +7397,12 @@ displayed after a scrolling operation to be somewhat inaccurate. */); defsubr (&Sset_window_hscroll); defsubr (&Swindow_redisplay_end_trigger); defsubr (&Sset_window_redisplay_end_trigger); - defsubr (&Swindow_edges); - defsubr (&Swindow_pixel_edges); - defsubr (&Swindow_absolute_pixel_edges); defsubr (&Swindow_mode_line_height); defsubr (&Swindow_header_line_height); defsubr (&Swindow_right_divider_width); defsubr (&Swindow_bottom_divider_width); defsubr (&Swindow_scroll_bar_width); defsubr (&Swindow_scroll_bar_height); - defsubr (&Swindow_inside_edges); - defsubr (&Swindow_inside_pixel_edges); - defsubr (&Swindow_inside_absolute_pixel_edges); defsubr (&Scoordinates_in_window_p); defsubr (&Swindow_at); defsubr (&Swindow_point);