aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-12-07 19:21:57 +0200
committerEli Zaretskii2013-12-07 19:21:57 +0200
commitce1d7b61f12dcc1b67535b68d9b0655b45fcadb6 (patch)
tree881d03f4f486933482cd2e3851184cd3b172ef1b /src/window.c
parent6630df25238c5a1efa2bc6a0fa7889782e8c91b5 (diff)
parentfa6fa1a1773f255b5efbe52a743b017f4908a6cb (diff)
downloademacs-ce1d7b61f12dcc1b67535b68d9b0655b45fcadb6.tar.gz
emacs-ce1d7b61f12dcc1b67535b68d9b0655b45fcadb6.zip
Merge from trunk.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c1111
1 files changed, 817 insertions, 294 deletions
diff --git a/src/window.c b/src/window.c
index bc0adaf459f..d1f3dd599b1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -51,6 +51,7 @@ static Lisp_Object Qrecord_window_buffer;
51static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 51static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
52static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 52static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
53static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; 53static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
54static Lisp_Object Qwindow_pixel_to_total;
54static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 55static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
55static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; 56static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
56 57
@@ -60,7 +61,6 @@ static int get_leaf_windows (struct window *, struct window **, int);
60static void window_scroll (Lisp_Object, EMACS_INT, bool, int); 61static void window_scroll (Lisp_Object, EMACS_INT, bool, int);
61static void window_scroll_pixel_based (Lisp_Object, int, bool, int); 62static void window_scroll_pixel_based (Lisp_Object, int, bool, int);
62static void window_scroll_line_based (Lisp_Object, int, bool, int); 63static void window_scroll_line_based (Lisp_Object, int, bool, int);
63static Lisp_Object window_list (void);
64static int add_window_to_list (struct window *, void *); 64static int add_window_to_list (struct window *, void *);
65static Lisp_Object next_window (Lisp_Object, Lisp_Object, 65static Lisp_Object next_window (Lisp_Object, Lisp_Object,
66 Lisp_Object, int); 66 Lisp_Object, int);
@@ -75,6 +75,7 @@ static int foreach_window_1 (struct window *,
75static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 75static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
76static int window_resize_check (struct window *, bool); 76static int window_resize_check (struct window *, bool);
77static void window_resize_apply (struct window *, bool); 77static void window_resize_apply (struct window *, bool);
78static void window_resize_apply_total (struct window *, bool);
78static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 79static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
79static void select_window_1 (Lisp_Object, bool); 80static void select_window_1 (Lisp_Object, bool);
80 81
@@ -113,6 +114,9 @@ Lisp_Object minibuf_selected_window;
113/* Hook run at end of temp_output_buffer_show. */ 114/* Hook run at end of temp_output_buffer_show. */
114static Lisp_Object Qtemp_buffer_show_hook; 115static Lisp_Object Qtemp_buffer_show_hook;
115 116
117/* Incremented for each window created. */
118static int sequence_number;
119
116/* Nonzero after init_window_once has finished. */ 120/* Nonzero after init_window_once has finished. */
117static int window_initialized; 121static int window_initialized;
118 122
@@ -482,6 +486,15 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
482 record_buffer before returning here. */ 486 record_buffer before returning here. */
483 goto record_and_return; 487 goto record_and_return;
484 488
489 if (NILP (norecord))
490 { /* Mark the window for redisplay since the selected-window has
491 a different mode-line. */
492 wset_redisplay (XWINDOW (selected_window));
493 wset_redisplay (w);
494 }
495 else
496 redisplay_other_windows ();
497
485 sf = SELECTED_FRAME (); 498 sf = SELECTED_FRAME ();
486 if (XFRAME (WINDOW_FRAME (w)) != sf) 499 if (XFRAME (WINDOW_FRAME (w)) != sf)
487 { 500 {
@@ -500,7 +513,6 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
500 513
501 select_window_1 (window, inhibit_point_swap); 514 select_window_1 (window, inhibit_point_swap);
502 bset_last_selected_window (XBUFFER (w->contents), window); 515 bset_last_selected_window (XBUFFER (w->contents), window);
503 windows_or_buffers_changed = 24;
504 516
505 record_and_return: 517 record_and_return:
506 /* record_buffer can run QUIT, so make sure it is run only after we have 518 /* record_buffer can run QUIT, so make sure it is run only after we have
@@ -669,6 +681,31 @@ selected one. */)
669 return make_number (decode_live_window (window)->use_time); 681 return make_number (decode_live_window (window)->use_time);
670} 682}
671 683
684DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
685 doc: /* Return the pixel width of window WINDOW.
686WINDOW must be a valid window and defaults to the selected one.
687
688The return value includes the fringes and margins of WINDOW as well as
689any vertical dividers or scroll bars belonging to WINDOW. If WINDOW is
690an internal window, its pixel width is the width of the screen areas
691spanned by its children. */)
692 (Lisp_Object window)
693{
694 return make_number (decode_valid_window (window)->pixel_width);
695}
696
697DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
698 doc: /* Return the pixel height of window WINDOW.
699WINDOW must be a valid window and defaults to the selected one.
700
701The return value includes the mode line and header line, if any. If
702WINDOW is an internal window, its pixel height is the height of the
703screen areas spanned by its children. */)
704 (Lisp_Object window)
705{
706 return make_number (decode_valid_window (window)->pixel_height);
707}
708
672DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0, 709DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
673 doc: /* Return the total height, in lines, of window WINDOW. 710 doc: /* Return the total height, in lines, of window WINDOW.
674WINDOW must be a valid window and defaults to the selected one. 711WINDOW must be a valid window and defaults to the selected one.
@@ -726,6 +763,30 @@ WINDOW must be a valid window and defaults to the selected one. */)
726 return decode_valid_window (window)->new_normal; 763 return decode_valid_window (window)->new_normal;
727} 764}
728 765
766DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
767 doc: /* Return new pixel size of window WINDOW.
768WINDOW must be a valid window and defaults to the selected one. */)
769 (Lisp_Object window)
770{
771 return decode_valid_window (window)->new_pixel;
772}
773
774DEFUN ("window-pixel-left", Fwindow_pixel_left, Swindow_pixel_left, 0, 1, 0,
775 doc: /* Return left pixel edge of window WINDOW.
776WINDOW must be a valid window and defaults to the selected one. */)
777 (Lisp_Object window)
778{
779 return make_number (decode_valid_window (window)->pixel_left);
780}
781
782DEFUN ("window-pixel-top", Fwindow_pixel_top, Swindow_pixel_top, 0, 1, 0,
783 doc: /* Return top pixel edge of window WINDOW.
784WINDOW must be a valid window and defaults to the selected one. */)
785 (Lisp_Object window)
786{
787 return make_number (decode_valid_window (window)->pixel_top);
788}
789
729DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0, 790DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
730 doc: /* Return left column of window WINDOW. 791 doc: /* Return left column of window WINDOW.
731This is the distance, in columns, between the left edge of WINDOW and 792This is the distance, in columns, between the left edge of WINDOW and
@@ -754,75 +815,118 @@ WINDOW must be a valid window and defaults to the selected one. */)
754 header line of W. */ 815 header line of W. */
755 816
756static int 817static int
757window_body_lines (struct window *w) 818window_body_height (struct window *w, bool pixelwise)
758{ 819{
759 int height = w->total_lines; 820 int pixels = (w->pixel_height
760 821 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
761 if (!MINI_WINDOW_P (w)) 822 - WINDOW_HEADER_LINE_HEIGHT (w)
762 { 823 - WINDOW_MODE_LINE_HEIGHT (w));
763 if (WINDOW_WANTS_MODELINE_P (w)) 824 int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
764 --height;
765 if (WINDOW_WANTS_HEADER_LINE_P (w))
766 --height;
767 }
768 825
769 return height; 826 return pixelwise ? pixels : ((pixels + unit - 1) / unit);
770} 827}
771 828
772/* Return the number of columns of W's body. Don't count columns 829/* Return the number of columns of W's body. Don't count columns
773 occupied by the scroll bar or the vertical bar separating W from its 830 occupied by the scroll bar or the vertical bar separating W from its
774 right sibling. On window-systems don't count fringes or display 831 right sibling. On window-systems don't count fringes or display
775 margins either. */ 832 margins either. */
776
777int 833int
778window_body_cols (struct window *w) 834window_body_width (struct window *w, bool pixelwise)
779{ 835{
780 struct frame *f = XFRAME (WINDOW_FRAME (w)); 836 struct frame *f = XFRAME (WINDOW_FRAME (w));
781 int width = w->total_cols;
782 837
783 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) 838 int pixels = (w->pixel_width
784 /* Scroll bars occupy a few columns. */ 839 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
785 width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w); 840 - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
786 else if (!FRAME_WINDOW_P (f) 841 ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
787 && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w)) 842 : ((!FRAME_WINDOW_P (f)
788 /* The column of `|' characters separating side-by-side windows 843 && !WINDOW_RIGHTMOST_P (w)
789 occupies one column only. */ 844 && !WINDOW_RIGHT_DIVIDER_WIDTH (w)
790 width -= 1; 845 && !WINDOW_FULL_WIDTH_P (w))
846 /* According to Eli this is either 1 or 0. */
847 ? 1 : 0))
848 - WINDOW_MARGINS_WIDTH (w)
849 - (FRAME_WINDOW_P (f)
850 ? WINDOW_FRINGES_WIDTH (w)
851 : 0));
852 int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
853
854 return pixelwise ? pixels : ((pixels + unit - 1) / unit);
855}
856
857DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
858 doc: /* Return the height, in lines, of WINDOW's text area.
859WINDOW must be a live window and defaults to the selected one.
791 860
792 /* Display margins cannot be used for normal text. */ 861Optional argument PIXELWISE non-nil means return the height in pixels.
793 width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w);
794 862
795 if (FRAME_WINDOW_P (f)) 863The returned height does not include the mode line or header line. On a
796 /* On window-systems, fringes cannot be used for normal text. */ 864graphical display, the height is expressed as an integer multiple of the
797 width -= WINDOW_FRINGE_COLS (w); 865default character height if PIXELWISE is nil.
798 866
799 return width; 867If PIXELWISE is nil and a line at the bottom of the text area is only
868partially visible, that counts as a whole line; to exclude
869partially-visible lines, use `window-text-height'. */)
870 (Lisp_Object window, Lisp_Object pixelwise)
871{
872 return make_number (window_body_height (decode_live_window (window),
873 NILP (pixelwise) ? 0 : 1));
800} 874}
801 875
802DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 1, 0, 876DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
803 doc: /* Return the height, in lines, of WINDOW's text area. 877 doc: /* Return the width, in columns, of WINDOW's text area.
804WINDOW must be a live window and defaults to the selected one. 878WINDOW must be a live window and defaults to the selected one.
805 879
806The returned height does not include the mode line or header line. 880Optional argument PIXELWISE non-nil means return the width in pixels.
807On a graphical display, the height is expressed as an integer multiple 881
808of the default character height. If a line at the bottom of the text 882The return value does not include any vertical dividers, fringe or
809area is only partially visible, that counts as a whole line; to 883marginal areas, or scroll bars. On a graphical display, the width is
810exclude partially-visible lines, use `window-text-height'. */) 884expressed as an integer multiple of the default character width if
885PIXELWISE is nil.
886
887If PIXELWISE is nil and a column at the right of the text area is only
888partially visible, that counts as a whole column; to exclude
889partially-visible columns, use `window-text-width'. */)
890 (Lisp_Object window, Lisp_Object pixelwise)
891{
892 return make_number (window_body_width (decode_live_window (window),
893 NILP (pixelwise) ? 0 : 1));
894}
895
896DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
897 Swindow_mode_line_height, 0, 1, 0,
898 doc: /* Return the height in pixel of WINDOW's mode-line.
899WINDOW must be a live window and defaults to the selected one. */)
811 (Lisp_Object window) 900 (Lisp_Object window)
812{ 901{
813 return make_number (window_body_lines (decode_live_window (window))); 902 return (make_number (WINDOW_MODE_LINE_HEIGHT (decode_live_window (window))));
814} 903}
815 904
816DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0, 905DEFUN ("window-header-line-height", Fwindow_header_line_height,
817 doc: /* Return the width, in columns, of WINDOW's text area. 906 Swindow_header_line_height, 0, 1, 0,
818WINDOW must be a live window and defaults to the selected one. 907 doc: /* Return the height in pixel of WINDOW's header-line.
908WINDOW must be a live window and defaults to the selected one. */)
909 (Lisp_Object window)
910{
911 return (make_number (WINDOW_HEADER_LINE_HEIGHT (decode_live_window (window))));
912}
819 913
820The return value does not include any vertical dividers, fringe or 914DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
821marginal areas, or scroll bars. On a graphical display, the width is 915 Swindow_right_divider_width, 0, 1, 0,
822expressed as an integer multiple of the default character width. */) 916 doc: /* Return the width of WINDOW's right divider.
917WINDOW must be a live window and defaults to the selected one. */)
918 (Lisp_Object window)
919{
920 return (make_number (WINDOW_RIGHT_DIVIDER_WIDTH (decode_live_window (window))));
921}
922
923DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
924 Swindow_bottom_divider_width, 0, 1, 0,
925 doc: /* Return the width of WINDOW's bottom divider.
926WINDOW must be a live window and defaults to the selected one. */)
823 (Lisp_Object window) 927 (Lisp_Object window)
824{ 928{
825 return make_number (window_body_cols (decode_live_window (window))); 929 return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window))));
826} 930}
827 931
828DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 932DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -1072,11 +1176,15 @@ display margins, fringes, header line, and/or mode line. */)
1072 1176
1073/* Test if the character at column X, row Y is within window W. 1177/* Test if the character at column X, row Y is within window W.
1074 If it is not, return ON_NOTHING; 1178 If it is not, return ON_NOTHING;
1179 if it is on the window's vertical divider, return
1180 ON_RIGHT_DIVIDER;
1181 if it is on the window's horizontal divider, return
1182 ON_BOTTOM_DIVIDER;
1075 if it is in the window's text area, return ON_TEXT; 1183 if it is in the window's text area, return ON_TEXT;
1076 if it is on the window's modeline, return ON_MODE_LINE; 1184 if it is on the window's modeline, return ON_MODE_LINE;
1077 if it is on the border between the window and its right sibling, 1185 if it is on the border between the window and its right sibling,
1078 return ON_VERTICAL_BORDER. 1186 return ON_VERTICAL_BORDER;
1079 if it is on a scroll bar, return ON_SCROLL_BAR. 1187 if it is on a scroll bar, return ON_SCROLL_BAR;
1080 if it is on the window's top line, return ON_HEADER_LINE; 1188 if it is on the window's top line, return ON_HEADER_LINE;
1081 if it is in left or right fringe of the window, 1189 if it is in left or right fringe of the window,
1082 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE; 1190 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
@@ -1104,13 +1212,28 @@ coordinates_in_window (register struct window *w, int x, int y)
1104 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x) 1212 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
1105 return ON_NOTHING; 1213 return ON_NOTHING;
1106 1214
1107 /* On the mode line or header line? */ 1215 /* On vertical window divider (which prevails horizontal
1108 if ((WINDOW_WANTS_MODELINE_P (w) 1216 dividers)? */
1109 && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w) 1217 if (!WINDOW_RIGHTMOST_P (w)
1110 && (part = ON_MODE_LINE)) 1218 && WINDOW_RIGHT_DIVIDER_WIDTH (w)
1111 || (WINDOW_WANTS_HEADER_LINE_P (w) 1219 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1112 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w) 1220 && x <= right_x)
1113 && (part = ON_HEADER_LINE))) 1221 return ON_RIGHT_DIVIDER;
1222 /* On the horizontal window divider? */
1223 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1224 && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1225 && y <= bottom_y)
1226 return ON_BOTTOM_DIVIDER;
1227 /* On the mode or header line? */
1228 else if ((WINDOW_WANTS_MODELINE_P (w)
1229 && y >= (bottom_y
1230 - CURRENT_MODE_LINE_HEIGHT (w)
1231 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1232 && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1233 && (part = ON_MODE_LINE))
1234 || (WINDOW_WANTS_HEADER_LINE_P (w)
1235 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
1236 && (part = ON_HEADER_LINE)))
1114 { 1237 {
1115 /* If it's under/over the scroll bar portion of the mode/header 1238 /* If it's under/over the scroll bar portion of the mode/header
1116 line, say it's on the vertical line. That's to be able to 1239 line, say it's on the vertical line. That's to be able to
@@ -1133,7 +1256,7 @@ coordinates_in_window (register struct window *w, int x, int y)
1133 if (w->pseudo_window_p) 1256 if (w->pseudo_window_p)
1134 { 1257 {
1135 left_x = 0; 1258 left_x = 0;
1136 right_x = WINDOW_TOTAL_WIDTH (w) - 1; 1259 right_x = WINDOW_PIXEL_WIDTH (w) - 1;
1137 } 1260 }
1138 else 1261 else
1139 { 1262 {
@@ -1163,6 +1286,8 @@ coordinates_in_window (register struct window *w, int x, int y)
1163 terminals, the vertical line's x coordinate is right_x. */ 1286 terminals, the vertical line's x coordinate is right_x. */
1164 else if (!w->pseudo_window_p 1287 else if (!w->pseudo_window_p
1165 && !WINDOW_RIGHTMOST_P (w) 1288 && !WINDOW_RIGHTMOST_P (w)
1289 /* Why check ux if we are not the rightmost window? Also
1290 shouldn't a pseudo window always be rightmost? */
1166 && x > right_x - ux) 1291 && x > right_x - ux)
1167 return ON_VERTICAL_BORDER; 1292 return ON_VERTICAL_BORDER;
1168 1293
@@ -1218,7 +1343,7 @@ window_relative_x_coord (struct window *w, enum window_part part, int x)
1218 case ON_RIGHT_MARGIN: 1343 case ON_RIGHT_MARGIN:
1219 return (x + 1 1344 return (x + 1
1220 - ((w->pseudo_window_p) 1345 - ((w->pseudo_window_p)
1221 ? WINDOW_TOTAL_WIDTH (w) 1346 ? WINDOW_PIXEL_WIDTH (w)
1222 : WINDOW_BOX_RIGHT_EDGE_X (w)) 1347 : WINDOW_BOX_RIGHT_EDGE_X (w))
1223 + window_box_width (w, RIGHT_MARGIN_AREA) 1348 + window_box_width (w, RIGHT_MARGIN_AREA)
1224 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) 1349 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
@@ -1303,6 +1428,12 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1303 /* Historically we are supposed to return nil in this case. */ 1428 /* Historically we are supposed to return nil in this case. */
1304 return Qnil; 1429 return Qnil;
1305 1430
1431 case ON_RIGHT_DIVIDER:
1432 return Qright_divider;
1433
1434 case ON_BOTTOM_DIVIDER:
1435 return Qbottom_divider;
1436
1306 default: 1437 default:
1307 emacs_abort (); 1438 emacs_abort ();
1308 } 1439 }
@@ -1553,7 +1684,7 @@ Return POS. */)
1553 set_marker_restricted (w->pointm, pos, w->contents); 1684 set_marker_restricted (w->pointm, pos, w->contents);
1554 /* We have to make sure that redisplay updates the window to show 1685 /* We have to make sure that redisplay updates the window to show
1555 the new value of point. */ 1686 the new value of point. */
1556 windows_or_buffers_changed = 25; 1687 wset_redisplay (w);
1557 } 1688 }
1558 1689
1559 return pos; 1690 return pos;
@@ -1574,9 +1705,9 @@ overriding motion of point in order to display at this exact start. */)
1574 if (NILP (noforce)) 1705 if (NILP (noforce))
1575 w->force_start = 1; 1706 w->force_start = 1;
1576 w->update_mode_line = 1; 1707 w->update_mode_line = 1;
1577 if (w != XWINDOW (selected_window)) 1708 /* Bug#15957. */
1578 /* Enforce full redisplay. FIXME: make it more selective. */ 1709 w->window_end_valid = 0;
1579 windows_or_buffers_changed = 26; 1710 wset_redisplay (w);
1580 1711
1581 return pos; 1712 return pos;
1582} 1713}
@@ -1995,6 +2126,10 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1995 2126
1996 if (setflag) 2127 if (setflag)
1997 { 2128 {
2129 n->pixel_left = o->pixel_left;
2130 n->pixel_top = o->pixel_top;
2131 n->pixel_width = o->pixel_width;
2132 n->pixel_height = o->pixel_height;
1998 n->left_col = o->left_col; 2133 n->left_col = o->left_col;
1999 n->top_line = o->top_line; 2134 n->top_line = o->top_line;
2000 n->total_cols = o->total_cols; 2135 n->total_cols = o->total_cols;
@@ -2075,13 +2210,13 @@ recombine_windows (Lisp_Object window)
2075 wset_parent (c, parent); 2210 wset_parent (c, parent);
2076 2211
2077 if (horflag) 2212 if (horflag)
2078 wset_normal_cols (c, 2213 wset_normal_cols
2079 make_float ((double) c->total_cols 2214 (c, make_float ((double) c->pixel_width
2080 / (double) p->total_cols)); 2215 / (double) p->pixel_width));
2081 else 2216 else
2082 wset_normal_lines (c, 2217 wset_normal_lines
2083 make_float ((double) c->total_lines 2218 (c, make_float ((double) c->pixel_height
2084 / (double) p->total_lines)); 2219 / (double) p->pixel_height));
2085 2220
2086 if (NILP (c->next)) 2221 if (NILP (c->next))
2087 { 2222 {
@@ -2137,7 +2272,7 @@ add_window_to_list (struct window *w, void *user_data)
2137 Vwindow_list is a list, return that list. Otherwise, build a new 2272 Vwindow_list is a list, return that list. Otherwise, build a new
2138 list, cache it in Vwindow_list, and return that. */ 2273 list, cache it in Vwindow_list, and return that. */
2139 2274
2140static Lisp_Object 2275Lisp_Object
2141window_list (void) 2276window_list (void)
2142{ 2277{
2143 if (!CONSP (Vwindow_list)) 2278 if (!CONSP (Vwindow_list))
@@ -2712,9 +2847,16 @@ selected frame and no others. */)
2712} 2847}
2713 2848
2714static Lisp_Object 2849static Lisp_Object
2715resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) 2850resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
2716{ 2851{
2717 return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore); 2852 return call5 (Qwindow_resize_root_window, window, delta, horizontal, ignore, pixelwise);
2853}
2854
2855
2856static Lisp_Object
2857window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
2858{
2859 return call2(Qwindow_pixel_to_total, frame, horizontal);
2718} 2860}
2719 2861
2720 2862
@@ -2778,8 +2920,8 @@ window-start value is reasonable when this function is called. */)
2778 { 2920 {
2779 startpos = marker_position (w->start); 2921 startpos = marker_position (w->start);
2780 startbyte = marker_byte_position (w->start); 2922 startbyte = marker_byte_position (w->start);
2781 top = WINDOW_TOP_EDGE_LINE (w) 2923 top = (WINDOW_TOP_EDGE_LINE (w)
2782 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2924 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))));
2783 /* Make sure WINDOW is the frame's selected window. */ 2925 /* Make sure WINDOW is the frame's selected window. */
2784 if (!EQ (window, FRAME_SELECTED_WINDOW (f))) 2926 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
2785 { 2927 {
@@ -2837,7 +2979,7 @@ window-start value is reasonable when this function is called. */)
2837 } 2979 }
2838 free_window_matrices (r); 2980 free_window_matrices (r);
2839 2981
2840 windows_or_buffers_changed = 27; 2982 fset_redisplay (f);
2841 Vwindow_list = Qnil; 2983 Vwindow_list = Qnil;
2842 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 2984 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2843 resize_failed = 0; 2985 resize_failed = 0;
@@ -2845,16 +2987,23 @@ window-start value is reasonable when this function is called. */)
2845 if (!WINDOW_LEAF_P (w)) 2987 if (!WINDOW_LEAF_P (w))
2846 { 2988 {
2847 /* Resize child windows vertically. */ 2989 /* Resize child windows vertically. */
2848 XSETINT (delta, r->total_lines - w->total_lines); 2990 XSETINT (delta, r->pixel_height - w->pixel_height);
2991 w->pixel_top = r->pixel_top;
2849 w->top_line = r->top_line; 2992 w->top_line = r->top_line;
2850 resize_root_window (window, delta, Qnil, Qnil); 2993 resize_root_window (window, delta, Qnil, Qnil, Qt);
2851 if (window_resize_check (w, 0)) 2994 if (window_resize_check (w, 0))
2852 window_resize_apply (w, 0); 2995 {
2996 window_resize_apply (w, 0);
2997 window_pixel_to_total (w->frame, Qnil);
2998 }
2853 else 2999 else
2854 { 3000 {
2855 resize_root_window (window, delta, Qnil, Qt); 3001 resize_root_window (window, delta, Qnil, Qt, Qt);
2856 if (window_resize_check (w, 0)) 3002 if (window_resize_check (w, 0))
2857 window_resize_apply (w, 0); 3003 {
3004 window_resize_apply (w, 0);
3005 window_pixel_to_total (w->frame, Qnil);
3006 }
2858 else 3007 else
2859 resize_failed = 1; 3008 resize_failed = 1;
2860 } 3009 }
@@ -2863,15 +3012,22 @@ window-start value is reasonable when this function is called. */)
2863 if (!resize_failed) 3012 if (!resize_failed)
2864 { 3013 {
2865 w->left_col = r->left_col; 3014 w->left_col = r->left_col;
2866 XSETINT (delta, r->total_cols - w->total_cols); 3015 w->pixel_left = r->pixel_left;
2867 resize_root_window (window, delta, Qt, Qnil); 3016 XSETINT (delta, r->pixel_width - w->pixel_width);
3017 resize_root_window (window, delta, Qt, Qnil, Qt);
2868 if (window_resize_check (w, 1)) 3018 if (window_resize_check (w, 1))
2869 window_resize_apply (w, 1); 3019 {
3020 window_resize_apply (w, 1);
3021 window_pixel_to_total (w->frame, Qt);
3022 }
2870 else 3023 else
2871 { 3024 {
2872 resize_root_window (window, delta, Qt, Qt); 3025 resize_root_window (window, delta, Qt, Qt, Qt);
2873 if (window_resize_check (w, 1)) 3026 if (window_resize_check (w, 1))
2874 window_resize_apply (w, 1); 3027 {
3028 window_resize_apply (w, 1);
3029 window_pixel_to_total (w->frame, Qt);
3030 }
2875 else 3031 else
2876 resize_failed = 1; 3032 resize_failed = 1;
2877 } 3033 }
@@ -2980,27 +3136,46 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
2980 } 3136 }
2981} 3137}
2982 3138
2983/* If *ROWS or *COLS are too small a size for FRAME, set them to the 3139/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
2984 minimum allowable size. */ 3140 minimum allowable size. PIXELWISE means interpret these as pixel
3141 sizes. */
2985 3142
2986void 3143void
2987check_frame_size (struct frame *frame, int *rows, int *cols) 3144check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
2988{ 3145{
2989 /* For height, we have to see: 3146 /* For height, we have to see:
2990 how many windows the frame has at minimum (one or two), 3147 how many windows the frame has at minimum (one or two),
2991 and whether it has a menu bar or other special stuff at the top. */ 3148 and whether it has a menu bar or other special stuff at the top. */
2992 int min_height 3149 if (pixelwise)
2993 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame)) 3150 {
2994 ? MIN_SAFE_WINDOW_HEIGHT 3151 int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
2995 : 2 * MIN_SAFE_WINDOW_HEIGHT); 3152 int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
3153
3154 if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
3155 min_height = 2 * min_height;
2996 3156
2997 if (FRAME_TOP_MARGIN (frame) > 0) 3157 min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
2998 min_height += FRAME_TOP_MARGIN (frame);
2999 3158
3000 if (*rows < min_height) 3159 if (*height < min_height)
3001 *rows = min_height; 3160 *height = min_height;
3002 if (*cols < MIN_SAFE_WINDOW_WIDTH) 3161 if (*width < min_width)
3003 *cols = MIN_SAFE_WINDOW_WIDTH; 3162 *width = min_width;
3163 }
3164 else
3165 {
3166 int min_height
3167 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
3168 ? MIN_SAFE_WINDOW_HEIGHT
3169 : 2 * MIN_SAFE_WINDOW_HEIGHT);
3170
3171 if (FRAME_TOP_MARGIN (frame) > 0)
3172 min_height += FRAME_TOP_MARGIN (frame);
3173
3174 if (*height < min_height)
3175 *height = min_height;
3176 if (*width < MIN_SAFE_WINDOW_WIDTH)
3177 *width = MIN_SAFE_WINDOW_WIDTH;
3178 }
3004} 3179}
3005 3180
3006/* Adjust the margins of window W if text area is too small. 3181/* Adjust the margins of window W if text area is too small.
@@ -3010,31 +3185,37 @@ check_frame_size (struct frame *frame, int *rows, int *cols)
3010static int 3185static int
3011adjust_window_margins (struct window *w) 3186adjust_window_margins (struct window *w)
3012{ 3187{
3013 int box_cols = (WINDOW_TOTAL_COLS (w) 3188 int box_width = (WINDOW_PIXEL_WIDTH (w)
3014 - WINDOW_FRINGE_COLS (w) 3189 - WINDOW_FRINGES_WIDTH (w)
3015 - WINDOW_SCROLL_BAR_COLS (w)); 3190 - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
3016 int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w) 3191 int margin_width = WINDOW_MARGINS_WIDTH (w);
3017 + WINDOW_RIGHT_MARGIN_COLS (w));
3018 3192
3019 if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH) 3193 if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3020 return 1; 3194 return 1;
3021 3195
3022 if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH) 3196 if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3023 return 0; 3197 return 0;
3024 3198 else
3025 /* Window's text area is too narrow, but reducing the window 3199 /* Window's text area is too narrow, but reducing the window
3026 margins will fix that. */ 3200 margins will fix that. */
3027 margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
3028 if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
3029 { 3201 {
3030 if (WINDOW_LEFT_MARGIN_COLS (w) > 0) 3202 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
3031 w->left_margin_cols = w->right_margin_cols = margin_cols / 2; 3203
3204 margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
3205
3206 if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
3207 {
3208 if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
3209 w->left_margin_cols = w->right_margin_cols =
3210 margin_width / (2 * unit);
3211 else
3212 w->right_margin_cols = margin_width / unit;
3213 }
3032 else 3214 else
3033 w->right_margin_cols = margin_cols; 3215 w->left_margin_cols = margin_width / unit;
3216
3217 return 1;
3034 } 3218 }
3035 else
3036 w->left_margin_cols = margin_cols;
3037 return 1;
3038} 3219}
3039 3220
3040/* The following three routines are needed for running a window's 3221/* The following three routines are needed for running a window's
@@ -3119,11 +3300,23 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
3119 return Qnil; 3300 return Qnil;
3120} 3301}
3121 3302
3122/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 3303DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions,
3123 means it's allowed to run hooks. See make_frame for a case where 3304 Srun_window_scroll_functions, 0, 1, 0,
3124 it's not allowed. KEEP_MARGINS_P non-zero means that the current 3305 doc: /* Run `window-scroll-functions' for WINDOW.
3125 margins, fringes, and scroll-bar settings of the window are not 3306If WINDOW is omitted or nil, it defaults to the selected window. */)
3126 reset from the buffer's local settings. */ 3307 (Lisp_Object window)
3308{
3309 if (! NILP (Vwindow_scroll_functions))
3310 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3311 Fmarker_position (decode_live_window (window)->start));
3312 return Qnil;
3313}
3314
3315/* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
3316 to run hooks. See make_frame for a case where it's not allowed.
3317 KEEP_MARGINS_P non-zero means that the current margins, fringes, and
3318 scroll-bar settings of the window are not reset from the buffer's
3319 local settings. */
3127 3320
3128void 3321void
3129set_window_buffer (Lisp_Object window, Lisp_Object buffer, 3322set_window_buffer (Lisp_Object window, Lisp_Object buffer,
@@ -3132,7 +3325,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3132 struct window *w = XWINDOW (window); 3325 struct window *w = XWINDOW (window);
3133 struct buffer *b = XBUFFER (buffer); 3326 struct buffer *b = XBUFFER (buffer);
3134 ptrdiff_t count = SPECPDL_INDEX (); 3327 ptrdiff_t count = SPECPDL_INDEX ();
3135 int samebuf = EQ (buffer, w->contents); 3328 bool samebuf = EQ (buffer, w->contents);
3136 3329
3137 wset_buffer (w, buffer); 3330 wset_buffer (w, buffer);
3138 3331
@@ -3171,7 +3364,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3171 } 3364 }
3172 /* Maybe we could move this into the `if' but it's not obviously safe and 3365 /* Maybe we could move this into the `if' but it's not obviously safe and
3173 I doubt it's worth the trouble. */ 3366 I doubt it's worth the trouble. */
3174 windows_or_buffers_changed = 28; 3367 wset_redisplay (w);
3175 3368
3176 /* We must select BUFFER for running the window-scroll-functions. */ 3369 /* We must select BUFFER for running the window-scroll-functions. */
3177 /* We can't check ! NILP (Vwindow_scroll_functions) here 3370 /* We can't check ! NILP (Vwindow_scroll_functions) here
@@ -3202,14 +3395,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3202 if (! NILP (Vwindow_scroll_functions)) 3395 if (! NILP (Vwindow_scroll_functions))
3203 run_hook_with_args_2 (Qwindow_scroll_functions, window, 3396 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3204 Fmarker_position (w->start)); 3397 Fmarker_position (w->start));
3205 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w))); 3398 if (!samebuf)
3399 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
3206 } 3400 }
3207 3401
3208 unbind_to (count, Qnil); 3402 unbind_to (count, Qnil);
3209} 3403}
3210 3404
3211DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, 3405DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
3212 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. 3406 doc: /* Make WINDOW display BUFFER-OR-NAME.
3213WINDOW must be a live window and defaults to the selected one. 3407WINDOW must be a live window and defaults to the selected one.
3214BUFFER-OR-NAME must be a buffer or the name of an existing buffer. 3408BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3215 3409
@@ -3381,6 +3575,8 @@ make_parent_window (Lisp_Object window, bool horflag)
3381 adjust_window_count (p, 1); 3575 adjust_window_count (p, 1);
3382 XSETWINDOW (parent, p); 3576 XSETWINDOW (parent, p);
3383 3577
3578 p->sequence_number = ++sequence_number;
3579
3384 replace_window (window, parent, 1); 3580 replace_window (window, parent, 1);
3385 3581
3386 wset_next (o, Qnil); 3582 wset_next (o, Qnil);
@@ -3409,6 +3605,7 @@ make_window (void)
3409 wset_normal_cols (w, make_float (1.0)); 3605 wset_normal_cols (w, make_float (1.0));
3410 wset_new_total (w, make_number (0)); 3606 wset_new_total (w, make_number (0));
3411 wset_new_normal (w, make_number (0)); 3607 wset_new_normal (w, make_number (0));
3608 wset_new_pixel (w, make_number (0));
3412 wset_start (w, Fmake_marker ()); 3609 wset_start (w, Fmake_marker ());
3413 wset_pointm (w, Fmake_marker ()); 3610 wset_pointm (w, Fmake_marker ());
3414 wset_vertical_scroll_bar_type (w, Qt); 3611 wset_vertical_scroll_bar_type (w, Qt);
@@ -3426,6 +3623,7 @@ make_window (void)
3426 w->phys_cursor_type = NO_CURSOR; 3623 w->phys_cursor_type = NO_CURSOR;
3427 w->phys_cursor_width = -1; 3624 w->phys_cursor_width = -1;
3428#endif 3625#endif
3626 w->sequence_number = ++sequence_number;
3429 w->scroll_bar_width = -1; 3627 w->scroll_bar_width = -1;
3430 w->column_number_displayed = -1; 3628 w->column_number_displayed = -1;
3431 3629
@@ -3436,6 +3634,30 @@ make_window (void)
3436 return window; 3634 return window;
3437} 3635}
3438 3636
3637DEFUN ("set-window-new-pixel", Fset_window_new_pixel, Sset_window_new_pixel, 2, 3, 0,
3638 doc: /* Set new pixel size of WINDOW to SIZE.
3639WINDOW must be a valid window and defaults to the selected one.
3640Return SIZE.
3641
3642Optional argument ADD non-nil means add SIZE to the new pixel size of
3643WINDOW and return the sum.
3644
3645Note: This function does not operate on any child windows of WINDOW. */)
3646 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
3647{
3648 struct window *w = decode_valid_window (window);
3649 EMACS_INT size_min = NILP (add) ? 0 : - XINT (w->new_pixel);
3650 EMACS_INT size_max = size_min + min (INT_MAX, MOST_POSITIVE_FIXNUM);
3651
3652 CHECK_RANGED_INTEGER (size, size_min, size_max);
3653 if (NILP (add))
3654 wset_new_pixel (w, size);
3655 else
3656 wset_new_pixel (w, make_number (XINT (w->new_pixel) + XINT (size)));
3657
3658 return w->new_pixel;
3659}
3660
3439DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0, 3661DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
3440 doc: /* Set new total size of WINDOW to SIZE. 3662 doc: /* Set new total size of WINDOW to SIZE.
3441WINDOW must be a valid window and defaults to the selected one. 3663WINDOW must be a valid window and defaults to the selected one.
@@ -3470,8 +3692,8 @@ Note: This function does not operate on any child windows of WINDOW. */)
3470 return size; 3692 return size;
3471} 3693}
3472 3694
3473/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is 3695/* Return 1 if setting w->pixel_height (w->pixel_width if HORFLAG is
3474 non-zero) to w->new_total would result in correct heights (widths) 3696 non-zero) to w->new_pixel would result in correct heights (widths)
3475 for window W and recursively all child windows of W. 3697 for window W and recursively all child windows of W.
3476 3698
3477 Note: This function does not check any of `window-fixed-size-p', 3699 Note: This function does not check any of `window-fixed-size-p',
@@ -3480,6 +3702,7 @@ Note: This function does not operate on any child windows of WINDOW. */)
3480static int 3702static int
3481window_resize_check (struct window *w, bool horflag) 3703window_resize_check (struct window *w, bool horflag)
3482{ 3704{
3705 struct frame *f = XFRAME (w->frame);
3483 struct window *c; 3706 struct window *c;
3484 3707
3485 if (WINDOW_VERTICAL_COMBINATION_P (w)) 3708 if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -3491,26 +3714,33 @@ window_resize_check (struct window *w, bool horflag)
3491 { 3714 {
3492 while (c) 3715 while (c)
3493 { 3716 {
3494 if ((XINT (c->new_total) != XINT (w->new_total)) 3717 if (XINT (c->new_pixel) != XINT (w->new_pixel)
3495 || !window_resize_check (c, horflag)) 3718 || !window_resize_check (c, horflag))
3496 return 0; 3719 return 0;
3720
3497 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3721 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3498 } 3722 }
3723
3499 return 1; 3724 return 1;
3500 } 3725 }
3501 else 3726 else
3502 /* The sum of the heights of the child windows of W must equal 3727 /* The sum of the heights of the child windows of W must equal
3503 W's height. */ 3728 W's height. */
3504 { 3729 {
3505 int sum_of_sizes = 0; 3730 int remaining_pixels = XINT (w->new_pixel);
3731
3506 while (c) 3732 while (c)
3507 { 3733 {
3508 if (!window_resize_check (c, horflag)) 3734 if (!window_resize_check (c, horflag))
3509 return 0; 3735 return 0;
3510 sum_of_sizes = sum_of_sizes + XINT (c->new_total); 3736
3737 remaining_pixels -= XINT (c->new_pixel);
3738 if (remaining_pixels < 0)
3739 return 0;
3511 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3740 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3512 } 3741 }
3513 return (sum_of_sizes == XINT (w->new_total)); 3742
3743 return remaining_pixels == 0;
3514 } 3744 }
3515 } 3745 }
3516 else if (WINDOW_HORIZONTAL_COMBINATION_P (w)) 3746 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
@@ -3521,26 +3751,33 @@ window_resize_check (struct window *w, bool horflag)
3521 /* The sum of the widths of the child windows of W must equal W's 3751 /* The sum of the widths of the child windows of W must equal W's
3522 width. */ 3752 width. */
3523 { 3753 {
3524 int sum_of_sizes = 0; 3754 int remaining_pixels = XINT (w->new_pixel);
3755
3525 while (c) 3756 while (c)
3526 { 3757 {
3527 if (!window_resize_check (c, horflag)) 3758 if (!window_resize_check (c, horflag))
3528 return 0; 3759 return 0;
3529 sum_of_sizes = sum_of_sizes + XINT (c->new_total); 3760
3761 remaining_pixels -= XINT (c->new_pixel);
3762 if (remaining_pixels < 0)
3763 return 0;
3530 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3764 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3531 } 3765 }
3532 return (sum_of_sizes == XINT (w->new_total)); 3766
3767 return remaining_pixels == 0;
3533 } 3768 }
3534 else 3769 else
3535 /* All child windows of W must have the same height as W. */ 3770 /* All child windows of W must have the same height as W. */
3536 { 3771 {
3537 while (c) 3772 while (c)
3538 { 3773 {
3539 if ((XINT (c->new_total) != XINT (w->new_total)) 3774 if (XINT (c->new_pixel) != XINT (w->new_pixel)
3540 || !window_resize_check (c, horflag)) 3775 || !window_resize_check (c, horflag))
3541 return 0; 3776 return 0;
3777
3542 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3778 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3543 } 3779 }
3780
3544 return 1; 3781 return 1;
3545 } 3782 }
3546 } 3783 }
@@ -3548,12 +3785,15 @@ window_resize_check (struct window *w, bool horflag)
3548 /* A leaf window. Make sure it's not too small. The following 3785 /* A leaf window. Make sure it's not too small. The following
3549 hardcodes the values of `window-safe-min-width' (2) and 3786 hardcodes the values of `window-safe-min-width' (2) and
3550 `window-safe-min-height' (1) which are defined in window.el. */ 3787 `window-safe-min-height' (1) which are defined in window.el. */
3551 return XINT (w->new_total) >= (horflag ? 2 : 1); 3788 return (XINT (w->new_pixel) >= (horflag
3789 ? (2 * FRAME_COLUMN_WIDTH (f))
3790 : FRAME_LINE_HEIGHT (f)));
3552} 3791}
3553 3792
3554/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to 3793
3555 w->new_total for window W and recursively all child windows of W. 3794/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
3556 Also calculate and assign the new vertical (horizontal) start 3795 w->new_pixel for window W and recursively all child windows of W.
3796 Also calculate and assign the new vertical (horizontal) pixel start
3557 positions of each of these windows. 3797 positions of each of these windows.
3558 3798
3559 This function does not perform any error checks. Make sure you have 3799 This function does not perform any error checks. Make sure you have
@@ -3562,25 +3802,30 @@ static void
3562window_resize_apply (struct window *w, bool horflag) 3802window_resize_apply (struct window *w, bool horflag)
3563{ 3803{
3564 struct window *c; 3804 struct window *c;
3565 int pos; 3805 int edge;
3806 int unit = (horflag
3807 ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))
3808 : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
3566 3809
3567 /* Note: Assigning new_normal requires that the new total size of the 3810 /* Note: Assigning new_normal requires that the new total size of the
3568 parent window has been set *before*. */ 3811 parent window has been set *before*. */
3569 if (horflag) 3812 if (horflag)
3570 { 3813 {
3571 w->total_cols = XFASTINT (w->new_total); 3814 w->pixel_width = XFASTINT (w->new_pixel);
3815 w->total_cols = w->pixel_width / unit;
3572 if (NUMBERP (w->new_normal)) 3816 if (NUMBERP (w->new_normal))
3573 wset_normal_cols (w, w->new_normal); 3817 wset_normal_cols (w, w->new_normal);
3574 3818
3575 pos = w->left_col; 3819 edge = w->pixel_left;
3576 } 3820 }
3577 else 3821 else
3578 { 3822 {
3579 w->total_lines = XFASTINT (w->new_total); 3823 w->pixel_height = XFASTINT (w->new_pixel);
3824 w->total_lines = w->pixel_height / unit;
3580 if (NUMBERP (w->new_normal)) 3825 if (NUMBERP (w->new_normal))
3581 wset_normal_lines (w, w->new_normal); 3826 wset_normal_lines (w, w->new_normal);
3582 3827
3583 pos = w->top_line; 3828 edge = w->pixel_top;
3584 } 3829 }
3585 3830
3586 if (WINDOW_VERTICAL_COMBINATION_P (w)) 3831 if (WINDOW_VERTICAL_COMBINATION_P (w))
@@ -3590,12 +3835,19 @@ window_resize_apply (struct window *w, bool horflag)
3590 while (c) 3835 while (c)
3591 { 3836 {
3592 if (horflag) 3837 if (horflag)
3593 c->left_col = pos; 3838 {
3839 c->pixel_left = edge;
3840 c->left_col = edge / unit;
3841 }
3594 else 3842 else
3595 c->top_line = pos; 3843 {
3844 c->pixel_top = edge;
3845 c->top_line = edge / unit;
3846 }
3596 window_resize_apply (c, horflag); 3847 window_resize_apply (c, horflag);
3597 if (!horflag) 3848 if (!horflag)
3598 pos = pos + c->total_lines; 3849 edge = edge + c->pixel_height;
3850
3599 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3851 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3600 } 3852 }
3601 } 3853 }
@@ -3606,18 +3858,90 @@ window_resize_apply (struct window *w, bool horflag)
3606 while (c) 3858 while (c)
3607 { 3859 {
3608 if (horflag) 3860 if (horflag)
3609 c->left_col = pos; 3861 {
3862 c->pixel_left = edge;
3863 c->left_col = edge / unit;
3864 }
3610 else 3865 else
3611 c->top_line = pos; 3866 {
3867 c->pixel_top = edge;
3868 c->top_line = edge / unit;
3869 }
3870
3612 window_resize_apply (c, horflag); 3871 window_resize_apply (c, horflag);
3613 if (horflag) 3872 if (horflag)
3614 pos = pos + c->total_cols; 3873 edge = edge + c->pixel_width;
3874
3615 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3875 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3616 } 3876 }
3617 } 3877 }
3878 else
3879 /* Bug#15957. */
3880 w->window_end_valid = 0;
3618} 3881}
3619 3882
3620 3883
3884/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
3885 w->new_total for window W and recursively all child windows of W.
3886 Also calculate and assign the new vertical (horizontal) start
3887 positions of each of these windows. */
3888static void
3889window_resize_apply_total (struct window *w, bool horflag)
3890{
3891 struct window *c;
3892 int edge;
3893
3894 /* Note: Assigning new_normal requires that the new total size of the
3895 parent window has been set *before*. */
3896 if (horflag)
3897 {
3898 w->total_cols = XFASTINT (w->new_total);
3899 edge = w->left_col;
3900 }
3901 else
3902 {
3903 w->total_lines = XFASTINT (w->new_total);
3904 edge = w->top_line;
3905 }
3906
3907 if (WINDOW_VERTICAL_COMBINATION_P (w))
3908 /* W is a vertical combination. */
3909 {
3910 c = XWINDOW (w->contents);
3911 while (c)
3912 {
3913 if (horflag)
3914 c->left_col = edge;
3915 else
3916 c->top_line = edge;
3917
3918 window_resize_apply_total (c, horflag);
3919 if (!horflag)
3920 edge = edge + c->total_lines;
3921
3922 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3923 }
3924 }
3925 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3926 /* W is a horizontal combination. */
3927 {
3928 c = XWINDOW (w->contents);
3929 while (c)
3930 {
3931 if (horflag)
3932 c->left_col = edge;
3933 else
3934 c->top_line = edge;
3935
3936 window_resize_apply_total (c, horflag);
3937 if (horflag)
3938 edge = edge + c->total_cols;
3939
3940 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3941 }
3942 }
3943}
3944
3621DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0, 3945DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
3622 doc: /* Apply requested size values for window-tree of FRAME. 3946 doc: /* Apply requested size values for window-tree of FRAME.
3623If FRAME is omitted or nil, it defaults to the selected frame. 3947If FRAME is omitted or nil, it defaults to the selected frame.
@@ -3639,20 +3963,44 @@ be applied on the Elisp level. */)
3639 bool horflag = !NILP (horizontal); 3963 bool horflag = !NILP (horizontal);
3640 3964
3641 if (!window_resize_check (r, horflag) 3965 if (!window_resize_check (r, horflag)
3642 || (XINT (r->new_total) 3966 || (XINT (r->new_pixel)
3643 != (horflag ? r->total_cols : r->total_lines))) 3967 != (horflag ? r->pixel_width : r->pixel_height)))
3644 return Qnil; 3968 return Qnil;
3645 3969
3646 block_input (); 3970 block_input ();
3647 window_resize_apply (r, horflag); 3971 window_resize_apply (r, horflag);
3648 3972
3649 windows_or_buffers_changed = 30; 3973 fset_redisplay (f);
3650 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 3974 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3651 3975
3652 adjust_frame_glyphs (f); 3976 adjust_frame_glyphs (f);
3653 unblock_input (); 3977 unblock_input ();
3654 3978
3655 run_window_configuration_change_hook (f); 3979 return Qt;
3980}
3981
3982
3983DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total, Swindow_resize_apply_total, 0, 2, 0,
3984 doc: /* Apply requested total size values for window-tree of FRAME.
3985If FRAME is omitted or nil, it defaults to the selected frame.
3986
3987This function does not assign pixel or normal size values. You should
3988have run `window-resize-apply' before running this.
3989
3990Optional argument HORIZONTAL omitted or nil means apply requested
3991height values. HORIZONTAL non-nil means apply requested width
3992values. */)
3993 (Lisp_Object frame, Lisp_Object horizontal)
3994{
3995 struct frame *f = decode_live_frame (frame);
3996 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3997
3998 block_input ();
3999 /* Necessary when deleting the top-/or leftmost window. */
4000 r->left_col = 0;
4001 r->top_line = FRAME_TOP_MARGIN (f);
4002 window_resize_apply_total (r, !NILP (horizontal));
4003 unblock_input ();
3656 4004
3657 return Qt; 4005 return Qt;
3658} 4006}
@@ -3660,59 +4008,107 @@ be applied on the Elisp level. */)
3660 4008
3661/* Resize frame F's windows when number of lines of F is set to SIZE. 4009/* Resize frame F's windows when number of lines of F is set to SIZE.
3662 HORFLAG 1 means resize windows when number of columns of F is set to 4010 HORFLAG 1 means resize windows when number of columns of F is set to
3663 SIZE. 4011 SIZE. PIXELWISE 1 means to interpret SIZE as pixels.
3664 4012
3665 This function can delete all windows but the selected one in order to 4013 This function can delete all windows but the selected one in order to
3666 satisfy the request. The result will be meaningful if and only if 4014 satisfy the request. The result will be meaningful if and only if
3667 F's windows have meaningful sizes when you call this. */ 4015 F's windows have meaningful sizes when you call this. */
3668void 4016void
3669resize_frame_windows (struct frame *f, int size, bool horflag) 4017resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
3670{ 4018{
3671 Lisp_Object root = f->root_window; 4019 Lisp_Object root = f->root_window;
3672 struct window *r = XWINDOW (root); 4020 struct window *r = XWINDOW (root);
3673 Lisp_Object mini = f->minibuffer_window; 4021 Lisp_Object mini = f->minibuffer_window;
3674 struct window *m; 4022 struct window *m;
4023 /* old_size is the old size of the frame's root window. */
4024 int old_size = horflag ? r->total_cols : r->total_lines;
4025 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
3675 /* new_size is the new size of the frame's root window. */ 4026 /* new_size is the new size of the frame's root window. */
3676 int new_size = (horflag 4027 int new_size, new_pixel_size;
3677 ? size 4028
3678 : (size 4029 if (pixelwise)
3679 - FRAME_TOP_MARGIN (f) 4030 {
3680 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 4031 new_pixel_size
3681 ? 1 : 0))); 4032 = (horflag
4033 ? size
4034 : (size
4035 - FRAME_TOP_MARGIN_HEIGHT (f)
4036 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4037 ? FRAME_LINE_HEIGHT (f) : 0)));
4038 new_size = new_pixel_size / (horflag
4039 ? FRAME_COLUMN_WIDTH (f)
4040 : FRAME_LINE_HEIGHT (f));
4041 }
4042 else
4043 {
4044 new_size= (horflag
4045 ? size
4046 : (size
4047 - FRAME_TOP_MARGIN (f)
4048 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4049 ? 1 : 0)));
4050 new_pixel_size = new_size * (horflag
4051 ? FRAME_COLUMN_WIDTH (f)
4052 : FRAME_LINE_HEIGHT (f));
4053 }
3682 4054
3683 r->top_line = FRAME_TOP_MARGIN (f); 4055 r->top_line = FRAME_TOP_MARGIN (f);
3684 if (WINDOW_LEAF_P (r)) 4056 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4057
4058 if (new_pixel_size == old_pixel_size)
4059 return;
4060 else if (WINDOW_LEAF_P (r))
3685 /* For a leaf root window just set the size. */ 4061 /* For a leaf root window just set the size. */
3686 if (horflag) 4062 if (horflag)
3687 r->total_cols = new_size; 4063 {
4064 r->total_cols = new_size;
4065 r->pixel_width = new_pixel_size;
4066 }
3688 else 4067 else
3689 r->total_lines = new_size; 4068 {
4069 r->total_lines = new_size;
4070 r->pixel_height = new_pixel_size;
4071 }
3690 else 4072 else
3691 { 4073 {
3692 /* old_size is the old size of the frame's root window. */
3693 int old_size = horflag ? r->total_cols : r->total_lines;
3694 Lisp_Object delta; 4074 Lisp_Object delta;
3695 4075
3696 XSETINT (delta, new_size - old_size); 4076 if (pixelwise)
4077 XSETINT (delta, new_pixel_size - old_pixel_size);
4078 else
4079 XSETINT (delta, new_size - old_size);
4080
3697 /* Try a "normal" resize first. */ 4081 /* Try a "normal" resize first. */
3698 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil); 4082 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil,
4083 pixelwise ? Qt : Qnil);
3699 if (window_resize_check (r, horflag) 4084 if (window_resize_check (r, horflag)
3700 && new_size == XINT (r->new_total)) 4085 && new_pixel_size == XINT (r->new_pixel))
3701 window_resize_apply (r, horflag); 4086 {
4087 window_resize_apply (r, horflag);
4088 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4089 }
3702 else 4090 else
3703 { 4091 {
3704 /* Try with "reasonable" minimum sizes next. */ 4092 /* Try with "reasonable" minimum sizes next. */
3705 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt); 4093 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt,
4094 pixelwise ? Qt : Qnil);
3706 if (window_resize_check (r, horflag) 4095 if (window_resize_check (r, horflag)
3707 && new_size == XINT (r->new_total)) 4096 && new_pixel_size == XINT (r->new_pixel))
3708 window_resize_apply (r, horflag); 4097 {
4098 window_resize_apply (r, horflag);
4099 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4100 }
3709 else 4101 else
3710 { 4102 {
3711 /* Finally, try with "safe" minimum sizes. */ 4103 /* Finally, try with "safe" minimum sizes. */
3712 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe); 4104 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe,
4105 pixelwise ? Qt : Qnil);
3713 if (window_resize_check (r, horflag) 4106 if (window_resize_check (r, horflag)
3714 && new_size == XINT (r->new_total)) 4107 && new_pixel_size == XINT (r->new_pixel))
3715 window_resize_apply (r, horflag); 4108 {
4109 window_resize_apply (r, horflag);
4110 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4111 }
3716 else 4112 else
3717 { 4113 {
3718 /* We lost. Delete all windows but the frame's 4114 /* We lost. Delete all windows but the frame's
@@ -3720,9 +4116,15 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
3720 root = f->selected_window; 4116 root = f->selected_window;
3721 Fdelete_other_windows_internal (root, Qnil); 4117 Fdelete_other_windows_internal (root, Qnil);
3722 if (horflag) 4118 if (horflag)
3723 XWINDOW (root)->total_cols = new_size; 4119 {
4120 XWINDOW (root)->total_cols = new_size;
4121 XWINDOW (root)->pixel_width = new_pixel_size;
4122 }
3724 else 4123 else
3725 XWINDOW (root)->total_lines = new_size; 4124 {
4125 XWINDOW (root)->total_lines = new_size;
4126 XWINDOW (root)->pixel_height = new_pixel_size;
4127 }
3726 } 4128 }
3727 } 4129 }
3728 } 4130 }
@@ -3732,42 +4134,47 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
3732 { 4134 {
3733 m = XWINDOW (mini); 4135 m = XWINDOW (mini);
3734 if (horflag) 4136 if (horflag)
3735 m->total_cols = size; 4137 {
4138 m->total_cols = size;
4139 m->pixel_width = new_pixel_size;
4140 }
3736 else 4141 else
3737 { 4142 {
3738 /* Are we sure we always want 1 line here? */ 4143 /* Are we sure we always want 1 line here? */
3739 m->total_lines = 1; 4144 m->total_lines = 1;
4145 m->pixel_height = FRAME_LINE_HEIGHT (f);
3740 m->top_line = r->top_line + r->total_lines; 4146 m->top_line = r->top_line + r->total_lines;
4147 m->pixel_top = r->pixel_top + r->pixel_height;
3741 } 4148 }
3742 } 4149 }
3743 4150
3744 windows_or_buffers_changed = 31; 4151 fset_redisplay (f);
3745} 4152}
3746 4153
3747 4154
3748DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, 4155DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
3749 doc: /* Split window OLD. 4156 doc: /* Split window OLD.
3750Second argument TOTAL-SIZE specifies the number of lines or columns of the 4157Second argument PIXEL-SIZE specifies the number of pixels of the
3751new window. In any case TOTAL-SIZE must be a positive integer. 4158new window. In any case TOTAL-SIZE must be a positive integer.
3752 4159
3753Third argument SIDE nil (or `below') specifies that the new window shall 4160Third argument SIDE nil (or `below') specifies that the new window shall
3754be located below WINDOW. SIDE `above' means the new window shall be 4161be located below WINDOW. SIDE `above' means the new window shall be
3755located above WINDOW. In both cases TOTAL-SIZE specifies the number of 4162located above WINDOW. In both cases PIXEL-SIZE specifies the pixel
3756lines of the new window including space reserved for the mode and/or 4163height of the new window including space reserved for the mode and/or
3757header line. 4164header line.
3758 4165
3759SIDE t (or `right') specifies that the new window shall be located on 4166SIDE t (or `right') specifies that the new window shall be located on
3760the right side of WINDOW. SIDE `left' means the new window shall be 4167the right side of WINDOW. SIDE `left' means the new window shall be
3761located on the left of WINDOW. In both cases TOTAL-SIZE specifies the 4168located on the left of WINDOW. In both cases PIXEL-SIZE specifies the
3762number of columns of the new window including space reserved for fringes 4169width of the new window including space reserved for fringes and the
3763and the scrollbar or a divider column. 4170scrollbar or a divider column.
3764 4171
3765Fourth argument NORMAL-SIZE specifies the normal size of the new window 4172Fourth argument NORMAL-SIZE specifies the normal size of the new window
3766according to the SIDE argument. 4173according to the SIDE argument.
3767 4174
3768The new total and normal sizes of all involved windows must have been 4175The new pixel and normal sizes of all involved windows must have been
3769set correctly. See the code of `split-window' for how this is done. */) 4176set correctly. See the code of `split-window' for how this is done. */)
3770 (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size) 4177 (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
3771{ 4178{
3772 /* OLD (*o) is the window we have to split. (*p) is either OLD's 4179 /* OLD (*o) is the window we have to split. (*p) is either OLD's
3773 parent window or an internal window we have to install as OLD's new 4180 parent window or an internal window we have to install as OLD's new
@@ -3776,19 +4183,24 @@ set correctly. See the code of `split-window' for how this is done. */)
3776 NEW (*n) is the new window created with some parameters taken from 4183 NEW (*n) is the new window created with some parameters taken from
3777 REFERENCE (*r). */ 4184 REFERENCE (*r). */
3778 register Lisp_Object new, frame, reference; 4185 register Lisp_Object new, frame, reference;
3779 register struct window *o, *p, *n, *r; 4186 register struct window *o, *p, *n, *r, *c;
3780 struct frame *f; 4187 struct frame *f;
3781 bool horflag 4188 bool horflag
3782 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ 4189 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3783 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); 4190 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3784 int combination_limit = 0; 4191 int combination_limit = 0, sum = 0;
4192 int total_size;
3785 4193
3786 CHECK_WINDOW (old); 4194 CHECK_WINDOW (old);
3787 o = XWINDOW (old); 4195 o = XWINDOW (old);
3788 frame = WINDOW_FRAME (o); 4196 frame = WINDOW_FRAME (o);
3789 f = XFRAME (frame); 4197 f = XFRAME (frame);
3790 4198
3791 CHECK_NUMBER (total_size); 4199 CHECK_NUMBER (pixel_size);
4200 total_size
4201 = XINT (pixel_size) / (horflag
4202 ? FRAME_COLUMN_WIDTH (f)
4203 : FRAME_LINE_HEIGHT (f));
3792 4204
3793 /* Set combination_limit to 1 if we have to make a new parent window. 4205 /* Set combination_limit to 1 if we have to make a new parent window.
3794 We do that if either `window-combination-limit' is t, or OLD has no 4206 We do that if either `window-combination-limit' is t, or OLD has no
@@ -3812,7 +4224,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3812 /* The following bugs are caught by `split-window'. */ 4224 /* The following bugs are caught by `split-window'. */
3813 if (MINI_WINDOW_P (o)) 4225 if (MINI_WINDOW_P (o))
3814 error ("Attempt to split minibuffer window"); 4226 error ("Attempt to split minibuffer window");
3815 else if (XINT (total_size) < (horflag ? 2 : 1)) 4227 else if (total_size < (horflag ? 2 : 1))
3816 error ("Size of new window too small (after split)"); 4228 error ("Size of new window too small (after split)");
3817 else if (!combination_limit && !NILP (Vwindow_combination_resize)) 4229 else if (!combination_limit && !NILP (Vwindow_combination_resize))
3818 /* `window-combination-resize' non-nil means try to resize OLD's siblings 4230 /* `window-combination-resize' non-nil means try to resize OLD's siblings
@@ -3820,26 +4232,25 @@ set correctly. See the code of `split-window' for how this is done. */)
3820 { 4232 {
3821 p = XWINDOW (o->parent); 4233 p = XWINDOW (o->parent);
3822 /* Temporarily pretend we split the parent window. */ 4234 /* Temporarily pretend we split the parent window. */
3823 wset_new_total 4235 wset_new_pixel
3824 (p, make_number ((horflag ? p->total_cols : p->total_lines) 4236 (p, make_number ((horflag ? p->pixel_width : p->pixel_height)
3825 - XINT (total_size))); 4237 - XINT (pixel_size)));
3826 if (!window_resize_check (p, horflag)) 4238 if (!window_resize_check (p, horflag))
3827 error ("Window sizes don't fit"); 4239 error ("Window sizes don't fit");
3828 else 4240 else
3829 /* Undo the temporary pretension. */ 4241 /* Undo the temporary pretension. */
3830 wset_new_total (p, make_number 4242 wset_new_pixel (p, make_number (horflag ? p->pixel_width : p->pixel_height));
3831 (horflag ? p->total_cols : p->total_lines));
3832 } 4243 }
3833 else 4244 else
3834 { 4245 {
3835 if (!window_resize_check (o, horflag)) 4246 if (!window_resize_check (o, horflag))
3836 error ("Resizing old window failed"); 4247 error ("Resizing old window failed");
3837 else if (XINT (total_size) + XINT (o->new_total) 4248 else if (XINT (pixel_size) + XINT (o->new_pixel)
3838 != (horflag ? o->total_cols : o->total_lines)) 4249 != (horflag ? o->pixel_width : o->pixel_height))
3839 error ("Sum of sizes of old and new window don't fit"); 4250 error ("Sum of sizes of old and new window don't fit");
3840 } 4251 }
3841 4252
3842 /* This is our point of no return. */ 4253 /* This is our point of no return. */
3843 if (combination_limit) 4254 if (combination_limit)
3844 { 4255 {
3845 /* Save the old value of o->normal_cols/lines. It gets corrupted 4256 /* Save the old value of o->normal_cols/lines. It gets corrupted
@@ -3855,14 +4266,16 @@ set correctly. See the code of `split-window' for how this is done. */)
3855 that its children get merged into another window. */ 4266 that its children get merged into another window. */
3856 wset_combination_limit (p, Qt); 4267 wset_combination_limit (p, Qt);
3857 /* These get applied below. */ 4268 /* These get applied below. */
3858 wset_new_total (p, make_number 4269 wset_new_pixel
3859 (horflag ? o->total_cols : o->total_lines)); 4270 (p, make_number (horflag ? o->pixel_width : o->pixel_height));
4271 wset_new_total
4272 (p, make_number (horflag ? o->total_cols : o->total_lines));
3860 wset_new_normal (p, new_normal); 4273 wset_new_normal (p, new_normal);
3861 } 4274 }
3862 else 4275 else
3863 p = XWINDOW (o->parent); 4276 p = XWINDOW (o->parent);
3864 4277
3865 windows_or_buffers_changed = 32; 4278 fset_redisplay (f);
3866 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4279 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3867 new = make_window (); 4280 new = make_window ();
3868 n = XWINDOW (new); 4281 n = XWINDOW (new);
@@ -3903,18 +4316,33 @@ set correctly. See the code of `split-window' for how this is done. */)
3903 /* Directly assign orthogonal coordinates and sizes. */ 4316 /* Directly assign orthogonal coordinates and sizes. */
3904 if (horflag) 4317 if (horflag)
3905 { 4318 {
4319 n->pixel_top = o->pixel_top;
3906 n->top_line = o->top_line; 4320 n->top_line = o->top_line;
4321 n->pixel_height = o->pixel_height;
3907 n->total_lines = o->total_lines; 4322 n->total_lines = o->total_lines;
3908 } 4323 }
3909 else 4324 else
3910 { 4325 {
4326 n->pixel_left = o->pixel_left;
3911 n->left_col = o->left_col; 4327 n->left_col = o->left_col;
4328 n->pixel_width = o->pixel_width;
3912 n->total_cols = o->total_cols; 4329 n->total_cols = o->total_cols;
3913 } 4330 }
3914 4331
3915 /* Iso-coordinates and sizes are assigned by window_resize_apply, 4332 /* Iso-coordinates and sizes are assigned by window_resize_apply,
3916 get them ready here. */ 4333 get them ready here. */
3917 wset_new_total (n, total_size); 4334 wset_new_pixel (n, pixel_size);
4335 c = XWINDOW (p->contents);
4336 while (c)
4337 {
4338 if (c != n)
4339 sum = sum + XINT (c->new_total);
4340 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4341 }
4342 wset_new_total (n, make_number ((horflag
4343 ? p->total_cols
4344 : p->total_lines)
4345 - sum));
3918 wset_new_normal (n, normal_size); 4346 wset_new_normal (n, normal_size);
3919 4347
3920 block_input (); 4348 block_input ();
@@ -3993,15 +4421,14 @@ Signal an error when WINDOW is the only window on its frame. */)
3993 } 4421 }
3994 4422
3995 if (window_resize_check (r, horflag) 4423 if (window_resize_check (r, horflag)
3996 && (XINT (r->new_total) 4424 && (XINT (r->new_pixel)
3997 == (horflag ? r->total_cols : r->total_lines))) 4425 == (horflag ? r->pixel_width : r->pixel_height)))
3998 /* We can delete WINDOW now. */ 4426 /* We can delete WINDOW now. */
3999 { 4427 {
4000 4428
4001 /* Block input. */ 4429 /* Block input. */
4002 block_input (); 4430 block_input ();
4003 window_resize_apply (p, horflag); 4431 window_resize_apply (p, horflag);
4004
4005 /* If this window is referred to by the dpyinfo's mouse 4432 /* If this window is referred to by the dpyinfo's mouse
4006 highlight, invalidate that slot to be safe (Bug#9904). */ 4433 highlight, invalidate that slot to be safe (Bug#9904). */
4007 if (!FRAME_INITIAL_P (f)) 4434 if (!FRAME_INITIAL_P (f))
@@ -4012,7 +4439,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4012 hlinfo->mouse_face_window = Qnil; 4439 hlinfo->mouse_face_window = Qnil;
4013 } 4440 }
4014 4441
4015 windows_or_buffers_changed = 33; 4442 fset_redisplay (f);
4016 Vwindow_list = Qnil; 4443 Vwindow_list = Qnil;
4017 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4444 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4018 4445
@@ -4112,54 +4539,76 @@ Signal an error when WINDOW is the only window on its frame. */)
4112/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we 4539/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4113 can. */ 4540 can. */
4114void 4541void
4115grow_mini_window (struct window *w, int delta) 4542grow_mini_window (struct window *w, int delta, bool pixelwise)
4116{ 4543{
4117 struct frame *f = XFRAME (w->frame); 4544 struct frame *f = XFRAME (w->frame);
4118 struct window *r; 4545 struct window *r;
4119 Lisp_Object root, value; 4546 Lisp_Object root, height;
4547 int line_height, pixel_height;
4120 4548
4121 eassert (MINI_WINDOW_P (w)); 4549 eassert (MINI_WINDOW_P (w));
4122 eassert (delta >= 0); 4550 eassert (delta >= 0);
4123 4551
4124 root = FRAME_ROOT_WINDOW (f); 4552 if (delta > 0)
4125 r = XWINDOW (root);
4126 value = call2 (Qwindow_resize_root_window_vertically,
4127 root, make_number (- delta));
4128 if (INTEGERP (value) && window_resize_check (r, 0))
4129 { 4553 {
4130 block_input (); 4554 root = FRAME_ROOT_WINDOW (f);
4131 window_resize_apply (r, 0); 4555 r = XWINDOW (root);
4556 height = call3 (Qwindow_resize_root_window_vertically,
4557 root, make_number (- delta), pixelwise ? Qt : Qnil);
4558 if (INTEGERP (height) && window_resize_check (r, 0))
4559 {
4560 block_input ();
4561 window_resize_apply (r, 0);
4132 4562
4133 /* Grow the mini-window. */ 4563 if (pixelwise)
4134 w->top_line = r->top_line + r->total_lines; 4564 {
4135 w->total_lines -= XINT (value); 4565 pixel_height = min (-XINT (height), INT_MAX - w->pixel_height);
4136 /* Enforce full redisplay. FIXME: make it more selective. */ 4566 line_height = pixel_height / FRAME_LINE_HEIGHT (f);
4137 windows_or_buffers_changed = 34; 4567 }
4138 adjust_frame_glyphs (f); 4568 else
4139 unblock_input (); 4569 {
4570 line_height = min (-XINT (height),
4571 ((INT_MAX - w->pixel_height)
4572 / FRAME_LINE_HEIGHT (f)));
4573 pixel_height = line_height * FRAME_LINE_HEIGHT (f);
4574 }
4575
4576 /* Grow the mini-window. */
4577 w->pixel_top = r->pixel_top + r->pixel_height;
4578 w->top_line = r->top_line + r->total_lines;
4579 w->pixel_height += pixel_height;
4580 w->total_lines += line_height;
4581
4582 /* Enforce full redisplay of the frame. */
4583 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4584 fset_redisplay (f);
4585 adjust_frame_glyphs (f);
4586 unblock_input ();
4587 }
4140 } 4588 }
4141} 4589}
4142 4590
4143 4591/* Shrink mini-window W to one line. */
4144/* Shrink mini-window W. */
4145void 4592void
4146shrink_mini_window (struct window *w) 4593shrink_mini_window (struct window *w, bool pixelwise)
4147{ 4594{
4148 struct frame *f = XFRAME (w->frame); 4595 struct frame *f = XFRAME (w->frame);
4149 struct window *r; 4596 struct window *r;
4150 Lisp_Object root, value; 4597 Lisp_Object root, delta;
4151 EMACS_INT size; 4598 EMACS_INT height, unit;
4152 4599
4153 eassert (MINI_WINDOW_P (w)); 4600 eassert (MINI_WINDOW_P (w));
4154 4601
4155 size = w->total_lines; 4602 height = pixelwise ? w->pixel_height : w->total_lines;
4156 if (size > 1) 4603 unit = pixelwise ? FRAME_LINE_HEIGHT (f) : 1;
4604 if (height > unit)
4157 { 4605 {
4158 root = FRAME_ROOT_WINDOW (f); 4606 root = FRAME_ROOT_WINDOW (f);
4159 r = XWINDOW (root); 4607 r = XWINDOW (root);
4160 value = call2 (Qwindow_resize_root_window_vertically, 4608 delta = call3 (Qwindow_resize_root_window_vertically,
4161 root, make_number (size - 1)); 4609 root, make_number (height - unit),
4162 if (INTEGERP (value) && window_resize_check (r, 0)) 4610 pixelwise ? Qt : Qnil);
4611 if (INTEGERP (delta) && window_resize_check (r, 0))
4163 { 4612 {
4164 block_input (); 4613 block_input ();
4165 window_resize_apply (r, 0); 4614 window_resize_apply (r, 0);
@@ -4167,8 +4616,11 @@ shrink_mini_window (struct window *w)
4167 /* Shrink the mini-window. */ 4616 /* Shrink the mini-window. */
4168 w->top_line = r->top_line + r->total_lines; 4617 w->top_line = r->top_line + r->total_lines;
4169 w->total_lines = 1; 4618 w->total_lines = 1;
4170 /* Enforce full redisplay. FIXME: make it more selective. */ 4619 w->pixel_top = r->pixel_top + r->pixel_height;
4171 windows_or_buffers_changed = 35; 4620 w->pixel_height = FRAME_LINE_HEIGHT (f);
4621 /* Enforce full redisplay of the frame. */
4622 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4623 fset_redisplay (f);
4172 adjust_frame_glyphs (f); 4624 adjust_frame_glyphs (f);
4173 unblock_input (); 4625 unblock_input ();
4174 } 4626 }
@@ -4197,26 +4649,27 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4197 error ("Cannot resize a minibuffer-only frame"); 4649 error ("Cannot resize a minibuffer-only frame");
4198 4650
4199 r = XWINDOW (FRAME_ROOT_WINDOW (f)); 4651 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4200 height = r->total_lines + w->total_lines; 4652 height = r->pixel_height + w->pixel_height;
4201 if (window_resize_check (r, 0) 4653 if (window_resize_check (r, 0)
4202 && XINT (w->new_total) > 0 4654 && XINT (w->new_pixel) > 0
4203 && height == XINT (r->new_total) + XINT (w->new_total)) 4655 && height == XINT (r->new_pixel) + XINT (w->new_pixel))
4204 { 4656 {
4205 block_input (); 4657 block_input ();
4206 window_resize_apply (r, 0); 4658 window_resize_apply (r, 0);
4207 4659
4208 w->total_lines = XFASTINT (w->new_total); 4660 w->total_lines = XFASTINT (w->new_total);
4209 w->top_line = r->top_line + r->total_lines; 4661 w->top_line = r->top_line + r->total_lines;
4662 w->pixel_height = XFASTINT (w->new_pixel);
4663 w->pixel_top = r->pixel_top + r->pixel_height;
4210 4664
4211 windows_or_buffers_changed = 36; 4665 fset_redisplay (f);
4212 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4666 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4213 adjust_frame_glyphs (f); 4667 adjust_frame_glyphs (f);
4214 unblock_input (); 4668 unblock_input ();
4215
4216 run_window_configuration_change_hook (f);
4217 return Qt; 4669 return Qt;
4218 } 4670 }
4219 else error ("Failed to resize minibuffer window"); 4671 else
4672 error ("Failed to resize minibuffer window");
4220} 4673}
4221 4674
4222/* Mark window cursors off for all windows in the window tree rooted 4675/* Mark window cursors off for all windows in the window tree rooted
@@ -4279,6 +4732,8 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
4279 immediate_quit = 1; 4732 immediate_quit = 1;
4280 n = clip_to_bounds (INT_MIN, n, INT_MAX); 4733 n = clip_to_bounds (INT_MIN, n, INT_MAX);
4281 4734
4735 wset_redisplay (XWINDOW (window));
4736
4282 /* If we must, use the pixel-based version which is much slower than 4737 /* If we must, use the pixel-based version which is much slower than
4283 the line-based one but can handle varying line heights. */ 4738 the line-based one but can handle varying line heights. */
4284 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame))) 4739 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
@@ -4286,6 +4741,8 @@ window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
4286 else 4741 else
4287 window_scroll_line_based (window, n, whole, noerror); 4742 window_scroll_line_based (window, n, whole, noerror);
4288 4743
4744 /* Bug#15957. */
4745 XWINDOW (window)->window_end_valid = 0;
4289 immediate_quit = 0; 4746 immediate_quit = 0;
4290} 4747}
4291 4748
@@ -4828,9 +5285,6 @@ scroll_command (Lisp_Object n, int direction)
4828 { 5285 {
4829 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 5286 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4830 Fset_buffer (XWINDOW (selected_window)->contents); 5287 Fset_buffer (XWINDOW (selected_window)->contents);
4831
4832 /* Make redisplay consider other windows than just selected_window. */
4833 windows_or_buffers_changed = 37;
4834 } 5288 }
4835 5289
4836 if (NILP (n)) 5290 if (NILP (n))
@@ -4940,7 +5394,6 @@ specifies the window to scroll. This takes precedence over
4940 5394
4941 /* Don't screw up if window_scroll gets an error. */ 5395 /* Don't screw up if window_scroll gets an error. */
4942 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 5396 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4943 windows_or_buffers_changed = 38;
4944 5397
4945 Fset_buffer (w->contents); 5398 Fset_buffer (w->contents);
4946 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm)); 5399 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
@@ -4976,7 +5429,7 @@ by this function. This happens in an interactive call. */)
4976{ 5429{
4977 struct window *w = XWINDOW (selected_window); 5430 struct window *w = XWINDOW (selected_window);
4978 EMACS_INT requested_arg = (NILP (arg) 5431 EMACS_INT requested_arg = (NILP (arg)
4979 ? window_body_cols (w) - 2 5432 ? window_body_width (w, 0) - 2
4980 : XINT (Fprefix_numeric_value (arg))); 5433 : XINT (Fprefix_numeric_value (arg)));
4981 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg); 5434 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
4982 5435
@@ -4999,7 +5452,7 @@ by this function. This happens in an interactive call. */)
4999{ 5452{
5000 struct window *w = XWINDOW (selected_window); 5453 struct window *w = XWINDOW (selected_window);
5001 EMACS_INT requested_arg = (NILP (arg) 5454 EMACS_INT requested_arg = (NILP (arg)
5002 ? window_body_cols (w) - 2 5455 ? window_body_width (w, 0) - 2
5003 : XINT (Fprefix_numeric_value (arg))); 5456 : XINT (Fprefix_numeric_value (arg)));
5004 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg); 5457 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
5005 5458
@@ -5273,22 +5726,36 @@ and redisplay normally--don't erase and redraw the frame. */)
5273 return Qnil; 5726 return Qnil;
5274} 5727}
5275 5728
5276DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5729DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
5277 0, 1, 0, 5730 0, 1, 0,
5278 doc: /* Return the height in lines of the text display area of WINDOW. 5731 doc: /* Return the width in columns of the text display area of WINDOW.
5279WINDOW must be a live window and defaults to the selected one. 5732WINDOW must be a live window and defaults to the selected one.
5280 5733
5281The returned height does not include the mode line, any header line, 5734The returned width does not include dividers, scrollbars, margins,
5282nor any partial-height lines at the bottom of the text area. */) 5735fringes, nor any partial-width columns at the right of the text
5736area. */)
5283 (Lisp_Object window) 5737 (Lisp_Object window)
5284{ 5738{
5285 struct window *w = decode_live_window (window); 5739 struct window *w = decode_live_window (window);
5286 int pixel_height = window_box_height (w); 5740
5287 int line_height = pixel_height / FRAME_LINE_HEIGHT (XFRAME (w->frame)); 5741 return make_number (window_box_width (w, TEXT_AREA)
5288 return make_number (line_height); 5742 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
5289} 5743}
5290 5744
5745DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5746 0, 1, 0,
5747 doc: /* Return the height in lines of the text display area of WINDOW.
5748WINDOW must be a live window and defaults to the selected one.
5749
5750The returned height does not include dividers, the mode line, any header
5751line, nor any partial-height lines at the bottom of the text area. */)
5752 (Lisp_Object window)
5753{
5754 struct window *w = decode_live_window (window);
5291 5755
5756 return make_number (window_box_height (w)
5757 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
5758}
5292 5759
5293DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, 5760DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
5294 1, 1, "P", 5761 1, 1, "P",
@@ -5381,9 +5848,15 @@ struct save_window_data
5381 5848
5382 /* All fields above are traced by the GC. 5849 /* All fields above are traced by the GC.
5383 From `frame-cols' down, the fields are ignored by the GC. */ 5850 From `frame-cols' down, the fields are ignored by the GC. */
5384 5851 /* We should be able to do without the following two. */
5385 int frame_cols, frame_lines, frame_menu_bar_lines; 5852 int frame_cols, frame_lines;
5386 int frame_tool_bar_lines; 5853 /* These two should get eventually replaced by their pixel
5854 counterparts. */
5855 int frame_menu_bar_lines, frame_tool_bar_lines;
5856 int frame_text_width, frame_text_height;
5857 /* These are currently unused. We need them as soon as we convert
5858 to pixels. */
5859 int frame_menu_bar_height, frame_tool_bar_height;
5387 }; 5860 };
5388 5861
5389/* This is saved as a Lisp_Vector */ 5862/* This is saved as a Lisp_Vector */
@@ -5392,6 +5865,7 @@ struct saved_window
5392 struct vectorlike_header header; 5865 struct vectorlike_header header;
5393 5866
5394 Lisp_Object window, buffer, start, pointm, mark; 5867 Lisp_Object window, buffer, start, pointm, mark;
5868 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
5395 Lisp_Object left_col, top_line, total_cols, total_lines; 5869 Lisp_Object left_col, top_line, total_cols, total_lines;
5396 Lisp_Object normal_cols, normal_lines; 5870 Lisp_Object normal_cols, normal_lines;
5397 Lisp_Object hscroll, min_hscroll; 5871 Lisp_Object hscroll, min_hscroll;
@@ -5512,8 +5986,12 @@ the return value is nil. Otherwise the value is t. */)
5512 made, we change the frame to the size specified in the 5986 made, we change the frame to the size specified in the
5513 configuration, restore the configuration, and then resize it 5987 configuration, restore the configuration, and then resize it
5514 back. We keep track of the prevailing height in these variables. */ 5988 back. We keep track of the prevailing height in these variables. */
5515 int previous_frame_lines = FRAME_LINES (f); 5989 int previous_frame_text_height = FRAME_TEXT_HEIGHT (f);
5516 int previous_frame_cols = FRAME_COLS (f); 5990 int previous_frame_text_width = FRAME_TEXT_WIDTH (f);
5991 /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */
5992 /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */
5993 /* int previous_frame_lines = FRAME_LINES (f); */
5994 /* int previous_frame_cols = FRAME_COLS (f); */
5517 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); 5995 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
5518 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); 5996 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
5519 5997
@@ -5536,13 +6014,12 @@ the return value is nil. Otherwise the value is t. */)
5536 if it runs during this. */ 6014 if it runs during this. */
5537 block_input (); 6015 block_input ();
5538 6016
5539 if (data->frame_lines != previous_frame_lines 6017 if (data->frame_text_width != previous_frame_text_width
5540 || data->frame_cols != previous_frame_cols) 6018 || data->frame_text_height != previous_frame_text_height)
5541 change_frame_size (f, data->frame_lines, 6019 change_frame_size (f, data->frame_text_width,
5542 data->frame_cols, 0, 0, 0); 6020 data->frame_text_height, 0, 0, 0, 1);
5543#ifdef HAVE_MENUS 6021
5544 if (data->frame_menu_bar_lines 6022 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
5545 != previous_frame_menu_bar_lines)
5546 { 6023 {
5547#ifdef HAVE_WINDOW_SYSTEM 6024#ifdef HAVE_WINDOW_SYSTEM
5548 if (FRAME_WINDOW_P (f)) 6025 if (FRAME_WINDOW_P (f))
@@ -5553,10 +6030,8 @@ the return value is nil. Otherwise the value is t. */)
5553 set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), 6030 set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
5554 make_number (0)); 6031 make_number (0));
5555 } 6032 }
5556#endif
5557#ifdef HAVE_WINDOW_SYSTEM 6033#ifdef HAVE_WINDOW_SYSTEM
5558 if (data->frame_tool_bar_lines 6034 if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines)
5559 != previous_frame_tool_bar_lines)
5560 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines), 6035 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
5561 make_number (0)); 6036 make_number (0));
5562#endif 6037#endif
@@ -5575,7 +6050,7 @@ the return value is nil. Otherwise the value is t. */)
5575 BUF_PT_BYTE (XBUFFER (w->contents))); 6050 BUF_PT_BYTE (XBUFFER (w->contents)));
5576 } 6051 }
5577 6052
5578 windows_or_buffers_changed = 39; 6053 fset_redisplay (f);
5579 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 6054 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
5580 6055
5581 /* Problem: Freeing all matrices and later allocating them again 6056 /* Problem: Freeing all matrices and later allocating them again
@@ -5628,6 +6103,10 @@ the return value is nil. Otherwise the value is t. */)
5628 /* If we squirreled away the buffer, restore it now. */ 6103 /* If we squirreled away the buffer, restore it now. */
5629 if (BUFFERP (w->combination_limit)) 6104 if (BUFFERP (w->combination_limit))
5630 wset_buffer (w, w->combination_limit); 6105 wset_buffer (w, w->combination_limit);
6106 w->pixel_left = XFASTINT (p->pixel_left);
6107 w->pixel_top = XFASTINT (p->pixel_top);
6108 w->pixel_width = XFASTINT (p->pixel_width);
6109 w->pixel_height = XFASTINT (p->pixel_height);
5631 w->left_col = XFASTINT (p->left_col); 6110 w->left_col = XFASTINT (p->left_col);
5632 w->top_line = XFASTINT (p->top_line); 6111 w->top_line = XFASTINT (p->top_line);
5633 w->total_cols = XFASTINT (p->total_cols); 6112 w->total_cols = XFASTINT (p->total_cols);
@@ -5728,25 +6207,17 @@ the return value is nil. Otherwise the value is t. */)
5728 make_number (old_point), 6207 make_number (old_point),
5729 XWINDOW (data->current_window)->contents); 6208 XWINDOW (data->current_window)->contents);
5730 6209
5731 /* In the following call to `select-window', prevent "swapping out
5732 point" in the old selected window using the buffer that has
5733 been restored into it. We already swapped out that point from
5734 that window's old buffer. */
5735 select_window (data->current_window, Qnil, 1);
5736 BVAR (XBUFFER (XWINDOW (selected_window)->contents), last_selected_window)
5737 = selected_window;
5738
5739 if (NILP (data->focus_frame) 6210 if (NILP (data->focus_frame)
5740 || (FRAMEP (data->focus_frame) 6211 || (FRAMEP (data->focus_frame)
5741 && FRAME_LIVE_P (XFRAME (data->focus_frame)))) 6212 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
5742 Fredirect_frame_focus (frame, data->focus_frame); 6213 Fredirect_frame_focus (frame, data->focus_frame);
5743 6214
5744 /* Set the screen height to the value it had before this function. */ 6215 /* Set the frame size to the value it had before this function. */
5745 if (previous_frame_lines != FRAME_LINES (f) 6216 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
5746 || previous_frame_cols != FRAME_COLS (f)) 6217 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
5747 change_frame_size (f, previous_frame_lines, previous_frame_cols, 6218 change_frame_size (f, previous_frame_text_width,
5748 0, 0, 0); 6219 previous_frame_text_height, 0, 0, 0, 1);
5749#ifdef HAVE_MENUS 6220
5750 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) 6221 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
5751 { 6222 {
5752#ifdef HAVE_WINDOW_SYSTEM 6223#ifdef HAVE_WINDOW_SYSTEM
@@ -5759,7 +6230,6 @@ the return value is nil. Otherwise the value is t. */)
5759 set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), 6230 set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
5760 make_number (0)); 6231 make_number (0));
5761 } 6232 }
5762#endif
5763#ifdef HAVE_WINDOW_SYSTEM 6233#ifdef HAVE_WINDOW_SYSTEM
5764 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f)) 6234 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f))
5765 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines), 6235 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines),
@@ -5786,6 +6256,20 @@ the return value is nil. Otherwise the value is t. */)
5786 delete_deletable_window (window); 6256 delete_deletable_window (window);
5787 } 6257 }
5788 6258
6259 /* In the following call to `select-window', prevent "swapping out
6260 point" in the old selected window using the buffer that has
6261 been restored into it. We already swapped out that point from
6262 that window's old buffer. */
6263 /* This `select_window' calls record_buffer which calls Fdelq which
6264 invokes QUIT, so we do it here at the end rather than earlier,
6265 to minimize the risk of interrupting the Fset_window_configuration
6266 in an inconsistent state (e.g. before frame-focus redirection is
6267 canceled). */
6268 select_window (data->current_window, Qnil, 1);
6269 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6270 last_selected_window)
6271 = selected_window;
6272
5789 /* Fselect_window will have made f the selected frame, so we 6273 /* Fselect_window will have made f the selected frame, so we
5790 reselect the proper frame here. Fhandle_switch_frame will change the 6274 reselect the proper frame here. Fhandle_switch_frame will change the
5791 selected window too, but that doesn't make the call to 6275 selected window too, but that doesn't make the call to
@@ -5938,6 +6422,10 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
5938 wset_temslot (w, make_number (i)); i++; 6422 wset_temslot (w, make_number (i)); i++;
5939 p->window = window; 6423 p->window = window;
5940 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil); 6424 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
6425 p->pixel_left = make_number (w->pixel_left);
6426 p->pixel_top = make_number (w->pixel_top);
6427 p->pixel_width = make_number (w->pixel_width);
6428 p->pixel_height = make_number (w->pixel_height);
5941 p->left_col = make_number (w->left_col); 6429 p->left_col = make_number (w->left_col);
5942 p->top_line = make_number (w->top_line); 6430 p->top_line = make_number (w->top_line);
5943 p->total_cols = make_number (w->total_cols); 6431 p->total_cols = make_number (w->total_cols);
@@ -6077,6 +6565,10 @@ saved by this function. */)
6077 data->frame_lines = FRAME_LINES (f); 6565 data->frame_lines = FRAME_LINES (f);
6078 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); 6566 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
6079 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); 6567 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
6568 data->frame_text_width = FRAME_TEXT_WIDTH (f);
6569 data->frame_text_height = FRAME_TEXT_HEIGHT (f);
6570 data->frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
6571 data->frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
6080 data->selected_frame = selected_frame; 6572 data->selected_frame = selected_frame;
6081 data->current_window = FRAME_SELECTED_WINDOW (f); 6573 data->current_window = FRAME_SELECTED_WINDOW (f);
6082 XSETBUFFER (data->current_buffer, current_buffer); 6574 XSETBUFFER (data->current_buffer, current_buffer);
@@ -6103,7 +6595,7 @@ apply_window_adjustment (struct window *w)
6103 adjust_window_margins (w); 6595 adjust_window_margins (w);
6104 clear_glyph_matrix (w->current_matrix); 6596 clear_glyph_matrix (w->current_matrix);
6105 w->window_end_valid = 0; 6597 w->window_end_valid = 0;
6106 windows_or_buffers_changed = 40; 6598 wset_redisplay (w);
6107 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w))); 6599 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
6108} 6600}
6109 6601
@@ -6163,8 +6655,10 @@ as nil. */)
6163 (Lisp_Object window) 6655 (Lisp_Object window)
6164{ 6656{
6165 struct window *w = decode_live_window (window); 6657 struct window *w = decode_live_window (window);
6166 return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil, 6658 return Fcons (w->left_margin_cols
6167 w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil); 6659 ? make_number (w->left_margin_cols) : Qnil,
6660 w->right_margin_cols
6661 ? make_number (w->right_margin_cols) : Qnil);
6168} 6662}
6169 6663
6170 6664
@@ -6274,15 +6768,14 @@ DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6274 doc: /* Set width and type of scroll bars of window WINDOW. 6768 doc: /* Set width and type of scroll bars of window WINDOW.
6275WINDOW must be a live window and defaults to the selected one. 6769WINDOW must be a live window and defaults to the selected one.
6276 6770
6277Second parameter WIDTH specifies the pixel width for the scroll bar; 6771Second parameter WIDTH specifies the pixel width for the scroll bar.
6278this is automatically adjusted to a multiple of the frame column width.
6279Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 6772Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6280bar: left, right, or nil. 6773bar: left, right, or nil.
6281If WIDTH is nil, use the frame's scroll-bar width. 6774If WIDTH is nil, use the frame's scroll-bar width.
6282If VERTICAL-TYPE is t, use the frame's scroll-bar type. 6775If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6283Fourth parameter HORIZONTAL-TYPE is currently unused. 6776Fourth parameter HORIZONTAL-TYPE is currently unused.
6284 6777
6285Return t if scroll bars was actually changed and nil otherwise. */) 6778Return t if scroll bars were actually changed and nil otherwise. */)
6286 (Lisp_Object window, Lisp_Object width, 6779 (Lisp_Object window, Lisp_Object width,
6287 Lisp_Object vertical_type, Lisp_Object horizontal_type) 6780 Lisp_Object vertical_type, Lisp_Object horizontal_type)
6288{ 6781{
@@ -6477,6 +6970,10 @@ compare_window_configurations (Lisp_Object configuration1,
6477 != EQ (d2->current_window, sw2->window) 6970 != EQ (d2->current_window, sw2->window)
6478 /* Windows' buffers must match. */ 6971 /* Windows' buffers must match. */
6479 || !EQ (sw1->buffer, sw2->buffer) 6972 || !EQ (sw1->buffer, sw2->buffer)
6973 || !EQ (sw1->pixel_left, sw2->pixel_left)
6974 || !EQ (sw1->pixel_top, sw2->pixel_top)
6975 || !EQ (sw1->pixel_height, sw2->pixel_height)
6976 || !EQ (sw1->pixel_width, sw2->pixel_width)
6480 || !EQ (sw1->left_col, sw2->left_col) 6977 || !EQ (sw1->left_col, sw2->left_col)
6481 || !EQ (sw1->top_line, sw2->top_line) 6978 || !EQ (sw1->top_line, sw2->top_line)
6482 || !EQ (sw1->total_cols, sw2->total_cols) 6979 || !EQ (sw1->total_cols, sw2->total_cols)
@@ -6555,6 +7052,7 @@ syms_of_window (void)
6555 DEFSYM (Qdelete_window, "delete-window"); 7052 DEFSYM (Qdelete_window, "delete-window");
6556 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); 7053 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
6557 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); 7054 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
7055 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
6558 DEFSYM (Qsafe, "safe"); 7056 DEFSYM (Qsafe, "safe");
6559 DEFSYM (Qdisplay_buffer, "display-buffer"); 7057 DEFSYM (Qdisplay_buffer, "display-buffer");
6560 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows"); 7058 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
@@ -6713,6 +7211,18 @@ Parameters not saved by `current-window-configuration' or
6713respectively are not installed by `window-state-put'. */); 7211respectively are not installed by `window-state-put'. */);
6714 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt)); 7212 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
6715 7213
7214 DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
7215 doc: /* Non-nil means resizing windows works pixelwise.
7216Functions currently affected by this option are `split-window',
7217`maximize-window', `minimize-window', `fit-window-to-buffer' and
7218`fit-frame-to-buffer' and all functions symmetrically resizing a
7219parent window.
7220
7221Note that when a frame's pixel size is not a multiple of the
7222frame's character size, at least one window may get resized
7223pixelwise even if this option is nil. */);
7224 window_resize_pixelwise = 0;
7225
6716 defsubr (&Sselected_window); 7226 defsubr (&Sselected_window);
6717 defsubr (&Sminibuffer_window); 7227 defsubr (&Sminibuffer_window);
6718 defsubr (&Swindow_minibuffer_p); 7228 defsubr (&Swindow_minibuffer_p);
@@ -6735,16 +7245,23 @@ respectively are not installed by `window-state-put'. */);
6735 defsubr (&Swindow_combination_limit); 7245 defsubr (&Swindow_combination_limit);
6736 defsubr (&Sset_window_combination_limit); 7246 defsubr (&Sset_window_combination_limit);
6737 defsubr (&Swindow_use_time); 7247 defsubr (&Swindow_use_time);
6738 defsubr (&Swindow_top_line); 7248 defsubr (&Swindow_pixel_width);
6739 defsubr (&Swindow_left_column); 7249 defsubr (&Swindow_pixel_height);
6740 defsubr (&Swindow_total_height);
6741 defsubr (&Swindow_total_width); 7250 defsubr (&Swindow_total_width);
7251 defsubr (&Swindow_total_height);
6742 defsubr (&Swindow_normal_size); 7252 defsubr (&Swindow_normal_size);
7253 defsubr (&Swindow_new_pixel);
6743 defsubr (&Swindow_new_total); 7254 defsubr (&Swindow_new_total);
6744 defsubr (&Swindow_new_normal); 7255 defsubr (&Swindow_new_normal);
7256 defsubr (&Swindow_pixel_left);
7257 defsubr (&Swindow_pixel_top);
7258 defsubr (&Swindow_left_column);
7259 defsubr (&Swindow_top_line);
7260 defsubr (&Sset_window_new_pixel);
6745 defsubr (&Sset_window_new_total); 7261 defsubr (&Sset_window_new_total);
6746 defsubr (&Sset_window_new_normal); 7262 defsubr (&Sset_window_new_normal);
6747 defsubr (&Swindow_resize_apply); 7263 defsubr (&Swindow_resize_apply);
7264 defsubr (&Swindow_resize_apply_total);
6748 defsubr (&Swindow_body_height); 7265 defsubr (&Swindow_body_height);
6749 defsubr (&Swindow_body_width); 7266 defsubr (&Swindow_body_width);
6750 defsubr (&Swindow_hscroll); 7267 defsubr (&Swindow_hscroll);
@@ -6754,6 +7271,10 @@ respectively are not installed by `window-state-put'. */);
6754 defsubr (&Swindow_edges); 7271 defsubr (&Swindow_edges);
6755 defsubr (&Swindow_pixel_edges); 7272 defsubr (&Swindow_pixel_edges);
6756 defsubr (&Swindow_absolute_pixel_edges); 7273 defsubr (&Swindow_absolute_pixel_edges);
7274 defsubr (&Swindow_mode_line_height);
7275 defsubr (&Swindow_header_line_height);
7276 defsubr (&Swindow_right_divider_width);
7277 defsubr (&Swindow_bottom_divider_width);
6757 defsubr (&Swindow_inside_edges); 7278 defsubr (&Swindow_inside_edges);
6758 defsubr (&Swindow_inside_pixel_edges); 7279 defsubr (&Swindow_inside_pixel_edges);
6759 defsubr (&Swindow_inside_absolute_pixel_edges); 7280 defsubr (&Swindow_inside_absolute_pixel_edges);
@@ -6776,6 +7297,7 @@ respectively are not installed by `window-state-put'. */);
6776 defsubr (&Sresize_mini_window_internal); 7297 defsubr (&Sresize_mini_window_internal);
6777 defsubr (&Sset_window_buffer); 7298 defsubr (&Sset_window_buffer);
6778 defsubr (&Srun_window_configuration_change_hook); 7299 defsubr (&Srun_window_configuration_change_hook);
7300 defsubr (&Srun_window_scroll_functions);
6779 defsubr (&Sselect_window); 7301 defsubr (&Sselect_window);
6780 defsubr (&Sforce_window_update); 7302 defsubr (&Sforce_window_update);
6781 defsubr (&Ssplit_window_internal); 7303 defsubr (&Ssplit_window_internal);
@@ -6787,6 +7309,7 @@ respectively are not installed by `window-state-put'. */);
6787 defsubr (&Sscroll_other_window); 7309 defsubr (&Sscroll_other_window);
6788 defsubr (&Sminibuffer_selected_window); 7310 defsubr (&Sminibuffer_selected_window);
6789 defsubr (&Srecenter); 7311 defsubr (&Srecenter);
7312 defsubr (&Swindow_text_width);
6790 defsubr (&Swindow_text_height); 7313 defsubr (&Swindow_text_height);
6791 defsubr (&Smove_to_window_line); 7314 defsubr (&Smove_to_window_line);
6792 defsubr (&Swindow_configuration_p); 7315 defsubr (&Swindow_configuration_p);