Browse Source

Fix InputMap.action_erase_event() failing to erase events correctly.

Fixes #52733

(3.x backport of 7104229a85acbc30bf5dcc9c8a0ada8571910456)
Álex Román Núñez 4 years ago
parent
commit
43bc8830f1
3 changed files with 57 additions and 40 deletions
  1. 46 35
      core/os/input_event.cpp
  2. 8 4
      core/os/input_event.h
  3. 3 1
      doc/classes/InputEvent.xml

+ 46 - 35
core/os/input_event.cpp

@@ -92,7 +92,7 @@ bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, f
 	return false;
 	return false;
 }
 }
 
 
-bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const {
+bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
 	return false;
 	return false;
 }
 }
 
 
@@ -114,7 +114,7 @@ void InputEvent::_bind_methods() {
 
 
 	ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text);
 	ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text);
 
 
-	ClassDB::bind_method(D_METHOD("shortcut_match", "event"), &InputEvent::shortcut_match);
+	ClassDB::bind_method(D_METHOD("shortcut_match", "event", "exact_match"), &InputEvent::shortcut_match, DEFVAL(true));
 
 
 	ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
 	ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
 
 
@@ -174,6 +174,23 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
 	set_metakey(event->get_metakey());
 	set_metakey(event->get_metakey());
 }
 }
 
 
+uint32_t InputEventWithModifiers::get_modifiers_mask() const {
+	uint32_t mask = 0;
+	if (get_control()) {
+		mask |= KEY_MASK_CTRL;
+	}
+	if (get_shift()) {
+		mask |= KEY_MASK_SHIFT;
+	}
+	if (get_alt()) {
+		mask |= KEY_MASK_ALT;
+	}
+	if (get_metakey()) {
+		mask |= KEY_MASK_META;
+	}
+	return mask;
+}
+
 void InputEventWithModifiers::_bind_methods() {
 void InputEventWithModifiers::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt);
 	ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt);
 	ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt);
 	ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt);
@@ -243,35 +260,11 @@ bool InputEventKey::is_echo() const {
 }
 }
 
 
 uint32_t InputEventKey::get_scancode_with_modifiers() const {
 uint32_t InputEventKey::get_scancode_with_modifiers() const {
-	uint32_t sc = scancode;
-	if (get_control()) {
-		sc |= KEY_MASK_CTRL;
-	}
-	if (get_alt()) {
-		sc |= KEY_MASK_ALT;
-	}
-	if (get_shift()) {
-		sc |= KEY_MASK_SHIFT;
-	}
-	if (get_metakey()) {
-		sc |= KEY_MASK_META;
-	}
-
-	return sc;
+	return scancode | get_modifiers_mask();
 }
 }
 
 
 uint32_t InputEventKey::get_physical_scancode_with_modifiers() const {
 uint32_t InputEventKey::get_physical_scancode_with_modifiers() const {
-	uint32_t sc = physical_scancode;
-	if (get_control())
-		sc |= KEY_MASK_CTRL;
-	if (get_alt())
-		sc |= KEY_MASK_ALT;
-	if (get_shift())
-		sc |= KEY_MASK_SHIFT;
-	if (get_metakey())
-		sc |= KEY_MASK_META;
-
-	return sc;
+	return physical_scancode | get_modifiers_mask();
 }
 }
 
 
 String InputEventKey::as_text() const {
 String InputEventKey::as_text() const {
@@ -330,16 +323,14 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
 	return match;
 	return match;
 }
 }
 
 
-bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
+bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
 	Ref<InputEventKey> key = p_event;
 	Ref<InputEventKey> key = p_event;
 	if (key.is_null()) {
 	if (key.is_null()) {
 		return false;
 		return false;
 	}
 	}
 
 
-	uint32_t code = get_scancode_with_modifiers();
-	uint32_t event_code = key->get_scancode_with_modifiers();
-
-	return code == event_code;
+	return scancode == key->scancode &&
+		   (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask());
 }
 }
 
 
 void InputEventKey::_bind_methods() {
 void InputEventKey::_bind_methods() {
@@ -494,6 +485,16 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p
 	return match;
 	return match;
 }
 }
 
 
+bool InputEventMouseButton::shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
+	Ref<InputEventMouseButton> mb = p_event;
+	if (mb.is_null()) {
+		return false;
+	}
+
+	return button_index == mb->button_index &&
+		   (!p_exact_match || get_modifiers_mask() == mb->get_modifiers_mask());
+}
+
 String InputEventMouseButton::as_text() const {
 String InputEventMouseButton::as_text() const {
 	String button_index_string = "";
 	String button_index_string = "";
 	switch (get_button_index()) {
 	switch (get_button_index()) {
@@ -760,6 +761,16 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
 	return match;
 	return match;
 }
 }
 
 
+bool InputEventJoypadMotion::shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
+	Ref<InputEventJoypadMotion> jm = p_event;
+	if (jm.is_null()) {
+		return false;
+	}
+
+	return axis == jm->axis &&
+		   (!p_exact_match || ((axis_value < 0) == (jm->axis_value < 0)));
+}
+
 String InputEventJoypadMotion::as_text() const {
 String InputEventJoypadMotion::as_text() const {
 	return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value));
 	return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value));
 }
 }
@@ -827,7 +838,7 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
 	return match;
 	return match;
 }
 }
 
 
-bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
+bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
 	Ref<InputEventJoypadButton> button = p_event;
 	Ref<InputEventJoypadButton> button = p_event;
 	if (button.is_null()) {
 	if (button.is_null()) {
 		return false;
 		return false;
@@ -1031,7 +1042,7 @@ float InputEventAction::get_strength() const {
 	return strength;
 	return strength;
 }
 }
 
 
-bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
+bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match) const {
 	if (p_event.is_null()) {
 	if (p_event.is_null()) {
 		return false;
 		return false;
 	}
 	}

+ 8 - 4
core/os/input_event.h

@@ -214,7 +214,7 @@ 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 bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
-	virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
+	virtual bool shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
 	virtual bool is_action_type() const;
 	virtual bool is_action_type() const;
 
 
 	virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
 	virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
@@ -263,6 +263,8 @@ public:
 
 
 	void set_modifiers_from_event(const InputEventWithModifiers *event);
 	void set_modifiers_from_event(const InputEventWithModifiers *event);
 
 
+	uint32_t get_modifiers_mask() const;
+
 	InputEventWithModifiers();
 	InputEventWithModifiers();
 };
 };
 
 
@@ -300,7 +302,7 @@ public:
 	uint32_t get_physical_scancode_with_modifiers() const;
 	uint32_t get_physical_scancode_with_modifiers() const;
 
 
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
-	virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
+	virtual bool shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
 
 
 	virtual bool is_action_type() const { return true; }
 	virtual bool is_action_type() const { return true; }
 
 
@@ -359,6 +361,7 @@ 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 bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
+	virtual bool shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
 
 
 	virtual bool is_action_type() const { return true; }
 	virtual bool is_action_type() const { return true; }
 	virtual String as_text() const;
 	virtual String as_text() const;
@@ -416,6 +419,7 @@ public:
 	virtual bool is_pressed() const;
 	virtual bool is_pressed() const;
 
 
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
+	virtual bool shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
 
 
 	virtual bool is_action_type() const { return true; }
 	virtual bool is_action_type() const { return true; }
 	virtual String as_text() const;
 	virtual String as_text() const;
@@ -443,7 +447,7 @@ public:
 	float get_pressure() const;
 	float get_pressure() const;
 
 
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
-	virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
+	virtual bool shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
 
 
 	virtual bool is_action_type() const { return true; }
 	virtual bool is_action_type() const { return true; }
 	virtual String as_text() const;
 	virtual String as_text() const;
@@ -531,7 +535,7 @@ public:
 
 
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 	virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
 
 
-	virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
+	virtual bool shortcut_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
 	virtual bool is_action_type() const { return true; }
 	virtual bool is_action_type() const { return true; }
 	virtual String as_text() const;
 	virtual String as_text() const;
 
 

+ 3 - 1
doc/classes/InputEvent.xml

@@ -85,8 +85,10 @@
 		<method name="shortcut_match" qualifiers="const">
 		<method name="shortcut_match" qualifiers="const">
 			<return type="bool" />
 			<return type="bool" />
 			<argument index="0" name="event" type="InputEvent" />
 			<argument index="0" name="event" type="InputEvent" />
+			<argument index="1" name="exact_match" type="bool" default="true" />
 			<description>
 			<description>
-				Returns [code]true[/code] if the given input event is checking for the same key ([InputEventKey]), button ([InputEventJoypadButton]) or action ([InputEventAction]).
+				Returns [code]true[/code] if the specified [code]event[/code] matches this event. Only valid for action events i.e key ([InputEventKey]), button ([InputEventMouseButton] or [InputEventJoypadButton]), axis [InputEventJoypadMotion] or action ([InputEventAction]) events.
+				If [code]exact_match[/code] is [code]false[/code], it ignores the input modifiers for [InputEventKey] and [InputEventMouseButton] events, and the direction for [InputEventJoypadMotion] events.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="xformed_by" qualifiers="const">
 		<method name="xformed_by" qualifiers="const">