From 8911723518befa50e4031e623bd6e4d806a9d341 Mon Sep 17 00:00:00 2001 From: Vulcalien Date: Tue, 10 Oct 2023 15:47:39 +0200 Subject: [PATCH 1/2] Window: always ask confirmation to close, even with only one terminal --- terminatorlib/window.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 9cf7f688..3b9d88fa 100644 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -280,22 +280,14 @@ 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'))) + + if (maker.isinstance(self.get_child(), 'Terminal') or + maker.isinstance(self.get_child(), 'Container')): + confirm_close = self.construct_confirm_close(window, _('window')) + return (confirm_close != Gtk.ResponseType.ACCEPT) 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)) + return False # close anyway def on_destroy_event(self, widget, data=None): """Handle window destruction""" From 8c0c7ceb4fb6d3817824d78ed1c42a82ca9baade Mon Sep 17 00:00:00 2001 From: Vulcalien Date: Tue, 10 Oct 2023 17:03:21 +0200 Subject: [PATCH 2/2] Add a setting to specify when to ask to confirm before closing 'ask_before_closing' replaces 'suppress_multiple_term_dialog'. The function 'Container.construct_confirm_close' was significantly modified. The terminator_config manpage has been updated. --- doc/terminator_config.5 | 15 +++++------ doc/terminator_config.adoc | 10 +++---- terminatorlib/config.py | 2 +- terminatorlib/container.py | 54 +++++++++++++++++++++++++++----------- terminatorlib/notebook.py | 34 +++++++++++------------- terminatorlib/window.py | 9 ++++--- 6 files changed, 72 insertions(+), 52 deletions(-) diff --git a/doc/terminator_config.5 b/doc/terminator_config.5 index 04b1e084..4af2ca9b 100644 --- a/doc/terminator_config.5 +++ b/doc/terminator_config.5 @@ -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 diff --git a/doc/terminator_config.adoc b/doc/terminator_config.adoc index bcca88ff..d0b89fe8 100644 --- a/doc/terminator_config.adoc +++ b/doc/terminator_config.adoc @@ -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 --- diff --git a/terminatorlib/config.py b/terminatorlib/config.py index 4fbb907d..45350611 100644 --- a/terminatorlib/config.py +++ b/terminatorlib/config.py @@ -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, diff --git a/terminatorlib/container.py b/terminatorlib/container.py index ba7ab8d3..14192779 100644 --- a/terminatorlib/container.py +++ b/terminatorlib/container.py @@ -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=_('Close multiple terminals?')) + primary = Gtk.Label(label=_('' + big_label_text + '')) 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 @@ 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() diff --git a/terminatorlib/notebook.py b/terminatorlib/notebook.py index eb630b17..de67c2ac 100644 --- a/terminatorlib/notebook.py +++ b/terminatorlib/notebook.py @@ -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""" diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 3b9d88fa..69e999f9 100644 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -281,12 +281,13 @@ def on_delete_event(self, window, event, data=None): """Handle a window close request""" maker = Factory() - if (maker.isinstance(self.get_child(), 'Terminal') or - maker.isinstance(self.get_child(), 'Container')): - confirm_close = self.construct_confirm_close(window, _('window')) + 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' % self.get_child()) + dbg('unknown child: %s' % child) return False # close anyway def on_destroy_event(self, widget, data=None):