Refresh GUI does not work instantly in macOS 11.2.3, rather reprints the GUI only after a time consuming process

Hey guys,
I found a pesky bug regarding the newest Mac. It’s quite simple: the ANYGUICOMPONENT.Refresh() method is not working as expected. Normally, It should make sure updating the GUI in an instant, so that you can show important info during a long taking process to the user.
Instead, the long taking process (e.g. we can simulate it with a sleep) needs to be finished and then afterwards we get a GUI refresh. This is not acceptable, in Windows it works as expected.

I attached several resource to state my point:

  1. My Mac version, I use the latest released XOJO:


  2. This is the code in the “standard dice” canvas testing project which tries to call the refresh method.

Unfortunately, the GUI changes in Mac only after the MessageBox has been triggered, not after the calls to the refresh method (which is the expected behaviour, working on windows)

  1. This is a link to my code:

https://lodgit.com/download/bugs/dice_project_refresh_issue.xojo_binary_project.zip

Hopefully this is enough to provide the point.

Feedback Case Number:

Please don’t do SleepCurrentThread in a GUI thread. It blocks the refresh!

And refresh call is not even needed. Just invalidate:

Sub Action() Handles Action
  Die1Canvas.Invalidate(False)
  Die2Canvas.Invalidate(False)
  'Die1Canvas.Refresh(false)
  'Die2Canvas.Refresh(false)
  'App.SleepCurrentThread(5000)
  'MessageBox("wurscht")
End Sub
3 Likes

What is the example supposed to show? Drawing in macOS is different compared to Windows.

1 Like

That was my guess. And on top of that, if it’s still the case, the client is not updated till the method ends.

What bugs me is that the OP says it works on Windows ?!?

Refresh is broken.

Here’s a ticket for Mojave <https://xojo.com/issue/55203>
As well as one for High Sierra: <https://xojo.com/issue/51189>

It does indeed. It’s supposed to work on Mac, but hasn’t for a few years (as noted by the tickets).

While it is true that there are better ways to draw, the fact is a lot of Xojo users use .Refresh to update UI from inside a tight loop. Refresh being broken gets in the way of a lot of older code.

5 Likes

Well, it’s like @Tim_Parnell said - we have a lot of lagecy code banking on “refresh”.

@Christian_Schmitz how should I make the GUI then react instantly e.g. when updating the GUI to show progress of a long lasting operation? Should I just use a thread?

Well, I don’t know if the desired behaviour is, that, refresh behaves differently on macOS than Windows. I only know that it’s redrawing on Windows but not on Mac. So I’m concerned, as we have so many lines referring to the refresh methods of the XOJO GUI components.

It should show that refresh is just doing nothing on Mac, rather than on Windows.

Well, as far as I see, Refresh calls displayRect on the control, which should draw it.
But the problem is that the event loop doesn’t run, which usually does composing of windows.

So this works with running the loop once to redraw:

Sub Action() Handles Action
  Die1Canvas.Invalidate(False)
  Die2Canvas.Invalidate(False)
  Die1Canvas.Refresh(false)
  Die2Canvas.Refresh(False)
  
  #if TargetMachO then
    NSRunLoopMBS.currentRunLoop.runOnce
  #EndIf
  
  App.SleepCurrentThread(5000)
  MessageBox("wurscht")
End Sub
3 Likes

It sounds like the macOS operating system has changed how it handles redrawing so there may be nothing Xojo can do about it.

Rather than fight it, I suggest you use a thread. Please remember to trigger your UI updates on the main thread and don’t try to update the UI on every loop iteration as it can really slow down your loop.

1 Like

This is our solution for now. At least for legacy code. You should use threads in other cases.

That feature alone is worth the price of MBS Complete!

1 Like

Could not one just judiciously use DoEvents to work around the bug as well?

BTW as .Refresh is not working as documented, regardless of what apple had done, it is still an Xojo bug, It’s Xojo’s Inc’s job to keep it’s APIs working regardless of what they have to do under the hood to keep it working.

-Karen

1 Like

So Christian can do it but Xojo can’t? Got ya.

2 Likes

Yes, and I have used DoEvents() successfully for years. In fact, I’ll create a scenario and test both modes and report back.

I didn’t say that.

Triggering the runloop seems to be similar to calling DoEvents so it may not be safe.

1 Like

Hmmm, .runOnce isn’t a valid option. Only .Run or .RunUntilDate.

it’s new in 21.1 as we added it this year.

Updating …

1 Like

IMO this is a priority one serious bug that Xojo should deal with immediately. Refresh is a fundamental operation that needs to work, and if it doesn’t work then it should be removed from the language. There shouldn’t be things known to not work just lurking in the language.

3 Likes