emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 6a00f2b: Handle buffer-local 'window-size-change-fu


From: Martin Rudalics
Subject: [Emacs-diffs] master 6a00f2b: Handle buffer-local 'window-size-change-functions' specially (Bug#32637)
Date: Mon, 10 Sep 2018 04:06:31 -0400 (EDT)

branch: master
commit 6a00f2babf84f309fa00269bff3abef7eb502023
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>

    Handle buffer-local 'window-size-change-functions' specially (Bug#32637)
    
    * src/window.c (run_window_size_change_functions): Run a
    buffer-local value once per each frame and only if at least
    one window showing the buffer on that frame has changed its
    size.  (Bug#32637)
    * doc/lispref/windows.texi (Window Hooks): Describe new
    behavior of buffer-local 'window-size-change-functions'.
---
 doc/lispref/windows.texi |  8 ++++++++
 etc/NEWS                 |  5 +++++
 src/window.c             | 48 +++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 3eaa15a..7cfa5ea 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -5205,6 +5205,14 @@ whether a specific window has changed size, compare the 
return values of
 @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
diff --git a/etc/NEWS b/etc/NEWS
index ff65a55..9ab2622 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -964,6 +964,11 @@ displaying the same buffer.  See the Info node "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.
+
++++
 ** New function assoc-delete-all.
 
 +++
diff --git a/src/window.c b/src/window.c
index 04de965..b81469b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3442,7 +3442,11 @@ run_window_size_change_functions (Lisp_Object frame)
 {
   struct frame *f = XFRAME (frame);
   struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
-  Lisp_Object functions = Vwindow_size_change_functions;
+
+  if (NILP (Vrun_hooks)
+      || !(f->can_x_set_window_size)
+      || !(f->after_make_frame))
+    return;
 
   if (FRAME_WINDOW_CONFIGURATION_CHANGED (f)
       /* Here we implicitly exclude the possibility that the height of
@@ -3450,11 +3454,44 @@ run_window_size_change_functions (Lisp_Object frame)
         of FRAME's root window alone.  */
       || window_size_changed (r))
     {
-      while (CONSP (functions))
+      Lisp_Object globals = Fdefault_value (Qwindow_size_change_functions);
+      Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
+      /* The buffers for which the local hook was already run.  */
+      Lisp_Object buffers = Qnil;
+
+      for (; CONSP (windows); windows = XCDR (windows))
+       {
+         Lisp_Object window = XCAR (windows);
+         Lisp_Object buffer = Fwindow_buffer (window);
+
+         /* Run a buffer-local value only once for that buffer and
+            only if at least one window showing that buffer on FRAME
+            actually changed its size.  Note that the function is run
+            with FRAME as its argument and as such oblivious to the
+            window checked below.  */
+         if (window_size_changed (XWINDOW (window))
+             && !Fmemq (buffer, buffers)
+             && Flocal_variable_p (Qwindow_size_change_functions, buffer))
+           {
+             Lisp_Object locals
+               = Fbuffer_local_value (Qwindow_size_change_functions, buffer);
+
+             while (CONSP (locals))
+               {
+                 if (!EQ (XCAR (locals), Qt))
+                   safe_call1 (XCAR (locals), frame);
+                 locals = XCDR (locals);
+               }
+
+             buffers = Fcons (buffer, buffers);
+           }
+       }
+
+      while (CONSP (globals))
        {
-         if (!EQ (XCAR (functions), Qt))
-           safe_call1 (XCAR (functions), frame);
-         functions = XCDR (functions);
+         if (!EQ (XCAR (globals), Qt))
+           safe_call1 (XCAR (globals), frame);
+         globals = XCDR (globals);
        }
 
       window_set_before_size_change_sizes (r);
@@ -7556,6 +7593,7 @@ syms_of_window (void)
   Fput (Qscroll_down, Qscroll_command, Qt);
 
   DEFSYM (Qwindow_configuration_change_hook, 
"window-configuration-change-hook");
+  DEFSYM (Qwindow_size_change_functions, "window-size-change-functions");
   DEFSYM (Qwindowp, "windowp");
   DEFSYM (Qwindow_configuration_p, "window-configuration-p");
   DEFSYM (Qwindow_live_p, "window-live-p");



reply via email to

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