diff --git a/gooey/gui/containers/application.py b/gooey/gui/containers/application.py index 3926e44..b490834 100644 --- a/gooey/gui/containers/application.py +++ b/gooey/gui/containers/application.py @@ -170,7 +170,13 @@ class GooeyApplication(wx.Frame): def onClose(self, *args, **kwargs): - """Cleanup the top level WxFrame and shutdown the process""" + """Stop any actively running client program, cleanup the top + level WxFrame and shutdown the current process""" + # issue #592 - we need to run the same onStopExecution machinery + # when the exit button is clicked to ensure everything is cleaned + # up correctly. + if self.clientRunner.running(): + self.onStopExecution() self.Destroy() sys.exit() diff --git a/gooey/tests/test_application.py b/gooey/tests/test_application.py index 1498b17..9447dec 100644 --- a/gooey/tests/test_application.py +++ b/gooey/tests/test_application.py @@ -1,3 +1,4 @@ +import sys import unittest from argparse import ArgumentParser from collections import namedtuple @@ -55,6 +56,26 @@ class TestGooeyApplication(unittest.TestCase): else: mockClientRunner.stop.assert_not_called() + @patch("gui.containers.application.modals.confirmForceStop") + def testOnCloseShutsDownActiveClients(self, mockModal): + """ + Issue 592: Closing the UI should clean up any actively running programs + """ + parser = self.basicParser() + with instrumentGooey(parser) as (app, gapp): + with patch('gui.containers.application.sys.exit') as exitmock: + gapp.clientRunner = MagicMock() + gapp.Destroy = MagicMock() + # mocking that the user clicks "yes shut down" in the warning modal + mockModal.return_value = True + gapp.onClose() + + mockModal.assert_called() + gapp.Destroy.assert_called() + exitmock.assert_called() + + + def basicParser(self):