From ccb439efb088c990b41a6ceb5b1b330c8c27a1aa Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sun, 8 Nov 2020 07:17:12 -0500 Subject: applets: Remove the previous web browser applet implementation --- src/yuzu/main.cpp | 154 ------------------------------------------------------ 1 file changed, 154 deletions(-) (limited to 'src/yuzu/main.cpp') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 3461fa675..7d4bba854 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -125,14 +125,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "yuzu/discord_impl.h" #endif -#ifdef YUZU_USE_QT_WEB_ENGINE -#include -#include -#include -#include -#include -#endif - #ifdef QT_STATICPLUGIN Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); #endif @@ -349,151 +341,6 @@ void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message emit SoftwareKeyboardFinishedCheckDialog(); } -#ifdef YUZU_USE_QT_WEB_ENGINE - -void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) { - NXInputWebEngineView web_browser_view(this); - - // Scope to contain the QProgressDialog for initialization - { - QProgressDialog progress(this); - progress.setMinimumDuration(200); - progress.setLabelText(tr("Loading Web Applet...")); - progress.setRange(0, 4); - progress.setValue(0); - progress.show(); - - auto future = QtConcurrent::run([this] { emit WebBrowserUnpackRomFS(); }); - - while (!future.isFinished()) - QApplication::processEvents(); - - progress.setValue(1); - - // Load the special shim script to handle input and exit. - QWebEngineScript nx_shim; - nx_shim.setSourceCode(GetNXShimInjectionScript()); - nx_shim.setWorldId(QWebEngineScript::MainWorld); - nx_shim.setName(QStringLiteral("nx_inject.js")); - nx_shim.setInjectionPoint(QWebEngineScript::DocumentCreation); - nx_shim.setRunsOnSubFrames(true); - web_browser_view.page()->profile()->scripts()->insert(nx_shim); - - web_browser_view.load( - QUrl(QUrl::fromLocalFile(QString::fromStdString(std::string(filename))).toString() + - QString::fromStdString(std::string(additional_args)))); - - progress.setValue(2); - - render_window->hide(); - web_browser_view.setFocus(); - - const auto& layout = render_window->GetFramebufferLayout(); - web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); - web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); - web_browser_view.setZoomFactor(static_cast(layout.screen.GetWidth()) / - Layout::ScreenUndocked::Width); - web_browser_view.settings()->setAttribute( - QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); - - web_browser_view.show(); - - progress.setValue(3); - - QApplication::processEvents(); - - progress.setValue(4); - } - - bool finished = false; - QAction* exit_action = new QAction(tr("Exit Web Applet"), this); - connect(exit_action, &QAction::triggered, this, [&finished] { finished = true; }); - ui.menubar->addAction(exit_action); - - auto& npad = - Core::System::GetInstance() - .ServiceManager() - .GetService("hid") - ->GetAppletResource() - ->GetController(Service::HID::HidController::NPad); - - const auto fire_js_keypress = [&web_browser_view](u32 key_code) { - web_browser_view.page()->runJavaScript( - QStringLiteral("document.dispatchEvent(new KeyboardEvent('keydown', {'key': %1}));") - .arg(key_code)); - }; - - QMessageBox::information( - this, tr("Exit"), - tr("To exit the web application, use the game provided controls to select exit, select the " - "'Exit Web Applet' option in the menu bar, or press the 'Enter' key.")); - - bool running_exit_check = false; - while (!finished) { - QApplication::processEvents(); - - if (!running_exit_check) { - web_browser_view.page()->runJavaScript(QStringLiteral("applet_done;"), - [&](const QVariant& res) { - running_exit_check = false; - if (res.toBool()) - finished = true; - }); - running_exit_check = true; - } - - const auto input = npad.GetAndResetPressState(); - for (std::size_t i = 0; i < Settings::NativeButton::NumButtons; ++i) { - if ((input & (1 << i)) != 0) { - LOG_DEBUG(Frontend, "firing input for button id={:02X}", i); - web_browser_view.page()->runJavaScript( - QStringLiteral("yuzu_key_callbacks[%1]();").arg(i)); - } - } - - if (input & 0x00888000) // RStick Down | LStick Down | DPad Down - fire_js_keypress(40); // Down Arrow Key - else if (input & 0x00444000) // RStick Right | LStick Right | DPad Right - fire_js_keypress(39); // Right Arrow Key - else if (input & 0x00222000) // RStick Up | LStick Up | DPad Up - fire_js_keypress(38); // Up Arrow Key - else if (input & 0x00111000) // RStick Left | LStick Left | DPad Left - fire_js_keypress(37); // Left Arrow Key - else if (input & 0x00000001) // A Button - fire_js_keypress(13); // Enter Key - } - - web_browser_view.hide(); - render_window->show(); - render_window->setFocus(); - ui.menubar->removeAction(exit_action); - - // Needed to update render window focus/show and remove menubar action - QApplication::processEvents(); - emit WebBrowserFinishedBrowsing(); -} - -#else - -void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) { -#ifndef __linux__ - QMessageBox::warning( - this, tr("Web Applet"), - tr("This version of yuzu was built without QtWebEngine support, meaning that yuzu cannot " - "properly display the game manual or web page requested."), - QMessageBox::Ok, QMessageBox::Ok); -#endif - - LOG_INFO(Frontend, - "(STUBBED) called - Missing QtWebEngine dependency needed to open website page at " - "'{}' with arguments '{}'!", - filename, additional_args); - - emit WebBrowserFinishedBrowsing(); -} - -#endif - void GMainWindow::InitializeWidgets() { #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING ui.action_Report_Compatibility->setVisible(true); @@ -993,7 +840,6 @@ bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) { system.SetAppletFrontendSet({ std::make_unique(*this), // Controller Selector - nullptr, // E-Commerce std::make_unique(*this), // Error Display nullptr, // Parental Controls nullptr, // Photo Viewer -- cgit v1.2.3 From 93cb7838539075f0d94cb08a65a25b0c05589d7d Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Mon, 30 Nov 2020 08:31:26 -0500 Subject: applets/web: Implement the Qt web browser applet frontend --- src/yuzu/main.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) (limited to 'src/yuzu/main.cpp') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 7d4bba854..bab76db1e 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -28,8 +28,6 @@ #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/applets/applets.h" -#include "core/hle/service/hid/controllers/npad.h" -#include "core/hle/service/hid/hid.h" // These are wrappers to avoid the calls to CreateDirectory and CreateFile because of the Windows // defines. @@ -182,6 +180,30 @@ static void InitializeLogging() { #endif } +static void RemoveCachedContents() { + const auto offline_fonts = Common::FS::SanitizePath( + fmt::format("{}/fonts", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)), + Common::FS::DirectorySeparator::PlatformDefault); + + const auto offline_manual = Common::FS::SanitizePath( + fmt::format("{}/offline_web_applet_manual", + Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)), + Common::FS::DirectorySeparator::PlatformDefault); + const auto offline_legal_information = Common::FS::SanitizePath( + fmt::format("{}/offline_web_applet_legal_information", + Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)), + Common::FS::DirectorySeparator::PlatformDefault); + const auto offline_system_data = Common::FS::SanitizePath( + fmt::format("{}/offline_web_applet_system_data", + Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)), + Common::FS::DirectorySeparator::PlatformDefault); + + Common::FS::DeleteDirRecursively(offline_fonts); + Common::FS::DeleteDirRecursively(offline_manual); + Common::FS::DeleteDirRecursively(offline_legal_information); + Common::FS::DeleteDirRecursively(offline_system_data); +} + GMainWindow::GMainWindow() : input_subsystem{std::make_shared()}, config{std::make_unique()}, vfs{std::make_shared()}, @@ -250,6 +272,9 @@ GMainWindow::GMainWindow() FileSys::ContentProviderUnionSlot::FrontendManual, provider.get()); Core::System::GetInstance().GetFileSystemController().CreateFactories(*vfs); + // Remove cached contents generated during the previous session + RemoveCachedContents(); + // Gen keys if necessary OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning); @@ -341,6 +366,86 @@ void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message emit SoftwareKeyboardFinishedCheckDialog(); } +void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, + std::string_view additional_args) { +#ifdef YUZU_USE_QT_WEB_ENGINE + + QtNXWebEngineView web_browser_view(this, Core::System::GetInstance()); + + web_browser_view.LoadLocalWebPage(main_url, additional_args); + + ui.action_Pause->setEnabled(false); + ui.action_Restart->setEnabled(false); + ui.action_Stop->setEnabled(false); + + if (render_window->IsLoadingComplete()) { + render_window->hide(); + } + + const auto& layout = render_window->GetFramebufferLayout(); + web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); + web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); + web_browser_view.setZoomFactor(static_cast(layout.screen.GetWidth()) / + static_cast(Layout::ScreenUndocked::Width)); + + web_browser_view.setFocus(); + web_browser_view.show(); + + bool exit_check = false; + + while (!web_browser_view.IsFinished()) { + QCoreApplication::processEvents(); + + if (!exit_check) { + web_browser_view.page()->runJavaScript( + QStringLiteral("end_applet;"), [&](const QVariant& variant) { + exit_check = false; + if (variant.toBool()) { + web_browser_view.SetFinished(true); + web_browser_view.SetExitReason(WebExitReason::EndButtonPressed); + } + }); + + exit_check = true; + } + + if (web_browser_view.GetCurrentURL().contains(QStringLiteral("localhost"))) { + if (!web_browser_view.IsFinished()) { + web_browser_view.SetFinished(true); + web_browser_view.SetExitReason(WebExitReason::CallbackURL); + } + + web_browser_view.SetLastURL(web_browser_view.GetCurrentURL().toStdString()); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + const auto exit_reason = web_browser_view.GetExitReason(); + const auto last_url = web_browser_view.GetLastURL(); + + web_browser_view.hide(); + + render_window->setFocus(); + + if (render_window->IsLoadingComplete()) { + render_window->show(); + } + + ui.action_Pause->setEnabled(true); + ui.action_Restart->setEnabled(true); + ui.action_Stop->setEnabled(true); + + emit WebBrowserClosed(exit_reason, last_url); + +#else + + // Utilize the same fallback as the default web browser applet. + emit WebBrowserClosed(WebExitReason::WindowClosed, "http://localhost"); + +#endif +} + void GMainWindow::InitializeWidgets() { #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING ui.action_Report_Compatibility->setVisible(true); @@ -1948,6 +2053,7 @@ void GMainWindow::OnStartGame() { qRegisterMetaType("std::string"); qRegisterMetaType>("std::optional"); qRegisterMetaType("std::string_view"); + qRegisterMetaType("Service::AM::Applets::WebExitReason"); connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError); -- cgit v1.2.3 From 8b95bf041da573459e953e27eee2dcf30208b02d Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Mon, 30 Nov 2020 10:15:00 -0500 Subject: main, applets/web: Re-add progress dialog for RomFS extraction --- src/yuzu/main.cpp | 58 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'src/yuzu/main.cpp') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index bab76db1e..f696fc494 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -372,24 +372,49 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, QtNXWebEngineView web_browser_view(this, Core::System::GetInstance()); - web_browser_view.LoadLocalWebPage(main_url, additional_args); - ui.action_Pause->setEnabled(false); ui.action_Restart->setEnabled(false); ui.action_Stop->setEnabled(false); - if (render_window->IsLoadingComplete()) { - render_window->hide(); - } + { + QProgressDialog loading_progress(this); + loading_progress.setLabelText(tr("Loading Web Applet...")); + loading_progress.setRange(0, 3); + loading_progress.setValue(0); + + if (!Common::FS::Exists(std::string(main_url))) { + loading_progress.show(); + + auto future = QtConcurrent::run([this] { emit WebBrowserExtractOfflineRomFS(); }); + + while (!future.isFinished()) { + QCoreApplication::processEvents(); + } + } - const auto& layout = render_window->GetFramebufferLayout(); - web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); - web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); - web_browser_view.setZoomFactor(static_cast(layout.screen.GetWidth()) / - static_cast(Layout::ScreenUndocked::Width)); + loading_progress.setValue(1); - web_browser_view.setFocus(); - web_browser_view.show(); + web_browser_view.LoadLocalWebPage(main_url, additional_args); + + if (render_window->IsLoadingComplete()) { + render_window->hide(); + } + + const auto& layout = render_window->GetFramebufferLayout(); + web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); + web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); + web_browser_view.setZoomFactor(static_cast(layout.screen.GetWidth()) / + static_cast(Layout::ScreenUndocked::Width)); + + web_browser_view.setFocus(); + web_browser_view.show(); + + loading_progress.setValue(2); + + QCoreApplication::processEvents(); + + loading_progress.setValue(3); + } bool exit_check = false; @@ -402,7 +427,8 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, exit_check = false; if (variant.toBool()) { web_browser_view.SetFinished(true); - web_browser_view.SetExitReason(WebExitReason::EndButtonPressed); + web_browser_view.SetExitReason( + Service::AM::Applets::WebExitReason::EndButtonPressed); } }); @@ -412,7 +438,7 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, if (web_browser_view.GetCurrentURL().contains(QStringLiteral("localhost"))) { if (!web_browser_view.IsFinished()) { web_browser_view.SetFinished(true); - web_browser_view.SetExitReason(WebExitReason::CallbackURL); + web_browser_view.SetExitReason(Service::AM::Applets::WebExitReason::CallbackURL); } web_browser_view.SetLastURL(web_browser_view.GetCurrentURL().toStdString()); @@ -436,12 +462,14 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, ui.action_Restart->setEnabled(true); ui.action_Stop->setEnabled(true); + QCoreApplication::processEvents(); + emit WebBrowserClosed(exit_reason, last_url); #else // Utilize the same fallback as the default web browser applet. - emit WebBrowserClosed(WebExitReason::WindowClosed, "http://localhost"); + emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost"); #endif } -- cgit v1.2.3 From 2ddd83cdfe2bfb63579d2932a1ee3b26073fbeea Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Mon, 30 Nov 2020 10:34:18 -0500 Subject: main: Add the ability to disable the web applet This should only be used for Super Mario 3D All-Stars. This is a temporary solution until it can be implemented properly. --- src/yuzu/main.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/yuzu/main.cpp') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f696fc494..ccff08074 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -370,6 +370,12 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, std::string_view additional_args) { #ifdef YUZU_USE_QT_WEB_ENGINE + if (disable_web_applet) { + emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, + "http://localhost"); + return; + } + QtNXWebEngineView web_browser_view(this, Core::System::GetInstance()); ui.action_Pause->setEnabled(false); @@ -418,6 +424,22 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, bool exit_check = false; + // TODO (Morph): Remove this + QAction* exit_action = new QAction(tr("Disable Web Applet"), this); + connect(exit_action, &QAction::triggered, this, [this, &web_browser_view] { + const auto result = QMessageBox::warning( + this, tr("Disable Web Applet"), + tr("Disabling the web applet will cause it to not be shown again for the rest of the " + "emulated session. This can lead to undefined behavior and should only be used with " + "Super Mario 3D All-Stars. Are you sure you want to disable the web applet?"), + QMessageBox::Yes | QMessageBox::No); + if (result == QMessageBox::Yes) { + disable_web_applet = true; + web_browser_view.SetFinished(true); + } + }); + ui.menubar->addAction(exit_action); + while (!web_browser_view.IsFinished()) { QCoreApplication::processEvents(); @@ -462,6 +484,8 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, ui.action_Restart->setEnabled(true); ui.action_Stop->setEnabled(true); + ui.menubar->removeAction(exit_action); + QCoreApplication::processEvents(); emit WebBrowserClosed(exit_reason, last_url); -- cgit v1.2.3 From 51cddcb8b8d4d12715ba0517638b394244b500bb Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Mon, 30 Nov 2020 22:25:01 -0500 Subject: applets/web: Fix keyboard to emulated controller input --- src/yuzu/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/yuzu/main.cpp') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index ccff08074..f835ee9cb 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -376,7 +376,7 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, return; } - QtNXWebEngineView web_browser_view(this, Core::System::GetInstance()); + QtNXWebEngineView web_browser_view(this, Core::System::GetInstance(), input_subsystem.get()); ui.action_Pause->setEnabled(false); ui.action_Restart->setEnabled(false); -- cgit v1.2.3 From 82fa9f8d56bc285e7bb58fc81b495a55be9ea82c Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Tue, 8 Dec 2020 06:20:45 -0500 Subject: applets/web: Implement the online web browser applet --- src/yuzu/main.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/yuzu/main.cpp') diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f835ee9cb..620e80cdc 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -366,13 +366,13 @@ void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message emit SoftwareKeyboardFinishedCheckDialog(); } -void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, - std::string_view additional_args) { +void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args, + bool is_local) { #ifdef YUZU_USE_QT_WEB_ENGINE if (disable_web_applet) { emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, - "http://localhost"); + "http://localhost/"); return; } @@ -388,7 +388,7 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, loading_progress.setRange(0, 3); loading_progress.setValue(0); - if (!Common::FS::Exists(std::string(main_url))) { + if (is_local && !Common::FS::Exists(std::string(main_url))) { loading_progress.show(); auto future = QtConcurrent::run([this] { emit WebBrowserExtractOfflineRomFS(); }); @@ -400,7 +400,11 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, loading_progress.setValue(1); - web_browser_view.LoadLocalWebPage(main_url, additional_args); + if (is_local) { + web_browser_view.LoadLocalWebPage(main_url, additional_args); + } else { + web_browser_view.LoadExternalWebPage(main_url, additional_args); + } if (render_window->IsLoadingComplete()) { render_window->hide(); @@ -493,7 +497,7 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, #else // Utilize the same fallback as the default web browser applet. - emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost"); + emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/"); #endif } -- cgit v1.2.3