From f24ac2c7b09d2bc1074498c6c1741e4619783d06 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Thu, 29 Jan 2026 20:45:59 +0100
Subject: [PATCH 1/2] [client,sdl] add SDL_Error to exceptions

---
 client/SDL/SDL3/sdl_freerdp.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/client/SDL/SDL3/sdl_freerdp.cpp b/client/SDL/SDL3/sdl_freerdp.cpp
index 9dc1c9416453..e92dc109333c 100644
--- a/client/SDL/SDL3/sdl_freerdp.cpp
+++ b/client/SDL/SDL3/sdl_freerdp.cpp
@@ -73,7 +73,8 @@
 class ErrorMsg : public std::exception
 {
   public:
-	ErrorMsg(int rc, Uint32 type, const std::string& msg);
+	ErrorMsg(int rc, Uint32 type, const std::string& msg,
+	         const std::string& sdlError = SDL_GetError());
 
 	[[nodiscard]] int rc() const;
 	[[nodiscard]] const char* what() const noexcept override;
@@ -82,6 +83,7 @@ class ErrorMsg : public std::exception
 	int _rc;
 	Uint32 _type;
 	std::string _msg;
+	std::string _sdlError;
 	std::string _buffer;
 };
 const char* ErrorMsg::what() const noexcept
@@ -94,10 +96,11 @@ int ErrorMsg::rc() const
 	return _rc;
 }
 
-ErrorMsg::ErrorMsg(int rc, Uint32 type, const std::string& msg) : _rc(rc), _type(type), _msg(msg)
+ErrorMsg::ErrorMsg(int rc, Uint32 type, const std::string& msg, const std::string& sdlError)
+    : _rc(rc), _type(type), _msg(msg), _sdlError(sdlError)
 {
 	std::stringstream ss;
-	ss << _msg << " {" << sdl::utils::toString(_type) << "}";
+	ss << _msg << " {" << sdl::utils::toString(_type) << "}{SDL:" << sdlError << "}";
 	_buffer = ss.str();
 }
 

From b7a92956e6a92569f5da0ac0f1f643d61a183826 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Thu, 29 Jan 2026 21:48:22 +0100
Subject: [PATCH 2/2] [client,sdl] log all cursor related errors

---
 client/SDL/SDL3/sdl_context.cpp | 12 ++++++++++++
 client/SDL/SDL3/sdl_pointer.cpp | 28 ++++++++++++++++++++++++++++
 client/SDL/SDL3/sdl_utils.cpp   |  5 ++++-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/client/SDL/SDL3/sdl_context.cpp b/client/SDL/SDL3/sdl_context.cpp
index a502cceb9919..80aeeb895a38 100644
--- a/client/SDL/SDL3/sdl_context.cpp
+++ b/client/SDL/SDL3/sdl_context.cpp
@@ -1303,7 +1303,10 @@ bool SdlContext::restoreCursor()
 	{
 		case CURSOR_NULL:
 			if (!SDL_HideCursor())
+			{
+				WLog_Print(getWLog(), WLOG_ERROR, "SDL_HideCursor failed");
 				return false;
+			}
 
 			setHasCursor(false);
 			return true;
@@ -1312,9 +1315,16 @@ bool SdlContext::restoreCursor()
 		{
 			auto def = SDL_GetDefaultCursor();
 			if (!SDL_SetCursor(def))
+			{
+				WLog_Print(getWLog(), WLOG_ERROR, "SDL_SetCursor(default=%p) failed",
+				           static_cast<void*>(def));
 				return false;
+			}
 			if (!SDL_ShowCursor())
+			{
+				WLog_Print(getWLog(), WLOG_ERROR, "SDL_ShowCursor failed");
 				return false;
+			}
 			setHasCursor(true);
 			return true;
 		}
@@ -1322,6 +1332,8 @@ bool SdlContext::restoreCursor()
 			setHasCursor(true);
 			return sdl_Pointer_Set_Process(this);
 		default:
+			WLog_Print(getWLog(), WLOG_ERROR, "Unknown cursorType %s",
+			           sdl::utils::toString(_cursorType).c_str());
 			return false;
 	}
 }
diff --git a/client/SDL/SDL3/sdl_pointer.cpp b/client/SDL/SDL3/sdl_pointer.cpp
index 13832254172a..322269190af3 100644
--- a/client/SDL/SDL3/sdl_pointer.cpp
+++ b/client/SDL/SDL3/sdl_pointer.cpp
@@ -134,10 +134,16 @@ bool sdl_Pointer_Set_Process(SdlContext* sdl)
 	ptr->image =
 	    SDL_CreateSurface(static_cast<int>(pos.w), static_cast<int>(pos.h), sdl->pixelFormat());
 	if (!ptr->image)
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_CreateSurface failed");
 		return false;
+	}
 
 	if (!SDL_LockSurface(ptr->image))
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_LockSurface failed");
 		return false;
+	}
 
 	auto pixels = static_cast<BYTE*>(ptr->image->pixels);
 	auto data = static_cast<const BYTE*>(ptr->data);
@@ -147,13 +153,19 @@ bool sdl_Pointer_Set_Process(SdlContext* sdl)
 	    gdi->dstFormat, 0, 0, 0, static_cast<UINT32>(isw), static_cast<UINT32>(ish));
 	SDL_UnlockSurface(ptr->image);
 	if (!rc)
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "freerdp_image_scale failed");
 		return false;
+	}
 
 	// create a cursor image in 100% display scale to trick SDL into creating the cursor with the
 	// correct size
 	auto fw = sdl->getFirstWindow();
 	if (!fw)
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "sdl->getFirstWindow() NULL");
 		return false;
+	}
 
 	const auto hidpi_scale =
 	    sdl->pixelToScreen(fw->id(), SDL_FPoint{ static_cast<float>(ptr->image->w),
@@ -163,20 +175,36 @@ bool sdl_Pointer_Set_Process(SdlContext* sdl)
 	assert(normal);
 	if (!SDL_BlitSurfaceScaled(ptr->image, nullptr, normal, nullptr,
 	                           SDL_ScaleMode::SDL_SCALEMODE_LINEAR))
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_BlitSurfaceScaled failed");
 		return false;
+	}
 	if (!SDL_AddSurfaceAlternateImage(normal, ptr->image))
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_AddSurfaceAlternateImage failed");
 		return false;
+	}
 
 	ptr->cursor = SDL_CreateColorCursor(normal, static_cast<int>(pos.x), static_cast<int>(pos.y));
 	if (!ptr->cursor)
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_CreateColorCursor(%fx%f) failed",
+		           static_cast<double>(pos.x), static_cast<double>(pos.y));
 		return false;
+	}
 
 	SDL_DestroySurface(normal);
 
 	if (!SDL_SetCursor(ptr->cursor))
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_SetCursor failed");
 		return false;
+	}
 	if (!SDL_ShowCursor())
+	{
+		WLog_Print(sdl->getWLog(), WLOG_ERROR, "SDL_ShowCursor failed");
 		return false;
+	}
 	sdl->setHasCursor(true);
 	return true;
 }
diff --git a/client/SDL/SDL3/sdl_utils.cpp b/client/SDL/SDL3/sdl_utils.cpp
index 970d4e1e795c..5210d7bae51f 100644
--- a/client/SDL/SDL3/sdl_utils.cpp
+++ b/client/SDL/SDL3/sdl_utils.cpp
@@ -144,7 +144,10 @@ bool sdl_push_user_event(Uint32 type, ...)
 			return false;
 	}
 	va_end(ap);
-	return SDL_PushEvent(&ev) == 1;
+	const auto rc = SDL_PushEvent(&ev);
+	if (rc != 1)
+		SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "[%s] SDL_PushEvent returned %d", __func__, rc);
+	return rc == 1;
 }
 
 bool sdl_push_quit()
