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

TextLog w/ max_lines only refreshes on powers-of-10 line writes? #1058

Closed
mindset-team opened this issue Oct 30, 2022 · 2 comments · Fixed by #1068
Closed

TextLog w/ max_lines only refreshes on powers-of-10 line writes? #1058

mindset-team opened this issue Oct 30, 2022 · 2 comments · Fixed by #1068
Assignees
Labels
bug Something isn't working

Comments

@mindset-team
Copy link

mindset-team commented Oct 30, 2022

Using TextLog with max_lines defined doesn't seem to work as intended, with the widget refreshing every power-of-10 line writes (sounds very weird, keep reading).

Code below writes to the text log every time a key is pressed ("Key press #{counter}") and advance a counter. With max_lines=3, three lines are printed out, sequentially and as expected:

from textual.app import App
from textual.widgets import TextLog

class TextLogLines(App):
    count = 0

    def compose(self):
        yield TextLog(max_lines=3)

    async def on_key(self):
        self.count += 1
        log_widget = self.query_one(TextLog)
        log_widget.write(f"Key press #{self.count}")
        print(log_widget.lines)  # Sanity check via `textual console`
        print(dict(log_widget._line_cache))  # What's in the cache?

app = TextLogLines()

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

A fourth press should refresh the TextLog and show lines #1,#2,#3. However, it doesn't. The print statement (as viewed at the output of textual console) shows the proper array of lines (list is 3-members long as one would expect from the source code.

Up to now this might be a "reasonably-misbehaving" bug - but if the key is pressed multiple times, the widget refreshes at the 10th press. This happens again at 100 (namely, no refresh when counter=11 to 99, but with the 100th press, the widget refreshed). 10, 100, best guess of next refresh is 1000 and indeed, widget refreshes again at 1000. Same at 10k line writes.

This odd behavior was observed with varying screen sizes, and max_line values (if max_lines > 10, e.g. 30 widget fills to 30 lines just fine, but next refresh is at 100 line writes).

Might this be somehow related to the LRUCache? Looking at the console output, the LRU cache fills to the third line, only updates on the 11th log write, but shows lines 1,2,3, 8,9,10 cached. Here's the output (well after the 11th write, for both the self.lines object and the LRU cache):

[00:58:44] PRINT                                                                                                                 main.py:24
[[Segment('Key press #31')], [Segment('Key press #32')], [Segment('Key press #33')]]
[00:58:44] PRINT                                                                                                                 main.py:25
{(0, 0, 139, 12): [Segment('Key press #1'), Segment('
', Style(color=Color('#e1e1e1', ColorType.TRUECOLOR, triplet=ColorTriplet(red=225, green=225, blue=225)), bgcolor=Color('#1e1e1e',
ColorType.TRUECOLOR, triplet=ColorTriplet(red=30, green=30, blue=30))))], (1, 0, 139, 12): [Segment('Key press #2'), Segment('
', Style(color=Color('#e1e1e1', ColorType.TRUECOLOR, triplet=ColorTriplet(red=225, green=225, blue=225)), bgcolor=Color('#1e1e1e',
ColorType.TRUECOLOR, triplet=ColorTriplet(red=30, green=30, blue=30))))], (2, 0, 139, 12): [Segment('Key press #3'), Segment('
', Style(color=Color('#e1e1e1', ColorType.TRUECOLOR, triplet=ColorTriplet(red=225, green=225, blue=225)), bgcolor=Color('#1e1e1e',
ColorType.TRUECOLOR, triplet=ColorTriplet(red=30, green=30, blue=30))))], (0, 0, 139, 13): [Segment('Key press #8'), Segment('
', Style(color=Color('#e1e1e1', ColorType.TRUECOLOR, triplet=ColorTriplet(red=225, green=225, blue=225)), bgcolor=Color('#1e1e1e',
ColorType.TRUECOLOR, triplet=ColorTriplet(red=30, green=30, blue=30))))], (1, 0, 139, 13): [Segment('Key press #9'), Segment('
', Style(color=Color('#e1e1e1', ColorType.TRUECOLOR, triplet=ColorTriplet(red=225, green=225, blue=225)), bgcolor=Color('#1e1e1e',
ColorType.TRUECOLOR, triplet=ColorTriplet(red=30, green=30, blue=30))))], (2, 0, 139, 13): [Segment('Key press #10'), Segment('
', Style(color=Color('#e1e1e1', ColorType.TRUECOLOR, triplet=ColorTriplet(red=225, green=225, blue=225)), bgcolor=Color('#1e1e1e',
ColorType.TRUECOLOR, triplet=ColorTriplet(red=30, green=30, blue=30))))]}

Without knowing much about LRU cache behavior, it seems odd to have these two groups of Segments cached, w/o anything in between, and it's unclear how any of this might lead to power-of-10 refreshes.

@mindset-team mindset-team changed the title TextLog w/ max_lines only refreshes on powers of 10? TextLog w/ max_lines only refreshes on powers-of-10 line writes? Oct 30, 2022
@willmcgugan willmcgugan self-assigned this Oct 30, 2022
@willmcgugan willmcgugan added the bug Something isn't working label Oct 30, 2022
@willmcgugan
Copy link
Collaborator

Thanks for the bug report. Should have a fix shortly.

The powers of ten issue was because the maximum width changed when you added an extra digit ti the key number.

@github-actions
Copy link

Did we solve your problem?

Glad we could help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants