You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adding await to self.app.pop_screen causes app to freeze when triggered via button, but works fine when triggered via key binding.
from __future__ importannotationsfromtypingimportcastfromtextualimportonfromtextual.appimportApp, ComposeResultfromtextual.bindingimportBindingfromtextual.screenimportScreenfromtextual.widgetsimportButton, Footer, Header, LabelclassFirstScreen(Screen):
defcompose(self) ->ComposeResult:
yieldHeader()
yieldLabel("this is the first screen")
yieldFooter()
classSecondScreen(Screen):
defcompose(self) ->ComposeResult:
yieldHeader()
yieldLabel("this is the second screen")
yieldButton("Pop back to first screen")
yieldFooter()
@on(Button.Pressed)asyncdefpressed(self) ->None:
app=cast(MyApp, self.app)
app.notify("Going back to first screen...")
awaitapp.action_pop_current_screen()
classMyApp(App):
BINDINGS= [
Binding("a", "pop_current_screen", "Pop screen"), # key binding works just fine with awaitBinding("d", "push", "Push screen"),
]
asyncdefon_mount(self) ->None:
awaitself.push_screen(FirstScreen())
asyncdefaction_pop_current_screen(self) ->None:
whilenotisinstance(self.screen, FirstScreen):
awaitself.pop_screen() # awaiting causes the bug, removing await fixes it in case of pressing the buttonasyncdefaction_push(self) ->None:
awaitself.push_screen(SecondScreen())
MyApp().run()
The text was updated successfully, but these errors were encountered:
By awaiting the pop_screen, you are waiting for all its messages to be processed. But your button.pressed message handler will never return, because it is waiting for itself to be popped. In other words, a deadlock.
I suspect the best thing for us to do is make it error / warning. To fix it, you can add @work to your action.
Putting @work over MyApp.action_pop_current_screen solves the case here. I thought it would be the same as self.run_worker(app.action_pop_current_screen()) in SecondScreen.pressed, however the second one crashes without any error.
Because real scenario is something more like: #5009
so putting @work over such an App method is a no-go for me.
By awaiting the pop_screen, you are waiting for all its messages to be processed
But in the case of pop_screen, there is no need to wait for all the screen messages to be processed I think? Because this call will destroy this screen anyway, so shouldn't it prioritize it over other messages?
Version: 0.79.1
Adding
await
toself.app.pop_screen
causes app to freeze when triggered via button, but works fine when triggered via key binding.The text was updated successfully, but these errors were encountered: