OnKeyDown doesn't work with a keyboard focused Editable Text Box wrapped in a Canvas in a User Widget.

Thank you for that! I have been looking and looking, and couldn’t find this anywhere.
Do you know by chance if I can do the same for gamepad keys?

The InKeyEvent knows if input was a gamepad key or not, but so far my best option has been to hash the string and compare that as how I do here (feels tedious):

UENUM(BlueprintType)
enum class EMyGamepadKey : uint8
{
	invalid,

	left_shoulder,
	right_shoulder,
	left_trigger,
	right_trigger,
	face_button_top,
	face_button_bottom,
	face_button_left,
	face_button_right,
	left_thumbstick_up,
	left_thumbstick_down,
	left_thumbstick_left,
	left_thumbstick_right,
	right_thumbstick_up,
	right_thumbstick_down,
	right_thumbstick_left,
	right_thumbstick_right,
	data_pad_up,
	data_pad_down,
	data_pad_left,
	data_pad_right,
	special_left,
	special_right
};

UCLASS()
class UMyGamepadKeyConverter final : public UObject
{
	GENERATED_BODY()

private:
	// Hard topic. Some help:
	// https://stackoverflow.com/questions/2111667/compile-time-string-hashing
	static constexpr size_t MyCompileTimeHash(const std::string_view Str)
	{
		size_t Hash = sizeof(size_t) == 8 ? 0xcbf29ce484222325 : 0x811c9dc5;
		constexpr size_t Prime = sizeof(size_t) == 8 ? 0x00000100000001b3 : 0x01000193;

		const char* Input = Str.data();
		while (*Input) {
			Hash ^= static_cast<size_t>(*Input);
			Hash *= Prime;
			++Input;
		}

		return Hash;
	}

public:
	UFUNCTION(BlueprintCallable)
	static inline EMyGamepadKey GetGamepadKeyFromString(const FString& GamepadKeyString)
	{
		// String hash library
		static constexpr std::string_view String_Ls = "Gamepad Left Shoulder";
		static constexpr std::string_view String_Rs = "Gamepad Right Shoulder";
		static constexpr std::string_view String_Lt = "Gamepad Left Trigger";
		static constexpr std::string_view String_Rt = "Gamepad Right Trigger";
		static constexpr std::string_view String_Fbt = "Gamepad Face Button Top";
		static constexpr std::string_view String_Fbb = "Gamepad Face Button Bottom";
		static constexpr std::string_view String_Fbl = "Gamepad Face Button Left";
		static constexpr std::string_view String_Fbr = "Gamepad Face Button Right";
		static constexpr std::string_view String_Ltu = "Gamepad Left Thumbstick Up";
		static constexpr std::string_view String_Ltd = "Gamepad Left Thumbstick Down";
		static constexpr std::string_view String_Ltl = "Gamepad Left Thumbstick Left";
		static constexpr std::string_view String_Ltr = "Gamepad Left Thumbstick Right";
		static constexpr std::string_view String_Rtu = "Gamepad Right Thumbstick Up";
		static constexpr std::string_view String_Rtd = "Gamepad Right Thumbstick Down";
		static constexpr std::string_view String_Rtl = "Gamepad Right Thumbstick Left";
		static constexpr std::string_view String_Rtr = "Gamepad Right Thumbstick Right";
		static constexpr std::string_view String_Dpu = "Gamepad D-pad Up";
		static constexpr std::string_view String_Dpd = "Gamepad D-pad Down";
		static constexpr std::string_view String_Dpl = "Gamepad D-pad Left";
		static constexpr std::string_view String_Dpr = "Gamepad D-pad Right";
		static constexpr std::string_view String_Sl = "Gamepad Special Left";
		static constexpr std::string_view String_Sr = "Gamepad Special Right";

		static constexpr size_t Ls = MyCompileTimeHash(String_Ls);
		static constexpr size_t Rs = MyCompileTimeHash(String_Rs);
		static constexpr size_t Lt = MyCompileTimeHash(String_Lt);
		static constexpr size_t Rt = MyCompileTimeHash(String_Rt);
		static constexpr size_t Fbt = MyCompileTimeHash(String_Fbt);
		static constexpr size_t Fbb = MyCompileTimeHash(String_Fbb);
		static constexpr size_t Fbl = MyCompileTimeHash(String_Fbl);
		static constexpr size_t Fbr = MyCompileTimeHash(String_Fbr);
		static constexpr size_t Ltu = MyCompileTimeHash(String_Ltu);
		static constexpr size_t Ltd = MyCompileTimeHash(String_Ltd);
		static constexpr size_t Ltl = MyCompileTimeHash(String_Ltl);
		static constexpr size_t Ltr = MyCompileTimeHash(String_Ltr);
		static constexpr size_t Rtu = MyCompileTimeHash(String_Rtu);
		static constexpr size_t Rtd = MyCompileTimeHash(String_Rtd);
		static constexpr size_t Rtl = MyCompileTimeHash(String_Rtl);
		static constexpr size_t Rtr = MyCompileTimeHash(String_Rtr);
		static constexpr size_t Dpu = MyCompileTimeHash(String_Dpu);
		static constexpr size_t Dpd = MyCompileTimeHash(String_Dpd);
		static constexpr size_t Dpl = MyCompileTimeHash(String_Dpl);
		static constexpr size_t Dpr = MyCompileTimeHash(String_Dpr);
		static constexpr size_t Sl = MyCompileTimeHash(String_Sl);
		static constexpr size_t Sr = MyCompileTimeHash(String_Sr);

		// Hashing the argument
		const TCHAR* Ptr = GetData(GamepadKeyString);
		const std::string_view Input = StringCast<ANSICHAR>(Ptr).Get();

		switch (MyCompileTimeHash(Input))
		{
		case Ls: return EMyGamepadKey::left_shoulder;
		case Rs: return EMyGamepadKey::right_shoulder;
		case Lt: return EMyGamepadKey::left_trigger;
		case Rt: return EMyGamepadKey::right_trigger;
		case Fbt: return EMyGamepadKey::face_button_top;
		case Fbb: return EMyGamepadKey::face_button_bottom;
		case Fbl: return EMyGamepadKey::face_button_left;
		case Fbr: return EMyGamepadKey::face_button_right;
		case Ltu: return EMyGamepadKey::left_thumbstick_up;
		case Ltd: return EMyGamepadKey::left_thumbstick_down;
		case Ltl: return EMyGamepadKey::left_thumbstick_left;
		case Ltr: return EMyGamepadKey::left_thumbstick_right;
		case Rtu: return EMyGamepadKey::right_thumbstick_up;
		case Rtd: return EMyGamepadKey::right_thumbstick_down;
		case Rtl: return EMyGamepadKey::right_thumbstick_left;
		case Rtr: return EMyGamepadKey::right_thumbstick_right;
		case Dpu: return EMyGamepadKey::data_pad_up;
		case Dpd: return EMyGamepadKey::data_pad_down;
		case Dpl: return EMyGamepadKey::data_pad_left;
		case Dpr: return EMyGamepadKey::data_pad_right;
		case Sl: return EMyGamepadKey::special_left;
		case Sr: return EMyGamepadKey::special_right;

		default:
			return EMyGamepadKey::invalid;
		}
	}
};

Sorry for the long code - just wanted to be exact. And maybe it’s useful to others as well. :slight_smile:

And yes, the string is fragile - but it would probably be okay if I at least use the TEXT() macro?