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.
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)
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
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.
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
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.
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.
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.