Function: window-state-put
window-state-put is a byte-compiled function defined in window.el.gz.
Signature
(window-state-put STATE &optional WINDOW IGNORE)
Documentation
Put window state STATE into WINDOW.
STATE should be the state of a window returned by an earlier
invocation of window-state-get. Optional argument WINDOW must
specify a valid window. If WINDOW is not a live window,
replace WINDOW by a new live window created on the same frame.
If WINDOW is nil, create a new window before putting STATE into it.
Assign all window parameters that have been stored in STATE. By default, this is the `clone-of’ parameter provided STATE was obtained from an invocation of `window-state-get’ with WRITABLE nil.
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.
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.
Probably introduced at or before Emacs version 24.1.
Source Code
;; Defined in /usr/src/emacs/lisp/window.el.gz
(defun window-state-put (state &optional window ignore)
"Put window state STATE into WINDOW.
STATE should be the state of a window returned by an earlier
invocation of `window-state-get'. Optional argument WINDOW must
specify a valid window. If WINDOW is not a live window,
replace WINDOW by a new live window created on the same frame.
If WINDOW is nil, create a new window before putting STATE into it.
Assign all window parameters that have been stored in STATE. By
default, this is the `clone-of’ parameter provided STATE was obtained
from an invocation of `window-state-get’ with WRITABLE nil.
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'.
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.
(unless (window-live-p window)
(let ((root window))
(setq window (if root
(catch 'live
(walk-window-subtree
(lambda (window)
(when (and (window-live-p window)
(not (window-parameter
window 'window-side)))
(throw 'live window)))
root))
(selected-window)))
(delete-other-windows-internal window root)
;; Create a new window to replace the existing one.
(setq window (prog1 (split-window window window-safe-min-width t)
(delete-window window)))))
(set-window-dedicated-p window nil)
(let* ((frame (window-frame window))
(head (car state))
;; We check here (1) whether the total sizes of root window of
;; STATE and that of WINDOW are equal so we can avoid
;; calculating new sizes, and (2) if we do have to resize
;; whether we can do so without violating size restrictions.
(pixelwise (and (cdr (assq 'pixel-width state))
(cdr (assq 'pixel-height state))))
(totals (or (and pixelwise
(= (window-pixel-width window)
(cdr (assq 'pixel-width state)))
(= (window-pixel-height window)
(cdr (assq 'pixel-height state))))
(and (= (window-total-width window)
(cdr (assq 'total-width state)))
(= (window-total-height window)
(cdr (assq 'total-height state))))))
(min-height (cdr (assq
(if pixelwise 'min-pixel-height 'min-height)
head)))
(min-width (cdr (assq
(if pixelwise 'min-pixel-width 'min-width)
head)))
;; Bind the following two variables. `window--state-put-1' has
;; to fully control them (see Bug#50867 and Bug#64405).
window-combination-limit window-combination-resize)
(if (and (not totals)
(or (> min-height (window-size window nil pixelwise))
(> min-width (window-size window t pixelwise)))
(or (not ignore)
(and (setq min-height
(cdr (assq
(if pixelwise
'min-pixel-height-ignore
'min-height-ignore)
head)))
(setq min-width
(cdr (assq
(if pixelwise
'min-pixel-width-ignore
'min-width-ignore)
head)))
(or (> min-height
(window-size window nil pixelwise))
(> min-width
(window-size window t pixelwise)))
(or (not (eq ignore 'safe))
(and (setq min-height
(cdr (assq
(if pixelwise
'min-pixel-height-safe
'min-height-safe)
head)))
(setq min-width
(cdr (assq
(if pixelwise
'min-pixel-width-safe
'min-width-safe)
head)))
(or (> min-height
(window-size window nil pixelwise))
(> min-width
(window-size window t pixelwise))))))))
;; The check above might not catch all errors due to rounding
;; issues - so IGNORE equal 'safe might not always produce the
;; minimum possible state. But such configurations hardly make
;; sense anyway.
(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
;; all live windows have been set by `window--state-put-2'.
(with-temp-buffer
(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
;; 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))))