all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
@ 2024-06-05 23:44 Al Haji-Ali
  2024-06-06  5:45 ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-05 23:44 UTC (permalink / raw)
  To: 71386


If I open a frame with multiple tabs, and one of the tabs has a dedicated window, then kill the buffer with the dedicated window, the frame is deleted along with its tabs.

I understand that this is the documented behaviour, however my expectation is that the tab should be deleted but the frame should stay when other tabs are available, similar to how the frame is not deleted if other windows are visible.

The following code illustrates the issue:

,----
| (with-selected-frame (make-frame)
|     (tab-bar-mode)
|     (switch-to-buffer (generate-new-buffer "test"))
|     (tab-bar-new-tab)
|     (switch-to-buffer (generate-new-buffer "test2"))
|     (set-window-dedicated-p (selected-window) t)
|     ;;(kill-buffer)  ;; Kill buffer manually to see the issue
| )
`----

I am unable to test this on Emacs 30, but I checked the source code and `window--delete` in `window.el`, which is the function that I think should be changed, seems to do the same as in Emacs 29.1.

-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-05 23:44 bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs Al Haji-Ali
@ 2024-06-06  5:45 ` Eli Zaretskii
  2024-06-06  6:12   ` Juri Linkov
  2024-06-06  9:19   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 44+ messages in thread
From: Eli Zaretskii @ 2024-06-06  5:45 UTC (permalink / raw)
  To: Al Haji-Ali, Juri Linkov, martin rudalics; +Cc: 71386

> From: Al Haji-Ali <abdo.haji.ali@gmail.com>
> Date: Thu, 06 Jun 2024 00:44:28 +0100
> 
> 
> If I open a frame with multiple tabs, and one of the tabs has a dedicated window, then kill the buffer with the dedicated window, the frame is deleted along with its tabs.
> 
> I understand that this is the documented behaviour, however my expectation is that the tab should be deleted but the frame should stay when other tabs are available, similar to how the frame is not deleted if other windows are visible.

I'm not sure I agree with you.  Tabs are just saved frame
configurations, they are not real windows.  If we make this behavior
dependent on tab-bar-mode, we basically introduce an incompatible
behavior change in this particular case, which people and Lisp
programs out there might not expect or like.

I'm adding Juri and Martin to this discussion.

> The following code illustrates the issue:
> 
> ,----
> | (with-selected-frame (make-frame)
> |     (tab-bar-mode)
> |     (switch-to-buffer (generate-new-buffer "test"))
> |     (tab-bar-new-tab)
> |     (switch-to-buffer (generate-new-buffer "test2"))
> |     (set-window-dedicated-p (selected-window) t)
> |     ;;(kill-buffer)  ;; Kill buffer manually to see the issue
> | )
> `----
> 
> I am unable to test this on Emacs 30, but I checked the source code and `window--delete` in `window.el`, which is the function that I think should be changed, seems to do the same as in Emacs 29.1.

Emacs 30 behaves the same in this regard.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-06  5:45 ` Eli Zaretskii
@ 2024-06-06  6:12   ` Juri Linkov
  2024-06-06  9:20     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-06 10:10     ` Eli Zaretskii
  2024-06-06  9:19   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 2 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-06  6:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: martin rudalics, Al Haji-Ali, 71386

>> If I open a frame with multiple tabs, and one of the tabs has
>> a dedicated window, then kill the buffer with the dedicated window,
>> the frame is deleted along with its tabs.
>> 
>> I understand that this is the documented behaviour, however my
>> expectation is that the tab should be deleted but the frame should
>> stay when other tabs are available, similar to how the frame is not
>> deleted if other windows are visible.
>
> I'm not sure I agree with you.  Tabs are just saved frame
> configurations, they are not real windows.  If we make this behavior
> dependent on tab-bar-mode, we basically introduce an incompatible
> behavior change in this particular case, which people and Lisp
> programs out there might not expect or like.
>
> I'm adding Juri and Martin to this discussion.

I don't understand the logic of window--delete.  But maybe
window-deletable-p should also check for existing tabs in tab-bar-mode
and return 'tab' instead of 'frame'.  Then window--delete
could close the tab instead of deleting the frame.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-06  5:45 ` Eli Zaretskii
  2024-06-06  6:12   ` Juri Linkov
@ 2024-06-06  9:19   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-07  6:39     ` Juri Linkov
  1 sibling, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-06  9:19 UTC (permalink / raw)
  To: Eli Zaretskii, Al Haji-Ali, Juri Linkov; +Cc: 71386

 >> If I open a frame with multiple tabs, and one of the tabs has a
 >> dedicated window, then kill the buffer with the dedicated window, the
 >> frame is deleted along with its tabs.
 >>
 >> I understand that this is the documented behaviour, however my
 >> expectation is that the tab should be deleted but the frame should
 >> stay when other tabs are available, similar to how the frame is not
 >> deleted if other windows are visible.
 >
 > I'm not sure I agree with you.  Tabs are just saved frame
 > configurations, they are not real windows.  If we make this behavior
 > dependent on tab-bar-mode, we basically introduce an incompatible
 > behavior change in this particular case, which people and Lisp
 > programs out there might not expect or like.

The current behavior of 'replace-buffer-in-windows' has been taken over
from 'quit-window' which Richard initially designed as

     ;; Get rid of the frame, if it has just one dedicated window
     ;; and other visible frames exist.

It is not carved in stone but if we want to change it for the tabs case
we should leave it in place.  So I think that Juri should provide a tabs
option that has 'quit-restore-window' (which 'replace-buffer-in-windows'
should call) spare the frame in that case.  Which buffer to show in that
window instead (especially if it never showed another buffer in its
whole life) is another question.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-06  6:12   ` Juri Linkov
@ 2024-06-06  9:20     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-06 10:10     ` Eli Zaretskii
  1 sibling, 0 replies; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-06  9:20 UTC (permalink / raw)
  To: Juri Linkov, Eli Zaretskii; +Cc: Al Haji-Ali, 71386

 > I don't understand the logic of window--delete.

It mainly tries to deal with the auto hide mechanism.  Other then that
it looks pretty innocuous to me.

 > But maybe
 > window-deletable-p should also check for existing tabs in tab-bar-mode
 > and return 'tab' instead of 'frame'.  Then window--delete
 > could close the tab instead of deleting the frame.

Governed by an option in the tabs code, I would say.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-06  6:12   ` Juri Linkov
  2024-06-06  9:20     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-06 10:10     ` Eli Zaretskii
  1 sibling, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2024-06-06 10:10 UTC (permalink / raw)
  To: Juri Linkov; +Cc: rudalics, abdo.haji.ali, 71386

> From: Juri Linkov <juri@linkov.net>
> Cc: Al Haji-Ali <abdo.haji.ali@gmail.com>,  martin rudalics
>  <rudalics@gmx.at>,  71386@debbugs.gnu.org
> Date: Thu, 06 Jun 2024 09:12:10 +0300
> 
> >> If I open a frame with multiple tabs, and one of the tabs has
> >> a dedicated window, then kill the buffer with the dedicated window,
> >> the frame is deleted along with its tabs.
> >> 
> >> I understand that this is the documented behaviour, however my
> >> expectation is that the tab should be deleted but the frame should
> >> stay when other tabs are available, similar to how the frame is not
> >> deleted if other windows are visible.
> >
> > I'm not sure I agree with you.  Tabs are just saved frame
> > configurations, they are not real windows.  If we make this behavior
> > dependent on tab-bar-mode, we basically introduce an incompatible
> > behavior change in this particular case, which people and Lisp
> > programs out there might not expect or like.
> >
> > I'm adding Juri and Martin to this discussion.
> 
> I don't understand the logic of window--delete.  But maybe
> window-deletable-p should also check for existing tabs in tab-bar-mode
> and return 'tab' instead of 'frame'.  Then window--delete
> could close the tab instead of deleting the frame.

Sure, technically it should not be hard to make this change.  I just
am not sure we should.  Martin, WDYT?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-06  9:19   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-07  6:39     ` Juri Linkov
  2024-06-07  8:23       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-07  6:39 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, Al Haji-Ali, 71386

>>> If I open a frame with multiple tabs, and one of the tabs has a
>>> dedicated window, then kill the buffer with the dedicated window, the
>>> frame is deleted along with its tabs.
>>>
>>> I understand that this is the documented behaviour, however my
>>> expectation is that the tab should be deleted but the frame should
>>> stay when other tabs are available, similar to how the frame is not
>>> deleted if other windows are visible.
>>
>> I'm not sure I agree with you.  Tabs are just saved frame
>> configurations, they are not real windows.  If we make this behavior
>> dependent on tab-bar-mode, we basically introduce an incompatible
>> behavior change in this particular case, which people and Lisp
>> programs out there might not expect or like.
>
> The current behavior of 'replace-buffer-in-windows' has been taken over
> from 'quit-window' which Richard initially designed as
>
>     ;; Get rid of the frame, if it has just one dedicated window
>     ;; and other visible frames exist.
>
> It is not carved in stone but if we want to change it for the tabs case
> we should leave it in place.  So I think that Juri should provide a tabs
> option that has 'quit-restore-window' (which 'replace-buffer-in-windows'
> should call) spare the frame in that case.  Which buffer to show in that
> window instead (especially if it never showed another buffer in its
> whole life) is another question.

Sorry, I don't understand what I should do in tab-bar-mode
for quit-restore-window.  I expected that changes should be
in window.el.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07  6:39     ` Juri Linkov
@ 2024-06-07  8:23       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-07 17:20         ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-07  8:23 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, Al Haji-Ali, 71386

 > Sorry, I don't understand what I should do in tab-bar-mode
 > for quit-restore-window.  I expected that changes should be
 > in window.el.

Provide an option, say 'tab-bar-save-frame', that allows users to
customize whether a frame should be deleted when "other tabs are
available for that frame".  And provide a function, say
'tab-bar-save-frame-p', 'window--delete' could call thusly

     (let ((deletable (window-deletable-p window)))
       (cond
        ((eq deletable 'frame)
	(let ((frame (window-frame window)))
	  (cond
	   ((and (fboundp 'tab-bar-save-frame-p)
		 (tab-bar-save-frame-p frame kill))
	    nil)
	   (kill
	    (delete-frame frame))

thus avoiding to kill the frame when that function returns non-nil.
'tab-bar-save-frame-p' itself would be free to do with the frame
whatever it wants according to the value of 'tab-bar-save-frame'.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07  8:23       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-07 17:20         ` Juri Linkov
  2024-06-07 17:52           ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-07 17:20 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, Al Haji-Ali, 71386

[-- Attachment #1: Type: text/plain, Size: 428 bytes --]

>> Sorry, I don't understand what I should do in tab-bar-mode
>> for quit-restore-window.  I expected that changes should be
>> in window.el.
>
> Provide an option, say 'tab-bar-save-frame', that allows users to
> customize whether a frame should be deleted when "other tabs are
> available for that frame".  And provide a function, say
> 'tab-bar-save-frame-p', 'window--delete' could call thusly

Ok, here is a better patch:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: window-delete-frame-predicate-functions.patch --]
[-- Type: text/x-diff, Size: 1557 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index 2208346ec8c..abc9f1b4011 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4968,6 +4968,10 @@ frame-auto-hide-function
   :group 'frames
   :version "26.1")
 
+(defvar window-delete-frame-predicate-functions nil
+  "Don't delete frame when one of functions returns t.
+Called with two arguments: FRAME and KILL.")
+
 (defun window--delete (&optional window dedicated-only kill)
   "Delete WINDOW if possible.
 WINDOW must be a live window and defaults to the selected one.
@@ -4982,6 +4986,10 @@ window--delete
        ((eq deletable 'frame)
 	(let ((frame (window-frame window)))
 	  (cond
+	   ((run-hook-with-args-until-success
+	     'window-delete-frame-predicate-functions
+	     frame kill)
+	    nil)
 	   (kill
 	    (delete-frame frame))
            ((functionp (frame-parameter frame 'auto-hide-function))
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index dac57ce2070..25bfefbc205 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -2631,6 +2631,14 @@ tab-switcher-mouse-select
   (goto-char (posn-point (event-end event)))
   (tab-switcher-select))
 
+\f
+(defun tab-bar-window-delete-frame-p (frame _kill)
+  "Whether FRAME should be deleted when other tabs are available for that frame.
+Used via `window-delete-frame-predicate-functions' by `window--delete'."
+  (and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1)))
+
+(add-hook 'window-delete-frame-predicate-functions #'tab-bar-window-delete-frame-p)
+
 \f
 (defun tab-bar--reusable-frames (all-frames)
   (cond

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07 17:20         ` Juri Linkov
@ 2024-06-07 17:52           ` Eli Zaretskii
  2024-06-07 18:16             ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2024-06-07 17:52 UTC (permalink / raw)
  To: Juri Linkov; +Cc: rudalics, abdo.haji.ali, 71386

> From: Juri Linkov <juri@linkov.net>
> Cc: Eli Zaretskii <eliz@gnu.org>,  Al Haji-Ali <abdo.haji.ali@gmail.com>,
>   71386@debbugs.gnu.org
> Date: Fri, 07 Jun 2024 20:20:03 +0300
> 
> > Provide an option, say 'tab-bar-save-frame', that allows users to
> > customize whether a frame should be deleted when "other tabs are
> > available for that frame".  And provide a function, say
> > 'tab-bar-save-frame-p', 'window--delete' could call thusly
> 
> Ok, here is a better patch:

Thanks, but I think this should be controlled by a user option, since
it's quite a drastic change in behavior.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07 17:52           ` Eli Zaretskii
@ 2024-06-07 18:16             ` Juri Linkov
  2024-06-07 18:44               ` Al Haji-Ali
  2024-06-07 19:50               ` Eli Zaretskii
  0 siblings, 2 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-07 18:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, abdo.haji.ali, 71386

>> Ok, here is a better patch:
>
> Thanks, but I think this should be controlled by a user option, since
> it's quite a drastic change in behavior.

I'm against adding useless options to tab-bar.el
since users can easily remove hook with 1 liner:

(remove-hook 'window-delete-frame-predicate-functions 'tab-bar-window-delete-frame-p)





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07 18:16             ` Juri Linkov
@ 2024-06-07 18:44               ` Al Haji-Ali
  2024-06-09 16:59                 ` Juri Linkov
  2024-06-07 19:50               ` Eli Zaretskii
  1 sibling, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-07 18:44 UTC (permalink / raw)
  To: Juri Linkov, Eli Zaretskii; +Cc: rudalics, 71386


On 07/06/2024, Juri Linkov wrote:
> Ok, here is a better patch:

Hello Juri,

If I may interject a bit, I think it would be better if the tab is closed (i.e., tab-bar-close-tab is called) and another tab is displayed when the dedicated buffer is killed if its the only one in a window. For example, I changed `window--delete` on my machine to have this

(if (and tab-bar-mode
         (> (length (tab-bar-tabs)) 1))
    (tab-bar-close-tab)
  (delete-frame frame))

In your patch, `tab-bar-window-delete-frame-p` doesn't do that, nor should it as it is a predicate. Maybe `window-delete-frame-predicate-functions` should be renamed to `window-delete-frame-actions` or something and `tab-bar-close-tab` should be called in `tab-bar-window-delete-frame-p` (removing `-p` probably) -- in fact, the `delete-frame` code itself could be added as such an action, if we are not averse to changes to the interface.

Also, just FYI, your patch doesn't allow the branches with `auto-hide-function` and `frame-auto-hide-function` to be called when `kill` is nil. I don't know the side-effects of not calling these functions in such cases, but might be worth checking.

-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07 18:16             ` Juri Linkov
  2024-06-07 18:44               ` Al Haji-Ali
@ 2024-06-07 19:50               ` Eli Zaretskii
  1 sibling, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2024-06-07 19:50 UTC (permalink / raw)
  To: Juri Linkov; +Cc: rudalics, abdo.haji.ali, 71386

> From: Juri Linkov <juri@linkov.net>
> Cc: rudalics@gmx.at,  abdo.haji.ali@gmail.com,  71386@debbugs.gnu.org
> Date: Fri, 07 Jun 2024 21:16:43 +0300
> 
> >> Ok, here is a better patch:
> >
> > Thanks, but I think this should be controlled by a user option, since
> > it's quite a drastic change in behavior.
> 
> I'm against adding useless options to tab-bar.el

It is not useless IMO.

> since users can easily remove hook with 1 liner:
> 
> (remove-hook 'window-delete-frame-predicate-functions 'tab-bar-window-delete-frame-p)

If we document this in NEWS, it could be good enough.






^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-07 18:44               ` Al Haji-Ali
@ 2024-06-09 16:59                 ` Juri Linkov
  2024-06-09 17:46                   ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-09 16:59 UTC (permalink / raw)
  To: Al Haji-Ali; +Cc: rudalics, Eli Zaretskii, 71386

[-- Attachment #1: Type: text/plain, Size: 1497 bytes --]

> If I may interject a bit, I think it would be better if the tab is
> closed (i.e., tab-bar-close-tab is called) and another tab is
> displayed when the dedicated buffer is killed if its the only one in
> a window.

Thanks, good suggestion.

> For example, I changed `window--delete` on my machine to
> have this
>
> (if (and tab-bar-mode
>          (> (length (tab-bar-tabs)) 1))
>     (tab-bar-close-tab)
>   (delete-frame frame))
>
> In your patch, `tab-bar-window-delete-frame-p` doesn't do that, nor
> should it as it is a predicate.  Maybe
> `window-delete-frame-predicate-functions` should be renamed to
> `window-delete-frame-actions` or something and `tab-bar-close-tab`
> should be called in `tab-bar-window-delete-frame-p` (removing `-p`
> probably) -- in fact, the `delete-frame` code itself could be added as
> such an action, if we are not averse to changes to the interface.

It should be sufficient to rename it to just 'window-delete-frame-functions'.
Then it's not a predicate, and also follows the naming convention of hooks
having the '-functions' suffix.

> Also, just FYI, your patch doesn't allow the branches with
> `auto-hide-function` and `frame-auto-hide-function` to be called when
> `kill` is nil.  I don't know the side-effects of not calling these
> functions in such cases, but might be worth checking.

Probably the frame should not be hidden after closing the tab,
so these branches should not be handled.

Ok, here is the patch that supports your initial case:

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tab-bar-window-delete-frame.patch --]
[-- Type: text/x-diff, Size: 1704 bytes --]

diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 6ab6324540e..485ea1d5dd0 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -2659,6 +2659,16 @@ tab-switcher-mouse-select
   (goto-char (posn-point (event-end event)))
   (tab-switcher-select))
 
+\f
+(defun tab-bar-window-delete-frame (frame _kill)
+  "Whether FRAME should be deleted when other tabs are available for that frame.
+Instead of deleting the frame, close the current tab.
+Used via `window-delete-frame-predicate-functions' by `window--delete'."
+  (and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1)
+       (progn (tab-bar-close-tab) t)))
+
+(add-hook 'window-delete-frame-functions #'tab-bar-window-delete-frame)
+
 \f
 (defun tab-bar--reusable-frames (all-frames)
   (cond
diff --git a/lisp/window.el b/lisp/window.el
index 2208346ec8c..b1e877b82a8 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4968,6 +4968,11 @@ frame-auto-hide-function
   :group 'frames
   :version "26.1")
 
+(defvar window-delete-frame-functions nil
+  "Don't delete frame when one of functions returns t.
+Each of functions is called with two arguments: FRAME and KILL.
+The function can perform an action instead of deleting the frame.")
+
 (defun window--delete (&optional window dedicated-only kill)
   "Delete WINDOW if possible.
 WINDOW must be a live window and defaults to the selected one.
@@ -4982,6 +4987,10 @@ window--delete
        ((eq deletable 'frame)
 	(let ((frame (window-frame window)))
 	  (cond
+	   ((run-hook-with-args-until-success
+	     'window-delete-frame-functions
+	     frame kill)
+	    nil)
 	   (kill
 	    (delete-frame frame))
            ((functionp (frame-parameter frame 'auto-hide-function))

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-09 16:59                 ` Juri Linkov
@ 2024-06-09 17:46                   ` Eli Zaretskii
  2024-06-09 17:58                     ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2024-06-09 17:46 UTC (permalink / raw)
  To: Juri Linkov; +Cc: rudalics, abdo.haji.ali, 71386

> From: Juri Linkov <juri@linkov.net>
> Cc: Eli Zaretskii <eliz@gnu.org>,  rudalics@gmx.at,  71386@debbugs.gnu.org
> Date: Sun, 09 Jun 2024 19:59:29 +0300
> 
> +(defun tab-bar-window-delete-frame (frame _kill)
> +  "Whether FRAME should be deleted when other tabs are available for that frame.
> +Instead of deleting the frame, close the current tab.

The first and the second sentences contradict each other.  The first
implies that this is a predicate which returns a boolean, whereas the
second says that it closes the tab and negtlets to say anything about
the return value.

> +(defvar window-delete-frame-functions nil
> +  "Don't delete frame when one of functions returns t.
> +Each of functions is called with two arguments: FRAME and KILL.
> +The function can perform an action instead of deleting the frame.")

This doc string should at least explain what is the KILL argument and
its meaning.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-09 17:46                   ` Eli Zaretskii
@ 2024-06-09 17:58                     ` Juri Linkov
  2024-06-09 18:16                       ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-09 17:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, abdo.haji.ali, 71386

>> +(defun tab-bar-window-delete-frame (frame _kill)
>> +  "Whether FRAME should be deleted when other tabs are available for that frame.
>> +Instead of deleting the frame, close the current tab.
>
> The first and the second sentences contradict each other.  The first
> implies that this is a predicate which returns a boolean, whereas the
> second says that it closes the tab and negtlets to say anything about
> the return value.
>
>> +(defvar window-delete-frame-functions nil
>> +  "Don't delete frame when one of functions returns t.
>> +Each of functions is called with two arguments: FRAME and KILL.
>> +The function can perform an action instead of deleting the frame.")
>
> This doc string should at least explain what is the KILL argument and
> its meaning.

I tried to improve these doc strings:

diff --git a/lisp/window.el b/lisp/window.el
index 2208346ec8c..e97557b5bb2 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4968,6 +4968,13 @@ frame-auto-hide-function
   :group 'frames
   :version "26.1")
 
+(defvar window-delete-frame-functions nil
+  "A list of functions to handle the frame deletion.
+Each of functions is called with two arguments: FRAME and KILL where
+KILL means the buffer shown in window will be killed.  When one of functions
+returns a non-nil value then `window--delete' will not delete the frame.
+The function can also perform own action instead of deleting the frame.")
+
 (defun window--delete (&optional window dedicated-only kill)
   "Delete WINDOW if possible.
 WINDOW must be a live window and defaults to the selected one.
@@ -4982,6 +4989,10 @@ window--delete
        ((eq deletable 'frame)
 	(let ((frame (window-frame window)))
 	  (cond
+	   ((run-hook-with-args-until-success
+	     'window-delete-frame-functions
+	     frame kill)
+	    nil)
 	   (kill
 	    (delete-frame frame))
            ((functionp (frame-parameter frame 'auto-hide-function))
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 6ab6324540e..2f7578b842b 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -2659,6 +2659,17 @@ tab-switcher-mouse-select
   (goto-char (posn-point (event-end event)))
   (tab-switcher-select))
 
+\f
+(defun tab-bar-window-delete-frame (frame _kill)
+  "Handle frame deletion in `tab-bar-mode'.
+When there are more than one tab on the selected frame, then close
+the current tab.  In this case return t to not delete the frame
+in `window--delete'."
+  (and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1)
+       (progn (tab-bar-close-tab) t)))
+
+(add-hook 'window-delete-frame-functions #'tab-bar-window-delete-frame)
+
 \f
 (defun tab-bar--reusable-frames (all-frames)
   (cond





^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-09 17:58                     ` Juri Linkov
@ 2024-06-09 18:16                       ` Eli Zaretskii
  2024-06-09 18:28                         ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2024-06-09 18:16 UTC (permalink / raw)
  To: Juri Linkov; +Cc: rudalics, abdo.haji.ali, 71386

> From: Juri Linkov <juri@linkov.net>
> Cc: abdo.haji.ali@gmail.com,  rudalics@gmx.at,  71386@debbugs.gnu.org
> Date: Sun, 09 Jun 2024 20:58:10 +0300
> 
> >> +(defun tab-bar-window-delete-frame (frame _kill)
> >> +  "Whether FRAME should be deleted when other tabs are available for that frame.
> >> +Instead of deleting the frame, close the current tab.
> >
> > The first and the second sentences contradict each other.  The first
> > implies that this is a predicate which returns a boolean, whereas the
> > second says that it closes the tab and negtlets to say anything about
> > the return value.
> >
> >> +(defvar window-delete-frame-functions nil
> >> +  "Don't delete frame when one of functions returns t.
> >> +Each of functions is called with two arguments: FRAME and KILL.
> >> +The function can perform an action instead of deleting the frame.")
> >
> > This doc string should at least explain what is the KILL argument and
> > its meaning.
> 
> I tried to improve these doc strings:

Thanks, they are more clear now.  But one point still needs
clarification, IMO:

> +(defvar window-delete-frame-functions nil
> +  "A list of functions to handle the frame deletion.
> +Each of functions is called with two arguments: FRAME and KILL where
> +KILL means the buffer shown in window will be killed.  When one of functions

So KILL is a boolean, and if it's non-nil, it means the buffer will be
killed?  If so, will the buffer be killed even if the function returns
non-nil?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-09 18:16                       ` Eli Zaretskii
@ 2024-06-09 18:28                         ` Juri Linkov
  2024-06-10  8:00                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-09 18:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, abdo.haji.ali, 71386

>> I tried to improve these doc strings:
>
> Thanks, they are more clear now.  But one point still needs
> clarification, IMO:
>
>> +(defvar window-delete-frame-functions nil
>> +  "A list of functions to handle the frame deletion.
>> +Each of functions is called with two arguments: FRAME and KILL where
>> +KILL means the buffer shown in window will be killed.  When one of functions
>
> So KILL is a boolean, and if it's non-nil, it means the buffer will be
> killed?  If so, will the buffer be killed even if the function returns
> non-nil?

I don't know, I just copied the text from the doc string of 'window--delete'.
But I don't understand the logic of using the KILL argument
in 'window--delete':

	   (kill
	    (delete-frame frame))

Maybe Martin could explain.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-09 18:28                         ` Juri Linkov
@ 2024-06-10  8:00                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-11  6:58                             ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-10  8:00 UTC (permalink / raw)
  To: Juri Linkov, Eli Zaretskii; +Cc: abdo.haji.ali, 71386

 >> So KILL is a boolean, and if it's non-nil, it means the buffer will be
 >> killed?  If so, will the buffer be killed even if the function returns
 >> non-nil?
 >
 > I don't know, I just copied the text from the doc string of 'window--delete'.
 > But I don't understand the logic of using the KILL argument
 > in 'window--delete':
 >
 > 	   (kill
 > 	    (delete-frame frame))
 >
 > Maybe Martin could explain.

KILL non-nil here comes from the prefix argument of 'quit-window' which,
if provided, 'quit-window' passes as 'kill' via BURY-OR-KILL to
'quit-restore-window' which then passes t via the KILL argument to
'window--delete'.  'window--delete' itself does not deal with buffers,
it handles windows only.

'quit-restore-window' calls 'kill-buffer' later when BURY-OR-KILL equals
'kill'.  At that time, the window should already have been taken care of
- either by deletion or by showing another buffer.  The return value of
'window--delete' is used to make the last conjuncts in the first 'cond'
of 'quit-restore-window' succeed or fail (in the latter case the next
clause will be probed).

The idea of deleting the frame comes from the fact that a killed buffer
cannot be re-shown in that frame's sole window.  'quit-restore-window'
calls 'window--delete' in this case iff that window has no previous
other buffer to show instead, so deleting the window (and possibly its
frame) is the obvious choice rather than showing some unrelated buffer
in it.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-10  8:00                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-11  6:58                             ` Juri Linkov
  2024-06-11 16:26                               ` Al Haji-Ali
  2024-06-12  8:57                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-11  6:58 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

>> But I don't understand the logic of using the KILL argument
>> in 'window--delete':
>>
>> 	   (kill
>> 	    (delete-frame frame))
>>
>> Maybe Martin could explain.
>
> KILL non-nil here comes from the prefix argument of 'quit-window' which,
> if provided, 'quit-window' passes as 'kill' via BURY-OR-KILL to
> 'quit-restore-window' which then passes t via the KILL argument to
> 'window--delete'.  'window--delete' itself does not deal with buffers,
> it handles windows only.
>
> 'quit-restore-window' calls 'kill-buffer' later when BURY-OR-KILL equals
> 'kill'.  At that time, the window should already have been taken care of
> - either by deletion or by showing another buffer.  The return value of
> 'window--delete' is used to make the last conjuncts in the first 'cond'
> of 'quit-restore-window' succeed or fail (in the latter case the next
> clause will be probed).
>
> The idea of deleting the frame comes from the fact that a killed buffer
> cannot be re-shown in that frame's sole window.  'quit-restore-window'
> calls 'window--delete' in this case iff that window has no previous
> other buffer to show instead, so deleting the window (and possibly its
> frame) is the obvious choice rather than showing some unrelated buffer
> in it.

So it makes no sense to send the value of the KILL arg to tab-bar code?
Because there is nothing to decide based on its value?





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-11  6:58                             ` Juri Linkov
@ 2024-06-11 16:26                               ` Al Haji-Ali
  2024-06-13  6:50                                 ` Juri Linkov
  2024-06-12  8:57                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-11 16:26 UTC (permalink / raw)
  To: Juri Linkov, martin rudalics; +Cc: Eli Zaretskii, 71386

On 11/06/2024, Juri Linkov wrote:

> So it makes no sense to send the value of the KILL arg to tab-bar code?
> Because there is nothing to decide based on its value?

Perhaps, for consistency, the argument should be send in case `window-delete-frame-functions` is used for other reasons by the user. Also, perhaps the tab should not be closed if `kill` is nil (similar to how the frame is not killed if `kill` is nil) and another buffer should be shown.

-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-11  6:58                             ` Juri Linkov
  2024-06-11 16:26                               ` Al Haji-Ali
@ 2024-06-12  8:57                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-13  6:53                                 ` Juri Linkov
  1 sibling, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-12  8:57 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

 > So it makes no sense to send the value of the KILL arg to tab-bar code?
 > Because there is nothing to decide based on its value?

But KILL means to delete the frame and the tab-bar code wants to prevent
that.  Or what am I missing?

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-11 16:26                               ` Al Haji-Ali
@ 2024-06-13  6:50                                 ` Juri Linkov
  0 siblings, 0 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-13  6:50 UTC (permalink / raw)
  To: Al Haji-Ali; +Cc: martin rudalics, Eli Zaretskii, 71386

>> So it makes no sense to send the value of the KILL arg to tab-bar code?
>> Because there is nothing to decide based on its value?
>
> Perhaps, for consistency, the argument should be send in case
> `window-delete-frame-functions` is used for other reasons by the
> user. Also, perhaps the tab should not be closed if `kill` is nil (similar
> to how the frame is not killed if `kill` is nil) and another buffer should
> be shown.

If I read `window--delete` code correctly, the frame goes away
in any case:

	   (kill
	    (delete-frame frame))
           ((functionp frame-auto-hide-function)
	    (funcall frame-auto-hide-function frame))

If `kill` is nil, the frame gets hidden: the default value of
`frame-auto-hide-function` is `iconify-frame` that is like
closing the tab too.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-12  8:57                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-13  6:53                                 ` Juri Linkov
  2024-06-13  8:21                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-13  6:53 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

>> So it makes no sense to send the value of the KILL arg to tab-bar code?
>> Because there is nothing to decide based on its value?
>
> But KILL means to delete the frame and the tab-bar code wants to prevent
> that.  Or what am I missing?

For frames KILL defines whether to delete or iconify the frame.
There is no such thing as to "iconify" the tab.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-13  6:53                                 ` Juri Linkov
@ 2024-06-13  8:21                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-14  6:13                                     ` Juri Linkov
  2024-06-14 17:46                                     ` Juri Linkov
  0 siblings, 2 replies; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-13  8:21 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

 >> But KILL means to delete the frame and the tab-bar code wants to prevent
 >> that.  Or what am I missing?
 >
 > For frames KILL defines whether to delete or iconify the frame.
 > There is no such thing as to "iconify" the tab.

Don't you want to distinguish 'kill' non-nil where the frame should get
deleted from 'kill' nil where nothing is done?  In the latter case the
window cannot even be deleted because when the return value of
'window-deletable-p' equals 'frame' this implies that WINDOW is the root
window of its frame.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-13  8:21                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-14  6:13                                     ` Juri Linkov
  2024-06-14 17:46                                     ` Juri Linkov
  1 sibling, 0 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-14  6:13 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

>>> But KILL means to delete the frame and the tab-bar code wants to prevent
>>> that.  Or what am I missing?
>>
>> For frames KILL defines whether to delete or iconify the frame.
>> There is no such thing as to "iconify" the tab.
>
> Don't you want to distinguish 'kill' non-nil where the frame should get
> deleted from 'kill' nil where nothing is done?  In the latter case the
> window cannot even be deleted because when the return value of
> 'window-deletable-p' equals 'frame' this implies that WINDOW is the root
> window of its frame.

I still don't understand how frame deletion should be handled for tabs
for this bug report and for bug#59862.  Probably need to study more.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-13  8:21                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-14  6:13                                     ` Juri Linkov
@ 2024-06-14 17:46                                     ` Juri Linkov
  2024-06-15  8:42                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-14 17:46 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

[-- Attachment #1: Type: text/plain, Size: 609 bytes --]

>>> But KILL means to delete the frame and the tab-bar code wants to prevent
>>> that.  Or what am I missing?
>>
>> For frames KILL defines whether to delete or iconify the frame.
>> There is no such thing as to "iconify" the tab.
>
> Don't you want to distinguish 'kill' non-nil where the frame should get
> deleted from 'kill' nil where nothing is done?  In the latter case the
> window cannot even be deleted because when the return value of
> 'window-deletable-p' equals 'frame' this implies that WINDOW is the root
> window of its frame.

This is the best that I can do, you can improve it if you want:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: window-delete-frame-functions.patch --]
[-- Type: text/x-diff, Size: 1855 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index 604b9868921..155b0b55482 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4948,6 +4968,13 @@ frame-auto-hide-function
   :group 'frames
   :version "26.1")
 
+(defvar window-delete-frame-functions nil
+  "A list of functions to handle the frame deletion.
+Each of functions is called with two arguments: FRAME and KILL where
+KILL means the buffer shown in window will be killed.  When one of functions
+returns a non-nil value then `window--delete' will not delete the frame.
+The function can also perform own action instead of deleting the frame.")
+
 (defun window--delete (&optional window dedicated-only kill)
   "Delete WINDOW if possible.
 WINDOW must be a live window and defaults to the selected one.
@@ -4962,6 +4989,10 @@ window--delete
        ((eq deletable 'frame)
 	(let ((frame (window-frame window)))
 	  (cond
+	   ((run-hook-with-args-until-success
+	     'window-delete-frame-functions
+	     frame kill)
+	    nil)
 	   (kill
 	    (delete-frame frame))
            ((functionp (frame-parameter frame 'auto-hide-function))
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 6ab6324540e..2f7578b842b 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -2659,6 +2659,17 @@ tab-switcher-mouse-select
   (goto-char (posn-point (event-end event)))
   (tab-switcher-select))
 
+\f
+(defun tab-bar-window-delete-frame (frame _kill)
+  "Handle frame deletion in `tab-bar-mode'.
+When there are more than one tab on the selected frame, then close
+the current tab.  In this case return t to not delete the frame
+in `window--delete'."
+  (and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1)
+       (progn (tab-bar-close-tab) t)))
+
+(add-hook 'window-delete-frame-functions #'tab-bar-window-delete-frame)
+
 \f
 (defun tab-bar--reusable-frames (all-frames)
   (cond

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-14 17:46                                     ` Juri Linkov
@ 2024-06-15  8:42                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-16  6:58                                         ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-15  8:42 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

+(defvar window-delete-frame-functions nil
+  "A list of functions to handle the frame deletion.

I'd still prefer a tab-bar specific option (like 'tab-bar-save-frame-p'
as mentioned earlier) for two reasons.

The first reason is that 'window--delete' is an internal function of
window.el.  I wouldn't want an internal function run a hook "of its own"
because that's difficult to explain to users.  OTOH I suppose that a
function like 'tab-bar-save-frame-p' should be callable from any other
function too, as soon as the need arises.

The second reason is that I wouldn't want "anyone" to inhibit frame
deletion.  Such a facility could have consequences I cannot fathom at
the moment.  Would we want 'delete-frame' to obey it too and possibly
spare the frame?

Let's see what Haji-Ali thinks.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-15  8:42                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-16  6:58                                         ` Juri Linkov
  2024-06-16  7:52                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-16  6:58 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

> +(defvar window-delete-frame-functions nil
> +  "A list of functions to handle the frame deletion.
>
> I'd still prefer a tab-bar specific option (like 'tab-bar-save-frame-p'
> as mentioned earlier) for two reasons.
>
> The first reason is that 'window--delete' is an internal function of
> window.el.  I wouldn't want an internal function run a hook "of its own"
> because that's difficult to explain to users.  OTOH I suppose that a
> function like 'tab-bar-save-frame-p' should be callable from any other
> function too, as soon as the need arises.
>
> The second reason is that I wouldn't want "anyone" to inhibit frame
> deletion.  Such a facility could have consequences I cannot fathom at
> the moment.  Would we want 'delete-frame' to obey it too and possibly
> spare the frame?

Ok, here is the right patch:

diff --git a/lisp/window.el b/lisp/window.el
index b7bd59bc813..872110a8321 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4120,6 +4120,8 @@ window-deletable-p
 
   (let ((frame (window-frame window)))
     (cond
+     ((and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1))
+      '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
@@ -4979,6 +4981,9 @@ window--delete
   (unless (and dedicated-only (not (window-dedicated-p window)))
     (let ((deletable (window-deletable-p window)))
       (cond
+       ((eq deletable 'tab)
+        (tab-bar-close-tab)
+        'tab)
        ((eq deletable 'frame)
 	(let ((frame (window-frame window)))
 	  (cond





^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-16  6:58                                         ` Juri Linkov
@ 2024-06-16  7:52                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-16 10:50                                             ` Al Haji-Ali
  2024-06-16 16:45                                             ` Juri Linkov
  0 siblings, 2 replies; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-16  7:52 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

+     ((and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1))
+      'tab)

How would users get back the old behavior?  By customizing
'tab-bar-close-last-tab-choice', 'tab-bar-tab-prevent-close-functions'?

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-16  7:52                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-16 10:50                                             ` Al Haji-Ali
  2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-16 16:45                                             ` Juri Linkov
  1 sibling, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-16 10:50 UTC (permalink / raw)
  To: martin rudalics, Juri Linkov; +Cc: Eli Zaretskii, 71386


On 15/06/2024, martin rudalics wrote:
> I'd still prefer a tab-bar specific option (like 'tab-bar-save-frame-p'
> as mentioned earlier) for two reasons.
>
This is probably the right approach to minimize unattended consequences and it would definitely address the issue (which is, to reiterate, is that fundamentally, tabs behave like windows in many situations, but not when deleting buffers with dedicated windows -- having two windows prevents deleting a frame, but not having two tabs).

I imagine Juri wanted to avoid having tab-specific code in `window.el` with the previous patch, hence the more generic hooks. The current patch of Juri should probably be protected with `featurep` or `fboundp` for tab-specific symbols.

Also if the proposed change to `window-deletable-p` is adopted, then a grep on `window-deletable-p` also reveals that, for consistency, `delete-windows-on` and even `calendar-exit` in `calendar.el` should be modified similarly to `window--delete`.

Best regards,
-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-16  7:52                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-16 10:50                                             ` Al Haji-Ali
@ 2024-06-16 16:45                                             ` Juri Linkov
  2024-06-17  6:16                                               ` Juri Linkov
  2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 2 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-16 16:45 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

> +     ((and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1))
> +      'tab)
>
> How would users get back the old behavior?  By customizing
> 'tab-bar-close-last-tab-choice', 'tab-bar-tab-prevent-close-functions'?

This patch just copies the logic of frame handling to tab handling.
There is no customization for frame handling, so there is
no customization for tab handling.

In window-deletable-p there is hard-coded 'frame-root-window-p'
that checks if the frame has only 1 window.  So the patch
does the same by checking if there is only 1 tab on the frame.

Also in window--delete the call of 'tab-bar-close-tab'
corresponds to the call 'delete-frame'.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-16 16:45                                             ` Juri Linkov
@ 2024-06-17  6:16                                               ` Juri Linkov
  2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 44+ messages in thread
From: Juri Linkov @ 2024-06-17  6:16 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

>> +     ((and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1))
>> +      'tab)
>>
>> How would users get back the old behavior?  By customizing
>> 'tab-bar-close-last-tab-choice', 'tab-bar-tab-prevent-close-functions'?
>
> This patch just copies the logic of frame handling to tab handling.
> There is no customization for frame handling, so there is
> no customization for tab handling.
>
> In window-deletable-p there is hard-coded 'frame-root-window-p'
> that checks if the frame has only 1 window.  So the patch
> does the same by checking if there is only 1 tab on the frame.
>
> Also in window--delete the call of 'tab-bar-close-tab'
> corresponds to the call 'delete-frame'.

Please see a more correct patch:

diff --git a/lisp/window.el b/lisp/window.el
index cf5c07395ab..588014b8f77 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4138,7 +4138,9 @@ window-deletable-p
                          (not (eq (default-toplevel-value
                                     'minibuffer-follows-selected-frame)
                                   t)))))
-	'frame))
+	(if (and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1))
+            'tab
+          'frame)))
      ((window-minibuffer-p window)
       ;; If WINDOW is the minibuffer window of a non-minibuffer-only
       ;; frame, it cannot be deleted separately.
@@ -4979,6 +4981,9 @@ window--delete
   (unless (and dedicated-only (not (window-dedicated-p window)))
     (let ((deletable (window-deletable-p window)))
       (cond
+       ((eq deletable 'tab)
+        (tab-bar-close-tab)
+        'tab)
        ((eq deletable 'frame)
 	(let ((frame (window-frame window)))
 	  (cond





^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-16 10:50                                             ` Al Haji-Ali
@ 2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-17 16:08                                                 ` Al Haji-Ali
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-17 14:47 UTC (permalink / raw)
  To: Al Haji-Ali, Juri Linkov; +Cc: Eli Zaretskii, 71386

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

 > Also if the proposed change to `window-deletable-p` is adopted, then a
 > grep on `window-deletable-p` also reveals that, for consistency,
 > `delete-windows-on` and even `calendar-exit` in `calendar.el` should
 > be modified similarly to `window--delete`.

This means that we should do the entire fix within 'window-deletable-p',
right?  That's not an internal function, so we can, in all conscience,
supply an abnormal hook as in the roughly tested patch attached.

martin

[-- Attachment #2: window-deletable-functions.diff --]
[-- Type: text/x-patch, Size: 2448 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index 604b9868921..04e38faa074 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4104,6 +4104,27 @@ one-window-p
 	(next-window base-window (if nomini 'arg) all-frames))))
 \f
 ;;; Deleting windows.
+(defcustom window-deletable-functions nil
+   "Abnormal hook to decide whether a window may be safely deleted.
+The value should be a list of functions that take two arguments.  The
+first argument is the window about to be deleted.  The second argument
+if non-nil, means that the window is the only window on its frame and
+should be deleted together with its frame.  The window's buffer is
+current when running this hook.
+
+If any of these functions returns nil, the window will not be deleted
+and another buffer will be shown in it.  This hook is run by
+`window-deletable-p' which, in is turn, is called by `delete-windows-on'
+and `quit-restore-window'.  It is neither run by `delete-window' nor
+`delete-frame'.
+
+The purpose of this hook is to give its clients a chance to save a
+window or its frame from deletion because they might still want to use
+that window or frame for their own purposes."
+  :type 'hook
+  :version "30.1"
+  :group 'windows)
+
 (defun window-deletable-p (&optional window)
   "Return t if WINDOW can be safely deleted from its frame.
 WINDOW must be a valid window and defaults to the selected one.
@@ -4137,14 +4158,20 @@ window-deletable-p
 		    (and minibuf (eq frame (window-frame minibuf))
                          (not (eq (default-toplevel-value
                                     'minibuffer-follows-selected-frame)
-                                  t)))))
+                                  t))))
+		  (not (with-current-buffer (window-buffer window)
+			 (run-hook-with-args-until-failure
+			  'window-deletable-functions window t))))
 	'frame))
      ((window-minibuffer-p window)
       ;; If WINDOW is the minibuffer window of a non-minibuffer-only
       ;; frame, it cannot be deleted separately.
       nil)
-     ((or ignore-window-parameters
-	  (not (eq window (window-main-window frame))))
+     ((and (or ignore-window-parameters
+	       (not (eq window (window-main-window frame))))
+	   (with-current-buffer (window-buffer window)
+	     (run-hook-with-args-until-failure
+	      'window-deletable-functions window nil)))
       ;; Otherwise, WINDOW can be deleted unless it is the main window
       ;; of its frame.
       t))))

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-16 16:45                                             ` Juri Linkov
  2024-06-17  6:16                                               ` Juri Linkov
@ 2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-17 14:47 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, abdo.haji.ali, 71386

 > This patch just copies the logic of frame handling to tab handling.
 > There is no customization for frame handling,

There is: 'auto-hide-function'.

 > so there is
 > no customization for tab handling.

But we want to customize the new behavior whether to retain a frame
because it has outstanding tabs or not.

 > In window-deletable-p there is hard-coded 'frame-root-window-p'
 > that checks if the frame has only 1 window.  So the patch
 > does the same by checking if there is only 1 tab on the frame.
 >
 > Also in window--delete the call of 'tab-bar-close-tab'
 > corresponds to the call 'delete-frame'.

And if a user wants to auto-hide the frame?

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-17 16:08                                                 ` Al Haji-Ali
  2024-06-17 16:47                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-17 16:08 UTC (permalink / raw)
  To: martin rudalics, Juri Linkov; +Cc: Eli Zaretskii, 71386


On 17/06/2024, martin rudalics wrote:
> This means that we should do the entire fix within 'window-deletable-p',
> right?  That's not an internal function, so we can, in all conscience,
> supply an abnormal hook as in the roughly tested patch attached.

It would be great if the fix is done entirely in `window-deletable-p`, but is the idea functions in `window-deletable-functions` could have side-effects even though they are called from a predicate?

For tabs, I believe an ideal fix would close the tab in lieu of deleting the frame when the buffer of a dedicated window is killed (similar to what Juri does in per patches).

-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-17 16:08                                                 ` Al Haji-Ali
@ 2024-06-17 16:47                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-17 17:01                                                     ` Al Haji-Ali
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-17 16:47 UTC (permalink / raw)
  To: Al Haji-Ali, Juri Linkov; +Cc: Eli Zaretskii, 71386

 > It would be great if the fix is done entirely in `window-deletable-p`,
 > but is the idea functions in `window-deletable-functions` could have
 > side-effects even though they are called from a predicate?

No.  We could emphasize that in the doc-string.  The idea is that such a
function can have 'window-deletable-p' return nil instead of 'frame' or
t.  WOW all functions on 'window-deletable-functions' have to agree that
'window-deletable-p' may return any non-nil value it initially proposes.

 > For tabs, I believe an ideal fix would close the tab in lieu of
 > deleting the frame when the buffer of a dedicated window is killed
 > (similar to what Juri does in per patches).

The patch I proposed will simply cause another buffer to be shown in
that window.  How this affects the tab bar code is beyond the limits of
'quit-restore-window' and colleagues.  I suppose the tab bar code should
do whatever it does when 'switch-to-prev-buffer' gets called.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-17 16:47                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-17 17:01                                                     ` Al Haji-Ali
  2024-06-18  9:52                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-17 17:01 UTC (permalink / raw)
  To: martin rudalics, Juri Linkov; +Cc: Eli Zaretskii, 71386


On 17/06/2024, martin rudalics wrote:
>
> The patch I proposed will simply cause another buffer to be shown in
> that window.  How this affects the tab bar code is beyond the limits of
> 'quit-restore-window' and colleagues.  I suppose the tab bar code should
> do whatever it does when 'switch-to-prev-buffer' gets called.

Ah, this could work and I can see it being more foolproof than modifying `window--delete`.
However, `switch-to-prev-buffer` does not seem to allow hooks to modify its behaviour (by the tab-bar code or otherwise), except to skip buffers.
Are we open to adding such hooks as well?

-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-17 17:01                                                     ` Al Haji-Ali
@ 2024-06-18  9:52                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-18 19:04                                                         ` Al Haji-Ali
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-18  9:52 UTC (permalink / raw)
  To: Al Haji-Ali, Juri Linkov; +Cc: Eli Zaretskii, 71386

 > However, `switch-to-prev-buffer` does not seem to allow hooks to
 > modify its behaviour (by the tab-bar code or otherwise), except to
 > skip buffers.  Are we open to adding such hooks as well?

We've been discussing changes to 'switch-to-prev-buffer' in Bug#69993
but ended up in disagreement on what to do.  Juri then implemented a
purely tab-bar based method.  For my Emacs I use an option that allows
it to switch to buffers that have been already displayed at least once
only and am quite happy with it (I've never managed to derive a suitable
regexp for all buffers I never want to switch to).

But I do not think that we need a hook for 'switch-to-prev-buffer'.  A
user may call it at any moment and the tab bar code must already know
how to deal with it via something like 'window-state-change-functions'
(and on a non-selected frame as well).

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-18  9:52                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-18 19:04                                                         ` Al Haji-Ali
  2024-06-19  6:24                                                           ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: Al Haji-Ali @ 2024-06-18 19:04 UTC (permalink / raw)
  To: martin rudalics, Juri Linkov; +Cc: Eli Zaretskii, 71386


On 18/06/2024, martin rudalics wrote:
> We've been discussing changes to 'switch-to-prev-buffer' in Bug#69993
> but ended up in disagreement on what to do.  Juri then implemented a
> purely tab-bar based method.  For my Emacs I use an option that allows
> it to switch to buffers that have been already displayed at least once
> only and am quite happy with it (I've never managed to derive a suitable
> regexp for all buffers I never want to switch to).

I see. The change you suggested is definitely needed in any case and would address the main issue in this bug report (frame being deleted and losing tab configuration). I would just suggest that `window-deletable-functions` be renamed to `window-deletable-predicates` or `window-deletable-p-functions` (as Juri suggested in his very first patch) to emphasize that these should be side-effect-free predicates.

I guess the code that Juri originally suggested for tab-bar can also be used with `window-deletable-functions`.
,----
| (defun tab-bar-window-delete-frame-p (window kill)
|   "Prevent deletion of WINDOW and its frame when it contains tabs.
| Used in `'window-deletable-functions'."
|   (and tab-bar-mode (> (length (funcall tab-bar-tabs-function frame)) 1)))
|   
| (add-hook 'window-deletable-functions #'tab-bar-window-delete-frame-p)
`----

I'll check Bug#69993 and try to figure out how to close the tab when it has a single dedicated window from `switch-to-prev-buffer`, or maybe Juri has some ideas?

-- Al





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-18 19:04                                                         ` Al Haji-Ali
@ 2024-06-19  6:24                                                           ` Juri Linkov
  2024-06-19  9:37                                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-19  6:24 UTC (permalink / raw)
  To: Al Haji-Ali; +Cc: martin rudalics, Eli Zaretskii, 71386

>> We've been discussing changes to 'switch-to-prev-buffer' in Bug#69993
>> but ended up in disagreement on what to do.  Juri then implemented a
>> purely tab-bar based method.  For my Emacs I use an option that allows
>> it to switch to buffers that have been already displayed at least once
>> only and am quite happy with it (I've never managed to derive a suitable
>> regexp for all buffers I never want to switch to).
>
> I'll check Bug#69993 and try to figure out how to close the tab when
> it has a single dedicated window from `switch-to-prev-buffer`,

Unfortunately, there is nothing to figure out from Bug#69993,
because it was about tab-line, not tab-bar.

> or maybe Juri has some ideas?

I don't know why Martin wants to avoid closing the tabs in window.el
when tabs have the same status as frames, and frames are deleted
in window.el.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-19  6:24                                                           ` Juri Linkov
@ 2024-06-19  9:37                                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-20  6:48                                                               ` Juri Linkov
  0 siblings, 1 reply; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-19  9:37 UTC (permalink / raw)
  To: Juri Linkov, Al Haji-Ali; +Cc: Eli Zaretskii, 71386

 > I don't know why Martin wants to avoid closing the tabs in window.el
 > when tabs have the same status as frames, and frames are deleted
 > in window.el.

I don't want to avoid closing tabs in window.el.  But please make sure
that the mechanism works for any window on any frame.  Whatever we
choose, 'window-deletable-p' and 'window--delete' have to work for an
arbitrary live window.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-19  9:37                                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-20  6:48                                                               ` Juri Linkov
  2024-06-20  9:29                                                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 44+ messages in thread
From: Juri Linkov @ 2024-06-20  6:48 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, Al Haji-Ali, 71386

>> I don't know why Martin wants to avoid closing the tabs in window.el
>> when tabs have the same status as frames, and frames are deleted
>> in window.el.
>
> I don't want to avoid closing tabs in window.el.  But please make sure
> that the mechanism works for any window on any frame.  Whatever we
> choose, 'window-deletable-p' and 'window--delete' have to work for an
> arbitrary live window.

So the obstacle is that tab-bar-close-tab closes tabs only on the
selected frame?  I don't know, this never was a problem.





^ permalink raw reply	[flat|nested] 44+ messages in thread

* bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs
  2024-06-20  6:48                                                               ` Juri Linkov
@ 2024-06-20  9:29                                                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 44+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-20  9:29 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, Al Haji-Ali, 71386

 > So the obstacle is that tab-bar-close-tab closes tabs only on the
 > selected frame?  I don't know, this never was a problem.

For example, 'quit-windows-on' has to deal with all windows showing a
specific buffer on all frames specified by the FRAME argument, killing
that buffer if KILL is non-nil.  If any such window was created by the
tab-bar code, that is, its second 'quit-restore' element equals 'tab',
'tab-bar-close-tab' has to take care of that window by deleting it or
showing some other buffer in it.

If 'tab-bar-close-tab' doesn't do that, 'kill-buffer' will kick in and
replace that window's buffer by some arbitrary other buffer.  If, as we
currently test with my other patch, 'replace-buffer-in-windows' calls
'quit-restore-window' and the buffer is again not replaced, then
'kill-buffer' will fall back on replace_buffer_in_windows_safely which
doesn't care about the 'quit-restore' parameter and puts some arbitrary
buffer in that window.

Now 'quit-windows-on' is already broken because when KILL is non-nil,
the buffer gets killed in the first call of 'quit-restore-window' which
means to call 'replace-buffer-in-windows' on it which on trunk deletes
windows only if they are dedicated.  This is probably not in the sense
of the caller but so far nobody protested.  In either case we have to
fix this eventually including the leak that results when 'quit-restore'
parameters reference dead buffers.  When we do that, the tab-bar
function called by 'quit-restore-window' should be prepared to handle
the scenario sketched above.

martin





^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2024-06-20  9:29 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-05 23:44 bug#71386: 29.1; Frame is auto-deleted even when it has multiple tabs Al Haji-Ali
2024-06-06  5:45 ` Eli Zaretskii
2024-06-06  6:12   ` Juri Linkov
2024-06-06  9:20     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-06 10:10     ` Eli Zaretskii
2024-06-06  9:19   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-07  6:39     ` Juri Linkov
2024-06-07  8:23       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-07 17:20         ` Juri Linkov
2024-06-07 17:52           ` Eli Zaretskii
2024-06-07 18:16             ` Juri Linkov
2024-06-07 18:44               ` Al Haji-Ali
2024-06-09 16:59                 ` Juri Linkov
2024-06-09 17:46                   ` Eli Zaretskii
2024-06-09 17:58                     ` Juri Linkov
2024-06-09 18:16                       ` Eli Zaretskii
2024-06-09 18:28                         ` Juri Linkov
2024-06-10  8:00                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-11  6:58                             ` Juri Linkov
2024-06-11 16:26                               ` Al Haji-Ali
2024-06-13  6:50                                 ` Juri Linkov
2024-06-12  8:57                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-13  6:53                                 ` Juri Linkov
2024-06-13  8:21                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-14  6:13                                     ` Juri Linkov
2024-06-14 17:46                                     ` Juri Linkov
2024-06-15  8:42                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-16  6:58                                         ` Juri Linkov
2024-06-16  7:52                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-16 10:50                                             ` Al Haji-Ali
2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-17 16:08                                                 ` Al Haji-Ali
2024-06-17 16:47                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-17 17:01                                                     ` Al Haji-Ali
2024-06-18  9:52                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-18 19:04                                                         ` Al Haji-Ali
2024-06-19  6:24                                                           ` Juri Linkov
2024-06-19  9:37                                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-20  6:48                                                               ` Juri Linkov
2024-06-20  9:29                                                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-16 16:45                                             ` Juri Linkov
2024-06-17  6:16                                               ` Juri Linkov
2024-06-17 14:47                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-07 19:50               ` Eli Zaretskii

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.