mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2025-01-22 23:55:02 +00:00
Rework Qt window handling during SDL window creation
- Avoids blindly enumeration all top-level windows - Properly tracks screen changes during the connection process - Starts stream window minimized if the Qt window was minimized Fixes #1231
This commit is contained in:
parent
0d67fd1ff0
commit
a45695a22a
3 changed files with 48 additions and 41 deletions
|
@ -176,7 +176,7 @@ Item {
|
|||
gc()
|
||||
|
||||
// Run the streaming session to completion
|
||||
session.exec(Screen.virtualX, Screen.virtualY)
|
||||
session.exec(Window.window)
|
||||
}
|
||||
|
||||
sourceComponent: Item {}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include <QGuiApplication>
|
||||
#include <QCursor>
|
||||
#include <QWindow>
|
||||
#include <QScreen>
|
||||
|
||||
#define CONN_TEST_SERVER "qt.conntest.moonlight-stream.org"
|
||||
|
||||
|
@ -549,8 +550,7 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere
|
|||
m_DecoderLock(0),
|
||||
m_AudioDisabled(false),
|
||||
m_AudioMuted(false),
|
||||
m_DisplayOriginX(0),
|
||||
m_DisplayOriginY(0),
|
||||
m_QtWindow(nullptr),
|
||||
m_UnexpectedTermination(true), // Failure prior to streaming is unexpected
|
||||
m_InputHandler(nullptr),
|
||||
m_MouseEmulationRefCount(0),
|
||||
|
@ -1117,26 +1117,38 @@ void Session::getWindowDimensions(int& x, int& y,
|
|||
// Create our window on the same display that Qt's UI
|
||||
// was being displayed on.
|
||||
else {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Qt UI screen is at (%d,%d)",
|
||||
m_DisplayOriginX, m_DisplayOriginY);
|
||||
for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) {
|
||||
SDL_Rect displayBounds;
|
||||
Q_ASSERT(m_QtWindow != nullptr);
|
||||
if (m_QtWindow != nullptr) {
|
||||
QScreen* screen = m_QtWindow->screen();
|
||||
if (screen != nullptr) {
|
||||
QRect displayRect = screen->geometry();
|
||||
|
||||
if (SDL_GetDisplayBounds(i, &displayBounds) == 0) {
|
||||
if (displayBounds.x == m_DisplayOriginX &&
|
||||
displayBounds.y == m_DisplayOriginY) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL found matching display %d",
|
||||
i);
|
||||
displayIndex = i;
|
||||
break;
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Qt UI screen is at (%d,%d)",
|
||||
displayRect.x(), displayRect.y());
|
||||
for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) {
|
||||
SDL_Rect displayBounds;
|
||||
|
||||
if (SDL_GetDisplayBounds(i, &displayBounds) == 0) {
|
||||
if (displayBounds.x == displayRect.x() &&
|
||||
displayBounds.y == displayRect.y()) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL found matching display %d",
|
||||
i);
|
||||
displayIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_GetDisplayBounds(%d) failed: %s",
|
||||
i, SDL_GetError());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_GetDisplayBounds(%d) failed: %s",
|
||||
i, SDL_GetError());
|
||||
"Qt window is not associated with a QScreen!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1503,10 +1515,9 @@ public:
|
|||
Session* m_Session;
|
||||
};
|
||||
|
||||
void Session::exec(int displayOriginX, int displayOriginY)
|
||||
void Session::exec(QWindow* qtWindow)
|
||||
{
|
||||
m_DisplayOriginX = displayOriginX;
|
||||
m_DisplayOriginY = displayOriginY;
|
||||
m_QtWindow = qtWindow;
|
||||
|
||||
// Use a separate thread for the streaming session on X11 or Wayland
|
||||
// to ensure we don't stomp on Qt's GL context. This breaks when using
|
||||
|
@ -1610,15 +1621,14 @@ void Session::execInternal()
|
|||
// We always want a resizable window with High DPI enabled
|
||||
Uint32 defaultWindowFlags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;
|
||||
|
||||
// If we're starting in windowed mode and the Moonlight GUI is maximized,
|
||||
// match that with the streaming window.
|
||||
if (!m_IsFullScreen) {
|
||||
QWindowList windows = QGuiApplication::topLevelWindows();
|
||||
for (const QWindow* window : windows) {
|
||||
if (window->windowState() & Qt::WindowMaximized) {
|
||||
defaultWindowFlags |= SDL_WINDOW_MAXIMIZED;
|
||||
break;
|
||||
}
|
||||
// If we're starting in windowed mode and the Moonlight GUI is maximized or
|
||||
// minimized, match that with the streaming window.
|
||||
if (!m_IsFullScreen && m_QtWindow != nullptr) {
|
||||
if (m_QtWindow->windowState() & Qt::WindowMaximized) {
|
||||
defaultWindowFlags |= SDL_WINDOW_MAXIMIZED;
|
||||
}
|
||||
else if (m_QtWindow->windowState() & Qt::WindowMinimized) {
|
||||
defaultWindowFlags |= SDL_WINDOW_MINIMIZED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1662,16 +1672,13 @@ void Session::execInternal()
|
|||
|
||||
// HACK: Remove once proper Dark Mode support lands in SDL
|
||||
#ifdef Q_OS_WIN32
|
||||
{
|
||||
BOOL darkModeEnabled = FALSE;
|
||||
if (m_QtWindow != nullptr) {
|
||||
BOOL darkModeEnabled;
|
||||
|
||||
// Query whether dark mode is enabled for our Qt window (which tracks the OS dark mode state)
|
||||
QWindowList windows = QGuiApplication::topLevelWindows();
|
||||
for (const QWindow* window : windows) {
|
||||
if (SUCCEEDED(DwmGetWindowAttribute((HWND)window->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, &darkModeEnabled, sizeof(darkModeEnabled))) ||
|
||||
SUCCEEDED(DwmGetWindowAttribute((HWND)window->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE_OLD, &darkModeEnabled, sizeof(darkModeEnabled)))) {
|
||||
break;
|
||||
}
|
||||
if (FAILED(DwmGetWindowAttribute((HWND)m_QtWindow->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, &darkModeEnabled, sizeof(darkModeEnabled))) &&
|
||||
FAILED(DwmGetWindowAttribute((HWND)m_QtWindow->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE_OLD, &darkModeEnabled, sizeof(darkModeEnabled)))) {
|
||||
darkModeEnabled = FALSE;
|
||||
}
|
||||
|
||||
SDL_SysWMinfo info;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <QSemaphore>
|
||||
#include <QWindow>
|
||||
|
||||
#include <Limelight.h>
|
||||
#include <opus_multistream.h>
|
||||
|
@ -26,7 +27,7 @@ public:
|
|||
// Use Session::exec() or DeferredSessionCleanupTask instead.
|
||||
virtual ~Session() {};
|
||||
|
||||
Q_INVOKABLE void exec(int displayOriginX, int displayOriginY);
|
||||
Q_INVOKABLE void exec(QWindow* qtWindow);
|
||||
|
||||
static
|
||||
void getDecoderInfo(SDL_Window* window,
|
||||
|
@ -166,8 +167,7 @@ private:
|
|||
bool m_AudioDisabled;
|
||||
bool m_AudioMuted;
|
||||
Uint32 m_FullScreenFlag;
|
||||
int m_DisplayOriginX;
|
||||
int m_DisplayOriginY;
|
||||
QWindow* m_QtWindow;
|
||||
bool m_ThreadedExec;
|
||||
bool m_UnexpectedTermination;
|
||||
SdlInputHandler* m_InputHandler;
|
||||
|
|
Loading…
Reference in a new issue