From 17d7e6a142500a80ba6628a32eca792c44bbbdb7 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 17 Oct 2016 03:57:32 +0200 Subject: [PATCH] Fix Keyboard Input Hangs when using modifiers Main input parsing loop only update actions for keyboard if the state has changed. `InputMap::event_is_action` now ignores keyboard modifiers if the event is not pressed. Clarify difference between `InputMap::action_has_event` and `InputMap::event_is_action` in docs. Fixes #6388. --- core/input_map.cpp | 6 +++--- core/input_map.h | 2 +- doc/base/classes.xml | 2 +- main/input_default.cpp | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/input_map.cpp b/core/input_map.cpp index 09cb7ce426e..ad1403a64be 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -106,7 +106,7 @@ List InputMap::get_actions() const { return actions; } -List::Element *InputMap::_find_event(List &p_list,const InputEvent& p_event) const { +List::Element *InputMap::_find_event(List &p_list,const InputEvent& p_event, bool p_mod_ignore=false) const { for (List::Element *E=p_list.front();E;E=E->next()) { @@ -122,7 +122,7 @@ List::Element *InputMap::_find_event(List &p_list,const case InputEvent::KEY: { - same=(e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod); + same=(e.key.scancode==p_event.key.scancode && (p_mod_ignore || e.key.mod == p_event.key.mod)); } break; case InputEvent::JOYSTICK_BUTTON: { @@ -229,7 +229,7 @@ bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_ac return p_event.action.action==E->get().id; } - return _find_event(E->get().inputs,p_event)!=NULL; + return _find_event(E->get().inputs,p_event,!p_event.is_pressed())!=NULL; } const Map& InputMap::get_action_map() const { diff --git a/core/input_map.h b/core/input_map.h index 21c479588d1..a974f6f1036 100644 --- a/core/input_map.h +++ b/core/input_map.h @@ -46,7 +46,7 @@ private: mutable Map input_map; mutable Map input_id_map; - List::Element *_find_event(List &p_list,const InputEvent& p_event) const; + List::Element *_find_event(List &p_list,const InputEvent& p_event, bool p_mod_ignore) const; Array _get_action_list(const StringName& p_action); Array _get_actions(); diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 4e0ba53f482..a711f591c66 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -18019,7 +18019,7 @@ - Return whether the given event is part of an existing action. + Return whether the given event is part of an existing action. This method ignores keyboard modifiers if the given [InputEvent] is not pressed (for proper release detection). See [method action_has_event] if you don't want this behavior. diff --git a/main/input_default.cpp b/main/input_default.cpp index c60fcd22434..6c2c6ebbb3a 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -377,13 +377,13 @@ void InputDefault::parse_input_event(const InputEvent& p_event) { if (InputMap::get_singleton()->event_is_action(p_event,E->key())) { - Action action; - action.fixed_frame=OS::get_singleton()->get_fixed_frames(); - action.idle_frame=OS::get_singleton()->get_idle_frames(); - action.pressed=p_event.is_pressed(); - - action_state[E->key()]=action; - + if(is_action_pressed(E->key()) != p_event.is_pressed()) { + Action action; + action.fixed_frame=OS::get_singleton()->get_fixed_frames(); + action.idle_frame=OS::get_singleton()->get_idle_frames(); + action.pressed=p_event.is_pressed(); + action_state[E->key()]=action; + } } } }