Textualize / textual

The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.
https://textual.textualize.io/
MIT License
24.07k stars 741 forks source link

Callback is not called when Screen is dismissed #4656

Closed villekr closed 2 weeks ago

villekr commented 2 weeks ago

Screen dismiss callback is not called. Confirmed with the documentation example and by adding print statement to callback function.

https://textual.textualize.io/guide/screens/#returning-data-from-screens

    def action_request_quit(self) -> None:
        """Action to display the quit dialog."""

        def check_quit(quit: bool) -> None:
            print("""Called when QuitScreen is dismissed.""")
            if quit:
                self.exit()

        self.push_screen(QuitScreen(), check_quit)

works as expected in 0.62.0 -> print statement in the console broken from 0.63.0 up to latest 0.68.0 -> no print statement in the console

Kind of critical bug. If callback is not anymore supported then please update the documentation and dismiss function accordingly.

github-actions[bot] commented 2 weeks ago

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

willmcgugan commented 2 weeks ago

I cannot reproduce this. You say you can't see the print statement, but does the app exit if you click the Quit button?

Could you please paste the results of textual diagnose.

davep commented 2 weeks ago

Just to back up what Will says, it's working perfectly fine for my with 0.68.0. As a self-contained example for you to try, complete with very visual feedback:

from textual import on
from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Button

class Test(Screen[str]):

    def compose(self) -> ComposeResult:
        yield Button("Yes", id="Yes")
        yield Button("No", id="No")

    @on(Button.Pressed)
    def test_the_callback(self, event: Button.Pressed) -> None:
        assert event.button.id is not None
        self.dismiss(event.button.id)

class ScreenCallbackTest(App[None]):

    def compose(self) -> ComposeResult:
        yield Button("Test")

    @on(Button.Pressed)
    def test_screen_callback(self) -> None:
        def show_result(result: str) -> None:
            self.notify(result)
        self.push_screen(Test(), callback=show_result)

if __name__ == "__main__":
    ScreenCallbackTest().run()

Can you confirm either way what happens for you with that code?

villekr commented 2 weeks ago

Textual Diagnostics

Versions

Name Value
Textual 0.68.0
Rich 13.7.1

Python

Name Value
Version 3.12.2
Implementation CPython
Compiler Clang 15.0.0 (clang-1500.1.0.2.5)
Executable /Users/villekarkkainen/Library/Application Support/hatch/env/virtual/paita/EKbaFG4f/paita/bin/python

Operating System

Name Value
System Darwin
Release 23.3.0
Version Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:27 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T8103

Terminal

Name Value
Terminal Application iTerm.app (3.5.2)
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=178, height=43
legacy_windows False
min_width 1
max_width 178
is_terminal True
encoding utf-8
max_height 43
justify None
overflow None
no_wrap False
highlight None
markup None
height None
villekr commented 2 weeks ago

@davep Your example works fine. But the documentation example doesn't work. Dialog is dismissed and if I select 'Quit' the app doesn't quit.

davep commented 2 weeks ago

@villekr If I run modal03.py and select quit, the app quits. This is with Textual 0.68.0.

villekr commented 2 weeks ago

Confirmed the behaviour with a new project, which only had textual dependency. Tested both with iTerm2 and macOS built-in terminal app. Same results with both.

0.62.0 - callback is called 0.63.0 (up to 0.68.0) - callback is not called

So definitely and consistently seems to be broken based on my tests.

willmcgugan commented 2 weeks ago

Have you upgraded Textual and Textual-dev ? i.e. pip install textual textual-dev -U

davep commented 2 weeks ago

@villekr How are you invoking the quit? Are you pressing the key q, or are you clicking on the option in the footer?

I'm going to guess the latter.

@willmcgugan Can you try the same with modal03.py? If I use the mouse to select the quit option from the Footer, and then attempt to quit from the dialog, it seems the callback isn't called. If I do it by pressing q on the keyboard it works fine.

willmcgugan commented 2 weeks ago

Ok, I see it if I click the footer and not if I press q!

github-actions[bot] commented 2 weeks ago

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

willmcgugan commented 2 weeks ago

Fixed in v0.69.0

villekr commented 2 weeks ago

Excellent work and super fast fix! Thank you! 0.69.0 confirmed working.