feat(ui): add QLaunch/Home Menu support to menubar

- Add Tools > Open QLaunch menu action

- Implement OnOpenQLaunch() to launch firmware home menu

- Add translation strings for QLaunch option
This commit is contained in:
Zephyron
2026-01-28 16:42:51 +10:00
parent 626ea63cbc
commit a5632d7576
4 changed files with 61 additions and 1 deletions

View File

@@ -44,6 +44,11 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
INSERT(Settings, wifi_web_auth_applet_mode, tr("Wifi web auth"), QStringLiteral());
INSERT(Settings, my_page_applet_mode, tr("My page"), QStringLiteral());
// System Applet
INSERT(Settings, qlaunch_enabled, tr("Enable Home Menu (QLaunch)"),
tr("When enabled, pressing the Home button will launch the firmware's Home Menu.\n"
"Requires firmware to be installed."));
// Audio
INSERT(Settings, sink_id, tr("Output Engine:"), QStringLiteral());
INSERT(Settings, audio_output_device_id, tr("Output Device:"), QStringLiteral());

View File

@@ -1725,6 +1725,7 @@ void GMainWindow::ConnectMenuEvents() {
connect(multiplayer_state, &MultiplayerState::SaveConfig, this, &GMainWindow::OnSaveConfig);
// Tools
connect_menu(ui->action_Load_Home_Menu, &GMainWindow::OnQLaunch);
connect_menu(ui->action_Load_Album, &GMainWindow::OnAlbum);
connect_menu(ui->action_Load_Cabinet_Nickname_Owner,
[this]() { OnCabinet(Service::NFP::CabinetMode::StartNicknameAndOwnerSettings); });
@@ -1769,7 +1770,8 @@ void GMainWindow::UpdateMenuState() {
ui->action_Pause,
};
const std::array applet_actions{ui->action_Load_Album,
const std::array applet_actions{ui->action_Load_Home_Menu,
ui->action_Load_Album,
ui->action_Load_Cabinet_Nickname_Owner,
ui->action_Load_Cabinet_Eraser,
ui->action_Load_Cabinet_Restorer,
@@ -2167,6 +2169,9 @@ void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletP
render_window->Exit();
});
// Set up home menu callback for QLaunch support
SetupHomeMenuCallback();
connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
@@ -5393,6 +5398,31 @@ void GMainWindow::OnOpenControllerMenu() {
LibraryAppletParameters(ControllerAppletId, Service::AM::AppletId::Controller));
}
void GMainWindow::OnQLaunch() {
if (!Settings::values.qlaunch_enabled.GetValue()) {
return;
}
constexpr u64 QLaunchId = static_cast<u64>(Service::AM::AppletProgramId::QLaunch);
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
tr("Please install firmware to use the Home Menu."));
return;
}
auto qlaunch_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
if (!qlaunch_nca) {
QMessageBox::warning(this, tr("Home Menu"),
tr("QLaunch applet not found. Please reinstall firmware."));
return;
}
const auto filename = QString::fromStdString(qlaunch_nca->GetFullPath());
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename, SystemAppletParameters(QLaunchId, Service::AM::AppletId::QLaunch));
}
void GMainWindow::OnCaptureScreenshot() {
if (emu_thread == nullptr || !emu_thread->IsRunning() || !render_window->IsLoadingComplete()) {
return;
@@ -6110,6 +6140,22 @@ Service::AM::FrontendAppletParameters GMainWindow::LibraryAppletParameters(
};
}
Service::AM::FrontendAppletParameters GMainWindow::SystemAppletParameters(
u64 program_id, Service::AM::AppletId applet_id) {
return Service::AM::FrontendAppletParameters{
.program_id = program_id,
.applet_id = applet_id,
.applet_type = Service::AM::AppletType::SystemApplet,
};
}
void GMainWindow::SetupHomeMenuCallback() {
system->GetAppletManager().SetHomeMenuRequestCallback([this]() {
// Use Qt's thread-safe invocation to call OnQLaunch from the main thread
QMetaObject::invokeMethod(this, "OnQLaunch", Qt::QueuedConnection);
});
}
void VolumeButton::wheelEvent(QWheelEvent* event) {
int num_degrees = event->angleDelta().y() / 8;

View File

@@ -201,6 +201,8 @@ private:
Core::PerfStatsResults last_perf_stats{};
Service::AM::FrontendAppletParameters ApplicationAppletParameters();
Service::AM::FrontendAppletParameters LibraryAppletParameters(u64 program_id, Service::AM::AppletId applet_id);
Service::AM::FrontendAppletParameters SystemAppletParameters(u64 program_id, Service::AM::AppletId applet_id);
void SetupHomeMenuCallback();
std::unique_ptr<FileSys::ManualContentProvider> autoloader_provider;
u64 current_title_id{0};
private slots:
@@ -288,6 +290,7 @@ private slots:
void OnCabinet(Service::NFP::CabinetMode mode);
void OnMiiEdit();
void OnOpenControllerMenu();
void OnQLaunch();
void OnCaptureScreenshot();
void OnCheckFirmwareDecryption();
void OnLanguageChanged(const QString& locale);

View File

@@ -176,6 +176,7 @@
<addaction name="action_Install_Firmware"/>
<addaction name="action_Verify_installed_contents"/>
<addaction name="separator"/>
<addaction name="action_Load_Home_Menu"/>
<addaction name="menu_cabinet_applet"/>
<addaction name="action_Load_Album"/>
<addaction name="action_Load_Mii_Edit"/>
@@ -487,6 +488,11 @@
<string>Open &amp;Mii Editor</string>
</property>
</action>
<action name="action_Load_Home_Menu">
<property name="text">
<string>Open &amp;Home Menu</string>
</property>
</action>
<action name="action_Configure_Tas">
<property name="text">
<string>&amp;Configure TAS...</string>