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 '\" t
.\" Title: terminator_config .\" Title: terminator_config
.\" Author: [see the "AUTHOR(S)" section] .\" Author: [see the "AUTHOR(S)" section]
.\" Generator: Asciidoctor 2.0.18 .\" Generator: Asciidoctor 2.0.16
.\" Date: 2023-04-22 .\" Date: 2023-10-10
.\" Manual: Manual for Terminator .\" Manual: Manual for Terminator
.\" Source: Terminator .\" Source: Terminator
.\" Language: English .\" 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 .ie \n(.g .ds Aq \(aq
.el .ds Aq ' .el .ds Aq '
.ss \n[.ss] 0 .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 Default value: \fBFalse\fP
.RE .RE
.sp .sp
\fBsuppress_multiple_term_dialog\fP = \fIboolean\fP \fBask_before_closing\fP = \fIstring\fP
.RS 4 .RS 4
If set to True, Terminator will ask for confirmation when closing Specify when to ask for confirmation before closing a window or a tab.
multiple terminals. Can be any of: \*(Aqalways\*(Aq, \*(Aqmultiple_terminals\*(Aq, \*(Aqnever\*(Aq.
.br Default value: \fBmultiple_terminals\fP
Default value: \fBFalse\fP
.RE .RE
.sp .sp
\fBborderless\fP = \fIboolean\fP \fBborderless\fP = \fIboolean\fP

View File

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

View File

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

View File

@ -152,33 +152,54 @@ class Container(object):
"""Unzoom a terminal""" """Unzoom a terminal"""
raise NotImplementedError('unzoom') raise NotImplementedError('unzoom')
def construct_confirm_close(self, window, reqtype): def construct_confirm_close(self, window, child):
"""Create a confirmation dialog for closing things""" """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 # 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 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 = Gtk.Dialog(_('Close?'), window, Gtk.DialogFlags.MODAL)
dialog.set_resizable(False) dialog.set_resizable(False)
dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT)
c_all = dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT) c_all = dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)
c_all.get_children()[0].get_children()[0].get_children()[1].set_label( 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_use_markup(True)
primary.set_alignment(0, 0.5) primary.set_alignment(0, 0.5)
if reqtype == 'window':
label_text = _('This window has several terminals open. Closing \ secondary = Gtk.Label(label=description_text)
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.set_line_wrap(True) secondary.set_line_wrap(True)
labels = Gtk.VBox() labels = Gtk.VBox()
@ -203,7 +224,8 @@ the tab will also close all terminals within it.')
# set configuration # set configuration
self.config.base.reload() 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() self.config.save()
dialog.destroy() dialog.destroy()

View File

@ -379,19 +379,22 @@ class Notebook(Container, Gtk.Notebook):
maker = Factory() maker = Factory()
child = nb.get_nth_page(tabnum) 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'): if maker.isinstance(child, 'Terminal'):
dbg('child is a single Terminal') dbg('child is a single Terminal')
del nb.last_active_term[child] del nb.last_active_term[child]
child.close() child.close()
# FIXME: We only do this del and return here to avoid removing the # FIXME: We only do this del and return here to avoid removing the
# page below, which child.close() implicitly does # page below, which child.close() implicitly does
del(label) del(label)
return
elif maker.isinstance(child, 'Container'): elif maker.isinstance(child, 'Container'):
dbg('child is a Container') dbg('child is a Container')
result = self.construct_confirm_close(self.window, _('tab'))
if result == Gtk.ResponseType.ACCEPT:
containers = None containers = None
objects = None objects = None
containers, objects = enumerate_descendants(child) containers, objects = enumerate_descendants(child)
@ -401,13 +404,8 @@ class Notebook(Container, Gtk.Notebook):
descendant.close() descendant.close()
while Gtk.events_pending(): while Gtk.events_pending():
Gtk.main_iteration() Gtk.main_iteration()
return
else:
dbg('user cancelled request')
return
else: else:
err('Notebook::closetab: child is unknown type %s' % child) err('Notebook::closetab: child is unknown type %s' % child)
return
def resizeterm(self, widget, keyname): def resizeterm(self, widget, keyname):
"""Handle a keyboard event requesting a terminal resize""" """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): def on_delete_event(self, window, event, data=None):
"""Handle a window close request""" """Handle a window close request"""
maker = Factory() 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): child = self.get_child()
"""Display a confirmation dialog when the user is closing multiple if (maker.isinstance(child, 'Terminal') or
terminals in one window""" maker.isinstance(child, 'Container')):
confirm_close = self.construct_confirm_close(window, child)
return(not (self.construct_confirm_close(window, type) == Gtk.ResponseType.ACCEPT)) return (confirm_close != Gtk.ResponseType.ACCEPT)
else:
dbg('unknown child: %s' % child)
return False # close anyway
def on_destroy_event(self, widget, data=None): def on_destroy_event(self, widget, data=None):
"""Handle window destruction""" """Handle window destruction"""