diff options
| -rw-r--r-- | src/core/frontend/applets/web_browser.cpp | 9 | ||||
| -rw-r--r-- | src/core/frontend/applets/web_browser.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/web_browser.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/web_browser.h | 2 | ||||
| -rw-r--r-- | src/yuzu/applets/web_browser.cpp | 148 | ||||
| -rw-r--r-- | src/yuzu/applets/web_browser.h | 33 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 16 | ||||
| -rw-r--r-- | src/yuzu/main.h | 3 | 
8 files changed, 167 insertions, 64 deletions
diff --git a/src/core/frontend/applets/web_browser.cpp b/src/core/frontend/applets/web_browser.cpp index a5d8f82ac..50db6a654 100644 --- a/src/core/frontend/applets/web_browser.cpp +++ b/src/core/frontend/applets/web_browser.cpp @@ -20,4 +20,13 @@ void DefaultWebBrowserApplet::OpenLocalWebPage(      callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/");  } +void DefaultWebBrowserApplet::OpenExternalWebPage( +    std::string_view external_url, +    std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const { +    LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open external web page at {}", +                external_url); + +    callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/"); +} +  } // namespace Core::Frontend diff --git a/src/core/frontend/applets/web_browser.h b/src/core/frontend/applets/web_browser.h index 5b0629cfb..1c5ef19a9 100644 --- a/src/core/frontend/applets/web_browser.h +++ b/src/core/frontend/applets/web_browser.h @@ -18,6 +18,10 @@ public:      virtual void OpenLocalWebPage(          std::string_view local_url, std::function<void()> extract_romfs_callback,          std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0; + +    virtual void OpenExternalWebPage( +        std::string_view external_url, +        std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;  };  class DefaultWebBrowserApplet final : public WebBrowserApplet { @@ -27,6 +31,10 @@ public:      void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback,                            std::function<void(Service::AM::Applets::WebExitReason, std::string)>                                callback) const override; + +    void OpenExternalWebPage(std::string_view external_url, +                             std::function<void(Service::AM::Applets::WebExitReason, std::string)> +                                 callback) const override;  };  } // namespace Core::Frontend diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 9c8be156f..2ab420789 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -409,7 +409,9 @@ void WebBrowser::InitializeOffline() {  void WebBrowser::InitializeShare() {} -void WebBrowser::InitializeWeb() {} +void WebBrowser::InitializeWeb() { +    external_url = ParseStringValue(GetInputTLVData(WebArgInputTLVType::InitialURL).value()); +}  void WebBrowser::InitializeWifi() {} @@ -456,8 +458,12 @@ void WebBrowser::ExecuteShare() {  }  void WebBrowser::ExecuteWeb() { -    LOG_WARNING(Service_AM, "(STUBBED) called, Web Applet is not implemented"); -    WebBrowserExit(WebExitReason::EndButtonPressed); +    LOG_INFO(Service_AM, "Opening external URL at {}", external_url); + +    frontend.OpenExternalWebPage(external_url, +                                 [this](WebExitReason exit_reason, std::string last_url) { +                                     WebBrowserExit(exit_reason, last_url); +                                 });  }  void WebBrowser::ExecuteWifi() { diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h index 936a49a86..04c274754 100644 --- a/src/core/hle/service/am/applets/web_browser.h +++ b/src/core/hle/service/am/applets/web_browser.h @@ -79,6 +79,8 @@ private:      std::string offline_document;      FileSys::VirtualFile offline_romfs; +    std::string external_url; +      Core::System& system;  }; diff --git a/src/yuzu/applets/web_browser.cpp b/src/yuzu/applets/web_browser.cpp index 7e2dc6ee9..e482ba029 100644 --- a/src/yuzu/applets/web_browser.cpp +++ b/src/yuzu/applets/web_browser.cpp @@ -51,59 +51,32 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system,                                       InputCommon::InputSubsystem* input_subsystem_)      : QWebEngineView(parent), input_subsystem{input_subsystem_},        url_interceptor(std::make_unique<UrlRequestInterceptor>()), -      input_interpreter(std::make_unique<InputInterpreter>(system)) { -    QWebEngineScript nx_font_css; -    QWebEngineScript load_nx_font; +      input_interpreter(std::make_unique<InputInterpreter>(system)), +      default_profile{QWebEngineProfile::defaultProfile()}, +      global_settings{QWebEngineSettings::globalSettings()} {      QWebEngineScript gamepad;      QWebEngineScript window_nx; -    const QString fonts_dir = QString::fromStdString(Common::FS::SanitizePath( -        fmt::format("{}/fonts", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)))); - -    nx_font_css.setName(QStringLiteral("nx_font_css.js")); -    load_nx_font.setName(QStringLiteral("load_nx_font.js"));      gamepad.setName(QStringLiteral("gamepad_script.js"));      window_nx.setName(QStringLiteral("window_nx_script.js")); -    nx_font_css.setSourceCode( -        QString::fromStdString(NX_FONT_CSS) -            .arg(fonts_dir + QStringLiteral("/FontStandard.ttf")) -            .arg(fonts_dir + QStringLiteral("/FontChineseSimplified.ttf")) -            .arg(fonts_dir + QStringLiteral("/FontExtendedChineseSimplified.ttf")) -            .arg(fonts_dir + QStringLiteral("/FontChineseTraditional.ttf")) -            .arg(fonts_dir + QStringLiteral("/FontKorean.ttf")) -            .arg(fonts_dir + QStringLiteral("/FontNintendoExtended.ttf")) -            .arg(fonts_dir + QStringLiteral("/FontNintendoExtended2.ttf"))); -    load_nx_font.setSourceCode(QString::fromStdString(LOAD_NX_FONT));      gamepad.setSourceCode(QString::fromStdString(GAMEPAD_SCRIPT));      window_nx.setSourceCode(QString::fromStdString(WINDOW_NX_SCRIPT)); -    nx_font_css.setInjectionPoint(QWebEngineScript::DocumentReady); -    load_nx_font.setInjectionPoint(QWebEngineScript::Deferred);      gamepad.setInjectionPoint(QWebEngineScript::DocumentCreation);      window_nx.setInjectionPoint(QWebEngineScript::DocumentCreation); -    nx_font_css.setWorldId(QWebEngineScript::MainWorld); -    load_nx_font.setWorldId(QWebEngineScript::MainWorld);      gamepad.setWorldId(QWebEngineScript::MainWorld);      window_nx.setWorldId(QWebEngineScript::MainWorld); -    nx_font_css.setRunsOnSubFrames(true); -    load_nx_font.setRunsOnSubFrames(true);      gamepad.setRunsOnSubFrames(true);      window_nx.setRunsOnSubFrames(true); -    auto* default_profile = QWebEngineProfile::defaultProfile(); - -    default_profile->scripts()->insert(nx_font_css); -    default_profile->scripts()->insert(load_nx_font);      default_profile->scripts()->insert(gamepad);      default_profile->scripts()->insert(window_nx);      default_profile->setRequestInterceptor(url_interceptor.get()); -    auto* global_settings = QWebEngineSettings::globalSettings(); -      global_settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);      global_settings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);      global_settings->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, true); @@ -111,13 +84,7 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system,      global_settings->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, true);      global_settings->setAttribute(QWebEngineSettings::ShowScrollBars, false); -    connect( -        url_interceptor.get(), &UrlRequestInterceptor::FrameChanged, url_interceptor.get(), -        [this] { -            std::this_thread::sleep_for(std::chrono::milliseconds(50)); -            page()->runJavaScript(QString::fromStdString(LOAD_NX_FONT)); -        }, -        Qt::QueuedConnection); +    global_settings->setFontFamily(QWebEngineSettings::StandardFont, QStringLiteral("Roboto"));      connect(          page(), &QWebEnginePage::windowCloseRequested, page(), @@ -137,6 +104,9 @@ QtNXWebEngineView::~QtNXWebEngineView() {  void QtNXWebEngineView::LoadLocalWebPage(std::string_view main_url,                                           std::string_view additional_args) { +    is_local = true; + +    LoadExtractedFonts();      SetUserAgent(UserAgent::WebApplet);      SetFinished(false);      SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed); @@ -147,6 +117,20 @@ void QtNXWebEngineView::LoadLocalWebPage(std::string_view main_url,                QString::fromStdString(std::string(additional_args))));  } +void QtNXWebEngineView::LoadExternalWebPage(std::string_view main_url, +                                            std::string_view additional_args) { +    is_local = false; + +    SetUserAgent(UserAgent::WebApplet); +    SetFinished(false); +    SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed); +    SetLastURL("http://localhost/"); +    StartInputThread(); + +    load(QUrl(QString::fromStdString(std::string(main_url)) + +              QString::fromStdString(std::string(additional_args)))); +} +  void QtNXWebEngineView::SetUserAgent(UserAgent user_agent) {      const QString user_agent_str = [user_agent] {          switch (user_agent) { @@ -208,11 +192,15 @@ void QtNXWebEngineView::hide() {  }  void QtNXWebEngineView::keyPressEvent(QKeyEvent* event) { -    input_subsystem->GetKeyboard()->PressKey(event->key()); +    if (is_local) { +        input_subsystem->GetKeyboard()->PressKey(event->key()); +    }  }  void QtNXWebEngineView::keyReleaseEvent(QKeyEvent* event) { -    input_subsystem->GetKeyboard()->ReleaseKey(event->key()); +    if (is_local) { +        input_subsystem->GetKeyboard()->ReleaseKey(event->key()); +    }  }  template <HIDButton... T> @@ -294,7 +282,10 @@ void QtNXWebEngineView::StartInputThread() {  }  void QtNXWebEngineView::StopInputThread() { -    QWidget::releaseKeyboard(); +    if (is_local) { +        QWidget::releaseKeyboard(); +    } +      input_thread_running = false;      if (input_thread.joinable()) {          input_thread.join(); @@ -305,7 +296,9 @@ void QtNXWebEngineView::InputThread() {      // Wait for 1 second before allowing any inputs to be processed.      std::this_thread::sleep_for(std::chrono::seconds(1)); -    QWidget::grabKeyboard(); +    if (is_local) { +        QWidget::grabKeyboard(); +    }      while (input_thread_running) {          input_interpreter->PollInput(); @@ -326,11 +319,53 @@ void QtNXWebEngineView::InputThread() {      }  } +void QtNXWebEngineView::LoadExtractedFonts() { +    QWebEngineScript nx_font_css; +    QWebEngineScript load_nx_font; + +    const QString fonts_dir = QString::fromStdString(Common::FS::SanitizePath( +        fmt::format("{}/fonts", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)))); + +    nx_font_css.setName(QStringLiteral("nx_font_css.js")); +    load_nx_font.setName(QStringLiteral("load_nx_font.js")); + +    nx_font_css.setSourceCode( +        QString::fromStdString(NX_FONT_CSS) +            .arg(fonts_dir + QStringLiteral("/FontStandard.ttf")) +            .arg(fonts_dir + QStringLiteral("/FontChineseSimplified.ttf")) +            .arg(fonts_dir + QStringLiteral("/FontExtendedChineseSimplified.ttf")) +            .arg(fonts_dir + QStringLiteral("/FontChineseTraditional.ttf")) +            .arg(fonts_dir + QStringLiteral("/FontKorean.ttf")) +            .arg(fonts_dir + QStringLiteral("/FontNintendoExtended.ttf")) +            .arg(fonts_dir + QStringLiteral("/FontNintendoExtended2.ttf"))); +    load_nx_font.setSourceCode(QString::fromStdString(LOAD_NX_FONT)); + +    nx_font_css.setInjectionPoint(QWebEngineScript::DocumentReady); +    load_nx_font.setInjectionPoint(QWebEngineScript::Deferred); + +    nx_font_css.setWorldId(QWebEngineScript::MainWorld); +    load_nx_font.setWorldId(QWebEngineScript::MainWorld); + +    nx_font_css.setRunsOnSubFrames(true); +    load_nx_font.setRunsOnSubFrames(true); + +    default_profile->scripts()->insert(nx_font_css); +    default_profile->scripts()->insert(load_nx_font); + +    connect( +        url_interceptor.get(), &UrlRequestInterceptor::FrameChanged, url_interceptor.get(), +        [this] { +            std::this_thread::sleep_for(std::chrono::milliseconds(50)); +            page()->runJavaScript(QString::fromStdString(LOAD_NX_FONT)); +        }, +        Qt::QueuedConnection); +} +  #endif  QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { -    connect(this, &QtWebBrowser::MainWindowOpenLocalWebPage, &main_window, -            &GMainWindow::WebBrowserOpenLocalWebPage, Qt::QueuedConnection); +    connect(this, &QtWebBrowser::MainWindowOpenWebPage, &main_window, +            &GMainWindow::WebBrowserOpenWebPage, Qt::QueuedConnection);      connect(&main_window, &GMainWindow::WebBrowserExtractOfflineRomFS, this,              &QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection);      connect(&main_window, &GMainWindow::WebBrowserClosed, this, @@ -340,17 +375,32 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {  QtWebBrowser::~QtWebBrowser() = default;  void QtWebBrowser::OpenLocalWebPage( -    std::string_view local_url, std::function<void()> extract_romfs_callback, -    std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const { -    this->extract_romfs_callback = std::move(extract_romfs_callback); -    this->callback = std::move(callback); +    std::string_view local_url, std::function<void()> extract_romfs_callback_, +    std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const { +    extract_romfs_callback = std::move(extract_romfs_callback_); +    callback = std::move(callback_);      const auto index = local_url.find('?');      if (index == std::string::npos) { -        emit MainWindowOpenLocalWebPage(local_url, ""); +        emit MainWindowOpenWebPage(local_url, "", true); +    } else { +        emit MainWindowOpenWebPage(local_url.substr(0, index), local_url.substr(index), true); +    } +} + +void QtWebBrowser::OpenExternalWebPage( +    std::string_view external_url, +    std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const { +    callback = std::move(callback_); + +    const auto index = external_url.find('?'); + +    if (index == std::string::npos) { +        emit MainWindowOpenWebPage(external_url, "", false);      } else { -        emit MainWindowOpenLocalWebPage(local_url.substr(0, index), local_url.substr(index)); +        emit MainWindowOpenWebPage(external_url.substr(0, index), external_url.substr(index), +                                   false);      }  } diff --git a/src/yuzu/applets/web_browser.h b/src/yuzu/applets/web_browser.h index cfddaa6f8..47f960d69 100644 --- a/src/yuzu/applets/web_browser.h +++ b/src/yuzu/applets/web_browser.h @@ -18,8 +18,8 @@  enum class HIDButton : u8; -class InputInterpreter;  class GMainWindow; +class InputInterpreter;  class UrlRequestInterceptor;  namespace Core { @@ -41,6 +41,9 @@ enum class UserAgent {      WifiWebAuthApplet,  }; +class QWebEngineProfile; +class QWebEngineSettings; +  class QtNXWebEngineView : public QWebEngineView {      Q_OBJECT @@ -58,6 +61,14 @@ public:      void LoadLocalWebPage(std::string_view main_url, std::string_view additional_args);      /** +     * Loads an external website. Cannot be used to load local urls. +     * +     * @param main_url The url to the website. +     * @param additional_args Additional arguments appended to the main url. +     */ +    void LoadExternalWebPage(std::string_view main_url, std::string_view additional_args); + +    /**       * Sets the background color of the web page.       *       * @param color The color to set. @@ -147,6 +158,9 @@ private:      /// The thread where input is being polled and processed.      void InputThread(); +    /// Loads the extracted fonts using JavaScript. +    void LoadExtractedFonts(); +      InputCommon::InputSubsystem* input_subsystem;      std::unique_ptr<UrlRequestInterceptor> url_interceptor; @@ -163,6 +177,11 @@ private:          Service::AM::Applets::WebExitReason::EndButtonPressed};      std::string last_url{"http://localhost/"}; + +    bool is_local{}; + +    QWebEngineProfile* default_profile; +    QWebEngineSettings* global_settings;  };  #endif @@ -174,13 +193,17 @@ public:      explicit QtWebBrowser(GMainWindow& parent);      ~QtWebBrowser() override; -    void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback, +    void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback_,                            std::function<void(Service::AM::Applets::WebExitReason, std::string)> -                              callback) const override; +                              callback_) const override; + +    void OpenExternalWebPage(std::string_view external_url, +                             std::function<void(Service::AM::Applets::WebExitReason, std::string)> +                                 callback_) const override;  signals: -    void MainWindowOpenLocalWebPage(std::string_view main_url, -                                    std::string_view additional_args) const; +    void MainWindowOpenWebPage(std::string_view main_url, std::string_view additional_args, +                               bool is_local) const;  private:      void MainWindowExtractOfflineRomFS(); 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  } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index b140995bf..22f82b20e 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -142,7 +142,8 @@ public slots:      void ProfileSelectorSelectProfile();      void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters);      void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message); -    void WebBrowserOpenLocalWebPage(std::string_view main_url, std::string_view additional_args); +    void WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args, +                               bool is_local);      void OnAppFocusStateChanged(Qt::ApplicationState state);  private:  | 
