mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
stop button spam on lost focus
This commit is contained in:
parent
6c34e0fb6c
commit
1968a30cd0
@ -291,6 +291,7 @@ void GraphicsWindowInputDevice::
|
||||
button_down(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_down, time));
|
||||
_buttons_held.insert(button);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -304,7 +305,9 @@ button_down(ButtonHandle button, double time) {
|
||||
void GraphicsWindowInputDevice::
|
||||
button_resume_down(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_resume_down, time));
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_resume_down, time)
|
||||
);
|
||||
_buttons_held.insert(button);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -316,6 +319,7 @@ void GraphicsWindowInputDevice::
|
||||
button_up(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_up, time));
|
||||
_buttons_held.erase(button);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -346,3 +350,24 @@ candidate(const wstring &candidate_string, size_t highlight_start,
|
||||
highlight_start, highlight_end,
|
||||
cursor_pos));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::focus_lost
|
||||
// Access: Public
|
||||
// Description: This should be called when the window focus is lost,
|
||||
// so that we may miss upcoming button events
|
||||
// (especially "up" events) for the next period of time.
|
||||
// It generates keyboard and mouse "up" events for those
|
||||
// buttons that we previously sent unpaired "down"
|
||||
// events, so that the Panda application will believe
|
||||
// all buttons are now released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
focus_lost(double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
ButtonsHeld::iterator bi;
|
||||
for (bi = _buttons_held.begin(); bi != _buttons_held.end(); ++bi) {
|
||||
_button_events.push_back(ButtonEvent(*bi, ButtonEvent::T_up, time));
|
||||
}
|
||||
_buttons_held.clear();
|
||||
}
|
||||
|
@ -79,7 +79,8 @@ PUBLISHED:
|
||||
void button_up(ButtonHandle button, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void keystroke(int keycode, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
void candidate(const wstring &candidate_string, size_t highlight_start,
|
||||
size_t higlight_end, size_t cursor_pos);
|
||||
size_t highlight_end, size_t cursor_pos);
|
||||
void focus_lost(double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
|
||||
INLINE void set_pointer_in_window(int x, int y, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
INLINE void set_pointer_out_of_window(double time = ClockObject::get_global_clock()->get_frame_time());
|
||||
@ -120,6 +121,8 @@ private:
|
||||
ButtonEvents _button_events;
|
||||
PT(PointerEventList) _pointer_events;
|
||||
|
||||
typedef pset<ButtonHandle> ButtonsHeld;
|
||||
ButtonsHeld _buttons_held;
|
||||
};
|
||||
|
||||
#include "graphicsWindowInputDevice.I"
|
||||
|
@ -13,45 +13,6 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::handle_keypress
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void WinGraphicsWindow::
|
||||
handle_keypress(ButtonHandle key, int x, int y, double time) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_down(key, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::handle_keyresume
|
||||
// Access: Private
|
||||
// Description: Indicates we detected a key was already down when the
|
||||
// focus is restored to the window. Mainly useful for
|
||||
// tracking the state of modifier keys.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void WinGraphicsWindow::
|
||||
handle_keyresume(ButtonHandle key, double time) {
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_resume_down(key, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::handle_keyrelease
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void WinGraphicsWindow::
|
||||
handle_keyrelease(ButtonHandle key, double time) {
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_up(key, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::translate_mouse
|
||||
// Access: Private
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
#define WANT_NEW_FOCUS_MANAGMENT
|
||||
|
||||
|
||||
|
||||
TypeHandle WinGraphicsWindow::_type_handle;
|
||||
TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
|
||||
@ -99,7 +96,6 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
_tracking_mouse_leaving = false;
|
||||
_maximized = false;
|
||||
_cursor = 0;
|
||||
memset(_keyboard_state, 0, sizeof(BYTE) * num_virtual_keys);
|
||||
_lost_keypresses = false;
|
||||
_lshift_down = false;
|
||||
_rshift_down = false;
|
||||
@ -1977,80 +1973,12 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
if (windisplay_cat.is_debug())
|
||||
{
|
||||
windisplay_cat.debug()
|
||||
<< "killfocus\n";
|
||||
}
|
||||
|
||||
#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;
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "killfocus\n";
|
||||
}
|
||||
#endif // WANT_NEW_FOCUS_MANAGMENT
|
||||
|
||||
_input_devices[0].focus_lost(get_message_time());
|
||||
properties.set_foreground(false);
|
||||
system_changed_properties(properties);
|
||||
break;
|
||||
@ -2186,81 +2114,11 @@ process_1_event() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::
|
||||
resend_lost_keypresses() {
|
||||
_lost_keypresses = false;
|
||||
return;
|
||||
nassertv(_lost_keypresses);
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "resending lost keypresses\n";
|
||||
}
|
||||
// This is now a no-op. Not sure we really want to generate new
|
||||
// "down" or "resume" events for keys that were held while the
|
||||
// window focus is restored.
|
||||
|
||||
BYTE new_keyboard_state[num_virtual_keys];
|
||||
GetKeyboardState(new_keyboard_state);
|
||||
double message_time = get_message_time();
|
||||
|
||||
#ifndef WANT_NEW_FOCUS_MANAGMENT
|
||||
for (int i = 0; i < num_virtual_keys; i++) {
|
||||
// Filter out these particular three. We don't want to test
|
||||
// these, because these are virtual duplicates for
|
||||
// VK_LSHIFT/VK_RSHIFT, etc.; and the left/right equivalent is
|
||||
// also in the table. If we respect both VK_LSHIFT as well as
|
||||
// VK_SHIFT, we'll generate two keyboard messages when
|
||||
// VK_LSHIFT changes state.
|
||||
if (i != VK_SHIFT && i != VK_CONTROL && i != VK_MENU) {
|
||||
if (((new_keyboard_state[i] ^ _keyboard_state[i]) & 0x80) != 0) {
|
||||
// This key has changed state.
|
||||
if ((new_keyboard_state[i] & 0x80) != 0) {
|
||||
// The key is now held down.
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "key has gone down: " << i << " (" << lookup_key(i) << ")\n";
|
||||
}
|
||||
|
||||
// Roger
|
||||
//handle_keyresume(lookup_key(i), message_time);
|
||||
// resume does not seem to work and sending the pointer position seems to
|
||||
// weird ot some cursor controls
|
||||
ButtonHandle key = lookup_key(i);
|
||||
if (key != ButtonHandle::none())
|
||||
_input_devices[0].button_down(key, message_time);
|
||||
|
||||
|
||||
} else {
|
||||
// The key is now released.
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "key has gone up: " << i << " (" << lookup_key(i) << ")\n";
|
||||
}
|
||||
handle_keyrelease(lookup_key(i), message_time);
|
||||
}
|
||||
} else {
|
||||
// This key is in the same state.
|
||||
if (windisplay_cat.is_debug()) {
|
||||
if ((new_keyboard_state[i] & 0x80) != 0) {
|
||||
windisplay_cat.debug()
|
||||
<< "key is still down: " << i << " (" << lookup_key(i) << ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else // WANT_NEW_FOCUS_MANAGMENT
|
||||
for (int i = 0; i < num_virtual_keys; i++)
|
||||
{
|
||||
if ((new_keyboard_state[i] & 0x80) != 0)
|
||||
{
|
||||
ButtonHandle key = lookup_key(i);
|
||||
if (key != ButtonHandle::none())
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< "resending key: " << " (" << key << ")\n";
|
||||
}
|
||||
_input_devices[0].button_down(key, message_time);
|
||||
}
|
||||
}
|
||||
#endif // WANT_NEW_FOCUS_MANAGMENT
|
||||
|
||||
// Keypresses are no longer lost.
|
||||
_lost_keypresses = false;
|
||||
}
|
||||
|
||||
@ -2402,6 +2260,45 @@ show_error_message(DWORD message_id) {
|
||||
LocalFree(message_buffer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::handle_keypress
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::
|
||||
handle_keypress(ButtonHandle key, int x, int y, double time) {
|
||||
_input_devices[0].set_pointer_in_window(x, y);
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_down(key, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::handle_keyresume
|
||||
// Access: Private
|
||||
// Description: Indicates we detected a key was already down when the
|
||||
// focus is restored to the window. Mainly useful for
|
||||
// tracking the state of modifier keys.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::
|
||||
handle_keyresume(ButtonHandle key, double time) {
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_resume_down(key, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::handle_keyrelease
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::
|
||||
handle_keyrelease(ButtonHandle key, double time) {
|
||||
if (key != ButtonHandle::none()) {
|
||||
_input_devices[0].button_up(key, time);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::lookup_key
|
||||
// Access: Private
|
||||
|
@ -127,9 +127,9 @@ private:
|
||||
|
||||
static void process_1_event();
|
||||
|
||||
INLINE void handle_keypress(ButtonHandle key, int x, int y, double time);
|
||||
INLINE void handle_keyresume(ButtonHandle key, double time);
|
||||
INLINE void handle_keyrelease(ButtonHandle key, double time);
|
||||
void handle_keypress(ButtonHandle key, int x, int y, double time);
|
||||
void handle_keyresume(ButtonHandle key, double time);
|
||||
void handle_keyrelease(ButtonHandle key, double time);
|
||||
ButtonHandle lookup_key(WPARAM wparam) const;
|
||||
INLINE int translate_mouse(int pos) const;
|
||||
INLINE void set_cursor_in_window();
|
||||
@ -138,6 +138,7 @@ private:
|
||||
INLINE static double get_message_time();
|
||||
|
||||
void resend_lost_keypresses();
|
||||
void release_all_buttons();
|
||||
static void update_cursor_window(WinGraphicsWindow *to_window);
|
||||
static void hide_or_show_cursor(bool hide_cursor);
|
||||
|
||||
@ -160,20 +161,6 @@ private:
|
||||
HCURSOR _cursor;
|
||||
DEVMODE _fullscreen_display_mode;
|
||||
|
||||
// This is used to remember the state of the keyboard when keyboard
|
||||
// focus is lost.
|
||||
enum { num_virtual_keys = 256 };
|
||||
// You might be wondering why the above is an enum. Originally the line
|
||||
// read "static const int num_virtual_keys = 256"
|
||||
// but in trying to support the MSVC6 compiler, we found that you
|
||||
// were not allowed to define the value of a const within a class like
|
||||
// that. Defining the value outside the class helps, but then we can't
|
||||
// use the value to define the length of the _keyboard_state array, and
|
||||
// also it creates multiply defined symbol errors when you link, because
|
||||
// other files include this header file. This enum is a clever solution
|
||||
// to work around the problem.
|
||||
|
||||
BYTE _keyboard_state[num_virtual_keys];
|
||||
bool _lost_keypresses;
|
||||
|
||||
// These are used to store the status of the individual left and right
|
||||
|
Loading…
x
Reference in New Issue
Block a user