Merge pull request #834 from Vulcalien/ask-before-closing
Ask before closing, even if there is only one terminal
This commit is contained in:
commit
b47f7d073e
|
@ -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
|
||||||
|
|
|
@ -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 ---
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
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 = 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()
|
||||||
|
|
|
@ -379,35 +379,33 @@ 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)
|
|
||||||
|
|
||||||
while len(objects) > 0:
|
while len(objects) > 0:
|
||||||
descendant = objects.pop()
|
descendant = objects.pop()
|
||||||
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"""
|
||||||
|
|
|
@ -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():
|
child = self.get_child()
|
||||||
return(self.confirm_close(window, _('window')))
|
if (maker.isinstance(child, 'Terminal') or
|
||||||
else:
|
maker.isinstance(child, 'Container')):
|
||||||
dbg('Only one child, closing is fine')
|
confirm_close = self.construct_confirm_close(window, child)
|
||||||
return(False)
|
return (confirm_close != Gtk.ResponseType.ACCEPT)
|
||||||
elif maker.isinstance(self.get_child(), 'Container'):
|
|
||||||
return(self.confirm_close(window, _('window')))
|
|
||||||
else:
|
else:
|
||||||
dbg('unknown child: %s' % self.get_child())
|
dbg('unknown child: %s' % child)
|
||||||
|
return False # close anyway
|
||||||
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))
|
|
||||||
|
|
||||||
def on_destroy_event(self, widget, data=None):
|
def on_destroy_event(self, widget, data=None):
|
||||||
"""Handle window destruction"""
|
"""Handle window destruction"""
|
||||||
|
|
Loading…
Reference in New Issue