diff --git a/app/gui/SettingsView.qml b/app/gui/SettingsView.qml
index 508a3215..0ce7f0de 100644
--- a/app/gui/SettingsView.qml
+++ b/app/gui/SettingsView.qml
@@ -230,26 +230,59 @@ ScrollView {
}
}
- Row {
- CheckBox {
- id: fullScreenCheck
- text: "Full-screen"
- font.pointSize: 12
- checked: prefs.fullScreen
- onCheckedChanged: {
- prefs.fullScreen = checked
+ Label {
+ width: parent.width
+ id: windowModeTitle
+ text: qsTr("Display mode")
+ font.pointSize: 12
+ wrapMode: Text.Wrap
+ color: "white"
+ }
+
+ ComboBox {
+ // ignore setting the index at first, and actually set it when the component is loaded
+ Component.onCompleted: {
+ var savedWm = prefs.windowMode
+ currentIndex = 0
+ for (var i = 0; i < windowModeListModel.count; i++) {
+ var thisWm = windowModeListModel.get(i).val;
+ if (savedWm === thisWm) {
+ currentIndex = i
+ }
}
}
- CheckBox {
- id: vsyncCheck
- text: "Enable V-Sync"
- font.pointSize: 12
- visible: fullScreenCheck.checked
- checked: prefs.enableVsync
- onCheckedChanged: {
- prefs.enableVsync = checked
+ id: windowModeComboBox
+ width: Math.min(bitrateDesc.implicitWidth, parent.width)
+ textRole: "text"
+ model: ListModel {
+ id: windowModeListModel
+ ListElement {
+ text: "Full-screen"
+ val: StreamingPreferences.WM_FULLSCREEN
}
+ ListElement {
+ text: "Borderless windowed"
+ val: StreamingPreferences.WM_FULLSCREEN_DESKTOP
+ }
+ ListElement {
+ text: "Windowed"
+ val: StreamingPreferences.WM_WINDOWED
+ }
+ }
+ onActivated: {
+ prefs.windowMode = windowModeListModel.get(currentIndex).val
+ }
+ }
+
+ CheckBox {
+ id: vsyncCheck
+ text: "Enable V-Sync"
+ font.pointSize: 12
+ visible: prefs.windowMode === StreamingPreferences.WM_FULLSCREEN
+ checked: prefs.enableVsync
+ onCheckedChanged: {
+ prefs.enableVsync = checked
}
}
}
diff --git a/app/settings/streamingpreferences.cpp b/app/settings/streamingpreferences.cpp
index 8cbf313c..a10eab0e 100644
--- a/app/settings/streamingpreferences.cpp
+++ b/app/settings/streamingpreferences.cpp
@@ -16,6 +16,7 @@
#define SER_AUDIOCFG "audiocfg"
#define SER_VIDEOCFG "videocfg"
#define SER_VIDEODEC "videodec"
+#define SER_WINDOWMODE "windowmode"
StreamingPreferences::StreamingPreferences()
{
@@ -30,7 +31,6 @@ void StreamingPreferences::reload()
height = settings.value(SER_HEIGHT, 720).toInt();
fps = settings.value(SER_FPS, 60).toInt();
bitrateKbps = settings.value(SER_BITRATE, getDefaultBitrate(width, height, fps)).toInt();
- fullScreen = settings.value(SER_FULLSCREEN, true).toBool();
enableVsync = settings.value(SER_VSYNC, true).toBool();
gameOptimizations = settings.value(SER_GAMEOPTS, true).toBool();
playAudioOnHost = settings.value(SER_HOSTAUDIO, false).toBool();
@@ -41,6 +41,10 @@ void StreamingPreferences::reload()
static_cast(VideoCodecConfig::VCC_AUTO)).toInt());
videoDecoderSelection = static_cast(settings.value(SER_VIDEODEC,
static_cast(VideoDecoderSelection::VDS_AUTO)).toInt());
+ windowMode = static_cast(settings.value(SER_WINDOWMODE,
+ // Try to load from the old preference value too
+ static_cast(settings.value(SER_FULLSCREEN, true).toBool() ?
+ WindowMode::WM_FULLSCREEN : WindowMode::WM_WINDOWED)).toInt());
}
void StreamingPreferences::save()
@@ -51,7 +55,6 @@ void StreamingPreferences::save()
settings.setValue(SER_HEIGHT, height);
settings.setValue(SER_FPS, fps);
settings.setValue(SER_BITRATE, bitrateKbps);
- settings.setValue(SER_FULLSCREEN, fullScreen);
settings.setValue(SER_VSYNC, enableVsync);
settings.setValue(SER_GAMEOPTS, gameOptimizations);
settings.setValue(SER_HOSTAUDIO, playAudioOnHost);
@@ -59,6 +62,7 @@ void StreamingPreferences::save()
settings.setValue(SER_AUDIOCFG, static_cast(audioConfig));
settings.setValue(SER_VIDEOCFG, static_cast(videoCodecConfig));
settings.setValue(SER_VIDEODEC, static_cast(videoDecoderSelection));
+ settings.setValue(SER_WINDOWMODE, static_cast(windowMode));
}
bool StreamingPreferences::hasAnyHardwareAcceleration()
diff --git a/app/settings/streamingpreferences.h b/app/settings/streamingpreferences.h
index b06020d2..7125a4f2 100644
--- a/app/settings/streamingpreferences.h
+++ b/app/settings/streamingpreferences.h
@@ -50,11 +50,18 @@ public:
};
Q_ENUM(VideoDecoderSelection)
+ enum WindowMode
+ {
+ WM_FULLSCREEN,
+ WM_FULLSCREEN_DESKTOP,
+ WM_WINDOWED
+ };
+ Q_ENUM(WindowMode);
+
Q_PROPERTY(int width MEMBER width NOTIFY displayModeChanged)
Q_PROPERTY(int height MEMBER height NOTIFY displayModeChanged)
Q_PROPERTY(int fps MEMBER fps NOTIFY displayModeChanged)
Q_PROPERTY(int bitrateKbps MEMBER bitrateKbps NOTIFY bitrateChanged)
- Q_PROPERTY(bool fullScreen MEMBER fullScreen NOTIFY fullScreenChanged)
Q_PROPERTY(bool enableVsync MEMBER enableVsync NOTIFY enableVsyncChanged)
Q_PROPERTY(bool gameOptimizations MEMBER gameOptimizations NOTIFY gameOptimizationsChanged)
Q_PROPERTY(bool playAudioOnHost MEMBER playAudioOnHost NOTIFY playAudioOnHostChanged)
@@ -62,13 +69,13 @@ public:
Q_PROPERTY(AudioConfig audioConfig MEMBER audioConfig NOTIFY audioConfigChanged)
Q_PROPERTY(VideoCodecConfig videoCodecConfig MEMBER videoCodecConfig NOTIFY videoCodecConfigChanged)
Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged)
+ Q_PROPERTY(WindowMode windowMode MEMBER windowMode NOTIFY windowModeChanged)
// Directly accessible members for preferences
int width;
int height;
int fps;
int bitrateKbps;
- bool fullScreen;
bool enableVsync;
bool gameOptimizations;
bool playAudioOnHost;
@@ -76,11 +83,11 @@ public:
AudioConfig audioConfig;
VideoCodecConfig videoCodecConfig;
VideoDecoderSelection videoDecoderSelection;
+ WindowMode windowMode;
signals:
void displayModeChanged();
void bitrateChanged();
- void fullScreenChanged();
void enableVsyncChanged();
void gameOptimizationsChanged();
void playAudioOnHostChanged();
@@ -88,5 +95,6 @@ signals:
void audioConfigChanged();
void videoCodecConfigChanged();
void videoDecoderSelectionChanged();
+ void windowModeChanged();
};
diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp
index 8eb92a91..3a332d24 100644
--- a/app/streaming/session.cpp
+++ b/app/streaming/session.cpp
@@ -19,13 +19,6 @@
#include "video/sl.h"
#endif
-#if defined(Q_OS_DARWIN)
-// Using full-screen desktop allows allows Spaces to work on macOS.
-#define SDL_OS_FULLSCREEN_FLAG SDL_WINDOW_FULLSCREEN_DESKTOP
-#else
-#define SDL_OS_FULLSCREEN_FLAG SDL_WINDOW_FULLSCREEN
-#endif
-
#ifdef Q_OS_WIN32
// Scaling the icon down on Win32 looks dreadful, so render at lower res
#define ICON_SIZE 32
@@ -372,6 +365,17 @@ Session::Session(NvComputer* computer, NvApp& app)
else {
m_StreamConfig.packetSize = 1024;
}
+
+ switch (m_Preferences.windowMode)
+ {
+ case StreamingPreferences::WM_FULLSCREEN_DESKTOP:
+ m_FullScreenFlag = SDL_WINDOW_FULLSCREEN_DESKTOP;
+ break;
+ case StreamingPreferences::WM_FULLSCREEN:
+ default:
+ m_FullScreenFlag = SDL_WINDOW_FULLSCREEN;
+ break;
+ }
}
void Session::emitLaunchWarning(QString text)
@@ -595,7 +599,7 @@ void Session::getWindowDimensions(bool fullScreen,
void Session::toggleFullscreen()
{
- bool fullScreen = !(SDL_GetWindowFlags(m_Window) & SDL_OS_FULLSCREEN_FLAG);
+ bool fullScreen = !(SDL_GetWindowFlags(m_Window) & m_FullScreenFlag);
int x, y, width, height;
@@ -613,7 +617,7 @@ void Session::toggleFullscreen()
if (fullScreen) {
SDL_SetWindowResizable(m_Window, SDL_FALSE);
- SDL_SetWindowFullscreen(m_Window, SDL_OS_FULLSCREEN_FLAG);
+ SDL_SetWindowFullscreen(m_Window, m_FullScreenFlag);
}
}
@@ -715,7 +719,7 @@ void Session::exec()
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
int x, y, width, height;
- getWindowDimensions(m_Preferences.fullScreen,
+ getWindowDimensions(m_Preferences.windowMode != StreamingPreferences::WM_WINDOWED,
x, y, width, height);
m_Window = SDL_CreateWindow("Moonlight",
@@ -736,7 +740,7 @@ void Session::exec()
// For non-full screen windows, call getWindowDimensions()
// again after creating a window to allow it to account
// for window chrome size.
- if (!m_Preferences.fullScreen) {
+ if (m_Preferences.windowMode == StreamingPreferences::WM_WINDOWED) {
getWindowDimensions(false, x, y, width, height);
SDL_SetWindowPosition(m_Window, x, y);
@@ -754,7 +758,7 @@ void Session::exec()
}
// Enter full screen
- SDL_SetWindowFullscreen(m_Window, SDL_OS_FULLSCREEN_FLAG);
+ SDL_SetWindowFullscreen(m_Window, m_FullScreenFlag);
}
QSvgRenderer svgIconRenderer(QString(":/res/moonlight.svg"));
diff --git a/app/streaming/session.hpp b/app/streaming/session.hpp
index 8f07baf9..2639fb8e 100644
--- a/app/streaming/session.hpp
+++ b/app/streaming/session.hpp
@@ -110,6 +110,7 @@ private:
SDL_SpinLock m_DecoderLock;
bool m_NeedsIdr;
bool m_AudioDisabled;
+ Uint32 m_FullScreenFlag;
int m_ActiveVideoFormat;
int m_ActiveVideoWidth;