X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/7a6968b45f2b93d984c5c3fcd5fce68d6e5b6ea9..7c1f66a94bf236a427606ef537b4629a48a1665b:/src/window.c diff --git a/src/window.c b/src/window.c index a8605ee628..880ca4a46b 100644 --- a/src/window.c +++ b/src/window.c @@ -1,6 +1,6 @@ /* 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. @@ -41,6 +41,9 @@ along with GNU Emacs. If not, see . */ #ifdef MSDOS #include "msdos.h" #endif +#ifdef HAVE_XWIDGETS +# include "xwidget.h" +#endif static ptrdiff_t count_windows (struct window *); static ptrdiff_t get_leaf_windows (struct window *, struct window **, @@ -205,6 +208,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. */ @@ -1666,7 +1683,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); @@ -3271,14 +3288,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); - /* 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 rtedisplay. */ - 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; + + 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. */ @@ -3962,9 +3973,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) { @@ -4056,37 +4069,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 */ } } } @@ -4096,7 +4078,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 @@ -4109,6 +4091,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise) } } + FRAME_WINDOW_SIZES_CHANGED (f) = true; fset_redisplay (f); } @@ -4390,6 +4373,9 @@ Signal an error when WINDOW is the only window on its frame. */) /* Block input. */ block_input (); +#ifdef HAVE_XWIDGETS + xwidget_view_delete_all_in_window (w); +#endif 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). */ @@ -4547,6 +4533,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 (); } @@ -4586,6 +4573,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 (); } @@ -4829,7 +4817,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; @@ -4977,7 +4965,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; @@ -4999,27 +4987,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; @@ -5043,7 +5038,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); @@ -5094,14 +5089,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 @@ -5211,12 +5212,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); @@ -5242,8 +5244,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); @@ -5269,8 +5279,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);