Subject: bug#35873: Add atomic window support to Gnus

From: Eric Abrahamsen <[email-masked]>
Date: Fri, 20 Sep 2019 12:28:05 -0700

Eric Abrahamsen <[email-masked]> writes:

> martin rudalics <[email-masked]> writes:
>
>>> I updated the patch with Martin's suggestion, and am back to running
>>> this daily. One thing I noticed is that (in this case in my Gnorb
>>> package) running `delete-other-windows' from a Gnus window will now
>>> result in one of these:
>>>
>>> delete-other-windows: Root of atomic window is root window of its frame
>>>
>>> That error is expected with atomic windows. I can change Gnorb to not
>>> use `delete-other-windows' (it shouldn't be using that anyway), but I
>>> wonder if that's likely to cause an unacceptable amount of friction with
>>> other packages/user code. (While noting that this behavior is off by
>>> default.)
>>
>> You can also specify a function in the 'delete-other-windows'
>> parameter of any window involved.  One that dissolves atomicity, for
>> example.
>
> Oh, excellent! I don't think I'll actually use that yet -- I'll fix my
> own package not to call `delete-other-windows', then ask folks to enable
> this feature and watch out for the error, and hopefully bug reports will
> show how `delete-other-windows' might be being used in the wild. Then we
> can look at how best to implement the d-o-w parameter for Gnus windows.

There's the patch as it stands. I'll push in a bit if there's no objection.

>From 1ac1048dff4f2ddae5dec9eee75c0a4122c3feb8 Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <[email-masked]>
Date: Sun, 21 Apr 2019 11:04:20 -0700
Subject: [PATCH] New option for making Gnus window layouts atomic

* lisp/gnus/gnus-win.el (gnus-use-atomic-windows): New boolean
  customization option.
  (gnus-configure-windows): When removing old window layouts, check
  for and remove atomicity.
  (gnus-configure-windows): When gnus-use-atomic-windows is non-nil,
  make Gnus window layouts atomic.
* doc/misc/gnus.texi (Window Layout): Document.
---
 doc/misc/gnus.texi    |  8 ++++++++
 lisp/gnus/gnus-win.el | 20 ++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index fb9581f985..d535c1a49e 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -22923,6 +22923,14 @@ Window Layout
 to fiddle with @code{gnus-tree-minimize-window} to avoid having the
 windows resized.
 
+Lastly, it's possible to make Gnus window layouts ``atomic''
+(@xref{Atomic Windows, , Atomic Windows, elisp, The GNU Emacs Lisp
+Reference Manual}) by setting @code{gnus-use-atomic-windows} to
+@code{t}.  This will ensure that pop-up buffers (e.g. help or
+completion buffers), will appear below or to the side of the entire
+Gnus window layout and not, for example, squashed between the summary
+and article buffers.
+
 @subsection Window Configuration Names
 
 Here's a list of most of the currently known window configurations,
diff --git a/lisp/gnus/gnus-win.el b/lisp/gnus/gnus-win.el
index e6906e99bb..c6a9832f30 100644
--- a/lisp/gnus/gnus-win.el
+++ b/lisp/gnus/gnus-win.el
@@ -39,6 +39,10 @@ gnus-use-full-window
   :group 'gnus-windows
   :type 'boolean)
 
+(defcustom gnus-use-atomic-windows t
+  "If non-nil, Gnus' window compositions will be atomic."
+  :type 'boolean)
+
 (defcustom gnus-window-min-width 2
   "Minimum width of Gnus buffers."
   :group 'gnus-windows
@@ -402,6 +406,15 @@ gnus-configure-windows
         (unless (gnus-buffer-live-p nntp-server-buffer)
           (nnheader-init-server-buffer))
 
+	;; Remove all 'window-atom parameters, as we're going to blast
+	;; and recreate the window layout.
+	(when (window-parameter nil 'window-atom)
+	  (let ((root (window-atom-root)))
+	    (walk-window-subtree
+	     (lambda (win)
+	       (set-window-parameter win 'window-atom nil))
+	     root t)))
+
         ;; Either remove all windows or just remove all Gnus windows.
         (let ((frame (selected-frame)))
           (unwind-protect
@@ -423,6 +436,13 @@ gnus-configure-windows
           (set-buffer nntp-server-buffer)
           (gnus-configure-frame split)
           (run-hooks 'gnus-configure-windows-hook)
+
+	  ;; If we're using atomic windows, and the current frame has
+	  ;; multiple windows, make them atomic.
+	  (when (and gnus-use-atomic-windows
+		     (window-parent (selected-window)))
+	    (window-make-atom (window-parent (selected-window))))
+
           (when gnus-window-frame-focus
             (select-frame-set-input-focus
              (window-frame gnus-window-frame-focus)))))))))
-- 
2.23.0