It’s the default behavior for Windows, and not yet implemented on Linux. The purpose is to manage the keypress state upon switching windows.
It’s in winGraphicsWindow.cxx :
#ifndef WANT_NEW_FOCUS_MANAGMENT
if (!_lost_keypresses)
{
// Record the current state of the keyboard when the focus is
// lost, so we can check it for changes when we regain focus.
GetKeyboardState(_keyboard_state);
if (windisplay_cat.is_debug()) {
// Report the set of keys that are held down at the time of
// the killfocus event.
for (int i = 0; i < num_virtual_keys; i++)
{
if (i != VK_SHIFT && i != VK_CONTROL && i != VK_MENU)
{
if ((_keyboard_state[i] & 0x80) != 0)
{
windisplay_cat.debug()
<< "on killfocus, key is down: " << i
<< " (" << lookup_key(i) << ")\n";
}
}
}
}
if (!hold_keys_across_windows)
{
// If we don't want to remember the keystate while the
// window focus is lost, then generate a keyup event
// right now for each key currently held.
double message_time = get_message_time();
for (int i = 0; i < num_virtual_keys; i++)
{
if (i != VK_SHIFT && i != VK_CONTROL && i != VK_MENU)
{
if ((_keyboard_state[i] & 0x80) != 0)
{
handle_keyrelease(lookup_key(i), message_time);
_keyboard_state[i] &= ~0x80;
}
}
}
}
// Now set the flag indicating that some keypresses from now
// on may be lost.
_lost_keypresses = true;
}
#else // WANT_NEW_FOCUS_MANAGMENT
{
double message_time = get_message_time();
int i;
for (i = 0; i < num_virtual_keys; i++) {
ButtonHandle bh = lookup_key(i);
if(bh != ButtonHandle::none()) {
handle_keyrelease(bh,message_time);
}
}
memset(_keyboard_state, 0, sizeof(BYTE) * num_virtual_keys);
// Also up the mouse buttons.
for (i = 0; i < MouseButton::num_mouse_buttons; ++i) {
handle_keyrelease(MouseButton::button(i), message_time);
}
handle_keyrelease(MouseButton::wheel_up(), message_time);
handle_keyrelease(MouseButton::wheel_down(), message_time);
_lost_keypresses = true;
}
#endif // WANT_NEW_FOCUS_MANAGMENT
WANT_NEW_FOCUS_MANAGMENT is defined by default. So, as you can see, what happens is all keys -up events will be thrown if panda window loses its focus. Recording the keys states should behave better than just throwing all release events, but this is just my opinion, and I’ve never tried to undef WANT_NEW_FOCUS_MANAGMENT.
I don’t know if there is any config var to control this behavior.
I found this is frustrating too, so I created this simple -up events silencer, which is triggered by “window-event” event :
mutedUpEvents=[]
focusLost=0
def rescueUpEvents(win):
global mutedUpEvents,focusLost
props= win.getProperties()
minimized=props.getMinimized()
foreground=props.getForeground()
if not focusLost and (minimized or not foreground):
print 'FOCUS LOST'
mutedUpEvents=[]
focusLost=1
for e in messenger.getEvents():
if e[-3:]=='-up':
mutedUpEvents.append((e,messenger.whoAccepts(e).copy()))
for e,listeners in mutedUpEvents:
for l in listeners:
messenger.ignore(e,l)
elif not base.mainWinMinimized:
print 'FOCUS GAINED'
focusLost=0
for e,listeners in mutedUpEvents:
for o,m in listeners.items():
messenger.accept(e,o,*m)
And you need to catch “window-event” event :
accept('window-event',rescueUpEvents)