Focus problem with shared panda3d and WxPandaPanel in 1.10.6 on Windows 10

EDIT: For clarity

Hi

I am trying fix a problem that effects keyboard shortcuts (and appearance) when using wxPython Frame containing a WxPandaPanel

Everything works when I use Panda3D 1.9.4 and the latest wxPython 4.0

When I switch to Panda3D 1.10.5 or 1.10.6 I get the problem

The problem is that, with Panda3D 1.10.5 or 1.10.6, on startup everything is normal except that WxPandaPanel is blank.

As soon as I resize the wx.Frame, or maximize, this focus problem shows up

So the focus problem is basically that I cannot send keyboard input to the wxFrame without having to constantly click on the wx.Frame header all the time after every time I click in the WxPandaPanel

I have a minimal example below that shows the problem

I tried on another example to call self.FindFocus() from the wx.Frame object, from within the wx main loop

Before the focus issue shows up, when I click in the WxPandaPanel, FindFocus returns that WxPandaPanel. And when I click on a wx.Button, FindFocus returns that wx.Button

But after the focus issue shows up, FindFocus still returns the wx.Button just fine, but returns None when I click on the WxPandaPanel

So…is this a bug? Did an API change happened?

Is there any other settings that I can check to see whats going on in terms of window properties? i.e. which ones change when resizing or maximizing

I have tried looking at …

but they didnt seem to match the problem

Thank you for any suggestions

Here’s my code

My WxPandaPanel is in the wx.Frame defined in the panel.py file, and I am using Panda3D to run the wx main loop as well. Using wxPython to run the main loop results in the same issue

main.py

import wx
import ui

wxApp=ui.AppShell()

base = ui.MyApp(wxApp)

import panel
frame=panel.MainWin(None)

frame.Show()

base.run()

ui.py

from direct.showbase.DirectObject import DirectObject
from direct.showbase.ShowBase import ShowBase, Loader
from direct.wxwidgets.WxPandaWindow import WxPandaWindow

from panda3d.core import loadPrcFileData

loadPrcFileData("", "window-type none")

import wx

class PandaPanel(WxPandaWindow):
    def __init__(self, *args, **kwargs):
        WxPandaWindow.__init__(self, *args, **kwargs)

class MyApp(ShowBase):

    def __init__(self, wxApp):
        ShowBase.__init__(self)

        # Load the environment model.
        #self.loader=Loader.Loader(self)
        self.scene = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.scene.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 42, 0)
        self.wxApp=wxApp
        self.frameSort=-100
        self.taskMgr.add(self.doFrame,'doFrames',sort=self.frameSort)

    def doFrame(self, task):
        self.wxApp.wxStep(task)

class AppShell(wx.App):

    def __init__(self):
        wx.App.__init__(self)
        self.SetAppName("Minimal Example")
        self.appInit()

    def wxStep(self, task = None):
        """A step in the WX event loop. You can either call this yourself or use as task."""
        while self.evtLoop.Pending():
            self.evtLoop.Dispatch()
        self.ProcessPendingEvents()
        if task != None:
            return task.cont

    def appInit(self):
        # Create a new event loop (to overide default wxEventLoop)
        self.evtLoop = wx.EventLoop()
        wx.EventLoop.SetActive(self.evtLoop)

panel.py

from ui import PandaPanel
import wx
import wx.xrc

###########################################################################
## Class MainWin
###########################################################################

class MainWin ( wx.Frame ):

	def __init__( self, parent ):
		wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( -1,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

		self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )

		bSizer1 = wx.BoxSizer( wx.VERTICAL )

		bSizer2 = wx.BoxSizer( wx.HORIZONTAL )

		self.m_button1 = wx.Button( self, wx.ID_ANY, u"Panda Sleep", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer2.Add( self.m_button1, 0, wx.ALL, 5 )

		self.m_button2 = wx.Button( self, wx.ID_ANY, u"Panda Drink", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer2.Add( self.m_button2, 0, wx.ALL, 5 )

		self.m_button3 = wx.Button( self, wx.ID_ANY, u"Panda Rage", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer2.Add( self.m_button3, 0, wx.ALL, 5 )

		self.m_button4 = wx.Button( self, wx.ID_ANY, u"Panda Fly", wx.DefaultPosition, wx.DefaultSize, 0 )
		bSizer2.Add( self.m_button4, 0, wx.ALL, 5 )


		bSizer1.Add( bSizer2, 0, wx.EXPAND, 5 )

		bSizer3 = wx.BoxSizer( wx.VERTICAL )

		self.pandaPanel = PandaPanel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
		bSizer3.Add( self.pandaPanel, 1, wx.EXPAND |wx.ALL, 5 )


		bSizer1.Add( bSizer3, 1, wx.EXPAND, 5 )


		self.SetSizer( bSizer1 )
		self.Layout()

		self.Centre( wx.BOTH )

	def __del__( self ):
		pass