aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2012-08-22 11:22:08 +0200
committerMartin Rudalics2012-08-22 11:22:08 +0200
commitcaceae2529106eef4b5cc2b56c0cc6319ea7fcdf (patch)
tree245e4ba036063c23dc33b886d61346b47e114e5a
parent842e3a93aa3a0826cb4148376e54cd1527d10901 (diff)
downloademacs-caceae2529106eef4b5cc2b56c0cc6319ea7fcdf.tar.gz
emacs-caceae2529106eef4b5cc2b56c0cc6319ea7fcdf.zip
Rewrite handling of side and atomic windows.
* window.el (display-buffer-in-atom-window, window--major-non-side-window) (window--major-side-window, display-buffer-in-major-side-window) (delete-side-window, display-buffer-in-side-window): New functions. (window--side-check, window-deletable-p, delete-window) (delete-other-windows, split-window): Handle side windows and atomic windows appropriately. (window--display-buffer): Call display-buffer-record-window also when the window buffer did not change.
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/window.el485
2 files changed, 409 insertions, 85 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4296280b22e..f8ed5ce15fd 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -7,6 +7,15 @@
7 (window-in-direction): Simplify and rewrite doc-string. 7 (window-in-direction): Simplify and rewrite doc-string.
8 (window--size-ignore): Rename to window--size-ignore-p. Update 8 (window--size-ignore): Rename to window--size-ignore-p. Update
9 callers. 9 callers.
10 (display-buffer-in-atom-window, window--major-non-side-window)
11 (window--major-side-window, display-buffer-in-major-side-window)
12 (delete-side-window, display-buffer-in-side-window): New
13 functions.
14 (window--side-check, window-deletable-p, delete-window)
15 (delete-other-windows, split-window): Handle side windows and
16 atomic windows appropriately.
17 (window--display-buffer): Call display-buffer-record-window also
18 when the window buffer did not change.
10 19
112012-08-22 Christopher Schmidt <christopher@ch.ristopher.com> 202012-08-22 Christopher Schmidt <christopher@ch.ristopher.com>
12 21
diff --git a/lisp/window.el b/lisp/window.el
index ab90d8a4bde..8f402f0c2b9 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -357,6 +357,45 @@ WINDOW must be an internal window. Return WINDOW."
357 window t) 357 window t)
358 window)) 358 window))
359 359
360(defun display-buffer-in-atom-window (buffer alist)
361 "Display BUFFER in an atomic window.
362This function displays BUFFER in a new window that will be
363combined with an existing window to form an atomic window. If
364the existing window is already part of an atomic window, add the
365new window to that atomic window. Operations like `split-window'
366or `delete-window', when applied to a constituent of an atomic
367window, are applied atomically to the root of that atomic window.
368
369ALIST is an association list of symbols and values. The
370following symbols can be used.
371
372`window' specifies the existing window the new window shall be
373 combined with. Use `window-atom-root' to make the new window a
374 sibling of an atomic window's root. If an internal window is
375 specified here, all children of that window become part of the
376 atomic window too. If no window is specified, the new window
377 becomes a sibling of the selected window.
378
379`side' denotes the side of the existing window where the new
380 window shall be located. Valid values are `below', `right',
381 `above' and `left'. The default is `below'.
382
383The return value is the new window, nil when creating that window
384failed."
385 (let ((ignore-window-parameters t)
386 (window-combination-limit t)
387 (window (cdr (assq 'window alist)))
388 (side (cdr (assq 'side alist)))
389 new)
390 (setq window (window-normalize-window window))
391 ;; Split off new window
392 (when (setq new (split-window window nil side))
393 ;; Make sure we have a valid atomic window.
394 (window-make-atom (window-parent window))
395 ;; Display BUFFER in NEW and return NEW.
396 (window--display-buffer
397 buffer new 'window display-buffer-mark-dedicated))))
398
360(defun window--atom-check-1 (window) 399(defun window--atom-check-1 (window)
361 "Subroutine of `window--atom-check'." 400 "Subroutine of `window--atom-check'."
362 (when window 401 (when window
@@ -446,23 +485,273 @@ number of slots on that side."
446 (integer :tag "Number" :value 3 :size 5))) 485 (integer :tag "Number" :value 3 :size 5)))
447 :group 'windows) 486 :group 'windows)
448 487
488(defun window--major-non-side-window (&optional frame)
489 "Return the major non-side window of frame FRAME.
490The optional argument FRAME must be a live frame and defaults to
491the selected one.
492
493If FRAME has at least one side window, the major non-side window
494is either an internal non-side window such that all other
495non-side windows on FRAME descend from it, or the single live
496non-side window of FRAME. If FRAME has no side windows, return
497its root window."
498 (let ((frame (window-normalize-frame frame))
499 major sibling)
500 ;; Set major to the _last_ window found by `walk-window-tree' that
501 ;; is not a side window but has a side window as its sibling.
502 (walk-window-tree
503 (lambda (window)
504 (and (not (window-parameter window 'window-side))
505 (or (and (setq sibling (window-prev-sibling window))
506 (window-parameter sibling 'window-side))
507 (and (setq sibling (window-next-sibling window))
508 (window-parameter sibling 'window-side)))
509 (setq major window)))
510 frame t)
511 (or major (frame-root-window frame))))
512
513(defun window--major-side-window (side)
514 "Return major side window on SIDE.
515SIDE must be one of the symbols `left', `top', `right' or
516`bottom'. Return nil if no such window exists."
517 (let ((root (frame-root-window))
518 window)
519 ;; (1) If a window on the opposite side exists, return that window's
520 ;; sibling.
521 ;; (2) If the new window shall span the entire side, return the
522 ;; frame's root window.
523 ;; (3) If a window on an orthogonal side exists, return that
524 ;; window's sibling.
525 ;; (4) Otherwise return the frame's root window.
526 (cond
527 ((or (and (eq side 'left)
528 (setq window (window-with-parameter 'window-side 'right nil t)))
529 (and (eq side 'top)
530 (setq window (window-with-parameter 'window-side 'bottom nil t))))
531 (window-prev-sibling window))
532 ((or (and (eq side 'right)
533 (setq window (window-with-parameter 'window-side 'left nil t)))
534 (and (eq side 'bottom)
535 (setq window (window-with-parameter 'window-side 'top nil t))))
536 (window-next-sibling window))
537 ((memq side '(left right))
538 (cond
539 (window-sides-vertical
540 root)
541 ((setq window (window-with-parameter 'window-side 'top nil t))
542 (window-next-sibling window))
543 ((setq window (window-with-parameter 'window-side 'bottom nil t))
544 (window-prev-sibling window))
545 (t root)))
546 ((memq side '(top bottom))
547 (cond
548 ((not window-sides-vertical)
549 root)
550 ((setq window (window-with-parameter 'window-side 'left nil t))
551 (window-next-sibling window))
552 ((setq window (window-with-parameter 'window-side 'right nil t))
553 (window-prev-sibling window))
554 (t root))))))
555
556(defun display-buffer-in-major-side-window (buffer side slot &optional alist)
557 "Display BUFFER in a new window on SIDE of the selected frame.
558SIDE must be one of `left', `top', `right' or `bottom'. SLOT
559specifies the slot to use. ALIST is an association list of
560symbols and values as passed to `display-buffer-in-side-window'.
561This function may be called only if no window on SIDE exists yet.
562The new window automatically becomes the \"major\" side window on
563SIDE. Return the new window, nil if its creation window failed."
564 (let* ((root (frame-root-window))
565 (left-or-right (memq side '(left right)))
566 (size (or (assq 'size alist)
567 (/ (window-total-size (frame-root-window) left-or-right)
568 ;; By default use a fourth of the size of the
569 ;; frame's root window. This has to be made
570 ;; customizable via ALIST.
571 4)))
572 (major (window--major-side-window side))
573 (selected-window (selected-window))
574 (on-side (cond
575 ((eq side 'top) 'above)
576 ((eq side 'bottom) 'below)
577 (t side)))
578 ;; The following two bindings will tell `split-window' to take
579 ;; the space for the new window from `major' and not make a new
580 ;; parent window unless needed.
581 (window-combination-resize 'side)
582 (window-combination-limit nil)
583 (new (split-window major (- size) on-side))
584 fun)
585 (when new
586 ;; Initialize `window-side' parameter of new window to SIDE.
587 (set-window-parameter new 'window-side side)
588 ;; Install `window-slot' parameter of new window.
589 (set-window-parameter new 'window-slot slot)
590 ;; Install `delete-window' parameter thus making sure that when
591 ;; the new window is deleted, a side window on the opposite side
592 ;; does not get resized.
593 (set-window-parameter new 'delete-window 'delete-side-window)
594 ;; Install BUFFER in new window and return NEW.
595 (window--display-buffer buffer new 'window 'side))))
596
597(defun delete-side-window (window)
598 "Delete side window WINDOW."
599 (let ((window-combination-resize
600 (window-parameter (window-parent window) 'window-side))
601 (ignore-window-parameters t))
602 (delete-window window)))
603
604(defun display-buffer-in-side-window (buffer alist)
605 "Display BUFFER in a window on side SIDE of the selected frame.
606ALIST is an association list of symbols and values. The
607following symbols can be used:
608
609`side' denotes the side of the existing window where the new
610 window shall be located. Valid values are `bottom', `right',
611 `top' and `left'. The default is `bottom'.
612
613`slot' if non-nil, specifies the window slot where to display
614 BUFFER. A value of zero or nil means use the middle slot on
615 the specified side. A negative value means use a slot
616 preceding (that is, above or on the left of) the middle slot.
617 A positive value means use a slot following (that is, below or
618 on the right of) the middle slot. The default is zero."
619 (let ((side (or (cdr (assq 'side alist)) 'bottom))
620 (slot (or (cdr (assq 'slot alist)) 0))
621 new)
622 (cond
623 ((not (memq side '(top bottom left right)))
624 (error "Invalid side %s specified" side))
625 ((not (numberp slot))
626 (error "Invalid slot %s specified" slot)))
627
628 (let* ((major (window-with-parameter 'window-side side nil t))
629 ;; `major' is the major window on SIDE, `windows' the list of
630 ;; life windows on SIDE.
631 (windows
632 (when major
633 (let (windows)
634 (walk-window-tree
635 (lambda (window)
636 (when (eq (window-parameter window 'window-side) side)
637 (setq windows (cons window windows)))))
638 (nreverse windows))))
639 (slots (when major (max 1 (window-child-count major))))
640 (max-slots
641 (nth (cond
642 ((eq side 'left) 0)
643 ((eq side 'top) 1)
644 ((eq side 'right) 2)
645 ((eq side 'bottom) 3))
646 window-sides-slots))
647 (selected-window (selected-window))
648 window this-window this-slot prev-window next-window
649 best-window best-slot abs-slot new-window)
650
651 (cond
652 ((and (numberp max-slots) (<= max-slots 0))
653 ;; No side-slots available on this side. Don't create an error,
654 ;; just return nil.
655 nil)
656 ((not windows)
657 ;; No major window exists on this side, make one.
658 (display-buffer-in-major-side-window buffer side slot alist))
659 (t
660 ;; Scan windows on SIDE.
661 (catch 'found
662 (dolist (window windows)
663 (setq this-slot (window-parameter window 'window-slot))
664 (cond
665 ;; The following should not happen and probably be checked
666 ;; by window--side-check.
667 ((not (numberp this-slot)))
668 ((= this-slot slot)
669 ;; A window with a matching slot has been found.
670 (setq this-window window)
671 (throw 'found t))
672 (t
673 ;; Check if this window has a better slot value wrt the
674 ;; slot of the window we want.
675 (setq abs-slot
676 (if (or (and (> this-slot 0) (> slot 0))
677 (and (< this-slot 0) (< slot 0)))
678 (abs (- slot this-slot))
679 (+ (abs slot) (abs this-slot))))
680 (unless (and best-slot (<= best-slot abs-slot))
681 (setq best-window window)
682 (setq best-slot abs-slot))
683 (cond
684 ((<= this-slot slot)
685 (setq prev-window window))
686 ((not next-window)
687 (setq next-window window)))))))
688
689 ;; `this-window' is the first window with the same SLOT.
690 ;; `prev-window' is the window with the largest slot < SLOT. A new
691 ;; window will be created after it.
692 ;; `next-window' is the window with the smallest slot > SLOT. A new
693 ;; window will be created before it.
694 ;; `best-window' is the window with the smallest absolute difference
695 ;; of its slot and SLOT.
696
697 ;; Note: We dedicate the window used softly to its buffer to
698 ;; avoid that "other" (non-side) buffer display functions steal
699 ;; it from us. This must eventually become customizable via
700 ;; ALIST (or, better, avoided in the "other" functions).
701 (or (and this-window
702 ;; Reuse `this-window'.
703 (window--display-buffer buffer this-window 'reuse 'side))
704 (and (or (not max-slots) (< slots max-slots))
705 (or (and next-window
706 ;; Make new window before `next-window'.
707 (let ((next-side
708 (if (memq side '(left right)) 'above 'left))
709 (window-combination-resize 'side))
710 (setq window (split-window next-window nil next-side))
711 ;; When the new window is deleted, its space
712 ;; is returned to other side windows.
713 (set-window-parameter
714 window 'delete-window 'delete-side-window)
715 window))
716 (and prev-window
717 ;; Make new window after `prev-window'.
718 (let ((prev-side
719 (if (memq side '(left right)) 'below 'right))
720 (window-combination-resize 'side))
721 (setq window (split-window prev-window nil prev-side))
722 ;; When the new window is deleted, its space
723 ;; is returned to other side windows.
724 (set-window-parameter
725 window 'delete-window 'delete-side-window)
726 window)))
727 (set-window-parameter window 'window-slot slot)
728 (window--display-buffer buffer window 'window 'side))
729 (and best-window
730 ;; Reuse `best-window'.
731 (progn
732 ;; Give best-window the new slot value.
733 (set-window-parameter best-window 'window-slot slot)
734 (window--display-buffer buffer best-window 'reuse 'side)))))))))
735
449(defun window--side-check (&optional frame) 736(defun window--side-check (&optional frame)
450 "Check the window-side parameter of all windows on FRAME. 737 "Check the side window configuration of FRAME.
451FRAME defaults to the selected frame. If the configuration is 738FRAME defaults to the selected frame.
452invalid, reset all window-side parameters to nil. 739
453 740A valid side window configuration preserves the following two
454A valid configuration has to preserve the following invariant: 741invariants:
455 742
456- If a window has a non-nil window-side parameter, it must have a 743- If there exists a window whose window-side parameter is
457 parent window and the parent window's window-side parameter 744 non-nil, there must exist at least one live window whose
458 must be either nil or the same as for window. 745 window-side parameter is nil.
459 746
460- If windows with non-nil window-side parameters exist, there 747- If a window W has a non-nil window-side parameter (i) it must
461 must be at most one window of each side and non-side with a 748 have a parent window and that parent's window-side parameter
462 parent whose window-side parameter is nil and there must be no 749 must be either nil or the same as for W, and (ii) any child
463 leaf window whose window-side parameter is nil." 750 window of W must have the same window-side parameter as W.
464 (let (normal none left top right bottom 751
465 side parent parent-side) 752If the configuration is invalid, reset the window-side parameters
753of all windows on FRAME to nil."
754 (let (left top right bottom none side parent parent-side)
466 (when (or (catch 'reset 755 (when (or (catch 'reset
467 (walk-window-tree 756 (walk-window-tree
468 (lambda (window) 757 (lambda (window)
@@ -478,40 +767,34 @@ A valid configuration has to preserve the following invariant:
478 ;; A parent whose window-side is non-nil must 767 ;; A parent whose window-side is non-nil must
479 ;; have a child with the same window-side. 768 ;; have a child with the same window-side.
480 (throw 'reset t))) 769 (throw 'reset t)))
481 ;; Now check that there's more than one main window 770 ((not side)
482 ;; for any of none, left, top, right and bottom. 771 (when (window-buffer window)
483 ((eq side 'none) 772 ;; Record that we have at least one non-side,
484 (if none 773 ;; live window.
485 (throw 'reset t)
486 (setq none t))) 774 (setq none t)))
775 ((if (memq side '(left top))
776 (window-prev-sibling window)
777 (window-next-sibling window))
778 ;; Left and top major side windows must not have a
779 ;; previous sibling, right and bottom major side
780 ;; windows must not have a next sibling.
781 (throw 'reset t))
782 ;; Now check that there's no more than one major
783 ;; window for any of left, top, right and bottom.
487 ((eq side 'left) 784 ((eq side 'left)
488 (if left 785 (if left (throw 'reset t) (setq left t)))
489 (throw 'reset t)
490 (setq left t)))
491 ((eq side 'top) 786 ((eq side 'top)
492 (if top 787 (if top (throw 'reset t) (setq top t)))
493 (throw 'reset t)
494 (setq top t)))
495 ((eq side 'right) 788 ((eq side 'right)
496 (if right 789 (if right (throw 'reset t) (setq right t)))
497 (throw 'reset t)
498 (setq right t)))
499 ((eq side 'bottom) 790 ((eq side 'bottom)
500 (if bottom 791 (if bottom (throw 'reset t) (setq bottom t)))
501 (throw 'reset t) 792 (t
502 (setq bottom t))) 793 (throw 'reset t))))
503 ((window-buffer window)
504 ;; A leaf window without window-side parameter,
505 ;; record its existence.
506 (setq normal t))))
507 frame t)) 794 frame t))
508 (if none 795 ;; If there's a side window, there must be at least one
509 ;; At least one non-side window exists, so there must 796 ;; non-side window.
510 ;; be at least one side-window and no normal window. 797 (and (or left top right bottom) (not none)))
511 (or (not (or left top right bottom)) normal)
512 ;; No non-side window exists, so there must be no side
513 ;; window either.
514 (or left top right bottom)))
515 (walk-window-tree 798 (walk-window-tree
516 (lambda (window) 799 (lambda (window)
517 (set-window-parameter window 'window-side nil)) 800 (set-window-parameter window 'window-side nil))
@@ -2393,8 +2676,7 @@ Return `frame' if deleting WINDOW should also delete its frame."
2393 (when (window-parameter window 'window-atom) 2676 (when (window-parameter window 'window-atom)
2394 (setq window (window-atom-root window)))) 2677 (setq window (window-atom-root window))))
2395 2678
2396 (let ((parent (window-parent window)) 2679 (let ((frame (window-frame window)))
2397 (frame (window-frame window)))
2398 (cond 2680 (cond
2399 ((frame-root-window-p window) 2681 ((frame-root-window-p window)
2400 ;; WINDOW's frame can be deleted only if there are other frames 2682 ;; WINDOW's frame can be deleted only if there are other frames
@@ -2405,10 +2687,9 @@ Return `frame' if deleting WINDOW should also delete its frame."
2405 (and minibuf (eq frame (window-frame minibuf))))) 2687 (and minibuf (eq frame (window-frame minibuf)))))
2406 'frame)) 2688 'frame))
2407 ((or ignore-window-parameters 2689 ((or ignore-window-parameters
2408 (not (eq (window-parameter window 'window-side) 'none)) 2690 (not (eq window (window--major-non-side-window frame))))
2409 (and parent (eq (window-parameter parent 'window-side) 'none))) 2691 ;; WINDOW can be deleted unless it is the major non-side window of
2410 ;; WINDOW can be deleted unless it is the main window of its 2692 ;; its frame.
2411 ;; frame.
2412 t)))) 2693 t))))
2413 2694
2414(defun window--in-subtree-p (window root) 2695(defun window--in-subtree-p (window root)
@@ -2459,13 +2740,13 @@ that is its frame's root window."
2459 ((and (window-parameter window 'window-atom) 2740 ((and (window-parameter window 'window-atom)
2460 (setq atom-root (window-atom-root window)) 2741 (setq atom-root (window-atom-root window))
2461 (not (eq atom-root window))) 2742 (not (eq atom-root window)))
2462 (throw 'done (delete-window atom-root))) 2743 (if (eq atom-root (frame-root-window frame))
2463 ((and (eq (window-parameter window 'window-side) 'none) 2744 (error "Root of atomic window is root window of its frame")
2464 (or (not parent) 2745 (throw 'done (delete-window atom-root))))
2465 (not (eq (window-parameter parent 'window-side) 'none))))
2466 (error "Attempt to delete last non-side window"))
2467 ((not parent) 2746 ((not parent)
2468 (error "Attempt to delete minibuffer or sole ordinary window"))) 2747 (error "Attempt to delete minibuffer or sole ordinary window"))
2748 ((eq window (window--major-non-side-window frame))
2749 (error "Attempt to delete last non-side window")))
2469 2750
2470 (let* ((horizontal (window-left-child parent)) 2751 (let* ((horizontal (window-left-child parent))
2471 (size (window-total-size window horizontal)) 2752 (size (window-total-size window horizontal))
@@ -2539,13 +2820,19 @@ window signal an error."
2539 ((and (window-parameter window 'window-atom) 2820 ((and (window-parameter window 'window-atom)
2540 (setq atom-root (window-atom-root window)) 2821 (setq atom-root (window-atom-root window))
2541 (not (eq atom-root window))) 2822 (not (eq atom-root window)))
2542 (throw 'done (delete-other-windows atom-root))) 2823 (if (eq atom-root (frame-root-window frame))
2543 ((eq window-side 'none) 2824 (error "Root of atomic window is root window of its frame")
2544 ;; Set side-main to the major non-side window. 2825 (throw 'done (delete-other-windows atom-root))))
2545 (setq side-main (window-with-parameter 'window-side 'none frame t)))
2546 ((memq window-side window-sides) 2826 ((memq window-side window-sides)
2547 (error "Cannot make side window the only window"))) 2827 (error "Cannot make side window the only window"))
2548 ;; If WINDOW is the main non-side window, do nothing. 2828 ((and (window-minibuffer-p window)
2829 (not (eq window (frame-root-window window))))
2830 (error "Can't expand minibuffer to full frame")))
2831
2832 ;; If WINDOW is the major non-side window, do nothing.
2833 (if (window-with-parameter 'window-side)
2834 (setq side-main (window--major-non-side-window frame))
2835 (setq side-main (frame-root-window frame)))
2549 (unless (eq window side-main) 2836 (unless (eq window side-main)
2550 (delete-other-windows-internal window side-main) 2837 (delete-other-windows-internal window side-main)
2551 (run-window-configuration-change-hook frame) 2838 (run-window-configuration-change-hook frame)
@@ -3204,14 +3491,16 @@ frame. The selected window is not changed by this function."
3204 ((not side) 'below) 3491 ((not side) 'below)
3205 ((memq side '(below above right left)) side) 3492 ((memq side '(below above right left)) side)
3206 (t 'right))) 3493 (t 'right)))
3207 (horizontal (not (memq side '(nil below above)))) 3494 (horizontal (not (memq side '(below above))))
3208 (frame (window-frame window)) 3495 (frame (window-frame window))
3209 (parent (window-parent window)) 3496 (parent (window-parent window))
3210 (function (window-parameter window 'split-window)) 3497 (function (window-parameter window 'split-window))
3211 (window-side (window-parameter window 'window-side)) 3498 (window-side (window-parameter window 'window-side))
3212 ;; Rebind `window-combination-limit' since in some cases we may 3499 ;; Rebind `window-combination-limit' and
3213 ;; have to override its value. 3500 ;; `window-combination-resize' since in some cases we may have
3501 ;; to override their value.
3214 (window-combination-limit window-combination-limit) 3502 (window-combination-limit window-combination-limit)
3503 (window-combination-resize window-combination-resize)
3215 atom-root) 3504 atom-root)
3216 3505
3217 (window--check frame) 3506 (window--check frame)
@@ -3229,20 +3518,32 @@ frame. The selected window is not changed by this function."
3229 ((and (window-parameter window 'window-atom) 3518 ((and (window-parameter window 'window-atom)
3230 (setq atom-root (window-atom-root window)) 3519 (setq atom-root (window-atom-root window))
3231 (not (eq atom-root window))) 3520 (not (eq atom-root window)))
3232 (throw 'done (split-window atom-root size side)))) 3521 (throw 'done (split-window atom-root size side)))
3233 3522 ;; If WINDOW is a side window or its first or last child is a
3234 (when (and window-side 3523 ;; side window, throw an error unless `window-combination-resize'
3235 (or (not parent) 3524 ;; equals 'side.
3236 (not (window-parameter parent 'window-side)))) 3525 ((and (not (eq window-combination-resize 'side))
3237 ;; WINDOW is a side root window. To make sure that a new parent 3526 (or (window-parameter window 'window-side)
3238 ;; window gets created set `window-combination-limit' to t. 3527 (and (window-child window)
3239 (setq window-combination-limit t)) 3528 (or (window-parameter
3240 3529 (window-child window) 'window-side)
3241 (when (and window-combination-resize size (> size 0)) 3530 (window-parameter
3242 ;; If `window-combination-resize' is non-nil and SIZE is a 3531 (window-last-child window) 'window-side)))))
3243 ;; non-negative integer, we cannot reasonably resize other 3532 (error "Cannot split side window or parent of side window"))
3244 ;; windows. Rather bind `window-combination-limit' to t to make 3533 ;; If `window-combination-resize' is 'side and window has a side
3245 ;; sure that subsequent window deletions are handled correctly. 3534 ;; window sibling, bind `window-combination-limit' to t.
3535 ((and (not (eq window-combination-resize 'side))
3536 (or (and (window-prev-sibling window)
3537 (window-parameter
3538 (window-prev-sibling window) 'window-side))
3539 (and (window-next-sibling window)
3540 (window-parameter
3541 (window-next-sibling window) 'window-side))))
3542 (setq window-combination-limit t)))
3543
3544 ;; If `window-combination-resize' is t and SIZE is non-negative,
3545 ;; bind `window-combination-limit' to t.
3546 (when (and (eq window-combination-resize t) size (> size 0))
3246 (setq window-combination-limit t)) 3547 (setq window-combination-limit t))
3247 3548
3248 (let* ((parent-size 3549 (let* ((parent-size
@@ -3252,7 +3553,10 @@ frame. The selected window is not changed by this function."
3252 ;; `resize' non-nil means we are supposed to resize other 3553 ;; `resize' non-nil means we are supposed to resize other
3253 ;; windows in WINDOW's combination. 3554 ;; windows in WINDOW's combination.
3254 (resize 3555 (resize
3255 (and window-combination-resize (not window-combination-limit) 3556 (and window-combination-resize
3557 (or (window-parameter window 'window-side)
3558 (not (eq window-combination-resize 'side)))
3559 (not window-combination-limit)
3256 ;; Resize makes sense in iso-combinations only. 3560 ;; Resize makes sense in iso-combinations only.
3257 (window-combined-p window horizontal))) 3561 (window-combined-p window horizontal)))
3258 ;; `old-size' is the current size of WINDOW. 3562 ;; `old-size' is the current size of WINDOW.
@@ -3363,10 +3667,21 @@ frame. The selected window is not changed by this function."
3363 new-normal))) 3667 new-normal)))
3364 3668
3365 (let* ((new (split-window-internal window new-size side new-normal))) 3669 (let* ((new (split-window-internal window new-size side new-normal)))
3366 ;; Inherit window-side parameters, if any. 3670 ;; Assign window-side parameters, if any.
3367 (when (and window-side new-parent) 3671 (when (eq window-combination-resize 'side)
3368 (set-window-parameter (window-parent new) 'window-side window-side) 3672 (let ((window-side
3369 (set-window-parameter new 'window-side window-side)) 3673 (cond
3674 (window-side window-side)
3675 ((eq side 'above) 'top)
3676 ((eq side 'below) 'bottom)
3677 (t side))))
3678 ;; We made a new side window.
3679 (set-window-parameter new 'window-side window-side)
3680 (when (and new-parent (window-parameter window 'window-side))
3681 ;; We've been splitting a side root window. Give the
3682 ;; new parent the same window-side parameter.
3683 (set-window-parameter
3684 (window-parent new) 'window-side window-side))))
3370 3685
3371 (run-window-configuration-change-hook frame) 3686 (run-window-configuration-change-hook frame)
3372 (window--check frame) 3687 (window--check frame)
@@ -4621,9 +4936,9 @@ is passed unaltered to `display-buffer-record-window'. Set
4621`window-dedicated-p' to DEDICATED if non-nil. Return WINDOW if 4936`window-dedicated-p' to DEDICATED if non-nil. Return WINDOW if
4622BUFFER and WINDOW are live." 4937BUFFER and WINDOW are live."
4623 (when (and (buffer-live-p buffer) (window-live-p window)) 4938 (when (and (buffer-live-p buffer) (window-live-p window))
4939 (display-buffer-record-window type window buffer)
4624 (unless (eq buffer (window-buffer window)) 4940 (unless (eq buffer (window-buffer window))
4625 (set-window-dedicated-p window nil) 4941 (set-window-dedicated-p window nil)
4626 (display-buffer-record-window type window buffer)
4627 (set-window-buffer window buffer) 4942 (set-window-buffer window buffer)
4628 (when dedicated 4943 (when dedicated
4629 (set-window-dedicated-p window dedicated)) 4944 (set-window-dedicated-p window dedicated))