diff --git a/app/SDL_compat.c b/app/SDL_compat.c index da2e9d89..e6df6c78 100644 --- a/app/SDL_compat.c +++ b/app/SDL_compat.c @@ -207,3 +207,28 @@ SDLC_VideoDriver SDLC_GetVideoDriver(void) } #endif } + +bool SDLC_IsFullscreen(SDL_Window* window) +{ + return !!(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN); +} + +bool SDLC_IsFullscreenExclusive(SDL_Window* window) +{ + return (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN; +} + +bool SDLC_IsFullscreenDesktop(SDL_Window* window) +{ + return (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; +} + +void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive) +{ + SDL_SetWindowFullscreen(window, exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP); +} + +void SDLC_LeaveFullscreen(SDL_Window* window) +{ + SDL_SetWindowFullscreen(window, 0); +} diff --git a/app/SDL_compat.h b/app/SDL_compat.h index d188be15..2fac3172 100644 --- a/app/SDL_compat.h +++ b/app/SDL_compat.h @@ -6,6 +6,7 @@ #pragma once #include +#include // This is a pure C header for compatibility with SDL.h #ifdef __cplusplus @@ -90,6 +91,12 @@ typedef enum { } SDLC_VideoDriver; SDLC_VideoDriver SDLC_GetVideoDriver(); +bool SDLC_IsFullscreen(SDL_Window* window); +bool SDLC_IsFullscreenExclusive(SDL_Window* window); +bool SDLC_IsFullscreenDesktop(SDL_Window* window); +void SDLC_EnterFullscreen(SDL_Window* window, bool exclusive); +void SDLC_LeaveFullscreen(SDL_Window* window); + #ifdef __cplusplus } #endif diff --git a/app/streaming/input/input.cpp b/app/streaming/input/input.cpp index 243606f0..6f1fe6a6 100644 --- a/app/streaming/input/input.cpp +++ b/app/streaming/input/input.cpp @@ -289,7 +289,7 @@ void SdlInputHandler::notifyFocusLost() // This lets user to interact with our window's title bar and with the buttons in it. // Doing this while the window is full-screen breaks the transition out of FS // (desktop and exclusive), so we must check for that before releasing mouse capture. - if (!(SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) && !m_AbsoluteMouseMode) { + if (!SDLC_IsFullscreen(m_Window) && !m_AbsoluteMouseMode) { setCaptureActive(false); } @@ -315,9 +315,8 @@ void SdlInputHandler::updateKeyboardGrabState() } bool shouldGrab = isCaptureActive(); - Uint32 windowFlags = SDL_GetWindowFlags(m_Window); if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN && - !(windowFlags & SDL_WINDOW_FULLSCREEN)) { + !SDLC_IsFullscreen(m_Window)) { // Ungrab if it's fullscreen only and we left fullscreen shouldGrab = false; } @@ -355,7 +354,7 @@ bool SdlInputHandler::isSystemKeyCaptureActive() } if (m_CaptureSystemKeysMode == StreamingPreferences::CSK_FULLSCREEN && - !(windowFlags & SDL_WINDOW_FULLSCREEN)) { + !SDLC_IsFullscreen(m_Window)) { return false; } diff --git a/app/streaming/input/mouse.cpp b/app/streaming/input/mouse.cpp index 6b1cae79..ef9b0d20 100644 --- a/app/streaming/input/mouse.cpp +++ b/app/streaming/input/mouse.cpp @@ -270,7 +270,7 @@ void SdlInputHandler::updatePointerRegionLock() // have full control over it and we don't touch it anymore. if (!m_PointerRegionLockToggledByUser) { // Lock the pointer in true full-screen mode and leave it unlocked in other modes - m_PointerRegionLockActive = (SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN; + m_PointerRegionLockActive = SDLC_IsFullscreenExclusive(m_Window); } // If region lock is enabled, grab the cursor so it can't accidentally leave our window. diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 21fa0a2c..14e3cd41 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -851,7 +851,7 @@ bool Session::initialize() case StreamingPreferences::WM_FULLSCREEN_DESKTOP: // Only use full-screen desktop mode if we're running a desktop environment if (WMUtils::isRunningDesktopEnvironment()) { - m_FullScreenFlag = SDL_WINDOW_FULLSCREEN_DESKTOP; + m_FullScreenExclusiveMode = false; break; } // Fall-through @@ -859,13 +859,13 @@ bool Session::initialize() #ifdef Q_OS_DARWIN if (qEnvironmentVariableIntValue("I_WANT_BUGGY_FULLSCREEN") == 0) { // Don't use "real" fullscreen on macOS by default. See comments above. - m_FullScreenFlag = SDL_WINDOW_FULLSCREEN_DESKTOP; + m_FullScreenExclusiveMode = false; } else { - m_FullScreenFlag = SDL_WINDOW_FULLSCREEN; + m_FullScreenExclusiveMode = true; } #else - m_FullScreenFlag = SDL_WINDOW_FULLSCREEN; + m_FullScreenExclusiveMode = true; #endif break; } @@ -877,7 +877,7 @@ bool Session::initialize() if (qgetenv("DESKTOP_SESSION") == "LXDE-pi") { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Forcing windowed mode on LXDE-Pi"); - m_FullScreenFlag = 0; + m_FullScreenExclusiveMode = false; } #endif @@ -1350,10 +1350,15 @@ void Session::getWindowDimensions(int& x, int& y, void Session::updateOptimalWindowDisplayMode() { SDL_DisplayMode desktopMode, bestMode, mode; - int displayIndex = SDL_GetWindowDisplayIndex(m_Window); + + // Nothing to do if we're not using full-screen exclusive mode + if (!m_FullScreenExclusiveMode) { + return; + } // Try the current display mode first. On macOS, this will be the normal // scaled desktop resolution setting. + int displayIndex = SDL_GetWindowDisplayIndex(m_Window); if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) { // If this doesn't fit the selected resolution, use the native // resolution of the panel (unscaled). @@ -1425,7 +1430,7 @@ void Session::updateOptimalWindowDisplayMode() bestMode = desktopMode; } - if ((SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + if (SDLC_IsFullscreenExclusive(m_Window)) { // Only print when the window is actually in full-screen exclusive mode, // otherwise we're not actually using the mode we've set here SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, @@ -1438,7 +1443,7 @@ void Session::updateOptimalWindowDisplayMode() void Session::toggleFullscreen() { - bool fullScreen = !(SDL_GetWindowFlags(m_Window) & m_FullScreenFlag); + bool enterFullScreen = !SDLC_IsFullscreen(m_Window); #if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN) // Destroy the video decoder before toggling full-screen because D3D9 can try @@ -1456,13 +1461,18 @@ void Session::toggleFullscreen() #endif // Actually enter/leave fullscreen - SDL_SetWindowFullscreen(m_Window, fullScreen ? m_FullScreenFlag : 0); + if (enterFullScreen) { + SDLC_EnterFullscreen(m_Window, m_FullScreenExclusiveMode); + } + else { + SDLC_LeaveFullscreen(m_Window); + } #ifdef Q_OS_DARWIN // SDL on macOS has a bug that causes the window size to be reset to crazy // large dimensions when exiting out of true fullscreen mode. We can work // around the issue by manually resetting the position and size here. - if (!fullScreen && m_FullScreenFlag == SDL_WINDOW_FULLSCREEN) { + if (!enterFullScreen && m_FullScreenExclusiveMode) { int x, y, width, height; getWindowDimensions(x, y, width, height); SDL_SetWindowSize(m_Window, width, height); @@ -1913,7 +1923,7 @@ void Session::execInternal() // Enter full screen if requested if (m_IsFullScreen) { - SDL_SetWindowFullscreen(m_Window, m_FullScreenFlag); + SDLC_EnterFullscreen(m_Window, m_FullScreenExclusiveMode); } bool needsFirstEnterCapture = false; diff --git a/app/streaming/session.h b/app/streaming/session.h index 95858437..7e185a4c 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -253,7 +253,7 @@ private: SDL_SpinLock m_DecoderLock; bool m_AudioDisabled; bool m_AudioMuted; - Uint32 m_FullScreenFlag; + bool m_FullScreenExclusiveMode; QWindow* m_QtWindow; bool m_ThreadedExec; bool m_UnexpectedTermination; diff --git a/app/streaming/streamutils.cpp b/app/streaming/streamutils.cpp index 230ded07..c8e46fa9 100644 --- a/app/streaming/streamutils.cpp +++ b/app/streaming/streamutils.cpp @@ -122,7 +122,7 @@ int StreamUtils::getDisplayRefreshRate(SDL_Window* window) } SDL_DisplayMode mode; - if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + if (SDLC_IsFullscreenExclusive(window)) { // Use the window display mode for full-screen exclusive mode if (SDL_GetWindowDisplayMode(window, &mode) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, diff --git a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp index a5b33c63..8432b5b0 100644 --- a/app/streaming/video/ffmpeg-renderers/d3d11va.cpp +++ b/app/streaming/video/ffmpeg-renderers/d3d11va.cpp @@ -427,7 +427,7 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params) // DXVA2 may let us take over for FSE V-sync off cases. However, if we don't have DXGI_FEATURE_PRESENT_ALLOW_TEARING // then we should not attempt to do this unless there's no other option (HDR, DXVA2 failed in pass 1, etc). if (!m_AllowTearing && m_DecoderSelectionPass == 0 && !(params->videoFormat & VIDEO_FORMAT_MASK_10BIT) && - (SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + SDLC_IsFullscreenExclusive(params->window)) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Defaulting to DXVA2 for FSE without DXGI_FEATURE_PRESENT_ALLOW_TEARING support"); return false; @@ -436,8 +436,8 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params) HWND window = (HWND)SDLC_Win32_GetHwnd(params->window); - // Always use windowed or borderless windowed mode.. SDL does mode-setting for us in - // full-screen exclusive mode (SDL_WINDOW_FULLSCREEN), so this actually works out okay. + // Always use windowed or borderless windowed mode. SDL does mode-setting for us in + // full-screen exclusive mode, so this actually works out okay. ComPtr swapChain; hr = m_Factory->CreateSwapChainForHwnd(m_Device.Get(), window, @@ -1184,7 +1184,7 @@ int D3D11VARenderer::getRendererAttributes() // In windowed mode, we will render as fast we can and DWM will grab whatever is latest at the // time unless the user opts for pacing. We will use pacing in full-screen mode and normal DWM // sequencing in full-screen desktop mode to behave similarly to the DXVA2 renderer. - if ((SDL_GetWindowFlags(m_DecoderParams.window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + if (SDLC_IsFullscreenExclusive(m_DecoderParams.window)) { attributes |= RENDERER_ATTRIBUTE_FORCE_PACING; } diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 33f9ba3b..7885b8be 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -549,7 +549,6 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) } int adapterIndex = SDL_Direct3D9GetAdapterIndex(SDL_GetWindowDisplayIndex(window)); - Uint32 windowFlags = SDL_GetWindowFlags(window); // Initialize quirks *before* calling CreateDeviceEx() to allow our below // logic to avoid a hang with NahimicOSD.dll's broken full-screen handling. @@ -583,7 +582,7 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) } } - if ((windowFlags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + if (SDLC_IsFullscreenExclusive(window)) { d3dpp.Windowed = false; d3dpp.BackBufferWidth = currentMode.Width; d3dpp.BackBufferHeight = currentMode.Height; diff --git a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp index 65f701ee..b7fdec8f 100644 --- a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp @@ -144,7 +144,7 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params) switch (SDLC_GetVideoDriver()) { case SDLC_VIDEO_WIN32: // DWM is always tear-free except in full-screen exclusive mode - if ((SDL_GetWindowFlags(params->window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + if (SDLC_IsFullscreenExclusive(params->window)) { if (params->enableVsync) { rendererFlags |= SDL_RENDERER_PRESENTVSYNC; }