Skip to content

Commit

Permalink
Add back webengine
Browse files Browse the repository at this point in the history
seems to be needed to sabe scores online, for the login
  • Loading branch information
Jojo-Schmitz committed Jan 4, 2025
1 parent 454f447 commit e9a1df5
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 3 deletions.
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ if (MSVC)
set (MINGW false)
endif (MSVC)

# We need this early, before FindQt5
option(BUILD_WEBENGINE "Built in webengine support" OFF)

if (BUILD_WEBENGINE)
if (MINGW OR MSVC)
SET (USE_WEBENGINE 0)
else (MINGW OR MSVC)
SET (USE_WEBENGINE 1)
endif(MINGW OR MSVC)
else (BUILD_WEBENGINE)
SET (USE_WEBENGINE 0)
endif (BUILD_WEBENGINE)

set(SCRIPT_INTERFACE TRUE)
# Look for Qt5
if (SCRIPT_INTERFACE)
Expand Down
8 changes: 8 additions & 0 deletions build/FindQt5.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ set(_components
LinguistTools
Help
)
if (USE_WEBENGINE)
set(_components
${_components}
WebEngine
WebEngineCore
WebEngineWidgets
)
endif(USE_WEBENGINE)

if (WIN32)
set(_components
Expand Down
18 changes: 17 additions & 1 deletion build/package_mac
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,20 @@ function change_rpath() {
done
}

rm -f ${WORKING_DIRECTORY}/${COMPRESSEDDMGNAME}
function change_rpath_QWebEngine() {
for P in `otool -L $1 | awk '{print $1}'`
do
if [[ "$P" == *@rpath* ]]
then
PSLASH=$(echo $P | sed 's,@rpath,@loader_path/../../../../../../..,g')
FNAME=$(echo $P | sed "s,@rpath,${VOLUME}/${APPNAME}.app/Contents/Frameworks,g")
install_name_tool -change $P $PSLASH $1
fi
done
}


rm ${WORKING_DIRECTORY}/${COMPRESSEDDMGNAME}

#tip: increase the size if error on copy or macdeployqt
hdiutil create -size 800m -fs HFS+ -volname ${VOLNAME} ${WORKING_DIRECTORY}/${DMGNAME}
Expand Down Expand Up @@ -138,6 +151,9 @@ macdeployqt ${VOLUME}/${APPNAME}.app
# fix the libs, qt5.6 has @rpath...
BIN_FILE=${VOLUME}/${APPNAME}.app/Contents/MacOS/mscore
change_rpath $BIN_FILE
# fix the QWebEngineProcess, qt5.9 has @rpath...
WebEngineProcess=${VOLUME}/${APPNAME}.app/Contents/Frameworks/QtWebEngineCore.framework/Versions/5/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess
change_rpath_QWebEngine $WebEngineProcess

# Workaround:
# fix Homebrew libraries with hard coded absolute path, see QTBUG-56814
Expand Down
22 changes: 20 additions & 2 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ else (MINGW)

if ( NOT MSVC )
## install qwebengine core
if (NOT APPLE)
if (NOT APPLE AND USE_WEBENGINE)
install(PROGRAMS
${QT_INSTALL_LIBEXECS}/QtWebEngineProcess
DESTINATION bin
Expand All @@ -242,7 +242,7 @@ else (MINGW)
${QT_INSTALL_TRANSLATIONS}/qtwebengine_locales
DESTINATION lib/qt5/translations
)
endif(NOT APPLE)
endif(NOT APPLE AND USE_WEBENGINE)

set_target_properties (
mscore
Expand Down Expand Up @@ -352,6 +352,9 @@ else (MINGW)
"${QT_INSTALL_BINS}/libEGL.dll" "${QT_INSTALL_BINS}/libGLESv2.dll" "${QT_INSTALL_BINS}/opengl32sw.dll"
"${QT_INSTALL_BINS}/d3dcompiler_47.dll"
)
if (USE_WEBENGINE)
list(APPEND dlls_to_copy "${QT_INSTALL_BINS}/Qt5WebEngineWidgets.dll" "${QT_INSTALL_BINS}/Qt5WebEngineCore.dll")
endif(USE_WEBENGINE)
if (Qt5Widgets_VERSION VERSION_GREATER_EQUAL "5.14.1")
list(APPEND dlls_to_copy "${QT_INSTALL_BINS}/Qt5QmlModels.dll")
list(APPEND dlls_to_copy "${QT_INSTALL_BINS}/Qt5QmlWorkerScript.dll")
Expand Down Expand Up @@ -449,6 +452,21 @@ else (MINGW)

install( TARGETS mscore RUNTIME DESTINATION bin ) # this duplicate due to the correctly package step

if (USE_WEBENGINE)
install(FILES
${QT_INSTALL_LIBEXECS}/QtWebEngineProcess.exe
DESTINATION bin
)
install(DIRECTORY
${QT_INSTALL_DATA}/resources
DESTINATION bin/webengineresources
)
install(DIRECTORY
${QT_INSTALL_TRANSLATIONS}/qtwebengine_locales
DESTINATION bin/webengineresources/translations
)
endif (USE_WEBENGINE)

install(DIRECTORY
${QT_INSTALL_QML}
DESTINATION .
Expand Down
126 changes: 126 additions & 0 deletions mscore/cloud/loginmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include "libmscore/score.h"
#include "preferences.h"

#ifdef USE_WEBENGINE
#include <QWebEngineCookieStore>
#endif

namespace Ms {

extern QString dataPath;
Expand Down Expand Up @@ -131,7 +135,13 @@ QUrl ApiInfo::getUpdateScoreInfoUrl(const QString& scoreId, const QString& acces
QUrlQuery query;
query.addQueryItem("id", scoreId);
query.addQueryItem("newScore", QString::number(newScore));

#ifdef USE_WEBENGINE
query.addQueryItem("_token", accessToken);
#else
Q_UNUSED(accessToken); // we'll be redirected to a browser, don't put access token there
#endif

url.setQuery(query);

return url;
Expand Down Expand Up @@ -321,10 +331,82 @@ void LoginManager::onTryLoginError(const QString& error)
disconnect(this, SIGNAL(getUserError(QString)), this, SLOT(onTryLoginError(QString)));
connect(this, SIGNAL(loginSuccess()), this, SLOT(tryLogin()));
logout();
#ifdef USE_WEBENGINE
loginInteractive();
#else
mscore->showLoginDialog();
#endif
}
/*------- END - TRY LOGIN ROUTINES ----------------------------*/

//---------------------------------------------------------
// clearHttpCacheOnRenderFinish
//---------------------------------------------------------

#ifdef USE_WEBENGINE
static void clearHttpCacheOnRenderFinish(QWebEngineView* webView)
{
QWebEnginePage* page = webView->page();
QWebEngineProfile* profile = page->profile();

// workaround for the crashes sometimes happening in Chromium on macOS with Qt 5.12
QObject::connect(webView, &QWebEngineView::renderProcessTerminated, webView, [profile, webView](QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
{
qDebug() << "Login page loading terminated" << terminationStatus << " " << exitCode;
profile->clearHttpCache();
webView->show();
});
}
#endif
//---------------------------------------------------------
// loginInteractive
//---------------------------------------------------------

#ifdef USE_WEBENGINE
void LoginManager::loginInteractive()
{
#if defined(WIN_PORTABLE)
QWebEngineProfile* defaultProfile = QWebEngineProfile::defaultProfile();
defaultProfile->setCachePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
defaultProfile->setPersistentStoragePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
#endif
QWebEngineView* webView = new QWebEngineView;
webView->setWindowModality(Qt::ApplicationModal);
webView->setAttribute(Qt::WA_DeleteOnClose);

QWebEnginePage* page = webView->page();
QWebEngineProfile* profile = page->profile();
// TODO: logout in editor does not log out in web view
profile->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
#if defined(WIN_PORTABLE)
profile->setCachePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
profile->setPersistentStoragePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
#endif
profile->setRequestInterceptor(new ApiWebEngineRequestInterceptor(profile));

clearHttpCacheOnRenderFinish(webView);

connect(page, &QWebEnginePage::loadFinished, this, [this, page, webView](bool ok) {
if (!ok)
return;
constexpr QUrl::FormattingOptions cmpOpt = QUrl::RemoveQuery | QUrl::RemoveFragment | QUrl::StripTrailingSlash;
if (!page->url().matches(ApiInfo::loginSuccessUrl, cmpOpt))
return;

page->runJavaScript("JSON.stringify(muGetAuthInfo())", [this, page, webView](const QVariant& v) {
onLoginReply(nullptr, HTTP_OK, QJsonDocument::fromJson(v.toString().toUtf8()).object());
// We have retrieved an access token, do not remain logged
// in with web view profile.
page->profile()->cookieStore()->deleteAllCookies();
webView->close();
});
});

webView->load(ApiInfo::loginUrl);
webView->show();
}
#endif

//---------------------------------------------------------
// login
//---------------------------------------------------------
Expand Down Expand Up @@ -762,7 +844,35 @@ bool LoginManager::syncUpload(const QString& path, int nid, const QString& title
void LoginManager::updateScoreData(const QString& nid, bool newScore)
{
const QUrl url(ApiInfo::getUpdateScoreInfoUrl(nid, _accessToken, newScore, _updateScoreDataPath));
#ifdef USE_WEBENGINE
#if defined(WIN_PORTABLE)
QWebEngineProfile* defaultProfile = QWebEngineProfile::defaultProfile();
defaultProfile->setCachePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
defaultProfile->setPersistentStoragePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
#endif
QWebEngineView* webView = new QWebEngineView;
webView->setWindowModality(Qt::ApplicationModal);
webView->setAttribute(Qt::WA_DeleteOnClose);

QWebEnginePage* page = webView->page();
QWebEngineProfile* profile = page->profile();

profile->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
#if defined(WIN_PORTABLE)
profile->setCachePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
profile->setPersistentStoragePath(QDir::cleanPath(QString("%1/../../../Data/settings/QWebEngine").arg(QCoreApplication::applicationDirPath())));
#endif
profile->setRequestInterceptor(new ApiWebEngineRequestInterceptor(profile));

connect(page, &QWebEnginePage::windowCloseRequested, webView, &QWebEngineView::close);

clearHttpCacheOnRenderFinish(webView);

webView->load(url);
webView->show();
#else
QDesktopServices::openUrl(url);
#endif
}

//---------------------------------------------------------
Expand Down Expand Up @@ -865,4 +975,20 @@ void ApiRequest::executeRequest(QNetworkAccessManager* networkManager)
_reply->setParent(this);
connect(_reply, &QNetworkReply::finished, this, [this]() { emit replyFinished(this); });
}

//---------------------------------------------------------
// ApiWebEngineRequestInterceptor::interceptRequest
// Sets the appropriate API headers for requests to
// musescore.com
//---------------------------------------------------------

#ifdef USE_WEBENGINE
void ApiWebEngineRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo& request)
{
const ApiInfo& apiInfo = ApiInfo::instance();
request.setHttpHeader("User-Agent", apiInfo.userAgent);
request.setHttpHeader(apiInfo.clientIdHeader, apiInfo.clientId);
request.setHttpHeader(apiInfo.apiKeyHeader, apiInfo.apiKey);
}
#endif
}
3 changes: 3 additions & 0 deletions mscore/cloud/loginmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class LoginManager : public QObject
public:
LoginManager(QAction* uploadAudioMenuAction, QObject* parent = 0);
void login(QString login, QString password);
#ifdef USE_WEBENGINE
void loginInteractive();
#endif
void upload(const QString& path, int nid, const QString& title);
void updateScoreData(const QString& nid, bool newScore);
bool hasAccessToken();
Expand Down
14 changes: 14 additions & 0 deletions mscore/cloud/loginmanager_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ class ApiRequest : public QObject
int retryCount() const { return _retryCount; }
};

//---------------------------------------------------------
// ApiWebEngineRequestInterceptor
//---------------------------------------------------------

#ifdef USE_WEBENGINE
class ApiWebEngineRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
Q_OBJECT
public:
ApiWebEngineRequestInterceptor(QObject* parent) : QWebEngineUrlRequestInterceptor(parent) {}
void interceptRequest(QWebEngineUrlRequestInfo& info) override;
};
#endif

//---------------------------------------------------------
// AsyncWait
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions mscore/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern bool converterMode;
extern bool pluginMode;
extern double guiScaling;
extern int trimMargin;
extern bool noWebView;
extern bool ignoreWarnings;

enum TelemetryDataCollectionType : unsigned char {
Expand Down
Loading

0 comments on commit e9a1df5

Please sign in to comment.