dc.Blit causes EVT_PAINT?

I'm working with wxPython on the Mac.

It seems that every time I call dc.Blit() I get an EVT_PAINT event.

Am I right that BLit is the cause of the EVT_PAINT?
How do I stop this happening?

Barry

More Blit problems

Why does the src_y measure from the bottom of the window and not the top?

The dst_y is measured from the top of the window.

I’m blitting using the same dc for src and dst.

Barry

···

On 30 Dec 2009, at 16:14, Barry Scott wrote:

I’m working with wxPython on the Mac.

It seems that every time I call dc.Blit() I get an EVT_PAINT event.

Am I right that BLit is the cause of the EVT_PAINT?
How do I stop this happening?

Hi,

···

On Wed, Dec 30, 2009 at 11:08 AM, Barry Scott <barry@barrys-emacs.org> wrote:

On 30 Dec 2009, at 16:14, Barry Scott wrote:

I'm working with wxPython on the Mac.

It seems that every time I call dc.Blit() I get an EVT_PAINT event.

Am I right that BLit is the cause of the EVT_PAINT?
How do I stop this happening?

More Blit problems
Why does the src_y measure from the bottom of the window and not the top?
The dst_y is measured from the top of the window.
I'm blitting using the same dc for src and dst.

You might want to include some sample code of what your doing or at
the very least mention what kind of DC your using.

Cody

Hi,

I'm working with wxPython on the Mac.

It seems that every time I call dc.Blit() I get an EVT_PAINT event.

Am I right that BLit is the cause of the EVT_PAINT?
How do I stop this happening?

I see in the wxWidgets sources mention of preventing OnPaint events in Blit
related code. Am I see a case where this does not work?

More Blit problems
Why does the src_y measure from the bottom of the window and not the top?
The dst_y is measured from the top of the window.
I'm blitting using the same dc for src and dst.

You might want to include some sample code of what your doing or at
the very least mention what kind of DC your using.

  dc = wx.ClientDC( self )

where self is a class derived from wx.Panel.

I'll work up a test case if that is necessary.

I have updated to 2.8.10.1 mac universal and the problem is still there.

I have just tested the same code on fedora12 using '2.8.9.2 (gtk2-unicode)' and it works.

I see from the change log that there have been a number of fixes to Blit for different
platforms. But not any for the Mac code as far as I can see. But I confess to getting
lose in the source code.

Given this work on LInux and not Mac I assume this is a bug.

Barry

···

On 30 Dec 2009, at 17:16, Cody Precord wrote:

On Wed, Dec 30, 2009 at 11:08 AM, Barry Scott <barry@barrys-emacs.org> wrote:

On 30 Dec 2009, at 16:14, Barry Scott wrote:

Hi Barry,

Hi,

I'm working with wxPython on the Mac.

It seems that every time I call dc.Blit() I get an EVT_PAINT event.

Am I right that BLit is the cause of the EVT_PAINT?
How do I stop this happening?

I see in the wxWidgets sources mention of preventing OnPaint events in Blit
related code. Am I see a case where this does not work?

More Blit problems
Why does the src_y measure from the bottom of the window and not the top?
The dst_y is measured from the top of the window.
I'm blitting using the same dc for src and dst.

You might want to include some sample code of what your doing or at
the very least mention what kind of DC your using.

  dc = wx.ClientDC( self )

where self is a class derived from wx.Panel.

I'll work up a test case if that is necessary.

I have updated to 2.8.10.1 mac universal and the problem is still there.

I have just tested the same code on fedora12 using '2.8.9.2 (gtk2-unicode)' and it works.

I see from the change log that there have been a number of fixes to Blit for different
platforms. But not any for the Mac code as far as I can see. But I confess to getting
lose in the source code.

Given this work on LInux and not Mac I assume this is a bug.

You shouldn't really use wx.ClientDC on Mac. It works, but barely, and it has a lot of problems because support for it is really just a hack to keep existing code working. (In fact, I wish it were deprecated for this reason...) Because the Mac window manager is compositing, really all drawing should happen inside paint events. It's possible to do it outside of that, but it performs really poorly and the window manager will end up firing EVT_PAINT events on your control(s) anyway. (along with any controls above or potentially below yours in the window hierarchy)

How best to fix it depends on what you're trying to do. If you're trying to do things like "rubber banding", there's wx.Overlay, but for most other things the solution is just to do a RefreshRect() and then let the redrawing happen in EVT_PAINT.

Regards,

Kevin

···

On Dec 30, 2009, at 10:19 AM, Barry Scott wrote:

On 30 Dec 2009, at 17:16, Cody Precord wrote:

On Wed, Dec 30, 2009 at 11:08 AM, Barry Scott <barry@barrys-emacs.org> wrote:

On 30 Dec 2009, at 16:14, Barry Scott wrote:

Barry

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

I’m writing a text editor. The wx.Panel client area is where I draw all the editor UI using a DC.

I assume that your comment is regarding Bl,it generation EVT_PAINT.

The bug with Blit() getting the source coordinations inverted I assume is broken with PaintDC() as well

or are you saying that it is broken on ClientDC() and not on PaintDC()?

I’ll experiment with the RefreshRect() and EVT_PAINT handling, but am I going to be in the position that

I have to use PaintDC() on Mac and use ClientDC() on GTK and Windows?

Moving to use EVT_PAINT is potentially a major redesign of the screen handling.

Barry

···

On 30 Dec 2009, at 20:39, Kevin Ollivier wrote:

Given this work on LInux and not Mac I assume this is a bug.

You shouldn’t really use wx.ClientDC on Mac. It works, but barely, and it has a lot of problems because support for it is really just a hack to keep existing code working. (In fact, I wish it were deprecated for this reason…) Because the Mac window manager is compositing, really all drawing should happen inside paint events. It’s possible to do it outside of that, but it performs really poorly and the window manager will end up firing EVT_PAINT events on your control(s) anyway. (along with any controls above or potentially below yours in the window hierarchy)

How best to fix it depends on what you’re trying to do. If you’re trying to do things like “rubber banding”, there’s wx.Overlay, but for most other things the solution is just to do a RefreshRect() and then let the redrawing happen in EVT_PAINT.

Hi Barry,

Given this work on LInux and not Mac I assume this is a bug.

You shouldn’t really use wx.ClientDC on Mac. It works, but barely, and it has a lot of problems because support for it is really just a hack to keep existing code working. (In fact, I wish it were deprecated for this reason…) Because the Mac window manager is compositing, really all drawing should happen inside paint events. It’s possible to do it outside of that, but it performs really poorly and the window manager will end up firing EVT_PAINT events on your control(s) anyway. (along with any controls above or potentially below yours in the window hierarchy)

How best to fix it depends on what you’re trying to do. If you’re trying to do things like “rubber banding”, there’s wx.Overlay, but for most other things the solution is just to do a RefreshRect() and then let the redrawing happen in EVT_PAINT.

I’m writing a text editor. The wx.Panel client area is where I draw all the editor UI using a DC.

I assume that your comment is regarding Bl,it generation EVT_PAINT.

The bug with Blit() getting the source coordinations inverted I assume is broken with PaintDC() as well

or are you saying that it is broken on ClientDC() and not on PaintDC()?

TBH, I don’t really know but Blit doesn’t work very well on Mac either for similar reasons. DrawBitmap is the way to go these days.

I’ll experiment with the RefreshRect() and EVT_PAINT handling, but am I going to be in the position that

I have to use PaintDC() on Mac and use ClientDC() on GTK and Windows?

No, you don’t have to use ClientDC() in your app at all, anywhere. Maybe from the name you’ve gotten the impression that it is what you should use to draw on the client area of a window, but that’s actually a misnomer. It’s for drawing outside of an EVT_PAINT handler, which is typically only done if you need to draw something on top of your existing UI. It’s certainly not to be used for general purpose drawing.

Moving to use EVT_PAINT is potentially a major redesign of the screen handling.

Well, it’s standard wxWidgets design to do this and standard design for the native toolkits as well. If there’s sample code out there using ClientDC for drawing the UI instead, I’d hope whoever wrote / maintains it would go and fix it. I actually maintain a text editor of sorts (wxWebKit), and I can tell you it does everything this way and it’s probably the only way to get decent cross-platform performance.

Regards,

Kevin

···

On Dec 31, 2009, at 4:19 AM, Barry Scott wrote:

On 30 Dec 2009, at 20:39, Kevin Ollivier wrote:

Barry

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Hi Barry,

Given this work on LInux and not Mac I assume this is a bug.

You shouldn’t really use wx.ClientDC on Mac. It works, but barely, and it has a lot of problems because support for it is really just a hack to keep existing code working. (In fact, I wish it were deprecated for this reason…) Because the Mac window manager is compositing, really all drawing should happen inside paint events. It’s possible to do it outside of that, but it performs really poorly and the window manager will end up firing EVT_PAINT events on your control(s) anyway. (along with any controls above or potentially below yours in the window hierarchy)

How best to fix it depends on what you’re trying to do. If you’re trying to do things like “rubber banding”, there’s wx.Overlay, but for most other things the solution is just to do a RefreshRect() and then let the redrawing happen in EVT_PAINT.

I’m writing a text editor. The wx.Panel client area is where I draw all the editor UI using a DC.

I assume that your comment is regarding Bl,it generation EVT_PAINT.

The bug with Blit() getting the source coordinations inverted I assume is broken with PaintDC() as well

or are you saying that it is broken on ClientDC() and not on PaintDC()?

TBH, I don’t really know but Blit doesn’t work very well on Mac either for similar reasons. DrawBitmap is the way to go these days.

I’ll experiment with the RefreshRect() and EVT_PAINT handling, but am I going to be in the position that

I have to use PaintDC() on Mac and use ClientDC() on GTK and Windows?

No, you don’t have to use ClientDC() in your app at all, anywhere. Maybe from the name you’ve gotten the impression that it is what you should use to draw on the client area of a window, but that’s actually a misnomer. It’s for drawing outside of an EVT_PAINT handler, which is typically only done if you need to draw something on top of your existing UI. It’s certainly not to be used for general purpose drawing.

I’m used to the world where EVT_PAINT is the window system telling me “fix up your window” and you use ClientDC to draw everything.

Thats the model I’m used to with Win32 and Motif.

The reason I’m porting to wxPython to to escape from all the platform specific and very old code I have at the moment.

(MFC and Motif).

Moving to use EVT_PAINT is potentially a major redesign of the screen handling.

Well, it’s standard wxWidgets design to do this and standard design for the native toolkits as well. If there’s sample code out there using ClientDC for drawing the UI instead, I’d hope whoever wrote / maintains it would go and fix it. I actually maintain a text editor of sorts (wxWebKit), and I can tell you it does everything this way and it’s probably the only way to get decent cross-platform performance.

Its not been too bad to move to EVT_PAINT based design.

I have a bitmap that I draw the whole UI into then DrawBitmap it into the client windows on EVT_PAINT.

This seems to have things working well enough. (I still have to solve the problems with performance with

needing to call DrawText for every char on the screen).

Barry

···

On 31 Dec 2009, at 14:44, Kevin Ollivier wrote:

On Dec 31, 2009, at 4:19 AM, Barry Scott wrote:

On 30 Dec 2009, at 20:39, Kevin Ollivier wrote:

You shouldn't really use wx.ClientDC on Mac. It works, but barely, and it has a lot of problems because support for it is really just a hack to keep existing code working. (In fact, I wish it were deprecated for this reason...) Because the Mac window manager is compositing, really all drawing should happen inside paint events. It's possible to do it outside of that, but it performs really poorly and the window manager will end up firing EVT_PAINT events on your control(s) anyway. (along with any controls above or potentially below yours in the window hierarchy)

Another way to explain this that may help those coming from the other platforms understand better is to discuss the display pipeline. On OS X all GUi applications interact with and update the display via the system's display pipeline, which is essentially a multi-stage series of steps that the system uses to optimize the updates of the graphics for all applications. This allows multiple window updates to be happening at the same time, where each is at a specific step in the pipeline and waiting for its turn to go to the next step.

The idea behind the wx.ClientDC is to allow the app to draw something "right now" instead of waiting for the next paint event to do it. In order to implement that for OS X then we essentially have to stop the pipeline, empty out any partial results for apps that may be in the process of drawing something, do the wx.ClientDC drawing, and then restart the pipeline and redoing the things that were partially completed before. Obviously this is a lot of overhead, and even can impact other windows or applications. And in the vast majority of cases it really is not needed.

Its not been too bad to move to EVT_PAINT based design.

I have a bitmap that I draw the whole UI into then DrawBitmap it into
the client windows on EVT_PAINT.

Exactly. In my experience the typical flow when using wx.ClientDC was something like this:

state changes --> draw with client DC
          paint event --> redraw same thing with paint DC

Switching it over to a do everything in the paint DC is usually a lot simpler than people think it will be. Something like this if you're already using buffering:

state changes --> update buffer --> RefreshRect(the area that has changed)
           paint event --> draw the buffer bitmap

or this if not:

state changes --> RefreshRect(the area that has changed)
           paint event --> draw the area in the update region

This seems to have things working well enough. (I still have to solve
the problems with performance with
needing to call DrawText for every char on the screen).

I'm sure there are some optimizations that can be made, such as only drawing the things that have changed since the last draw, if contiguous characters need drawn then do them in a single DrawText call, etc.

···

On 12/30/09 12:39 PM, Kevin Ollivier wrote:
On 12/31/09 9:25 AM, Barry Scott wrote:

--
Robin Dunn
Software Craftsman

Kevin Ollivier wrote:

You shouldn't really use wx.ClientDC on Mac. It works, but barely,
and it has a lot of problems because support for it is really just a hack to
keep existing code working. (In fact, I wish it were deprecated for this
reason...)

hmm -- last I tried, I couldn't get FloatCanvas to work right without ClientDC (on the mac). I've found that there is no other way to get the Mac to draw something "right now" -- it seems to wait for the event loop to empty, or something (now that I think about it, it still won't let you draw with a ClientDC in a loop in an event handler).

Anyway, maybe time ti try again.

How best to fix it depends on what you're trying to do. If you're
trying to do things like "rubber banding", there's wx.Overlay,

That may be what I couldn't get working without ClientDC. IIRC, there were some issues with Overlay, too, but I have solved those (but never write the Wiki page I intended). So I guess it is time to revisit.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Barry Scott wrote:

The reason I'm porting to wxPython to to escape from all the platform specific and very old code I have at the moment.

well, there are till some platform issues with wx, but very very few where there is not one way that will work on all platforms. For the most part, what you find is that the "recommended" way works everywhere, and some not-recommended ways will work only on some. So once you find the right solution, you don't have platform specific code.

>> If there's sample code out there

using ClientDC for drawing the UI instead, I'd hope whoever wrote / maintains it would go and fix it.

Guilty as charged (probably). I'll try to see what I can do to update the Wiki, etc.

FWIW, I'll bet there's stuff in the Demo that uses ClientDC

This seems to have things working well enough. (I still have to solve the problems with performance with needing to call DrawText for every

> char on the screen).

It seems that you probably would want to keep track of what has changed and what hasn't anyway, but I guess it is more of a pain than just re-drawing everything every time.

good luck,

-CHB

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Christopher Barker wrote:

Barry Scott wrote:
  

The reason I'm porting to wxPython to to escape from all the platform specific and very old code I have at the moment.
    
well, there are till some platform issues with wx, but very very few where there is not one way that will work on all platforms. For the most part, what you find is that the "recommended" way works everywhere, and some not-recommended ways will work only on some. So once you find the right solution, you don't have platform specific code.

>> If there's sample code out there
  

using ClientDC for drawing the UI instead, I'd hope whoever wrote / maintains it would go and fix it.
      
Guilty as charged (probably). I'll try to see what I can do to update the Wiki, etc.

FWIW, I'll bet there's stuff in the Demo that uses ClientDC

This seems to have things working well enough. (I still have to solve the problems with performance with needing to call DrawText for every
    

> char on the screen).

It seems that you probably would want to keep track of what has changed and what hasn't anyway, but I guess it is more of a pain than just re-drawing everything every time.

good luck,

-CHB

IIRC, I had troubles with drawing on a ScrolledPanel if I don't use the following code (to "get" a drawable DC -- self in this case refers to a scrollpanel instance)

    def get_dc(self):
        cdc = wx.ClientDC(self)
        self.PrepareDC(cdc)
        return wx.BufferedDC(cdc, self.buffer, wx.BUFFER_VIRTUAL_AREA)

as well as a mixture of ScrolledPanel.RefreshRect

I'm not sure how I'd go about converting to a clientDC-less code base.

···

--
Steven Sproat, BSc
http://www.basicrpg.com/

I do not want the slight movement of the characters that drawing more then
one at a time will lead to. Since I know the old and new contents of the
screen I can optimise to only draw what has changed. I can also use
DrawRectangle() to write runs of SPACE chars.

Thanks for every ones help.

Barry

···

On 31 Dec 2009, at 20:55, Robin Dunn wrote:

On 12/30/09 12:39 PM, Kevin Ollivier wrote:

You shouldn't really use wx.ClientDC on Mac. It works, but barely, and it has a lot of problems because support for it is really just a hack to keep existing code working. (In fact, I wish it were deprecated for this reason...) Because the Mac window manager is compositing, really all drawing should happen inside paint events. It's possible to do it outside of that, but it performs really poorly and the window manager will end up firing EVT_PAINT events on your control(s) anyway. (along with any controls above or potentially below yours in the window hierarchy)

Another way to explain this that may help those coming from the other
platforms understand better is to discuss the display pipeline. On OS X
all GUi applications interact with and update the display via the
system's display pipeline, which is essentially a multi-stage series of
steps that the system uses to optimize the updates of the graphics for
all applications. This allows multiple window updates to be happening
at the same time, where each is at a specific step in the pipeline and
waiting for its turn to go to the next step.

The idea behind the wx.ClientDC is to allow the app to draw something
"right now" instead of waiting for the next paint event to do it. In
order to implement that for OS X then we essentially have to stop the
pipeline, empty out any partial results for apps that may be in the
process of drawing something, do the wx.ClientDC drawing, and then
restart the pipeline and redoing the things that were partially
completed before. Obviously this is a lot of overhead, and even can
impact other windows or applications. And in the vast majority of cases
it really is not needed.

On 12/31/09 9:25 AM, Barry Scott wrote:

Its not been too bad to move to EVT_PAINT based design.

I have a bitmap that I draw the whole UI into then DrawBitmap it into
the client windows on EVT_PAINT.

Exactly. In my experience the typical flow when using wx.ClientDC was
something like this:

state changes --> draw with client DC
       paint event --> redraw same thing with paint DC

Switching it over to a do everything in the paint DC is usually a lot
simpler than people think it will be. Something like this if you're
already using buffering:

state changes --> update buffer --> RefreshRect(the area that has changed)
        paint event --> draw the buffer bitmap

or this if not:

state changes --> RefreshRect(the area that has changed)
        paint event --> draw the area in the update region

This seems to have things working well enough. (I still have to solve
the problems with performance with
needing to call DrawText for every char on the screen).

I'm sure there are some optimizations that can be made, such as only
drawing the things that have changed since the last draw, if contiguous
characters need drawn then do them in a single DrawText call, etc.

Hi Chris,

Kevin Ollivier wrote:

You shouldn't really use wx.ClientDC on Mac. It works, but barely,
and it has a lot of problems because support for it is really just a hack to
keep existing code working. (In fact, I wish it were deprecated for this
reason...)

hmm -- last I tried, I couldn't get FloatCanvas to work right without
ClientDC (on the mac). I've found that there is no other way to get the
Mac to draw something "right now" -- it seems to wait for the event loop
to empty, or something (now that I think about it, it still won't let
you draw with a ClientDC in a loop in an event handler).

Anyway, maybe time ti try again.

Yeah, if win.Update() isn't working as it should, it'd be nice to have a sample case to know why. :slight_smile: ClientDC() is IIUC doing the same thing as Update() under the hood - basically forcing the OS to flush the current state and draw it to screen.

Regards,

Kevin

···

On Dec 31, 2009, at 5:20 PM, Christopher Barker wrote:

How best to fix it depends on what you're trying to do. If you're
trying to do things like "rubber banding", there's wx.Overlay,

That may be what I couldn't get working without ClientDC. IIRC, there
were some issues with Overlay, too, but I have solved those (but never
write the Wiki page I intended). So I guess it is time to revisit.

-Chris

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en