I’m literally going mad still having no clue on how to re-gain the darn keyboard input on WindowsXP with my wxwidget wrapper, after loosing it for switching to another window. The very same code works on ubuntu linux like a charm and this is true for p3d 1.5.4 and 1.6.0 - why?
Shouldn’t be enough this code
wp=WindowProperties()
wp.setForeground(True)
base.win.requestProperties(wp)
to have the keyboard back???
Here some working code to try it out - launch it from a console - type some keys after the launch and you have it - swithc to another window or click somewhere outside the window and then come back and type keys - you have it no more. Why why why?
import os, sys, time, wx
from pandac.PandaModules import WindowProperties, loadPrcFileData
loadPrcFileData("", "window-type none")
#
#===================================================================
# CLASSES
#===================================================================
#
class P3dWxWindow(wx.Frame):
#------------------------------------------------------------
#
def __init__(self, *args, **kw):
wx.Frame.__init__(self, None, -1, *args, **kw)
#------------------------------------------------------------
#
def getP3DSurface(self):
return self.GetHandle()
def getP3DSurfaceSize(self):
return self.GetClientSizeTuple()
#===================================================================
#
import direct.directbase.DirectStart
class P3dWxApp(wx.App):
#------------------------------------------------------------
#
def OnInit(self):
#prepare and start the p3d-wx hybrid-engine mainloop
self.wxevt_loop = wx.EventLoop()
self.wxevt_old_loop = wx.EventLoop.GetActive()
wx.EventLoop.SetActive(self.wxevt_loop)
base.taskMgr.add(self._mainLoop, "MainLoopTask")
#instantiate and assign the wx UI object
self.win = P3dWxWindow(size=wx.Size(640, 480))
self.SetTopWindow(self.win)
#show the wx window
self.win.Show(True)
# is essential to let make up wx window before P3D stuff
self._mainLoop()
#bind wx events
self.win.Bind(wx.EVT_SIZE, self.onSize)
self.win.Bind(wx.EVT_CLOSE, self.onClose)
self.vetoActivate=False
self.win.Bind(wx.EVT_ACTIVATE, self.onActivate)
#open the p3d window undecorated to use in the wx frame window
wp=WindowProperties().getDefault()
wp.setUndecorated(True)
wp.setOpen(True)
wp.setParentWindow(self.win.getP3DSurface())
wp.setOrigin(0,0)
wp.setForeground(True)
wp.setSize(*self.win.getP3DSurfaceSize())
print ">>>opening p3dsurface"
assert base.openDefaultWindow(props=wp) == True
#
return True
#------------------------------------------------------------
#
def _mainLoop(self, task = None):
while self.wxevt_loop.Pending(): self.wxevt_loop.Dispatch()
self.ProcessIdle()
if task != None: return task.cont
#------------------------------------------------------------
#
def onSize(self, event=None):
'''to resize P3d Surface accordingly to his wx window container and to re-gain keyboard focus
'''
wp0=base.win.getProperties()
if not wp0.getOpen():
print ">>>[app onSize] win wasn't open: lets quit!"
return
wp=WindowProperties()
wp.addProperties(wp0)
wp.setSize(*self.win.getP3DSurfaceSize())
wp.setForeground(True)
base.win.requestProperties(wp)
if event != None: event.Skip()
#------------------------------------------------------------
#
def p3dSurfaceFocus(self):
'''re-gain keyboard focus
NOT
'''
wp=WindowProperties()
wp.setForeground(True)
base.win.requestProperties(wp)
print ">>>p3d surface try to re-gain focus - do keyboard events still work?"
#------------------------------------------------------------
#
def onActivate(self, evt=None):
'''
force focus to p3d surface expec. to get keyboard control back
'''
if self.vetoActivate:
print (">>>[onActivate] veto!")
evt.Skip()
else:
if evt.GetActive():
print (">>>[onActivate] win ACTIVE")
self.p3dSurfaceFocus()
evt.Skip()
else:
print (">>>[onActivate] win IN-ACTIVE")
evt.StopPropagation()
#------------------------------------------------------------
#
def onClose(self, event):
while self.wxevt_loop.Pending(): self.wxevt_loop.Dispatch()
self.win.Destroy()
try: base.userExit()
except: sys.exit()
#========================================================================
#
if __name__ == "__main__":
from direct.gui.DirectGui import OnscreenText
_app = P3dWxApp(0)
base.messenger.toggleVerbose()
OnscreenText(
text="we're on P3D actually\n"
"ALT+TAB or click ouside this window to loose focus\n"
"an then come back again\n"
"you'll see the keyboard won't work anymore", style=1, fg=(1,1,1,1),
pos=(0,0), scale = .08
)
run()