Repository: Textualize/textual

Issue:
Line drawing artefacts in `Tree` on Windows, in Windows Terminal
To start with I'm adding this as a tentative bug report, as I doubt it's really a `Tree` or `DirectoryTree` issue, but I have never seen it before and only noticed it while testing the work done on #2545; it's very likely going to require some attempts at isolation.

Simply put, while playing with a sandbox application to soak-test the worker-updating of `DirectoryTree` on Windows, depending on terminal size, sometimes I'd see artefacts like this:

![Screenshot 2023-05-11 at 15 09 31](https://github.com/Textualize/textual/assets/28237/b58be7e4-305f-49f9-9c2d-9bc777efd981)

Presumably the old "multibyte character got truncated" issue. Unsurprisingly it would then throw off the rest of the line it was on:

![Screenshot 2023-05-11 at 15 10 37](https://github.com/Textualize/textual/assets/28237/2332ad62-6e66-4a12-a30e-4e6521d37858)

Here's the whole terminal, putting it in context (see the bottom row):

<img width="1501" alt="Screenshot 2023-05-11 at 14 02 32" src="https://github.com/Textualize/textual/assets/28237/692331b9-2a89-407b-8d48-a1aa674eb8bc">

However... in this particular case, the issue would only show up if focus was within the first six director trees (the first two rows). If I tabbed focus into any of the final three it would fix itself:

<img width="1511" alt="Screenshot 2023-05-11 at 14 02 56" src="https://github.com/Textualize/textual/assets/28237/7124fbda-9cd1-4bbf-9dd0-84474cf947b8">

<img width="1505" alt="Screenshot 2023-05-11 at 14 03 09" src="https://github.com/Textualize/textual/assets/28237/f0b1cea4-5051-4a8e-8ce8-c424ca41045d">

<img width="1505" alt="Screenshot 2023-05-11 at 14 03 20" src="https://github.com/Textualize/textual/assets/28237/af985f7c-1c14-43e7-8c48-38a61ce6af9e">

As mentioned above, this did seem to change the way it worked depending on the size of the terminal, and the content; but I didn't really spend too much time trying to narrow that down as I was trying to concentrate on the thing I was in Windows to test.

I've not been able to recreate the issue on macOS.

Like I say: this is placed here for further investigation, and hopefully to take a bit of time to try and come up with a way to replicate the problem in as minimal an example as possible.


Discussion:
Update: not just line drawing characters. Still only seeing this in Windows Terminal. This particular glitch only happened when the focus was on the same row.

<img width="1525" alt="Screenshot 2023-05-17 at 13 31 09" src="https://github.com/Textualize/textual/assets/28237/40e0a148-f999-404d-a0e2-de61d2686522">

<img width="210" alt="Screenshot 2023-05-17 at 13 31 20" src="https://github.com/Textualize/textual/assets/28237/c3e07c93-eca8-4e59-8d50-2c2b17795f6f">

I've got the same problem on Windows as well.
@willmcgugan Looking back to find this issue again and this very much looks to be the same thing we were looking at at my desk just now, with the key tester/recorder app under Windows (both Terminal and Hyper). The behaviour I recorded above, with the directory tree, displayed all the same symptoms and had the same feel in regards to the possible underlying cause (multibyte character at the end of a buffer sort of thing).
Moving this into todo. I feel this is important enough that it go into the queue of things getting attention soon; even if it's to narrow down the cause.
@davep This behaviour is a bit unpredictable, but from playing around with this I _think_ I've discovered that weirdly this seems to go away when the padding setting in Windows Terminal is set to zero...
Interesting. The working hypothesis was that it was a buffer size issue on our side (either in Textual or Python). Hadn't considered it would be a Windows Terminal issue. 

It'll be interesting to try and reproduce the issue in Tabby, Wez or Hyper, etc. What you say suggests it should not happen. 
I might be wrong as the behaviour is a bit unpredictable.  But interestingly, it looks like the problem also goes away if you set the padding to the same size as the font.

Edit: Nope, looks I can reproduce on Wezterm after minimising then maximizing the window, so this must just be pure coincidence, sorry.

![image](https://github.com/Textualize/textual/assets/101601846/6cfb521c-5d45-4624-bf64-c7884e06cdea)

No apologies needed. All useful stuff for eliminating the possible causes and influences. 
While messing around with resizing the Windows Terminal, I found you also can create other strange displays like below. The other screenshots show missing glyhs, whereas here it looks like the bottom corner of the border has been duplicated. 

![image](https://github.com/Textualize/textual/assets/101601846/e2521570-a087-44ba-b282-03d674c917c9)

Trying to make a small tool that will hopefully allow me to get a stable reproduction of this issue and... so far so good. One thing I've found is that, given a particular terminal size (I've not tried other sizes yet, that's next), I *can* get corruption to appear at the exact same spot, every single time:

![Screenshot 2023-11-07 at 11 31 27](https://github.com/Textualize/textual/assets/28237/f456faf7-00ad-4543-8215-443a48c52d81)

If I close the app down, run it up again, the corruption appears in the same place, starting around character 1504. The second location is always 3584.
Different terminal sizes have the corruption at different locations, but always in the same location every time. There is a pattern. Likewise, if i make a fresh terminal the same size as the one above, I see the exact same pattern.
🍿 
Using the same test application, I've recreated the problem, with very similar results, using:

- Hyper
- Wez
- Tabby

I did try rio too but, while I've managed to install it, I can't seem to get it running to the point that I get a prompt. I think it's fair to assume though that the issue will be evident there also. This would very much suggest that the problem is either within Textual itself, or something in the Windows build of Python.

Resolving patch:
diff --git a/src/textual/app.py b/src/textual/app.py
--- a/src/textual/app.py
+++ b/src/textual/app.py
@@ -2526,7 +2526,22 @@ def _display(self, screen: Screen, renderable: RenderableType | None) -> None:
                     except Exception as error:
                         self._handle_exception(error)
                     else:
-                        self._driver.write(terminal_sequence)
+                        if WINDOWS:
+                            # Combat a problem with Python on Windows.
+                            #
+                            # https://github.com/Textualize/textual/issues/2548
+                            # https://github.com/python/cpython/issues/82052
+                            CHUNK_SIZE = 8192
+                            write = self._driver.write
+                            for chunk in (
+                                terminal_sequence[offset : offset + CHUNK_SIZE]
+                                for offset in range(
+                                    0, len(terminal_sequence), CHUNK_SIZE
+                                )
+                            ):
+                                write(chunk)
+                        else:
+                            self._driver.write(terminal_sequence)
                 finally:
                     self._end_update()
 


Test patch: