287 lines
13 KiB
Plaintext
287 lines
13 KiB
Plaintext
--- Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp.orig 2026-05-08 14:11:02.262757499 -0400
|
|
+++ Engine/Plugins/Developer/VisualStudioCodeSourceCodeAccess/Source/VisualStudioCodeSourceCodeAccess/Private/VisualStudioCodeSourceCodeAccessor.cpp 2026-05-05 15:36:35.232152395 -0400
|
|
@@ -149,7 +149,7 @@
|
|
FString SolutionDir = GetSolutionPath();
|
|
TArray<FString> Args;
|
|
Args.Add(MakePath(SolutionDir));
|
|
- Args.Add(TEXT("-g ") + MakePath(FullPath) + FString::Printf(TEXT(":%d:%d"), LineNumber, ColumnNumber));
|
|
+ Args.Add(TEXT("-g ") + MakePath(FullPath + FString::Printf(TEXT(":%d:%d"), LineNumber, ColumnNumber)));
|
|
return Launch(Args);
|
|
}
|
|
|
|
--- Engine/Source/Editor/UnrealEd/Private/SourceCodeNavigation.cpp.orig 2026-05-08 14:11:02.370759731 -0400
|
|
+++ Engine/Source/Editor/UnrealEd/Private/SourceCodeNavigation.cpp 2026-05-05 15:36:35.232353795 -0400
|
|
@@ -557,7 +557,7 @@
|
|
ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>("SourceCodeAccess");
|
|
ISourceCodeAccessor& SourceCodeAccessor = SourceCodeAccessModule.GetAccessor();
|
|
|
|
-#if PLATFORM_WINDOWS
|
|
+#if PLATFORM_WINDOWS || PLATFORM_LINUX
|
|
FString SourceFileName;
|
|
uint32 SourceLineNumber = 1;
|
|
uint32 SourceColumnNumber = 0;
|
|
@@ -716,8 +716,8 @@
|
|
}
|
|
|
|
UE_LOG(LogSelectionDetails, Warning, TEXT("NavigateToFunctionSource: Unable to look up symbol: %s in module:%s"), *FunctionSymbolName, *FunctionModuleName);
|
|
-
|
|
-#endif // PLATFORM_WINDOWS
|
|
+
|
|
+#endif // PLATFORM_WINDOWS || PLATFORM_LINUX
|
|
}
|
|
|
|
|
|
--- Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp.orig 2026-05-08 14:11:02.477761942 -0400
|
|
+++ Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp 2026-05-05 15:36:35.232635087 -0400
|
|
@@ -317,6 +317,9 @@
|
|
// Furthermore SDL hides the mouse which we prevent by setting SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE
|
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // When relative mouse mode is active, don't hide cursor.
|
|
|
|
+ // Unreal does its own dynamic capturing, we don't need SDL to do it.
|
|
+ SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
|
+
|
|
// If we're rendering offscreen, use the "dummy" SDL video driver
|
|
if (FParse::Param(FCommandLine::Get(), TEXT("RenderOffScreen")) && !getenv("SDL_VIDEODRIVER"))
|
|
{
|
|
--- Engine/Source/Runtime/Core/Private/Unix/UnixPlatformStackWalk.cpp.orig 2026-05-08 14:11:02.584764153 -0400
|
|
+++ Engine/Source/Runtime/Core/Private/Unix/UnixPlatformStackWalk.cpp 2026-05-05 15:36:35.232750204 -0400
|
|
@@ -15,6 +15,7 @@
|
|
#include "HAL/ExceptionHandling.h"
|
|
#include "HAL/PlatformProcess.h"
|
|
#include "HAL/PlatformTime.h"
|
|
+#include "Modules/ModuleManager.h"
|
|
#include "AutoRTFM.h"
|
|
|
|
#include <link.h>
|
|
@@ -1063,3 +1064,69 @@
|
|
}
|
|
ReportLock.Unlock();
|
|
}
|
|
+
|
|
+bool FUnixPlatformStackWalk::GetFunctionDefinitionLocation(const FString& FunctionSymbolName, const FString& FunctionModuleName, FString& OutPathname, uint32& OutLineNumber, uint32& OutColumnNumber)
|
|
+{
|
|
+ // Find the .so path for this module.
|
|
+ FString ModulePath;
|
|
+ TArray<FModuleStatus> AllModules;
|
|
+ FModuleManager::Get().QueryModules(AllModules);
|
|
+ for (const FModuleStatus& Status : AllModules)
|
|
+ {
|
|
+ if (FPaths::GetBaseFilename(Status.FilePath) == FunctionModuleName)
|
|
+ {
|
|
+ ModulePath = Status.FilePath;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (ModulePath.IsEmpty())
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Debug symbols are in a separate .debug file alongside the .so.
|
|
+ FString DebugPath = FPaths::ChangeExtension(ModulePath, TEXT("debug"));
|
|
+ if (!FPaths::FileExists(DebugPath))
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Use lldb to look up the source file and line number.
|
|
+ // Run: lldb -b -o "image lookup -v -n ClassName::FuncName" <debug_file>
|
|
+ FString LldbParams = FString::Printf(TEXT("-b -o \"image lookup -v -n %s\" \"%s\""), *FunctionSymbolName, *DebugPath);
|
|
+ int32 ReturnCode = 0;
|
|
+ FString AllOutput;
|
|
+ FString Errors;
|
|
+ FPlatformProcess::ExecProcess(TEXT("/usr/bin/lldb"), *LldbParams, &ReturnCode, &AllOutput, &Errors);
|
|
+ if (ReturnCode != 0)
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Parse the LineEntry from lldb verbose output.
|
|
+ // Format: "LineEntry: [0x...-0x...): /path/to/file.cpp:132"
|
|
+ TArray<FString> Lines;
|
|
+ AllOutput.ParseIntoArrayLines(Lines);
|
|
+ for (const FString& Line : Lines)
|
|
+ {
|
|
+ FString Trimmed = Line.TrimStartAndEnd();
|
|
+ if (!Trimmed.StartsWith(TEXT("LineEntry:")))
|
|
+ continue;
|
|
+
|
|
+ int32 ParenIndex = Trimmed.Find(TEXT("): "));
|
|
+ if (ParenIndex == INDEX_NONE)
|
|
+ continue;
|
|
+ FString FileAndLine = Trimmed.Mid(ParenIndex + 3);
|
|
+
|
|
+ int32 ColonIndex;
|
|
+ if (!FileAndLine.FindLastChar(TCHAR(':'), ColonIndex))
|
|
+ continue;
|
|
+
|
|
+ OutPathname = FileAndLine.Left(ColonIndex);
|
|
+ OutLineNumber = FCString::Atoi(*FileAndLine.Mid(ColonIndex + 1));
|
|
+ OutColumnNumber = 0;
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
--- Engine/Source/Runtime/Core/Public/Unix/UnixPlatformStackWalk.h.orig 2026-05-08 14:11:02.692766385 -0400
|
|
+++ Engine/Source/Runtime/Core/Public/Unix/UnixPlatformStackWalk.h 2026-05-05 15:36:35.232861435 -0400
|
|
@@ -24,6 +24,8 @@
|
|
static CORE_API void ThreadStackWalkAndDump(ANSICHAR* HumanReadableString, SIZE_T HumanReadableStringSize, int32 IgnoreCount, uint32 ThreadId);
|
|
static CORE_API int32 GetProcessModuleCount();
|
|
static CORE_API int32 GetProcessModuleSignatures(FStackWalkModuleInfo *ModuleSignatures, const int32 ModuleSignaturesSize);
|
|
+
|
|
+ static CORE_API bool GetFunctionDefinitionLocation(const FString& FunctionSymbolName, const FString& FunctionModuleName, FString& OutPathname, uint32& OutLineNumber, uint32& OutColumnNumber);
|
|
};
|
|
|
|
typedef FUnixPlatformStackWalk FPlatformStackWalk;
|
|
--- Engine/Source/Runtime/ApplicationCore/Public/Linux/LinuxApplication.h.orig 2026-05-08 14:11:02.802768658 -0400
|
|
+++ Engine/Source/Runtime/ApplicationCore/Public/Linux/LinuxApplication.h 2026-05-08 14:09:14.778161399 -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-08 14:11:02.910770890 -0400
|
|
+++ Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxApplication.cpp 2026-05-08 14:09:14.778345206 -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);
|