still having keyboard focus issues on Windows

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()

This is an old one, and you’ll find lots of references about it on the forums.
If you press Alt, then Tab, it switches to another window, but to Panda, the “Alt” key is still pressed. If you release it, Panda can’t track that, since Panda can only track those events while the window is focused.
So, you need to press Alt key once after returning to the Panda window - just to trigger the up event.
Add this:

messenger.toggleVerbose()

And you’ll see that all events are prefixed by “alt-” when you return focus.
The keys are still there, but not as you expect them.
A workaround would be to turn off modifier buttons.

no pro_rsoft it is not the alt- issue
as I wrote it happens also loosing and regaining focus clicking with the mouse. My sample code above already got the toggleverbose thing, that sound dead after re-gaining the focus and I sift out the whole forum for months and found no definitive solution. Also, I said that on linux it works, so it is definitely just a Windows-side issue. I’m really out of ideas on how to catch this issue beside to stick my hands on C sources but honestly I would avoid it - if somebody got a clue or knows a way on how to investigate effectively just give a shout, please.

You only need to add SetFocus() call.

discourse.panda3d.org/viewtopic.php?t=4589

My previous post:
www1.panda3d.org/phpbb2/viewtopi … highlight=

I think it is the same issue. My understanding is, the wx Frame window does not know it has a child (the panda window). When focus is switching back to the frame window, it does not pass the keyboard focus to panda.

It can be fixed by calling Win32 specific API. Or panda has to change to way it create the panda window under wxpython.

@jo
looks like you went totally unheard - I guess why P3d staff still miss this nasty bug…
@cheung
yes it is and I’d seen it time ago but I hate like death to use low level hacks from high level tools - it must be fixed in the p3d core.

Anyhow I’m thinking about the usual panda window it works on WindowsXP - do you guys knows if is a python call or C hardcoded? Cos if it is pythonic code I just have to borrow it from the script that use it and case closed.

an update:
today I opened the file cited by ynjh_jo (src/windisplay/winGraphicsWindow.cxx) and look what I found:

LOL :slight_smile:

by the way: Jo do you know from were the heck rains down the SetFocus() function? I searched the whole src CVS folder and found just this call

913       SetFocus(_hWnd);

at line 913 of the file above but no function declaration no definition anywhere else - :open_mouth:

SetFocus is Windows function, of course you can’t find it under panda tree.
What about WANT_NEW_FOCUS_MANAGEMENT ?
What made you laugh ?

ah of course - I should have get it

ah, nothing - was just 'cos I’m here talking about that routine got to be fixed and, you know…that constant name make looks like even who wrote it would need too. :wink: But of course I can’t say it really got that meaning so it’s just pure silliness sometime come to me so never mind…

ANOTHER UPDATE

ok, today I feel I’m close to spank this nasty baby.
I finally bent myself to add the SetFocus hack and that was good for a while when I discovered a weird behavior that circumvented it making loose the kb focus nonetheless: it happens pressing and keeping down (not necessarily at the same time) for a while the arrow-up and arrow-left keys while using other keys in place of those, that won’t happen.
If somebody’s interested I uploaded code that clearly show this here.
unzippit and launch python p3ddojo.py from console - in both samples you’ll find alternatives to the forementioned arrow keys in the common wsad bunch so ‘w’ and ‘a’ for up and left.
To close definitely this case now needs to dig the C++ sources (though no clue where, actually) to see why just those keys freak out the thing.