emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 0aece3e: Expand spectrum of window change functions


From: Martin Rudalics
Subject: [Emacs-diffs] master 0aece3e: Expand spectrum of window change functions
Date: Thu, 17 Jan 2019 04:22:49 -0500 (EST)

branch: master
commit 0aece3e1181e66f2a1a067ae876e55bdaa45edd5
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>

    Expand spectrum of window change functions
    
    * src/window.c (run_window_change_functions): Run window
    change functions for Qwindow_state_change_functions.
    (resize_frame_windows): Set frame's window_change slot when
    single-window frames change size.
    (Qwindow_state_change_functions): New symbol.
    (Vwindow_state_change_functions): New Lisp variable.
    * doc/lispref/windows.texi (Selecting Windows): Mention
    'window-selection/state-change-functions' and add reference to
    Window Hooks.
    (Window Hooks): Document 'window-state-change-functions'.
    * etc/NEWS: Mention new hook 'window-state-change-functions'.
---
 doc/lispref/windows.texi | 46 +++++++++++++++++++++++++++++++++++------
 etc/NEWS                 |  9 +++++---
 src/window.c             | 53 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 98 insertions(+), 10 deletions(-)

diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 6b5aa66..afb81e6 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -1758,7 +1758,7 @@ raise the frame or make sure input focus is directed to 
that frame.
 @xref{Input Focus}.
 @end defun
 
address@hidden select window hook
address@hidden select window hooks
 @cindex running a hook when a window gets selected
 For historical reasons, Emacs does not run a separate hook whenever a
 window gets selected.  Applications and internal routines often
@@ -1774,8 +1774,8 @@ useful.
   However, when its @var{norecord} argument is @code{nil},
 @code{select-window} updates the buffer list and thus indirectly runs
 the normal hook @code{buffer-list-update-hook} (@pxref{Buffer List}).
-Consequently, that hook provides a reasonable way to run a function
-whenever a window gets selected more ``permanently''.
+Consequently, that hook provides one way to run a function whenever a
+window gets selected more ``permanently''.
 
   Since @code{buffer-list-update-hook} is also run by functions that are
 not related to window management, it will usually make sense to save the
@@ -1787,6 +1787,13 @@ temporarily passes a address@hidden @var{norecord} 
argument.  If
 possible, the macro @code{with-selected-window} (see below) should be
 used in such cases.
 
+  Emacs also runs the hook @code{window-selection-change-functions}
+whenever the redisplay routine detects that another window has been
+selected since last redisplay.  @xref{Window Hooks}, for a detailed
+explanation.  @code{window-state-change-functions} (described in the
+same section) is another abnormal hook run after a different window
+has been selected but is triggered by other window changes as well.
+
 @cindex most recently selected windows
   The sequence of calls to @code{select-window} with a address@hidden
 @var{norecord} argument determines an ordering of windows by their
@@ -6039,7 +6046,7 @@ 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 remainder of this section covers five 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
@@ -6108,10 +6115,37 @@ window has changed since the last time window change 
functions were
 run.  In this case the frame is passed as argument.
 @end defvar
 
address@hidden window state change
+The fourth of these hooks is run after a @dfn{window state change} has
+been detected, which means that at least one of the three preceding
+window changes has occurred.
+
address@hidden window-state-change-functions
+This variable specifies functions called at the end of redisplay when
+a window buffer or size change occurred or 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 added or assigned
+another buffer, total or body size or 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 at
+least one window on that frame has been added, deleted or assigned
+another buffer, total or body size or 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.
address@hidden defvar
+
 @cindex window configuration change
-The fourth of these hooks is run when a @dfn{window configuration
+The fifth 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.
+size of a window changed.  It differs from the four preceding hooks in
+the way it is run.
 
 @defvar window-configuration-change-hook
 This variable specifies functions called at the end of redisplay when
diff --git a/etc/NEWS b/etc/NEWS
index 0250307..10bcc5a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1303,14 +1303,17 @@ of the Emacs Lisp Reference manual for more detail.
 
 +++
 ** 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:
+that a change has actually occurred.  The five 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
+(like the former but run also when a window was deleted),
 'window-selection-change-functions' (run when the selected window
-changed).  'window-scroll-functions' are unaffected by these changes.
+changed) and 'window-state-change-functions' (run when any of the
+preceding ones is run).  '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
diff --git a/src/window.c b/src/window.c
index 7eb532f..c0d7459 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3799,7 +3799,7 @@ run_window_change_functions (void)
            run_window_change_functions_1
              (Qwindow_size_change_functions, buffer, window);
 
-         /* This window's selection has changed when it it was
+         /* This window's selection has changed when it was
             (de-)selected as its frame's or the globally selected
             window.  */
          if (((frame_selected_change
@@ -3811,6 +3811,21 @@ run_window_change_functions (void)
              && WINDOW_LIVE_P (window))
            run_window_change_functions_1
              (Qwindow_selection_change_functions, buffer, window);
+
+         /* This window's state has changed when its buffer or size
+            changed or it was (de-)selected as its frame's or the
+            globally selected window.  */
+         if ((window_buffer_change
+              || window_size_change
+              || ((frame_selected_change
+                   && (EQ (window, old_selected_window)
+                       || EQ (window, selected_window)))
+                  || (frame_selected_window_change
+                      && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))
+                          || EQ (window, FRAME_SELECTED_WINDOW (f))))))
+             && WINDOW_LIVE_P (window))
+           run_window_change_functions_1
+             (Qwindow_state_change_functions, buffer, window);
        }
 
       /* When the number of windows on a frame has decreased, at least
@@ -3840,6 +3855,15 @@ run_window_change_functions (void)
        run_window_change_functions_1
          (Qwindow_selection_change_functions, Qnil, frame);
 
+      /* A frame has changed state when a size or buffer change
+        occurrd or its selected window has changed or when it was
+        (de-)selected.  */
+      if ((frame_selected_change || frame_selected_window_change
+          || frame_buffer_change || window_deleted || frame_size_change)
+         && FRAME_LIVE_P (f))
+       run_window_change_functions_1
+         (Qwindow_state_change_functions, Qnil, frame);
+
       /* A frame's configuration changed when one of its windows has
         changed buffer or size or at least one window was deleted.  */
       if ((frame_size_change || window_deleted) && FRAME_LIVE_P (f))
@@ -4650,16 +4674,26 @@ resize_frame_windows (struct frame *f, int size, bool 
horflag, bool pixelwise)
     /* For a leaf root window just set the size.  */
     if (horflag)
       {
+       bool changed = r->pixel_width != new_pixel_size;
+
        r->total_cols = new_size;
        r->pixel_width = new_pixel_size;
+
+       if (changed && !WINDOW_PSEUDO_P (r))
+         FRAME_WINDOW_CHANGE (f) = true;
       }
     else
       {
+       bool changed = r->pixel_height != new_pixel_size;
+
        r->top_line = FRAME_TOP_MARGIN (f);
        r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
 
        r->total_lines = new_size;
        r->pixel_height = new_pixel_size;
+
+       if (changed && !WINDOW_PSEUDO_P (r))
+         FRAME_WINDOW_CHANGE (f) = true;
       }
   else
     {
@@ -7953,6 +7987,7 @@ syms_of_window (void)
   Fput (Qscroll_down, Qscroll_command, Qt);
 
   DEFSYM (Qwindow_configuration_change_hook, 
"window-configuration-change-hook");
+  DEFSYM (Qwindow_state_change_functions, "window-state-change-functions");
   DEFSYM (Qwindow_size_change_functions, "window-size-change-functions");
   DEFSYM (Qwindow_buffer_change_functions, "window-buffer-change-functions");
   DEFSYM (Qwindow_selection_change_functions, 
"window-selection-change-functions");
@@ -8074,6 +8109,22 @@ the frame's selected window has changed since the last 
redisplay.  In
 this case the frame is passed as argument.  */);
   Vwindow_selection_change_functions = Qnil;
 
+  DEFVAR_LISP ("window-state-change-functions", Vwindow_state_change_functions,
+              doc: /* Functions called during redisplay when the window state 
changed.
+The value should be a list of functions that take one argument.
+
+Functions specified buffer-locally are called for each window showing
+the corresponding buffer if and only if that window has been added,
+resized, changed its buffer or has been (de-)selected since the last
+redisplay.  In this case the window is passed as argument.
+
+Functions specified by the default value are called for each frame if
+at least one window on that frame has been added, deleted, changed its
+buffer or its total or body size or the frame has been (de-)selected
+or its selected window has changed since the last redisplay.  In this
+case the frame is passed as argument.  */);
+  Vwindow_selection_change_functions = Qnil;
+
   DEFVAR_LISP ("window-configuration-change-hook", 
Vwindow_configuration_change_hook,
               doc: /* Functions called during redisplay when window 
configuration has changed.
 The value should be a list of functions that take no argument.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]