diff options
| author | Martin Rudalics | 2019-01-11 10:02:47 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2019-01-11 10:02:47 +0100 |
| commit | e567ac149518967f992b1286d90d94df6bb589b7 (patch) | |
| tree | 32464d12a2b3fcc7ecf7e4cd5d6fc2d4ef7c729b /src | |
| parent | 470082de55f7b1c1cde8aabbb5b8de55b4b08f83 (diff) | |
| download | emacs-e567ac149518967f992b1286d90d94df6bb589b7.tar.gz emacs-e567ac149518967f992b1286d90d94df6bb589b7.zip | |
Run window change functions during redisplay
* doc/lispref/windows.texi (Window Sizes): Move (and rename)
descriptions of 'window-pixel-height-before-size-change' and
'window-pixel-width-before-size-change' to Window Hooks
section.
(Window Configurations): Remove warning against use of
'save-window-excursion' in 'window-size-change-functions'.
(Window Hooks): Rewrite section according to redesign of
window change functions.
* lisp/erc/erc-track.el (erc-window-configuration-change)
(erc-modified-channels-update): Call latter directly from
'window-configuration-change-hook' instead via
'post-command-hook'.
* lisp/frame.el (frame-size-changed-p): Change nomenclature
in let bindings.
* lisp/net/rcirc.el (rcirc-window-configuration-change)
(rcirc-window-configuration-change-1): Call latter directly
from 'window-configuration-change-hook' instead via
'post-command-hook'.
* lisp/window.el (window-pixel-width-before-size-change)
(window-pixel-height-before-size-change): Defalias.
(window--resize-mini-window, window-resize)
(adjust-window-trailing-edge, delete-window)
(delete-other-windows, balance-windows): Don't run
'window-configuration-change-hook' any more from here.
(split-window): Don't run 'window-configuration-change-hook'
from here. 'run-window-scroll-functions' from here.
(window--adjust-process-windows): Run from
'window-configuration-change-hook' only.
* src/frame.c (old_selected_frame): New Lisp variable.
(make_frame): Initialize frame's change_stamp slot.
(Fold_selected_frame): New function.
* src/frame.h (struct frame): New slots old_selected_window,
window_change, change_stamp and number_of_windows.
(fset_old_selected_window): New inlined function.
(FRAME_WINDOW_CHANGE, FRAME_OLD_SELECTED_WINDOW): New macros.
* src/window.c (old_selected_window): New Lisp variable.
(wset_old_buffer): New inlined function.
(Fframe_old_selected_window, Fold_selected_window)
(Fwindow_old_buffer): New functions.
(Fwindow_old_pixel_width, Fwindow_old_pixel_height): Rename
from Fwindow_pixel_width_before_size_change and
Fwindow_pixel_height_before_size_change. Update doc-strings.
(Fwindow_old_body_pixel_width, Fwindow_old_body_pixel_height):
New functions.
(Fdelete_other_windows_internal): Set frame's window_change
slot instead of running 'window-configuration-change-hook'.
(Frun_window_configuration_change_hook): In doc-string tell
that this function is no more needed.
(Frun_window_scroll_functions): Amend doc-string. Run with
window's buffer current.
(window_sub_list, window_change_record_windows)
(window_change_record_frame, window_change_record)
(run_window_change_functions_1, run_window_change_functions):
New functions.
(set_window_buffer): Set frame's window_change slot instead of
running 'window-configuration-change-hook'.
(make_window): Don't initialize pixel_width_before_size_change
and pixel_height_before_size_change slots.
(window_resize_apply, Fdelete_window_internal): Set frame's
window_change slot.
(Fsplit_window_internal): Set frame's window_change slot.
Don't run 'window-scroll-functions' from here.
* src/window.h (struct window): New slots old_buffer,
change_stamp, old_pixel_width (renamed from
pixel_width_before_size_change), old_pixel_height (renamed
from pixel_height_before_size_change), old_body_pixel_width
and old_body_pixel_height.
* src/xdisp.c (init_iterator): Set frame's window_change slot
when the body height or width changes.
(prepare_menu_bars): Don't run_window_size_change_functions.
(redisplay_internal): Don't run_window_size_change_functions,
run_window_change_functions instead.
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 25 | ||||
| -rw-r--r-- | src/frame.h | 46 | ||||
| -rw-r--r-- | src/window.c | 767 | ||||
| -rw-r--r-- | src/window.h | 27 | ||||
| -rw-r--r-- | src/xdisp.c | 72 |
5 files changed, 680 insertions, 257 deletions
diff --git a/src/frame.c b/src/frame.c index ca6704a44c0..6d93abd09bf 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -55,9 +55,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| 57 | /* The currently selected frame. */ | 57 | /* The currently selected frame. */ |
| 58 | |||
| 59 | Lisp_Object selected_frame; | 58 | Lisp_Object selected_frame; |
| 60 | 59 | ||
| 60 | /* The selected frame the last time window change functions were run. */ | ||
| 61 | Lisp_Object old_selected_frame; | ||
| 62 | |||
| 61 | /* A frame which is not just a mini-buffer, or NULL if there are no such | 63 | /* A frame which is not just a mini-buffer, or NULL if there are no such |
| 62 | frames. This is usually the most recent such frame that was selected. */ | 64 | frames. This is usually the most recent such frame that was selected. */ |
| 63 | 65 | ||
| @@ -855,7 +857,8 @@ make_frame (bool mini_p) | |||
| 855 | f->ns_transparent_titlebar = false; | 857 | f->ns_transparent_titlebar = false; |
| 856 | #endif | 858 | #endif |
| 857 | #endif | 859 | #endif |
| 858 | 860 | /* This one should never be zero. */ | |
| 861 | f->change_stamp = 1; | ||
| 859 | root_window = make_window (); | 862 | root_window = make_window (); |
| 860 | rw = XWINDOW (root_window); | 863 | rw = XWINDOW (root_window); |
| 861 | if (mini_p) | 864 | if (mini_p) |
| @@ -1451,7 +1454,8 @@ This function returns FRAME, or nil if FRAME has been deleted. */) | |||
| 1451 | return do_switch_frame (frame, 1, 0, norecord); | 1454 | return do_switch_frame (frame, 1, 0, norecord); |
| 1452 | } | 1455 | } |
| 1453 | 1456 | ||
| 1454 | DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "^e", | 1457 | DEFUN ("handle-switch-frame", Fhandle_switch_frame, |
| 1458 | Shandle_switch_frame, 1, 1, "^e", | ||
| 1455 | doc: /* Handle a switch-frame event EVENT. | 1459 | doc: /* Handle a switch-frame event EVENT. |
| 1456 | Switch-frame events are usually bound to this function. | 1460 | Switch-frame events are usually bound to this function. |
| 1457 | A switch-frame event is an event Emacs sends itself to | 1461 | A switch-frame event is an event Emacs sends itself to |
| @@ -1471,6 +1475,18 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0, | |||
| 1471 | { | 1475 | { |
| 1472 | return selected_frame; | 1476 | return selected_frame; |
| 1473 | } | 1477 | } |
| 1478 | |||
| 1479 | DEFUN ("old-selected-frame", Fold_selected_frame, | ||
| 1480 | Sold_selected_frame, 0, 0, 0, | ||
| 1481 | doc: /* Return the old selected FRAME. | ||
| 1482 | FRAME must be a live frame and defaults to the selected one. | ||
| 1483 | |||
| 1484 | The return value is the frame selected the last time window change | ||
| 1485 | functions were run. */) | ||
| 1486 | (void) | ||
| 1487 | { | ||
| 1488 | return old_selected_frame; | ||
| 1489 | } | ||
| 1474 | 1490 | ||
| 1475 | DEFUN ("frame-list", Fframe_list, Sframe_list, | 1491 | DEFUN ("frame-list", Fframe_list, Sframe_list, |
| 1476 | 0, 0, 0, | 1492 | 0, 0, 0, |
| @@ -6098,9 +6114,10 @@ iconify the top level frame instead. */); | |||
| 6098 | defsubr (&Swindow_system); | 6114 | defsubr (&Swindow_system); |
| 6099 | defsubr (&Sframe_windows_min_size); | 6115 | defsubr (&Sframe_windows_min_size); |
| 6100 | defsubr (&Smake_terminal_frame); | 6116 | defsubr (&Smake_terminal_frame); |
| 6101 | defsubr (&Shandle_switch_frame); | ||
| 6102 | defsubr (&Sselect_frame); | 6117 | defsubr (&Sselect_frame); |
| 6118 | defsubr (&Shandle_switch_frame); | ||
| 6103 | defsubr (&Sselected_frame); | 6119 | defsubr (&Sselected_frame); |
| 6120 | defsubr (&Sold_selected_frame); | ||
| 6104 | defsubr (&Sframe_list); | 6121 | defsubr (&Sframe_list); |
| 6105 | defsubr (&Sframe_parent); | 6122 | defsubr (&Sframe_parent); |
| 6106 | defsubr (&Sframe_ancestor_p); | 6123 | defsubr (&Sframe_ancestor_p); |
diff --git a/src/frame.h b/src/frame.h index b7059027fbe..ab3efdfa926 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -125,6 +125,10 @@ struct frame | |||
| 125 | The selected window of the selected frame is Emacs's selected window. */ | 125 | The selected window of the selected frame is Emacs's selected window. */ |
| 126 | Lisp_Object selected_window; | 126 | Lisp_Object selected_window; |
| 127 | 127 | ||
| 128 | /* This frame's selected window when run_window_change_functions was | ||
| 129 | called the last time on this frame. */ | ||
| 130 | Lisp_Object old_selected_window; | ||
| 131 | |||
| 128 | /* This frame's minibuffer window. | 132 | /* This frame's minibuffer window. |
| 129 | Most frames have their own minibuffer windows, | 133 | Most frames have their own minibuffer windows, |
| 130 | but only the selected frame's minibuffer window | 134 | but only the selected frame's minibuffer window |
| @@ -321,9 +325,14 @@ struct frame | |||
| 321 | cleared. */ | 325 | cleared. */ |
| 322 | bool_bf explicit_name : 1; | 326 | bool_bf explicit_name : 1; |
| 323 | 327 | ||
| 324 | /* True if configuration of windows on this frame has changed since | 328 | /* True if at least one window on this frame changed since the last |
| 325 | last call of run_window_size_change_functions. */ | 329 | call of run_window_change_functions. Changes are either "state |
| 326 | bool_bf window_configuration_changed : 1; | 330 | changes" (a window has been created, deleted or got assigned |
| 331 | another buffer) or "size changes" (the total or body size of a | ||
| 332 | window changed). run_window_change_functions exits early unless | ||
| 333 | either this flag is true or a window selection happened on this | ||
| 334 | frame. */ | ||
| 335 | bool_bf window_change : 1; | ||
| 327 | 336 | ||
| 328 | /* True if the mouse has moved on this display device | 337 | /* True if the mouse has moved on this display device |
| 329 | since the last time we checked. */ | 338 | since the last time we checked. */ |
| @@ -406,6 +415,20 @@ struct frame | |||
| 406 | 415 | ||
| 407 | /* Bitfield area ends here. */ | 416 | /* Bitfield area ends here. */ |
| 408 | 417 | ||
| 418 | /* This frame's change stamp, set the last time window change | ||
| 419 | functions were run for this frame. Should never be 0 because | ||
| 420 | that's the change stamp of a new window. A window was not on a | ||
| 421 | frame the last run_window_change_functions was called on it if | ||
| 422 | it's change stamp differs from that of its frame. */ | ||
| 423 | int change_stamp; | ||
| 424 | |||
| 425 | /* This frame's number of windows, set the last time window change | ||
| 426 | functions were run for this frame. Should never be 0 even for | ||
| 427 | minibuffer-only frames. If no window has been added, this allows | ||
| 428 | to detect whether a window was deleted on this frame since the | ||
| 429 | last time run_window_change_functions was called on it. */ | ||
| 430 | ptrdiff_t number_of_windows; | ||
| 431 | |||
| 409 | /* Number of lines (rounded up) of tool bar. REMOVE THIS */ | 432 | /* Number of lines (rounded up) of tool bar. REMOVE THIS */ |
| 410 | int tool_bar_lines; | 433 | int tool_bar_lines; |
| 411 | 434 | ||
| @@ -662,6 +685,11 @@ fset_selected_window (struct frame *f, Lisp_Object val) | |||
| 662 | f->selected_window = val; | 685 | f->selected_window = val; |
| 663 | } | 686 | } |
| 664 | INLINE void | 687 | INLINE void |
| 688 | fset_old_selected_window (struct frame *f, Lisp_Object val) | ||
| 689 | { | ||
| 690 | f->old_selected_window = val; | ||
| 691 | } | ||
| 692 | INLINE void | ||
| 665 | fset_title (struct frame *f, Lisp_Object val) | 693 | fset_title (struct frame *f, Lisp_Object val) |
| 666 | { | 694 | { |
| 667 | f->title = val; | 695 | f->title = val; |
| @@ -908,10 +936,9 @@ default_pixels_per_inch_y (void) | |||
| 908 | are frozen on frame F. */ | 936 | are frozen on frame F. */ |
| 909 | #define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts | 937 | #define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts |
| 910 | 938 | ||
| 911 | /* True if the frame's window configuration has changed since last call | 939 | /* True if at least one window changed on frame F since the last time |
| 912 | of run_window_size_change_functions. */ | 940 | window change functions were run on F. */ |
| 913 | #define FRAME_WINDOW_CONFIGURATION_CHANGED(f) \ | 941 | #define FRAME_WINDOW_CHANGE(f) (f)->window_change |
| 914 | (f)->window_configuration_changed | ||
| 915 | 942 | ||
| 916 | /* The minibuffer window of frame F, if it has one; otherwise nil. */ | 943 | /* The minibuffer window of frame F, if it has one; otherwise nil. */ |
| 917 | #define FRAME_MINIBUF_WINDOW(f) f->minibuffer_window | 944 | #define FRAME_MINIBUF_WINDOW(f) f->minibuffer_window |
| @@ -919,8 +946,10 @@ default_pixels_per_inch_y (void) | |||
| 919 | /* The root window of the window tree of frame F. */ | 946 | /* The root window of the window tree of frame F. */ |
| 920 | #define FRAME_ROOT_WINDOW(f) f->root_window | 947 | #define FRAME_ROOT_WINDOW(f) f->root_window |
| 921 | 948 | ||
| 922 | /* The currently selected window of the window tree of frame F. */ | 949 | /* The currently selected window of frame F. */ |
| 923 | #define FRAME_SELECTED_WINDOW(f) f->selected_window | 950 | #define FRAME_SELECTED_WINDOW(f) f->selected_window |
| 951 | /* The old selected window of frame F. */ | ||
| 952 | #define FRAME_OLD_SELECTED_WINDOW(f) f->old_selected_window | ||
| 924 | 953 | ||
| 925 | #define FRAME_INSERT_COST(f) (f)->insert_line_cost | 954 | #define FRAME_INSERT_COST(f) (f)->insert_line_cost |
| 926 | #define FRAME_DELETE_COST(f) (f)->delete_line_cost | 955 | #define FRAME_DELETE_COST(f) (f)->delete_line_cost |
| @@ -1215,6 +1244,7 @@ SET_FRAME_VISIBLE (struct frame *f, int v) | |||
| 1215 | (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i)) | 1244 | (f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i)) |
| 1216 | 1245 | ||
| 1217 | extern Lisp_Object selected_frame; | 1246 | extern Lisp_Object selected_frame; |
| 1247 | extern Lisp_Object old_selected_frame; | ||
| 1218 | 1248 | ||
| 1219 | #if ! (defined USE_GTK || defined HAVE_NS) | 1249 | #if ! (defined USE_GTK || defined HAVE_NS) |
| 1220 | extern int frame_default_tool_bar_height; | 1250 | extern int frame_default_tool_bar_height; |
diff --git a/src/window.c b/src/window.c index 72185f9340a..0fc4f622995 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -77,6 +77,11 @@ static void apply_window_adjustment (struct window *); | |||
| 77 | FRAME_SELECTED_WINDOW (selected_frame). */ | 77 | FRAME_SELECTED_WINDOW (selected_frame). */ |
| 78 | Lisp_Object selected_window; | 78 | Lisp_Object selected_window; |
| 79 | 79 | ||
| 80 | /* The value of selected_window at the last time window change | ||
| 81 | functions were run. This is always the same as | ||
| 82 | FRAME_OLD_SELECTED_WINDOW (old_selected_frame). */ | ||
| 83 | Lisp_Object old_selected_window; | ||
| 84 | |||
| 80 | /* A list of all windows for use by next_window and Fwindow_list. | 85 | /* A list of all windows for use by next_window and Fwindow_list. |
| 81 | Functions creating or deleting windows should invalidate this cache | 86 | Functions creating or deleting windows should invalidate this cache |
| 82 | by setting it to nil. */ | 87 | by setting it to nil. */ |
| @@ -304,6 +309,12 @@ wset_buffer (struct window *w, Lisp_Object val) | |||
| 304 | adjust_window_count (w, 1); | 309 | adjust_window_count (w, 1); |
| 305 | } | 310 | } |
| 306 | 311 | ||
| 312 | static void | ||
| 313 | wset_old_buffer (struct window *w, Lisp_Object val) | ||
| 314 | { | ||
| 315 | w->old_buffer = val; | ||
| 316 | } | ||
| 317 | |||
| 307 | DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, | 318 | DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, |
| 308 | doc: /* Return t if OBJECT is a window and nil otherwise. */) | 319 | doc: /* Return t if OBJECT is a window and nil otherwise. */) |
| 309 | (Lisp_Object object) | 320 | (Lisp_Object object) |
| @@ -428,6 +439,22 @@ return the selected window of that frame. */) | |||
| 428 | return window; | 439 | return window; |
| 429 | } | 440 | } |
| 430 | 441 | ||
| 442 | DEFUN ("frame-old-selected-window", Fframe_old_selected_window, | ||
| 443 | Sframe_old_selected_window, 0, 1, 0, | ||
| 444 | doc: /* Return old selected window of FRAME. | ||
| 445 | FRAME must be a live frame and defaults to the selected one. | ||
| 446 | |||
| 447 | The return value is the window selected on FRAME the last time window | ||
| 448 | change functions were run for FRAME. */) | ||
| 449 | (Lisp_Object frame) | ||
| 450 | { | ||
| 451 | if (NILP (frame)) | ||
| 452 | frame = selected_frame; | ||
| 453 | CHECK_LIVE_FRAME (frame); | ||
| 454 | |||
| 455 | return XFRAME (frame)->old_selected_window; | ||
| 456 | } | ||
| 457 | |||
| 431 | DEFUN ("set-frame-selected-window", Fset_frame_selected_window, | 458 | DEFUN ("set-frame-selected-window", Fset_frame_selected_window, |
| 432 | Sset_frame_selected_window, 2, 3, 0, | 459 | Sset_frame_selected_window, 2, 3, 0, |
| 433 | doc: /* Set selected window of FRAME to WINDOW. | 460 | doc: /* Set selected window of FRAME to WINDOW. |
| @@ -465,6 +492,16 @@ selected windows appears and to which many commands apply. */) | |||
| 465 | return selected_window; | 492 | return selected_window; |
| 466 | } | 493 | } |
| 467 | 494 | ||
| 495 | DEFUN ("old-selected-window", Fold_selected_window, | ||
| 496 | Sold_selected_window, 0, 0, 0, | ||
| 497 | doc: /* Return the old selected window. | ||
| 498 | The return value is the window selected the last time window change | ||
| 499 | functions were run. */) | ||
| 500 | (void) | ||
| 501 | { | ||
| 502 | return old_selected_window; | ||
| 503 | } | ||
| 504 | |||
| 468 | EMACS_INT window_select_count; | 505 | EMACS_INT window_select_count; |
| 469 | 506 | ||
| 470 | /* If select_window is called with inhibit_point_swap true it will | 507 | /* If select_window is called with inhibit_point_swap true it will |
| @@ -597,9 +634,33 @@ Return nil for an internal window or a deleted window. */) | |||
| 597 | (Lisp_Object window) | 634 | (Lisp_Object window) |
| 598 | { | 635 | { |
| 599 | struct window *w = decode_any_window (window); | 636 | struct window *w = decode_any_window (window); |
| 637 | |||
| 600 | return WINDOW_LEAF_P (w) ? w->contents : Qnil; | 638 | return WINDOW_LEAF_P (w) ? w->contents : Qnil; |
| 601 | } | 639 | } |
| 602 | 640 | ||
| 641 | DEFUN ("window-old-buffer", Fwindow_old_buffer, Swindow_old_buffer, 0, 1, 0, | ||
| 642 | doc: /* Return the old buffer displayed by WINDOW. | ||
| 643 | WINDOW must be a live window and defaults to the selected one. | ||
| 644 | |||
| 645 | The return value is the buffer shown in WINDOW at the last time window | ||
| 646 | change functions were run. It is nil if WINDOW was created after | ||
| 647 | that. It is t if WINDOW has been restored from a window configuration | ||
| 648 | after that. */) | ||
| 649 | (Lisp_Object window) | ||
| 650 | { | ||
| 651 | struct window *w = decode_live_window (window); | ||
| 652 | |||
| 653 | return (NILP (w->old_buffer) | ||
| 654 | /* A new window. */ | ||
| 655 | ? Qnil | ||
| 656 | : (w->change_stamp != WINDOW_XFRAME (w)->change_stamp) | ||
| 657 | /* A window restored from a configuration. */ | ||
| 658 | ? Qt | ||
| 659 | /* A window that was live the last time seen by window | ||
| 660 | change functions. */ | ||
| 661 | : w->old_buffer); | ||
| 662 | } | ||
| 663 | |||
| 603 | DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0, | 664 | DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0, |
| 604 | doc: /* Return the parent window of window WINDOW. | 665 | doc: /* Return the parent window of window WINDOW. |
| 605 | WINDOW must be a valid window and defaults to the selected one. | 666 | WINDOW must be a valid window and defaults to the selected one. |
| @@ -723,34 +784,32 @@ the height of the screen areas spanned by its children. */) | |||
| 723 | return make_fixnum (decode_valid_window (window)->pixel_height); | 784 | return make_fixnum (decode_valid_window (window)->pixel_height); |
| 724 | } | 785 | } |
| 725 | 786 | ||
| 726 | DEFUN ("window-pixel-width-before-size-change", | 787 | DEFUN ("window-old-pixel-width", Fwindow_old_pixel_width, |
| 727 | Fwindow_pixel_width_before_size_change, | 788 | Swindow_old_pixel_width, 0, 1, 0, |
| 728 | Swindow_pixel_width_before_size_change, 0, 1, 0, | 789 | doc: /* Return old total pixel width of WINDOW. |
| 729 | doc: /* Return pixel width of window WINDOW before last size changes. | ||
| 730 | WINDOW must be a valid window and defaults to the selected one. | 790 | WINDOW must be a valid window and defaults to the selected one. |
| 731 | 791 | ||
| 732 | The return value is the pixel width of WINDOW at the last time | 792 | The return value is the total pixel width of WINDOW after the last |
| 733 | `window-size-change-functions' was run. It's zero if WINDOW was made | 793 | time window change functions found WINDOW live on its frame. It is |
| 734 | after that. */) | 794 | zero if WINDOW was created after that. */) |
| 735 | (Lisp_Object window) | 795 | (Lisp_Object window) |
| 736 | { | 796 | { |
| 737 | return (make_fixnum | 797 | return (make_fixnum |
| 738 | (decode_valid_window (window)->pixel_width_before_size_change)); | 798 | (decode_valid_window (window)->old_pixel_width)); |
| 739 | } | 799 | } |
| 740 | 800 | ||
| 741 | DEFUN ("window-pixel-height-before-size-change", | 801 | DEFUN ("window-old-pixel-height", Fwindow_old_pixel_height, |
| 742 | Fwindow_pixel_height_before_size_change, | 802 | Swindow_old_pixel_height, 0, 1, 0, |
| 743 | Swindow_pixel_height_before_size_change, 0, 1, 0, | 803 | doc: /* Return old total pixel height of WINDOW. |
| 744 | doc: /* Return pixel height of window WINDOW before last size changes. | ||
| 745 | WINDOW must be a valid window and defaults to the selected one. | 804 | WINDOW must be a valid window and defaults to the selected one. |
| 746 | 805 | ||
| 747 | The return value is the pixel height of WINDOW at the last time | 806 | The return value is the total pixel height of WINDOW after the last |
| 748 | `window-size-change-functions' was run. It's zero if WINDOW was made | 807 | time window change functions found WINDOW live on its frame. It is |
| 749 | after that. */) | 808 | zero if WINDOW was created after that. */) |
| 750 | (Lisp_Object window) | 809 | (Lisp_Object window) |
| 751 | { | 810 | { |
| 752 | return (make_fixnum | 811 | return (make_fixnum |
| 753 | (decode_valid_window (window)->pixel_height_before_size_change)); | 812 | (decode_valid_window (window)->old_pixel_height)); |
| 754 | } | 813 | } |
| 755 | 814 | ||
| 756 | DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0, | 815 | DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0, |
| @@ -984,6 +1043,26 @@ window_body_width (struct window *w, bool pixelwise) | |||
| 984 | 0); | 1043 | 0); |
| 985 | } | 1044 | } |
| 986 | 1045 | ||
| 1046 | DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0, | ||
| 1047 | doc: /* Return the width of WINDOW's text area. | ||
| 1048 | WINDOW must be a live window and defaults to the selected one. Optional | ||
| 1049 | argument PIXELWISE non-nil means return the width in pixels. The return | ||
| 1050 | value does not include any vertical dividers, fringes or marginal areas, | ||
| 1051 | or scroll bars. | ||
| 1052 | |||
| 1053 | If PIXELWISE is nil, return the largest integer smaller than WINDOW's | ||
| 1054 | pixel width divided by the character width of WINDOW's frame. This | ||
| 1055 | means that if a column at the right of the text area is only partially | ||
| 1056 | visible, that column is not counted. | ||
| 1057 | |||
| 1058 | Note that the returned value includes the column reserved for the | ||
| 1059 | continuation glyph. */) | ||
| 1060 | (Lisp_Object window, Lisp_Object pixelwise) | ||
| 1061 | { | ||
| 1062 | return make_fixnum (window_body_width (decode_live_window (window), | ||
| 1063 | !NILP (pixelwise))); | ||
| 1064 | } | ||
| 1065 | |||
| 987 | DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0, | 1066 | DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0, |
| 988 | doc: /* Return the height of WINDOW's text area. | 1067 | doc: /* Return the height of WINDOW's text area. |
| 989 | WINDOW must be a live window and defaults to the selected one. Optional | 1068 | WINDOW must be a live window and defaults to the selected one. Optional |
| @@ -1001,24 +1080,34 @@ visible, that line is not counted. */) | |||
| 1001 | !NILP (pixelwise))); | 1080 | !NILP (pixelwise))); |
| 1002 | } | 1081 | } |
| 1003 | 1082 | ||
| 1004 | DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0, | 1083 | DEFUN ("window-old-body-pixel-width", |
| 1005 | doc: /* Return the width of WINDOW's text area. | 1084 | Fwindow_old_body_pixel_width, |
| 1006 | WINDOW must be a live window and defaults to the selected one. Optional | 1085 | Swindow_old_body_pixel_width, 0, 1, 0, |
| 1007 | argument PIXELWISE non-nil means return the width in pixels. The return | 1086 | doc: /* Return old width of WINDOW's text area in pixels. |
| 1008 | value does not include any vertical dividers, fringes or marginal areas, | 1087 | WINDOW must be a live window and defaults to the selected one. |
| 1009 | or scroll bars. | ||
| 1010 | 1088 | ||
| 1011 | If PIXELWISE is nil, return the largest integer smaller than WINDOW's | 1089 | The return value is the pixel width of WINDOW's text area after the |
| 1012 | pixel width divided by the character width of WINDOW's frame. This | 1090 | last time window change functions found WINDOW live on its frame. It |
| 1013 | means that if a column at the right of the text area is only partially | 1091 | is zero if WINDOW was created after that. */) |
| 1014 | visible, that column is not counted. | 1092 | (Lisp_Object window) |
| 1093 | { | ||
| 1094 | return (make_fixnum | ||
| 1095 | (decode_live_window (window)->old_body_pixel_width)); | ||
| 1096 | } | ||
| 1015 | 1097 | ||
| 1016 | Note that the returned value includes the column reserved for the | 1098 | DEFUN ("window-old-body-pixel-height", |
| 1017 | continuation glyph. */) | 1099 | Fwindow_old_body_pixel_height, |
| 1018 | (Lisp_Object window, Lisp_Object pixelwise) | 1100 | Swindow_old_body_pixel_height, 0, 1, 0, |
| 1101 | doc: /* Return old height of WINDOW's text area in pixels. | ||
| 1102 | WINDOW must be a live window and defaults to the selected one. | ||
| 1103 | |||
| 1104 | The return value is the pixel height of WINDOW's text area after the | ||
| 1105 | last time window change functions found WINDOW live on its frame. It | ||
| 1106 | is zero if WINDOW was created after that. */) | ||
| 1107 | (Lisp_Object window) | ||
| 1019 | { | 1108 | { |
| 1020 | return make_fixnum (window_body_width (decode_live_window (window), | 1109 | return (make_fixnum |
| 1021 | !NILP (pixelwise))); | 1110 | (decode_live_window (window)->old_body_pixel_height)); |
| 1022 | } | 1111 | } |
| 1023 | 1112 | ||
| 1024 | DEFUN ("window-mode-line-height", Fwindow_mode_line_height, | 1113 | DEFUN ("window-mode-line-height", Fwindow_mode_line_height, |
| @@ -3264,7 +3353,7 @@ window-start value is reasonable when this function is called. */) | |||
| 3264 | adjust_frame_glyphs (f); | 3353 | adjust_frame_glyphs (f); |
| 3265 | unblock_input (); | 3354 | unblock_input (); |
| 3266 | 3355 | ||
| 3267 | run_window_configuration_change_hook (f); | 3356 | FRAME_WINDOW_CHANGE (f) = true; |
| 3268 | 3357 | ||
| 3269 | return Qnil; | 3358 | return Qnil; |
| 3270 | } | 3359 | } |
| @@ -3318,6 +3407,15 @@ select_frame_norecord (Lisp_Object frame) | |||
| 3318 | Fselect_frame (frame, Qt); | 3407 | Fselect_frame (frame, Qt); |
| 3319 | } | 3408 | } |
| 3320 | 3409 | ||
| 3410 | /** | ||
| 3411 | * run_window_configuration_change_hook: | ||
| 3412 | * | ||
| 3413 | * Run any functions on 'window-configuration-change-hook' for the | ||
| 3414 | * frame specified by F. The buffer-local values are run with the | ||
| 3415 | * window showing the buffer selected. The default value is run with | ||
| 3416 | * the frame specified by F selected. All functions are called with | ||
| 3417 | * the selected window's buffer current. | ||
| 3418 | */ | ||
| 3321 | static void | 3419 | static void |
| 3322 | run_window_configuration_change_hook (struct frame *f) | 3420 | run_window_configuration_change_hook (struct frame *f) |
| 3323 | { | 3421 | { |
| @@ -3371,7 +3469,10 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3371 | DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook, | 3469 | DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook, |
| 3372 | Srun_window_configuration_change_hook, 0, 1, 0, | 3470 | Srun_window_configuration_change_hook, 0, 1, 0, |
| 3373 | doc: /* Run `window-configuration-change-hook' for FRAME. | 3471 | doc: /* Run `window-configuration-change-hook' for FRAME. |
| 3374 | If FRAME is omitted or nil, it defaults to the selected frame. */) | 3472 | If FRAME is omitted or nil, it defaults to the selected frame. |
| 3473 | |||
| 3474 | This function should not be needed any more and will be therefore | ||
| 3475 | considered obsolete. */) | ||
| 3375 | (Lisp_Object frame) | 3476 | (Lisp_Object frame) |
| 3376 | { | 3477 | { |
| 3377 | run_window_configuration_change_hook (decode_live_frame (frame)); | 3478 | run_window_configuration_change_hook (decode_live_frame (frame)); |
| @@ -3381,130 +3482,381 @@ If FRAME is omitted or nil, it defaults to the selected frame. */) | |||
| 3381 | DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions, | 3482 | DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions, |
| 3382 | Srun_window_scroll_functions, 0, 1, 0, | 3483 | Srun_window_scroll_functions, 0, 1, 0, |
| 3383 | doc: /* Run `window-scroll-functions' for WINDOW. | 3484 | doc: /* Run `window-scroll-functions' for WINDOW. |
| 3384 | If WINDOW is omitted or nil, it defaults to the selected window. */) | 3485 | If WINDOW is omitted or nil, it defaults to the selected window. |
| 3486 | |||
| 3487 | This function is curently only called by 'split-window' for the new | ||
| 3488 | window after it has established the size of the new window. */) | ||
| 3385 | (Lisp_Object window) | 3489 | (Lisp_Object window) |
| 3386 | { | 3490 | { |
| 3387 | if (! NILP (Vwindow_scroll_functions)) | 3491 | struct window *w = decode_live_window (window); |
| 3492 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 3493 | |||
| 3494 | record_unwind_current_buffer (); | ||
| 3495 | Fset_buffer (w->contents); | ||
| 3496 | if (!NILP (Vwindow_scroll_functions)) | ||
| 3388 | run_hook_with_args_2 (Qwindow_scroll_functions, window, | 3497 | run_hook_with_args_2 (Qwindow_scroll_functions, window, |
| 3389 | Fmarker_position (decode_live_window (window)->start)); | 3498 | Fmarker_position (w->start)); |
| 3499 | unbind_to (count, Qnil); | ||
| 3500 | |||
| 3390 | return Qnil; | 3501 | return Qnil; |
| 3391 | } | 3502 | } |
| 3392 | 3503 | ||
| 3393 | 3504 | ||
| 3394 | /* Compare old and present pixel sizes of windows in tree rooted at W. | 3505 | /** |
| 3395 | Return true iff any of these windows differs in size. */ | 3506 | * window_sub_list: |
| 3396 | 3507 | * | |
| 3397 | static bool | 3508 | * Return list of live windows constructed by traversing any window |
| 3398 | window_size_changed (struct window *w) | 3509 | * sub-tree rooted at WINDOW in preorder followed by right siblings of |
| 3510 | * WINDOW. Called from outside with second argument WINDOWS nil. The | ||
| 3511 | * returned list is in reverse order. | ||
| 3512 | */ | ||
| 3513 | static Lisp_Object | ||
| 3514 | window_sub_list (Lisp_Object window, Lisp_Object windows) | ||
| 3399 | { | 3515 | { |
| 3400 | if (w->pixel_width != w->pixel_width_before_size_change | ||
| 3401 | || w->pixel_height != w->pixel_height_before_size_change) | ||
| 3402 | return true; | ||
| 3403 | 3516 | ||
| 3404 | if (WINDOW_INTERNAL_P (w)) | 3517 | struct window *w = XWINDOW (window); |
| 3518 | |||
| 3519 | while (w) | ||
| 3405 | { | 3520 | { |
| 3406 | w = XWINDOW (w->contents); | 3521 | if (WINDOW_INTERNAL_P (w)) |
| 3407 | while (w) | 3522 | windows = window_sub_list (w->contents, windows); |
| 3408 | { | 3523 | else |
| 3409 | if (window_size_changed (w)) | 3524 | windows = Fcons (window, windows); |
| 3410 | return true; | ||
| 3411 | 3525 | ||
| 3412 | w = NILP (w->next) ? 0 : XWINDOW (w->next); | 3526 | window = w->next; |
| 3413 | } | 3527 | w = NILP (window) ? 0 : XWINDOW (window); |
| 3414 | } | 3528 | } |
| 3415 | 3529 | ||
| 3416 | return false; | 3530 | return windows; |
| 3417 | } | 3531 | } |
| 3418 | 3532 | ||
| 3419 | /* Set before size change pixel sizes of windows in tree rooted at W to | ||
| 3420 | their present pixel sizes. */ | ||
| 3421 | 3533 | ||
| 3422 | static void | 3534 | /** |
| 3423 | window_set_before_size_change_sizes (struct window *w) | 3535 | * window_change_record_windows: |
| 3536 | * | ||
| 3537 | * Record changes for all live windows found by traversing any window | ||
| 3538 | * sub-tree rooted at WINDOW in preorder followed by any right | ||
| 3539 | * siblings of WINDOW. This sets the old buffer, old pixel and old | ||
| 3540 | * body pixel sizes of each live window found to the respective | ||
| 3541 | * current values. It also sets the change stamp of each window found | ||
| 3542 | * to STAMP. Return the number of live windows found. | ||
| 3543 | * | ||
| 3544 | * When not called by itself recursively, WINDOW is its frame's root | ||
| 3545 | * window, STAMP is the current change stamp of WINDOW's frame and | ||
| 3546 | * NUMBER is 0. | ||
| 3547 | */ | ||
| 3548 | static ptrdiff_t | ||
| 3549 | window_change_record_windows (Lisp_Object window, int stamp, ptrdiff_t number) | ||
| 3424 | { | 3550 | { |
| 3425 | w->pixel_width_before_size_change = w->pixel_width; | 3551 | struct window *w = XWINDOW (window); |
| 3426 | w->pixel_height_before_size_change = w->pixel_height; | ||
| 3427 | 3552 | ||
| 3428 | if (WINDOW_INTERNAL_P (w)) | 3553 | while (w) |
| 3429 | { | 3554 | { |
| 3430 | w = XWINDOW (w->contents); | 3555 | if (WINDOW_INTERNAL_P (w)) |
| 3431 | while (w) | 3556 | number = window_change_record_windows (w->contents, stamp, number); |
| 3557 | else | ||
| 3432 | { | 3558 | { |
| 3433 | window_set_before_size_change_sizes (w); | 3559 | number += 1; |
| 3434 | w = NILP (w->next) ? 0 : XWINDOW (w->next); | 3560 | w->change_stamp = stamp; |
| 3561 | wset_old_buffer (w, w->contents); | ||
| 3562 | w->old_pixel_width = w->pixel_width; | ||
| 3563 | w->old_pixel_height = w->pixel_height; | ||
| 3564 | w->old_body_pixel_width = window_body_width (w, true); | ||
| 3565 | w->old_body_pixel_height = window_body_height (w, true); | ||
| 3435 | } | 3566 | } |
| 3567 | |||
| 3568 | w = NILP (w->next) ? 0 : XWINDOW (w->next); | ||
| 3436 | } | 3569 | } |
| 3570 | |||
| 3571 | return number; | ||
| 3437 | } | 3572 | } |
| 3438 | 3573 | ||
| 3439 | 3574 | ||
| 3440 | void | 3575 | /** |
| 3441 | run_window_size_change_functions (Lisp_Object frame) | 3576 | * window_change_record_frame: |
| 3577 | * | ||
| 3578 | * Record changes for FRAME. This records FRAME's selected window, | ||
| 3579 | * updates FRAME's change stamp, records the states of all live | ||
| 3580 | * windows of FRAME via window_change_record_windows and resets | ||
| 3581 | * FRAME's window_change flag. | ||
| 3582 | */ | ||
| 3583 | static void | ||
| 3584 | window_change_record_frame (Lisp_Object frame) | ||
| 3442 | { | 3585 | { |
| 3443 | struct frame *f = XFRAME (frame); | 3586 | struct frame *f = XFRAME (frame); |
| 3444 | struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f)); | ||
| 3445 | 3587 | ||
| 3446 | if (NILP (Vrun_hooks) | 3588 | /* Record selected window. */ |
| 3447 | || !(f->can_x_set_window_size) | 3589 | fset_old_selected_window (f, FRAME_SELECTED_WINDOW (f)); |
| 3448 | || !(f->after_make_frame)) | ||
| 3449 | return; | ||
| 3450 | 3590 | ||
| 3451 | if (FRAME_WINDOW_CONFIGURATION_CHANGED (f) | 3591 | /* Bump up FRAME's change stamp. If this wraps, make it 1 to avoid |
| 3452 | /* Here we implicitly exclude the possibility that the height of | 3592 | that a new window (whose change stamp is always set to 0) gets |
| 3453 | FRAME and its minibuffer window both change leaving the height | 3593 | reported as "existing before". */ |
| 3454 | of FRAME's root window alone. */ | 3594 | f->change_stamp += 1; |
| 3455 | || window_size_changed (r)) | 3595 | if (f->change_stamp == 0) |
| 3456 | { | 3596 | f->change_stamp = 1; |
| 3457 | Lisp_Object globals = Fdefault_value (Qwindow_size_change_functions); | ||
| 3458 | Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); | ||
| 3459 | /* The buffers for which the local hook was already run. */ | ||
| 3460 | Lisp_Object buffers = Qnil; | ||
| 3461 | 3597 | ||
| 3462 | for (; CONSP (windows); windows = XCDR (windows)) | 3598 | /* Bump up the change stamps of all live windows on this frame so |
| 3463 | { | 3599 | the next call of this function can tell whether any of them |
| 3464 | Lisp_Object window = XCAR (windows); | 3600 | "existed before" and record state for each of these windows. */ |
| 3465 | Lisp_Object buffer = Fwindow_buffer (window); | 3601 | f->number_of_windows |
| 3466 | 3602 | = window_change_record_windows (f->root_window, f->change_stamp, 0); | |
| 3467 | /* Run a buffer-local value only once for that buffer and | ||
| 3468 | only if at least one window showing that buffer on FRAME | ||
| 3469 | actually changed its size. Note that the function is run | ||
| 3470 | with FRAME as its argument and as such oblivious to the | ||
| 3471 | window checked below. */ | ||
| 3472 | if (window_size_changed (XWINDOW (window)) | ||
| 3473 | && !NILP (Flocal_variable_p (Qwindow_size_change_functions, buffer)) | ||
| 3474 | && NILP (Fmemq (buffer, buffers))) | ||
| 3475 | { | ||
| 3476 | Lisp_Object locals | ||
| 3477 | = Fbuffer_local_value (Qwindow_size_change_functions, buffer); | ||
| 3478 | 3603 | ||
| 3479 | while (CONSP (locals)) | 3604 | /* Reset our flag. */ |
| 3480 | { | 3605 | FRAME_WINDOW_CHANGE (f) = false; |
| 3481 | if (!EQ (XCAR (locals), Qt)) | 3606 | } |
| 3482 | safe_call1 (XCAR (locals), frame); | ||
| 3483 | locals = XCDR (locals); | ||
| 3484 | } | ||
| 3485 | 3607 | ||
| 3486 | buffers = Fcons (buffer, buffers); | ||
| 3487 | } | ||
| 3488 | } | ||
| 3489 | 3608 | ||
| 3490 | while (CONSP (globals)) | 3609 | /** |
| 3610 | * window_change_record: | ||
| 3611 | * | ||
| 3612 | * Record selected window in old_selected_window and selected frame in | ||
| 3613 | * old_selected_frame. | ||
| 3614 | */ | ||
| 3615 | static void | ||
| 3616 | window_change_record (void) | ||
| 3617 | { | ||
| 3618 | /* Strictly spoken we don't need old_selected_window at all - its | ||
| 3619 | value is the old selected window of old_selected_frame. */ | ||
| 3620 | old_selected_window = selected_window; | ||
| 3621 | old_selected_frame = selected_frame; | ||
| 3622 | } | ||
| 3623 | |||
| 3624 | |||
| 3625 | /** | ||
| 3626 | * run_window_change_functions_1: | ||
| 3627 | * | ||
| 3628 | * Run window change functions specified by SYMBOL with argument | ||
| 3629 | * WINDOW_OR_FRAME. If BUFFER is nil, WINDOW_OR_FRAME specifies a | ||
| 3630 | * frame. In this case, run the default value of SYMBOL. Otherwise, | ||
| 3631 | * WINDOW_OR_FRAME denotes a window showing BUFFER. In this case, run | ||
| 3632 | * the buffer local value of SYMBOL in BUFFER, if any. | ||
| 3633 | */ | ||
| 3634 | static void | ||
| 3635 | run_window_change_functions_1 (Lisp_Object symbol, Lisp_Object buffer, | ||
| 3636 | Lisp_Object window_or_frame) | ||
| 3637 | { | ||
| 3638 | Lisp_Object funs = Qnil; | ||
| 3639 | |||
| 3640 | if (NILP (buffer)) | ||
| 3641 | funs = Fdefault_value (symbol); | ||
| 3642 | else if (!NILP (Fassoc (symbol, BVAR (XBUFFER (buffer), local_var_alist), | ||
| 3643 | Qnil))) | ||
| 3644 | /* Don't run global value buffer-locally. */ | ||
| 3645 | funs = buffer_local_value (symbol, buffer); | ||
| 3646 | |||
| 3647 | while (CONSP (funs)) | ||
| 3648 | { | ||
| 3649 | if (!EQ (XCAR (funs), Qt)) | ||
| 3650 | safe_call1 (XCAR (funs), window_or_frame); | ||
| 3651 | funs = XCDR (funs); | ||
| 3652 | } | ||
| 3653 | } | ||
| 3654 | |||
| 3655 | |||
| 3656 | /** | ||
| 3657 | * run_window_change_functions: | ||
| 3658 | * | ||
| 3659 | * Run window change functions for each live frame. This function | ||
| 3660 | * must be called from a "safe" position in redisplay_internal. | ||
| 3661 | * | ||
| 3662 | * Do not run any functions for a frame whose window_change flag is | ||
| 3663 | * nil and where no window selection happened since the last time this | ||
| 3664 | * function was called. Also, skip any tooltip frame. | ||
| 3665 | * | ||
| 3666 | * The change functions run are, in this order: | ||
| 3667 | * | ||
| 3668 | * 'window-buffer-change-functions' which are run for a window that | ||
| 3669 | * changed its buffer or that was not shown the last time window | ||
| 3670 | * change functions were run. The default value is also run when a | ||
| 3671 | * window was deleted since the last time window change functions were | ||
| 3672 | * run. | ||
| 3673 | * | ||
| 3674 | * `window-size-change-functions' run for a window that changed its | ||
| 3675 | * body or total size, a window that changed its buffer or a window | ||
| 3676 | * that was not shown the last time window change functions were run. | ||
| 3677 | * | ||
| 3678 | * `window-selected-change-functions' run for a window that was | ||
| 3679 | * (de-)selected since the last time window change functions were run. | ||
| 3680 | * | ||
| 3681 | * A buffer-local value of these functions is run if and only if the | ||
| 3682 | * window for which the functions are run, currently shows the buffer. | ||
| 3683 | * Each call gets one argument - the window showing the buffer. This | ||
| 3684 | * means that the buffer-local value of these functions may be called | ||
| 3685 | * as many times at the buffer is shown on the frame. | ||
| 3686 | * | ||
| 3687 | * The default value of these functions is called only after all | ||
| 3688 | * buffer-local values for all of these functions have been run. Each | ||
| 3689 | * such call receives one argument - the frame for which this function | ||
| 3690 | * is run. | ||
| 3691 | * | ||
| 3692 | * After the three change functions cited above have been run in the | ||
| 3693 | * indicated way, functions on 'window-configuration-change-hook' are | ||
| 3694 | * run. A buffer-local value is run if a window shows that buffer and | ||
| 3695 | * has either changed its buffer or its body or total size or did not | ||
| 3696 | * appear on this frame since the last time window change functions | ||
| 3697 | * were run. The functions are called without argument and the | ||
| 3698 | * buffer's window selected. The default value is run without | ||
| 3699 | * argument and the frame for which the function is run selected. | ||
| 3700 | * | ||
| 3701 | * This function does not save and restore match data. Any functions | ||
| 3702 | * it calls are responsible for doing that themselves. | ||
| 3703 | */ | ||
| 3704 | void | ||
| 3705 | run_window_change_functions (void) | ||
| 3706 | { | ||
| 3707 | Lisp_Object tail, frame; | ||
| 3708 | bool selected_frame_change = !EQ (selected_frame, old_selected_frame); | ||
| 3709 | ptrdiff_t count_outer = SPECPDL_INDEX (); | ||
| 3710 | |||
| 3711 | record_unwind_protect_void (window_change_record); | ||
| 3712 | |||
| 3713 | FOR_EACH_FRAME (tail, frame) | ||
| 3714 | { | ||
| 3715 | struct frame *f = XFRAME (frame); | ||
| 3716 | Lisp_Object root = FRAME_ROOT_WINDOW (f); | ||
| 3717 | bool frame_window_change = FRAME_WINDOW_CHANGE (f); | ||
| 3718 | bool window_buffer_change, window_size_change; | ||
| 3719 | bool frame_buffer_change = false, frame_size_change = false; | ||
| 3720 | bool frame_selected_change | ||
| 3721 | = (selected_frame_change | ||
| 3722 | && (EQ (frame, old_selected_frame) | ||
| 3723 | || EQ (frame, selected_frame))); | ||
| 3724 | bool frame_selected_window_change | ||
| 3725 | = !EQ (FRAME_OLD_SELECTED_WINDOW (f), FRAME_SELECTED_WINDOW (f)); | ||
| 3726 | bool window_deleted = false; | ||
| 3727 | Lisp_Object windows; | ||
| 3728 | ptrdiff_t number_of_windows; | ||
| 3729 | ptrdiff_t count_inner = SPECPDL_INDEX (); | ||
| 3730 | |||
| 3731 | if (!f->can_x_set_window_size | ||
| 3732 | || !f->after_make_frame | ||
| 3733 | || FRAME_TOOLTIP_P (f) | ||
| 3734 | || !(frame_window_change | ||
| 3735 | || frame_selected_change | ||
| 3736 | || frame_selected_window_change)) | ||
| 3737 | /* Either we cannot run hooks for this frame yet or no window | ||
| 3738 | change has been reported for this frame since the last time | ||
| 3739 | we ran window change functions on it. */ | ||
| 3740 | continue; | ||
| 3741 | |||
| 3742 | /* Analyze windows and run buffer locals hooks in pre-order. */ | ||
| 3743 | windows = Fnreverse (window_sub_list (root, Qnil)); | ||
| 3744 | number_of_windows = 0; | ||
| 3745 | |||
| 3746 | record_unwind_protect (window_change_record_frame, frame); | ||
| 3747 | |||
| 3748 | /* The following loop collects all data needed to tell whether | ||
| 3749 | the default value of a hook shall be run and runs any buffer | ||
| 3750 | local hooks right away. */ | ||
| 3751 | for (; CONSP (windows); windows = XCDR (windows)) | ||
| 3491 | { | 3752 | { |
| 3492 | if (!EQ (XCAR (globals), Qt)) | 3753 | Lisp_Object window = XCAR (windows); |
| 3493 | safe_call1 (XCAR (globals), frame); | 3754 | struct window *w = XWINDOW (window); |
| 3494 | globals = XCDR (globals); | 3755 | Lisp_Object buffer = WINDOW_BUFFER (w); |
| 3756 | |||
| 3757 | /* Count this window even if it has been deleted while | ||
| 3758 | running a hook. */ | ||
| 3759 | number_of_windows += 1; | ||
| 3760 | |||
| 3761 | if (!WINDOW_LIVE_P (window)) | ||
| 3762 | continue; | ||
| 3763 | |||
| 3764 | /* A "buffer change" means either the window's buffer | ||
| 3765 | changed or the window was not part of this frame the last | ||
| 3766 | time window change functions were run for it. */ | ||
| 3767 | window_buffer_change = | ||
| 3768 | (frame_window_change | ||
| 3769 | && (!EQ (buffer, w->old_buffer) | ||
| 3770 | || w->change_stamp != f->change_stamp)); | ||
| 3771 | /* A "size change" means either a buffer change or that the | ||
| 3772 | total or body size of the window has changed. | ||
| 3773 | |||
| 3774 | Note: A buffer change implies a size change because either | ||
| 3775 | this window didn't show the buffer before or this window | ||
| 3776 | didn't show the buffer the last time the window change | ||
| 3777 | functions were run. In either case, an application | ||
| 3778 | tracing size changes in a buffer-locally fashion might | ||
| 3779 | want to be informed about that change. */ | ||
| 3780 | window_size_change = | ||
| 3781 | (frame_window_change | ||
| 3782 | && (window_buffer_change | ||
| 3783 | || w->pixel_width != w->old_pixel_width | ||
| 3784 | || w->pixel_height != w->old_pixel_height | ||
| 3785 | || window_body_width (w, true) != w->old_body_pixel_width | ||
| 3786 | || window_body_height (w, true) != w->old_body_pixel_height)); | ||
| 3787 | |||
| 3788 | /* The following two are needed when running the default | ||
| 3789 | values for this frame below. */ | ||
| 3790 | frame_buffer_change = frame_buffer_change || window_buffer_change; | ||
| 3791 | frame_size_change = frame_size_change || window_size_change; | ||
| 3792 | |||
| 3793 | if (window_buffer_change) | ||
| 3794 | run_window_change_functions_1 | ||
| 3795 | (Qwindow_buffer_change_functions, buffer, window); | ||
| 3796 | |||
| 3797 | if (window_size_change && WINDOW_LIVE_P (window)) | ||
| 3798 | run_window_change_functions_1 | ||
| 3799 | (Qwindow_size_change_functions, buffer, window); | ||
| 3800 | |||
| 3801 | /* This window's selection has changed when it it was | ||
| 3802 | (de-)selected as its frame's or the globally selected | ||
| 3803 | window. */ | ||
| 3804 | if (((frame_selected_change | ||
| 3805 | && (EQ (window, old_selected_window) | ||
| 3806 | || EQ (window, selected_window))) | ||
| 3807 | || (frame_selected_window_change | ||
| 3808 | && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f)) | ||
| 3809 | || EQ (window, FRAME_SELECTED_WINDOW (f))))) | ||
| 3810 | && WINDOW_LIVE_P (window)) | ||
| 3811 | run_window_change_functions_1 | ||
| 3812 | (Qwindow_selection_change_functions, buffer, window); | ||
| 3495 | } | 3813 | } |
| 3496 | 3814 | ||
| 3497 | window_set_before_size_change_sizes (r); | 3815 | /* When the number of windows on a frame has decreased, at least |
| 3816 | one window of that frame was deleted. In that case, we want | ||
| 3817 | to run the default buffer and configuration change hooks. The | ||
| 3818 | default size change hook is not necessarily run in that case, | ||
| 3819 | but usually will be unless the deletion was "compensated" by | ||
| 3820 | a reduction of the frame size or an increase of a minibuffer | ||
| 3821 | window size. */ | ||
| 3822 | window_deleted = number_of_windows < f->number_of_windows; | ||
| 3823 | /* A frame changed buffers when one of its windows has changed | ||
| 3824 | its buffer or at least one window was deleted. */ | ||
| 3825 | if ((frame_buffer_change || window_deleted) && FRAME_LIVE_P (f)) | ||
| 3826 | run_window_change_functions_1 | ||
| 3827 | (Qwindow_buffer_change_functions, Qnil, frame); | ||
| 3828 | |||
| 3829 | /* A size change occurred when at least one of the frame's | ||
| 3830 | windows has changed size. */ | ||
| 3831 | if (frame_size_change && FRAME_LIVE_P (f)) | ||
| 3832 | run_window_change_functions_1 | ||
| 3833 | (Qwindow_size_change_functions, Qnil, frame); | ||
| 3834 | |||
| 3835 | /* A frame has changed its window selection when its selected | ||
| 3836 | window has changed or when it was (de-)selected. */ | ||
| 3837 | if ((frame_selected_change || frame_selected_window_change) | ||
| 3838 | && FRAME_LIVE_P (f)) | ||
| 3839 | run_window_change_functions_1 | ||
| 3840 | (Qwindow_selection_change_functions, Qnil, frame); | ||
| 3841 | |||
| 3842 | /* A frame's configuration changed when one of its windows has | ||
| 3843 | changed buffer or size or at least one window was deleted. */ | ||
| 3844 | if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f)) | ||
| 3845 | /* This will run any buffer local window configuration change | ||
| 3846 | hook as well. */ | ||
| 3847 | run_window_configuration_change_hook (f); | ||
| 3498 | 3848 | ||
| 3499 | if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) | 3849 | if (!FRAME_LIVE_P (f)) |
| 3500 | /* Record size of FRAME's minibuffer window too. */ | 3850 | continue; |
| 3501 | window_set_before_size_change_sizes | ||
| 3502 | (XWINDOW (FRAME_MINIBUF_WINDOW (f))); | ||
| 3503 | 3851 | ||
| 3504 | FRAME_WINDOW_CONFIGURATION_CHANGED (f) = false; | 3852 | /* Record changes (via window_change_record_frame) for this |
| 3853 | frame, even when an unhandled error occurred. */ | ||
| 3854 | unbind_to (count_inner, Qnil); | ||
| 3505 | } | 3855 | } |
| 3506 | } | ||
| 3507 | 3856 | ||
| 3857 | /* Record selected window and frame. */ | ||
| 3858 | unbind_to (count_outer, Qnil); | ||
| 3859 | } | ||
| 3508 | 3860 | ||
| 3509 | /* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed | 3861 | /* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed |
| 3510 | to run hooks. See make_frame for a case where it's not allowed. | 3862 | to run hooks. See make_frame for a case where it's not allowed. |
| @@ -3581,14 +3933,18 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, | |||
| 3581 | apply_window_adjustment (w); | 3933 | apply_window_adjustment (w); |
| 3582 | } | 3934 | } |
| 3583 | 3935 | ||
| 3584 | if (run_hooks_p) | 3936 | if (run_hooks_p && !NILP (Vwindow_scroll_functions)) |
| 3585 | { | 3937 | run_hook_with_args_2 (Qwindow_scroll_functions, window, |
| 3586 | if (!NILP (Vwindow_scroll_functions)) | 3938 | Fmarker_position (w->start)); |
| 3587 | run_hook_with_args_2 (Qwindow_scroll_functions, window, | 3939 | |
| 3588 | Fmarker_position (w->start)); | 3940 | /* Ensure that window change functions are run later if the buffer |
| 3589 | if (!samebuf) | 3941 | differs and the window is neither a mini nor a pseudo window. |
| 3590 | run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w))); | 3942 | |
| 3591 | } | 3943 | Note: Running window change functions for the minibuffer is noisy |
| 3944 | and was generally suppressed in the past. Is there any reason we | ||
| 3945 | should run them? */ | ||
| 3946 | if (!samebuf && !MINI_WINDOW_P (w) && !WINDOW_PSEUDO_P (w)) | ||
| 3947 | FRAME_WINDOW_CHANGE (XFRAME (w->frame)) = true; | ||
| 3592 | 3948 | ||
| 3593 | unbind_to (count, Qnil); | 3949 | unbind_to (count, Qnil); |
| 3594 | } | 3950 | } |
| @@ -3828,8 +4184,6 @@ make_window (void) | |||
| 3828 | w->phys_cursor_width = -1; | 4184 | w->phys_cursor_width = -1; |
| 3829 | #endif | 4185 | #endif |
| 3830 | w->sequence_number = ++sequence_number; | 4186 | w->sequence_number = ++sequence_number; |
| 3831 | w->pixel_width_before_size_change = 0; | ||
| 3832 | w->pixel_height_before_size_change = 0; | ||
| 3833 | w->scroll_bar_width = -1; | 4187 | w->scroll_bar_width = -1; |
| 3834 | w->scroll_bar_height = -1; | 4188 | w->scroll_bar_height = -1; |
| 3835 | w->column_number_displayed = -1; | 4189 | w->column_number_displayed = -1; |
| @@ -4095,6 +4449,9 @@ window_resize_apply (struct window *w, bool horflag) | |||
| 4095 | else | 4449 | else |
| 4096 | /* Bug#15957. */ | 4450 | /* Bug#15957. */ |
| 4097 | w->window_end_valid = false; | 4451 | w->window_end_valid = false; |
| 4452 | |||
| 4453 | if (!WINDOW_PSEUDO_P (w)) | ||
| 4454 | FRAME_WINDOW_CHANGE (WINDOW_XFRAME (w)) = true; | ||
| 4098 | } | 4455 | } |
| 4099 | 4456 | ||
| 4100 | 4457 | ||
| @@ -4559,17 +4916,11 @@ set correctly. See the code of `split-window' for how this is done. */) | |||
| 4559 | block_input (); | 4916 | block_input (); |
| 4560 | window_resize_apply (p, horflag); | 4917 | window_resize_apply (p, horflag); |
| 4561 | adjust_frame_glyphs (f); | 4918 | adjust_frame_glyphs (f); |
| 4562 | /* Set buffer of NEW to buffer of reference window. Don't run | 4919 | /* Set buffer of NEW to buffer of reference window. */ |
| 4563 | any hooks. */ | 4920 | set_window_buffer (new, r->contents, true, true); |
| 4564 | set_window_buffer (new, r->contents, false, true); | 4921 | FRAME_WINDOW_CHANGE (f) = true; |
| 4565 | unblock_input (); | 4922 | unblock_input (); |
| 4566 | 4923 | ||
| 4567 | /* Maybe we should run the scroll functions in Elisp (which already | ||
| 4568 | runs the configuration change hook). */ | ||
| 4569 | if (! NILP (Vwindow_scroll_functions)) | ||
| 4570 | run_hook_with_args_2 (Qwindow_scroll_functions, new, | ||
| 4571 | Fmarker_position (n->start)); | ||
| 4572 | /* Return NEW. */ | ||
| 4573 | return new; | 4924 | return new; |
| 4574 | } | 4925 | } |
| 4575 | 4926 | ||
| @@ -4720,6 +5071,8 @@ Signal an error when WINDOW is the only window on its frame. */) | |||
| 4720 | } | 5071 | } |
| 4721 | else | 5072 | else |
| 4722 | unblock_input (); | 5073 | unblock_input (); |
| 5074 | |||
| 5075 | FRAME_WINDOW_CHANGE (f) = true; | ||
| 4723 | } | 5076 | } |
| 4724 | else | 5077 | else |
| 4725 | /* We failed: Relink WINDOW into window tree. */ | 5078 | /* We failed: Relink WINDOW into window tree. */ |
| @@ -6310,7 +6663,6 @@ struct saved_window | |||
| 6310 | 6663 | ||
| 6311 | Lisp_Object window, buffer, start, pointm, old_pointm; | 6664 | Lisp_Object window, buffer, start, pointm, old_pointm; |
| 6312 | Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; | 6665 | Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; |
| 6313 | Lisp_Object pixel_height_before_size_change, pixel_width_before_size_change; | ||
| 6314 | Lisp_Object left_col, top_line, total_cols, total_lines; | 6666 | Lisp_Object left_col, top_line, total_cols, total_lines; |
| 6315 | Lisp_Object normal_cols, normal_lines; | 6667 | Lisp_Object normal_cols, normal_lines; |
| 6316 | Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll; | 6668 | Lisp_Object hscroll, min_hscroll, hscroll_whole, suspend_auto_hscroll; |
| @@ -6426,12 +6778,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6426 | struct window *root_window; | 6778 | struct window *root_window; |
| 6427 | struct window **leaf_windows; | 6779 | struct window **leaf_windows; |
| 6428 | ptrdiff_t i, k, n_leaf_windows; | 6780 | ptrdiff_t i, k, n_leaf_windows; |
| 6429 | /* Records whether a window has been added or removed wrt the | ||
| 6430 | original configuration. */ | ||
| 6431 | bool window_changed = false; | ||
| 6432 | /* Records whether a window has changed its buffer wrt the | ||
| 6433 | original configuration. */ | ||
| 6434 | bool buffer_changed = false; | ||
| 6435 | 6781 | ||
| 6436 | /* Don't do this within the main loop below: This may call Lisp | 6782 | /* Don't do this within the main loop below: This may call Lisp |
| 6437 | code and is thus potentially unsafe while input is blocked. */ | 6783 | code and is thus potentially unsafe while input is blocked. */ |
| @@ -6441,11 +6787,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6441 | window = p->window; | 6787 | window = p->window; |
| 6442 | w = XWINDOW (window); | 6788 | w = XWINDOW (window); |
| 6443 | 6789 | ||
| 6444 | if (NILP (w->contents)) | ||
| 6445 | /* A dead window that will be resurrected, the window | ||
| 6446 | configuration will change. */ | ||
| 6447 | window_changed = true; | ||
| 6448 | |||
| 6449 | if (BUFFERP (w->contents) | 6790 | if (BUFFERP (w->contents) |
| 6450 | && !EQ (w->contents, p->buffer) | 6791 | && !EQ (w->contents, p->buffer) |
| 6451 | && BUFFER_LIVE_P (XBUFFER (p->buffer))) | 6792 | && BUFFER_LIVE_P (XBUFFER (p->buffer))) |
| @@ -6530,10 +6871,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6530 | w->pixel_top = XFIXNAT (p->pixel_top); | 6871 | w->pixel_top = XFIXNAT (p->pixel_top); |
| 6531 | w->pixel_width = XFIXNAT (p->pixel_width); | 6872 | w->pixel_width = XFIXNAT (p->pixel_width); |
| 6532 | w->pixel_height = XFIXNAT (p->pixel_height); | 6873 | w->pixel_height = XFIXNAT (p->pixel_height); |
| 6533 | w->pixel_width_before_size_change | ||
| 6534 | = XFIXNAT (p->pixel_width_before_size_change); | ||
| 6535 | w->pixel_height_before_size_change | ||
| 6536 | = XFIXNAT (p->pixel_height_before_size_change); | ||
| 6537 | w->left_col = XFIXNAT (p->left_col); | 6874 | w->left_col = XFIXNAT (p->left_col); |
| 6538 | w->top_line = XFIXNAT (p->top_line); | 6875 | w->top_line = XFIXNAT (p->top_line); |
| 6539 | w->total_cols = XFIXNAT (p->total_cols); | 6876 | w->total_cols = XFIXNAT (p->total_cols); |
| @@ -6581,9 +6918,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6581 | if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) | 6918 | if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) |
| 6582 | /* If saved buffer is alive, install it. */ | 6919 | /* If saved buffer is alive, install it. */ |
| 6583 | { | 6920 | { |
| 6584 | if (!EQ (w->contents, p->buffer)) | ||
| 6585 | /* Record buffer configuration change. */ | ||
| 6586 | buffer_changed = true; | ||
| 6587 | wset_buffer (w, p->buffer); | 6921 | wset_buffer (w, p->buffer); |
| 6588 | w->start_at_line_beg = !NILP (p->start_at_line_beg); | 6922 | w->start_at_line_beg = !NILP (p->start_at_line_beg); |
| 6589 | set_marker_restricted (w->start, p->start, w->contents); | 6923 | set_marker_restricted (w->start, p->start, w->contents); |
| @@ -6617,8 +6951,6 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6617 | else if (!NILP (w->start)) | 6951 | else if (!NILP (w->start)) |
| 6618 | /* Leaf window has no live buffer, get one. */ | 6952 | /* Leaf window has no live buffer, get one. */ |
| 6619 | { | 6953 | { |
| 6620 | /* Record buffer configuration change. */ | ||
| 6621 | buffer_changed = true; | ||
| 6622 | /* Get the buffer via other_buffer_safely in order to | 6954 | /* Get the buffer via other_buffer_safely in order to |
| 6623 | avoid showing an unimportant buffer and, if necessary, to | 6955 | avoid showing an unimportant buffer and, if necessary, to |
| 6624 | recreate *scratch* in the course (part of Juanma's bs-show | 6956 | recreate *scratch* in the course (part of Juanma's bs-show |
| @@ -6666,10 +6998,7 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6666 | /* Now, free glyph matrices in windows that were not reused. */ | 6998 | /* Now, free glyph matrices in windows that were not reused. */ |
| 6667 | for (i = 0; i < n_leaf_windows; i++) | 6999 | for (i = 0; i < n_leaf_windows; i++) |
| 6668 | if (NILP (leaf_windows[i]->contents)) | 7000 | if (NILP (leaf_windows[i]->contents)) |
| 6669 | { | 7001 | free_window_matrices (leaf_windows[i]); |
| 6670 | free_window_matrices (leaf_windows[i]); | ||
| 6671 | window_changed = true; | ||
| 6672 | } | ||
| 6673 | 7002 | ||
| 6674 | /* Allow x_set_window_size again and apply frame size changes if | 7003 | /* Allow x_set_window_size again and apply frame size changes if |
| 6675 | needed. */ | 7004 | needed. */ |
| @@ -6699,35 +7028,10 @@ the return value is nil. Otherwise the value is t. */) | |||
| 6699 | selected window. */ | 7028 | selected window. */ |
| 6700 | if (FRAME_LIVE_P (XFRAME (data->selected_frame))) | 7029 | if (FRAME_LIVE_P (XFRAME (data->selected_frame))) |
| 6701 | do_switch_frame (data->selected_frame, 0, 0, Qnil); | 7030 | do_switch_frame (data->selected_frame, 0, 0, Qnil); |
| 6702 | |||
| 6703 | if (window_changed) | ||
| 6704 | /* At least one window has been added or removed. Run | ||
| 6705 | `window-configuration-change-hook' and make sure | ||
| 6706 | `window-size-change-functions' get run later. | ||
| 6707 | |||
| 6708 | We have to do this in order to capture the following | ||
| 6709 | scenario: Suppose our frame contains two live windows W1 and | ||
| 6710 | W2 and 'set-window-configuration' replaces them by two | ||
| 6711 | windows W3 and W4 that were dead the last time | ||
| 6712 | run_window_size_change_functions was run. If W3 and W4 have | ||
| 6713 | the same values for their old and new pixel sizes but these | ||
| 6714 | values differ from those of W1 and W2, the sizes of our | ||
| 6715 | frame's two live windows changed but window_size_changed has | ||
| 6716 | no means to detect that fact. | ||
| 6717 | |||
| 6718 | Obviously, this will get us false positives, for example, | ||
| 6719 | when we restore the original configuration with W1 and W2 | ||
| 6720 | before run_window_size_change_functions gets called. */ | ||
| 6721 | { | ||
| 6722 | run_window_configuration_change_hook (f); | ||
| 6723 | FRAME_WINDOW_CONFIGURATION_CHANGED (f) = true; | ||
| 6724 | } | ||
| 6725 | else if (buffer_changed) | ||
| 6726 | /* At least one window has changed its buffer. Run | ||
| 6727 | `window-configuration-change-hook' only. */ | ||
| 6728 | run_window_configuration_change_hook (f); | ||
| 6729 | } | 7031 | } |
| 6730 | 7032 | ||
| 7033 | FRAME_WINDOW_CHANGE (f) = true; | ||
| 7034 | |||
| 6731 | if (!NILP (new_current_buffer)) | 7035 | if (!NILP (new_current_buffer)) |
| 6732 | { | 7036 | { |
| 6733 | Fset_buffer (new_current_buffer); | 7037 | Fset_buffer (new_current_buffer); |
| @@ -6889,10 +7193,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i) | |||
| 6889 | p->pixel_top = make_fixnum (w->pixel_top); | 7193 | p->pixel_top = make_fixnum (w->pixel_top); |
| 6890 | p->pixel_width = make_fixnum (w->pixel_width); | 7194 | p->pixel_width = make_fixnum (w->pixel_width); |
| 6891 | p->pixel_height = make_fixnum (w->pixel_height); | 7195 | p->pixel_height = make_fixnum (w->pixel_height); |
| 6892 | p->pixel_width_before_size_change | ||
| 6893 | = make_fixnum (w->pixel_width_before_size_change); | ||
| 6894 | p->pixel_height_before_size_change | ||
| 6895 | = make_fixnum (w->pixel_height_before_size_change); | ||
| 6896 | p->left_col = make_fixnum (w->left_col); | 7196 | p->left_col = make_fixnum (w->left_col); |
| 6897 | p->top_line = make_fixnum (w->top_line); | 7197 | p->top_line = make_fixnum (w->top_line); |
| 6898 | p->total_cols = make_fixnum (w->total_cols); | 7198 | p->total_cols = make_fixnum (w->total_cols); |
| @@ -7581,9 +7881,9 @@ init_window_once (void) | |||
| 7581 | { | 7881 | { |
| 7582 | struct frame *f = make_initial_frame (); | 7882 | struct frame *f = make_initial_frame (); |
| 7583 | XSETFRAME (selected_frame, f); | 7883 | XSETFRAME (selected_frame, f); |
| 7584 | Vterminal_frame = selected_frame; | 7884 | old_selected_frame = Vterminal_frame = selected_frame; |
| 7585 | minibuf_window = f->minibuffer_window; | 7885 | minibuf_window = f->minibuffer_window; |
| 7586 | selected_window = f->selected_window; | 7886 | old_selected_window = selected_window = f->selected_window; |
| 7587 | } | 7887 | } |
| 7588 | 7888 | ||
| 7589 | void | 7889 | void |
| @@ -7604,6 +7904,8 @@ syms_of_window (void) | |||
| 7604 | 7904 | ||
| 7605 | DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook"); | 7905 | DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook"); |
| 7606 | DEFSYM (Qwindow_size_change_functions, "window-size-change-functions"); | 7906 | DEFSYM (Qwindow_size_change_functions, "window-size-change-functions"); |
| 7907 | DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions"); | ||
| 7908 | DEFSYM (Qwindow_selection_change_functions, "window-selection-change-functions"); | ||
| 7607 | DEFSYM (Qwindowp, "windowp"); | 7909 | DEFSYM (Qwindowp, "windowp"); |
| 7608 | DEFSYM (Qwindow_configuration_p, "window-configuration-p"); | 7910 | DEFSYM (Qwindow_configuration_p, "window-configuration-p"); |
| 7609 | DEFSYM (Qwindow_live_p, "window-live-p"); | 7911 | DEFSYM (Qwindow_live_p, "window-live-p"); |
| @@ -7688,24 +7990,66 @@ on their symbols to be controlled by this variable. */); | |||
| 7688 | Vwindow_point_insertion_type = Qnil; | 7990 | Vwindow_point_insertion_type = Qnil; |
| 7689 | DEFSYM (Qwindow_point_insertion_type, "window-point-insertion-type"); | 7991 | DEFSYM (Qwindow_point_insertion_type, "window-point-insertion-type"); |
| 7690 | 7992 | ||
| 7691 | DEFVAR_LISP ("window-configuration-change-hook", | 7993 | DEFVAR_LISP ("window-buffer-change-functions", Vwindow_buffer_change_functions, |
| 7692 | Vwindow_configuration_change_hook, | 7994 | doc: /* Functions called during redisplay when window buffers have changed. |
| 7693 | doc: /* Functions to call when window configuration changes. | 7995 | The value should be a list of functions that take one argument. |
| 7694 | The buffer-local value is run once per window, with the relevant window | 7996 | |
| 7695 | selected; while the global value is run only once for the modified frame, | 7997 | Functions specified buffer-locally are called for each window showing |
| 7696 | with the relevant frame selected. */); | 7998 | the corresponding buffer if and only if that window has been added or |
| 7697 | Vwindow_configuration_change_hook = Qnil; | 7999 | changed its buffer since the last redisplay. In this case the window |
| 8000 | is passed as argument. | ||
| 8001 | |||
| 8002 | Functions specified by the default value are called for each frame if | ||
| 8003 | at least one window on that frame has been added, deleted or changed | ||
| 8004 | its buffer since the last redisplay. In this case the frame is passed | ||
| 8005 | as argument. */); | ||
| 8006 | Vwindow_buffer_change_functions = Qnil; | ||
| 7698 | 8007 | ||
| 7699 | DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions, | 8008 | DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions, |
| 7700 | doc: /* Functions called during redisplay, if window sizes have changed. | 8009 | doc: /* Functions called during redisplay when window sizes have changed. |
| 7701 | The value should be a list of functions that take one argument. | 8010 | The value should be a list of functions that take one argument. |
| 7702 | During the first part of redisplay, for each frame, if any of its windows | 8011 | |
| 7703 | have changed size since the last redisplay, or have been split or deleted, | 8012 | Functions specified buffer-locally are called for each window showing |
| 7704 | all the functions in the list are called, with the frame as argument. | 8013 | the corresponding buffer if and only if that window has been added or |
| 7705 | If redisplay decides to resize the minibuffer window, it calls these | 8014 | changed its buffer or its total or body size since the last redisplay. |
| 7706 | functions on behalf of that as well. */); | 8015 | In this case the window is passed as argument. |
| 8016 | |||
| 8017 | Functions specified by the default value are called for each frame if | ||
| 8018 | at least one window on that frame has been added or changed its buffer | ||
| 8019 | or its total or body size since the last redisplay. In this case the | ||
| 8020 | frame is passed as argument. */); | ||
| 7707 | Vwindow_size_change_functions = Qnil; | 8021 | Vwindow_size_change_functions = Qnil; |
| 7708 | 8022 | ||
| 8023 | DEFVAR_LISP ("window-selection-change-functions", Vwindow_selection_change_functions, | ||
| 8024 | doc: /* Functions called during redisplay when the selected window has changed. | ||
| 8025 | The value should be a list of functions that take one argument. | ||
| 8026 | |||
| 8027 | Functions specified buffer-locally are called for each window showing | ||
| 8028 | the corresponding buffer if and only if that window has been selected | ||
| 8029 | or deselected since the last redisplay. In this case the window is | ||
| 8030 | passed as argument. | ||
| 8031 | |||
| 8032 | Functions specified by the default value are called for each frame if | ||
| 8033 | the frame's selected window has changed since the last redisplay. In | ||
| 8034 | this case the frame is passed as argument. */); | ||
| 8035 | Vwindow_selection_change_functions = Qnil; | ||
| 8036 | |||
| 8037 | DEFVAR_LISP ("window-configuration-change-hook", Vwindow_configuration_change_hook, | ||
| 8038 | doc: /* Functions called during redisplay when window configuration has changed. | ||
| 8039 | The value should be a list of functions that take no argument. | ||
| 8040 | |||
| 8041 | Functions specified buffer-locally are called for each window showing | ||
| 8042 | the corresponding buffer if at least one window on that frame has been | ||
| 8043 | added, deleted or changed its buffer or its total or body size since | ||
| 8044 | the last redisplay. Each call is performed with the window showing | ||
| 8045 | the buffer temporarily selected. | ||
| 8046 | |||
| 8047 | Functions specified by the default value are called for each frame if | ||
| 8048 | at least one window on that frame has been added, deleted or changed | ||
| 8049 | its buffer or its total or body size since the last redisplay. Each | ||
| 8050 | call is performed with the frame temporarily selected. */); | ||
| 8051 | Vwindow_configuration_change_hook = Qnil; | ||
| 8052 | |||
| 7709 | DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay, | 8053 | DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay, |
| 7710 | doc: /* Non-nil means `recenter' redraws entire frame. | 8054 | doc: /* Non-nil means `recenter' redraws entire frame. |
| 7711 | If this option is non-nil, then the `recenter' command with a nil | 8055 | If this option is non-nil, then the `recenter' command with a nil |
| @@ -7817,6 +8161,7 @@ displayed after a scrolling operation to be somewhat inaccurate. */); | |||
| 7817 | Vfast_but_imprecise_scrolling = false; | 8161 | Vfast_but_imprecise_scrolling = false; |
| 7818 | 8162 | ||
| 7819 | defsubr (&Sselected_window); | 8163 | defsubr (&Sselected_window); |
| 8164 | defsubr (&Sold_selected_window); | ||
| 7820 | defsubr (&Sminibuffer_window); | 8165 | defsubr (&Sminibuffer_window); |
| 7821 | defsubr (&Swindow_minibuffer_p); | 8166 | defsubr (&Swindow_minibuffer_p); |
| 7822 | defsubr (&Swindowp); | 8167 | defsubr (&Swindowp); |
| @@ -7826,10 +8171,12 @@ displayed after a scrolling operation to be somewhat inaccurate. */); | |||
| 7826 | defsubr (&Sframe_root_window); | 8171 | defsubr (&Sframe_root_window); |
| 7827 | defsubr (&Sframe_first_window); | 8172 | defsubr (&Sframe_first_window); |
| 7828 | defsubr (&Sframe_selected_window); | 8173 | defsubr (&Sframe_selected_window); |
| 8174 | defsubr (&Sframe_old_selected_window); | ||
| 7829 | defsubr (&Sset_frame_selected_window); | 8175 | defsubr (&Sset_frame_selected_window); |
| 7830 | defsubr (&Spos_visible_in_window_p); | 8176 | defsubr (&Spos_visible_in_window_p); |
| 7831 | defsubr (&Swindow_line_height); | 8177 | defsubr (&Swindow_line_height); |
| 7832 | defsubr (&Swindow_buffer); | 8178 | defsubr (&Swindow_buffer); |
| 8179 | defsubr (&Swindow_old_buffer); | ||
| 7833 | defsubr (&Swindow_parent); | 8180 | defsubr (&Swindow_parent); |
| 7834 | defsubr (&Swindow_top_child); | 8181 | defsubr (&Swindow_top_child); |
| 7835 | defsubr (&Swindow_left_child); | 8182 | defsubr (&Swindow_left_child); |
| @@ -7840,8 +8187,10 @@ displayed after a scrolling operation to be somewhat inaccurate. */); | |||
| 7840 | defsubr (&Swindow_use_time); | 8187 | defsubr (&Swindow_use_time); |
| 7841 | defsubr (&Swindow_pixel_width); | 8188 | defsubr (&Swindow_pixel_width); |
| 7842 | defsubr (&Swindow_pixel_height); | 8189 | defsubr (&Swindow_pixel_height); |
| 7843 | defsubr (&Swindow_pixel_width_before_size_change); | 8190 | defsubr (&Swindow_old_pixel_width); |
| 7844 | defsubr (&Swindow_pixel_height_before_size_change); | 8191 | defsubr (&Swindow_old_pixel_height); |
| 8192 | defsubr (&Swindow_old_body_pixel_width); | ||
| 8193 | defsubr (&Swindow_old_body_pixel_height); | ||
| 7845 | defsubr (&Swindow_total_width); | 8194 | defsubr (&Swindow_total_width); |
| 7846 | defsubr (&Swindow_total_height); | 8195 | defsubr (&Swindow_total_height); |
| 7847 | defsubr (&Swindow_normal_size); | 8196 | defsubr (&Swindow_normal_size); |
diff --git a/src/window.h b/src/window.h index ee6ec3bb19a..9c4aea85ea6 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -142,6 +142,11 @@ struct window | |||
| 142 | as well. */ | 142 | as well. */ |
| 143 | Lisp_Object contents; | 143 | Lisp_Object contents; |
| 144 | 144 | ||
| 145 | /* The old buffer of this window, set to this window's buffer by | ||
| 146 | run_window_change_functions every time it sees this window. | ||
| 147 | Unused for internal windows. */ | ||
| 148 | Lisp_Object old_buffer; | ||
| 149 | |||
| 145 | /* A marker pointing to where in the text to start displaying. | 150 | /* A marker pointing to where in the text to start displaying. |
| 146 | BIDI Note: This is the _logical-order_ start, i.e. the smallest | 151 | BIDI Note: This is the _logical-order_ start, i.e. the smallest |
| 147 | buffer position visible in the window, not necessarily the | 152 | buffer position visible in the window, not necessarily the |
| @@ -229,6 +234,14 @@ struct window | |||
| 229 | /* Unique number of window assigned when it was created. */ | 234 | /* Unique number of window assigned when it was created. */ |
| 230 | EMACS_INT sequence_number; | 235 | EMACS_INT sequence_number; |
| 231 | 236 | ||
| 237 | /* The change stamp of this window. Set to 0 when the window is | ||
| 238 | created, it is set to its frame's change stamp every time | ||
| 239 | run_window_change_functions is run on that frame with this | ||
| 240 | window live. It is left alone when the window exists only | ||
| 241 | within a window configuration. Not useful for internal | ||
| 242 | windows. */ | ||
| 243 | int change_stamp; | ||
| 244 | |||
| 232 | /* The upper left corner pixel coordinates of this window, as | 245 | /* The upper left corner pixel coordinates of this window, as |
| 233 | integers relative to upper left corner of frame = 0, 0. */ | 246 | integers relative to upper left corner of frame = 0, 0. */ |
| 234 | int pixel_left; | 247 | int pixel_left; |
| @@ -243,10 +256,13 @@ struct window | |||
| 243 | int pixel_width; | 256 | int pixel_width; |
| 244 | int pixel_height; | 257 | int pixel_height; |
| 245 | 258 | ||
| 246 | /* The pixel sizes of the window at the last time | 259 | /* The pixel and pixel body sizes of the window at the last time |
| 247 | `window-size-change-functions' was run. */ | 260 | run_window_change_functions was run with this window live. Not |
| 248 | int pixel_width_before_size_change; | 261 | useful for internal windows. */ |
| 249 | int pixel_height_before_size_change; | 262 | int old_pixel_width; |
| 263 | int old_pixel_height; | ||
| 264 | int old_body_pixel_width; | ||
| 265 | int old_body_pixel_height; | ||
| 250 | 266 | ||
| 251 | /* The size of the window. */ | 267 | /* The size of the window. */ |
| 252 | int total_cols; | 268 | int total_cols; |
| @@ -1023,6 +1039,7 @@ wset_next_buffers (struct window *w, Lisp_Object val) | |||
| 1023 | This value is always the same as FRAME_SELECTED_WINDOW (selected_frame). */ | 1039 | This value is always the same as FRAME_SELECTED_WINDOW (selected_frame). */ |
| 1024 | 1040 | ||
| 1025 | extern Lisp_Object selected_window; | 1041 | extern Lisp_Object selected_window; |
| 1042 | extern Lisp_Object old_selected_window; | ||
| 1026 | 1043 | ||
| 1027 | /* This is a time stamp for window selection, so we can find the least | 1044 | /* This is a time stamp for window selection, so we can find the least |
| 1028 | recently used window. Its only users are Fselect_window, | 1045 | recently used window. Its only users are Fselect_window, |
| @@ -1051,7 +1068,7 @@ extern void grow_mini_window (struct window *, int, bool); | |||
| 1051 | extern void shrink_mini_window (struct window *, bool); | 1068 | extern void shrink_mini_window (struct window *, bool); |
| 1052 | extern int window_relative_x_coord (struct window *, enum window_part, int); | 1069 | extern int window_relative_x_coord (struct window *, enum window_part, int); |
| 1053 | 1070 | ||
| 1054 | void run_window_size_change_functions (Lisp_Object); | 1071 | void run_window_change_functions (void); |
| 1055 | 1072 | ||
| 1056 | /* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed | 1073 | /* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed |
| 1057 | to run hooks. See make_frame for a case where it's not allowed. */ | 1074 | to run hooks. See make_frame for a case where it's not allowed. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 7725570ced3..86495078fb6 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2786,6 +2786,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2786 | struct glyph_row *row, enum face_id base_face_id) | 2786 | struct glyph_row *row, enum face_id base_face_id) |
| 2787 | { | 2787 | { |
| 2788 | enum face_id remapped_base_face_id = base_face_id; | 2788 | enum face_id remapped_base_face_id = base_face_id; |
| 2789 | int body_width = 0, body_height = 0; | ||
| 2789 | 2790 | ||
| 2790 | /* Some precondition checks. */ | 2791 | /* Some precondition checks. */ |
| 2791 | eassert (w != NULL && it != NULL); | 2792 | eassert (w != NULL && it != NULL); |
| @@ -2962,7 +2963,7 @@ init_iterator (struct it *it, struct window *w, | |||
| 2962 | { | 2963 | { |
| 2963 | /* Mode lines, menu bar in terminal frames. */ | 2964 | /* Mode lines, menu bar in terminal frames. */ |
| 2964 | it->first_visible_x = 0; | 2965 | it->first_visible_x = 0; |
| 2965 | it->last_visible_x = WINDOW_PIXEL_WIDTH (w); | 2966 | it->last_visible_x = body_width = WINDOW_PIXEL_WIDTH (w); |
| 2966 | } | 2967 | } |
| 2967 | else | 2968 | else |
| 2968 | { | 2969 | { |
| @@ -2982,8 +2983,12 @@ init_iterator (struct it *it, struct window *w, | |||
| 2982 | else | 2983 | else |
| 2983 | it->first_visible_x = | 2984 | it->first_visible_x = |
| 2984 | window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f); | 2985 | window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f); |
| 2985 | it->last_visible_x = (it->first_visible_x | 2986 | |
| 2986 | + window_box_width (w, TEXT_AREA)); | 2987 | body_width = window_box_width (w, TEXT_AREA); |
| 2988 | if (!w->pseudo_window_p && !MINI_WINDOW_P (w) | ||
| 2989 | && body_width != w->old_body_pixel_width) | ||
| 2990 | FRAME_WINDOW_CHANGE (it->f) = true; | ||
| 2991 | it->last_visible_x = it->first_visible_x + body_width; | ||
| 2987 | 2992 | ||
| 2988 | /* If we truncate lines, leave room for the truncation glyph(s) at | 2993 | /* If we truncate lines, leave room for the truncation glyph(s) at |
| 2989 | the right margin. Otherwise, leave room for the continuation | 2994 | the right margin. Otherwise, leave room for the continuation |
| @@ -2997,7 +3002,8 @@ init_iterator (struct it *it, struct window *w, | |||
| 2997 | } | 3002 | } |
| 2998 | 3003 | ||
| 2999 | it->header_line_p = window_wants_header_line (w); | 3004 | it->header_line_p = window_wants_header_line (w); |
| 3000 | it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll; | 3005 | body_height = WINDOW_HEADER_LINE_HEIGHT (w); |
| 3006 | it->current_y = body_height + w->vscroll; | ||
| 3001 | } | 3007 | } |
| 3002 | 3008 | ||
| 3003 | /* Leave room for a border glyph. */ | 3009 | /* Leave room for a border glyph. */ |
| @@ -3006,6 +3012,10 @@ init_iterator (struct it *it, struct window *w, | |||
| 3006 | it->last_visible_x -= 1; | 3012 | it->last_visible_x -= 1; |
| 3007 | 3013 | ||
| 3008 | it->last_visible_y = window_text_bottom_y (w); | 3014 | it->last_visible_y = window_text_bottom_y (w); |
| 3015 | body_height += it->last_visible_y; | ||
| 3016 | if (!w->pseudo_window_p && !MINI_WINDOW_P (w) | ||
| 3017 | && body_height != w->old_body_pixel_height) | ||
| 3018 | FRAME_WINDOW_CHANGE (it->f) = true; | ||
| 3009 | 3019 | ||
| 3010 | /* For mode lines and alike, arrange for the first glyph having a | 3020 | /* For mode lines and alike, arrange for the first glyph having a |
| 3011 | left box line if the face specifies a box. */ | 3021 | left box line if the face specifies a box. */ |
| @@ -12200,8 +12210,6 @@ prepare_menu_bars (void) | |||
| 12200 | && !XBUFFER (w->contents)->text->redisplay) | 12210 | && !XBUFFER (w->contents)->text->redisplay) |
| 12201 | continue; | 12211 | continue; |
| 12202 | 12212 | ||
| 12203 | run_window_size_change_functions (frame); | ||
| 12204 | |||
| 12205 | if (FRAME_PARENT_FRAME (f)) | 12213 | if (FRAME_PARENT_FRAME (f)) |
| 12206 | continue; | 12214 | continue; |
| 12207 | 12215 | ||
| @@ -14119,20 +14127,6 @@ redisplay_internal (void) | |||
| 14119 | { | 14127 | { |
| 14120 | echo_area_display (false); | 14128 | echo_area_display (false); |
| 14121 | 14129 | ||
| 14122 | /* If echo_area_display resizes the mini-window, the redisplay and | ||
| 14123 | window_sizes_changed flags of the selected frame are set, but | ||
| 14124 | it's too late for the hooks in window-size-change-functions, | ||
| 14125 | which have been examined already in prepare_menu_bars. So in | ||
| 14126 | that case we call the hooks here only for the selected frame. */ | ||
| 14127 | if (sf->redisplay) | ||
| 14128 | { | ||
| 14129 | ptrdiff_t count1 = SPECPDL_INDEX (); | ||
| 14130 | |||
| 14131 | record_unwind_save_match_data (); | ||
| 14132 | run_window_size_change_functions (selected_frame); | ||
| 14133 | unbind_to (count1, Qnil); | ||
| 14134 | } | ||
| 14135 | |||
| 14136 | if (message_cleared_p) | 14130 | if (message_cleared_p) |
| 14137 | update_miniwindow_p = true; | 14131 | update_miniwindow_p = true; |
| 14138 | 14132 | ||
| @@ -14149,15 +14143,6 @@ redisplay_internal (void) | |||
| 14149 | && (current_buffer->clip_changed || window_outdated (w)) | 14143 | && (current_buffer->clip_changed || window_outdated (w)) |
| 14150 | && resize_mini_window (w, false)) | 14144 | && resize_mini_window (w, false)) |
| 14151 | { | 14145 | { |
| 14152 | if (sf->redisplay) | ||
| 14153 | { | ||
| 14154 | ptrdiff_t count1 = SPECPDL_INDEX (); | ||
| 14155 | |||
| 14156 | record_unwind_save_match_data (); | ||
| 14157 | run_window_size_change_functions (selected_frame); | ||
| 14158 | unbind_to (count1, Qnil); | ||
| 14159 | } | ||
| 14160 | |||
| 14161 | /* Resized active mini-window to fit the size of what it is | 14146 | /* Resized active mini-window to fit the size of what it is |
| 14162 | showing if its contents might have changed. */ | 14147 | showing if its contents might have changed. */ |
| 14163 | must_finish = true; | 14148 | must_finish = true; |
| @@ -14347,7 +14332,19 @@ redisplay_internal (void) | |||
| 14347 | && (w = XWINDOW (selected_window)) != sw) | 14332 | && (w = XWINDOW (selected_window)) != sw) |
| 14348 | goto retry; | 14333 | goto retry; |
| 14349 | 14334 | ||
| 14350 | /* We used to always goto end_of_redisplay here, but this | 14335 | if (!NILP (Vrun_hooks)) |
| 14336 | { | ||
| 14337 | run_window_change_functions (); | ||
| 14338 | |||
| 14339 | /* If windows or buffers changed or selected_window | ||
| 14340 | changed, redisplay again. */ | ||
| 14341 | if ((windows_or_buffers_changed) | ||
| 14342 | || (WINDOWP (selected_window) | ||
| 14343 | && (w = XWINDOW (selected_window)) != sw)) | ||
| 14344 | goto retry; | ||
| 14345 | } | ||
| 14346 | |||
| 14347 | /* We used to always goto end_of_redisplay here, but this | ||
| 14351 | isn't enough if we have a blinking cursor. */ | 14348 | isn't enough if we have a blinking cursor. */ |
| 14352 | if (w->cursor_off_p == w->last_cursor_off_p) | 14349 | if (w->cursor_off_p == w->last_cursor_off_p) |
| 14353 | goto end_of_redisplay; | 14350 | goto end_of_redisplay; |
| @@ -14706,9 +14703,22 @@ redisplay_internal (void) | |||
| 14706 | /* If we just did a pending size change, or have additional | 14703 | /* If we just did a pending size change, or have additional |
| 14707 | visible frames, or selected_window changed, redisplay again. */ | 14704 | visible frames, or selected_window changed, redisplay again. */ |
| 14708 | if ((windows_or_buffers_changed && !pending) | 14705 | if ((windows_or_buffers_changed && !pending) |
| 14709 | || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)) | 14706 | || (WINDOWP (selected_window) |
| 14707 | && (w = XWINDOW (selected_window)) != sw)) | ||
| 14710 | goto retry; | 14708 | goto retry; |
| 14711 | 14709 | ||
| 14710 | if (!NILP (Vrun_hooks)) | ||
| 14711 | { | ||
| 14712 | run_window_change_functions (); | ||
| 14713 | |||
| 14714 | /* If windows or buffers changed or selected_window changed, | ||
| 14715 | redisplay again. */ | ||
| 14716 | if ((windows_or_buffers_changed) | ||
| 14717 | || (WINDOWP (selected_window) | ||
| 14718 | && (w = XWINDOW (selected_window)) != sw)) | ||
| 14719 | goto retry; | ||
| 14720 | } | ||
| 14721 | |||
| 14712 | /* Clear the face and image caches. | 14722 | /* Clear the face and image caches. |
| 14713 | 14723 | ||
| 14714 | We used to do this only if consider_all_windows_p. But the cache | 14724 | We used to do this only if consider_all_windows_p. But the cache |