diff --git a/client/SDL/SDL3/sdl_context.cpp b/client/SDL/SDL3/sdl_context.cpp index 75df27721..0dbf299fb 100644 --- a/client/SDL/SDL3/sdl_context.cpp +++ b/client/SDL/SDL3/sdl_context.cpp @@ -411,9 +411,6 @@ bool SdlContext::createWindows() if (!freerdp_settings_get_bool(settings, FreeRDP_Decorations)) flags |= SDL_WINDOW_BORDERLESS; - std::stringstream ss; - ss << title << ":" << x; - auto did = WINPR_ASSERTING_INT_CAST(SDL_DisplayID, id); auto window = SdlWindow::create(did, title, flags, w, h); @@ -667,7 +664,10 @@ int SdlContext::sdl_client_thread_run(std::string& error_msg) const DWORD status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE); if (status == WAIT_FAILED) + { + WLog_Print(getWLog(), WLOG_ERROR, "WaitForMultipleObjects WAIT_FAILED"); break; + } if (!freerdp_check_event_handles(context())) { @@ -763,6 +763,16 @@ int SdlContext::error_info_to_error(DWORD* pcode, char** msg, size_t* len) const return exit_code; } +void SdlContext::applyMonitorOffset(SDL_WindowID window, float& x, float& y) const +{ + if (!freerdp_settings_get_bool(context()->settings, FreeRDP_UseMultimon)) + return; + + auto w = getWindowForId(window); + x -= static_cast(w->offsetX()); + y -= static_cast(w->offsetY()); +} + bool SdlContext::drawToWindow(SdlWindow& window, const std::vector& rects) { if (!isConnected()) @@ -840,6 +850,14 @@ bool SdlContext::removeDisplay(SDL_DisplayID id) return true; } +const SdlWindow* SdlContext::getWindowForId(SDL_WindowID id) const +{ + auto it = _windows.find(id); + if (it == _windows.end()) + return nullptr; + return &it->second; +} + SdlWindow* SdlContext::getWindowForId(SDL_WindowID id) { auto it = _windows.find(id); @@ -900,6 +918,7 @@ bool SdlContext::handleEvent(const SDL_MouseMotionEvent& ev) return false; removeLocalScaling(copy.motion.x, copy.motion.y); removeLocalScaling(copy.motion.xrel, copy.motion.yrel); + applyMonitorOffset(copy.motion.windowID, copy.motion.x, copy.motion.y); return SdlTouch::handleEvent(this, copy.motion); } @@ -937,6 +956,8 @@ bool SdlContext::handleEvent(const SDL_WindowEvent& ev) switch (ev.type) { + case SDL_EVENT_WINDOW_MOUSE_ENTER: + return restoreCursor(); case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: if (isConnected()) { @@ -944,7 +965,7 @@ bool SdlContext::handleEvent(const SDL_WindowEvent& ev) return false; if (!drawToWindow(*window)) return false; - if (!sdl_Pointer_Set_Process(this)) + if (!restoreCursor()) return false; } break; @@ -953,7 +974,7 @@ bool SdlContext::handleEvent(const SDL_WindowEvent& ev) return false; if (!drawToWindow(*window)) return false; - if (!sdl_Pointer_Set_Process(this)) + if (!restoreCursor()) return false; break; case SDL_EVENT_WINDOW_MOVED: @@ -1016,6 +1037,7 @@ bool SdlContext::handleEvent(const SDL_MouseButtonEvent& ev) if (!eventToPixelCoordinates(ev.windowID, copy)) return false; removeLocalScaling(copy.button.x, copy.button.y); + applyMonitorOffset(copy.button.windowID, copy.button.x, copy.button.y); return SdlTouch::handleEvent(this, copy.button); } @@ -1027,6 +1049,7 @@ bool SdlContext::handleEvent(const SDL_TouchFingerEvent& ev) return false; removeLocalScaling(copy.tfinger.dx, copy.tfinger.dy); removeLocalScaling(copy.tfinger.x, copy.tfinger.y); + applyMonitorOffset(copy.tfinger.windowID, copy.tfinger.x, copy.tfinger.y); return SdlTouch::handleEvent(this, copy.tfinger); } @@ -1035,9 +1058,11 @@ bool SdlContext::eventToPixelCoordinates(SDL_WindowID id, SDL_Event& ev) auto w = getWindowForId(id); if (!w) return false; + + /* Ignore errors here, sometimes SDL has no renderer */ auto renderer = SDL_GetRenderer(w->window()); if (!renderer) - return false; + return true; return SDL_ConvertEventToRenderCoordinates(renderer, &ev); } @@ -1065,9 +1090,11 @@ SDL_FPoint SdlContext::screenToPixel(SDL_WindowID id, const SDL_FPoint& pos) auto w = getWindowForId(id); if (!w) return {}; + + /* Ignore errors here, sometimes SDL has no renderer */ auto renderer = SDL_GetRenderer(w->window()); if (!renderer) - return {}; + return pos; SDL_FPoint rpos{}; if (!SDL_RenderCoordinatesFromWindow(renderer, pos.x, pos.y, &rpos.x, &rpos.y)) @@ -1081,9 +1108,11 @@ SDL_FPoint SdlContext::pixelToScreen(SDL_WindowID id, const SDL_FPoint& pos) auto w = getWindowForId(id); if (!w) return {}; + + /* Ignore errors here, sometimes SDL has no renderer */ auto renderer = SDL_GetRenderer(w->window()); if (!renderer) - return {}; + return pos; SDL_FPoint rpos{}; if (!SDL_RenderCoordinatesToWindow(renderer, pos.x, pos.y, &rpos.x, &rpos.y)) @@ -1247,9 +1276,16 @@ rdpClientContext* SdlContext::common() const return reinterpret_cast(context()); } -void SdlContext::setCursor(rdpPointer* cursor) +bool SdlContext::setCursor(CursorType type) +{ + _cursorType = type; + return restoreCursor(); +} + +bool SdlContext::setCursor(rdpPointer* cursor) { _cursor = cursor; + return setCursor(CURSOR_IMAGE); } rdpPointer* SdlContext::cursor() const @@ -1257,6 +1293,36 @@ rdpPointer* SdlContext::cursor() const return _cursor; } +bool SdlContext::restoreCursor() +{ + WLog_Print(getWLog(), WLOG_DEBUG, "restore cursor: %d", _cursorType); + switch (_cursorType) + { + case CURSOR_NULL: + if (!SDL_HideCursor()) + return false; + + setHasCursor(false); + return true; + + case CURSOR_DEFAULT: + { + auto def = SDL_GetDefaultCursor(); + if (!SDL_SetCursor(def)) + return false; + if (!SDL_ShowCursor()) + return false; + setHasCursor(true); + return true; + } + case CURSOR_IMAGE: + setHasCursor(true); + return sdl_Pointer_Set_Process(this); + default: + return false; + } +} + void SdlContext::setMonitorIds(const std::vector& ids) { _monitorIds.clear(); diff --git a/client/SDL/SDL3/sdl_context.hpp b/client/SDL/SDL3/sdl_context.hpp index e83b1b0b2..ef6b59fb7 100644 --- a/client/SDL/SDL3/sdl_context.hpp +++ b/client/SDL/SDL3/sdl_context.hpp @@ -43,6 +43,13 @@ class SdlContext { public: + enum CursorType + { + CURSOR_NULL, + CURSOR_DEFAULT, + CURSOR_IMAGE + }; + explicit SdlContext(rdpContext* context); SdlContext(const SdlContext& other) = delete; SdlContext(SdlContext&& other) = delete; @@ -78,15 +85,17 @@ class SdlContext [[nodiscard]] rdpContext* context() const; [[nodiscard]] rdpClientContext* common() const; - void setCursor(rdpPointer* cursor); + [[nodiscard]] bool setCursor(CursorType type); + [[nodiscard]] bool setCursor(rdpPointer* cursor); [[nodiscard]] rdpPointer* cursor() const; + [[nodiscard]] bool restoreCursor(); void setMonitorIds(const std::vector& ids); - const std::vector& monitorIds() const; - int64_t monitorId(uint32_t index) const; + [[nodiscard]] const std::vector& monitorIds() const; + [[nodiscard]] int64_t monitorId(uint32_t index) const; void push(std::vector&& rects); - std::vector pop(); + [[nodiscard]] std::vector pop(); void setHasCursor(bool val); [[nodiscard]] bool hasCursor() const; @@ -106,6 +115,7 @@ class SdlContext [[nodiscard]] int exitCode() const; [[nodiscard]] SDL_PixelFormat pixelFormat() const; + [[nodiscard]] const SdlWindow* getWindowForId(SDL_WindowID id) const; [[nodiscard]] SdlWindow* getWindowForId(SDL_WindowID id); [[nodiscard]] SdlWindow* getFirstWindow(); @@ -162,12 +172,15 @@ class SdlContext [[nodiscard]] int error_info_to_error(DWORD* pcode, char** msg, size_t* len) const; + void applyMonitorOffset(SDL_WindowID window, float& x, float& y) const; + rdpContext* _context = nullptr; wLog* _log = nullptr; std::atomic _connected = false; bool _cursor_visible = true; rdpPointer* _cursor = nullptr; + CursorType _cursorType = CURSOR_NULL; std::vector _monitorIds; std::mutex _queue_mux; std::queue> _queue; diff --git a/client/SDL/SDL3/sdl_freerdp.cpp b/client/SDL/SDL3/sdl_freerdp.cpp index 81d86a1c3..9dc1c9416 100644 --- a/client/SDL/SDL3/sdl_freerdp.cpp +++ b/client/SDL/SDL3/sdl_freerdp.cpp @@ -70,6 +70,37 @@ #define SDL_TAG CLIENT_TAG("SDL") #endif +class ErrorMsg : public std::exception +{ + public: + ErrorMsg(int rc, Uint32 type, const std::string& msg); + + [[nodiscard]] int rc() const; + [[nodiscard]] const char* what() const noexcept override; + + private: + int _rc; + Uint32 _type; + std::string _msg; + std::string _buffer; +}; +const char* ErrorMsg::what() const noexcept +{ + return _buffer.c_str(); +} + +int ErrorMsg::rc() const +{ + return _rc; +} + +ErrorMsg::ErrorMsg(int rc, Uint32 type, const std::string& msg) : _rc(rc), _type(type), _msg(msg) +{ + std::stringstream ss; + ss << _msg << " {" << sdl::utils::toString(_type) << "}"; + _buffer = ss.str(); +} + static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const char* signame, [[maybe_unused]] void* context) { @@ -81,21 +112,23 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const int rc = -1; WINPR_ASSERT(sdl); - while (!sdl->shallAbort()) + try { - SDL_Event windowEvent = {}; - while (!sdl->shallAbort() && SDL_WaitEventTimeout(nullptr, 1000)) + while (!sdl->shallAbort()) { - /* Only poll standard SDL events and SDL_EVENT_USERS meant to create - * dialogs. do not process the dialog return value events here. - */ - const int prc = SDL_PeepEvents(&windowEvent, 1, SDL_GETEVENT, SDL_EVENT_FIRST, - SDL_EVENT_USER_RETRY_DIALOG); - if (prc < 0) + SDL_Event windowEvent = {}; + while (!sdl->shallAbort() && SDL_WaitEventTimeout(nullptr, 1000)) { - if (sdl_log_error(prc, sdl->getWLog(), "SDL_PeepEvents")) - continue; - } + /* Only poll standard SDL events and SDL_EVENT_USERS meant to create + * dialogs. do not process the dialog return value events here. + */ + const int prc = SDL_PeepEvents(&windowEvent, 1, SDL_GETEVENT, SDL_EVENT_FIRST, + SDL_EVENT_USER_RETRY_DIALOG); + if (prc < 0) + { + if (sdl_log_error(prc, sdl->getWLog(), "SDL_PeepEvents")) + continue; + } #if defined(WITH_DEBUG_SDL_EVENTS) SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "got event %s [0x%08" PRIx32 "]", @@ -108,12 +141,12 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const continue; if (!sdl->handleEvent(windowEvent)) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl->handleEvent" }; switch (windowEvent.type) { case SDL_EVENT_QUIT: - freerdp_abort_connect_context(sdl->context()); + std::ignore = freerdp_abort_connect_context(sdl->context()); break; case SDL_EVENT_USER_CERT_DIALOG: { @@ -121,7 +154,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const auto title = static_cast(windowEvent.user.data1); auto msg = static_cast(windowEvent.user.data2); if (!sdl_cert_dialog_show(title, msg)) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl_cert_dialog_show" }; } break; case SDL_EVENT_USER_SHOW_DIALOG: @@ -130,7 +163,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const auto title = static_cast(windowEvent.user.data1); auto msg = static_cast(windowEvent.user.data2); if (!sdl_message_dialog_show(title, msg, windowEvent.user.code)) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl_message_dialog_show" }; } break; case SDL_EVENT_USER_SCARD_DIALOG: @@ -139,7 +172,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const auto title = static_cast(windowEvent.user.data1); auto msg = static_cast(windowEvent.user.data2); if (!sdl_scard_dialog_show(title, windowEvent.user.code, msg)) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl_scard_dialog_show" }; } break; case SDL_EVENT_USER_AUTH_DIALOG: @@ -147,7 +180,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const SDLConnectionDialogHider hider(sdl); if (!sdl_auth_dialog_show( reinterpret_cast(windowEvent.padding))) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl_auth_dialog_show" }; } break; case SDL_EVENT_USER_UPDATE: @@ -157,7 +190,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const { rectangles = sdl->pop(); if (!sdl->drawToWindows(rectangles)) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl->drawToWindows" }; } while (!rectangles.empty()); } break; @@ -165,7 +198,7 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const { auto ctx = static_cast(windowEvent.user.data1); if (!ctx->createWindows()) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl->createWindows" }; } break; case SDL_EVENT_USER_WINDOW_RESIZEABLE: @@ -186,22 +219,16 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const break; case SDL_EVENT_USER_WINDOW_MINIMIZE: if (!sdl->minimizeAllWindows()) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl->minimizeAllWindows" }; break; case SDL_EVENT_USER_POINTER_NULL: - SDL_HideCursor(); - sdl->setCursor(nullptr); - sdl->setHasCursor(false); + if (!sdl->setCursor(SdlContext::CURSOR_NULL)) + throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" }; break; case SDL_EVENT_USER_POINTER_DEFAULT: - { - SDL_Cursor* def = SDL_GetDefaultCursor(); - SDL_SetCursor(def); - SDL_ShowCursor(); - sdl->setCursor(nullptr); - sdl->setHasCursor(true); - } - break; + if (!sdl->setCursor(SdlContext::CURSOR_DEFAULT)) + throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" }; + break; case SDL_EVENT_USER_POINTER_POSITION: { const auto x = @@ -210,22 +237,26 @@ static void sdl_term_handler([[maybe_unused]] int signum, [[maybe_unused]] const static_cast(reinterpret_cast(windowEvent.user.data2)); if (!sdl->moveMouseTo( { static_cast(x) * 1.0f, static_cast(y) * 1.0f })) - return -1; + throw ErrorMsg{ -1, windowEvent.type, "sdl->moveMouseTo" }; } break; case SDL_EVENT_USER_POINTER_SET: - sdl->setCursor(static_cast(windowEvent.user.data1)); - if (!sdl_Pointer_Set_Process(sdl)) - return -1; + if (!sdl->setCursor(static_cast(windowEvent.user.data1))) + throw ErrorMsg{ -1, windowEvent.type, "sdl->setCursor" }; break; case SDL_EVENT_USER_QUIT: default: break; } + } } - } - rc = 1; + } + catch (ErrorMsg& msg) + { + WLog_Print(sdl->getWLog(), WLOG_ERROR, "[exception] %s", msg.what()); + rc = msg.rc(); + } return rc; } diff --git a/client/SDL/SDL3/sdl_input.cpp b/client/SDL/SDL3/sdl_input.cpp index 1d9ef0f5b..6e7c3e7b3 100644 --- a/client/SDL/SDL3/sdl_input.cpp +++ b/client/SDL/SDL3/sdl_input.cpp @@ -309,16 +309,14 @@ bool sdlInput::keyboard_focus_in() WINPR_ASSERT(input); auto syncFlags = sdl_get_kbd_flags(); - freerdp_input_send_focus_in_event(input, WINPR_ASSERTING_INT_CAST(uint16_t, syncFlags)); + if (!freerdp_input_send_focus_in_event(input, WINPR_ASSERTING_INT_CAST(uint16_t, syncFlags))) + return false; /* finish with a mouse pointer position like mstsc.exe if required */ // TODO: fullscreen/remote app float fx = 0.0f; float fy = 0.0f; - if (_sdl->fullscreen()) - SDL_GetGlobalMouseState(&fx, &fy); - else - SDL_GetMouseState(&fx, &fy); + SDL_GetMouseState(&fx, &fy); auto w = SDL_GetMouseFocus(); const auto& pos = _sdl->screenToPixel(SDL_GetWindowID(w), SDL_FPoint{ fx, fy }); diff --git a/client/SDL/SDL3/sdl_pointer.cpp b/client/SDL/SDL3/sdl_pointer.cpp index 292aec296..138322541 100644 --- a/client/SDL/SDL3/sdl_pointer.cpp +++ b/client/SDL/SDL3/sdl_pointer.cpp @@ -103,7 +103,7 @@ static void sdl_Pointer_Free(rdpContext* context, rdpPointer* pointer) return sdl_push_user_event(SDL_EVENT_USER_POINTER_SET, pointer); } -BOOL sdl_Pointer_Set_Process(SdlContext* sdl) +bool sdl_Pointer_Set_Process(SdlContext* sdl) { WINPR_ASSERT(sdl); @@ -111,7 +111,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl) auto pointer = sdl->cursor(); auto ptr = reinterpret_cast(pointer); if (!ptr) - return TRUE; + return true; rdpGdi* gdi = context->gdi; WINPR_ASSERT(gdi); @@ -121,7 +121,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl) auto isw = static_cast(pointer->width); auto ish = static_cast(pointer->height); - SDL_Window* window = SDL_GetMouseFocus(); + auto window = SDL_GetMouseFocus(); if (!window) return sdl_Pointer_SetDefault(context); @@ -134,9 +134,11 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl) ptr->image = SDL_CreateSurface(static_cast(pos.w), static_cast(pos.h), sdl->pixelFormat()); if (!ptr->image) - return FALSE; + return false; + + if (!SDL_LockSurface(ptr->image)) + return false; - SDL_LockSurface(ptr->image); auto pixels = static_cast(ptr->image->pixels); auto data = static_cast(ptr->data); const BOOL rc = freerdp_image_scale( @@ -145,13 +147,13 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl) gdi->dstFormat, 0, 0, 0, static_cast(isw), static_cast(ish)); SDL_UnlockSurface(ptr->image); if (!rc) - return FALSE; + 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) - return FALSE; + return false; const auto hidpi_scale = sdl->pixelToScreen(fw->id(), SDL_FPoint{ static_cast(ptr->image->w), @@ -159,20 +161,24 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl) auto normal = SDL_CreateSurface(static_cast(hidpi_scale.x), static_cast(hidpi_scale.y), ptr->image->format); assert(normal); - SDL_BlitSurfaceScaled(ptr->image, nullptr, normal, nullptr, - SDL_ScaleMode::SDL_SCALEMODE_LINEAR); - SDL_AddSurfaceAlternateImage(normal, ptr->image); + if (!SDL_BlitSurfaceScaled(ptr->image, nullptr, normal, nullptr, + SDL_ScaleMode::SDL_SCALEMODE_LINEAR)) + return false; + if (!SDL_AddSurfaceAlternateImage(normal, ptr->image)) + return false; ptr->cursor = SDL_CreateColorCursor(normal, static_cast(pos.x), static_cast(pos.y)); if (!ptr->cursor) - return FALSE; + return false; SDL_DestroySurface(normal); - SDL_SetCursor(ptr->cursor); - SDL_ShowCursor(); + if (!SDL_SetCursor(ptr->cursor)) + return false; + if (!SDL_ShowCursor()) + return false; sdl->setHasCursor(true); - return TRUE; + return true; } [[nodiscard]] static BOOL sdl_Pointer_SetNull(rdpContext* context) @@ -190,7 +196,7 @@ BOOL sdl_Pointer_Set_Process(SdlContext* sdl) return sdl_push_user_event(SDL_EVENT_USER_POINTER_POSITION, x, y); } -BOOL sdl_register_pointer(rdpGraphics* graphics) +bool sdl_register_pointer(rdpGraphics* graphics) { const rdpPointer pointer = { sizeof(sdlPointer), sdl_Pointer_New, @@ -211,5 +217,5 @@ BOOL sdl_register_pointer(rdpGraphics* graphics) nullptr, {} }; graphics_register_pointer(graphics, &pointer); - return TRUE; + return true; } diff --git a/client/SDL/SDL3/sdl_pointer.hpp b/client/SDL/SDL3/sdl_pointer.hpp index 830bee7c2..fc134e749 100644 --- a/client/SDL/SDL3/sdl_pointer.hpp +++ b/client/SDL/SDL3/sdl_pointer.hpp @@ -25,6 +25,6 @@ #include -[[nodiscard]] BOOL sdl_register_pointer(rdpGraphics* graphics); +[[nodiscard]] bool sdl_register_pointer(rdpGraphics* graphics); -[[nodiscard]] BOOL sdl_Pointer_Set_Process(SdlContext* sdl); +[[nodiscard]] bool sdl_Pointer_Set_Process(SdlContext* sdl); diff --git a/client/SDL/SDL3/sdl_window.cpp b/client/SDL/SDL3/sdl_window.cpp index be1241d3e..0a1aa0fcf 100644 --- a/client/SDL/SDL3/sdl_window.cpp +++ b/client/SDL/SDL3/sdl_window.cpp @@ -23,15 +23,14 @@ #include "sdl_window.hpp" #include "sdl_utils.hpp" -SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width, - Sint32 height, [[maybe_unused]] Uint32 flags) +SdlWindow::SdlWindow(const std::string& title, const SDL_Rect& rect, [[maybe_unused]] Uint32 flags) { auto props = SDL_CreateProperties(); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title.c_str()); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, startupX); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, startupY); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, rect.x); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, rect.y); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, rect.w); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, rect.h); if (flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, true); @@ -47,8 +46,8 @@ SdlWindow::SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, auto sc = scale(); const int iscale = static_cast(sc * 100.0f); - auto w = 100 * width / iscale; - auto h = 100 * height / iscale; + auto w = 100 * rect.w / iscale; + auto h = 100 * rect.h / iscale; std::ignore = resize({ w, h }); SDL_SetHint(SDL_HINT_APP_NAME, ""); std::ignore = SDL_SyncWindow(_window); @@ -315,29 +314,20 @@ SdlWindow SdlWindow::create(SDL_DisplayID id, const std::string& title, Uint32 f Uint32 height) { flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY; - auto startupX = static_cast(SDL_WINDOWPOS_CENTERED_DISPLAY(id)); - auto startupY = static_cast(SDL_WINDOWPOS_CENTERED_DISPLAY(id)); + + SDL_Rect rect = { static_cast(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), + static_cast(SDL_WINDOWPOS_CENTERED_DISPLAY(id)), static_cast(width), + static_cast(height) }; if ((flags & SDL_WINDOW_FULLSCREEN) != 0) { - SDL_Rect rect = {}; - SDL_GetDisplayBounds(id, &rect); - startupX = rect.x; - startupY = rect.y; - width = static_cast(rect.w); - height = static_cast(rect.h); + std::ignore = SDL_GetDisplayBounds(id, &rect); } - std::stringstream ss; - ss << title << ":" << id; - SdlWindow window{ - ss.str(), startupX, startupY, static_cast(width), static_cast(height), flags - }; + SdlWindow window{ title, rect, flags }; if ((flags & (SDL_WINDOW_FULLSCREEN)) != 0) { - SDL_Rect rect = {}; - SDL_GetDisplayBounds(id, &rect); window.setOffsetX(rect.x); window.setOffsetY(rect.y); } diff --git a/client/SDL/SDL3/sdl_window.hpp b/client/SDL/SDL3/sdl_window.hpp index c2a8e5973..ae6a72486 100644 --- a/client/SDL/SDL3/sdl_window.hpp +++ b/client/SDL/SDL3/sdl_window.hpp @@ -80,8 +80,7 @@ class SdlWindow void updateSurface(); protected: - SdlWindow(const std::string& title, Sint32 startupX, Sint32 startupY, Sint32 width, - Sint32 height, Uint32 flags); + SdlWindow(const std::string& title, const SDL_Rect& rect, Uint32 flags); private: SDL_Window* _window = nullptr; diff --git a/client/common/client.c b/client/common/client.c index 487554dd9..e4f99a7f0 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -1771,8 +1771,8 @@ BOOL freerdp_client_send_button_event(rdpClientContext* cctx, BOOL relative, UIN cctx->lastX = x; cctx->lastY = y; } - freerdp_input_send_mouse_event(cctx->context.input, mflags, (UINT16)cctx->lastX, - (UINT16)cctx->lastY); + return freerdp_input_send_mouse_event(cctx->context.input, mflags, (UINT16)cctx->lastX, + (UINT16)cctx->lastY); } return TRUE; }