handle exit from load

This commit is contained in:
Will McGugan
2022-12-16 20:53:11 +00:00
parent cf82a120a8
commit 124df59361
3 changed files with 26 additions and 20 deletions

View File

@@ -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 - 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 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 - `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 ### Fixed

View File

@@ -350,6 +350,7 @@ class App(Generic[ReturnType], DOMNode):
self.devtools = DevtoolsClient() self.devtools = DevtoolsClient()
self._return_value: ReturnType | None = None self._return_value: ReturnType | None = None
self._exit = False
self.css_monitor = ( self.css_monitor = (
FileMonitor(self.css_path, self._on_css_change) 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. result (ReturnType | None, optional): Return value. Defaults to None.
message (RenderableType | None): Optional message to display on exit. message (RenderableType | None): Optional message to display on exit.
""" """
self._exit = True
self._return_value = result self._return_value = result
self.post_message_no_wait(messages.ExitApp(sender=self)) self.post_message_no_wait(messages.ExitApp(sender=self))
if message: if message:
@@ -1413,28 +1415,29 @@ class App(Generic[ReturnType], DOMNode):
) )
driver = self._driver = driver_class(self.console, self, size=terminal_size) driver = self._driver = driver_class(self.console, self, size=terminal_size)
driver.start_application_mode() if not self._exit:
try: driver.start_application_mode()
if headless: try:
await run_process_messages() if headless:
else: await run_process_messages()
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()
else: else:
null_file = _NullFile() if self.devtools is not None:
with redirect_stderr(null_file): devtools = self.devtools
with redirect_stdout(null_file): assert devtools is not None
await run_process_messages() from .devtools.redirect_output import StdoutRedirector
finally: redirector = StdoutRedirector(devtools)
driver.stop_application_mode() 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: except Exception as error:
self._handle_exception(error) self._handle_exception(error)

View File

@@ -297,6 +297,7 @@ class Screen(Widget):
self.focused.post_message_no_wait(events.Blur(self)) self.focused.post_message_no_wait(events.Blur(self))
self.focused.emit_no_wait(events.DescendantBlur(self)) self.focused.emit_no_wait(events.DescendantBlur(self))
self.focused = None self.focused = None
self.log.debug("focus was removed")
elif widget.can_focus: elif widget.can_focus:
if self.focused != widget: if self.focused != widget:
if self.focused is not None: if self.focused is not None:
@@ -310,6 +311,7 @@ class Screen(Widget):
self.screen.scroll_to_widget(widget) self.screen.scroll_to_widget(widget)
widget.post_message_no_wait(events.Focus(self)) widget.post_message_no_wait(events.Focus(self))
widget.emit_no_wait(events.DescendantFocus(self)) widget.emit_no_wait(events.DescendantFocus(self))
self.log.debug(widget, "was focused")
async def _on_idle(self, event: events.Idle) -> None: async def _on_idle(self, event: events.Idle) -> None:
# Check for any widgets marked as 'dirty' (needs a repaint) # Check for any widgets marked as 'dirty' (needs a repaint)