FIX #7357: Event sheet tabs take a second to set correct layout
This PR addresses and fixes this issue by implementing layout caching and pre-resize logic to significantly improve the user experience when switching between external event tabs in the GDevelop Events Editor. Previously, users encountered a 1–2 second delay before the conditions column resized properly, along with layout flickering, inconsistent column widths across tabs, and poor text wrapping that caused the UI to feel unresponsive and visually unstable.
The root cause was that layout calculations (such as column widths) were performed after rendering, and each tab recalculated widths independently without caching. To solve this, we introduced an independent caching system (for each tab) that stores and restores the total tab width, conditions column width, and actions column width, allowing each tab to retain its layout immediately upon being shown. These layout values are now computed before the UI is rendered, eliminating flicker and visual jumps.
Additionally, we added maximum width constraints to condition and action cells, enabling proper text wrapping that also prevents text overflow. Moreover, we developed automated tests to ensure long-term stability and correctness of the layout behaviour.
The result is a much smoother, flicker-free tab switching experience with consistent column widths, better text readability, and improved responsiveness in the Events Editor, even for projects with long or complex events.
Hi! Thanks for opening this PR. :)
Would you be able to record a video of the cases where flicker disappeared? Can you also post screenshots of the "proper text wrapping"?
Thank you!
Hi @4ian, yes of course! Here follows a video of the flickering disappearing and a screenshot of the text wrapping, respectively.
https://github.com/user-attachments/assets/8527195d-6c06-4218-a477-8c745c436b2b
In relation to the text-wrapping, we just ensured it was all always visible and that it wasn't cut or under other layers etc... What we corrected, was we made sure that the width of all the condition and action columns is the same on every event-tab sheet. The text wrapping is the same as before, but as it looks automatic, when we fixed the widths, it looked automatically fixed. We also did some user-testing to ensure it was fixed.
Ok, can you merge the master branch on your branch (or rebase your branch and then force push, as you prefer) so that we can test this with the latest changes that have been done on master?
I will then make some manual tests to see how this behaves. Thank you again :)
Ok I think I have done what you asked @4ian, is it all correct and ok?
You properly rebased the branch indeed, thanks. I'm sorry but I'm not sure I can find by myself the improvement on the user experience here - I can't find the responsiveness improvement or "consistent" column width?
Can you make a video or two showing the exact same things being done on GDevelop with this change and without this change (using editor.gdevelop.io)? When I go on editor.gdevelop.io, I can instantly switch between events of a scene or external events. There is some flickering but it's happening at the first render when the tab is opened for the first time.
As this adds some complexity with a new cache, cache keys and computations, I need to be sure I understand what this is changing exactly. I know this is a bit of a pain, but I would need a video showing exactly the improvement and that can be compared with the existing version :)
Note that I've had a report from another user showing a "jump" in the width of the condition column when switching between events sheet. It's interesting because it never happened to me before. If you can make a video, this will help confirm we're dealing with the same issue that is being fixed by your PR, thanks!
Of course @4ian, no problem. Here is the video with the before and after. The "before" is the exact same situation reported in the videos in the issue #7357.
https://github.com/user-attachments/assets/4143b63e-3f42-4b4a-99bf-993623d92dc1
Ok, I see thanks!
The root cause is that when we switch to another events editor, the eventsSheetWidth is set to 0. You can verify this by logging it in newIDE/app/src/EventsSheet/index.js render method or in newIDE/app/src/EventsSheet/EventsTree/ConditionsActionsColumns.js.
When you switch back to the editor, the proper width is set back, but this caused a rendering with a super small size (0!), trashing everything.
0 is actually passed because when you switch to another editor, the other editors are staying in the DOM but are hidden and have a size of 0x0.
I think the proper fix is to:
- Memorize the size, as you did, but if it's 0 on width or height, you just ignore it and keep using the old size.
- Not use any cache. A cache is dangerous and hard to maintain because in the future we could have multiple editors for the same scene or external events. In the case of your implementation, if two scenes and/or external events have the same name, they will sadly share the same cache, which can create weird issues.
Instead, you can store the cached width/height inside... the EventsSheet itself :) The best cache for a component is inside the component itself (without using a React State because it's more like a cache than a real state).
Here is an example that I tried and which seems to work: https://github.com/4ian/GDevelop/compare/master...experimental-build/events-editor-layout-trashing Notice that there is very little changes (most of the lines are because I moved a component away in favor of a hook, so lines have been re-indented).
As you helped finding this by giving the idea of a cache, it would be good if you either adapt entirely this PR or close this one and open a new one with the fix that is inspired or copied from my commit (it's no problem, and you can try by yourself to see if it works).
Note that this will make the whole tests for the cache useless, but that's ok - the best tests are the tests that do not need to exist at all.
Let me know if it works for you
As the fix seems to work and it's important to get it in the next version, I've merged the fix based on what I described in my previous message. I've credited you in the PR and in the commit (so your GitHub handle will be included in the changelog).
This will make the app looks smoother and flicker free when switching between event tabs, which is a very welcome improvement :) There is some flickering when first opening the events, but it looks harder to fix as it's a required rendering of all events to know their height.
Hello @4ian , ok thanks so much! I have been trying to implement what you suggested and I was about to message you with my changes, checking if I was doing it the correct way. Once again thank you for you support.
Hello @4ian , ok thanks so much! I have been trying to implement what you suggested and I was about to message you with my changes, checking if I was doing it the correct way. Once again thank you for you support.