Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ask before closing, even if there is only one terminal #834

Merged
merged 2 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions doc/terminator_config.5
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions doc/terminator_config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
:doctype: manpage
:manmanual: Manual for Terminator
:mansource: Terminator
:revdate: 2023-04-22
:revdate: 2023-10-10
:docdate: {revdate}

== NAME
Expand Down Expand Up @@ -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 ---

Expand Down
2 changes: 1 addition & 1 deletion terminatorlib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
'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,
Expand Down
54 changes: 38 additions & 16 deletions terminatorlib/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,33 +152,54 @@ def unzoom(self, widget):
"""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()
Expand All @@ -203,7 +224,8 @@ def construct_confirm_close(self, window, reqtype):

# 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()
Expand Down
34 changes: 16 additions & 18 deletions terminatorlib/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,35 +379,33 @@ def closetab(self, widget, label):
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)

while len(objects) > 0:
descendant = objects.pop()
descendant.close()
while Gtk.events_pending():
Gtk.main_iteration()
return
else:
dbg('user cancelled request')
return

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()
else:
err('Notebook::closetab: child is unknown type %s' % child)
return

def resizeterm(self, widget, keyname):
"""Handle a keyboard event requesting a terminal resize"""
Expand Down
23 changes: 8 additions & 15 deletions terminatorlib/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,22 +280,15 @@ def tab_new(self, widget=None, debugtab=False, _param1=None, _param2=None):
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"""
Expand Down
Loading