mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-24 21:55:46 +00:00
applets/web: Implement the online web browser applet
This commit is contained in:
parent
150d237919
commit
469ed33cf6
8 changed files with 167 additions and 64 deletions
|
@ -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 MainWindowOpenLocalWebPage(local_url.substr(0, index), local_url.substr(index));
|
||||
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 MainWindowOpenWebPage(external_url.substr(0, index), external_url.substr(index),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue