relationship of doublebuffer, transparent, erasebackgound

I have a couple of scrolling canvases into which I am drawing vector graphics. Peculiar things are happening.

On OSX ElCapitan:
If doublebuffer is ON, there is a “shadow” or slightly lighter area in the upper left corner of the canvas, with nothing painted. the canvas is 500 x 400 and the shadow is from 0,0 to about 450,250. It comes and goes with doublebuffer ON/OFF. It moves with the window and expands with the window. This is with transparent ON, erasebackground seems to be a NOP. I can draw into this with no odd effects.

If transparent is turned ON, the area gets much more visible as the background of the canvas is darker grey. I can draw into this as well, but if I scroll, the area outside of the shadow does not get erased, just gets drawn over. The area inside the shadow gets redrawn correctly. If doublebuffer is turned OFF, the shadow is gone and now the entire canvas does not get erased but is drawn over. Again, erasebackground seems to be a NOP.

The documentation states that doublebuffer has no effect on OSX but clearly it does.

The recommendation for Windows is doublebuffer ON, transparent OFF. This does not behave the same way as OSX: no shadow and no overdrawing, but no redrawing during a drag either.

What’s going on here? Is there any updated documentation on this? Does anyone know the relationship between these settings on OSX and on Windows?

Doublebuffer isn’t doing anything on MacOS. Really.

Show us your codez and add some screenshots.

Double buffer does do something on macOS, Really. A single change - clicking on the DoubleBuffer switch and recompile - changes the appearance of the window.

Here is a screen shot of the window without double buffer. Note I have put in a checkbox to change the value of Canvas.DoubleBuffer. It is unchecked:

Here it is with the box checked and no other changes:

I’d say that’s doing something. No other changes between the two, just clicked the checkbox. Unclick it and the shadow disappears. Here is the code for the checkbox:

FlightCanvas.DoubleBuffer = Me.Value flightcanvas.Invalidate

The result is the same if I change the doublebuffer switch in the interface builder. So yes, its doing something alright. A bug for sure, but in my code or Xojo? All I have done there is instantiate a canvas, haven’t drawn a thing.

Note also that though it it subtle, the “shadow” is not the same shade as the window background, but slightly lighter.


Yes I am aware of that, as I have read the documentation. Since this app must run on both OSX and Windows, I used doublebuffer. Unfortunately, it seems to cause a problem on OSX. The settings of these three switches also does not behave on Windows as advertised, but that is another subject.

More curious is how the window on OSX behaves if transparent is set to false. The area inside the “shadow” gets drawn correctly, the area outside does not. None of this is described in the docs.

Another clue might be: the shape of the shadow suggests that it is the same size as the canvas, but located in the upper left corner of the window.

And sure enough, if I move the canvas to the upper left corner of the window, things behave much closer to what the docs suggest (though not exactly). So: something is happening in OSX when doublebuffer is switched on, and whatever is being done is not respecting the the offset of the canvas within the window.

What is in the white area below the checkboxes “Show Airspace” etc? Controls on top of each other lead to “bad things ™”. Do you have something like that? Have you tried to reproduce your problem with a simple example?

You could use the following on the OPEN event of the Canvas:

#IF TargetWin32 Me.DoubleBuffer = True Me.EraseBackground = False #Else Me.DoubleBuffer = False #Endif

The white area is a rectangle I put underneath it so that the change in shade shows better. It does this whether the rectangle is there or not. That was my first suspicion, something I forgot left underneath but there is nothing (except the window itself). I will try a simple example and then write it up as a bug I guess.

Thanks for the compiler directives - I figured that was possible, hadn’t gotten around to looking it up yet. Will use that as a work around.

OK, I just did a simple example. A window, a Canvas, and one checkbox that toggles the Canvas.DoubleBuffer property. It does the same thing. There are three lines of code in the project, 2 for the checkbox like above and one in the Close event for the window (“quit”).

So I guess this is a Xojo bug.

  • My response above was not strictly accurate: the canvas sits on the tab area. But that is not the problem.

The Transparent property tells Xojo whether or not your canvas is going to draw to every pixel in it. When it’s set to False, Xojo doesn’t need to draw any of the parent controls because no compositing needs to happen. If you set this to False and don’t draw into every pixel, you’re broken your promise and are going to have unexpected output.

On Linux this also controls how child controls get clipped. A Transparent Canvas does not clip its children while a non-Transparent Canvas will.

The EraseBackground property tells Xojo whether or not to “erase” the Canvas’ content by drawing the window’s background color* first. This only applies to Windows.

The DoubleBuffer property tells Xojo that all drawing should go to an offscreen picture and the Xojo framework will draw that picture in one operation, avoiding potential tearing on Windows. The buffer on Windows starts off filled with the window’s background color* and even though OS X double buffers everything, Xojo fills the canvas with the background color on OS X to get the same behavior.

  • More or less.

Thank you for that explanation.

It appears that Xojo does not fill the entire background on OSX. Is there are way to post a project here? Or it is simple to recreate: simply instantiate a window and put a canvas in it that covers only the lower 2/3 of the window. (If the canvas is aligned in the upper left corner you will not see this). Then set double buffer true and invalidate, and then false and invalidate. A rectangle changes color, but the rectangle is not the same as the canvas. It seems like it should not change color, but if it must, the whole canvas should change color not just a part of it.

Submitted and confirmed as a bug, so I guess I will mark the thread answered.