Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling pop_screen multiple times causes a flickering effect #3126

Closed
mzebrak opened this issue Aug 21, 2023 · 2 comments · Fixed by #3194
Closed

Calling pop_screen multiple times causes a flickering effect #3126

mzebrak opened this issue Aug 21, 2023 · 2 comments · Fixed by #3194

Comments

@mzebrak
Copy link

mzebrak commented Aug 21, 2023

Consider the example below. When calling pop_screen multiple times (which is not so unusual - because a "form" structure where we can go through subsequent screens can work in such a way that it dumps all screens after approval), flickering occurs.

import random
from typing import Callable

from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.color import Color
from textual.containers import Container
from textual.screen import Screen
from textual.widgets import Footer, Header


class SomeScreen(Screen):
    def compose(self) -> ComposeResult:
        yield Header()

        element = Container()
        element.styles.background = self._get_random_color()
        yield element

        yield Footer()

    @staticmethod
    def _get_random_color() -> Color:
        def rand() -> int:
            return random.randint(0, 255)
        return Color(rand(), rand(), rand())


class MyApp(App[None]):
    BINDINGS = [
        Binding("p", "pop", "Pop multiple screens"),
    ]

    def on_mount(self) -> None:
        self.push_screen(SomeScreen(id="first"))
        for _ in range(50):
            self.push_screen(SomeScreen())

    def action_pop(self) -> None:
        self.pop_screen_until(lambda screen: screen.id == "first")

    def pop_screen_until(self, condition_callback: Callable[[Screen], bool]) -> None:
        while not condition_callback(self.screen):
            self.pop_screen()


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

What I tried is with self.batch_update() context manager but it seems it does not work in this context.
Maybe it's possible to extend the batch_update method to apply it on screen-related actions also or create a new method like batch_screen_update?

@github-actions
Copy link

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

@github-actions
Copy link

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant