Improve logic of tab handling when quitting windows (bug#71386)
* lisp/window.el (window-deletable-p): Add tab logic that returns the symbol 'tab' for a set of predefined conditions. (window--delete): Call 'tab-bar-close-tab' when 'window-deletable-p' returns the symbol 'tab'. (quit-restore-window): Remove tab logic and merge it with frame logic. * test/lisp/tab-bar-tests.el (tab-bar-tests-close-other-tabs-default) (tab-bar-tests-close-other-tabs-with-arg): Clean up tabs afterwards. (tab-bar-tests-quit-restore-window): New test.
This commit is contained in:
parent
513a05dd87
commit
a97a61b630
2 changed files with 128 additions and 9 deletions
|
@ -4187,6 +4187,21 @@ returns nil."
|
|||
|
||||
(let ((frame (window-frame window)))
|
||||
(cond
|
||||
((and tab-bar-mode
|
||||
;; Fall back to frame handling in case of less than 2 tabs
|
||||
(> (length (funcall tab-bar-tabs-function frame)) 1)
|
||||
;; Close the tab with the initial window (bug#59862)
|
||||
(or (eq (nth 1 (window-parameter window 'quit-restore)) 'tab)
|
||||
;; or with the dedicated window (bug#71386)
|
||||
(and (window-dedicated-p window)
|
||||
(frame-root-window-p window)))
|
||||
;; Don't close the tab if more windows were created explicitly
|
||||
(< (seq-count (lambda (w)
|
||||
(memq (car (window-parameter w 'quit-restore))
|
||||
'(window tab frame same)))
|
||||
(window-list-1 nil 'nomini))
|
||||
2))
|
||||
'tab)
|
||||
((frame-root-window-p window)
|
||||
;; WINDOW's frame can be deleted only if there are other frames
|
||||
;; on the same terminal, and it does not contain the active
|
||||
|
@ -5022,6 +5037,10 @@ if WINDOW gets deleted or its frame is auto-hidden."
|
|||
(unless (and dedicated-only (not (window-dedicated-p window)))
|
||||
(let ((deletable (window-deletable-p window)))
|
||||
(cond
|
||||
((eq deletable 'tab)
|
||||
(tab-bar-close-tab)
|
||||
(message "Tab closed after deleting the last window")
|
||||
'tab)
|
||||
((eq deletable 'frame)
|
||||
(let ((frame (window-frame window)))
|
||||
(cond
|
||||
|
@ -5388,13 +5407,7 @@ elsewhere. This value is used by `quit-windows-on'."
|
|||
;; If the previously selected window is still alive, select it.
|
||||
(window--quit-restore-select-window quit-restore-2))
|
||||
((and (not prev-buffer)
|
||||
(eq (nth 1 quit-restore) 'tab)
|
||||
(eq (nth 3 quit-restore) buffer))
|
||||
(tab-bar-close-tab)
|
||||
;; If the previously selected window is still alive, select it.
|
||||
(window--quit-restore-select-window quit-restore-2))
|
||||
((and (not prev-buffer)
|
||||
(or (eq (nth 1 quit-restore) 'frame)
|
||||
(or (memq (nth 1 quit-restore) '(frame tab))
|
||||
(and (eq (nth 1 quit-restore) 'window)
|
||||
;; If the window has been created on an existing
|
||||
;; frame and ended up as the sole window on that
|
||||
|
|
|
@ -42,10 +42,116 @@
|
|||
(should (eq (length tab-bar-closed-tabs) 0)))
|
||||
|
||||
(ert-deftest tab-bar-tests-close-other-tabs-default ()
|
||||
(tab-bar-tests-close-other-tabs nil))
|
||||
(tab-bar-tests-close-other-tabs nil)
|
||||
;; Clean up tabs afterwards
|
||||
(tab-bar-tabs-set nil))
|
||||
|
||||
(ert-deftest tab-bar-tests-close-other-tabs-with-arg ()
|
||||
(dotimes (i 5) (tab-bar-tests-close-other-tabs i)))
|
||||
(dotimes (i 5) (tab-bar-tests-close-other-tabs i))
|
||||
;; Clean up tabs afterwards
|
||||
(tab-bar-tabs-set nil))
|
||||
|
||||
(ert-deftest tab-bar-tests-quit-restore-window ()
|
||||
(let* ((frame-params (when noninteractive
|
||||
'((window-system . nil)
|
||||
(tty-type . "linux"))))
|
||||
(pop-up-frame-alist frame-params)
|
||||
(frame-auto-hide-function 'delete-frame))
|
||||
|
||||
;; 1.1. 'quit-restore-window' should delete the frame
|
||||
;; from initial window (bug#59862)
|
||||
(progn
|
||||
(should (eq (length (frame-list)) 1))
|
||||
(other-frame-prefix)
|
||||
(info)
|
||||
(should (eq (length (frame-list)) 2))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(view-echo-area-messages)
|
||||
(other-window 1)
|
||||
(should (eq (length (window-list)) 2))
|
||||
(should (equal (buffer-name) "*Messages*"))
|
||||
(quit-window)
|
||||
(should (eq (length (window-list)) 1))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(quit-window)
|
||||
(should (eq (length (frame-list)) 1)))
|
||||
|
||||
;; 1.2. 'quit-restore-window' should not delete the frame
|
||||
;; from non-initial window (bug#59862)
|
||||
(progn
|
||||
(should (eq (length (frame-list)) 1))
|
||||
(other-frame-prefix)
|
||||
(info)
|
||||
(should (eq (length (frame-list)) 2))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(view-echo-area-messages)
|
||||
(should (eq (length (window-list)) 2))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(quit-window)
|
||||
(should (eq (length (window-list)) 1))
|
||||
(should (eq (length (frame-list)) 2))
|
||||
;; FIXME: uncomment (should (equal (buffer-name) "*Messages*"))
|
||||
(quit-window)
|
||||
(should (eq (length (frame-list)) 2))
|
||||
;; Clean up the frame afterwards
|
||||
(delete-frame))
|
||||
|
||||
;; 2.1. 'quit-restore-window' should close the tab
|
||||
;; from initial window (bug#59862)
|
||||
(progn
|
||||
(should (eq (length (tab-bar-tabs)) 1))
|
||||
(other-tab-prefix)
|
||||
(info)
|
||||
(should (eq (length (tab-bar-tabs)) 2))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(view-echo-area-messages)
|
||||
(other-window 1)
|
||||
(should (eq (length (window-list)) 2))
|
||||
(should (equal (buffer-name) "*Messages*"))
|
||||
(quit-window)
|
||||
(should (eq (length (window-list)) 1))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(quit-window)
|
||||
(should (eq (length (tab-bar-tabs)) 1)))
|
||||
|
||||
;; 2.2. 'quit-restore-window' should not close the tab
|
||||
;; from non-initial window (bug#59862)
|
||||
(progn
|
||||
(should (eq (length (tab-bar-tabs)) 1))
|
||||
(other-tab-prefix)
|
||||
(info)
|
||||
(should (eq (length (tab-bar-tabs)) 2))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(view-echo-area-messages)
|
||||
(should (eq (length (window-list)) 2))
|
||||
(should (equal (buffer-name) "*info*"))
|
||||
(quit-window)
|
||||
(should (eq (length (window-list)) 1))
|
||||
(should (eq (length (tab-bar-tabs)) 2))
|
||||
(should (equal (buffer-name) "*Messages*"))
|
||||
(quit-window)
|
||||
(should (eq (length (tab-bar-tabs)) 2))
|
||||
;; Clean up the tab afterwards
|
||||
(tab-close))
|
||||
|
||||
;; 3. Don't delete the frame with dedicated window
|
||||
;; from the second tab (bug#71386)
|
||||
(with-selected-frame (make-frame frame-params)
|
||||
(switch-to-buffer (generate-new-buffer "test1"))
|
||||
(tab-new)
|
||||
(switch-to-buffer (generate-new-buffer "test2"))
|
||||
(set-window-dedicated-p (selected-window) t)
|
||||
(kill-buffer)
|
||||
(should (eq (length (frame-list)) 2))
|
||||
(should (eq (length (tab-bar-tabs)) 1))
|
||||
;; But now should delete the frame with dedicated window
|
||||
;; from the last tab
|
||||
(set-window-dedicated-p (selected-window) t)
|
||||
(kill-buffer)
|
||||
(should (eq (length (frame-list)) 1)))
|
||||
|
||||
;; Clean up tabs afterwards
|
||||
(tab-bar-tabs-set nil)))
|
||||
|
||||
(provide 'tab-bar-tests)
|
||||
;;; tab-bar-tests.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue