More work on Prompt Widget
This commit is contained in:
@@ -84,3 +84,16 @@ DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.Defaul
|
||||
-ConsoleKeys=Tilde
|
||||
+ConsoleKeys=Tilde
|
||||
|
||||
[InputPlatformSettings_Linux InputPlatformSettings]
|
||||
MaxPlatformUserCount=8
|
||||
input.DeviceMappingPolicy=1
|
||||
MaxTriggerFeedbackPosition=8
|
||||
MaxTriggerFeedbackStrength=8
|
||||
MaxTriggerVibrationTriggerPosition=9
|
||||
MaxTriggerVibrationFrequency=255
|
||||
MaxTriggerVibrationAmplitude=8
|
||||
+HardwareDevices=(InputClassName="",HardwareDeviceIdentifier="",PrimaryDeviceType=Unspecified,SupportedFeaturesMask=0)
|
||||
+HardwareDevices=(InputClassName="DefaultKeyboardAndMouse",HardwareDeviceIdentifier="KBM",PrimaryDeviceType=KeyboardAndMouse,SupportedFeaturesMask=3)
|
||||
+HardwareDevices=(InputClassName="DefaultGamepad",HardwareDeviceIdentifier="Gamepad",PrimaryDeviceType=Gamepad,SupportedFeaturesMask=4)
|
||||
+HardwareDevices=(InputClassName="DefaultMobileTouch",HardwareDeviceIdentifier="MobileTouch",PrimaryDeviceType=Touch,SupportedFeaturesMask=8)
|
||||
|
||||
|
||||
@@ -134,3 +134,153 @@
|
||||
};
|
||||
|
||||
typedef FUnixPlatformStackWalk FPlatformStackWalk;
|
||||
--- Engine/Source/Runtime/ApplicationCore/Public/Linux/LinuxApplication.h.orig 2026-05-05 21:15:20.644087179 -0400
|
||||
+++ Engine/Source/Runtime/ApplicationCore/Public/Linux/LinuxApplication.h 2026-05-05 21:15:38.654613091 -0400
|
||||
@@ -265,6 +265,12 @@
|
||||
/** The input device Id of the controller that can be used to find the matching ULocalPlayer */
|
||||
FInputDeviceId DeviceId;
|
||||
|
||||
+ /** SDL gamepad type string (e.g. "ps4", "xboxone"), used as HardwareDeviceIdentifier in FInputDeviceScope */
|
||||
+ FName GamepadType;
|
||||
+
|
||||
+ /** SDL gamepad name (human-readable device name), used as InputDeviceName in FInputDeviceScope */
|
||||
+ FName GamepadName;
|
||||
+
|
||||
/** Store axis values from events here to be handled once per frame. */
|
||||
TMap<FGamepadKeyNames::Type, float> AxisEvents;
|
||||
|
||||
--- Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxApplication.cpp.orig 2026-05-05 21:15:20.646317814 -0400
|
||||
+++ Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxApplication.cpp 2026-05-05 23:13:59.528028910 -0400
|
||||
@@ -13,6 +13,13 @@
|
||||
#include "IHapticDevice.h"
|
||||
#include "GenericPlatform/GenericPlatformInputDeviceMapper.h"
|
||||
|
||||
+namespace UE::LinuxInput
|
||||
+{
|
||||
+ static const FName InputClassName = TEXT("LinuxApplication");
|
||||
+ static const FString KBMInputHardwareName = TEXT("KBM");
|
||||
+ static const FString TouchInputHardwareName = TEXT("MobileTouch");
|
||||
+}
|
||||
+
|
||||
//
|
||||
// GameController thresholds
|
||||
//
|
||||
@@ -320,6 +327,7 @@
|
||||
{
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::KBMInputHardwareName);
|
||||
const SDL_KeyboardEvent &KeyEvent = Event.key;
|
||||
SDL_Keycode KeySym = KeyEvent.key;
|
||||
const uint32 CharCode = CharCodeFromSDLKeySym(KeySym);
|
||||
@@ -342,6 +350,7 @@
|
||||
break;
|
||||
case SDL_EVENT_KEY_UP:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::KBMInputHardwareName);
|
||||
const SDL_KeyboardEvent &KeyEvent = Event.key;
|
||||
const SDL_Keycode KeySym = KeyEvent.key;
|
||||
const uint32 CharCode = CharCodeFromSDLKeySym(KeySym);
|
||||
@@ -352,6 +361,7 @@
|
||||
break;
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::KBMInputHardwareName);
|
||||
// Slate now gets all its text from here, I hope.
|
||||
const bool bIsRepeated = false; //Event.key.repeat != 0;
|
||||
const FString TextStr(UTF8_TO_TCHAR(Event.text.text));
|
||||
@@ -363,6 +373,7 @@
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::KBMInputHardwareName);
|
||||
SDL_MouseMotionEvent motionEvent = Event.motion;
|
||||
FLinuxCursor *LinuxCursor = (FLinuxCursor*)Cursor.Get();
|
||||
LinuxCursor->InvalidateCaches();
|
||||
@@ -406,6 +417,7 @@
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::KBMInputHardwareName);
|
||||
SDL_MouseButtonEvent buttonEvent = Event.button;
|
||||
|
||||
EMouseButtons::Type button;
|
||||
@@ -484,6 +496,7 @@
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_WHEEL:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::KBMInputHardwareName);
|
||||
SDL_MouseWheelEvent *WheelEvent = &Event.wheel;
|
||||
float Amount = (float)WheelEvent->y * fMouseWheelScrollAccel;
|
||||
|
||||
@@ -515,6 +528,7 @@
|
||||
|
||||
SDLControllerState &ControllerState = ControllerStates[caxisEvent.which];
|
||||
FPlatformUserId UserId = IPlatformInputDeviceMapper::Get().GetUserForInputDevice(ControllerState.DeviceId);
|
||||
+ FInputDeviceScope InputScope(nullptr, ControllerState.GamepadName, ControllerState.DeviceId.GetId(), ControllerState.GamepadType.ToString());
|
||||
|
||||
switch (caxisEvent.axis)
|
||||
{
|
||||
@@ -740,15 +754,17 @@
|
||||
|
||||
if (Button != FGamepadKeyNames::Invalid)
|
||||
{
|
||||
- FPlatformUserId UserId = IPlatformInputDeviceMapper::Get().GetUserForInputDevice(ControllerStates[cbuttonEvent.which].DeviceId);
|
||||
+ SDLControllerState& ButtonControllerState = ControllerStates[cbuttonEvent.which];
|
||||
+ FPlatformUserId UserId = IPlatformInputDeviceMapper::Get().GetUserForInputDevice(ButtonControllerState.DeviceId);
|
||||
+ FInputDeviceScope InputScope(nullptr, ButtonControllerState.GamepadName, ButtonControllerState.DeviceId.GetId(), ButtonControllerState.GamepadType.ToString());
|
||||
|
||||
if(cbuttonEvent.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN)
|
||||
{
|
||||
- MessageHandler->OnControllerButtonPressed(Button, UserId, ControllerStates[cbuttonEvent.which].DeviceId, false);
|
||||
+ MessageHandler->OnControllerButtonPressed(Button, UserId, ButtonControllerState.DeviceId, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
- MessageHandler->OnControllerButtonReleased(Button, UserId, ControllerStates[cbuttonEvent.which].DeviceId, false);
|
||||
+ MessageHandler->OnControllerButtonReleased(Button, UserId, ButtonControllerState.DeviceId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1018,6 +1034,7 @@
|
||||
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::TouchInputHardwareName);
|
||||
UE_LOG(LogLinuxWindow, Verbose, TEXT("Finger %llu is down at (%f, %f)"), Event.tfinger.fingerID, Event.tfinger.x, Event.tfinger.y);
|
||||
|
||||
// touch events can have no window associated with them, in that case ignore (with a warning)
|
||||
@@ -1053,6 +1070,7 @@
|
||||
break;
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::TouchInputHardwareName);
|
||||
UE_LOG(LogLinuxWindow, Verbose, TEXT("Finger %llu is up at (%f, %f)"), Event.tfinger.fingerID, Event.tfinger.x, Event.tfinger.y);
|
||||
|
||||
// touch events can have no window associated with them, in that case ignore (with a warning)
|
||||
@@ -1087,6 +1105,7 @@
|
||||
break;
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, UE::LinuxInput::InputClassName, IPlatformInputDeviceMapper::Get().GetDefaultInputDevice().GetId(), UE::LinuxInput::TouchInputHardwareName);
|
||||
// touch events can have no window associated with them, in that case ignore (with a warning)
|
||||
if (LIKELY(!bWindowlessEvent))
|
||||
{
|
||||
@@ -1196,6 +1215,7 @@
|
||||
IPlatformInputDeviceMapper& Mapper = IPlatformInputDeviceMapper::Get();
|
||||
for(auto ControllerIt = ControllerStates.CreateIterator(); ControllerIt; ++ControllerIt)
|
||||
{
|
||||
+ FInputDeviceScope InputScope(nullptr, ControllerIt.Value().GamepadName, ControllerIt.Value().DeviceId.GetId(), ControllerIt.Value().GamepadType.ToString());
|
||||
for(auto Event = ControllerIt.Value().AxisEvents.CreateConstIterator(); Event; ++Event)
|
||||
{
|
||||
FPlatformUserId UserId = Mapper.GetUserForInputDevice(ControllerIt.Value().DeviceId);
|
||||
@@ -2075,6 +2095,9 @@
|
||||
UE_LOG(LogLinux, Verbose, TEXT("Adding controller %i '%s'"), FirstUnusedIndex, UTF8_TO_TCHAR(SDL_GetGamepadName(Controller)));
|
||||
auto& ControllerState = ControllerStates.Add(Id);
|
||||
ControllerState.Controller = Controller;
|
||||
+ ControllerState.GamepadName = FName(UTF8_TO_TCHAR(SDL_GetGamepadName(Controller)));
|
||||
+ const char* GamepadTypeStr = SDL_GetGamepadStringForType(SDL_GetGamepadType(Controller));
|
||||
+ ControllerState.GamepadType = FName(GamepadTypeStr ? UTF8_TO_TCHAR(GamepadTypeStr) : TEXT("unknown"));
|
||||
|
||||
FPlatformUserId UserId = FPlatformUserId::CreateFromInternalId(FirstUnusedIndex);
|
||||
DeviceMapper.RemapControllerIdToPlatformUserAndDevice(FirstUnusedIndex, UserId, ControllerState.DeviceId);
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
"files.watcherExclude": {
|
||||
"[UNREALENGINE]/Engine/**": true,
|
||||
"[UNREALENGINE]/Samples/**": true,
|
||||
"[UNREALENGINE]/Templates/**": true
|
||||
"[UNREALENGINE]/Templates/**": true,
|
||||
"**/.*": true
|
||||
},
|
||||
"files.associations": {
|
||||
"**/include/**": "cpp",
|
||||
@@ -130,7 +131,7 @@
|
||||
"settings set target.inline-breakpoint-strategy always",
|
||||
"settings set target.prefer-dynamic-value no-run-target",
|
||||
"process handle SIGTRAP --notify false --pass false --stop false",
|
||||
"target stop-hook add --one-liner \"p ::UngrabAllInputImpl()\""
|
||||
"target stop-hook add --one-liner \"p FUnixPlatformMisc::UngrabAllInput()\""
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "PromptWidget.h"
|
||||
#include "UtilityLibrary.h"
|
||||
#include "PlayerControllerBase.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "GameFramework/InputDeviceSubsystem.h"
|
||||
#include "InputAction.h"
|
||||
#include "InputMappingContext.h"
|
||||
#include "Widgets/SOverlay.h"
|
||||
@@ -22,6 +20,7 @@
|
||||
// Row 7: Space Bar, unused, unused, unused
|
||||
// Row 8: unused, unused, unused, unused.
|
||||
|
||||
|
||||
int32 UlxPromptWidget::ChooseIcon(bool Playstation, FKey Key) const
|
||||
{
|
||||
// Mouse buttons (row 1)
|
||||
@@ -68,15 +67,6 @@ void UlxPromptWidget::ChooseAppearance(int32 &OutIcon, FString &OutGlyph)
|
||||
else OutGlyph = TEXT("");
|
||||
}
|
||||
|
||||
void UlxPromptWidget::OnHardwareDeviceChanged(const FPlatformUserId UserId, const FInputDeviceId DeviceId)
|
||||
{
|
||||
ElxControllerType Type = UlxUtilityLibrary::DetectControllerType(GetOwningLocalPlayer());
|
||||
if (ControllerType != Type)
|
||||
{
|
||||
ControllerType = Type;
|
||||
SynchronizeProperties();
|
||||
}
|
||||
}
|
||||
|
||||
FBox2f UlxPromptWidget::GetIconUVs(int32 IconIndex)
|
||||
{
|
||||
@@ -202,15 +192,23 @@ void UlxPromptWidget::SetKeysFromBindings(const UInputMappingContext* InputMappi
|
||||
SetKeys(NewGamepadKey, NewKeyboardKey);
|
||||
}
|
||||
|
||||
bool UlxPromptWidget::OnTick(float DeltaTime)
|
||||
{
|
||||
ElxControllerType Type = UlxUtilityLibrary::DetectControllerType(GetOwningLocalPlayer());
|
||||
if (ControllerType != Type)
|
||||
{
|
||||
ControllerType = Type;
|
||||
SynchronizeProperties();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TSharedRef<SWidget> UlxPromptWidget::RebuildWidget()
|
||||
{
|
||||
if (!IsDesignTime())
|
||||
{
|
||||
ControllerType = UlxUtilityLibrary::DetectControllerType(GetOwningLocalPlayer());
|
||||
if (UInputDeviceSubsystem* IDS = GEngine->GetEngineSubsystem<UInputDeviceSubsystem>())
|
||||
{
|
||||
IDS->OnInputHardwareDeviceChanged.AddDynamic(this, &UlxPromptWidget::OnHardwareDeviceChanged);
|
||||
}
|
||||
TickHandle = FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateUObject(this, &UlxPromptWidget::OnTick));
|
||||
}
|
||||
|
||||
MyBrush.SetResourceObject(ButtonAtlas.Get());
|
||||
@@ -240,10 +238,7 @@ void UlxPromptWidget::ReleaseSlateResources(bool bReleaseChildren)
|
||||
Super::ReleaseSlateResources(bReleaseChildren);
|
||||
if (!IsDesignTime())
|
||||
{
|
||||
if (UInputDeviceSubsystem* IDS = GEngine->GetEngineSubsystem<UInputDeviceSubsystem>())
|
||||
{
|
||||
IDS->OnInputHardwareDeviceChanged.RemoveDynamic(this, &UlxPromptWidget::OnHardwareDeviceChanged);
|
||||
}
|
||||
FTSTicker::GetCoreTicker().RemoveTicker(TickHandle);
|
||||
}
|
||||
MyBox.Reset();
|
||||
MyOverlay.Reset();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Widgets/SOverlay.h"
|
||||
#include "Widgets/Layout/SBox.h"
|
||||
#include "Widgets/Layout/SScaleBox.h"
|
||||
#include "Containers/Ticker.h"
|
||||
#include "PromptWidget.generated.h"
|
||||
|
||||
class UInputAction;
|
||||
@@ -62,8 +63,6 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category="Prompt")
|
||||
void SetDepressed(bool InDepressed);
|
||||
|
||||
UFUNCTION()
|
||||
void OnHardwareDeviceChanged(const FPlatformUserId UserId, const FInputDeviceId DeviceId);
|
||||
|
||||
protected:
|
||||
virtual TSharedRef<SWidget> RebuildWidget() override;
|
||||
@@ -84,4 +83,7 @@ private:
|
||||
FMargin GetScaledMargins() const;
|
||||
int32 ChooseIcon(bool Playstation, FKey Key) const;
|
||||
void ChooseAppearance(int32 &OutIcon, FString &OutGlyph);
|
||||
bool OnTick(float DeltaTime);
|
||||
|
||||
FTSTicker::FDelegateHandle TickHandle;
|
||||
};
|
||||
|
||||
@@ -283,17 +283,12 @@ ElxControllerType UlxUtilityLibrary::DetectControllerType(ULocalPlayer *Player)
|
||||
UInputDeviceSubsystem *IDS = GEngine->GetEngineSubsystem<UInputDeviceSubsystem>();
|
||||
if (!IDS) return ElxControllerType::KeyboardMouse;
|
||||
|
||||
FHardwareDeviceIdentifier Device = IDS->GetMostRecentlyUsedHardwareDevice(Player->GetPlatformUserId());
|
||||
if (Device.PrimaryDeviceType != EHardwareDevicePrimaryType::Gamepad)
|
||||
{
|
||||
FName Id = IDS->GetMostRecentlyUsedHardwareDevice(Player->GetPlatformUserId()).HardwareDeviceIdentifier;
|
||||
|
||||
if (Id == TEXT("ps3") || Id == TEXT("ps4") || Id == TEXT("ps5")) return ElxControllerType::PlayStationGamepad;
|
||||
if (Id == TEXT("xbox360") || Id == TEXT("xboxone")) return ElxControllerType::XboxGamepad;
|
||||
|
||||
// Unknown or unrecognized device — assume keyboard/mouse
|
||||
return ElxControllerType::KeyboardMouse;
|
||||
}
|
||||
|
||||
FString DeviceName = Device.HardwareDeviceIdentifier.ToString();
|
||||
if (DeviceName.Contains(TEXT("PS4")) || DeviceName.Contains(TEXT("PS5")) || DeviceName.Contains(TEXT("PlayStation")))
|
||||
{
|
||||
return ElxControllerType::PlayStationGamepad;
|
||||
}
|
||||
return ElxControllerType::XboxGamepad;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ function cube.lookmenu(add)
|
||||
end
|
||||
|
||||
function sphere.lookhotkeys(add)
|
||||
add("DPadU", "Sphere Hi", function () dprint("Doing Sphere Hi") end)
|
||||
add("DPadL", "Sphere Bye", function () dprint("Doing Sphere Bye") end)
|
||||
add("DPadR", "Sphere Yo", function () dprint("Doing Sphere Yo") end)
|
||||
add("FaceL", "Sphere Hi", function () dprint("Doing Sphere Hi") end)
|
||||
add("FaceM", "Sphere Bye", function () dprint("Doing Sphere Bye") end)
|
||||
add("FaceR", "Sphere Yo", function () dprint("Doing Sphere Yo") end)
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user