diff options
| -rw-r--r-- | changes/bug_3047_wizard_hangs_client_on_termination | 1 | ||||
| -rw-r--r-- | src/leap/gui/mainwindow.py | 18 | ||||
| -rw-r--r-- | src/leap/gui/wizard.py | 11 | ||||
| -rw-r--r-- | src/leap/services/abstractbootstrapper.py | 3 | 
4 files changed, 26 insertions, 7 deletions
| diff --git a/changes/bug_3047_wizard_hangs_client_on_termination b/changes/bug_3047_wizard_hangs_client_on_termination new file mode 100644 index 00000000..00af4738 --- /dev/null +++ b/changes/bug_3047_wizard_hangs_client_on_termination @@ -0,0 +1 @@ +  o Make wizard use the main event loop, ensuring clean termination. diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 7180139a..52caf08e 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -310,12 +310,22 @@ class MainWindow(QtGui.QMainWindow):          if self._wizard is None:              self._wizard = Wizard(bypass_checks=self._bypass_checks)              self._wizard.accepted.connect(self._finish_init) +            self._wizard.rejected.connect(self._wizard.close)          self.setVisible(False) -        self._wizard.exec_() -        # We need this to process any wizard related event -        QtCore.QCoreApplication.processEvents() -        self._wizard = None +        # Do NOT use exec_, it will use a child event loop! +        # Refer to http://www.themacaque.com/?p=1067 for funny details. +        self._wizard.show() +        self._wizard.finished.connect(self._wizard_finished) + +    def _wizard_finished(self): +        """ +        SLOT +        TRIGGERS +          self._wizard.finished + +        Called when the wizard has finished. +        """          self.setVisible(True)      def _get_leap_logging_handler(self): diff --git a/src/leap/gui/wizard.py b/src/leap/gui/wizard.py index 67ade349..5333edeb 100644 --- a/src/leap/gui/wizard.py +++ b/src/leap/gui/wizard.py @@ -125,6 +125,11 @@ class Wizard(QtGui.QWizard):          self._domain = None          self._provider_config = ProviderConfig() +        # We will store a reference to the defers for eventual use +        # (eg, to cancel them) but not doing anything with them right now. +        self._provider_select_defer = None +        self._provider_setup_defer = None +          self.currentIdChanged.connect(self._current_id_changed)          self.ui.lblPassword.setEchoMode(QtGui.QLineEdit.Password) @@ -361,8 +366,8 @@ class Wizard(QtGui.QWizard):          self._domain = self.ui.lnProvider.text()          self.ui.lblNameResolution.setPixmap(self.QUESTION_ICON) -        self._provider_bootstrapper.run_provider_select_checks( -            self._domain) +        self._provider_select_defer = self._provider_bootstrapper.\ +            run_provider_select_checks(self._domain)      def _complete_task(self, data, label, complete=False, complete_page=-1):          """ @@ -561,7 +566,7 @@ class Wizard(QtGui.QWizard):                                            (self._provider_config                                             .get_name(),))              self.ui.lblDownloadCaCert.setPixmap(self.QUESTION_ICON) -            self._provider_bootstrapper.\ +            self._provider_setup_defer = self._provider_bootstrapper.\                  run_provider_setup_checks(self._provider_config)          if pageId == self.PRESENT_PROVIDER_PAGE: diff --git a/src/leap/services/abstractbootstrapper.py b/src/leap/services/abstractbootstrapper.py index 633d818d..9e50948c 100644 --- a/src/leap/services/abstractbootstrapper.py +++ b/src/leap/services/abstractbootstrapper.py @@ -142,6 +142,9 @@ class AbstractBootstrapper(QtCore.QObject):          :param callbacks: List of tuples of callbacks and the signal                            associated to that callback          :type callbacks: list(tuple(func, func)) + +        :returns: the defer with the callback chain +        :rtype: deferred          """          leap_assert_type(callbacks, list) | 
