how to force a refresh on 64bit?

this puzzles and worries me.

Why?

Some time ago we moved our code from

mycanvas.graphics.dosomething mycanvas.graphics.dosomethingelse

and replaced it by

sub myCanvas.Paint() //do it all here when the OS tells you to paint g.dosomething g.dosomethingelse end sub

What could possibly go into a timer event to make that canvas draw itself in the same way, apart from .refresh?

Surely we cannot go back to

mycanvas.graphics.dosomething mycanvas.graphics.dosomethingelse

inside a timer?

Whether Refresh should work or not in 64 bit is debatable. Sure, if it did, that would be real nice as it would spare refactoring code. Fact is, it does not for the moment, and Xojo has not given any timeline for when or if it will work in 64 bit.

BTW I tried the old trick that consist in switching visible to try and force a redraw to no avail before posting a suggested timer solution.

Maybe I am warped by Xojo Web, where there is absolutely no way to refresh the UI during an event, but I feel it is good to part with older ways, before new systems force us to do so.

[quote=236710:@Jeff Tullin]this puzzles and worries me.
…/…
Some time ago we moved our code from
mycanvas.graphics.dosomething
…/…and replaced it by
sub myCanvas.Paint()
What could possibly go into a timer event to make that canvas draw itself in the same way, apart from .refresh?
[/quote]

myCanvas.Invalidate will very simply trigger the Paint event, and have the code execute.

If you fiercely miss the old mycanvas.graphics.dosomething though, you can perfectly do

mycanvas.backdrop.graphics.dosomething where instead of manipulating the control graphics layer, you do so in the backdrop picture. That can save headaches when updating existing code. Of course, it requires first creating the said picture for your code to have something to draw on.

I dont.
I’m just worried that this seems to hint at an unexpected and unwelcome need for more refactoring.

Simply, yes.
regularly enough… maybe not.
I need spend some serious time in testing to see what (if any) impact this has for me.

Regardless of how one thinks about it or describes it, the simple fact is that the OS expects the main thread to be responsive and lengthy tasks to be done on secondary threads. Blocking the main thread leaves your application unresponsive to user input, shows the beachball cursor, and problems like Refresh not flushing to screen.

This isn’t a Xojo thing – it’s just a fact of how modern systems expect applications to behave. I’d almost go as far as saying that any time the beachball cursor be treated as a bug in the program. I’d also say that App.DoEvents, RectControl.Refresh, and Window.UpdateNow should be avoided entirely.

There are things the framework can do to make this less painful (like the Task class in the examples folder), but there’s no silver bullet.

[quote=236710:@Jeff Tullin]What could possibly go into a timer event to make that canvas draw itself in the same way, apart from .refresh?

Surely we cannot go back to

mycanvas.graphics.dosomething mycanvas.graphics.dosomethingelse

inside a timer?[/quote]

No, in this example the timer event is just a calling Invalidate to let the OS know the control needs redrawing.

[quote=236716:@Jeff Tullin]I dont.
I’m just worried that this seems to hint at an unexpected and unwelcome need for more refactoring.
[/quote]

As technology evolves, drawing to the screen real time like we used to do 30 years ago in AppleSoft Basic will probably fade away. That is where the difference between Refresh and Invalidate is important. Refresh does not comply to the scheduler, and forces an immediate redraw, whereas Invalidate waits until the ‘proper’ time.

I do not think you should much worry about yet another evolution such as leaving Canvas.Graphics.dosomething, since after all, the Paint event is indeed where the picture forms in the end.

What I strongly believe, though, is that bypassing the scheduler, would that be with Refresh or DoEvent, is not a good idea.

What confuses me is that Invalidate->setNeedsDisplay and Refresh->display, yet Apples 10.11.2 docs for setNeedsDisplay say

So are Apples docs out of date or what? This should draw inline but I don’t have 10.11 or 64bit to test…

[code] declare sub display lib “AppKit” selector “display” (id As integer)

for i As integer = 0 to 300
Label1.Text = Str(i)
display(Label1.Handle)
next[/code]

[quote=236731:@Will Shank]What confuses me is that Invalidate->setNeedsDisplay and Refresh->display, yet Apples 10.11.2 docs for setNeedsDisplay say

So are Apples docs out of date or what? This should draw inline but I don’t have 10.11 or 64bit to test…
[/quote]
I just compiled this:

  Declare Sub display Lib "AppKit" selector "display"(id As Integer)
  
  // Loop  5 seconds
  
  Dim stop As Double = Microseconds + 5000000
  
  While Microseconds < stop
    Label1.Text = Microseconds.ToText
    display(Label1.Handle)
  Wend

and it works on 32bit but unfortunately, not on 64bit. :confused:

My similar case involves a very lengthy process to add rows to a list box and a desire to show users that progress.

I’m familiar with looping in a background thread and updating the GUI via a timer.

But is it OK to AddRows or Sort a listbox from a background thread? I thought that was verboten…

So would the only successful way to do this be via small listbox updates driven by a timer so that the window can update itself between timer events?

have you tried this ?
https://forum.xojo.com/conversation/post/236689