Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
Forbin
Earned a small fee
Earned a small fee
Posts: 21
Joined: Mon Oct 31, 2016 7:26 pm

Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by Forbin »

Platform: Mac OSX 10.11.6 and 10.12
Compiler: Xcode 7.3.1 (7D1014)
wxWidgets: OSX/cocoa 3.0.2

I am using an wxOwnerDrawnComboBox in a project being compiled for both Mac and Windows. On Windows, it works just fine, but on the Mac, it looks like an underlying class is not getting the (Mac) Peer object set. Thus, none of the class functions in wxTextEntry can work.

I am wondering what the best approach would be for fixing this. (Please read on. More below!)

FWIW, the class hierarchy is:

Code: Select all

class WXDLLIMPEXP_ADV wxOwnerDrawnComboBox : public wxWindowWithItems<wxComboCtrl, wxItemContainer> {}

class WXDLLIMPEXP_CORE wxComboCtrl : public wxGenericComboCtrl {}

class WXDLLIMPEXP_CORE wxGenericComboCtrl : public wxComboCtrlBase {}

class WXDLLIMPEXP_CORE wxComboCtrlBase : public wxControl, public wxTextEntry {}
                                         
class WXDLLIMPEXP_CORE wxTextEntry: public wxTextEntryBase {}

wxTextEntryBase is an abstract base class. 
As luck would have it, the first place it was blowing up on me was a call to wxTextEntry::SetMaxLength(), which is the only method that calls upon wxTextEntry::GetTextPeer() without a wxCHECK_RET to warn that the physical Mac control hasn't been created yet! So that took a little time to track down.

FYI, GetTextPeer() looks like this:

Code: Select all

wxTextWidgetImpl * wxTextEntry::GetTextPeer() const
{
    wxWindow * const win = const_cast<wxTextEntry *>(this)->GetEditableWindow();

    return win ? dynamic_cast<wxTextWidgetImpl *>(win->GetPeer()) : NULL;
}
So, I am wondering... can I fix this by intercepting the peer (mac) control that gets created by the "combo-boxy" side of the inheritance tree, and just cast that and set the wxTextEntry to have that same peer? Or do I need to call DontCreatePeer() in my own Create() and then do SetPeer() on both sides of the inheritance hierarchy? Or do they require separate peers? (That doesn't seem likely to me considering that there is just the combo box control on the screen, right?)

Or am I missing some fundamental knowledge here?


Thanks!
-- forbin
Forbin
Earned a small fee
Earned a small fee
Posts: 21
Joined: Mon Oct 31, 2016 7:26 pm

Re: Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by Forbin »

I've solved the problem locally, but I believe there is a bug in the wxOwnerDrawnComboBox hierarchy.

The function wxTextEntry::GetTextPeer() works by doing a GetEditableWindow() and if it succeeds, does a GetPeer() which it tries to dynamically cast to a wxTextWidgetImpl*. In the case of wxOwnerDrawnComboBox, the returned object is not castable to that type, and the dynamic_cast results in NULL. I believe this problem occurs possibly as early as wxComboCtrlBase.

But, as it turns out, wxGenericComboCtrl in its Create() method, creates a text control, m_text, and during that control's creation, a peer is created for it and held (by pointer) within it. There's a public GetTextCtrl() method that returns m_text, so it's accessible, and wxTextCtrl has it's own GetTextPeer().

It also turns out, the wxWidgets team chanced to make wxTextEntry::GetTextPeer() virtual.
(Huge sigh of relief here.)

So I overloaded GetTextPeer() in our owner drawn combobox class to return GetTextCtrl()->GetTextPeer() and it started working!

I believe the proper correction for wxWidgets is to add the following method (or something like it) to wxGenericComboCtrl:

Code: Select all


#if defined(__WXMAC__)

/*virtual*/
wxTextWidgetImpl* wxGenericComboCtrl::GetTextPeer() const
{
    wxTextCtrl* pTextCtrl = GetTextCtrl();
    return pTextCtrl ? pTextCtrl->GetTextPeer() : nullptr;
}

#endif

Forbin
Earned a small fee
Earned a small fee
Posts: 21
Joined: Mon Oct 31, 2016 7:26 pm

Re: Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by Forbin »

How should I go about recommending this fix to the wxWidgets maintainers?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by PB »

If you believe you found an issue, please create either a ticket on http://trac.wxwidgets.org/ or a PR on https://github.com/wxWidgets/wxWidgets.
It is best if you can provide a most simplified example showing the issue, preferably as a patch to one of the bundled samples.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7449
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by ONEEYEMAN »

On top what PB said:
Submit a patch that fix the issue and the patch to one of the samples, which can display the issue and verify that the issue is closed.

If the reproduction steps are not trivial, include them in you ticket/PR description. Something like:

1. Apply and compile sample X.
2. Do this.
3. Do that.
4. Expected: this and this should happen.
5. Actual: that and that actually happens.

Also, make sure you say how you configure the library and what OS/toolkit you tried it on.
Forbin
Earned a small fee
Earned a small fee
Posts: 21
Joined: Mon Oct 31, 2016 7:26 pm

Re: Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by Forbin »

That will take a little research on my part; I don't configure the library, it is built by a different team at my employer and used by multiple teams here.

So I will need to pick this up later (which rankles me a bit, because I'm a big believer in the principle of "the way you pay for the help you receive is by helping others, and by contributing to the improvement of the code you get to use").
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7449
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Mac wxOwnerDrawnComboBox - wxTextEntry doesn't get Peer

Post by ONEEYEMAN »

That's OK.
Problem here is - the more info you provide the better chance it will be the fix will be applied sooner.

Thank you.
Post Reply