FSlateApplication::Get().GeneratePathToWidgetChecked has a race condition with Hittest grid of SWindow

No easy repro, but happens to us quite often particulary with material color picker in conjunction with an UNDO (ctrl + z) operation.

One of our partners delved pretty deep into the issue and found this.

  1. have a sufficiently large world partition map open
  2. Open a material instance, with a color picker and a texture value in it and modify the color picker value
  3. Undo using ctrl + z (this actually causes the editor to stall out for like 15 seconds or so if you’re in a large world partition)
  4. during the stall double click on the texture preview, then try to manipulate the color picker as well

during this time inputs are still being processed for UI and slate will very likely crash

Emmanuel’s explanation

During a long blocking operation you can queue up input events, there is then a race between the inputs, the widget paths being updated (first) and the Hittest grid being updated by OnPaint. When inputs are processed between the Paths being updated and the HittestGrid being updated, those two can not agree on the state of the presented widgets.

(I am referring to the repro steps I wrote about just bellow) I have done more investigation, and I believe the issue is that the HittestGrid of the SWindow ( the main Editor window) as not been updated before the input from the last click to open the color picker.

Looking into the HitttestGrid implementation the Paint function of widget is adding/updating the Hittest. So I believe that we are processing the click before the TextureEditor become vsible. When routing the event (it depends on the HittestGrid) we find the SColorBlock, so we try to open the SColorPicker. To attach the SColorPicker we try to generate the path of the widget with FSlateApplication::Get().GeneratePathToWidgetChecked, but that was updated and can’t find the path of the SColorBlock.

Steps to Reproduce

Hi,

Since it sounds like this may be challenging to repro, are you able to record a quick video so we can get a better idea of what’s going on? An example callstack could be useful as well, I assume you’re asserting on check(bWasFound) in GeneratePathToWidgetChecked? Is this always happening with the color picker, or do you see it happen in other scenarios as well?

We could change the color picker to more gracefully handle not being able to find it’s parent window, it seems like it may make sense to use GeneratePathToWidgetUnchecked here and abort creation if we can’t generate the path. However, I’d want to verify that this issue is specific to the color picker and that we aren’t just fixing one potential case.

Best,

Cody

Hi I’ll file a separate confidential question regarding this one with videos and a stack trace

Thank you! I’ll close this ticket out and we’ll pick up the discussion on the other ticket.