mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-05-19 16:10:35 +00:00
Increase Qt requirement to 5.12 and remove pre-5.12 workarounds
This commit is contained in:
@@ -54,7 +54,7 @@ Hosting for Moonlight's Debian and L4T package repositories is graciously provid
|
|||||||
* [create-dmg](https://github.com/sindresorhus/create-dmg) (only if building DMGs for use on non-development Macs)
|
* [create-dmg](https://github.com/sindresorhus/create-dmg) (only if building DMGs for use on non-development Macs)
|
||||||
|
|
||||||
### Linux/Unix Build Requirements
|
### Linux/Unix Build Requirements
|
||||||
* Qt 6 is recommended, but Qt 5.9 or later is also supported (replace `qmake6` with `qmake` when using Qt 5).
|
* Qt 6 is recommended, but Qt 5.12 or later is also supported (replace `qmake6` with `qmake` when using Qt 5).
|
||||||
* GCC or Clang
|
* GCC or Clang
|
||||||
* FFmpeg 4.0 or later
|
* FFmpeg 4.0 or later
|
||||||
* Install the required packages:
|
* Install the required packages:
|
||||||
@@ -75,7 +75,7 @@ Hosting for Moonlight's Debian and L4T package repositories is graciously provid
|
|||||||
### Build Setup Steps
|
### Build Setup Steps
|
||||||
1. Install the latest Qt SDK (and optionally, the Qt Creator IDE) from https://www.qt.io/download
|
1. Install the latest Qt SDK (and optionally, the Qt Creator IDE) from https://www.qt.io/download
|
||||||
* You can install Qt via Homebrew on macOS, but you will need to use `brew install qt --with-debug` to be able to create debug builds of Moonlight.
|
* You can install Qt via Homebrew on macOS, but you will need to use `brew install qt --with-debug` to be able to create debug builds of Moonlight.
|
||||||
* You may also use your Linux distro's package manager for the Qt SDK as long as the packages are Qt 5.9 or later.
|
* You may also use your Linux distro's package manager for the Qt SDK as long as the packages are Qt 5.12 or later.
|
||||||
* This step is not required for building on Steam Link, because the Steam Link SDK includes Qt 5.14.
|
* This step is not required for building on Steam Link, because the Steam Link SDK includes Qt 5.14.
|
||||||
2. Run `git submodule update --init --recursive` from within `moonlight-qt/`
|
2. Run `git submodule update --init --recursive` from within `moonlight-qt/`
|
||||||
3. Open the project in Qt Creator or build from qmake on the command line.
|
3. Open the project in Qt Creator or build from qmake on the command line.
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QRandomGenerator>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#define SER_HOSTS "hosts"
|
#define SER_HOSTS "hosts"
|
||||||
#define SER_HOSTS_BACKUP "hostsbackup"
|
#define SER_HOSTS_BACKUP "hostsbackup"
|
||||||
@@ -966,14 +965,9 @@ void ComputerManager::addNewHost(NvAddress address, bool mdns, NvAddress mdnsIpv
|
|||||||
QThreadPool::globalInstance()->start(addTask);
|
QThreadPool::globalInstance()->start(addTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use QRandomGenerator when we drop Qt 5.9 support
|
|
||||||
QString ComputerManager::generatePinString()
|
QString ComputerManager::generatePinString()
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<int> dist(0, 9999);
|
return QString::asprintf("%04u", QRandomGenerator::system()->bounded(10000));
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937 engine(rd());
|
|
||||||
|
|
||||||
return QString::asprintf("%04u", dist(engine));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "computermanager.moc"
|
#include "computermanager.moc"
|
||||||
|
|||||||
+4
-8
@@ -38,7 +38,7 @@ CenteredGridView {
|
|||||||
activated = true
|
activated = true
|
||||||
|
|
||||||
// Highlight the first item if a gamepad is connected
|
// Highlight the first item if a gamepad is connected
|
||||||
if (currentIndex == -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
|
if (currentIndex === -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
|
||||||
currentIndex = 0
|
currentIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +94,9 @@ CenteredGridView {
|
|||||||
// the image size checks if this is not an app collector game. We know the officially
|
// the image size checks if this is not an app collector game. We know the officially
|
||||||
// supported games all have box art, so this check is not required.
|
// supported games all have box art, so this check is not required.
|
||||||
if (!model.isAppCollectorGame &&
|
if (!model.isAppCollectorGame &&
|
||||||
((sourceSize.width == 130 && sourceSize.height == 180) || // GFE 2.0 placeholder image
|
((sourceSize.width === 130 && sourceSize.height === 180) || // GFE 2.0 placeholder image
|
||||||
(sourceSize.width == 628 && sourceSize.height == 888) || // GFE 3.0 placeholder image
|
(sourceSize.width === 628 && sourceSize.height === 888) || // GFE 3.0 placeholder image
|
||||||
(sourceSize.width == 200 && sourceSize.height == 266))) // Our no_app_image.png
|
(sourceSize.width === 200 && sourceSize.height === 266))) // Our no_app_image.png
|
||||||
{
|
{
|
||||||
isPlaceholder = true
|
isPlaceholder = true
|
||||||
}
|
}
|
||||||
@@ -299,18 +299,15 @@ CenteredGridView {
|
|||||||
sourceComponent: NavigableMenu {
|
sourceComponent: NavigableMenu {
|
||||||
id: appContextMenu
|
id: appContextMenu
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: appContextMenu
|
|
||||||
text: model.running ? qsTr("Resume Game") : qsTr("Launch Game")
|
text: model.running ? qsTr("Resume Game") : qsTr("Launch Game")
|
||||||
onTriggered: launchOrResumeSelectedApp(true)
|
onTriggered: launchOrResumeSelectedApp(true)
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: appContextMenu
|
|
||||||
text: qsTr("Quit Game")
|
text: qsTr("Quit Game")
|
||||||
onTriggered: doQuitGame()
|
onTriggered: doQuitGame()
|
||||||
visible: model.running
|
visible: model.running
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: appContextMenu
|
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model.directLaunch
|
checked: model.directLaunch
|
||||||
text: qsTr("Direct Launch")
|
text: qsTr("Direct Launch")
|
||||||
@@ -323,7 +320,6 @@ CenteredGridView {
|
|||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: appContextMenu
|
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model.hidden
|
checked: model.hidden
|
||||||
text: qsTr("Hide Game")
|
text: qsTr("Hide Game")
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ import QtQuick 2.9
|
|||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
GridView {
|
GridView {
|
||||||
// Detect Qt 5.11 or earlier using presence of synchronousDrag.
|
|
||||||
// Prior to 5.12, the leftMargin and rightMargin values did not work.
|
|
||||||
property bool hasBrokenMargins: this.synchronousDrag === undefined
|
|
||||||
|
|
||||||
property int minMargin: 10
|
property int minMargin: 10
|
||||||
property real availableWidth: (parent.width - 2 * minMargin)
|
property real availableWidth: (parent.width - 2 * minMargin)
|
||||||
property int itemsPerRow: availableWidth / cellWidth
|
property int itemsPerRow: availableWidth / cellWidth
|
||||||
@@ -15,11 +11,6 @@ GridView {
|
|||||||
function updateMargins() {
|
function updateMargins() {
|
||||||
leftMargin = horizontalMargin
|
leftMargin = horizontalMargin
|
||||||
rightMargin = horizontalMargin
|
rightMargin = horizontalMargin
|
||||||
|
|
||||||
if (hasBrokenMargins) {
|
|
||||||
anchors.leftMargin = leftMargin
|
|
||||||
anchors.rightMargin = rightMargin
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onHorizontalMarginChanged: {
|
onHorizontalMarginChanged: {
|
||||||
@@ -27,15 +18,6 @@ GridView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (hasBrokenMargins) {
|
|
||||||
// This will cause an anchor conflict with the parent StackView
|
|
||||||
// which breaks animation, but otherwise the grid will not be
|
|
||||||
// centered in the window.
|
|
||||||
anchors.fill = parent
|
|
||||||
anchors.topMargin = topMargin
|
|
||||||
anchors.bottomMargin = bottomMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
updateMargins()
|
updateMargins()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ import QtQuick 2.0
|
|||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
// Qt 5.10 has a menu property, but we need to support 5.9
|
|
||||||
// so we must make our own.
|
|
||||||
property Menu parentMenu
|
|
||||||
|
|
||||||
// Ensure focus can't be given to an invisible item
|
// Ensure focus can't be given to an invisible item
|
||||||
enabled: visible
|
enabled: visible
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
@@ -15,7 +11,7 @@ MenuItem {
|
|||||||
// We must close the context menu first or
|
// We must close the context menu first or
|
||||||
// it can steal focus from any dialogs that
|
// it can steal focus from any dialogs that
|
||||||
// onTriggered may spawn.
|
// onTriggered may spawn.
|
||||||
parentMenu.close()
|
menu.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
@@ -27,6 +23,6 @@ MenuItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEscapePressed: {
|
Keys.onEscapePressed: {
|
||||||
parentMenu.close()
|
menu.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-7
@@ -35,7 +35,7 @@ CenteredGridView {
|
|||||||
ComputerManager.computerAddCompleted.connect(addComplete)
|
ComputerManager.computerAddCompleted.connect(addComplete)
|
||||||
|
|
||||||
// Highlight the first item if a gamepad is connected
|
// Highlight the first item if a gamepad is connected
|
||||||
if (currentIndex == -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
|
if (currentIndex === -1 && SdlGamepadKeyNavigation.getConnectedGamepads() > 0) {
|
||||||
currentIndex = 0
|
currentIndex = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,6 @@ CenteredGridView {
|
|||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: pcContextMenu
|
|
||||||
text: qsTr("View All Apps")
|
text: qsTr("View All Apps")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
var component = Qt.createComponent("AppView.qml")
|
var component = Qt.createComponent("AppView.qml")
|
||||||
@@ -179,13 +178,11 @@ CenteredGridView {
|
|||||||
visible: model.online && model.paired
|
visible: model.online && model.paired
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: pcContextMenu
|
|
||||||
text: qsTr("Wake PC")
|
text: qsTr("Wake PC")
|
||||||
onTriggered: computerModel.wakeComputer(index)
|
onTriggered: computerModel.wakeComputer(index)
|
||||||
visible: !model.online && model.wakeable
|
visible: !model.online && model.wakeable
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: pcContextMenu
|
|
||||||
text: qsTr("Test Network")
|
text: qsTr("Test Network")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
computerModel.testConnectionForComputer(index)
|
computerModel.testConnectionForComputer(index)
|
||||||
@@ -194,7 +191,6 @@ CenteredGridView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: pcContextMenu
|
|
||||||
text: qsTr("Rename PC")
|
text: qsTr("Rename PC")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
renamePcDialog.pcIndex = index
|
renamePcDialog.pcIndex = index
|
||||||
@@ -203,7 +199,6 @@ CenteredGridView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: pcContextMenu
|
|
||||||
text: qsTr("Delete PC")
|
text: qsTr("Delete PC")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
deletePcDialog.pcIndex = index
|
deletePcDialog.pcIndex = index
|
||||||
@@ -212,7 +207,6 @@ CenteredGridView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
NavigableMenuItem {
|
NavigableMenuItem {
|
||||||
parentMenu: pcContextMenu
|
|
||||||
text: qsTr("View Details")
|
text: qsTr("View Details")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
showPcDetailsDialog.pcDetails = model.details
|
showPcDetailsDialog.pcDetails = model.details
|
||||||
|
|||||||
+6
-16
@@ -205,20 +205,10 @@ ApplicationWindow {
|
|||||||
SdlGamepadKeyNavigation.notifyWindowFocus(visible && active)
|
SdlGamepadKeyNavigation.notifyWindowFocus(visible && active)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for lack of instanceof in Qt 5.9.
|
|
||||||
//
|
|
||||||
// Based on https://stackoverflow.com/questions/13923794/how-to-do-a-is-a-typeof-or-instanceof-in-qml
|
|
||||||
function qmltypeof(obj, className) { // QtObject, string -> bool
|
|
||||||
// className plus "(" is the class instance without modification
|
|
||||||
// className plus "_QML" is the class instance with user-defined properties
|
|
||||||
var str = obj.toString();
|
|
||||||
return str.startsWith(className + "(") || str.startsWith(className + "_QML");
|
|
||||||
}
|
|
||||||
|
|
||||||
function navigateTo(url, objectType)
|
function navigateTo(url, objectType)
|
||||||
{
|
{
|
||||||
var existingItem = stackView.find(function(item, index) {
|
var existingItem = stackView.find(function(item, index) {
|
||||||
return qmltypeof(item, objectType)
|
return item instanceof objectType
|
||||||
})
|
})
|
||||||
|
|
||||||
if (existingItem !== null) {
|
if (existingItem !== null) {
|
||||||
@@ -285,7 +275,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: versionLabel
|
id: versionLabel
|
||||||
visible: qmltypeof(stackView.currentItem, "SettingsView")
|
visible: stackView.currentItem instanceof SettingsView
|
||||||
text: qsTr("Version %1").arg(SystemProperties.versionString)
|
text: qsTr("Version %1").arg(SystemProperties.versionString)
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
horizontalAlignment: Qt.AlignRight
|
horizontalAlignment: Qt.AlignRight
|
||||||
@@ -295,7 +285,7 @@ ApplicationWindow {
|
|||||||
NavigableToolButton {
|
NavigableToolButton {
|
||||||
id: discordButton
|
id: discordButton
|
||||||
visible: SystemProperties.hasBrowser &&
|
visible: SystemProperties.hasBrowser &&
|
||||||
qmltypeof(stackView.currentItem, "SettingsView")
|
stackView.currentItem instanceof SettingsView
|
||||||
|
|
||||||
iconSource: "qrc:/res/discord.svg"
|
iconSource: "qrc:/res/discord.svg"
|
||||||
|
|
||||||
@@ -314,7 +304,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
NavigableToolButton {
|
NavigableToolButton {
|
||||||
id: addPcButton
|
id: addPcButton
|
||||||
visible: qmltypeof(stackView.currentItem, "PcView")
|
visible: stackView.currentItem instanceof PcView
|
||||||
|
|
||||||
iconSource: "qrc:/res/ic_add_to_queue_white_48px.svg"
|
iconSource: "qrc:/res/ic_add_to_queue_white_48px.svg"
|
||||||
|
|
||||||
@@ -412,7 +402,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
iconSource: "qrc:/res/ic_videogame_asset_white_48px.svg"
|
iconSource: "qrc:/res/ic_videogame_asset_white_48px.svg"
|
||||||
|
|
||||||
onClicked: navigateTo("qrc:/gui/GamepadMapper.qml", "GamepadMapper")
|
onClicked: navigateTo("qrc:/gui/GamepadMapper.qml", GamepadMapper)
|
||||||
|
|
||||||
Keys.onDownPressed: {
|
Keys.onDownPressed: {
|
||||||
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
|
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
|
||||||
@@ -424,7 +414,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
iconSource: "qrc:/res/settings.svg"
|
iconSource: "qrc:/res/settings.svg"
|
||||||
|
|
||||||
onClicked: navigateTo("qrc:/gui/SettingsView.qml", "SettingsView")
|
onClicked: navigateTo("qrc:/gui/SettingsView.qml", SettingsView)
|
||||||
|
|
||||||
Keys.onDownPressed: {
|
Keys.onDownPressed: {
|
||||||
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
|
stackView.currentItem.forceActiveFocus(Qt.TabFocus)
|
||||||
|
|||||||
Reference in New Issue
Block a user