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

Implement Widget.render_delta_lines #4353

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rodrigogiraoserrao
Copy link
Contributor

The method Widget.render_delta_lines provides a mechanism for a widget to render itself and only issue strips that correspond to lines that actually changed.

The code in this draft isn't as polished as it should be but provides a fairly decent proof of concept for this feature.
At the moment, the PR shows that all widgets have opted into this system and scrollbars have explicitly opted out.
In the future, this feature will probably only be used by some widgets (and not all) but I did this to test it better.

It is easy to see that this code already skips updating large chunks of apps.
To check this, you can do something as simple as adding a print inside the method Widget.render_delta_lines:

...
if matches_cache:
    print(f"Skipped printing {len(new_strips)}.")
    y_offset += len(new_strips)
    continue

Currently there is at least one bug with the implementation.
You can trigger this bug if you have an app with a single Input widget.
Follow these steps to trigger the bug:

  1. run the app
  2. click the input to focus it
  3. click outside of the terminal so that focus goes out of the app
  4. click back in the terminal but not on the input directly

After the cursor blinks once, the top and bottom strips of the input will look weird, just like in this recording:

Screen.Recording.2024-03-28.at.15.29.52.mov

You can use this app to trigger the bug:

from textual.app import App, ComposeResult
from textual.app import App, ComposeResult
from textual.widgets import Input


class MyApp(App[None]):
    """Textual app to compute and visually display diffs."""

    AUTO_FOCUS = None

    def compose(self) -> ComposeResult:
        yield Input()


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

The method `Widget.render_delta_lines` provides a mechanism for a widget to render itself and only issue strips that correspond to lines that actually changed.
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 this pull request may close these issues.

1 participant