aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c854
1 files changed, 679 insertions, 175 deletions
diff --git a/src/window.c b/src/window.c
index 5f29791284a..36133362c1b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -58,6 +58,7 @@ static Lisp_Object Qrecord_window_buffer;
58static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 58static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
59static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 59static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
60static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; 60static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
61static Lisp_Object Qwindow_sanitize_window_sizes;
61static Lisp_Object Qwindow_pixel_to_total; 62static Lisp_Object Qwindow_pixel_to_total;
62static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 63static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
63static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; 64static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
@@ -93,7 +94,7 @@ static struct window *set_window_fringes (struct window *, Lisp_Object,
93static struct window *set_window_margins (struct window *, Lisp_Object, 94static struct window *set_window_margins (struct window *, Lisp_Object,
94 Lisp_Object); 95 Lisp_Object);
95static struct window *set_window_scroll_bars (struct window *, Lisp_Object, 96static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
96 Lisp_Object, Lisp_Object); 97 Lisp_Object, Lisp_Object, Lisp_Object);
97static void apply_window_adjustment (struct window *); 98static void apply_window_adjustment (struct window *);
98 99
99/* This is the window in which the terminal's cursor should 100/* This is the window in which the terminal's cursor should
@@ -149,66 +150,85 @@ wset_combination_limit (struct window *w, Lisp_Object val)
149{ 150{
150 w->combination_limit = val; 151 w->combination_limit = val;
151} 152}
153
152static void 154static void
153wset_dedicated (struct window *w, Lisp_Object val) 155wset_dedicated (struct window *w, Lisp_Object val)
154{ 156{
155 w->dedicated = val; 157 w->dedicated = val;
156} 158}
159
157static void 160static void
158wset_display_table (struct window *w, Lisp_Object val) 161wset_display_table (struct window *w, Lisp_Object val)
159{ 162{
160 w->display_table = val; 163 w->display_table = val;
161} 164}
165
162static void 166static void
163wset_new_normal (struct window *w, Lisp_Object val) 167wset_new_normal (struct window *w, Lisp_Object val)
164{ 168{
165 w->new_normal = val; 169 w->new_normal = val;
166} 170}
171
167static void 172static void
168wset_new_total (struct window *w, Lisp_Object val) 173wset_new_total (struct window *w, Lisp_Object val)
169{ 174{
170 w->new_total = val; 175 w->new_total = val;
171} 176}
177
172static void 178static void
173wset_normal_cols (struct window *w, Lisp_Object val) 179wset_normal_cols (struct window *w, Lisp_Object val)
174{ 180{
175 w->normal_cols = val; 181 w->normal_cols = val;
176} 182}
183
177static void 184static void
178wset_normal_lines (struct window *w, Lisp_Object val) 185wset_normal_lines (struct window *w, Lisp_Object val)
179{ 186{
180 w->normal_lines = val; 187 w->normal_lines = val;
181} 188}
189
182static void 190static void
183wset_parent (struct window *w, Lisp_Object val) 191wset_parent (struct window *w, Lisp_Object val)
184{ 192{
185 w->parent = val; 193 w->parent = val;
186} 194}
195
187static void 196static void
188wset_pointm (struct window *w, Lisp_Object val) 197wset_pointm (struct window *w, Lisp_Object val)
189{ 198{
190 w->pointm = val; 199 w->pointm = val;
191} 200}
201
202static void
203wset_old_pointm (struct window *w, Lisp_Object val)
204{
205 w->old_pointm = val;
206}
207
192static void 208static void
193wset_start (struct window *w, Lisp_Object val) 209wset_start (struct window *w, Lisp_Object val)
194{ 210{
195 w->start = val; 211 w->start = val;
196} 212}
213
197static void 214static void
198wset_temslot (struct window *w, Lisp_Object val) 215wset_temslot (struct window *w, Lisp_Object val)
199{ 216{
200 w->temslot = val; 217 w->temslot = val;
201} 218}
219
202static void 220static void
203wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val) 221wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
204{ 222{
205 w->vertical_scroll_bar_type = val; 223 w->vertical_scroll_bar_type = val;
206} 224}
225
207static void 226static void
208wset_window_parameters (struct window *w, Lisp_Object val) 227wset_window_parameters (struct window *w, Lisp_Object val)
209{ 228{
210 w->window_parameters = val; 229 w->window_parameters = val;
211} 230}
231
212static void 232static void
213wset_combination (struct window *w, bool horflag, Lisp_Object val) 233wset_combination (struct window *w, bool horflag, Lisp_Object val)
214{ 234{
@@ -877,6 +897,9 @@ window_body_height (struct window *w, bool pixelwise)
877{ 897{
878 int height = (w->pixel_height 898 int height = (w->pixel_height
879 - WINDOW_HEADER_LINE_HEIGHT (w) 899 - WINDOW_HEADER_LINE_HEIGHT (w)
900 - (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
901 ? WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
902 : 0)
880 - WINDOW_MODE_LINE_HEIGHT (w) 903 - WINDOW_MODE_LINE_HEIGHT (w)
881 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)); 904 - WINDOW_BOTTOM_DIVIDER_WIDTH (w));
882 905
@@ -997,6 +1020,15 @@ WINDOW must be a live window and defaults to the selected one. */)
997 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window)))); 1020 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window))));
998} 1021}
999 1022
1023DEFUN ("window-scroll-bar-height", Fwindow_scroll_bar_height,
1024 Swindow_scroll_bar_height, 0, 1, 0,
1025 doc: /* Return the height in pixels of WINDOW's horizontal scrollbar.
1026WINDOW must be a live window and defaults to the selected one. */)
1027 (Lisp_Object window)
1028{
1029 return (make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (decode_live_window (window))));
1030}
1031
1000DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 1032DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
1001 doc: /* Return the number of columns by which WINDOW is scrolled from left margin. 1033 doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
1002WINDOW must be a live window and defaults to the selected one. */) 1034WINDOW must be a live window and defaults to the selected one. */)
@@ -1024,6 +1056,8 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
1024 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1; 1056 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
1025 1057
1026 w->hscroll = new_hscroll; 1058 w->hscroll = new_hscroll;
1059 w->suspend_auto_hscroll = 1;
1060
1027 return make_number (new_hscroll); 1061 return make_number (new_hscroll);
1028} 1062}
1029 1063
@@ -1173,12 +1207,16 @@ display margins, fringes, header line, and/or mode line. */)
1173 1207
1174 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w) 1208 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
1175 + WINDOW_LEFT_MARGIN_COLS (w) 1209 + WINDOW_LEFT_MARGIN_COLS (w)
1176 + WINDOW_LEFT_FRINGE_COLS (w)), 1210 + ((WINDOW_LEFT_FRINGE_WIDTH (w)
1211 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
1212 / WINDOW_FRAME_COLUMN_WIDTH (w))),
1177 (WINDOW_TOP_EDGE_LINE (w) 1213 (WINDOW_TOP_EDGE_LINE (w)
1178 + WINDOW_HEADER_LINE_LINES (w)), 1214 + WINDOW_HEADER_LINE_LINES (w)),
1179 (WINDOW_BOX_RIGHT_EDGE_COL (w) 1215 (WINDOW_BOX_RIGHT_EDGE_COL (w)
1180 - WINDOW_RIGHT_MARGIN_COLS (w) 1216 - WINDOW_RIGHT_MARGIN_COLS (w)
1181 - WINDOW_RIGHT_FRINGE_COLS (w)), 1217 - ((WINDOW_RIGHT_FRINGE_WIDTH (w)
1218 + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
1219 / WINDOW_FRAME_COLUMN_WIDTH (w))),
1182 (WINDOW_BOTTOM_EDGE_LINE (w) 1220 (WINDOW_BOTTOM_EDGE_LINE (w)
1183 - WINDOW_MODE_LINE_LINES (w))); 1221 - WINDOW_MODE_LINE_LINES (w)));
1184} 1222}
@@ -1292,6 +1330,17 @@ coordinates_in_window (register struct window *w, int x, int y)
1292 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w) 1330 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1293 && x <= right_x) 1331 && x <= right_x)
1294 return ON_RIGHT_DIVIDER; 1332 return ON_RIGHT_DIVIDER;
1333 /* On the horizontal scroll bar? (Including the empty space at its
1334 right!) */
1335 else if ((WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w)
1336 && y >= (bottom_y
1337 - WINDOW_SCROLL_BAR_AREA_HEIGHT (w)
1338 - CURRENT_MODE_LINE_HEIGHT (w)
1339 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1340 && y <= (bottom_y
1341 - CURRENT_MODE_LINE_HEIGHT (w)
1342 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))))
1343 return ON_HORIZONTAL_SCROLL_BAR;
1295 /* On the mode or header line? */ 1344 /* On the mode or header line? */
1296 else if ((WINDOW_WANTS_MODELINE_P (w) 1345 else if ((WINDOW_WANTS_MODELINE_P (w)
1297 && y >= (bottom_y 1346 && y >= (bottom_y
@@ -1335,7 +1384,7 @@ coordinates_in_window (register struct window *w, int x, int y)
1335 1384
1336 /* Outside any interesting column? */ 1385 /* Outside any interesting column? */
1337 if (x < left_x || x > right_x) 1386 if (x < left_x || x > right_x)
1338 return ON_SCROLL_BAR; 1387 return ON_VERTICAL_SCROLL_BAR;
1339 1388
1340 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA); 1389 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
1341 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA); 1390 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
@@ -1499,10 +1548,13 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1499 case ON_RIGHT_MARGIN: 1548 case ON_RIGHT_MARGIN:
1500 return Qright_margin; 1549 return Qright_margin;
1501 1550
1502 case ON_SCROLL_BAR: 1551 case ON_VERTICAL_SCROLL_BAR:
1503 /* Historically we are supposed to return nil in this case. */ 1552 /* Historically we are supposed to return nil in this case. */
1504 return Qnil; 1553 return Qnil;
1505 1554
1555 case ON_HORIZONTAL_SCROLL_BAR:
1556 return Qnil;
1557
1506 case ON_RIGHT_DIVIDER: 1558 case ON_RIGHT_DIVIDER:
1507 return Qright_divider; 1559 return Qright_divider;
1508 1560
@@ -1643,6 +1695,14 @@ correct to return the top-level value of `point', outside of any
1643 return Fmarker_position (w->pointm); 1695 return Fmarker_position (w->pointm);
1644} 1696}
1645 1697
1698DEFUN ("window-old-point", Fwindow_old_point, Swindow_old_point, 0, 1, 0,
1699 doc: /* Return old value of point in WINDOW.
1700WINDOW must be a live window and defaults to the selected one. */)
1701 (Lisp_Object window)
1702{
1703 return Fmarker_position (decode_live_window (window)->old_pointm);
1704}
1705
1646DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0, 1706DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
1647 doc: /* Return position at which display currently starts in WINDOW. 1707 doc: /* Return position at which display currently starts in WINDOW.
1648WINDOW must be a live window and defaults to the selected one. 1708WINDOW must be a live window and defaults to the selected one.
@@ -2921,6 +2981,7 @@ selected frame and no others. */)
2921 return Qnil; 2981 return Qnil;
2922} 2982}
2923 2983
2984
2924static Lisp_Object 2985static Lisp_Object
2925resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise) 2986resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
2926{ 2987{
@@ -2928,10 +2989,17 @@ resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizonta
2928} 2989}
2929 2990
2930 2991
2992Lisp_Object
2993sanitize_window_sizes (Lisp_Object frame, Lisp_Object horizontal)
2994{
2995 return call2 (Qwindow_sanitize_window_sizes, frame, horizontal);
2996}
2997
2998
2931static Lisp_Object 2999static Lisp_Object
2932window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal) 3000window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
2933{ 3001{
2934 return call2(Qwindow_pixel_to_total, frame, horizontal); 3002 return call2 (Qwindow_pixel_to_total, frame, horizontal);
2935} 3003}
2936 3004
2937 3005
@@ -3210,89 +3278,6 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
3210 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame); 3278 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
3211 } 3279 }
3212} 3280}
3213
3214/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
3215 minimum allowable size. PIXELWISE means interpret these as pixel
3216 sizes. */
3217
3218void
3219check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
3220{
3221 /* For height, we have to see:
3222 how many windows the frame has at minimum (one or two),
3223 and whether it has a menu bar or other special stuff at the top. */
3224 if (pixelwise)
3225 {
3226 int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
3227 int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
3228
3229 if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
3230 min_height = 2 * min_height;
3231
3232 min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
3233 min_height += FRAME_INTERNAL_BORDER_WIDTH (frame);
3234
3235 if (*height < min_height)
3236 *height = min_height;
3237 if (*width < min_width)
3238 *width = min_width;
3239 }
3240 else
3241 {
3242 int min_height
3243 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
3244 ? MIN_SAFE_WINDOW_HEIGHT
3245 : 2 * MIN_SAFE_WINDOW_HEIGHT);
3246
3247 if (FRAME_TOP_MARGIN (frame) > 0)
3248 min_height += FRAME_TOP_MARGIN (frame);
3249
3250 if (*height < min_height)
3251 *height = min_height;
3252 if (*width < MIN_SAFE_WINDOW_WIDTH)
3253 *width = MIN_SAFE_WINDOW_WIDTH;
3254 }
3255}
3256
3257/* Adjust the margins of window W if text area is too small.
3258 Return 1 if window width is ok after adjustment; 0 if window
3259 is still too narrow. */
3260
3261static int
3262adjust_window_margins (struct window *w)
3263{
3264 int box_width = (WINDOW_PIXEL_WIDTH (w)
3265 - WINDOW_FRINGES_WIDTH (w)
3266 - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
3267 int margin_width = WINDOW_MARGINS_WIDTH (w);
3268
3269 if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3270 return 1;
3271
3272 if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3273 return 0;
3274 else
3275 /* Window's text area is too narrow, but reducing the window
3276 margins will fix that. */
3277 {
3278 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
3279
3280 margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
3281
3282 if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
3283 {
3284 if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
3285 w->left_margin_cols = w->right_margin_cols =
3286 margin_width / (2 * unit);
3287 else
3288 w->right_margin_cols = margin_width / unit;
3289 }
3290 else
3291 w->left_margin_cols = margin_width / unit;
3292
3293 return 1;
3294 }
3295}
3296 3281
3297/* The following three routines are needed for running a window's 3282/* The following three routines are needed for running a window's
3298 configuration change hook. */ 3283 configuration change hook. */
@@ -3326,7 +3311,7 @@ run_window_configuration_change_hook (struct frame *f)
3326 = Fdefault_value (Qwindow_configuration_change_hook); 3311 = Fdefault_value (Qwindow_configuration_change_hook);
3327 XSETFRAME (frame, f); 3312 XSETFRAME (frame, f);
3328 3313
3329 if (NILP (Vrun_hooks) || !NILP (inhibit_lisp_code)) 3314 if (NILP (Vrun_hooks) || !(f->official))
3330 return; 3315 return;
3331 3316
3332 /* Use the right buffer. Matters when running the local hooks. */ 3317 /* Use the right buffer. Matters when running the local hooks. */
@@ -3421,17 +3406,21 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3421 w->last_cursor_vpos = 0; 3406 w->last_cursor_vpos = 0;
3422 3407
3423 if (!(keep_margins_p && samebuf)) 3408 if (!(keep_margins_p && samebuf))
3424 { /* If we're not actually changing the buffer, don't reset hscroll and 3409 { /* If we're not actually changing the buffer, don't reset hscroll
3425 vscroll. This case happens for example when called from 3410 and vscroll. This case happens for example when called from
3426 change_frame_size_1, where we use a dummy call to 3411 change_frame_size_1, where we use a dummy call to
3427 Fset_window_buffer on the frame's selected window (and no other) 3412 Fset_window_buffer on the frame's selected window (and no
3428 just in order to run window-configuration-change-hook. 3413 other) just in order to run window-configuration-change-hook
3429 Resetting hscroll and vscroll here is problematic for things like 3414 (no longer true since change_frame_size_1 directly calls
3430 image-mode and doc-view-mode since it resets the image's position 3415 run_window_configuration_change_hook). Resetting hscroll and
3431 whenever we resize the frame. */ 3416 vscroll here is problematic for things like image-mode and
3432 w->hscroll = w->min_hscroll = 0; 3417 doc-view-mode since it resets the image's position whenever we
3418 resize the frame. */
3419 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
3420 w->suspend_auto_hscroll = 0;
3433 w->vscroll = 0; 3421 w->vscroll = 0;
3434 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b)); 3422 set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
3423 set_marker_both (w->old_pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
3435 set_marker_restricted (w->start, 3424 set_marker_restricted (w->start,
3436 make_number (b->last_window_start), 3425 make_number (b->last_window_start),
3437 buffer); 3426 buffer);
@@ -3449,6 +3438,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3449 Fset_buffer (buffer); 3438 Fset_buffer (buffer);
3450 3439
3451 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type); 3440 XMARKER (w->pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
3441 XMARKER (w->old_pointm)->insertion_type = !NILP (Vwindow_point_insertion_type);
3452 3442
3453 if (!keep_margins_p) 3443 if (!keep_margins_p)
3454 { 3444 {
@@ -3457,7 +3447,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3457 BVAR (b, right_fringe_width), 3447 BVAR (b, right_fringe_width),
3458 BVAR (b, fringes_outside_margins)); 3448 BVAR (b, fringes_outside_margins));
3459 set_window_scroll_bars (w, BVAR (b, scroll_bar_width), 3449 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
3460 BVAR (b, vertical_scroll_bar_type), Qnil); 3450 BVAR (b, vertical_scroll_bar_type),
3451 BVAR (b, scroll_bar_height),
3452 BVAR (b, horizontal_scroll_bar_type));
3461 set_window_margins (w, BVAR (b, left_margin_cols), 3453 set_window_margins (w, BVAR (b, left_margin_cols),
3462 BVAR (b, right_margin_cols)); 3454 BVAR (b, right_margin_cols));
3463 apply_window_adjustment (w); 3455 apply_window_adjustment (w);
@@ -3603,10 +3595,11 @@ temp_output_buffer_show (register Lisp_Object buf)
3603 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); 3595 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
3604 Vminibuf_scroll_window = window; 3596 Vminibuf_scroll_window = window;
3605 w = XWINDOW (window); 3597 w = XWINDOW (window);
3606 w->hscroll = 0; 3598 w->hscroll = w->min_hscroll = w->hscroll_whole = 0;
3607 w->min_hscroll = 0; 3599 w->suspend_auto_hscroll = 0;
3608 set_marker_restricted_both (w->start, buf, BEG, BEG); 3600 set_marker_restricted_both (w->start, buf, BEG, BEG);
3609 set_marker_restricted_both (w->pointm, buf, BEG, BEG); 3601 set_marker_restricted_both (w->pointm, buf, BEG, BEG);
3602 set_marker_restricted_both (w->old_pointm, buf, BEG, BEG);
3610 3603
3611 /* Run temp-buffer-show-hook, with the chosen window selected 3604 /* Run temp-buffer-show-hook, with the chosen window selected
3612 and its buffer current. */ 3605 and its buffer current. */
@@ -3658,6 +3651,7 @@ make_parent_window (Lisp_Object window, bool horflag)
3658 /* ...but now P becomes an internal window. */ 3651 /* ...but now P becomes an internal window. */
3659 wset_start (p, Qnil); 3652 wset_start (p, Qnil);
3660 wset_pointm (p, Qnil); 3653 wset_pointm (p, Qnil);
3654 wset_old_pointm (p, Qnil);
3661 wset_buffer (p, Qnil); 3655 wset_buffer (p, Qnil);
3662 wset_combination (p, horflag, window); 3656 wset_combination (p, horflag, window);
3663 wset_combination_limit (p, Qnil); 3657 wset_combination_limit (p, Qnil);
@@ -3681,7 +3675,9 @@ make_window (void)
3681 wset_new_pixel (w, make_number (0)); 3675 wset_new_pixel (w, make_number (0));
3682 wset_start (w, Fmake_marker ()); 3676 wset_start (w, Fmake_marker ());
3683 wset_pointm (w, Fmake_marker ()); 3677 wset_pointm (w, Fmake_marker ());
3678 wset_old_pointm (w, Fmake_marker ());
3684 wset_vertical_scroll_bar_type (w, Qt); 3679 wset_vertical_scroll_bar_type (w, Qt);
3680 wset_horizontal_scroll_bar_type (w, Qt);
3685 /* These Lisp fields are marked specially so they're not set to nil by 3681 /* These Lisp fields are marked specially so they're not set to nil by
3686 allocate_window. */ 3682 allocate_window. */
3687 wset_prev_buffers (w, Qnil); 3683 wset_prev_buffers (w, Qnil);
@@ -3698,8 +3694,8 @@ make_window (void)
3698#endif 3694#endif
3699 w->sequence_number = ++sequence_number; 3695 w->sequence_number = ++sequence_number;
3700 w->scroll_bar_width = -1; 3696 w->scroll_bar_width = -1;
3697 w->scroll_bar_height = -1;
3701 w->column_number_displayed = -1; 3698 w->column_number_displayed = -1;
3702
3703 /* Reset window_list. */ 3699 /* Reset window_list. */
3704 Vwindow_list = Qnil; 3700 Vwindow_list = Qnil;
3705 /* Return window. */ 3701 /* Return window. */
@@ -3864,7 +3860,7 @@ window_resize_check (struct window *w, bool horflag)
3864} 3860}
3865 3861
3866 3862
3867/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to 3863/* Set w->pixel_height (w->pixel_width if HORFLAG is non-zero) to
3868 w->new_pixel for window W and recursively all child windows of W. 3864 w->new_pixel for window W and recursively all child windows of W.
3869 Also calculate and assign the new vertical (horizontal) pixel start 3865 Also calculate and assign the new vertical (horizontal) pixel start
3870 positions of each of these windows. 3866 positions of each of these windows.
@@ -3949,15 +3945,12 @@ window_resize_apply (struct window *w, bool horflag)
3949 } 3945 }
3950 } 3946 }
3951 else 3947 else
3952 { 3948 /* Bug#15957. */
3953 adjust_window_margins (w); 3949 w->window_end_valid = 0;
3954 /* Bug#15957. */
3955 w->window_end_valid = 0;
3956 }
3957} 3950}
3958 3951
3959 3952
3960/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to 3953/* Set w->total_lines (w->total_cols if HORFLAG is non-zero) to
3961 w->new_total for window W and recursively all child windows of W. 3954 w->new_total for window W and recursively all child windows of W.
3962 Also calculate and assign the new vertical (horizontal) start 3955 Also calculate and assign the new vertical (horizontal) start
3963 positions of each of these windows. */ 3956 positions of each of these windows. */
@@ -4113,6 +4106,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4113 /* old_size is the old size of the frame's root window. */ 4106 /* old_size is the old size of the frame's root window. */
4114 int old_size = horflag ? r->total_cols : r->total_lines; 4107 int old_size = horflag ? r->total_cols : r->total_lines;
4115 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height; 4108 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
4109 int old_pixel_top = r->pixel_top;
4116 /* new_size is the new size of the frame's root window. */ 4110 /* new_size is the new size of the frame's root window. */
4117 int new_size, new_pixel_size; 4111 int new_size, new_pixel_size;
4118 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f); 4112 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
@@ -4127,7 +4121,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4127 new_pixel_size = max (horflag 4121 new_pixel_size = max (horflag
4128 ? size 4122 ? size
4129 : (size 4123 : (size
4130 - FRAME_TOP_MARGIN_HEIGHT (f) 4124/** - FRAME_TOP_MARGIN_HEIGHT (f) **/
4131 - ((FRAME_HAS_MINIBUF_P (f) 4125 - ((FRAME_HAS_MINIBUF_P (f)
4132 && !FRAME_MINIBUF_ONLY_P (f)) 4126 && !FRAME_MINIBUF_ONLY_P (f))
4133 ? FRAME_LINE_HEIGHT (f) : 0)), 4127 ? FRAME_LINE_HEIGHT (f) : 0)),
@@ -4139,7 +4133,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4139 new_size = max (horflag 4133 new_size = max (horflag
4140 ? size 4134 ? size
4141 : (size 4135 : (size
4142 - FRAME_TOP_MARGIN (f) 4136/** - FRAME_TOP_MARGIN (f) **/
4143 - ((FRAME_HAS_MINIBUF_P (f) 4137 - ((FRAME_HAS_MINIBUF_P (f)
4144 && !FRAME_MINIBUF_ONLY_P (f)) 4138 && !FRAME_MINIBUF_ONLY_P (f))
4145 ? 1 : 0)), 4139 ? 1 : 0)),
@@ -4150,7 +4144,8 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4150 r->top_line = FRAME_TOP_MARGIN (f); 4144 r->top_line = FRAME_TOP_MARGIN (f);
4151 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f); 4145 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4152 4146
4153 if (new_pixel_size == old_pixel_size) 4147 if (new_pixel_size == old_pixel_size
4148 && r->pixel_top == old_pixel_top)
4154 ; 4149 ;
4155 else if (WINDOW_LEAF_P (r)) 4150 else if (WINDOW_LEAF_P (r))
4156 /* For a leaf root window just set the size. */ 4151 /* For a leaf root window just set the size. */
@@ -4192,6 +4187,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4192 { 4187 {
4193 window_resize_apply (r, horflag); 4188 window_resize_apply (r, horflag);
4194 window_pixel_to_total (r->frame, horflag ? Qt : Qnil); 4189 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4190#if 0 /* Let's try without safe sizes and/or killing other windows. */
4195 } 4191 }
4196 else 4192 else
4197 { 4193 {
@@ -4204,7 +4200,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4204 window_resize_apply (r, horflag); 4200 window_resize_apply (r, horflag);
4205 window_pixel_to_total (r->frame, horflag ? Qt : Qnil); 4201 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4206 } 4202 }
4207#if 0 /* Let's try without killing other windows. */
4208 else 4203 else
4209 { 4204 {
4210 /* We lost. Delete all windows but the frame's 4205 /* We lost. Delete all windows but the frame's
@@ -4408,7 +4403,9 @@ set correctly. See the code of `split-window' for how this is done. */)
4408 n->right_fringe_width = r->right_fringe_width; 4403 n->right_fringe_width = r->right_fringe_width;
4409 n->fringes_outside_margins = r->fringes_outside_margins; 4404 n->fringes_outside_margins = r->fringes_outside_margins;
4410 n->scroll_bar_width = r->scroll_bar_width; 4405 n->scroll_bar_width = r->scroll_bar_width;
4406 n->scroll_bar_height = r->scroll_bar_height;
4411 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); 4407 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
4408 wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
4412 4409
4413 /* Directly assign orthogonal coordinates and sizes. */ 4410 /* Directly assign orthogonal coordinates and sizes. */
4414 if (horflag) 4411 if (horflag)
@@ -4555,6 +4552,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4555 { 4552 {
4556 unshow_buffer (w); 4553 unshow_buffer (w);
4557 unchain_marker (XMARKER (w->pointm)); 4554 unchain_marker (XMARKER (w->pointm));
4555 unchain_marker (XMARKER (w->old_pointm));
4558 unchain_marker (XMARKER (w->start)); 4556 unchain_marker (XMARKER (w->start));
4559 wset_buffer (w, Qnil); 4557 wset_buffer (w, Qnil);
4560 } 4558 }
@@ -4816,6 +4814,7 @@ window_internal_height (struct window *w)
4816 4814
4817 return ht; 4815 return ht;
4818} 4816}
4817
4819 4818
4820/************************************************************************ 4819/************************************************************************
4821 Window Scrolling 4820 Window Scrolling
@@ -4866,6 +4865,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4866 void *itdata = NULL; 4865 void *itdata = NULL;
4867 int window_total_lines; 4866 int window_total_lines;
4868 int frame_line_height = default_line_pixel_height (w); 4867 int frame_line_height = default_line_pixel_height (w);
4868 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
4869 Fwindow_old_point (window)));
4869 4870
4870 SET_TEXT_POS_FROM_MARKER (start, w->start); 4871 SET_TEXT_POS_FROM_MARKER (start, w->start);
4871 /* Scrolling a minibuffer window via scroll bar when the echo area 4872 /* Scrolling a minibuffer window via scroll bar when the echo area
@@ -4994,6 +4995,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4994 { 4995 {
4995 ptrdiff_t start_pos = IT_CHARPOS (it); 4996 ptrdiff_t start_pos = IT_CHARPOS (it);
4996 int dy = frame_line_height; 4997 int dy = frame_line_height;
4998
4997 dy = max ((window_box_height (w) 4999 dy = max ((window_box_height (w)
4998 - next_screen_context_lines * dy), 5000 - next_screen_context_lines * dy),
4999 dy) * n; 5001 dy) * n;
@@ -5170,6 +5172,32 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
5170 charpos = IT_CHARPOS (it); 5172 charpos = IT_CHARPOS (it);
5171 bytepos = IT_BYTEPOS (it); 5173 bytepos = IT_BYTEPOS (it);
5172 5174
5175 /* If PT is in the screen line at the last fully visible line,
5176 move_it_to will stop at X = 0 in that line, because the
5177 required Y coordinate is reached there. See if we can get to
5178 PT without descending lower in Y, and if we can, it means we
5179 reached PT before the scroll margin. */
5180 if (charpos != PT)
5181 {
5182 struct it it2;
5183 void *it_data;
5184
5185 it2 = it;
5186 it_data = bidi_shelve_cache ();
5187 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
5188 if (IT_CHARPOS (it) == PT && it.current_y == it2.current_y)
5189 {
5190 charpos = IT_CHARPOS (it);
5191 bytepos = IT_BYTEPOS (it);
5192 bidi_unshelve_cache (it_data, 1);
5193 }
5194 else
5195 {
5196 it = it2;
5197 bidi_unshelve_cache (it_data, 0);
5198 }
5199 }
5200
5173 /* See if point is on a partially visible line at the end. */ 5201 /* See if point is on a partially visible line at the end. */
5174 if (it.what == IT_EOB) 5202 if (it.what == IT_EOB)
5175 partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y; 5203 partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y;
@@ -5211,6 +5239,13 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
5211 } 5239 }
5212 } 5240 }
5213 bidi_unshelve_cache (itdata, 0); 5241 bidi_unshelve_cache (itdata, 0);
5242
5243 if (adjust_old_pointm)
5244 Fset_marker (w->old_pointm,
5245 ((w == XWINDOW (selected_window))
5246 ? make_number (BUF_PT (XBUFFER (w->contents)))
5247 : Fmarker_position (w->pointm)),
5248 w->contents);
5214} 5249}
5215 5250
5216 5251
@@ -5235,6 +5270,8 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5235 ptrdiff_t startpos = marker_position (w->start); 5270 ptrdiff_t startpos = marker_position (w->start);
5236 ptrdiff_t startbyte = marker_byte_position (w->start); 5271 ptrdiff_t startbyte = marker_byte_position (w->start);
5237 Lisp_Object original_pos = Qnil; 5272 Lisp_Object original_pos = Qnil;
5273 bool adjust_old_pointm = !NILP (Fequal (Fwindow_point (window),
5274 Fwindow_old_point (window)));
5238 5275
5239 /* If scrolling screen-fulls, compute the number of lines to 5276 /* If scrolling screen-fulls, compute the number of lines to
5240 scroll from the window's height. */ 5277 scroll from the window's height. */
@@ -5250,6 +5287,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5250 struct position posit 5287 struct position posit
5251 = *compute_motion (startpos, startbyte, 0, 0, 0, 5288 = *compute_motion (startpos, startbyte, 0, 0, 0,
5252 PT, ht, 0, -1, w->hscroll, 0, w); 5289 PT, ht, 0, -1, w->hscroll, 0, w);
5290
5253 window_scroll_preserve_vpos = posit.vpos; 5291 window_scroll_preserve_vpos = posit.vpos;
5254 window_scroll_preserve_hpos = posit.hpos + w->hscroll; 5292 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
5255 } 5293 }
@@ -5365,6 +5403,13 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5365 else 5403 else
5366 xsignal0 (Qend_of_buffer); 5404 xsignal0 (Qend_of_buffer);
5367 } 5405 }
5406
5407 if (adjust_old_pointm)
5408 Fset_marker (w->old_pointm,
5409 ((w == XWINDOW (selected_window))
5410 ? make_number (BUF_PT (XBUFFER (w->contents)))
5411 : Fmarker_position (w->pointm)),
5412 w->contents);
5368} 5413}
5369 5414
5370 5415
@@ -5501,6 +5546,7 @@ specifies the window to scroll. This takes precedence over
5501 5546
5502 Fset_buffer (w->contents); 5547 Fset_buffer (w->contents);
5503 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm)); 5548 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
5549 SET_PT_BOTH (marker_position (w->old_pointm), marker_byte_position (w->old_pointm));
5504 5550
5505 if (NILP (arg)) 5551 if (NILP (arg))
5506 window_scroll (window, 1, 1, 1); 5552 window_scroll (window, 1, 1, 1);
@@ -5515,6 +5561,7 @@ specifies the window to scroll. This takes precedence over
5515 } 5561 }
5516 5562
5517 set_marker_both (w->pointm, Qnil, PT, PT_BYTE); 5563 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
5564 set_marker_both (w->old_pointm, Qnil, PT, PT_BYTE);
5518 unbind_to (count, Qnil); 5565 unbind_to (count, Qnil);
5519 5566
5520 return Qnil; 5567 return Qnil;
@@ -5540,6 +5587,8 @@ by this function. This happens in an interactive call. */)
5540 if (!NILP (set_minimum)) 5587 if (!NILP (set_minimum))
5541 w->min_hscroll = w->hscroll; 5588 w->min_hscroll = w->hscroll;
5542 5589
5590 w->suspend_auto_hscroll = 1;
5591
5543 return result; 5592 return result;
5544} 5593}
5545 5594
@@ -5563,6 +5612,8 @@ by this function. This happens in an interactive call. */)
5563 if (!NILP (set_minimum)) 5612 if (!NILP (set_minimum))
5564 w->min_hscroll = w->hscroll; 5613 w->min_hscroll = w->hscroll;
5565 5614
5615 w->suspend_auto_hscroll = 1;
5616
5566 return result; 5617 return result;
5567} 5618}
5568 5619
@@ -5660,7 +5711,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5660 5711
5661 if (buf != current_buffer) 5712 if (buf != current_buffer)
5662 error ("`recenter'ing a window that does not display current-buffer."); 5713 error ("`recenter'ing a window that does not display current-buffer.");
5663 5714
5664 /* If redisplay is suppressed due to an error, try again. */ 5715 /* If redisplay is suppressed due to an error, try again. */
5665 buf->display_error_modiff = 0; 5716 buf->display_error_modiff = 0;
5666 5717
@@ -5830,34 +5881,46 @@ and redisplay normally--don't erase and redraw the frame. */)
5830} 5881}
5831 5882
5832DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width, 5883DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
5833 0, 1, 0, 5884 0, 2, 0,
5834 doc: /* Return the width in columns of the text display area of WINDOW. 5885 doc: /* Return the width in columns of the text display area of WINDOW.
5835WINDOW must be a live window and defaults to the selected one. 5886WINDOW must be a live window and defaults to the selected one.
5836 5887
5837The returned width does not include dividers, scrollbars, margins, 5888The returned width does not include dividers, scrollbars, margins,
5838fringes, nor any partial-width columns at the right of the text 5889fringes, nor any partial-width columns at the right of the text
5839area. */) 5890area.
5840 (Lisp_Object window) 5891
5892Optional argument PIXELWISE non-nil, means to return the width in
5893pixels. */)
5894 (Lisp_Object window, Lisp_Object pixelwise)
5841{ 5895{
5842 struct window *w = decode_live_window (window); 5896 struct window *w = decode_live_window (window);
5843 5897
5844 return make_number (window_box_width (w, TEXT_AREA) 5898 if (NILP (pixelwise))
5845 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))); 5899 return make_number (window_box_width (w, TEXT_AREA)
5900 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
5901 else
5902 return make_number (window_box_width (w, TEXT_AREA));
5846} 5903}
5847 5904
5848DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5905DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5849 0, 1, 0, 5906 0, 2, 0,
5850 doc: /* Return the height in lines of the text display area of WINDOW. 5907 doc: /* Return the height in lines of the text display area of WINDOW.
5851WINDOW must be a live window and defaults to the selected one. 5908WINDOW must be a live window and defaults to the selected one.
5852 5909
5853The returned height does not include dividers, the mode line, any header 5910The returned height does not include dividers, the mode line, any header
5854line, nor any partial-height lines at the bottom of the text area. */) 5911line, nor any partial-height lines at the bottom of the text area.
5855 (Lisp_Object window) 5912
5913Optional argument PIXELWISE non-nil, means to return the height in
5914pixels. */)
5915 (Lisp_Object window, Lisp_Object pixelwise)
5856{ 5916{
5857 struct window *w = decode_live_window (window); 5917 struct window *w = decode_live_window (window);
5858 5918
5859 return make_number (window_box_height (w) 5919 if (NILP (pixelwise))
5860 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w))); 5920 return make_number (window_box_height (w)
5921 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
5922 else
5923 return make_number (window_box_height (w));
5861} 5924}
5862 5925
5863DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, 5926DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
@@ -5967,17 +6030,18 @@ struct saved_window
5967{ 6030{
5968 struct vectorlike_header header; 6031 struct vectorlike_header header;
5969 6032
5970 Lisp_Object window, buffer, start, pointm; 6033 Lisp_Object window, buffer, start, pointm, old_pointm;
5971 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; 6034 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
5972 Lisp_Object left_col, top_line, total_cols, total_lines; 6035 Lisp_Object left_col, top_line, total_cols, total_lines;
5973 Lisp_Object normal_cols, normal_lines; 6036 Lisp_Object normal_cols, normal_lines;
5974 Lisp_Object hscroll, min_hscroll; 6037 Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll;
5975 Lisp_Object parent, prev; 6038 Lisp_Object parent, prev;
5976 Lisp_Object start_at_line_beg; 6039 Lisp_Object start_at_line_beg;
5977 Lisp_Object display_table; 6040 Lisp_Object display_table;
5978 Lisp_Object left_margin_cols, right_margin_cols; 6041 Lisp_Object left_margin_cols, right_margin_cols;
5979 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 6042 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
5980 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated; 6043 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
6044 Lisp_Object scroll_bar_height, horizontal_scroll_bar_type;
5981 Lisp_Object combination_limit, window_parameters; 6045 Lisp_Object combination_limit, window_parameters;
5982}; 6046};
5983 6047
@@ -6005,13 +6069,359 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config
6005 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; 6069 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6006} 6070}
6007 6071
6008/* From Chong's unwind_create_frame_1. */ 6072DEFUN ("set-window-configuration", Fset_window_configuration,
6009static void 6073 Sset_window_configuration, 1, 1, 0,
6010unwind_change_frame (Lisp_Object val) 6074 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6075CONFIGURATION must be a value previously returned
6076by `current-window-configuration' (which see).
6077If CONFIGURATION was made from a frame that is now deleted,
6078only frame-independent values can be restored. In this case,
6079the return value is nil. Otherwise the value is t. */)
6080 (Lisp_Object configuration)
6011{ 6081{
6012 inhibit_lisp_code = val; 6082 register struct save_window_data *data;
6083 struct Lisp_Vector *saved_windows;
6084 Lisp_Object new_current_buffer;
6085 Lisp_Object frame;
6086 struct frame *f;
6087 ptrdiff_t old_point = -1;
6088
6089 CHECK_WINDOW_CONFIGURATION (configuration);
6090
6091 data = (struct save_window_data *) XVECTOR (configuration);
6092 saved_windows = XVECTOR (data->saved_windows);
6093
6094 new_current_buffer = data->current_buffer;
6095 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
6096 new_current_buffer = Qnil;
6097 else
6098 {
6099 if (XBUFFER (new_current_buffer) == current_buffer)
6100 /* The code further down "preserves point" by saving here PT in
6101 old_point and then setting it later back into PT. When the
6102 current-selected-window and the final-selected-window both show
6103 the current buffer, this suffers from the problem that the
6104 current PT is the window-point of the current-selected-window,
6105 while the final PT is the point of the final-selected-window, so
6106 this copy from one PT to the other would end up moving the
6107 window-point of the final-selected-window to the window-point of
6108 the current-selected-window. So we have to be careful which
6109 point of the current-buffer we copy into old_point. */
6110 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6111 && WINDOWP (selected_window)
6112 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
6113 && !EQ (selected_window, data->current_window))
6114 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6115 else
6116 old_point = PT;
6117 else
6118 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6119 point in new_current_buffer as of the last time this buffer was
6120 used. This can be non-deterministic since it can be changed by
6121 things like jit-lock by mere temporary selection of some random
6122 window that happens to show this buffer.
6123 So if possible we want this arbitrary choice of "which point" to
6124 be the one from the to-be-selected-window so as to prevent this
6125 window's cursor from being copied from another window. */
6126 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
6127 /* If current_window = selected_window, its point is in BUF_PT. */
6128 && !EQ (selected_window, data->current_window))
6129 old_point = marker_position (XWINDOW (data->current_window)->pointm);
6130 else
6131 old_point = BUF_PT (XBUFFER (new_current_buffer));
6132 }
6133
6134 frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
6135 f = XFRAME (frame);
6136
6137 /* If f is a dead frame, don't bother rebuilding its window tree.
6138 However, there is other stuff we should still try to do below. */
6139 if (FRAME_LIVE_P (f))
6140 {
6141 Lisp_Object window;
6142 Lisp_Object dead_windows = Qnil;
6143 register Lisp_Object tem, par, pers;
6144 register struct window *w;
6145 register struct saved_window *p;
6146 struct window *root_window;
6147 struct window **leaf_windows;
6148 int n_leaf_windows;
6149 ptrdiff_t k;
6150 int i, n;
6151
6152 /* Don't do this within the main loop below: This may call Lisp
6153 code and is thus potentially unsafe while input is blocked. */
6154 for (k = 0; k < saved_windows->header.size; k++)
6155 {
6156 p = SAVED_WINDOW_N (saved_windows, k);
6157 window = p->window;
6158 w = XWINDOW (window);
6159 if (BUFFERP (w->contents)
6160 && !EQ (w->contents, p->buffer)
6161 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6162 /* If a window we restore gets another buffer, record the
6163 window's old buffer. */
6164 call1 (Qrecord_window_buffer, window);
6165 }
6166
6167 /* Consider frame unofficial, temporarily. */
6168 f->official = false;
6169 /* The mouse highlighting code could get screwed up
6170 if it runs during this. */
6171 block_input ();
6172
6173 /* "Swap out" point from the selected window's buffer
6174 into the window itself. (Normally the pointm of the selected
6175 window holds garbage.) We do this now, before
6176 restoring the window contents, and prevent it from
6177 being done later on when we select a new window. */
6178 if (! NILP (XWINDOW (selected_window)->contents))
6179 {
6180 w = XWINDOW (selected_window);
6181 set_marker_both (w->pointm,
6182 w->contents,
6183 BUF_PT (XBUFFER (w->contents)),
6184 BUF_PT_BYTE (XBUFFER (w->contents)));
6185 }
6186
6187 fset_redisplay (f);
6188 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
6189
6190 /* Problem: Freeing all matrices and later allocating them again
6191 is a serious redisplay flickering problem. What we would
6192 really like to do is to free only those matrices not reused
6193 below. */
6194 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
6195 leaf_windows = alloca (count_windows (root_window)
6196 * sizeof *leaf_windows);
6197 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6198
6199 /* Kludge Alert!
6200 Mark all windows now on frame as "deleted".
6201 Restoring the new configuration "undeletes" any that are in it.
6202
6203 Save their current buffers in their height fields, since we may
6204 need it later, if a buffer saved in the configuration is now
6205 dead. */
6206 delete_all_child_windows (FRAME_ROOT_WINDOW (f));
6207
6208 for (k = 0; k < saved_windows->header.size; k++)
6209 {
6210 p = SAVED_WINDOW_N (saved_windows, k);
6211 window = p->window;
6212 w = XWINDOW (window);
6213 wset_next (w, Qnil);
6214
6215 if (!NILP (p->parent))
6216 wset_parent
6217 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
6218 else
6219 wset_parent (w, Qnil);
6220
6221 if (!NILP (p->prev))
6222 {
6223 wset_prev
6224 (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
6225 wset_next (XWINDOW (w->prev), p->window);
6226 }
6227 else
6228 {
6229 wset_prev (w, Qnil);
6230 if (!NILP (w->parent))
6231 wset_combination (XWINDOW (w->parent),
6232 (XINT (p->total_cols)
6233 != XWINDOW (w->parent)->total_cols),
6234 p->window);
6235 }
6236
6237 /* If we squirreled away the buffer, restore it now. */
6238 if (BUFFERP (w->combination_limit))
6239 wset_buffer (w, w->combination_limit);
6240 w->pixel_left = XFASTINT (p->pixel_left);
6241 w->pixel_top = XFASTINT (p->pixel_top);
6242 w->pixel_width = XFASTINT (p->pixel_width);
6243 w->pixel_height = XFASTINT (p->pixel_height);
6244 w->left_col = XFASTINT (p->left_col);
6245 w->top_line = XFASTINT (p->top_line);
6246 w->total_cols = XFASTINT (p->total_cols);
6247 w->total_lines = XFASTINT (p->total_lines);
6248 wset_normal_cols (w, p->normal_cols);
6249 wset_normal_lines (w, p->normal_lines);
6250 w->hscroll = XFASTINT (p->hscroll);
6251 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6252 w->min_hscroll = XFASTINT (p->min_hscroll);
6253 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6254 wset_display_table (w, p->display_table);
6255 w->left_margin_cols = XINT (p->left_margin_cols);
6256 w->right_margin_cols = XINT (p->right_margin_cols);
6257 w->left_fringe_width = XINT (p->left_fringe_width);
6258 w->right_fringe_width = XINT (p->right_fringe_width);
6259 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6260 w->scroll_bar_width = XINT (p->scroll_bar_width);
6261 w->scroll_bar_height = XINT (p->scroll_bar_height);
6262 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6263 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6264 wset_dedicated (w, p->dedicated);
6265 wset_combination_limit (w, p->combination_limit);
6266 /* Restore any window parameters that have been saved.
6267 Parameters that have not been saved are left alone. */
6268 for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
6269 {
6270 pers = XCAR (tem);
6271 if (CONSP (pers))
6272 {
6273 if (NILP (XCDR (pers)))
6274 {
6275 par = Fassq (XCAR (pers), w->window_parameters);
6276 if (CONSP (par) && !NILP (XCDR (par)))
6277 /* Reset a parameter to nil if and only if it
6278 has a non-nil association. Don't make new
6279 associations. */
6280 Fsetcdr (par, Qnil);
6281 }
6282 else
6283 /* Always restore a non-nil value. */
6284 Fset_window_parameter (window, XCAR (pers), XCDR (pers));
6285 }
6286 }
6287
6288 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
6289 /* If saved buffer is alive, install it. */
6290 {
6291 wset_buffer (w, p->buffer);
6292 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6293 set_marker_restricted (w->start, p->start, w->contents);
6294 set_marker_restricted (w->pointm, p->pointm, w->contents);
6295 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6296 /* As documented in Fcurrent_window_configuration, don't
6297 restore the location of point in the buffer which was
6298 current when the window configuration was recorded. */
6299 if (!EQ (p->buffer, new_current_buffer)
6300 && XBUFFER (p->buffer) == current_buffer)
6301 Fgoto_char (w->pointm);
6302 }
6303 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6304 /* Keep window's old buffer; make sure the markers are real. */
6305 {
6306 /* Set window markers at start of visible range. */
6307 if (XMARKER (w->start)->buffer == 0)
6308 set_marker_restricted_both (w->start, w->contents, 0, 0);
6309 if (XMARKER (w->pointm)->buffer == 0)
6310 set_marker_restricted_both
6311 (w->pointm, w->contents,
6312 BUF_PT (XBUFFER (w->contents)),
6313 BUF_PT_BYTE (XBUFFER (w->contents)));
6314 if (XMARKER (w->old_pointm)->buffer == 0)
6315 set_marker_restricted_both
6316 (w->old_pointm, w->contents,
6317 BUF_PT (XBUFFER (w->contents)),
6318 BUF_PT_BYTE (XBUFFER (w->contents)));
6319 w->start_at_line_beg = 1;
6320 }
6321 else if (!NILP (w->start))
6322 /* Leaf window has no live buffer, get one. */
6323 {
6324 /* Get the buffer via other_buffer_safely in order to
6325 avoid showing an unimportant buffer and, if necessary, to
6326 recreate *scratch* in the course (part of Juanma's bs-show
6327 scenario from March 2011). */
6328 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6329 /* This will set the markers to beginning of visible
6330 range. */
6331 set_marker_restricted_both (w->start, w->contents, 0, 0);
6332 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6333 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6334 w->start_at_line_beg = 1;
6335 if (!NILP (w->dedicated))
6336 /* Record this window as dead. */
6337 dead_windows = Fcons (window, dead_windows);
6338 /* Make sure window is no more dedicated. */
6339 wset_dedicated (w, Qnil);
6340 }
6341 }
6342
6343 fset_root_window (f, data->root_window);
6344 /* Arrange *not* to restore point in the buffer that was
6345 current when the window configuration was saved. */
6346 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6347 set_marker_restricted (XWINDOW (data->current_window)->pointm,
6348 make_number (old_point),
6349 XWINDOW (data->current_window)->contents);
6350
6351 /* In the following call to `select-window', prevent "swapping out
6352 point" in the old selected window using the buffer that has
6353 been restored into it. We already swapped out that point from
6354 that window's old buffer.
6355
6356 Do not record the buffer here. We do that in a separate call
6357 to select_window below. See also Bug#16207. */
6358 select_window (data->current_window, Qt, 1);
6359 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6360 last_selected_window)
6361 = selected_window;
6362
6363 if (NILP (data->focus_frame)
6364 || (FRAMEP (data->focus_frame)
6365 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
6366 Fredirect_frame_focus (frame, data->focus_frame);
6367
6368 /* Now, free glyph matrices in windows that were not reused. */
6369 for (i = n = 0; i < n_leaf_windows; ++i)
6370 {
6371 if (NILP (leaf_windows[i]->contents))
6372 free_window_matrices (leaf_windows[i]);
6373 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
6374 ++n;
6375 }
6376
6377 /* Make frame official again and apply frame size changes if
6378 needed. */
6379 f->official = true;
6380 adjust_frame_size (f, -1, -1, 1, 0);
6381
6382 adjust_frame_glyphs (f);
6383 unblock_input ();
6384
6385 /* Scan dead buffer windows. */
6386 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
6387 {
6388 window = XCAR (dead_windows);
6389 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
6390 delete_deletable_window (window);
6391 }
6392
6393 /* Record the selected window's buffer here. The window should
6394 already be the selected one from the call above. */
6395 select_window (data->current_window, Qnil, 0);
6396
6397 /* Fselect_window will have made f the selected frame, so we
6398 reselect the proper frame here. Fhandle_switch_frame will change the
6399 selected window too, but that doesn't make the call to
6400 Fselect_window above totally superfluous; it still sets f's
6401 selected window. */
6402 if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
6403 do_switch_frame (data->selected_frame, 0, 0, Qnil);
6404
6405 run_window_configuration_change_hook (f);
6406 }
6407
6408 if (!NILP (new_current_buffer))
6409 {
6410 Fset_buffer (new_current_buffer);
6411 /* If the new current buffer doesn't appear in the selected
6412 window, go to its old point (see bug#12208). */
6413 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
6414 Fgoto_char (make_number (old_point));
6415 }
6416
6417 Vminibuf_scroll_window = data->minibuf_scroll_window;
6418 minibuf_selected_window = data->minibuf_selected_window;
6419
6420 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6013} 6421}
6014 6422
6423
6424#if 0
6015DEFUN ("set-window-configuration", Fset_window_configuration, 6425DEFUN ("set-window-configuration", Fset_window_configuration,
6016 Sset_window_configuration, 1, 1, 0, 6426 Sset_window_configuration, 1, 1, 0,
6017 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. 6427 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
@@ -6120,18 +6530,18 @@ the return value is nil. Otherwise the value is t. */)
6120 call1 (Qrecord_window_buffer, window); 6530 call1 (Qrecord_window_buffer, window);
6121 } 6531 }
6122 6532
6123 /* Don't run lisp in the following segment since the frame is in a 6533 /* Consider frame unofficial, temporarily. */
6124 completely inconsistent state. See Bug#16207. */ 6534 f->official = false;
6125 record_unwind_protect (unwind_change_frame, inhibit_lisp_code);
6126 inhibit_lisp_code = Qt;
6127 /* The mouse highlighting code could get screwed up 6535 /* The mouse highlighting code could get screwed up
6128 if it runs during this. */ 6536 if it runs during this. */
6129 block_input (); 6537 block_input ();
6130 6538
6131 if (data->frame_text_width != previous_frame_text_width 6539 if (data->frame_text_width != previous_frame_text_width
6132 || data->frame_text_height != previous_frame_text_height) 6540 || data->frame_text_height != previous_frame_text_height)
6133 change_frame_size (f, data->frame_text_width, 6541 /* Make frame size fit the one in data, so window sizes restored
6134 data->frame_text_height, 0, 0, 0, 1); 6542 from data match those of the frame. */
6543 adjust_frame_size (f, data->frame_text_width,
6544 data->frame_text_height, 5, 0);
6135 6545
6136 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines) 6546 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
6137 { 6547 {
@@ -6228,7 +6638,9 @@ the return value is nil. Otherwise the value is t. */)
6228 wset_normal_cols (w, p->normal_cols); 6638 wset_normal_cols (w, p->normal_cols);
6229 wset_normal_lines (w, p->normal_lines); 6639 wset_normal_lines (w, p->normal_lines);
6230 w->hscroll = XFASTINT (p->hscroll); 6640 w->hscroll = XFASTINT (p->hscroll);
6641 w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll);
6231 w->min_hscroll = XFASTINT (p->min_hscroll); 6642 w->min_hscroll = XFASTINT (p->min_hscroll);
6643 w->hscroll_whole = XFASTINT (p->hscroll_whole);
6232 wset_display_table (w, p->display_table); 6644 wset_display_table (w, p->display_table);
6233 w->left_margin_cols = XINT (p->left_margin_cols); 6645 w->left_margin_cols = XINT (p->left_margin_cols);
6234 w->right_margin_cols = XINT (p->right_margin_cols); 6646 w->right_margin_cols = XINT (p->right_margin_cols);
@@ -6236,7 +6648,9 @@ the return value is nil. Otherwise the value is t. */)
6236 w->right_fringe_width = XINT (p->right_fringe_width); 6648 w->right_fringe_width = XINT (p->right_fringe_width);
6237 w->fringes_outside_margins = !NILP (p->fringes_outside_margins); 6649 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
6238 w->scroll_bar_width = XINT (p->scroll_bar_width); 6650 w->scroll_bar_width = XINT (p->scroll_bar_width);
6651 w->scroll_bar_height = XINT (p->scroll_bar_height);
6239 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); 6652 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
6653 wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type);
6240 wset_dedicated (w, p->dedicated); 6654 wset_dedicated (w, p->dedicated);
6241 wset_combination_limit (w, p->combination_limit); 6655 wset_combination_limit (w, p->combination_limit);
6242 /* Restore any window parameters that have been saved. 6656 /* Restore any window parameters that have been saved.
@@ -6267,16 +6681,15 @@ the return value is nil. Otherwise the value is t. */)
6267 wset_buffer (w, p->buffer); 6681 wset_buffer (w, p->buffer);
6268 w->start_at_line_beg = !NILP (p->start_at_line_beg); 6682 w->start_at_line_beg = !NILP (p->start_at_line_beg);
6269 set_marker_restricted (w->start, p->start, w->contents); 6683 set_marker_restricted (w->start, p->start, w->contents);
6270 set_marker_restricted (w->pointm, p->pointm, 6684 set_marker_restricted (w->pointm, p->pointm, w->contents);
6271 w->contents); 6685 set_marker_restricted (w->old_pointm, p->old_pointm, w->contents);
6272
6273 /* As documented in Fcurrent_window_configuration, don't 6686 /* As documented in Fcurrent_window_configuration, don't
6274 restore the location of point in the buffer which was 6687 restore the location of point in the buffer which was
6275 current when the window configuration was recorded. */ 6688 current when the window configuration was recorded. */
6276 if (!EQ (p->buffer, new_current_buffer) 6689 if (!EQ (p->buffer, new_current_buffer)
6277 && XBUFFER (p->buffer) == current_buffer) 6690 && XBUFFER (p->buffer) == current_buffer)
6278 Fgoto_char (w->pointm); 6691 Fgoto_char (w->pointm);
6279 } 6692 }
6280 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents))) 6693 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
6281 /* Keep window's old buffer; make sure the markers are real. */ 6694 /* Keep window's old buffer; make sure the markers are real. */
6282 { 6695 {
@@ -6288,20 +6701,26 @@ the return value is nil. Otherwise the value is t. */)
6288 (w->pointm, w->contents, 6701 (w->pointm, w->contents,
6289 BUF_PT (XBUFFER (w->contents)), 6702 BUF_PT (XBUFFER (w->contents)),
6290 BUF_PT_BYTE (XBUFFER (w->contents))); 6703 BUF_PT_BYTE (XBUFFER (w->contents)));
6704 if (XMARKER (w->old_pointm)->buffer == 0)
6705 set_marker_restricted_both
6706 (w->old_pointm, w->contents,
6707 BUF_PT (XBUFFER (w->contents)),
6708 BUF_PT_BYTE (XBUFFER (w->contents)));
6291 w->start_at_line_beg = 1; 6709 w->start_at_line_beg = 1;
6292 } 6710 }
6293 else if (!NILP (w->start)) 6711 else if (!NILP (w->start))
6294 /* Leaf window has no live buffer, get one. */ 6712 /* Leaf window has no live buffer, get one. */
6295 { 6713 {
6296 /* Get the buffer via other_buffer_safely in order to 6714 /* Get the buffer via other_buffer_safely in order to
6297 avoid showing an unimportant buffer and, if necessary, to 6715 avoid showing an unimportant buffer and, if necessary, to
6298 recreate *scratch* in the course (part of Juanma's bs-show 6716 recreate *scratch* in the course (part of Juanma's bs-show
6299 scenario from March 2011). */ 6717 scenario from March 2011). */
6300 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); 6718 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
6301 /* This will set the markers to beginning of visible 6719 /* This will set the markers to beginning of visible
6302 range. */ 6720 range. */
6303 set_marker_restricted_both (w->start, w->contents, 0, 0); 6721 set_marker_restricted_both (w->start, w->contents, 0, 0);
6304 set_marker_restricted_both (w->pointm, w->contents, 0, 0); 6722 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
6723 set_marker_restricted_both (w->old_pointm, w->contents, 0, 0);
6305 w->start_at_line_beg = 1; 6724 w->start_at_line_beg = 1;
6306 if (!NILP (w->dedicated)) 6725 if (!NILP (w->dedicated))
6307 /* Record this window as dead. */ 6726 /* Record this window as dead. */
@@ -6339,8 +6758,8 @@ the return value is nil. Otherwise the value is t. */)
6339 /* Set the frame size to the value it had before this function. */ 6758 /* Set the frame size to the value it had before this function. */
6340 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f) 6759 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
6341 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f)) 6760 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
6342 change_frame_size (f, previous_frame_text_width, 6761 adjust_frame_size (f, previous_frame_text_width,
6343 previous_frame_text_height, 0, 0, 0, 1); 6762 previous_frame_text_height, 5, 0);
6344 6763
6345 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) 6764 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
6346 { 6765 {
@@ -6369,9 +6788,13 @@ the return value is nil. Otherwise the value is t. */)
6369 ++n; 6788 ++n;
6370 } 6789 }
6371 6790
6791 /* Make frame official again and apply frame size changes if
6792 needed. */
6793 f->official = true;
6794 adjust_frame_size (f, -1, -1, 1, 0);
6795
6372 adjust_frame_glyphs (f); 6796 adjust_frame_glyphs (f);
6373 unblock_input (); 6797 unblock_input ();
6374 unbind_to (count, Qnil);
6375 6798
6376 /* Scan dead buffer windows. */ 6799 /* Scan dead buffer windows. */
6377 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows)) 6800 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
@@ -6410,6 +6833,7 @@ the return value is nil. Otherwise the value is t. */)
6410 6833
6411 return (FRAME_LIVE_P (f) ? Qt : Qnil); 6834 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6412} 6835}
6836#endif
6413 6837
6414void 6838void
6415restore_window_configuration (Lisp_Object configuration) 6839restore_window_configuration (Lisp_Object configuration)
@@ -6442,6 +6866,7 @@ delete_all_child_windows (Lisp_Object window)
6442 { 6866 {
6443 unshow_buffer (w); 6867 unshow_buffer (w);
6444 unchain_marker (XMARKER (w->pointm)); 6868 unchain_marker (XMARKER (w->pointm));
6869 unchain_marker (XMARKER (w->old_pointm));
6445 unchain_marker (XMARKER (w->start)); 6870 unchain_marker (XMARKER (w->start));
6446 /* Since combination limit makes sense for an internal windows 6871 /* Since combination limit makes sense for an internal windows
6447 only, we use this slot to save the buffer for the sake of 6872 only, we use this slot to save the buffer for the sake of
@@ -6548,7 +6973,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6548 p->normal_cols = w->normal_cols; 6973 p->normal_cols = w->normal_cols;
6549 p->normal_lines = w->normal_lines; 6974 p->normal_lines = w->normal_lines;
6550 XSETFASTINT (p->hscroll, w->hscroll); 6975 XSETFASTINT (p->hscroll, w->hscroll);
6976 p->suspend_auto_hscroll = w->suspend_auto_hscroll ? Qt : Qnil;
6551 XSETFASTINT (p->min_hscroll, w->min_hscroll); 6977 XSETFASTINT (p->min_hscroll, w->min_hscroll);
6978 XSETFASTINT (p->hscroll_whole, w->hscroll_whole);
6552 p->display_table = w->display_table; 6979 p->display_table = w->display_table;
6553 p->left_margin_cols = make_number (w->left_margin_cols); 6980 p->left_margin_cols = make_number (w->left_margin_cols);
6554 p->right_margin_cols = make_number (w->right_margin_cols); 6981 p->right_margin_cols = make_number (w->right_margin_cols);
@@ -6556,7 +6983,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6556 p->right_fringe_width = make_number (w->right_fringe_width); 6983 p->right_fringe_width = make_number (w->right_fringe_width);
6557 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; 6984 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
6558 p->scroll_bar_width = make_number (w->scroll_bar_width); 6985 p->scroll_bar_width = make_number (w->scroll_bar_width);
6986 p->scroll_bar_height = make_number (w->scroll_bar_height);
6559 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 6987 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6988 p->horizontal_scroll_bar_type = w->horizontal_scroll_bar_type;
6560 p->dedicated = w->dedicated; 6989 p->dedicated = w->dedicated;
6561 p->combination_limit = w->combination_limit; 6990 p->combination_limit = w->combination_limit;
6562 p->window_parameters = Qnil; 6991 p->window_parameters = Qnil;
@@ -6618,9 +7047,13 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6618 BUF_PT_BYTE (XBUFFER (w->contents))); 7047 BUF_PT_BYTE (XBUFFER (w->contents)));
6619 else 7048 else
6620 p->pointm = Fcopy_marker (w->pointm, Qnil); 7049 p->pointm = Fcopy_marker (w->pointm, Qnil);
7050 p->old_pointm = Fcopy_marker (w->old_pointm, Qnil);
6621 XMARKER (p->pointm)->insertion_type 7051 XMARKER (p->pointm)->insertion_type
6622 = !NILP (buffer_local_value /* Don't signal error if void. */ 7052 = !NILP (buffer_local_value /* Don't signal error if void. */
6623 (Qwindow_point_insertion_type, w->contents)); 7053 (Qwindow_point_insertion_type, w->contents));
7054 XMARKER (p->old_pointm)->insertion_type
7055 = !NILP (buffer_local_value /* Don't signal error if void. */
7056 (Qwindow_point_insertion_type, w->contents));
6624 7057
6625 p->start = Fcopy_marker (w->start, Qnil); 7058 p->start = Fcopy_marker (w->start, Qnil);
6626 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil; 7059 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
@@ -6628,6 +7061,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6628 else 7061 else
6629 { 7062 {
6630 p->pointm = Qnil; 7063 p->pointm = Qnil;
7064 p->old_pointm = Qnil;
6631 p->start = Qnil; 7065 p->start = Qnil;
6632 p->start_at_line_beg = Qnil; 7066 p->start_at_line_beg = Qnil;
6633 } 7067 }
@@ -6697,7 +7131,6 @@ static void
6697apply_window_adjustment (struct window *w) 7131apply_window_adjustment (struct window *w)
6698{ 7132{
6699 eassert (w); 7133 eassert (w);
6700 adjust_window_margins (w);
6701 clear_glyph_matrix (w->current_matrix); 7134 clear_glyph_matrix (w->current_matrix);
6702 w->window_end_valid = 0; 7135 w->window_end_valid = 0;
6703 windows_or_buffers_changed = 30; 7136 windows_or_buffers_changed = 30;
@@ -6715,8 +7148,8 @@ set_window_margins (struct window *w, Lisp_Object left_width,
6715 Lisp_Object right_width) 7148 Lisp_Object right_width)
6716{ 7149{
6717 int left, right; 7150 int left, right;
7151 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
6718 7152
6719 /* FIXME: what about margins that are too wide? */
6720 left = (NILP (left_width) ? 0 7153 left = (NILP (left_width) ? 0
6721 : (CHECK_NATNUM (left_width), XINT (left_width))); 7154 : (CHECK_NATNUM (left_width), XINT (left_width)));
6722 right = (NILP (right_width) ? 0 7155 right = (NILP (right_width) ? 0
@@ -6724,11 +7157,23 @@ set_window_margins (struct window *w, Lisp_Object left_width,
6724 7157
6725 if (w->left_margin_cols != left || w->right_margin_cols != right) 7158 if (w->left_margin_cols != left || w->right_margin_cols != right)
6726 { 7159 {
6727 w->left_margin_cols = left; 7160 /* Don't change anything if new margins won't fit. */
6728 w->right_margin_cols = right; 7161 if ((WINDOW_PIXEL_WIDTH (w)
6729 return w; 7162 - WINDOW_FRINGES_WIDTH (w)
7163 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7164 - (left + right) * unit)
7165 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7166 {
7167 w->left_margin_cols = left;
7168 w->right_margin_cols = right;
7169
7170 return w;
7171 }
7172 else
7173 return NULL;
6730 } 7174 }
6731 return NULL; 7175 else
7176 return NULL;
6732} 7177}
6733 7178
6734DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 7179DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
@@ -6790,12 +7235,25 @@ set_window_fringes (struct window *w, Lisp_Object left_width,
6790 || w->right_fringe_width != right 7235 || w->right_fringe_width != right
6791 || w->fringes_outside_margins != outside)) 7236 || w->fringes_outside_margins != outside))
6792 { 7237 {
7238 if (left > 0 || right > 0)
7239 {
7240 /* Don't change anything if new fringes don't fit. */
7241 if ((WINDOW_PIXEL_WIDTH (w)
7242 - WINDOW_MARGINS_WIDTH (w)
7243 - WINDOW_SCROLL_BAR_AREA_WIDTH (w)
7244 - max (left, 0) - max (right, 0))
7245 < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7246 return NULL;
7247 }
7248
6793 w->left_fringe_width = left; 7249 w->left_fringe_width = left;
6794 w->right_fringe_width = right; 7250 w->right_fringe_width = right;
6795 w->fringes_outside_margins = outside; 7251 w->fringes_outside_margins = outside;
7252
6796 return w; 7253 return w;
6797 } 7254 }
6798 return NULL; 7255 else
7256 return NULL;
6799} 7257}
6800 7258
6801DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 7259DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
@@ -6846,9 +7304,12 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6846 7304
6847static struct window * 7305static struct window *
6848set_window_scroll_bars (struct window *w, Lisp_Object width, 7306set_window_scroll_bars (struct window *w, Lisp_Object width,
6849 Lisp_Object vertical_type, Lisp_Object horizontal_type) 7307 Lisp_Object vertical_type, Lisp_Object height,
7308 Lisp_Object horizontal_type)
6850{ 7309{
6851 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); 7310 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
7311 int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height)));
7312 bool changed = 0;
6852 7313
6853 if (iwidth == 0) 7314 if (iwidth == 0)
6854 vertical_type = Qnil; 7315 vertical_type = Qnil;
@@ -6862,32 +7323,69 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
6862 if (w->scroll_bar_width != iwidth 7323 if (w->scroll_bar_width != iwidth
6863 || !EQ (w->vertical_scroll_bar_type, vertical_type)) 7324 || !EQ (w->vertical_scroll_bar_type, vertical_type))
6864 { 7325 {
6865 w->scroll_bar_width = iwidth; 7326 /* Don't change anything if new scroll bar won't fit. */
6866 wset_vertical_scroll_bar_type (w, vertical_type); 7327 if ((WINDOW_PIXEL_WIDTH (w)
6867 return w; 7328 - WINDOW_MARGINS_WIDTH (w)
7329 - WINDOW_FRINGES_WIDTH (w)
7330 - max (iwidth, 0))
7331 >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
7332 {
7333 w->scroll_bar_width = iwidth;
7334 wset_vertical_scroll_bar_type (w, vertical_type);
7335 changed = 1;
7336 }
7337 }
7338
7339 if (MINI_WINDOW_P (w) || iheight == 0)
7340 horizontal_type = Qnil;
7341
7342 if (!(NILP (horizontal_type)
7343 || EQ (horizontal_type, Qbottom)
7344 || EQ (horizontal_type, Qt)))
7345 error ("Invalid type of horizontal scroll bar");
7346
7347 if (w->scroll_bar_height != iheight
7348 || !EQ (w->horizontal_scroll_bar_type, horizontal_type))
7349 {
7350 /* Don't change anything if new scroll bar won't fit. */
7351 if ((WINDOW_PIXEL_HEIGHT (w)
7352 - WINDOW_HEADER_LINE_HEIGHT (w)
7353 - WINDOW_MODE_LINE_HEIGHT (w)
7354 - max (iheight, 0))
7355 >= MIN_SAFE_WINDOW_PIXEL_HEIGHT (w))
7356 {
7357 w->scroll_bar_height = iheight;
7358 wset_horizontal_scroll_bar_type (w, horizontal_type);
7359 changed = 1;
7360 }
6868 } 7361 }
6869 return NULL; 7362
7363 return changed ? w : NULL;
6870} 7364}
6871 7365
6872DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, 7366DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6873 Sset_window_scroll_bars, 2, 4, 0, 7367 Sset_window_scroll_bars, 1, 5, 0,
6874 doc: /* Set width and type of scroll bars of window WINDOW. 7368 doc: /* Set width and type of scroll bars of window WINDOW.
6875WINDOW must be a live window and defaults to the selected one. 7369WINDOW must be a live window and defaults to the selected one.
6876 7370
6877Second parameter WIDTH specifies the pixel width for the scroll bar. 7371Second parameter WIDTH specifies the pixel width for the scroll bar.
6878Third parameter VERTICAL-TYPE specifies the type of the vertical scroll 7372Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6879bar: left, right, or nil. 7373bar: left, right, or nil. If WIDTH is nil, use the frame's scroll-bar
6880If WIDTH is nil, use the frame's scroll-bar width. 7374width. If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6881If VERTICAL-TYPE is t, use the frame's scroll-bar type. 7375
6882Fourth parameter HORIZONTAL-TYPE is currently unused. 7376Fourth parameter HEIGHT specifies the pixel height for the scroll bar.
7377Fifth parameter HORIZONTAL-TYPE specifies the type of the vertical
7378scroll bar: nil, bottom, or t. If HEIGHT is nil, use the frame's
7379scroll-bar height. If HORIZONTAL-TYPE is t, use the frame's scroll-bar
7380type.
6883 7381
6884Return t if scroll bars were actually changed and nil otherwise. */) 7382Return t if scroll bars were actually changed and nil otherwise. */)
6885 (Lisp_Object window, Lisp_Object width, 7383 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type,
6886 Lisp_Object vertical_type, Lisp_Object horizontal_type) 7384 Lisp_Object height, Lisp_Object horizontal_type)
6887{ 7385{
6888 struct window *w 7386 struct window *w
6889 = set_window_scroll_bars (decode_live_window (window), 7387 = set_window_scroll_bars (decode_live_window (window),
6890 width, vertical_type, horizontal_type); 7388 width, vertical_type, height, horizontal_type);
6891 return w ? (apply_window_adjustment (w), Qt) : Qnil; 7389 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6892} 7390}
6893 7391
@@ -6897,19 +7395,20 @@ DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
6897 doc: /* Get width and type of scroll bars of window WINDOW. 7395 doc: /* Get width and type of scroll bars of window WINDOW.
6898WINDOW must be a live window and defaults to the selected one. 7396WINDOW must be a live window and defaults to the selected one.
6899 7397
6900Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE). 7398Value is a list of the form (WIDTH COLS VERTICAL-TYPE HEIGHT LINES
6901If WIDTH is nil or TYPE is t, the window is using the frame's corresponding 7399HORIZONTAL-TYPE). If WIDTH or HEIGHT is nil or TYPE is t, the window is
6902value. */) 7400using the frame's corresponding value. */)
6903 (Lisp_Object window) 7401 (Lisp_Object window)
6904{ 7402{
6905 struct window *w = decode_live_window (window); 7403 struct window *w = decode_live_window (window);
6906 7404
6907 return list4 (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)), 7405 return Fcons (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)),
6908 make_number (WINDOW_SCROLL_BAR_COLS (w)), 7406 list5 (make_number (WINDOW_SCROLL_BAR_COLS (w)),
6909 w->vertical_scroll_bar_type, Qnil); 7407 w->vertical_scroll_bar_type,
7408 make_number (WINDOW_SCROLL_BAR_AREA_HEIGHT (w)),
7409 make_number (WINDOW_SCROLL_BAR_LINES (w)),
7410 w->horizontal_scroll_bar_type));
6910} 7411}
6911
6912
6913 7412
6914/*********************************************************************** 7413/***********************************************************************
6915 Smooth scrolling 7414 Smooth scrolling
@@ -7099,7 +7598,9 @@ compare_window_configurations (Lisp_Object configuration1,
7099 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width) 7598 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
7100 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins) 7599 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
7101 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width) 7600 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
7102 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)) 7601 || !EQ (sw1->scroll_bar_height, sw2->scroll_bar_height)
7602 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type)
7603 || !EQ (sw1->horizontal_scroll_bar_type, sw2->horizontal_scroll_bar_type))
7103 return 0; 7604 return 0;
7104 } 7605 }
7105 7606
@@ -7153,6 +7654,7 @@ syms_of_window (void)
7153 DEFSYM (Qdelete_window, "delete-window"); 7654 DEFSYM (Qdelete_window, "delete-window");
7154 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); 7655 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
7155 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); 7656 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
7657 DEFSYM (Qwindow_sanitize_window_sizes, "window--sanitize-window-sizes");
7156 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total"); 7658 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
7157 DEFSYM (Qsafe, "safe"); 7659 DEFSYM (Qsafe, "safe");
7158 DEFSYM (Qdisplay_buffer, "display-buffer"); 7660 DEFSYM (Qdisplay_buffer, "display-buffer");
@@ -7379,12 +7881,14 @@ pixelwise even if this option is nil. */);
7379 defsubr (&Swindow_right_divider_width); 7881 defsubr (&Swindow_right_divider_width);
7380 defsubr (&Swindow_bottom_divider_width); 7882 defsubr (&Swindow_bottom_divider_width);
7381 defsubr (&Swindow_scroll_bar_width); 7883 defsubr (&Swindow_scroll_bar_width);
7884 defsubr (&Swindow_scroll_bar_height);
7382 defsubr (&Swindow_inside_edges); 7885 defsubr (&Swindow_inside_edges);
7383 defsubr (&Swindow_inside_pixel_edges); 7886 defsubr (&Swindow_inside_pixel_edges);
7384 defsubr (&Swindow_inside_absolute_pixel_edges); 7887 defsubr (&Swindow_inside_absolute_pixel_edges);
7385 defsubr (&Scoordinates_in_window_p); 7888 defsubr (&Scoordinates_in_window_p);
7386 defsubr (&Swindow_at); 7889 defsubr (&Swindow_at);
7387 defsubr (&Swindow_point); 7890 defsubr (&Swindow_point);
7891 defsubr (&Swindow_old_point);
7388 defsubr (&Swindow_start); 7892 defsubr (&Swindow_start);
7389 defsubr (&Swindow_end); 7893 defsubr (&Swindow_end);
7390 defsubr (&Sset_window_point); 7894 defsubr (&Sset_window_point);