Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[20_13] Do not add duplicated values to copy_always to avoid stack ov…
…erflow <!-- Thank you for your contribution! --> ## What Add check before adding new values to `edit_interface_rep::copy_always` in function `edit_interface_rep::apply_changes()`. New rectangle will be added to `copy_always` if `copy_always` is empty/nil or the first item of `copy_always` is not equal to newly added value. ## Why Since `apply_changes()` will be called when the window receives any event, `copy_always` will become very large and cause stack overflow when it's cleared. The `copy_always` is a linked list and when it's cleared, the destructor is called from head to tail recursively, causing stack overflow. ## How to test your changes? That's the potential risk: I can only test it on Windows with few scenarios, I don't know the result in Linux, Mac. already run `xmake run --yes -vD --group=tests` and `xmake run --yes -vD --group=integration_tests` The investigations below are all in Windows environment. ### Where is the code to clear `copy_always`? In `edit_interface_rep::scroll_to()` and `edit_interface_rep::set_extents()`, by using `copy_always = rectangles ()`. ### When will `copy_always` be cleared? `scroll_to()` is called when the cursor is moved out of current view. I can't add breakpoint in `set_extents()`, I don't know when will it will be called. ### What's the purpose of `copy_always`? The comment says it's used for wiping out cursor. However I think it doesn't do anything now. I comment out the code that uses it, get nothing wrong. But removing it is more dangerous. ### Where is `copy_always` used? In `edit_interface_rep::draw_pre()` and `edit_interface_rep::draw_with_shadow()`. In `draw_pre()`, it will go through all rectangles in `copy_always` and call `win->put_shadow()`, but it doesn't draw anything at all. Because in `qt_renderer_rep::put_shadow()`, `painter == static_cast<qt_renderer_rep*> (ren)->painter` is true and returns directly. In `draw_with_shadow()`, it's only used if `gui_interrupted()` returns true, but `gui_interrupted()` doesn't return true in my machine. These shadow functions are related to the double buffering, the behavior may be different in other OS. In summary, I don't think it's necessary to store all the old rectangles in `copy_always`. The latest ones `ocr`(old cursor) and `ncr`(new cursor) should be enough for cursor drawing stuff.
- Loading branch information