vdi-cloud/terminal/moonlight/patches/0007-vdi-kiosk-launch-surface.patch

129 lines
4.7 KiB
Diff

--- a/app/main.cpp
+++ b/app/main.cpp
@@ -1033,6 +1033,14 @@
}
if (hasGUI) {
+ // The VDI shell owns all connection/error UI. Keep the CLI Qt window
+ // unmapped; only the full-screen SDL stream may appear over the shell.
+ const bool vdiKioskLaunch = commandLineParserResult == GlobalCommandLineParser::StreamRequested &&
+ qEnvironmentVariableIntValue("VDI_KIOSK_STREAM") == 1;
+ engine.rootContext()->setContextProperty("vdiKioskLaunch", vdiKioskLaunch);
+ if (vdiKioskLaunch) {
+ app.setQuitOnLastWindowClosed(false);
+ }
engine.rootContext()->setContextProperty("initialView", initialView);
engine.rootContext()->setContextProperty("runConfigChecks", commandLineParserResult == GlobalCommandLineParser::NormalStartRequested);
--- a/app/gui/main.qml
+++ b/app/gui/main.qml
@@ -35,6 +35,9 @@
}
Component.onCompleted: {
+ if (vdiKioskLaunch) {
+ return
+ }
// Show the window according to the user's preferences
if (SystemProperties.hasDesktopEnvironment) {
if (StreamingPreferences.uiDisplayMode == StreamingPreferences.UI_MAXIMIZED) {
--- a/app/gui/CliStartStreamSegue.qml
+++ b/app/gui/CliStartStreamSegue.qml
@@ -23,12 +23,21 @@
}
function onLaunchFailed(message) {
+ if (vdiKioskLaunch) {
+ console.error(message)
+ Qt.exit(1)
+ return
+ }
errorDialog.text = message
errorDialog.open()
console.error(message)
}
function onAppQuitRequired(appName) {
+ if (vdiKioskLaunch) {
+ onLaunchFailed(qsTr("Another application is already running: %1").arg(appName))
+ return
+ }
quitAppDialog.appName = appName
quitAppDialog.open()
}
--- a/app/gui/StreamSegue.qml
+++ b/app/gui/StreamSegue.qml
@@ -56,11 +56,19 @@
stackView.replace(stackView.currentItem, component.createObject(stackView, {"appName": appName}), StackView.Immediate)
// Show the Qt window again to show quit segue
- window.visible = true
+ window.visible = !vdiKioskLaunch
}
function sessionFinished(portTestResult)
{
+ if (vdiKioskLaunch) {
+ // Never restore a hidden CLI dialog over the product surface.
+ if (streamSegueErrorDialog.text) {
+ console.error(streamSegueErrorDialog.text)
+ }
+ Qt.exit(streamSegueErrorDialog.text ? 1 : 0)
+ return
+ }
if (portTestResult !== 0 && portTestResult !== -1 && streamSegueErrorDialog.text) {
streamSegueErrorDialog.text += "\n\n" + qsTr("This PC's Internet connection is blocking Moonlight. Streaming over the Internet may not work while connected to this network.")
}
@@ -145,7 +153,8 @@
Loader {
id: streamLoader
active: false
- asynchronous: true
+ // A hidden Qt window has no render frames to drive incubation.
+ asynchronous: !vdiKioskLaunch
onLoaded: {
// Set the hint text. We do this here rather than
@@ -178,6 +187,9 @@
for (var i = 0; i < session.launchWarnings.length; i++) {
var text = session.launchWarnings[i]
console.warn(text)
+ if (vdiKioskLaunch) {
+ continue
+ }
// Show the tooltip for 3 seconds
var toast = Qt.createQmlObject('import QtQuick.Controls 2.2; ToolTip {}', parent, '')
--- a/app/streaming/session.cpp
+++ b/app/streaming/session.cpp
@@ -1365,6 +1365,19 @@
}
}
+ if (m_IsFullScreen && qEnvironmentVariableIntValue("VDI_KIOSK_STREAM") == 1) {
+ // No EWMH window manager: size the surface before SDL maps it so the
+ // first mapped frame already covers the output.
+ SDL_Rect bounds;
+ if (SDL_GetDisplayBounds(displayIndex, &bounds) == 0) {
+ x = bounds.x;
+ y = bounds.y;
+ width = bounds.w;
+ height = bounds.h;
+ return;
+ }
+ }
+
SDL_Rect usableBounds;
if (SDL_GetDisplayUsableBounds(displayIndex, &usableBounds) == 0) {
// If the stream resolution fits within the usable display area, use it directly
@@ -1817,6 +1830,9 @@
// We always want a resizable window with High DPI enabled
Uint32 defaultWindowFlags = SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE;
+ if (m_IsFullScreen && qEnvironmentVariableIntValue("VDI_KIOSK_STREAM") == 1) {
+ defaultWindowFlags |= SDL_WINDOW_BORDERLESS;
+ }
// If we're starting in windowed mode and the Moonlight GUI is maximized or
// minimized, match that with the streaming window.