From f10b547a498ee94ca225acd5809e8a5621cf34ea Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 24 Apr 2022 16:37:57 -0500 Subject: [PATCH] Partially revert "Rework window management to fix issues restoring window state between windowed and full-screen" This exposes all sorts of issues with full-screen transitions on Windows and macOS: - Loss of proper window decorations when transitioning from full-screen to windowed on Windows - Improper sizing when transitioning from true full-screen to windowed on macOS This reverts commit 38396b26919d56dab02e3e06e7791ef9b748bacf. --- app/streaming/session.cpp | 88 ++++++++++++++++++++++++++++++--------- app/streaming/session.h | 1 + 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index ac6cfbfc..2704ccc1 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -449,6 +449,7 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere m_AudioMuted(false), m_DisplayOriginX(0), m_DisplayOriginY(0), + m_PendingWindowedTransition(false), m_UnexpectedTermination(true), // Failure prior to streaming is unexpected m_InputHandler(nullptr), m_MouseEmulationRefCount(0), @@ -896,10 +897,12 @@ void Session::getWindowDimensions(int& x, int& y, int& width, int& height) { int displayIndex = 0; + bool fullScreen; if (m_Window != nullptr) { displayIndex = SDL_GetWindowDisplayIndex(m_Window); SDL_assert(displayIndex >= 0); + fullScreen = (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN); } // Create our window on the same display that Qt's UI // was being displayed on. @@ -926,19 +929,38 @@ void Session::getWindowDimensions(int& x, int& y, i, SDL_GetError()); } } + + fullScreen = m_IsFullScreen; } SDL_Rect usableBounds; - if (SDL_GetDisplayUsableBounds(displayIndex, &usableBounds) == 0) { - // Don't use more than 80% of the display to leave room for system UI - width = (int)SDL_roundf(usableBounds.w * 0.80f); - height = (int)SDL_roundf(usableBounds.h * 0.80f); + if (fullScreen && SDL_GetDisplayBounds(displayIndex, &usableBounds) == 0) { + width = usableBounds.w; + height = usableBounds.h; + } + else if (SDL_GetDisplayUsableBounds(displayIndex, &usableBounds) == 0) { + width = usableBounds.w; + height = usableBounds.h; - // If the stream window can fit within the usable drawing area with 1:1 - // scaling, do that rather than filling the screen. - if (m_StreamConfig.width < width && m_StreamConfig.height < height) { - width = m_StreamConfig.width; - height = m_StreamConfig.height; + if (m_Window != nullptr) { + int top, left, bottom, right; + + if (SDL_GetWindowBordersSize(m_Window, &top, &left, &bottom, &right) == 0) { + width -= left + right; + height -= top + bottom; + } + else { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "Unable to get window border size: %s", + SDL_GetError()); + } + + // If the stream window can fit within the usable drawing area with 1:1 + // scaling, do that rather than filling the screen. + if (m_StreamConfig.width < width && m_StreamConfig.height < height) { + width = m_StreamConfig.width; + height = m_StreamConfig.height; + } } } else { @@ -1048,6 +1070,7 @@ void Session::toggleFullscreen() SDL_SetWindowGrab(m_Window, SDL_TRUE); } + SDL_SetWindowResizable(m_Window, SDL_FALSE); SDL_SetWindowFullscreen(m_Window, m_FullScreenFlag); } else { @@ -1055,6 +1078,10 @@ void Session::toggleFullscreen() SDL_SetWindowGrab(m_Window, SDL_FALSE); SDL_SetWindowFullscreen(m_Window, 0); + SDL_SetWindowResizable(m_Window, SDL_TRUE); + + // Reposition the window when the resize is complete + m_PendingWindowedTransition = true; } // Input handler might need to start/stop keyboard grab after changing modes @@ -1351,19 +1378,12 @@ void Session::execInternal() SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - Uint32 windowFlags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE; - - // If the video is larger than the entire desktop, maximize the window - if (m_StreamConfig.width > width || m_StreamConfig.height > height) { - windowFlags |= SDL_WINDOW_MAXIMIZED; - } - m_Window = SDL_CreateWindow("Moonlight", x, y, width, height, - windowFlags | StreamUtils::getPlatformWindowFlags()); + SDL_WINDOW_ALLOW_HIGHDPI | StreamUtils::getPlatformWindowFlags()); if (!m_Window) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow() failed with platform flags: %s", @@ -1374,7 +1394,7 @@ void Session::execInternal() y, width, height, - windowFlags); + SDL_WINDOW_ALLOW_HIGHDPI); if (!m_Window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow() failed: %s", @@ -1411,8 +1431,22 @@ void Session::execInternal() } #endif - // Enter full-screen if requested - if (m_IsFullScreen) { + // For non-full screen windows, call getWindowDimensions() + // again after creating a window to allow it to account + // for window chrome size. + if (!m_IsFullScreen) { + getWindowDimensions(x, y, width, height); + + // We must set the size before the position because centering + // won't work unless it knows the final size of the window. + SDL_SetWindowSize(m_Window, width, height); + SDL_SetWindowPosition(m_Window, x, y); + + // Passing SDL_WINDOW_RESIZABLE to set this during window + // creation causes our window to be full screen for some reason + SDL_SetWindowResizable(m_Window, SDL_TRUE); + } + else { // Update the window display mode based on our current monitor updateOptimalWindowDisplayMode(); @@ -1582,6 +1616,20 @@ void Session::execInternal() } #endif + // Complete any repositioning that was deferred until + // the resize from full-screen to windowed had completed. + // If we try to do this immediately, the resize won't take effect + // properly on Windows. + if (m_PendingWindowedTransition) { + m_PendingWindowedTransition = false; + + int x, y, width, height; + getWindowDimensions(x, y, width, height); + + SDL_SetWindowSize(m_Window, width, height); + SDL_SetWindowPosition(m_Window, x, y); + } + if (m_FlushingWindowEventsRef > 0) { // Ignore window events for renderer reset if flushing SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, diff --git a/app/streaming/session.h b/app/streaming/session.h index 7ab26686..bf5bbfc9 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -163,6 +163,7 @@ private: int m_DisplayOriginX; int m_DisplayOriginY; bool m_ThreadedExec; + bool m_PendingWindowedTransition; bool m_UnexpectedTermination; SdlInputHandler* m_InputHandler; int m_MouseEmulationRefCount;