diff --git a/modules/feature/popup/autoload.el b/modules/feature/popup/autoload.el index 1b7dfd191..f9d035fee 100644 --- a/modules/feature/popup/autoload.el +++ b/modules/feature/popup/autoload.el @@ -415,6 +415,94 @@ prevent the popup(s) from messing up the UI (or vice versa)." ;; Popup actions ;; +(when (version< emacs-version "26") + (defun window--sides-reverse-on-frame-p (frame) + "Return non-nil when side windows should appear reversed on FRAME. +This uses some heuristics to guess the user's intentions when the +selected window of FRAME is a side window ." + (cond + ;; Reverse when `window-sides-reversed' is t. Do not reverse when + ;; `window-sides-reversed' is nil. + ((memq window-sides-reversed '(nil t)) + window-sides-reversed) + ;; Reverse when FRAME's selected window shows a right-to-left buffer. + ((let ((window (frame-selected-window frame))) + (when (and (not (window-parameter window 'window-side)) + (or (not (window-minibuffer-p window)) + (setq window (minibuffer-selected-window)))) + (with-current-buffer (window-buffer window) + (eq bidi-paragraph-direction 'right-to-left))))) + ;; Reverse when FRAME's `window-sides-main-selected-window' parameter + ;; specifies a live window showing a right-to-left buffer. + ((let ((window (frame-parameter + frame 'window-sides-main-selected-window))) + (when (window-live-p window) + (with-current-buffer (window-buffer window) + (eq bidi-paragraph-direction 'right-to-left))))) + ;; Reverse when all windows in FRAME's main window show right-to-left + ;; buffers. + (t + (catch 'found + (walk-window-subtree + (lambda (window) + (with-current-buffer (window-buffer window) + (when (eq bidi-paragraph-direction 'left-to-right) + (throw 'found nil)))) + (window-main-window frame)) + t)))) + + (defun window--make-major-side-window (buffer side slot &optional alist) + "Display BUFFER in a new major side window on the selected frame. +SIDE must be one of `left', `top', `right' or `bottom'. SLOT +specifies the slot to use. ALIST is an association list of +symbols and values as passed to `display-buffer-in-side-window'. +Return the new window, nil if its creation failed. + +This is an auxiliary function of `display-buffer-in-side-window' +and may be called only if no window on SIDE exists yet." + (let* ((left-or-right (memq side '(left right))) + (next-to (window--make-major-side-window-next-to side)) + (on-side (cond + ((eq side 'top) 'above) + ((eq side 'bottom) 'below) + (t side))) + (window--sides-inhibit-check t) + ;; The following two bindings will tell `split-window' to take + ;; the space for the new window from the selected frame's main + ;; window and not make a new parent window unless needed. + (window-combination-resize 'side) + (window-combination-limit nil) + (window (split-window-no-error next-to nil on-side))) + (when window + ;; Initialize `window-side' parameter of new window to SIDE and + ;; make that parameter persistent. + (set-window-parameter window 'window-side side) + (add-to-list 'window-persistent-parameters '(window-side . writable)) + ;; Install `window-slot' parameter of new window and make that + ;; parameter persistent. + (set-window-parameter window 'window-slot slot) + (add-to-list 'window-persistent-parameters '(window-slot . writable)) + ;; Auto-adjust height/width of new window unless a size has been + ;; explicitly requested. + (unless (if left-or-right + (cdr (assq 'window-width alist)) + (cdr (assq 'window-height alist))) + (setq alist + (cons + (cons + (if left-or-right 'window-width 'window-height) + (/ (window-total-size (frame-root-window) left-or-right) + ;; By default use a fourth of the size of the frame's + ;; root window. + 4)) + alist))) + (with-current-buffer buffer + (setq window--sides-shown t)) + ;; Install BUFFER in new window and return WINDOW. + (window--display-buffer buffer window 'window alist 'side)))) + + (advice-add #'window--sides-check :override #'ignore)) + ;;;###autoload (defun +popup-display-buffer (buffer alist) "A `display-buffer' action that serves as an alternative to