mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -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) {
|
button_down(ButtonHandle button, double time) {
|
||||||
LightMutexHolder holder(_lock);
|
LightMutexHolder holder(_lock);
|
||||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_down, time));
|
_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::
|
void GraphicsWindowInputDevice::
|
||||||
button_resume_down(ButtonHandle button, double time) {
|
button_resume_down(ButtonHandle button, double time) {
|
||||||
LightMutexHolder holder(_lock);
|
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) {
|
button_up(ButtonHandle button, double time) {
|
||||||
LightMutexHolder holder(_lock);
|
LightMutexHolder holder(_lock);
|
||||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_up, time));
|
_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,
|
highlight_start, highlight_end,
|
||||||
cursor_pos));
|
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 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 keystroke(int keycode, double time = ClockObject::get_global_clock()->get_frame_time());
|
||||||
void candidate(const wstring &candidate_string, size_t highlight_start,
|
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_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());
|
INLINE void set_pointer_out_of_window(double time = ClockObject::get_global_clock()->get_frame_time());
|
||||||
@ -120,6 +121,8 @@ private:
|
|||||||
ButtonEvents _button_events;
|
ButtonEvents _button_events;
|
||||||
PT(PointerEventList) _pointer_events;
|
PT(PointerEventList) _pointer_events;
|
||||||
|
|
||||||
|
typedef pset<ButtonHandle> ButtonsHeld;
|
||||||
|
ButtonsHeld _buttons_held;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "graphicsWindowInputDevice.I"
|
#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
|
// Function: WinGraphicsWindow::translate_mouse
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -27,9 +27,6 @@
|
|||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
|
|
||||||
#define WANT_NEW_FOCUS_MANAGMENT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TypeHandle WinGraphicsWindow::_type_handle;
|
TypeHandle WinGraphicsWindow::_type_handle;
|
||||||
TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
|
TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
|
||||||
@ -99,7 +96,6 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||||||
_tracking_mouse_leaving = false;
|
_tracking_mouse_leaving = false;
|
||||||
_maximized = false;
|
_maximized = false;
|
||||||
_cursor = 0;
|
_cursor = 0;
|
||||||
memset(_keyboard_state, 0, sizeof(BYTE) * num_virtual_keys);
|
|
||||||
_lost_keypresses = false;
|
_lost_keypresses = false;
|
||||||
_lshift_down = false;
|
_lshift_down = false;
|
||||||
_rshift_down = false;
|
_rshift_down = false;
|
||||||
@ -1977,80 +1973,12 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
if (windisplay_cat.is_debug())
|
if (windisplay_cat.is_debug()) {
|
||||||
{
|
windisplay_cat.debug()
|
||||||
windisplay_cat.debug()
|
<< "killfocus\n";
|
||||||
<< "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;
|
|
||||||
}
|
}
|
||||||
#endif // WANT_NEW_FOCUS_MANAGMENT
|
|
||||||
|
_input_devices[0].focus_lost(get_message_time());
|
||||||
properties.set_foreground(false);
|
properties.set_foreground(false);
|
||||||
system_changed_properties(properties);
|
system_changed_properties(properties);
|
||||||
break;
|
break;
|
||||||
@ -2186,81 +2114,11 @@ process_1_event() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void WinGraphicsWindow::
|
void WinGraphicsWindow::
|
||||||
resend_lost_keypresses() {
|
resend_lost_keypresses() {
|
||||||
_lost_keypresses = false;
|
|
||||||
return;
|
|
||||||
nassertv(_lost_keypresses);
|
nassertv(_lost_keypresses);
|
||||||
if (windisplay_cat.is_debug()) {
|
// This is now a no-op. Not sure we really want to generate new
|
||||||
windisplay_cat.debug()
|
// "down" or "resume" events for keys that were held while the
|
||||||
<< "resending lost keypresses\n";
|
// 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;
|
_lost_keypresses = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2402,6 +2260,45 @@ show_error_message(DWORD message_id) {
|
|||||||
LocalFree(message_buffer);
|
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
|
// Function: WinGraphicsWindow::lookup_key
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -127,9 +127,9 @@ private:
|
|||||||
|
|
||||||
static void process_1_event();
|
static void process_1_event();
|
||||||
|
|
||||||
INLINE void handle_keypress(ButtonHandle key, int x, int y, double time);
|
void handle_keypress(ButtonHandle key, int x, int y, double time);
|
||||||
INLINE void handle_keyresume(ButtonHandle key, double time);
|
void handle_keyresume(ButtonHandle key, double time);
|
||||||
INLINE void handle_keyrelease(ButtonHandle key, double time);
|
void handle_keyrelease(ButtonHandle key, double time);
|
||||||
ButtonHandle lookup_key(WPARAM wparam) const;
|
ButtonHandle lookup_key(WPARAM wparam) const;
|
||||||
INLINE int translate_mouse(int pos) const;
|
INLINE int translate_mouse(int pos) const;
|
||||||
INLINE void set_cursor_in_window();
|
INLINE void set_cursor_in_window();
|
||||||
@ -138,6 +138,7 @@ private:
|
|||||||
INLINE static double get_message_time();
|
INLINE static double get_message_time();
|
||||||
|
|
||||||
void resend_lost_keypresses();
|
void resend_lost_keypresses();
|
||||||
|
void release_all_buttons();
|
||||||
static void update_cursor_window(WinGraphicsWindow *to_window);
|
static void update_cursor_window(WinGraphicsWindow *to_window);
|
||||||
static void hide_or_show_cursor(bool hide_cursor);
|
static void hide_or_show_cursor(bool hide_cursor);
|
||||||
|
|
||||||
@ -160,20 +161,6 @@ private:
|
|||||||
HCURSOR _cursor;
|
HCURSOR _cursor;
|
||||||
DEVMODE _fullscreen_display_mode;
|
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;
|
bool _lost_keypresses;
|
||||||
|
|
||||||
// These are used to store the status of the individual left and right
|
// These are used to store the status of the individual left and right
|
||||||
|
Loading…
x
Reference in New Issue
Block a user