wx 2.9, OSX, wx.XOR mode not obeyed?

Sorry to be posting so much stuff lately.

When moving from wx 2.8.11 to 2.9.1, some rubberbanding code that I was using, that utilizes wx.XOR drawing mode, broke. In trying to figure out what went wrong, I’ve tested 2.9.1 and 2.9.2-svn, and both exhibit the same behavior. It looks to me like the wx.XOR mode is just not being respected. For example if you run

wx/lib/mixins/rubberband.py

and play with the rubber band in that sample, it works fine for 2.8.11 but not for anything 2.9.

As another test, the attached sample (optest.py) can be run; I’ve also attached the results of running this script on Windows (using wxpython 2.9.1.1), OSX (with wxpython 2.8.11), and OSX (wxpython 2.9.1.1).

I’m sure this is really a problem in wxWidgets, but I thought I would start here to make sure that others can confirm the same behavior.

windows_wx29.png

osx_wx28.png

osx_wx29.png

optest.py (730 Bytes)

···


Daniel Hyams
dhyams@gmail.com

And I should add that the erroneous behavior seen in wx 2.9 is the
same whether I'm using cocoa or carbon builds of wxwidgets/wxpython.

OK; found a fix...

1) All of the blend modes are turned off if the mac compatibility
version is 10.4 (which it is by default). This is in
http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/graphics.cpp#L1851
. I can't imagine this is intentional, because the blending modes
work fine in wx 2.8.11. So, if as long as you ./configure the 2.9.1.1
source code with --with-macosx-version-min=10.6 (10.5 will probably
work too), that enables the blending modes again.

2) on line http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/graphics.cpp#L1888,
kCGBlendModeXOR needs to be kCGBlendModeExclusion. Why they act
differently I have no idea, but if you dig into the include files
(specifically CGContext.h), each mode has its own number (one is 11,
the other is 25). Sure enough, if you make that change, the xor'ing in
wxwidgets starts working again. To my untrained eye, it looks like
the Apple devs left a little pothole to fall into there.

With these two fixes implemented, the sample script optest.py in the
original post returns the correct results, and rubberbanding works
again.

A side issue to Robin: can the build-wxpython.py script be modified
slightly to be able to pass through options to the wxwidgets configure
script? I had to hack the build/tools/build-wxwidgets.py script in
order to pass the desired configure options off. I can do so myself
of course, so let me know if you want me to add the capability and
then just submit a patch.

Hi Daniel,

OK; found a fix...

1) All of the blend modes are turned off if the mac compatibility
version is 10.4 (which it is by default). This is in
wxTrac has been migrated to GitHub Issues - wxWidgets
. I can't imagine this is intentional, because the blending modes
work fine in wx 2.8.11.

Only two do, actually - wx.INVERT and wx.XOR. The rest are no-ops.

So, if as long as you ./configure the 2.9.1.1
source code with --with-macosx-version-min=10.6 (10.5 will probably
work too), that enables the blending modes again.

They should actually be compiling if wxUSE_COCOA_OR_CARBON is set. The real issue, I think, is that the "else" block that uses CGContextSetBlendMode for everything is only used under 10.6, even though that's what you want to use on 10.4 up. Your fix probably would not do the right thing even on 10.5 because of that. What's weird is that CGContextSetBlendMode is introduced in 10.4 and most of the constants we need are available as of 10.5, so why is it using the private CGContextSetCompositeOperator API at all in 10.5 still? That's probably a question only Stefan (the wxMac maintainer) can answer.

If you want a really quick hack to fix the problem in a way that works with 10.4, try changing line 1835 to say "mode = kCGBlendModeExclusion;". I bet that will fix the problem even with the default compilation options still set.

Regards,

Kevin

···

On Mar 26, 2011, at 7:46 PM, dhyams wrote:

2) on line wxTrac has been migrated to GitHub Issues - wxWidgets,
kCGBlendModeXOR needs to be kCGBlendModeExclusion. Why they act
differently I have no idea, but if you dig into the include files
(specifically CGContext.h), each mode has its own number (one is 11,
the other is 25). Sure enough, if you make that change, the xor'ing in
wxwidgets starts working again. To my untrained eye, it looks like
the Apple devs left a little pothole to fall into there.

With these two fixes implemented, the sample script optest.py in the
original post returns the correct results, and rubberbanding works
again.

A side issue to Robin: can the build-wxpython.py script be modified
slightly to be able to pass through options to the wxwidgets configure
script? I had to hack the build/tools/build-wxwidgets.py script in
order to pass the desired configure options off. I can do so myself
of course, so let me know if you want me to add the capability and
then just submit a patch.

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

Hi Kevin:

Thanks for the input!

I think the compiling with -with-macosx-version-min=10.5 (at least) is
necessary; on my system anyway (I traced it though), the check

UMAGetSystemVersion() < 0x1060

always fails...which makes sense if that really means the the version
number has to be strictly less than 10.6; I'm running 10.6.7. So it
fails that if check, and there's nothing else in that routine to try
to set a composition mode unless things have been compiled with -
version-min=10.5 or greater. So the path of execution will never make
it to line 1835 with the normal compile options.

I'm definitely on the outside-looking-in on a topic like this...I
would have no idea why things are structured like they are, and
definitely wouldn't know anything about the history of Mac API's. I
can, though (usually) find a fix and then turn it over to the experts
on how to really fix it properly. I don't care to have compatibility
before 10.6, so my hacked fix works for me :slight_smile:

···

On Mar 27, 4:06 pm, Kevin Ollivier <kevin-li...@theolliviers.com> wrote:

Hi Daniel,

On Mar 26, 2011, at 7:46 PM, dhyams wrote:

> OK; found a fix...

> 1) All of the blend modes are turned off if the mac compatibility
> version is 10.4 (which it is by default). This is in
>wxTrac has been migrated to GitHub Issues - wxWidgets
> . I can't imagine this is intentional, because the blending modes
> work fine in wx 2.8.11.

Only two do, actually - wx.INVERT and wx.XOR. The rest are no-ops.

> So, if as long as you ./configure the 2.9.1.1
> source code with --with-macosx-version-min=10.6 (10.5 will probably
> work too), that enables the blending modes again.

They should actually be compiling if wxUSE_COCOA_OR_CARBON is set. The real issue, I think, is that the "else" block that uses CGContextSetBlendMode for everything is only used under 10.6, even though that's what you want to use on 10.4 up. Your fix probably would not do the right thing even on 10.5 because of that. What's weird is that CGContextSetBlendMode is introduced in 10.4 and most of the constants we need are available as of 10.5, so why is it using the private CGContextSetCompositeOperator API at all in 10.5 still? That's probably a question only Stefan (the wxMac maintainer) can answer.

If you want a really quick hack to fix the problem in a way that works with 10.4, try changing line 1835 to say "mode = kCGBlendModeExclusion;". I bet that will fix the problem even with the default compilation options still set.

Regards,

Kevin

> 2) on linehttp://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/grap…,
> kCGBlendModeXOR needs to be kCGBlendModeExclusion. Why they act
> differently I have no idea, but if you dig into the include files
> (specifically CGContext.h), each mode has its own number (one is 11,
> the other is 25). Sure enough, if you make that change, the xor'ing in
> wxwidgets starts working again. To my untrained eye, it looks like
> the Apple devs left a little pothole to fall into there.

> With these two fixes implemented, the sample script optest.py in the
> original post returns the correct results, and rubberbanding works
> again.

> A side issue to Robin: can the build-wxpython.py script be modified
> slightly to be able to pass through options to the wxwidgets configure
> script? I had to hack the build/tools/build-wxwidgets.py script in
> order to pass the desired configure options off. I can do so myself
> of course, so let me know if you want me to add the capability and
> then just submit a patch.

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

Hi Daniel,

Hi Kevin:

Thanks for the input!

I think the compiling with -with-macosx-version-min=10.5 (at least) is
necessary; on my system anyway (I traced it though), the check

UMAGetSystemVersion() < 0x1060

always fails...which makes sense if that really means the the version
number has to be strictly less than 10.6; I'm running 10.6.7.

Ah, right, of course, I overlooked that. That 10.6 check on line 1798 also must be in an #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 block. So it becomes:

#if wxOSX_USE_COCOA_OR_CARBON
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
    if ( UMAGetSystemVersion() < 0x1060 )
#endif
    {

That way, if the else block isn't compiled, then neither is the if check, and the code inside the if block always runs.

So it
fails that if check, and there's nothing else in that routine to try
to set a composition mode unless things have been compiled with -
version-min=10.5 or greater. So the path of execution will never make
it to line 1835 with the normal compile options.

I'm definitely on the outside-looking-in on a topic like this...I
would have no idea why things are structured like they are, and
definitely wouldn't know anything about the history of Mac API's. I
can, though (usually) find a fix and then turn it over to the experts
on how to really fix it properly. I don't care to have compatibility
before 10.6, so my hacked fix works for me :slight_smile:

Yes, but if it's fixed everywhere then the fix can be landed, and you don't need that hack any more. :slight_smile:

Regards,

Kevin

···

On Mar 27, 2011, at 1:49 PM, dhyams wrote:

On Mar 27, 4:06 pm, Kevin Ollivier <kevin-li...@theolliviers.com> > wrote:

Hi Daniel,

On Mar 26, 2011, at 7:46 PM, dhyams wrote:

OK; found a fix...

1) All of the blend modes are turned off if the mac compatibility
version is 10.4 (which it is by default). This is in
http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/grap
. I can't imagine this is intentional, because the blending modes
work fine in wx 2.8.11.

Only two do, actually - wx.INVERT and wx.XOR. The rest are no-ops.

So, if as long as you ./configure the 2.9.1.1
source code with --with-macosx-version-min=10.6 (10.5 will probably
work too), that enables the blending modes again.

They should actually be compiling if wxUSE_COCOA_OR_CARBON is set. The real issue, I think, is that the "else" block that uses CGContextSetBlendMode for everything is only used under 10.6, even though that's what you want to use on 10.4 up. Your fix probably would not do the right thing even on 10.5 because of that. What's weird is that CGContextSetBlendMode is introduced in 10.4 and most of the constants we need are available as of 10.5, so why is it using the private CGContextSetCompositeOperator API at all in 10.5 still? That's probably a question only Stefan (the wxMac maintainer) can answer.

If you want a really quick hack to fix the problem in a way that works with 10.4, try changing line 1835 to say "mode = kCGBlendModeExclusion;". I bet that will fix the problem even with the default compilation options still set.

Regards,

Kevin

2) on linehttp://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/grap…,
kCGBlendModeXOR needs to be kCGBlendModeExclusion. Why they act
differently I have no idea, but if you dig into the include files
(specifically CGContext.h), each mode has its own number (one is 11,
the other is 25). Sure enough, if you make that change, the xor'ing in
wxwidgets starts working again. To my untrained eye, it looks like
the Apple devs left a little pothole to fall into there.

With these two fixes implemented, the sample script optest.py in the
original post returns the correct results, and rubberbanding works
again.

A side issue to Robin: can the build-wxpython.py script be modified
slightly to be able to pass through options to the wxwidgets configure
script? I had to hack the build/tools/build-wxwidgets.py script in
order to pass the desired configure options off. I can do so myself
of course, so let me know if you want me to add the capability and
then just submit a patch.

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

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

I went ahead and submitted a ticket for this one:

http://trac.wxwidgets.org/ticket/13095

Thanks. It will probably get quicker attention from Stefan if you make a patch with the changes you and Kevin discussed and attach it to the ticket.

···

On 3/28/11 6:52 AM, dhyams wrote:

I went ahead and submitted a ticket for this one:

wxTrac has been migrated to GitHub Issues - wxWidgets

--
Robin Dunn
Software Craftsman