]> git.eshelyaron.com Git - emacs.git/commitdiff
Handle buffer-local 'window-size-change-functions' specially (Bug#32637)
authorMartin Rudalics <rudalics@gmx.at>
Mon, 10 Sep 2018 08:05:20 +0000 (10:05 +0200)
committerMartin Rudalics <rudalics@gmx.at>
Mon, 10 Sep 2018 08:05:20 +0000 (10:05 +0200)
* 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
etc/NEWS
src/window.c

index 3eaa15a6036f7e0f4150dffc139964a98553fd05..7cfa5ead5f1f1d4416739fbff47e9efb542b5c54 100644 (file)
@@ -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
index ff65a5520d524fa6cc8139dd7a4304a4b270bc33..9ab26222ec2911eaaf0187e1e86b33febd39d2ec 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -963,6 +963,11 @@ now support filters, allowing faces to vary between different windows
 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.
 
index 04de9656809e8318c5f6c4c190386a56286ddaa9..b81469b9d69b267303e019e4a4348c64c64eedef 100644 (file)
@@ -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");