summaryrefslogtreecommitdiff
path: root/lisp/window.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/window.el')
-rw-r--r--lisp/window.el108
1 files changed, 89 insertions, 19 deletions
diff --git a/lisp/window.el b/lisp/window.el
index e100f25526b..df55a7ca673 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -6174,6 +6174,12 @@ value can be also stored on disk and read back in a new session."
(defvar window-state-put-stale-windows nil
"Helper variable for `window-state-put'.")
+(defvar window-state-put-kept-windows nil
+ "Helper variable for `window-state-put'.")
+
+(defvar window-state-put-selected-window nil
+ "Helper variable for `window-state-put'.")
+
(defun window--state-put-1 (state &optional window ignore totals pixelwise)
"Helper function for `window-state-put'."
(let ((type (car state)))
@@ -6278,9 +6284,11 @@ value can be also stored on disk and read back in a new session."
(set-window-parameter window (car parameter) (cdr parameter))))
;; Process buffer related state.
(when state
- (let ((buffer (get-buffer (car state)))
- (state (cdr state)))
- (if buffer
+ (let* ((old-buffer-or-name (car state))
+ (buffer (get-buffer old-buffer-or-name))
+ (state (cdr state))
+ (dedicated (cdr (assq 'dedicated state))))
+ (if (buffer-live-p buffer)
(with-current-buffer buffer
(set-window-buffer window buffer)
(set-window-hscroll window (cdr (assq 'hscroll state)))
@@ -6338,7 +6346,7 @@ value can be also stored on disk and read back in a new session."
window delta t ignore nil nil nil pixelwise))
(window-resize window delta t ignore pixelwise))))
;; Set dedicated status.
- (set-window-dedicated-p window (cdr (assq 'dedicated state)))
+ (set-window-dedicated-p window dedicated)
;; Install positions (maybe we should do this after all
;; windows have been created and sized).
(ignore-errors
@@ -6348,7 +6356,18 @@ value can be also stored on disk and read back in a new session."
(set-window-point window (cdr (assq 'point state))))
;; Select window if it's the selected one.
(when (cdr (assq 'selected state))
- (select-window window))
+ ;; This used to call 'select-window' which, however,
+ ;; can be partially undone because the current buffer
+ ;; may subsequently change twice: When leaving the
+ ;; present 'with-current-buffer' and when leaving the
+ ;; containing 'with-temp-buffer' form (Bug#69093).
+ ;; 'window-state-put-selected-window' should now work
+ ;; around that bug but we leave this 'select-window'
+ ;; in since some code run before the part that fixed
+ ;; it might still refer to this window as the selected
+ ;; one.
+ (select-window window)
+ (setq window-state-put-selected-window window))
(set-window-next-buffers
window
(delq nil (mapcar (lambda (buffer)
@@ -6370,12 +6389,31 @@ value can be also stored on disk and read back in a new session."
(set-marker (make-marker) m2
buffer))))))
prev-buffers))))
- ;; We don't want to raise an error in case the buffer does
- ;; not exist anymore, so we switch to a previous one and
- ;; save the window with the intention of deleting it later
- ;; if possible.
- (switch-to-prev-buffer window)
- (push window window-state-put-stale-windows)))))))
+ (unless (window-minibuffer-p window)
+ ;; Preferably show a buffer previously shown in this
+ ;; window.
+ (switch-to-prev-buffer window)
+ (cond
+ ((functionp window-restore-killed-buffer-windows)
+ (let* ((start (cdr (assq 'start state)))
+ ;; Handle both - marker positions from writable
+ ;; states and markers from non-writable states.
+ (start-pos (if (markerp start)
+ (marker-last-position start)
+ start))
+ (point (cdr (assq 'point state)))
+ (point-pos (if (markerp point)
+ (marker-last-position point)
+ point)))
+ (push (list window old-buffer-or-name
+ start-pos point-pos dedicated nil)
+ window-state-put-kept-windows)))
+ ((or (and dedicated
+ (eq window-restore-killed-buffer-windows 'dedicated))
+ (memq window-restore-killed-buffer-windows '(nil delete)))
+ ;; Try to delete the window.
+ (push window window-state-put-stale-windows)))
+ (set-window-dedicated-p window nil))))))))
(defun window-state-put (state &optional window ignore)
"Put window state STATE into WINDOW.
@@ -6388,8 +6426,13 @@ If WINDOW is nil, create a new window before putting STATE into it.
Optional argument IGNORE non-nil means ignore minimum window
sizes and fixed size restrictions. IGNORE equal `safe' means
windows can get as small as `window-safe-min-height' and
-`window-safe-min-width'."
+`window-safe-min-width'.
+
+If this function tries to restore a non-minibuffer window whose buffer
+was killed since STATE was made, it will consult the variable
+`window-restore-killed-buffer-windows' on how to proceed."
(setq window-state-put-stale-windows nil)
+ (setq window-state-put-kept-windows nil)
;; When WINDOW is internal or nil, reduce it to a live one,
;; then create a new window on the same frame to put STATE into.
@@ -6482,6 +6525,7 @@ windows can get as small as `window-safe-min-height' and
(error "Window %s too small to accommodate state" window)
(setq state (cdr state))
(setq window-state-put-list nil)
+ (setq window-state-put-selected-window nil)
;; Work on the windows of a temporary buffer to make sure that
;; splitting proceeds regardless of any buffer local values of
;; `window-size-fixed'. Release that buffer after the buffers of
@@ -6490,14 +6534,20 @@ windows can get as small as `window-safe-min-height' and
(set-window-buffer window (current-buffer))
(window--state-put-1 state window nil totals pixelwise)
(window--state-put-2 ignore pixelwise))
+ (when (window-live-p window-state-put-selected-window)
+ (select-window window-state-put-selected-window))
(while window-state-put-stale-windows
(let ((window (pop window-state-put-stale-windows)))
- ;; Avoid that 'window-deletable-p' throws an error if window
+ ;; Avoid that 'window-deletable-p' throws an error if window
;; was already deleted when exiting 'with-temp-buffer' above
;; (Bug#54028).
(when (and (window-valid-p window)
(eq (window-deletable-p window) t))
(delete-window window))))
+ (when (functionp window-restore-killed-buffer-windows)
+ (funcall window-restore-killed-buffer-windows
+ frame window-state-put-kept-windows 'state)
+ (setq window-state-put-kept-windows nil))
(window--check frame))))
(defun window-state-buffers (state)
@@ -7798,6 +7848,14 @@ Action alist entries are:
and `preserve-size' are applied. The function is supposed
to fill the window body with some contents that might depend
on dimensions of the displayed window.
+ `post-command-select-window' -- A non-nil value means that after the
+ current command is executed and the hook `post-command-hook' is called,
+ the window displayed by this function will be selected. A nil value
+ means that if functions like `pop-to-buffer' selected another window,
+ at the end of this command that window will be deselected, and the
+ window that was selected before calling this function will remain
+ selected regardless of which windows were selected afterwards within
+ this command.
The entries `window-height', `window-width', `window-size' and
`preserve-size' are applied only when the window used for
@@ -7853,6 +7911,17 @@ specified by the ACTION argument."
(while (and functions (not window))
(setq window (funcall (car functions) buffer alist)
functions (cdr functions)))
+ (when-let ((select (assq 'post-command-select-window alist)))
+ (letrec ((old-selected-window (selected-window))
+ (postfun
+ (lambda ()
+ (if (cdr select)
+ (when (window-live-p window)
+ (select-window window))
+ (when (window-live-p old-selected-window)
+ (select-window old-selected-window)))
+ (remove-hook 'post-command-hook postfun))))
+ (add-hook 'post-command-hook postfun)))
(and (windowp window) window))))
(defun display-buffer-other-frame (buffer)
@@ -8599,14 +8668,14 @@ buffer. ALIST is a buffer display action alist as compiled by
use time is higher than this.
- `window-min-width' specifies a preferred minimum width in
- canonical frame columns. If it is the constant `full-width',
+ canonical frame columns. If it is the symbol `full-width',
prefer a full-width window.
- `window-min-height' specifies a preferred minimum height in
- canonical frame lines. If it is the constant `full-height',
+ canonical frame lines. If it is the symbol `full-height',
prefer a full-height window.
-If ALIST contains a non-nil `inhibit-same--window' entry, do not
+If ALIST contains a non-nil `inhibit-same-window' entry, do not
return the selected window."
(let ((windows
(window-list-1 nil 'nomini (cdr (assq 'lru-frames alist))))
@@ -8730,11 +8799,11 @@ Distinctive features are:
call.
`window-min-width' specifies a preferred minimum width in
- canonical frame columns. If it is the constant `full-width',
+ canonical frame columns. If it is the symbol `full-width',
prefer a full-width window.
`window-min-height' specifies a preferred minimum height in
- canonical frame lines. If it is the constant `full-height',
+ canonical frame lines. If it is the symbol `full-height',
prefer a full-height window.
- If the preceding steps fail, try to pop up a new window on the
@@ -10813,7 +10882,8 @@ Used in `repeat-mode'."
"^ f" #'tear-off-window
"^ t" #'tab-window-detach
"-" #'fit-window-to-buffer
- "0" #'delete-windows-on)
+ "0" #'delete-windows-on
+ "q" #'quit-window)
(define-key ctl-x-map "w" window-prefix-map)
(provide 'window)