Merge pull request #834 from Vulcalien/ask-before-closing

Ask before closing, even if there is only one terminal
This commit is contained in:
Matt Rose 2024-02-08 15:49:18 -05:00 committed by GitHub
commit b47f7d073e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 73 additions and 61 deletions

View File

@ -1,13 +1,13 @@
'\" t
.\" Title: terminator_config
.\" Author: [see the "AUTHOR(S)" section]
.\" Generator: Asciidoctor 2.0.18
.\" Date: 2023-04-22
.\" Generator: Asciidoctor 2.0.16
.\" Date: 2023-10-10
.\" Manual: Manual for Terminator
.\" Source: Terminator
.\" Language: English
.\"
.TH "TERMINATOR_CONFIG" "5" "2023-04-22" "Terminator" "Manual for Terminator"
.TH "TERMINATOR_CONFIG" "5" "2023-10-10" "Terminator" "Manual for Terminator"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
@ -130,12 +130,11 @@ If set to True, the window will resize in step with font sizes.
Default value: \fBFalse\fP
.RE
.sp
\fBsuppress_multiple_term_dialog\fP = \fIboolean\fP
\fBask_before_closing\fP = \fIstring\fP
.RS 4
If set to True, Terminator will ask for confirmation when closing
multiple terminals.
.br
Default value: \fBFalse\fP
Specify when to ask for confirmation before closing a window or a tab.
Can be any of: \*(Aqalways\*(Aq, \*(Aqmultiple_terminals\*(Aq, \*(Aqnever\*(Aq.
Default value: \fBmultiple_terminals\fP
.RE
.sp
\fBborderless\fP = \fIboolean\fP

View File

@ -2,7 +2,7 @@
:doctype: manpage
:manmanual: Manual for Terminator
:mansource: Terminator
:revdate: 2023-04-22
:revdate: 2023-10-10
:docdate: {revdate}
== NAME
@ -90,10 +90,10 @@ Default value: *False*
If set to True, the window will resize in step with font sizes. +
Default value: *False*
*suppress_multiple_term_dialog* = _boolean_::
If set to True, Terminator will ask for confirmation when closing
multiple terminals. +
Default value: *False*
*ask_before_closing* = _string_::
Specify when to ask for confirmation before closing a window or a tab.
Can be any of: 'always', 'multiple_terminals', 'never'.
Default value: *multiple_terminals*
// --- Window appearance ---

View File

@ -105,7 +105,7 @@ DEFAULTS = {
'enabled_plugins' : ['LaunchpadBugURLHandler',
'LaunchpadCodeURLHandler',
'APTURLHandler'],
'suppress_multiple_term_dialog': False,
'ask_before_closing' : 'multiple_terminals',
'always_split_with_profile': False,
'putty_paste_style' : False,
'putty_paste_style_source_clipboard': False,

View File

@ -152,33 +152,54 @@ class Container(object):
"""Unzoom a terminal"""
raise NotImplementedError('unzoom')
def construct_confirm_close(self, window, reqtype):
def construct_confirm_close(self, window, child):
"""Create a confirmation dialog for closing things"""
maker = Factory()
has_multiple_terms = False
if not maker.isinstance(child, 'Terminal'):
has_multiple_terms = True
elif maker.isinstance(self, 'Window'):
has_multiple_terms = self.is_zoomed()
# skip this dialog if applicable
if self.config['suppress_multiple_term_dialog']:
if self.config['ask_before_closing'] == 'never':
return Gtk.ResponseType.ACCEPT
elif self.config['ask_before_closing'] == 'multiple_terminals':
if not has_multiple_terms:
return Gtk.ResponseType.ACCEPT
# text
confirm_button_text = (_('Close _Terminals') if has_multiple_terms
else _('Close _Terminal'))
big_label_text = (_('Close multiple terminals?') if has_multiple_terms
else _('Close terminal?'))
if not has_multiple_terms:
description_text = _('Do you really wish to close this terminal?')
elif maker.isinstance(self, 'Window'):
description_text = _('This window has several terminals open. Closing \
the window will also close all terminals within it.')
elif maker.isinstance(self, 'Notebook'):
description_text = _('This tab has several terminals open. Closing \
the tab will also close all terminals within it.')
else:
description_text = ''
# dialog GUI
dialog = Gtk.Dialog(_('Close?'), window, Gtk.DialogFlags.MODAL)
dialog.set_resizable(False)
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT)
c_all = dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)
c_all.get_children()[0].get_children()[0].get_children()[1].set_label(
_('Close _Terminals'))
confirm_button_text)
primary = Gtk.Label(label=_('<big><b>Close multiple terminals?</b></big>'))
primary = Gtk.Label(label=_('<big><b>' + big_label_text + '</b></big>'))
primary.set_use_markup(True)
primary.set_alignment(0, 0.5)
if reqtype == 'window':
label_text = _('This window has several terminals open. Closing \
the window will also close all terminals within it.')
elif reqtype == 'tab':
label_text = _('This tab has several terminals open. Closing \
the tab will also close all terminals within it.')
else:
label_text = ''
secondary = Gtk.Label(label=label_text)
secondary = Gtk.Label(label=description_text)
secondary.set_line_wrap(True)
labels = Gtk.VBox()
@ -203,7 +224,8 @@ the tab will also close all terminals within it.')
# set configuration
self.config.base.reload()
self.config['suppress_multiple_term_dialog'] = checkbox.get_active()
if checkbox.get_active():
self.config['ask_before_closing'] = 'never'
self.config.save()
dialog.destroy()

View File

@ -379,35 +379,33 @@ class Notebook(Container, Gtk.Notebook):
maker = Factory()
child = nb.get_nth_page(tabnum)
confirm_close = self.construct_confirm_close(self.window, child)
if confirm_close != Gtk.ResponseType.ACCEPT:
dbg('user cancelled request')
return
if maker.isinstance(child, 'Terminal'):
dbg('child is a single Terminal')
del nb.last_active_term[child]
child.close()
# FIXME: We only do this del and return here to avoid removing the
# page below, which child.close() implicitly does
del(label)
return
elif maker.isinstance(child, 'Container'):
dbg('child is a Container')
result = self.construct_confirm_close(self.window, _('tab'))
if result == Gtk.ResponseType.ACCEPT:
containers = None
objects = None
containers, objects = enumerate_descendants(child)
containers = None
objects = None
containers, objects = enumerate_descendants(child)
while len(objects) > 0:
descendant = objects.pop()
descendant.close()
while Gtk.events_pending():
Gtk.main_iteration()
return
else:
dbg('user cancelled request')
return
while len(objects) > 0:
descendant = objects.pop()
descendant.close()
while Gtk.events_pending():
Gtk.main_iteration()
else:
err('Notebook::closetab: child is unknown type %s' % child)
return
def resizeterm(self, widget, keyname):
"""Handle a keyboard event requesting a terminal resize"""

View File

@ -280,22 +280,15 @@ class Window(Container, Gtk.Window):
def on_delete_event(self, window, event, data=None):
"""Handle a window close request"""
maker = Factory()
if maker.isinstance(self.get_child(), 'Terminal'):
if self.is_zoomed():
return(self.confirm_close(window, _('window')))
else:
dbg('Only one child, closing is fine')
return(False)
elif maker.isinstance(self.get_child(), 'Container'):
return(self.confirm_close(window, _('window')))
else:
dbg('unknown child: %s' % self.get_child())
def confirm_close(self, window, type):
"""Display a confirmation dialog when the user is closing multiple
terminals in one window"""
return(not (self.construct_confirm_close(window, type) == Gtk.ResponseType.ACCEPT))
child = self.get_child()
if (maker.isinstance(child, 'Terminal') or
maker.isinstance(child, 'Container')):
confirm_close = self.construct_confirm_close(window, child)
return (confirm_close != Gtk.ResponseType.ACCEPT)
else:
dbg('unknown child: %s' % child)
return False # close anyway
def on_destroy_event(self, widget, data=None):
"""Handle window destruction"""