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.

View in manual

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))))