Add support for event accumlation (off by default, on for editor), fixes #26536
This commit is contained in:
parent
a9fe834a8e
commit
a1e73dcc94
|
@ -91,6 +91,7 @@ void Input::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
|
ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
|
||||||
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
|
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
|
||||||
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
|
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
|
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
|
||||||
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
|
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
|
||||||
|
|
|
@ -132,6 +132,9 @@ public:
|
||||||
virtual int get_joy_axis_index_from_string(String p_axis) = 0;
|
virtual int get_joy_axis_index_from_string(String p_axis) = 0;
|
||||||
|
|
||||||
virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0;
|
virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0;
|
||||||
|
virtual void accumulate_input_event(const Ref<InputEvent> &p_event) = 0;
|
||||||
|
virtual void flush_accumulated_events() = 0;
|
||||||
|
virtual void set_use_accumulated_input(bool p_enable) = 0;
|
||||||
|
|
||||||
Input();
|
Input();
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,6 +122,8 @@ void InputEvent::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
|
ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("accumulate", "with_event"), &InputEvent::accumulate);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("xformed_by", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2()));
|
ClassDB::bind_method(D_METHOD("xformed_by", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2()));
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device");
|
||||||
|
@ -620,6 +622,44 @@ String InputEventMouseMotion::as_text() const {
|
||||||
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
|
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
|
Ref<InputEventMouseMotion> motion = p_event;
|
||||||
|
if (motion.is_null())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (is_pressed() != motion->is_pressed()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_button_mask() != motion->get_button_mask()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_shift() != motion->get_shift()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_control() != motion->get_control()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_alt() != motion->get_alt()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_metakey() != motion->get_metakey()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_position(motion->get_position());
|
||||||
|
set_global_position(motion->get_global_position());
|
||||||
|
set_speed(motion->get_speed());
|
||||||
|
relative += motion->get_relative();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void InputEventMouseMotion::_bind_methods() {
|
void InputEventMouseMotion::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
|
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
|
||||||
|
|
|
@ -186,6 +186,7 @@ public:
|
||||||
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
|
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
|
||||||
virtual bool is_action_type() const;
|
virtual bool is_action_type() const;
|
||||||
|
|
||||||
|
virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
|
||||||
InputEvent();
|
InputEvent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -351,6 +352,8 @@ public:
|
||||||
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
|
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
|
||||||
virtual String as_text() const;
|
virtual String as_text() const;
|
||||||
|
|
||||||
|
virtual bool accumulate(const Ref<InputEvent> &p_event);
|
||||||
|
|
||||||
InputEventMouseMotion();
|
InputEventMouseMotion();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4850,6 +4850,7 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err
|
||||||
|
|
||||||
EditorNode::EditorNode() {
|
EditorNode::EditorNode() {
|
||||||
|
|
||||||
|
Input::get_singleton()->set_use_accumulated_input(true);
|
||||||
Resource::_get_local_scene_func = _resource_get_edited_scene;
|
Resource::_get_local_scene_func = _resource_get_edited_scene;
|
||||||
|
|
||||||
VisualServer::get_singleton()->textures_keep_original(true);
|
VisualServer::get_singleton()->textures_keep_original(true);
|
||||||
|
|
|
@ -657,8 +657,35 @@ void InputDefault::set_mouse_in_window(bool p_in_window) {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputDefault::accumulate_input_event(const Ref<InputEvent> &p_event) {
|
||||||
|
ERR_FAIL_COND(p_event.is_null());
|
||||||
|
|
||||||
|
if (!use_accumulated_input) {
|
||||||
|
parse_input_event(p_event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!accumulated_events.empty() && accumulated_events.back()->get()->accumulate(p_event)) {
|
||||||
|
return; //event was accumulated, exit
|
||||||
|
}
|
||||||
|
|
||||||
|
accumulated_events.push_back(p_event);
|
||||||
|
}
|
||||||
|
void InputDefault::flush_accumulated_events() {
|
||||||
|
|
||||||
|
while (accumulated_events.front()) {
|
||||||
|
parse_input_event(accumulated_events.front()->get());
|
||||||
|
accumulated_events.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputDefault::set_use_accumulated_input(bool p_enable) {
|
||||||
|
|
||||||
|
use_accumulated_input = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
InputDefault::InputDefault() {
|
InputDefault::InputDefault() {
|
||||||
|
|
||||||
|
use_accumulated_input = false;
|
||||||
mouse_button_mask = 0;
|
mouse_button_mask = 0;
|
||||||
emulate_touch_from_mouse = false;
|
emulate_touch_from_mouse = false;
|
||||||
emulate_mouse_from_touch = false;
|
emulate_mouse_from_touch = false;
|
||||||
|
|
|
@ -183,6 +183,9 @@ private:
|
||||||
|
|
||||||
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
|
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
|
||||||
|
|
||||||
|
List<Ref<InputEvent> > accumulated_events;
|
||||||
|
bool use_accumulated_input;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool is_key_pressed(int p_scancode) const;
|
virtual bool is_key_pressed(int p_scancode) const;
|
||||||
virtual bool is_mouse_button_pressed(int p_button) const;
|
virtual bool is_mouse_button_pressed(int p_button) const;
|
||||||
|
@ -264,6 +267,11 @@ public:
|
||||||
bool is_joy_mapped(int p_device);
|
bool is_joy_mapped(int p_device);
|
||||||
String get_joy_guid_remapped(int p_device) const;
|
String get_joy_guid_remapped(int p_device) const;
|
||||||
void set_fallback_mapping(String p_guid);
|
void set_fallback_mapping(String p_guid);
|
||||||
|
|
||||||
|
virtual void accumulate_input_event(const Ref<InputEvent> &p_event);
|
||||||
|
virtual void flush_accumulated_events();
|
||||||
|
virtual void set_use_accumulated_input(bool p_enable);
|
||||||
|
|
||||||
InputDefault();
|
InputDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2529,6 +2529,8 @@ void OS_OSX::process_events() {
|
||||||
|
|
||||||
[autoreleasePool drain];
|
[autoreleasePool drain];
|
||||||
autoreleasePool = [[NSAutoreleasePool alloc] init];
|
autoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
input->flush_accumulated_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_OSX::process_key_events() {
|
void OS_OSX::process_key_events() {
|
||||||
|
@ -2571,13 +2573,14 @@ void OS_OSX::process_key_events() {
|
||||||
void OS_OSX::push_input(const Ref<InputEvent> &p_event) {
|
void OS_OSX::push_input(const Ref<InputEvent> &p_event) {
|
||||||
|
|
||||||
Ref<InputEvent> ev = p_event;
|
Ref<InputEvent> ev = p_event;
|
||||||
input->parse_input_event(ev);
|
input->accumulate_input_event(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_OSX::force_process_input() {
|
void OS_OSX::force_process_input() {
|
||||||
|
|
||||||
process_events(); // get rid of pending events
|
process_events(); // get rid of pending events
|
||||||
joypad_osx->process_joypads();
|
joypad_osx->process_joypads();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_OSX::run() {
|
void OS_OSX::run() {
|
||||||
|
|
|
@ -271,7 +271,7 @@ void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) {
|
||||||
event->set_position(Vector2(p_x, p_y));
|
event->set_position(Vector2(p_x, p_y));
|
||||||
|
|
||||||
if (main_loop) {
|
if (main_loop) {
|
||||||
input->parse_input_event(event);
|
input->accumulate_input_event(event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ void OS_Windows::_drag_event(float p_x, float p_y, int idx) {
|
||||||
event->set_position(Vector2(p_x, p_y));
|
event->set_position(Vector2(p_x, p_y));
|
||||||
|
|
||||||
if (main_loop)
|
if (main_loop)
|
||||||
input->parse_input_event(event);
|
input->accumulate_input_event(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
@ -458,7 +458,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window_has_focus && main_loop && mm->get_relative() != Vector2())
|
if (window_has_focus && main_loop && mm->get_relative() != Vector2())
|
||||||
input->parse_input_event(mm);
|
input->accumulate_input_event(mm);
|
||||||
}
|
}
|
||||||
delete[] lpb;
|
delete[] lpb;
|
||||||
} break;
|
} break;
|
||||||
|
@ -545,7 +545,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
old_x = mm->get_position().x;
|
old_x = mm->get_position().x;
|
||||||
old_y = mm->get_position().y;
|
old_y = mm->get_position().y;
|
||||||
if (window_has_focus && main_loop)
|
if (window_has_focus && main_loop)
|
||||||
input->parse_input_event(mm);
|
input->accumulate_input_event(mm);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
@ -718,14 +718,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
mb->set_global_position(mb->get_position());
|
mb->set_global_position(mb->get_position());
|
||||||
|
|
||||||
if (main_loop) {
|
if (main_loop) {
|
||||||
input->parse_input_event(mb);
|
input->accumulate_input_event(mb);
|
||||||
if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) {
|
if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) {
|
||||||
//send release for mouse wheel
|
//send release for mouse wheel
|
||||||
Ref<InputEventMouseButton> mbd = mb->duplicate();
|
Ref<InputEventMouseButton> mbd = mb->duplicate();
|
||||||
last_button_state &= ~(1 << (mbd->get_button_index() - 1));
|
last_button_state &= ~(1 << (mbd->get_button_index() - 1));
|
||||||
mbd->set_button_mask(last_button_state);
|
mbd->set_button_mask(last_button_state);
|
||||||
mbd->set_pressed(false);
|
mbd->set_pressed(false);
|
||||||
input->parse_input_event(mbd);
|
input->accumulate_input_event(mbd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -988,7 +988,7 @@ void OS_Windows::process_key_events() {
|
||||||
if (k->get_unicode() < 32)
|
if (k->get_unicode() < 32)
|
||||||
k->set_unicode(0);
|
k->set_unicode(0);
|
||||||
|
|
||||||
input->parse_input_event(k);
|
input->accumulate_input_event(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
//do nothing
|
//do nothing
|
||||||
|
@ -1026,7 +1026,7 @@ void OS_Windows::process_key_events() {
|
||||||
|
|
||||||
k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30))));
|
k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30))));
|
||||||
|
|
||||||
input->parse_input_event(k);
|
input->accumulate_input_event(k);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -2252,6 +2252,7 @@ void OS_Windows::process_events() {
|
||||||
|
|
||||||
if (!drop_events) {
|
if (!drop_events) {
|
||||||
process_key_events();
|
process_key_events();
|
||||||
|
input->flush_accumulated_events();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1660,7 +1660,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
|
||||||
k->set_shift(true);
|
k->set_shift(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
input->parse_input_event(k);
|
input->accumulate_input_event(k);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1804,7 +1804,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("key: %x\n",k->get_scancode());
|
//printf("key: %x\n",k->get_scancode());
|
||||||
input->parse_input_event(k);
|
input->accumulate_input_event(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Property {
|
struct Property {
|
||||||
|
@ -1991,12 +1991,12 @@ void OS_X11::process_xevents() {
|
||||||
// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
|
// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
|
||||||
xi.mouse_pos_to_filter = pos;
|
xi.mouse_pos_to_filter = pos;
|
||||||
}
|
}
|
||||||
input->parse_input_event(st);
|
input->accumulate_input_event(st);
|
||||||
} else {
|
} else {
|
||||||
if (!xi.state.has(index)) // Defensive
|
if (!xi.state.has(index)) // Defensive
|
||||||
break;
|
break;
|
||||||
xi.state.erase(index);
|
xi.state.erase(index);
|
||||||
input->parse_input_event(st);
|
input->accumulate_input_event(st);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -2014,7 +2014,7 @@ void OS_X11::process_xevents() {
|
||||||
sd->set_index(index);
|
sd->set_index(index);
|
||||||
sd->set_position(pos);
|
sd->set_position(pos);
|
||||||
sd->set_relative(pos - curr_pos_elem->value());
|
sd->set_relative(pos - curr_pos_elem->value());
|
||||||
input->parse_input_event(sd);
|
input->accumulate_input_event(sd);
|
||||||
|
|
||||||
curr_pos_elem->value() = pos;
|
curr_pos_elem->value() = pos;
|
||||||
}
|
}
|
||||||
|
@ -2102,7 +2102,7 @@ void OS_X11::process_xevents() {
|
||||||
st.instance();
|
st.instance();
|
||||||
st->set_index(E->key());
|
st->set_index(E->key());
|
||||||
st->set_position(E->get());
|
st->set_position(E->get());
|
||||||
input->parse_input_event(st);
|
input->accumulate_input_event(st);
|
||||||
}
|
}
|
||||||
xi.state.clear();
|
xi.state.clear();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2163,7 +2163,7 @@ void OS_X11::process_xevents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input->parse_input_event(mb);
|
input->accumulate_input_event(mb);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case MotionNotify: {
|
case MotionNotify: {
|
||||||
|
@ -2273,7 +2273,7 @@ void OS_X11::process_xevents() {
|
||||||
// this is so that the relative motion doesn't get messed up
|
// this is so that the relative motion doesn't get messed up
|
||||||
// after we regain focus.
|
// after we regain focus.
|
||||||
if (window_has_focus || !mouse_mode_grab)
|
if (window_has_focus || !mouse_mode_grab)
|
||||||
input->parse_input_event(mm);
|
input->accumulate_input_event(mm);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
|
@ -2457,6 +2457,8 @@ void OS_X11::process_xevents() {
|
||||||
printf("Win: %d,%d\n", win_x, win_y);
|
printf("Win: %d,%d\n", win_x, win_y);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input->flush_accumulated_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainLoop *OS_X11::get_main_loop() const {
|
MainLoop *OS_X11::get_main_loop() const {
|
||||||
|
|
Loading…
Reference in New Issue