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.
This commit is contained in:
parent
470082de55
commit
e567ac1495
11 changed files with 961 additions and 395 deletions
|
@ -568,12 +568,6 @@ its pixel height is the pixel height of the screen areas spanned by its
|
|||
children.
|
||||
@end defun
|
||||
|
||||
@defun window-pixel-height-before-size-change &optional Lisp_Object &optional window
|
||||
This function returns the height of window @var{window} in pixels at the
|
||||
time @code{window-size-change-functions} was run for the last time on
|
||||
@var{window}'s frame (@pxref{Window Hooks}).
|
||||
@end defun
|
||||
|
||||
@cindex window pixel width
|
||||
@cindex pixel width of a window
|
||||
@cindex total pixel width of a window
|
||||
|
@ -588,12 +582,6 @@ If @var{window} is an internal window, its pixel width is the width of
|
|||
the screen areas spanned by its children.
|
||||
@end defun
|
||||
|
||||
@defun window-pixel-width-before-size-change &optional Lisp_Object &optional window
|
||||
This function returns the width of window @var{window} in pixels at the
|
||||
time @code{window-size-change-functions} was run for the last time on
|
||||
@var{window}'s frame (@pxref{Window Hooks}).
|
||||
@end defun
|
||||
|
||||
@cindex full-width window
|
||||
@cindex full-height window
|
||||
The following functions can be used to determine whether a given
|
||||
|
@ -5705,10 +5693,6 @@ prevent the code in @var{forms} from opening new windows, because new
|
|||
windows might be opened in other frames (@pxref{Choosing Window}), and
|
||||
@code{save-window-excursion} only saves and restores the window
|
||||
configuration on the current frame.
|
||||
|
||||
Do not use this macro in @code{window-size-change-functions}; exiting
|
||||
the macro triggers execution of @code{window-size-change-functions},
|
||||
leading to an endless loop.
|
||||
@end defmac
|
||||
|
||||
@defun window-configuration-p object
|
||||
|
@ -5827,10 +5811,10 @@ This function sets @var{window}'s value of @var{parameter} to
|
|||
is the selected window.
|
||||
@end defun
|
||||
|
||||
By default, the functions that save and restore window configurations or the
|
||||
states of windows (@pxref{Window Configurations}) do not care about
|
||||
window parameters. This means that when you change the value of a
|
||||
parameter within the body of a @code{save-window-excursion}, the
|
||||
By default, the functions that save and restore window configurations
|
||||
or the states of windows (@pxref{Window Configurations}) do not care
|
||||
about window parameters. This means that when you change the value of
|
||||
a parameter within the body of a @code{save-window-excursion}, the
|
||||
previous value is not restored when that macro exits. It also means
|
||||
that when you restore via @code{window-state-put} a window state saved
|
||||
earlier by @code{window-state-get}, all cloned windows have their
|
||||
|
@ -6019,27 +6003,26 @@ applications. It might be replaced by an improved solution in future
|
|||
versions of Emacs.
|
||||
@end table
|
||||
|
||||
|
||||
@node Window Hooks
|
||||
@section Hooks for Window Scrolling and Changes
|
||||
@cindex hooks for window operations
|
||||
|
||||
This section describes how a Lisp program can take action whenever a
|
||||
window displays a different part of its buffer or a different buffer.
|
||||
There are three actions that can change this: scrolling the window,
|
||||
switching buffers in the window, and changing the size of the window.
|
||||
The first two actions run @code{window-scroll-functions}; the last runs
|
||||
@code{window-size-change-functions}.
|
||||
This section describes how Lisp programs can take action after a
|
||||
window has been scrolled or other window modifications occurred. We
|
||||
first consider the case where a window shows a different part of its
|
||||
buffer.
|
||||
|
||||
@defvar window-scroll-functions
|
||||
This variable holds a list of functions that Emacs should call before
|
||||
redisplaying a window with scrolling. Displaying a different buffer in
|
||||
the window also runs these functions.
|
||||
redisplaying a window with scrolling. Displaying a different buffer
|
||||
in a window and making a new window also call these functions.
|
||||
|
||||
This variable is not a normal hook, because each function is called with
|
||||
two arguments: the window, and its new display-start position. At the
|
||||
time of the call, the display-start position of the window argument is
|
||||
already set to its new value, and the buffer to be displayed in the
|
||||
window is already set as the current buffer.
|
||||
This variable is not a normal hook, because each function is called
|
||||
with two arguments: the window, and its new display-start position.
|
||||
At the time of the call, the display-start position of the argument
|
||||
window is already set to its new value, and the buffer to be displayed
|
||||
in the window is set as the current buffer.
|
||||
|
||||
These functions must take care when using @code{window-end}
|
||||
(@pxref{Window Start and End}); if you need an up-to-date value, you
|
||||
|
@ -6050,63 +6033,226 @@ is scrolled. It's not designed for that, and such use probably won't
|
|||
work.
|
||||
@end defvar
|
||||
|
||||
@defun run-window-scroll-functions &optional window
|
||||
This function calls @code{window-scroll-functions} for the specified
|
||||
@var{window}, which defaults to the selected window.
|
||||
@end defun
|
||||
|
||||
@defvar window-size-change-functions
|
||||
This variable holds a list of functions to be called if the size of any
|
||||
window changes for any reason. The functions are called once per
|
||||
redisplay, and once for each frame on which size changes have occurred.
|
||||
|
||||
Each function receives the frame as its sole argument. To find out
|
||||
whether a specific window has changed size, compare the return values of
|
||||
@code{window-pixel-width-before-size-change} and
|
||||
@code{window-pixel-width} respectively
|
||||
@code{window-pixel-height-before-size-change} and
|
||||
@code{window-pixel-height} for that window (@pxref{Window Sizes}).
|
||||
|
||||
The buffer-local value of this hook is run once for the buffer and the
|
||||
frame in question, provided at least one window showing the buffer on
|
||||
that frame has changed its size. As it still receives the frame as
|
||||
its sole argument, any function called on a buffer-local basis will be
|
||||
oblivious to which window(s) showing the buffer changed its (their)
|
||||
size and has to check out these windows by using the method described
|
||||
in the previous paragraph.
|
||||
|
||||
These function are usually only called when at least one window was
|
||||
added or has changed size since the last time this hook was run for
|
||||
the associated frame. In some rare cases this hook also runs when a
|
||||
window that was added intermittently has been deleted afterwards. In
|
||||
these cases none of the windows on the frame will appear to have
|
||||
changed its size.
|
||||
@end defvar
|
||||
|
||||
@defvar window-configuration-change-hook
|
||||
A normal hook that is run every time the window configuration of a
|
||||
frame changes. Window configuration changes include splitting and
|
||||
deleting windows, and the display of a different buffer in a window.
|
||||
|
||||
The hook can be also used for tracking changes of window sizes. It
|
||||
is, however, not run when the size of a frame changes or automatic
|
||||
resizing of a minibuffer window (@pxref{Minibuffer Windows}) changes
|
||||
the size of another window. As a rule, adding a function to
|
||||
@code{window-size-change-functions}, see above, is the recommended way
|
||||
for reliably tracking size changes of any window.
|
||||
|
||||
The buffer-local value of this hook is run once for each window on the
|
||||
affected frame, with the relevant window selected and its buffer
|
||||
current. The global value of this hook is run once for the modified
|
||||
frame, with that frame selected.
|
||||
@end defvar
|
||||
|
||||
@defun run-window-configuration-change-hook &optional frame
|
||||
This function runs @code{window-configuration-change-hook} for the
|
||||
specified @var{frame}, which defaults to the selected frame.
|
||||
@end defun
|
||||
|
||||
In addition, you can use @code{jit-lock-register} to register a Font
|
||||
In addition, you can use @code{jit-lock-register} to register a Font
|
||||
Lock fontification function, which will be called whenever parts of a
|
||||
buffer are (re)fontified because a window was scrolled or its size
|
||||
changed. @xref{Other Font Lock Variables}.
|
||||
|
||||
@cindex window change functions
|
||||
The remainder of this section covers four hooks that are called at
|
||||
the end of redisplay provided a significant, non-scrolling change of a
|
||||
window has been detected. For simplicity, these hooks and the
|
||||
functions they call will be collectively referred to as @dfn{window
|
||||
change functions}.
|
||||
|
||||
@cindex window buffer change
|
||||
The first of these hooks is run after a @dfn{window buffer change} is
|
||||
detected, which means that a window was created, deleted or assigned
|
||||
another buffer.
|
||||
|
||||
@defvar window-buffer-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
window buffers have changed. The value should be a list of functions
|
||||
that take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if that window has been created or assigned
|
||||
that buffer since the last time window change functions were run. In
|
||||
this case the window is passed as argument.
|
||||
|
||||
Functions specified by the default value are called for a frame if at
|
||||
least one window on that frame has been added, deleted or assigned
|
||||
another buffer since the last time window change functions were run.
|
||||
In this case the frame is passed as argument.
|
||||
@end defvar
|
||||
|
||||
@cindex window size change
|
||||
The second of these hooks is run after a @dfn{window size change} has
|
||||
been detected which means that a window was created, assigned another
|
||||
buffer, or changed its total size or that of its text area.
|
||||
|
||||
@defvar window-size-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
a window size change occurred. The value should be a list of
|
||||
functions that take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if that window has been added or assigned
|
||||
another buffer, total or body size since the last time window change
|
||||
functions were run. In this case the window is passed as argument.
|
||||
|
||||
Functions specified by the default value are called for a frame if at
|
||||
least one window on that frame has been added or assigned another
|
||||
buffer, total or body size since the last time window change functions
|
||||
were run. In this case the frame is passed as argument.
|
||||
@end defvar
|
||||
|
||||
@cindex window selection change
|
||||
The third of these hooks is run after a @dfn{window selection change}
|
||||
has selected another window since the last redisplay.
|
||||
|
||||
@defvar window-selection-change-functions
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
the selected window or a frame's selected window has changed. The
|
||||
value should be a list of functions that take one argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if that window has been selected or
|
||||
deselected (among all windows or among all windows on its frame) since
|
||||
the last time window change functions were run. In this case the
|
||||
window is passed as argument.
|
||||
|
||||
Functions specified by the default value are called for a frame if
|
||||
that frame has been selected or deselected or the frame's selected
|
||||
window has changed since the last time window change functions were
|
||||
run. In this case the frame is passed as argument.
|
||||
@end defvar
|
||||
|
||||
@cindex window configuration change
|
||||
The fourth of these hooks is run when a @dfn{window configuration
|
||||
change} has been detected which means that either the buffer or the
|
||||
size of a window changed.
|
||||
|
||||
@defvar window-configuration-change-hook
|
||||
This variable specifies functions called at the end of redisplay when
|
||||
either the buffer or the size of a window has changed. The value
|
||||
should be a list of functions that take no argument.
|
||||
|
||||
Functions specified buffer-locally are called for any window showing
|
||||
the corresponding buffer if at least one window on that frame has been
|
||||
added, deleted or assigned another buffer, total or body size since
|
||||
the last time window change functions were run. Each call is
|
||||
performed with the window showing the buffer temporarily selected and
|
||||
its buffer current.
|
||||
|
||||
Functions specified by the default value are called for each frame if
|
||||
at least one window on that frame has been added, deleted or assigned
|
||||
another buffer, total or body size since the last time window change
|
||||
functions were run. Each call is performed with the frame temporarily
|
||||
selected and the selected window's buffer current.
|
||||
@end defvar
|
||||
|
||||
Window change functions are called at the end of redisplay for each
|
||||
frame as follows: First, any buffer-local window buffer change
|
||||
function, window size change function and selected window change
|
||||
functions are called in this order. Next, the default values for
|
||||
these functions are called in the same order. Then any buffer-local
|
||||
window configuration change functions are called followed by functions
|
||||
specified by the default value of those functions.
|
||||
|
||||
Window change functions are run for a specific frame only if a
|
||||
corresponding change was registered for that frame earlier. Such
|
||||
changes include the creation or deletion of a window or the assignment
|
||||
of another buffer or size to a window. Note that even when such a
|
||||
change has been registered, this does not mean that any of the hooks
|
||||
described above is run. If, for example, a change was registered
|
||||
within the scope of a window excursion (@pxref{Window
|
||||
Configurations}), this will trigger a call of window change functions
|
||||
only if that excursion still persists at the time change functions are
|
||||
run. If it is exited earlier, hooks will be run only if registered by
|
||||
a change outside the scope of that excursion.
|
||||
|
||||
While window change functions are run, the functions described next
|
||||
can be called to get more insight into what has changed for a specific
|
||||
window or frame since the last redisplay. All these functions take a
|
||||
live window as single, optional argument, defaulting to the selected
|
||||
window.
|
||||
|
||||
@defun window-old-buffer &optional window
|
||||
This function returns the buffer shown in @var{window} at the last
|
||||
time window change functions were run for @var{window}'s frame. If it
|
||||
returns @code{nil}, @var{window} has been created after that. If it
|
||||
returns @code{t}, @var{window} was not shown at that time but has been
|
||||
restored from a previously saved window configuration afterwards.
|
||||
Otherwise, the return value is the buffer shown by @code{window} at
|
||||
that time.
|
||||
@end defun
|
||||
|
||||
@defun window-old-pixel-width &optional window
|
||||
This function returns the total pixel width of @var{window} the
|
||||
last time window change functions found @code{window} live on its
|
||||
frame. It is zero if @code{window} was created after that.
|
||||
@end defun
|
||||
|
||||
@defun window-old-pixel-height &optional window
|
||||
This function returns the total pixel height of @var{window} the last
|
||||
time window change functions found @code{window} live on its frame.
|
||||
It is zero if @code{window} was created after that.
|
||||
@end defun
|
||||
|
||||
@defun window-old-body-pixel-width &optional window
|
||||
This function returns the pixel width of @var{window}'s text area the
|
||||
last time window change functions found @code{window} live on its
|
||||
frame. It is zero if @code{window} was created after that.
|
||||
@end defun
|
||||
|
||||
@defun window-old-body-pixel-height &optional window
|
||||
This function returns the pixel height of @var{window}'s text area the
|
||||
last time window change functions found @code{window} live on its
|
||||
frame. It is zero if @code{window} was created after that.
|
||||
@end defun
|
||||
|
||||
In order to find out which window or frame was selected the last time
|
||||
window change functions were run, the following functions can be used:
|
||||
|
||||
@defun frame-old-selected-window &optional frame
|
||||
This function returns the selected window of @var{frame} at the last
|
||||
time window change functions were run. If omitted or @code{nil}
|
||||
@var{frame} defaults to the selected frame.
|
||||
@end defun
|
||||
|
||||
@defun old-selected-window
|
||||
This function returns the selected window at the last time window
|
||||
change functions were run.
|
||||
@end defun
|
||||
|
||||
@defun old-selected-frame
|
||||
This function returns the selected frame at the last time window
|
||||
change functions were run.
|
||||
@end defun
|
||||
|
||||
Note that window change functions provide no information about which
|
||||
windows have been deleted since the last time they were run. If
|
||||
necessary, an application should remember any window showing a
|
||||
specific buffer in a local variable of that buffer and update it in a
|
||||
function run by the default value of
|
||||
@code{window-buffer-change-functions} or
|
||||
@code{window-configuration-change-hook} (the only hooks triggered by
|
||||
the deletion of windows).
|
||||
|
||||
The following caveats should be considered when adding a function
|
||||
to window change functions:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Some operations will not trigger a call of window change functions.
|
||||
These include showing another buffer in a minibuffer window or any
|
||||
change of a tooltip window.
|
||||
|
||||
@item
|
||||
Window change functions should not create or delete windows or change
|
||||
the buffer, size or selection status of any window because there is no
|
||||
guarantee that the information about such a change will be propagated
|
||||
to other window change functions. If at all, any such change should
|
||||
be executed only by the last function listed by the default value of
|
||||
@code{window-configuration-change-hook}.
|
||||
|
||||
@item
|
||||
Macros like @code{save-window-excursion}, @code{with-selected-window}
|
||||
or @code{with-current-buffer} can be used when running window change
|
||||
functions.
|
||||
|
||||
@item
|
||||
Running window change functions does not save and restore match data.
|
||||
Unless running @code{window-configuration-change-hook} it does not
|
||||
save or restore the selected window or frame or the current buffer
|
||||
either.
|
||||
|
||||
@item
|
||||
Any redisplay triggering the run of window change functions may be
|
||||
aborted. If the abort occurs before window change functions have run
|
||||
to their completion, they will be run again with the previous values,
|
||||
that is, as if redisplay had not been performed. If aborted later,
|
||||
they will be run with the new values, that is, as if redisplay had
|
||||
been actually performed.
|
||||
@end itemize
|
||||
|
|
27
etc/NEWS
27
etc/NEWS
|
@ -1283,9 +1283,30 @@ displaying the same buffer. See the node "(elisp) Face Remapping"
|
|||
of the Emacs Lisp Reference manual for more detail.
|
||||
|
||||
+++
|
||||
** Special handling of buffer-local 'window-size-change-functions'.
|
||||
A buffer-local value of this hook is now run only if at least one
|
||||
window showing the buffer has changed its size.
|
||||
** Window change functions have been redesigned completely.
|
||||
Hooks reacting to window changes run now only when redisplay detects
|
||||
that a change has actually occurred. The four hooks provided are:
|
||||
'window-buffer-change-functions' (run after window buffers have
|
||||
changed), 'window-size-change-functions' (run after a window was
|
||||
assigned a new buffer or size), 'window-configuration-change-hook'
|
||||
(like the former but run also when a window was deleted) and
|
||||
'window-selection-change-functions' (run when the selected window
|
||||
changed). 'window-scroll-functions' are unaffected by these changes.
|
||||
|
||||
In addition, a number of functions now allow the caller to detect what
|
||||
has changed since last redisplay: 'window-old-buffer' returns for any
|
||||
window the buffer it showed at that time. ‘old-selected-window’ and
|
||||
'old-selected-frame' return the window and frame that were selected
|
||||
during last redisplay. 'window-old-pixel-width' (renamed from
|
||||
'window-pixel-width-before-size-change'), 'window-old-pixel-height'
|
||||
(renamed from 'window-pixel-height-before-size-change'),
|
||||
'window-old-body-pixel-width' and 'window-old-body-pixel-height'
|
||||
return the total and body sizes of any window during last redisplay.
|
||||
|
||||
One consequence of these changes is that all window change functions
|
||||
run now after functions run by 'post-command-hook'. See the section
|
||||
"(elisp) Window Hooks" in the Elisp manual for a detailed explanation
|
||||
of the new behavior.
|
||||
|
||||
+++
|
||||
** New buffer display action alist entry 'dedicated'.
|
||||
|
|
|
@ -640,7 +640,7 @@ only consider active buffers visible.")
|
|||
(unless (minibuffer-window-active-p (minibuffer-window))
|
||||
;; delay this until command has finished to make sure window is
|
||||
;; actually visible before clearing activity
|
||||
(add-hook 'post-command-hook 'erc-modified-channels-update)))
|
||||
(erc-modified-channels-update)))
|
||||
|
||||
(defvar erc-modified-channels-update-inside nil
|
||||
"Variable to prevent running `erc-modified-channels-update' multiple
|
||||
|
@ -669,8 +669,7 @@ ARGS are ignored."
|
|||
(erc-modified-channels-remove-buffer buffer))))
|
||||
erc-modified-channels-alist)
|
||||
(when removed-channel
|
||||
(erc-modified-channels-display)))
|
||||
(remove-hook 'post-command-hook 'erc-modified-channels-update)))
|
||||
(erc-modified-channels-display)))))
|
||||
|
||||
(defvar erc-track-mouse-face (if (featurep 'xemacs)
|
||||
'modeline-mousable
|
||||
|
|
|
@ -1745,20 +1745,17 @@ for FRAME."
|
|||
(let* ((frame (window-normalize-frame frame))
|
||||
(root (frame-root-window frame))
|
||||
(mini (minibuffer-window frame))
|
||||
(mini-height-before-size-change 0)
|
||||
(mini-old-height 0)
|
||||
(mini-height 0))
|
||||
;; FRAME's minibuffer window counts iff it's on FRAME and FRAME is
|
||||
;; not a minibuffer-only frame.
|
||||
(when (and (eq (window-frame mini) frame) (not (eq mini root)))
|
||||
(setq mini-height-before-size-change
|
||||
(window-pixel-height-before-size-change mini))
|
||||
(setq mini-old-height (window-old-pixel-height mini))
|
||||
(setq mini-height (window-pixel-height mini)))
|
||||
;; Return non-nil when either the width of the root or the sum of
|
||||
;; the heights of root and minibuffer window changed.
|
||||
(or (/= (window-pixel-width-before-size-change root)
|
||||
(window-pixel-width root))
|
||||
(/= (+ (window-pixel-height-before-size-change root)
|
||||
mini-height-before-size-change)
|
||||
(or (/= (window-old-pixel-width root) (window-pixel-width root))
|
||||
(/= (+ (window-old-pixel-height root) mini-old-height)
|
||||
(+ (window-pixel-height root) mini-height)))))
|
||||
|
||||
;;;; Frame/display capabilities.
|
||||
|
|
|
@ -2064,9 +2064,7 @@ activity. Only run if the buffer is not visible and
|
|||
(defvar rcirc-visible-buffers nil)
|
||||
(defun rcirc-window-configuration-change ()
|
||||
(unless (minibuffer-window-active-p (minibuffer-window))
|
||||
;; delay this until command has finished to make sure window is
|
||||
;; actually visible before clearing activity
|
||||
(add-hook 'post-command-hook 'rcirc-window-configuration-change-1)))
|
||||
(rcirc-window-configuration-change-1)))
|
||||
|
||||
(defun rcirc-window-configuration-change-1 ()
|
||||
;; clear activity and overlay arrows
|
||||
|
@ -2090,9 +2088,7 @@ activity. Only run if the buffer is not visible and
|
|||
rcirc-activity)))
|
||||
;; update the mode-line string
|
||||
(unless (equal old-activity rcirc-activity)
|
||||
(rcirc-update-activity-string)))
|
||||
|
||||
(remove-hook 'post-command-hook 'rcirc-window-configuration-change-1))
|
||||
(rcirc-update-activity-string))))
|
||||
|
||||
|
||||
;;; buffer name abbreviation
|
||||
|
|
|
@ -2043,6 +2043,8 @@ doc-string of `window-resizable'."
|
|||
;; Aliases of functions defined in window.c.
|
||||
(defalias 'window-height 'window-total-height)
|
||||
(defalias 'window-width 'window-body-width)
|
||||
(defalias 'window-pixel-width-before-size-change 'window-old-pixel-width)
|
||||
(defalias 'window-pixel-height-before-size-change 'window-old-pixel-height)
|
||||
|
||||
(defun window-full-height-p (&optional window)
|
||||
"Return t if WINDOW is as high as its containing frame.
|
||||
|
@ -2759,8 +2761,7 @@ as small) as possible, but don't signal an error."
|
|||
;; The following routine catches the case where we want to resize
|
||||
;; a minibuffer-only frame.
|
||||
(when (resize-mini-window-internal window)
|
||||
(window--pixel-to-total frame)
|
||||
(run-window-configuration-change-hook frame))))))
|
||||
(window--pixel-to-total frame))))))
|
||||
|
||||
(defun window--resize-apply-p (frame &optional horizontal)
|
||||
"Return t when a window on FRAME shall be resized vertically.
|
||||
|
@ -2858,9 +2859,7 @@ instead."
|
|||
(window--resize-siblings window delta horizontal ignore))
|
||||
(when (window--resize-apply-p frame horizontal)
|
||||
(if (window-resize-apply frame horizontal)
|
||||
(progn
|
||||
(window--pixel-to-total frame horizontal)
|
||||
(run-window-configuration-change-hook frame))
|
||||
(window--pixel-to-total frame horizontal)
|
||||
(error "Failed to apply resizing %s" window))))
|
||||
(t
|
||||
(error "Cannot resize window %s" window)))))
|
||||
|
@ -3579,9 +3578,7 @@ move it as far as possible in the desired direction."
|
|||
;; Don't report an error in the standard case.
|
||||
(when (window--resize-apply-p frame horizontal)
|
||||
(if (window-resize-apply frame horizontal)
|
||||
(progn
|
||||
(window--pixel-to-total frame horizontal)
|
||||
(run-window-configuration-change-hook frame))
|
||||
(window--pixel-to-total frame horizontal)
|
||||
;; But do report an error if applying the changes fails.
|
||||
(error "Failed adjusting window %s" window))))))))
|
||||
|
||||
|
@ -4112,7 +4109,6 @@ that is its frame's root window."
|
|||
;; `delete-window-internal' has selected a window that should
|
||||
;; not be selected, fix this here.
|
||||
(other-window -1 frame))
|
||||
(run-window-configuration-change-hook frame)
|
||||
(window--check frame)
|
||||
;; Always return nil.
|
||||
nil))))
|
||||
|
@ -4198,7 +4194,6 @@ any window whose `no-delete-other-windows' parameter is non-nil."
|
|||
;; If WINDOW is the main window of its frame do nothing.
|
||||
(unless (eq window main)
|
||||
(delete-other-windows-internal window main)
|
||||
(run-window-configuration-change-hook frame)
|
||||
(window--check frame))
|
||||
;; Always return nil.
|
||||
nil)))
|
||||
|
@ -5186,7 +5181,6 @@ frame. The selected window is not changed by this function."
|
|||
(unless size
|
||||
(window--sanitize-window-sizes horizontal))
|
||||
|
||||
(run-window-configuration-change-hook frame)
|
||||
(run-window-scroll-functions new)
|
||||
(window--check frame)
|
||||
;; Always return the new window.
|
||||
|
@ -5417,15 +5411,13 @@ window."
|
|||
(balance-windows-1 window)
|
||||
(when (window--resize-apply-p frame)
|
||||
(window-resize-apply frame)
|
||||
(window--pixel-to-total frame)
|
||||
(run-window-configuration-change-hook frame))
|
||||
(window--pixel-to-total frame))
|
||||
;; Balance horizontally.
|
||||
(window--resize-reset (window-frame window) t)
|
||||
(balance-windows-1 window t)
|
||||
(when (window--resize-apply-p frame t)
|
||||
(window-resize-apply frame t)
|
||||
(window--pixel-to-total frame t)
|
||||
(run-window-configuration-change-hook frame))))
|
||||
(window--pixel-to-total frame t))))
|
||||
|
||||
(defun window-fixed-size-p (&optional window direction)
|
||||
"Return t if WINDOW cannot be resized in DIRECTION.
|
||||
|
@ -9441,15 +9433,7 @@ displaying that processes's buffer."
|
|||
(when size
|
||||
(set-process-window-size process (cdr size) (car size))))))))))
|
||||
|
||||
;; Remove the following call in Emacs 27, running
|
||||
;; 'window-size-change-functions' should suffice.
|
||||
(add-hook 'window-configuration-change-hook 'window--adjust-process-windows)
|
||||
|
||||
;; Catch any size changes not handled by
|
||||
;; 'window-configuration-change-hook' (Bug#32720, "another issue" in
|
||||
;; Bug#33230).
|
||||
(add-hook 'window-size-change-functions (lambda (_frame)
|
||||
(window--adjust-process-windows)))
|
||||
|
||||
;; Some of these are in tutorial--default-keys, so update that if you
|
||||
;; change these.
|
||||
|
|
25
src/frame.c
25
src/frame.c
|
@ -55,9 +55,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#endif
|
||||
|
||||
/* The currently selected frame. */
|
||||
|
||||
Lisp_Object selected_frame;
|
||||
|
||||
/* The selected frame the last time window change functions were run. */
|
||||
Lisp_Object old_selected_frame;
|
||||
|
||||
/* A frame which is not just a mini-buffer, or NULL if there are no such
|
||||
frames. This is usually the most recent such frame that was selected. */
|
||||
|
||||
|
@ -855,7 +857,8 @@ make_frame (bool mini_p)
|
|||
f->ns_transparent_titlebar = false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This one should never be zero. */
|
||||
f->change_stamp = 1;
|
||||
root_window = make_window ();
|
||||
rw = XWINDOW (root_window);
|
||||
if (mini_p)
|
||||
|
@ -1451,7 +1454,8 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
|
|||
return do_switch_frame (frame, 1, 0, norecord);
|
||||
}
|
||||
|
||||
DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "^e",
|
||||
DEFUN ("handle-switch-frame", Fhandle_switch_frame,
|
||||
Shandle_switch_frame, 1, 1, "^e",
|
||||
doc: /* Handle a switch-frame event EVENT.
|
||||
Switch-frame events are usually bound to this function.
|
||||
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,
|
|||
{
|
||||
return selected_frame;
|
||||
}
|
||||
|
||||
DEFUN ("old-selected-frame", Fold_selected_frame,
|
||||
Sold_selected_frame, 0, 0, 0,
|
||||
doc: /* Return the old selected FRAME.
|
||||
FRAME must be a live frame and defaults to the selected one.
|
||||
|
||||
The return value is the frame selected the last time window change
|
||||
functions were run. */)
|
||||
(void)
|
||||
{
|
||||
return old_selected_frame;
|
||||
}
|
||||
|
||||
DEFUN ("frame-list", Fframe_list, Sframe_list,
|
||||
0, 0, 0,
|
||||
|
@ -6098,9 +6114,10 @@ iconify the top level frame instead. */);
|
|||
defsubr (&Swindow_system);
|
||||
defsubr (&Sframe_windows_min_size);
|
||||
defsubr (&Smake_terminal_frame);
|
||||
defsubr (&Shandle_switch_frame);
|
||||
defsubr (&Sselect_frame);
|
||||
defsubr (&Shandle_switch_frame);
|
||||
defsubr (&Sselected_frame);
|
||||
defsubr (&Sold_selected_frame);
|
||||
defsubr (&Sframe_list);
|
||||
defsubr (&Sframe_parent);
|
||||
defsubr (&Sframe_ancestor_p);
|
||||
|
|
46
src/frame.h
46
src/frame.h
|
@ -125,6 +125,10 @@ struct frame
|
|||
The selected window of the selected frame is Emacs's selected window. */
|
||||
Lisp_Object selected_window;
|
||||
|
||||
/* This frame's selected window when run_window_change_functions was
|
||||
called the last time on this frame. */
|
||||
Lisp_Object old_selected_window;
|
||||
|
||||
/* This frame's minibuffer window.
|
||||
Most frames have their own minibuffer windows,
|
||||
but only the selected frame's minibuffer window
|
||||
|
@ -321,9 +325,14 @@ struct frame
|
|||
cleared. */
|
||||
bool_bf explicit_name : 1;
|
||||
|
||||
/* True if configuration of windows on this frame has changed since
|
||||
last call of run_window_size_change_functions. */
|
||||
bool_bf window_configuration_changed : 1;
|
||||
/* True if at least one window on this frame changed since the last
|
||||
call of run_window_change_functions. Changes are either "state
|
||||
changes" (a window has been created, deleted or got assigned
|
||||
another buffer) or "size changes" (the total or body size of a
|
||||
window changed). run_window_change_functions exits early unless
|
||||
either this flag is true or a window selection happened on this
|
||||
frame. */
|
||||
bool_bf window_change : 1;
|
||||
|
||||
/* True if the mouse has moved on this display device
|
||||
since the last time we checked. */
|
||||
|
@ -406,6 +415,20 @@ struct frame
|
|||
|
||||
/* Bitfield area ends here. */
|
||||
|
||||
/* This frame's change stamp, set the last time window change
|
||||
functions were run for this frame. Should never be 0 because
|
||||
that's the change stamp of a new window. A window was not on a
|
||||
frame the last run_window_change_functions was called on it if
|
||||
it's change stamp differs from that of its frame. */
|
||||
int change_stamp;
|
||||
|
||||
/* This frame's number of windows, set the last time window change
|
||||
functions were run for this frame. Should never be 0 even for
|
||||
minibuffer-only frames. If no window has been added, this allows
|
||||
to detect whether a window was deleted on this frame since the
|
||||
last time run_window_change_functions was called on it. */
|
||||
ptrdiff_t number_of_windows;
|
||||
|
||||
/* Number of lines (rounded up) of tool bar. REMOVE THIS */
|
||||
int tool_bar_lines;
|
||||
|
||||
|
@ -662,6 +685,11 @@ fset_selected_window (struct frame *f, Lisp_Object val)
|
|||
f->selected_window = val;
|
||||
}
|
||||
INLINE void
|
||||
fset_old_selected_window (struct frame *f, Lisp_Object val)
|
||||
{
|
||||
f->old_selected_window = val;
|
||||
}
|
||||
INLINE void
|
||||
fset_title (struct frame *f, Lisp_Object val)
|
||||
{
|
||||
f->title = val;
|
||||
|
@ -908,10 +936,9 @@ default_pixels_per_inch_y (void)
|
|||
are frozen on frame F. */
|
||||
#define FRAME_WINDOWS_FROZEN(f) (f)->frozen_window_starts
|
||||
|
||||
/* True if the frame's window configuration has changed since last call
|
||||
of run_window_size_change_functions. */
|
||||
#define FRAME_WINDOW_CONFIGURATION_CHANGED(f) \
|
||||
(f)->window_configuration_changed
|
||||
/* True if at least one window changed on frame F since the last time
|
||||
window change functions were run on F. */
|
||||
#define FRAME_WINDOW_CHANGE(f) (f)->window_change
|
||||
|
||||
/* The minibuffer window of frame F, if it has one; otherwise nil. */
|
||||
#define FRAME_MINIBUF_WINDOW(f) f->minibuffer_window
|
||||
|
@ -919,8 +946,10 @@ default_pixels_per_inch_y (void)
|
|||
/* The root window of the window tree of frame F. */
|
||||
#define FRAME_ROOT_WINDOW(f) f->root_window
|
||||
|
||||
/* The currently selected window of the window tree of frame F. */
|
||||
/* The currently selected window of frame F. */
|
||||
#define FRAME_SELECTED_WINDOW(f) f->selected_window
|
||||
/* The old selected window of frame F. */
|
||||
#define FRAME_OLD_SELECTED_WINDOW(f) f->old_selected_window
|
||||
|
||||
#define FRAME_INSERT_COST(f) (f)->insert_line_cost
|
||||
#define FRAME_DELETE_COST(f) (f)->delete_line_cost
|
||||
|
@ -1215,6 +1244,7 @@ SET_FRAME_VISIBLE (struct frame *f, int v)
|
|||
(f)->iconified = (eassert (0 <= (i) && (i) <= 1), (i))
|
||||
|
||||
extern Lisp_Object selected_frame;
|
||||
extern Lisp_Object old_selected_frame;
|
||||
|
||||
#if ! (defined USE_GTK || defined HAVE_NS)
|
||||
extern int frame_default_tool_bar_height;
|
||||
|
|
779
src/window.c
779
src/window.c
File diff suppressed because it is too large
Load diff
27
src/window.h
27
src/window.h
|
@ -142,6 +142,11 @@ struct window
|
|||
as well. */
|
||||
Lisp_Object contents;
|
||||
|
||||
/* The old buffer of this window, set to this window's buffer by
|
||||
run_window_change_functions every time it sees this window.
|
||||
Unused for internal windows. */
|
||||
Lisp_Object old_buffer;
|
||||
|
||||
/* A marker pointing to where in the text to start displaying.
|
||||
BIDI Note: This is the _logical-order_ start, i.e. the smallest
|
||||
buffer position visible in the window, not necessarily the
|
||||
|
@ -229,6 +234,14 @@ struct window
|
|||
/* Unique number of window assigned when it was created. */
|
||||
EMACS_INT sequence_number;
|
||||
|
||||
/* The change stamp of this window. Set to 0 when the window is
|
||||
created, it is set to its frame's change stamp every time
|
||||
run_window_change_functions is run on that frame with this
|
||||
window live. It is left alone when the window exists only
|
||||
within a window configuration. Not useful for internal
|
||||
windows. */
|
||||
int change_stamp;
|
||||
|
||||
/* The upper left corner pixel coordinates of this window, as
|
||||
integers relative to upper left corner of frame = 0, 0. */
|
||||
int pixel_left;
|
||||
|
@ -243,10 +256,13 @@ struct window
|
|||
int pixel_width;
|
||||
int pixel_height;
|
||||
|
||||
/* The pixel sizes of the window at the last time
|
||||
`window-size-change-functions' was run. */
|
||||
int pixel_width_before_size_change;
|
||||
int pixel_height_before_size_change;
|
||||
/* The pixel and pixel body sizes of the window at the last time
|
||||
run_window_change_functions was run with this window live. Not
|
||||
useful for internal windows. */
|
||||
int old_pixel_width;
|
||||
int old_pixel_height;
|
||||
int old_body_pixel_width;
|
||||
int old_body_pixel_height;
|
||||
|
||||
/* The size of the window. */
|
||||
int total_cols;
|
||||
|
@ -1023,6 +1039,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
|
|||
This value is always the same as FRAME_SELECTED_WINDOW (selected_frame). */
|
||||
|
||||
extern Lisp_Object selected_window;
|
||||
extern Lisp_Object old_selected_window;
|
||||
|
||||
/* This is a time stamp for window selection, so we can find the least
|
||||
recently used window. Its only users are Fselect_window,
|
||||
|
@ -1051,7 +1068,7 @@ extern void grow_mini_window (struct window *, int, bool);
|
|||
extern void shrink_mini_window (struct window *, bool);
|
||||
extern int window_relative_x_coord (struct window *, enum window_part, int);
|
||||
|
||||
void run_window_size_change_functions (Lisp_Object);
|
||||
void run_window_change_functions (void);
|
||||
|
||||
/* Make WINDOW display BUFFER. RUN_HOOKS_P means it's allowed
|
||||
to run hooks. See make_frame for a case where it's not allowed. */
|
||||
|
|
72
src/xdisp.c
72
src/xdisp.c
|
@ -2786,6 +2786,7 @@ init_iterator (struct it *it, struct window *w,
|
|||
struct glyph_row *row, enum face_id base_face_id)
|
||||
{
|
||||
enum face_id remapped_base_face_id = base_face_id;
|
||||
int body_width = 0, body_height = 0;
|
||||
|
||||
/* Some precondition checks. */
|
||||
eassert (w != NULL && it != NULL);
|
||||
|
@ -2962,7 +2963,7 @@ init_iterator (struct it *it, struct window *w,
|
|||
{
|
||||
/* Mode lines, menu bar in terminal frames. */
|
||||
it->first_visible_x = 0;
|
||||
it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
|
||||
it->last_visible_x = body_width = WINDOW_PIXEL_WIDTH (w);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2982,8 +2983,12 @@ init_iterator (struct it *it, struct window *w,
|
|||
else
|
||||
it->first_visible_x =
|
||||
window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f);
|
||||
it->last_visible_x = (it->first_visible_x
|
||||
+ window_box_width (w, TEXT_AREA));
|
||||
|
||||
body_width = window_box_width (w, TEXT_AREA);
|
||||
if (!w->pseudo_window_p && !MINI_WINDOW_P (w)
|
||||
&& body_width != w->old_body_pixel_width)
|
||||
FRAME_WINDOW_CHANGE (it->f) = true;
|
||||
it->last_visible_x = it->first_visible_x + body_width;
|
||||
|
||||
/* If we truncate lines, leave room for the truncation glyph(s) at
|
||||
the right margin. Otherwise, leave room for the continuation
|
||||
|
@ -2997,7 +3002,8 @@ init_iterator (struct it *it, struct window *w,
|
|||
}
|
||||
|
||||
it->header_line_p = window_wants_header_line (w);
|
||||
it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
|
||||
body_height = WINDOW_HEADER_LINE_HEIGHT (w);
|
||||
it->current_y = body_height + w->vscroll;
|
||||
}
|
||||
|
||||
/* Leave room for a border glyph. */
|
||||
|
@ -3006,6 +3012,10 @@ init_iterator (struct it *it, struct window *w,
|
|||
it->last_visible_x -= 1;
|
||||
|
||||
it->last_visible_y = window_text_bottom_y (w);
|
||||
body_height += it->last_visible_y;
|
||||
if (!w->pseudo_window_p && !MINI_WINDOW_P (w)
|
||||
&& body_height != w->old_body_pixel_height)
|
||||
FRAME_WINDOW_CHANGE (it->f) = true;
|
||||
|
||||
/* For mode lines and alike, arrange for the first glyph having a
|
||||
left box line if the face specifies a box. */
|
||||
|
@ -12200,8 +12210,6 @@ prepare_menu_bars (void)
|
|||
&& !XBUFFER (w->contents)->text->redisplay)
|
||||
continue;
|
||||
|
||||
run_window_size_change_functions (frame);
|
||||
|
||||
if (FRAME_PARENT_FRAME (f))
|
||||
continue;
|
||||
|
||||
|
@ -14119,20 +14127,6 @@ redisplay_internal (void)
|
|||
{
|
||||
echo_area_display (false);
|
||||
|
||||
/* If echo_area_display resizes the mini-window, the redisplay and
|
||||
window_sizes_changed flags of the selected frame are set, but
|
||||
it's too late for the hooks in window-size-change-functions,
|
||||
which have been examined already in prepare_menu_bars. So in
|
||||
that case we call the hooks here only for the selected frame. */
|
||||
if (sf->redisplay)
|
||||
{
|
||||
ptrdiff_t count1 = SPECPDL_INDEX ();
|
||||
|
||||
record_unwind_save_match_data ();
|
||||
run_window_size_change_functions (selected_frame);
|
||||
unbind_to (count1, Qnil);
|
||||
}
|
||||
|
||||
if (message_cleared_p)
|
||||
update_miniwindow_p = true;
|
||||
|
||||
|
@ -14149,15 +14143,6 @@ redisplay_internal (void)
|
|||
&& (current_buffer->clip_changed || window_outdated (w))
|
||||
&& resize_mini_window (w, false))
|
||||
{
|
||||
if (sf->redisplay)
|
||||
{
|
||||
ptrdiff_t count1 = SPECPDL_INDEX ();
|
||||
|
||||
record_unwind_save_match_data ();
|
||||
run_window_size_change_functions (selected_frame);
|
||||
unbind_to (count1, Qnil);
|
||||
}
|
||||
|
||||
/* Resized active mini-window to fit the size of what it is
|
||||
showing if its contents might have changed. */
|
||||
must_finish = true;
|
||||
|
@ -14347,7 +14332,19 @@ redisplay_internal (void)
|
|||
&& (w = XWINDOW (selected_window)) != sw)
|
||||
goto retry;
|
||||
|
||||
/* We used to always goto end_of_redisplay here, but this
|
||||
if (!NILP (Vrun_hooks))
|
||||
{
|
||||
run_window_change_functions ();
|
||||
|
||||
/* If windows or buffers changed or selected_window
|
||||
changed, redisplay again. */
|
||||
if ((windows_or_buffers_changed)
|
||||
|| (WINDOWP (selected_window)
|
||||
&& (w = XWINDOW (selected_window)) != sw))
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* We used to always goto end_of_redisplay here, but this
|
||||
isn't enough if we have a blinking cursor. */
|
||||
if (w->cursor_off_p == w->last_cursor_off_p)
|
||||
goto end_of_redisplay;
|
||||
|
@ -14706,9 +14703,22 @@ redisplay_internal (void)
|
|||
/* If we just did a pending size change, or have additional
|
||||
visible frames, or selected_window changed, redisplay again. */
|
||||
if ((windows_or_buffers_changed && !pending)
|
||||
|| (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
|
||||
|| (WINDOWP (selected_window)
|
||||
&& (w = XWINDOW (selected_window)) != sw))
|
||||
goto retry;
|
||||
|
||||
if (!NILP (Vrun_hooks))
|
||||
{
|
||||
run_window_change_functions ();
|
||||
|
||||
/* If windows or buffers changed or selected_window changed,
|
||||
redisplay again. */
|
||||
if ((windows_or_buffers_changed)
|
||||
|| (WINDOWP (selected_window)
|
||||
&& (w = XWINDOW (selected_window)) != sw))
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* Clear the face and image caches.
|
||||
|
||||
We used to do this only if consider_all_windows_p. But the cache
|
||||
|
|
Loading…
Add table
Reference in a new issue