diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cf376002..6d7aa3251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - When looking for bindings that have priority, they are now looked from `App` downwards. https://github.com/Textualize/textual/issues/1343 - `BINDINGS` on an `App`-derived class have priority by default. https://github.com/Textualize/textual/issues/1343 - `BINDINGS` on a `Screen`-derived class have priority by default. https://github.com/Textualize/textual/issues/1343 +- Added a message parameter to Widget.exit ### Fixed diff --git a/src/textual/app.py b/src/textual/app.py index c034a2328..1b95b8400 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -350,6 +350,7 @@ class App(Generic[ReturnType], DOMNode): self.devtools = DevtoolsClient() self._return_value: ReturnType | None = None + self._exit = False self.css_monitor = ( FileMonitor(self.css_path, self._on_css_change) @@ -425,6 +426,7 @@ class App(Generic[ReturnType], DOMNode): result (ReturnType | None, optional): Return value. Defaults to None. message (RenderableType | None): Optional message to display on exit. """ + self._exit = True self._return_value = result self.post_message_no_wait(messages.ExitApp(sender=self)) if message: @@ -1413,28 +1415,29 @@ class App(Generic[ReturnType], DOMNode): ) driver = self._driver = driver_class(self.console, self, size=terminal_size) - driver.start_application_mode() - try: - if headless: - await run_process_messages() - else: - if self.devtools is not None: - devtools = self.devtools - assert devtools is not None - from .devtools.redirect_output import StdoutRedirector - - redirector = StdoutRedirector(devtools) - with redirect_stderr(redirector): - with redirect_stdout(redirector): # type: ignore - await run_process_messages() + if not self._exit: + driver.start_application_mode() + try: + if headless: + await run_process_messages() else: - null_file = _NullFile() - with redirect_stderr(null_file): - with redirect_stdout(null_file): - await run_process_messages() + if self.devtools is not None: + devtools = self.devtools + assert devtools is not None + from .devtools.redirect_output import StdoutRedirector - finally: - driver.stop_application_mode() + redirector = StdoutRedirector(devtools) + with redirect_stderr(redirector): + with redirect_stdout(redirector): # type: ignore + await run_process_messages() + else: + null_file = _NullFile() + with redirect_stderr(null_file): + with redirect_stdout(null_file): + await run_process_messages() + + finally: + driver.stop_application_mode() except Exception as error: self._handle_exception(error) diff --git a/src/textual/screen.py b/src/textual/screen.py index c08bd20b4..0de76479e 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -297,6 +297,7 @@ class Screen(Widget): self.focused.post_message_no_wait(events.Blur(self)) self.focused.emit_no_wait(events.DescendantBlur(self)) self.focused = None + self.log.debug("focus was removed") elif widget.can_focus: if self.focused != widget: if self.focused is not None: @@ -310,6 +311,7 @@ class Screen(Widget): self.screen.scroll_to_widget(widget) widget.post_message_no_wait(events.Focus(self)) widget.emit_no_wait(events.DescendantFocus(self)) + self.log.debug(widget, "was focused") async def _on_idle(self, event: events.Idle) -> None: # Check for any widgets marked as 'dirty' (needs a repaint)