From 9699be211067136779a5a3300878ff00da05fab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 26 Sep 2024 01:09:56 +0200 Subject: [PATCH 1/5] RetroAchievements: Cleanup better on login failure --- Common/System/NativeApp.h | 7 +++++-- Core/RetroAchievements.cpp | 15 +++++++++++++-- UI/NativeApp.cpp | 10 ++++++---- Windows/GEDebugger/VertexPreview.cpp | 1 + headless/Headless.cpp | 4 ++-- libretro/libretro.cpp | 4 ++-- unittest/UnitTest.cpp | 5 +++-- 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Common/System/NativeApp.h b/Common/System/NativeApp.h index 9b69b7f179..3f1a74a6a4 100644 --- a/Common/System/NativeApp.h +++ b/Common/System/NativeApp.h @@ -78,6 +78,9 @@ void NativeShutdown(); void PostLoadConfig(); // Returns false on failure. Shouldn't really happen, though. -bool NativeSaveSecret(const char *nameOfSecret, const std::string &data); +bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data); +inline bool NativeClearSecret(std::string_view nameOfSecret) { + return NativeSaveSecret(nameOfSecret, ""); +} // On failure, returns an empty string. Good enough since any real secret is non-empty. -std::string NativeLoadSecret(const char *nameOfSecret); +std::string NativeLoadSecret(std::string_view nameOfSecret); diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index 7ca969c7fc..7171691871 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -503,8 +503,19 @@ static void login_token_callback(int result, const char *error_message, rc_clien auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS); g_OSD.Show(OSDType::MESSAGE_WARNING, ac->T("Failed logging in to RetroAchievements"), "", g_RAImageID); } + + // Clear the token. + if (result == RC_INVALID_CREDENTIALS || result == RC_EXPIRED_TOKEN) { + g_Config.sAchievementsUserName.clear(); + NativeClearSecret(RA_TOKEN_SECRET_NAME); + g_loginResult = RC_OK; + } else { + g_loginResult = result; + } + OnAchievementsLoginStateChange(); - break; + g_isLoggingIn = false; + return; } } g_loginResult = result; @@ -718,7 +729,7 @@ void Logout() { rc_client_logout(g_rcClient); // remove from config g_Config.sAchievementsUserName.clear(); - NativeSaveSecret(RA_TOKEN_SECRET_NAME, ""); + NativeClearSecret(RA_TOKEN_SECRET_NAME); g_Config.Save("Achievements logout"); g_activeChallenges.clear(); g_loginResult = RC_OK; // Allow trying again diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 377ca7ddb4..96a53ea7ac 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1536,14 +1536,16 @@ void NativeShutdown() { // In the future, we might make this more sophisticated, such as storing in the app private directory on Android. // Right now we just store secrets in separate files next to ppsspp.ini. The important thing is keeping them out of it // since we often ask people to post or send the ini for debugging. -static Path GetSecretPath(const char *nameOfSecret) { +static Path GetSecretPath(std::string_view nameOfSecret) { return GetSysDirectory(DIRECTORY_SYSTEM) / ("ppsspp_" + std::string(nameOfSecret) + ".dat"); } // name should be simple alphanumerics to avoid problems on Windows. -bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { +bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { Path path = GetSecretPath(nameOfSecret); - if (!File::WriteDataToFile(false, data.data(), data.size(), path)) { + if (data.empty() && File::Exists(path)) { + return File::Delete(path); + } else if (!File::WriteDataToFile(false, data.data(), data.size(), path)) { WARN_LOG(Log::System, "Failed to write secret '%s' to path '%s'", nameOfSecret, path.c_str()); return false; } @@ -1551,7 +1553,7 @@ bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { } // On failure, returns an empty string. Good enough since any real secret is non-empty. -std::string NativeLoadSecret(const char *nameOfSecret) { +std::string NativeLoadSecret(std::string_view nameOfSecret) { Path path = GetSecretPath(nameOfSecret); std::string data; if (!File::ReadBinaryFileToString(path, &data)) { diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index f508037f49..bc2a69b4ee 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -348,6 +348,7 @@ void CGEDebugger::UpdatePrimPreview(u32 op, int which) { u16 minIndex = 0; u16 maxIndex = count - 1; if (!indices.empty()) { + _dbg_assert_(count <= indices.size()); minIndex = 0xFFFF; maxIndex = 0; for (int i = 0; i < count; ++i) { diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 59be04616f..20a3359790 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -142,8 +142,8 @@ void System_AudioClear() {} void System_AudioPushSamples(const s32 *audio, int numSamples) {} // TODO: To avoid having to define these here, these should probably be turned into system "requests". -bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { return false; } -std::string NativeLoadSecret(const char *nameOfSecret) { +bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; } +std::string NativeLoadSecret(std::string_view nameOfSecret) { return ""; } diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 11007d5c5d..c24f1e43d0 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1962,7 +1962,7 @@ bool System_AudioRecordingState() { return false; } #endif // TODO: To avoid having to define these here, these should probably be turned into system "requests". -bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { return false; } -std::string NativeLoadSecret(const char *nameOfSecret) { +bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; } +std::string NativeLoadSecret(std::string_view nameOfSecret) { return ""; } diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index b68e5e43ae..2502bb235d 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -108,8 +108,9 @@ void System_AudioClear() {} void System_AudioPushSamples(const s32 *audio, int numSamples) {} // TODO: To avoid having to define these here, these should probably be turned into system "requests". -bool NativeSaveSecret(const char *nameOfSecret, const std::string &data) { return false; } -std::string NativeLoadSecret(const char *nameOfSecret) { +// To clear the secret entirely, just save an empty string. +bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; } +std::string NativeLoadSecret(std::string_view nameOfSecret) { return ""; } From f020d1d8150084578530712e0508df55537d9b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 26 Sep 2024 10:48:31 +0200 Subject: [PATCH 2/5] Windows inputbox: Add flags field, delete dupe code, add ability to mask passwords --- Common/System/Request.h | 4 +- Common/UI/PopupScreens.cpp | 2 +- Core/Dialog/PSPOskDialog.cpp | 2 +- SDL/SDLMain.cpp | 3 +- UI/ChatScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 14 +- UI/MainScreen.cpp | 4 +- UI/RetroAchievementScreens.cpp | 2 +- UI/SavedataScreen.cpp | 2 +- Windows/Debugger/CtrlDisAsmView.cpp | 15 +- Windows/Debugger/DebuggerShared.cpp | 4 +- Windows/GEDebugger/CtrlDisplayListView.cpp | 2 +- Windows/InputBox.cpp | 152 +++++++++------------ Windows/InputBox.h | 12 +- Windows/main.cpp | 9 +- android/jni/app-android.cpp | 1 + 16 files changed, 109 insertions(+), 121 deletions(-) diff --git a/Common/System/Request.h b/Common/System/Request.h index c7947f0c6e..b16fc43f97 100644 --- a/Common/System/Request.h +++ b/Common/System/Request.h @@ -84,8 +84,8 @@ extern RequestManager g_requestManager; // Wrappers for easy requests. // NOTE: Semantics have changed - this no longer calls the callback on cancellation, instead you // can specify a different callback for that. -inline void System_InputBoxGetString(RequesterToken token, std::string_view title, std::string_view defaultValue, RequestCallback callback, RequestFailedCallback failedCallback = nullptr) { - g_requestManager.MakeSystemRequest(SystemRequestType::INPUT_TEXT_MODAL, token, callback, failedCallback, title, defaultValue, 0); +inline void System_InputBoxGetString(RequesterToken token, std::string_view title, std::string_view defaultValue, bool passwordMasking, RequestCallback callback, RequestFailedCallback failedCallback = nullptr) { + g_requestManager.MakeSystemRequest(SystemRequestType::INPUT_TEXT_MODAL, token, callback, failedCallback, title, defaultValue, passwordMasking ? 1 : 0); } // This one will pop up a special image browser if available. You can also pick diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index a8715591d1..acc9c90372 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -528,7 +528,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) { // Choose method depending on platform capabilities. if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { - System_InputBoxGetString(token_, text_, *value_ , [=](const std::string &enteredValue, int) { + System_InputBoxGetString(token_, text_, *value_, passwordDisplay_, [=](const std::string &enteredValue, int) { *value_ = StripSpaces(enteredValue); EventParams params{}; OnChange.Trigger(params); diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 2ce00f4f48..67ddd5453a 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -897,7 +897,7 @@ int PSPOskDialog::NativeKeyboard() { defaultText.assign(u"VALUE"); // There's already ConvertUCS2ToUTF8 in this file. Should we use that instead of the global ones? - System_InputBoxGetString(NON_EPHEMERAL_TOKEN, ::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), + System_InputBoxGetString(NON_EPHEMERAL_TOKEN, ::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), false, [&](const std::string &value, int) { // Success callback std::lock_guard guard(nativeMutex_); diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 53a2160440..9087f062b4 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -234,7 +234,8 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string g_QuitRequested = true; return true; #if PPSSPP_PLATFORM(SWITCH) - case SystemRequestType::INPUT_TEXT_MODAL: { + case SystemRequestType::INPUT_TEXT_MODAL: + { // swkbd only works on "real" titles if (__nx_applet_type != AppletType_Application && __nx_applet_type != AppletType_SystemApplication) { g_requestManager.PostSystemFailure(requestId); diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 6cafc63a05..7c0a107719 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -180,7 +180,7 @@ void ChatMenu::Update() { // Could remove the fullscreen check here, it works now. auto n = GetI18NCategory(I18NCat::NETWORKING); if (promptInput_ && g_Config.bBypassOSKWithKeyboard && !g_Config.UseFullScreen()) { - System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), [](const std::string &value, int) { + System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), false, [](const std::string &value, int) { sendChat(value); }); promptInput_ = false; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 0199a7d2d7..aefbce2bf8 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1648,7 +1648,7 @@ UI::EventReturn GameSettingsScreen::OnAudioDevice(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, [](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, false, [](const std::string &value, int) { g_Config.sQuickChat0 = value; }); #endif @@ -1658,7 +1658,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, [](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, false, [](const std::string &value, int) { g_Config.sQuickChat1 = value; }); #endif @@ -1668,7 +1668,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, [](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, false, [](const std::string &value, int) { g_Config.sQuickChat2 = value; }); #endif @@ -1678,7 +1678,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, [](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, false, [](const std::string &value, int) { g_Config.sQuickChat3 = value; }); #endif @@ -1688,7 +1688,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, [](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, false, [](const std::string &value, int) { g_Config.sQuickChat4 = value; }); #endif @@ -1698,7 +1698,7 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnChangeNickname(UI::EventParams &e) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter a new PSP nickname"), g_Config.sNickName, [](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("Enter a new PSP nickname"), g_Config.sNickName, false, [](const std::string &value, int) { g_Config.sNickName = StripSpaces(value); }); #endif @@ -2325,7 +2325,7 @@ UI::EventReturn HostnameSelectScreen::OnDeleteAllClick(UI::EventParams &e) { UI::EventReturn HostnameSelectScreen::OnEditClick(UI::EventParams& e) { auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("proAdhocServer Address:"), addrView_->GetText(), [this](const std::string& value, int) { + System_InputBoxGetString(GetRequesterToken(), n->T("proAdhocServer Address:"), addrView_->GetText(), false, [this](const std::string& value, int) { addrView_->SetText(value); }); return UI::EVENT_DONE; diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index e38d5d3ccb..a4294c12b5 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -798,7 +798,7 @@ void GameBrowser::Refresh() { if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_TV) { topBar->Add(new Choice(mm->T("Enter Path"), new LayoutParams(WRAP_CONTENT, 64.0f)))->OnClick.Add([=](UI::EventParams &) { auto mm = GetI18NCategory(I18NCat::MAINMENU); - System_InputBoxGetString(token_, mm->T("Enter Path"), path_.GetPath().ToString(), [=](const char *responseString, int responseValue) { + System_InputBoxGetString(token_, mm->T("Enter Path"), path_.GetPath().ToString(), false, [=](const char *responseString, int responseValue) { this->SetPath(Path(responseString)); }); return UI::EVENT_DONE; @@ -1358,7 +1358,7 @@ bool MainScreen::key(const KeyInput &touch) { searchKeyModifier_ = true; if (touch.keyCode == NKCODE_F && searchKeyModifier_ && System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { auto se = GetI18NCategory(I18NCat::SEARCH); - System_InputBoxGetString(GetRequesterToken(), se->T("Search term"), searchFilter_, [&](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), se->T("Search term"), searchFilter_, false, [&](const std::string &value, int) { searchFilter_ = StripSpaces(value); searchChanged_ = true; }); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index d7022ef567..810d6757e0 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -296,7 +296,7 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) Achievements::Logout(); return UI::EVENT_DONE; }); - } else if (System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) { + } else if (false && System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) { viewGroup->Add(new Choice(di->T("Log in")))->OnClick.Add([=](UI::EventParams &) -> UI::EventReturn { std::string title = StringFromFormat("RetroAchievements: %s", di->T_cstr("Log in")); System_AskUsernamePassword(GetRequesterToken(), title, [](const std::string &value, int) { diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 4c8162d4f1..3f349adfb0 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -670,7 +670,7 @@ UI::EventReturn SavedataScreen::OnSortClick(UI::EventParams &e) { UI::EventReturn SavedataScreen::OnSearch(UI::EventParams &e) { if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { auto di = GetI18NCategory(I18NCat::DIALOG); - System_InputBoxGetString(GetRequesterToken(), di->T("Filter"), searchFilter_, [](const std::string &value, int ivalue) { + System_InputBoxGetString(GetRequesterToken(), di->T("Filter"), searchFilter_, false, [](const std::string &value, int ivalue) { System_PostUIMessage(UIMessage::SAVEDATA_SEARCH, value); }); } diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 6ba46c4dc5..7f9d2a2dbd 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -280,21 +280,22 @@ std::string trimString(std::string input) void CtrlDisAsmView::assembleOpcode(u32 address, const std::string &defaultText) { auto memLock = Memory::Lock(); - if (Core_IsStepping() == false) { + if (!Core_IsStepping()) { MessageBox(wnd,L"Cannot change code while the core is running!",L"Error",MB_OK); return; } std::string op; - bool result = InputBox_GetString(MainWindow::GetHInstance(),wnd,L"Assemble opcode",defaultText, op, false); - if (!result) + bool result = InputBox_GetString(MainWindow::GetHInstance(), wnd, L"Assemble opcode", defaultText, op, InputBoxFlags::Default); + if (!result) { return; + } // check if it changes registers first - auto seperator = op.find('='); - if (seperator != std::string::npos) + auto separator = op.find('='); + if (separator != std::string::npos) { - std::string registerName = trimString(op.substr(0,seperator)); - std::string expression = trimString(op.substr(seperator+1)); + std::string registerName = trimString(op.substr(0,separator)); + std::string expression = trimString(op.substr(separator+1)); u32 value; if (parseExpression(expression.c_str(),debugger,value) == true) diff --git a/Windows/Debugger/DebuggerShared.cpp b/Windows/Debugger/DebuggerShared.cpp index 9f3bc64313..35bdfe2cb5 100644 --- a/Windows/Debugger/DebuggerShared.cpp +++ b/Windows/Debugger/DebuggerShared.cpp @@ -18,7 +18,7 @@ void displayExpressionError(HWND hwnd) bool executeExpressionWindow(HWND hwnd, DebugInterface* cpu, u32& dest) { std::string expression; - if (InputBox_GetString(GetModuleHandle(NULL), hwnd, L"Expression", "",expression) == false) + if (InputBox_GetString(GetModuleHandle(NULL), hwnd, L"Expression", "", expression) == false) { return false; } @@ -30,4 +30,4 @@ bool executeExpressionWindow(HWND hwnd, DebugInterface* cpu, u32& dest) } return true; -} \ No newline at end of file +} diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 2d9e64239d..cc859ee41c 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -397,7 +397,7 @@ void CtrlDisplayListView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) case ID_GEDBG_GOTOADDR: { std::string expression = StringFromFormat("%08x", curAddress); - if (!InputBox_GetString(GetModuleHandle(NULL), wnd, L"Address", expression, expression, true)) { + if (!InputBox_GetString(GetModuleHandle(NULL), wnd, L"Address", expression, expression, InputBoxFlags::Selected)) { break; } uint32_t newAddress = curAddress; diff --git a/Windows/InputBox.cpp b/Windows/InputBox.cpp index 49cb2eb4e2..4c760585da 100644 --- a/Windows/InputBox.cpp +++ b/Windows/InputBox.cpp @@ -6,31 +6,45 @@ #include "Windows/W32Util/Misc.h" #include "Common/Data/Encoding/Utf8.h" -static std::wstring textBoxContents; -static std::wstring passwordContents; -static std::wstring out; -static std::wstring windowTitle; -static bool defaultSelected; -static std::string g_userName; -static std::string g_passWord; +struct DialogBoxParams { + std::wstring textBoxContents; + std::wstring passwordContents; + std::wstring out; + std::wstring windowTitle; + bool defaultSelected; + bool passwordMasking; + std::string userName; + std::string passWord; +}; + +static DialogBoxParams g_params; static INT_PTR CALLBACK InputBoxFunc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: - SetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), textBoxContents.c_str()); - SetWindowText(hDlg, windowTitle.c_str()); - if (defaultSelected == false) - PostMessage(GetDlgItem(hDlg,IDC_INPUTBOX),EM_SETSEL,-1,-1); + { + HWND hwndTextBox = GetDlgItem(hDlg, IDC_INPUTBOX); + SetWindowText(hwndTextBox, g_params.textBoxContents.c_str()); + SetWindowText(hDlg, g_params.windowTitle.c_str()); + if (!g_params.defaultSelected) { + PostMessage(hwndTextBox, EM_SETSEL, -1, -1); + } + if (g_params.passwordMasking) { + LONG_PTR style = GetWindowLongPtr(hwndTextBox, GWL_STYLE); + SetWindowLongPtr(hwndTextBox, GWL_STYLE, style | ES_PASSWORD); + SendMessage(hwndTextBox, EM_SETPASSWORDCHAR, (WPARAM)'*', 0); + } W32Util::CenterWindow(hDlg); return TRUE; + } case WM_COMMAND: switch (wParam) { case IDOK: { wchar_t temp[512]; - GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, ARRAY_SIZE(temp) - 1); - out = temp; + GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, ARRAY_SIZE(temp)); + g_params.out = temp; EndDialog(hDlg, IDOK); return TRUE; } @@ -45,97 +59,55 @@ static INT_PTR CALLBACK InputBoxFunc(HWND hDlg, UINT message, WPARAM wParam, LPA } } -bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue, bool selected) -{ - defaultSelected = selected; - if (defaultValue.size() < 255) - textBoxContents = ConvertUTF8ToWString(defaultValue); - else - textBoxContents.clear(); - - if (title != NULL) - windowTitle = title; - else - windowTitle.clear(); - - if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) { - outvalue = ConvertWStringToUTF8(out); - return true; - } - else - return false; -} - -bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue) -{ +bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultValue, std::string &outvalue, InputBoxFlags flags) { const wchar_t *defaultTitle = L"Input value"; - defaultSelected = true; - textBoxContents = ConvertUTF8ToWString(defaultValue); + g_params.defaultSelected = flags & InputBoxFlags::Selected; + g_params.passwordMasking = flags & InputBoxFlags::PasswordMasking; + if (defaultValue.size() < 255) { + g_params.textBoxContents = ConvertUTF8ToWString(defaultValue); + } else { + g_params.textBoxContents.clear(); + } - if (title && wcslen(title) <= 0) - windowTitle = defaultTitle; - else if (title && wcslen(title) < 255) - windowTitle = title; - else - windowTitle = defaultTitle; + if (title && wcslen(title) <= 0) { + g_params.windowTitle = defaultTitle; + } else if (title && wcslen(title) < 255) { + g_params.windowTitle = title; + } else { + g_params.windowTitle = defaultTitle; + } if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) { - outvalue = ConvertWStringToUTF8(out); + outvalue = ConvertWStringToUTF8(g_params.out); return true; - } - else + } else { return false; + } } -bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultValue, std::wstring &outvalue) -{ - const wchar_t *defaultTitle = L"Input value"; - defaultSelected = true; - - textBoxContents = defaultValue; - - if (title && wcslen(title) <= 0) - windowTitle = defaultTitle; - else if (title && wcslen(title) < 255) - windowTitle = title; - else - windowTitle = defaultTitle; - - if (IDOK == DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc)) { - outvalue = out; - return true; - } - else - return false; -} - -bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t* title, u32 defaultvalue, u32& outvalue) -{ +bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t* title, u32 defaultvalue, u32 &outvalue) { const wchar_t *defaultTitle = L"Input value"; wchar_t temp[256]; wsprintf(temp, L"%08x", defaultvalue); - textBoxContents = temp; + g_params.textBoxContents = temp; if (title && wcslen(title) <= 0) - windowTitle = defaultTitle; + g_params.windowTitle = defaultTitle; else if (title && wcslen(title) < 255) - windowTitle = title; + g_params.windowTitle = title; else - windowTitle = defaultTitle; + g_params.windowTitle = defaultTitle; INT_PTR value = DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc); - if (value == IDOK) - { - if (swscanf(out.c_str(), L"0x%08x", &outvalue) == 1) + if (value == IDOK) { + if (swscanf(g_params.out.c_str(), L"0x%08x", &outvalue) == 1) return true; - if (swscanf(out.c_str(), L"%08x", &outvalue) == 1) + if (swscanf(g_params.out.c_str(), L"%08x", &outvalue) == 1) return true; return false; - } - else - { + } else { outvalue = 0; return false; } @@ -147,7 +119,7 @@ static INT_PTR CALLBACK UserPasswordBoxFunc(HWND hDlg, UINT message, WPARAM wPar case WM_INITDIALOG: SetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), L""); SetWindowText(GetDlgItem(hDlg, IDC_PASSWORDBOX), L""); - SetWindowText(hDlg, windowTitle.c_str()); + SetWindowText(hDlg, g_params.windowTitle.c_str()); PostMessage(GetDlgItem(hDlg, IDC_INPUTBOX), EM_SETSEL, -1, -1); PostMessage(GetDlgItem(hDlg, IDC_PASSWORDBOX), EM_SETSEL, -1, -1); W32Util::CenterWindow(hDlg); @@ -158,10 +130,10 @@ static INT_PTR CALLBACK UserPasswordBoxFunc(HWND hDlg, UINT message, WPARAM wPar case IDOK: { wchar_t temp[256]; - GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, 255); - g_userName = ConvertWStringToUTF8(temp); - GetWindowText(GetDlgItem(hDlg, IDC_PASSWORDBOX), temp, 255); - g_passWord = ConvertWStringToUTF8(temp); + GetWindowText(GetDlgItem(hDlg, IDC_INPUTBOX), temp, sizeof(temp)); + g_params.userName = ConvertWStringToUTF8(temp); + GetWindowText(GetDlgItem(hDlg, IDC_PASSWORDBOX), temp, sizeof(temp)); + g_params.passWord = ConvertWStringToUTF8(temp); EndDialog(hDlg, IDOK); return TRUE; } @@ -177,12 +149,12 @@ static INT_PTR CALLBACK UserPasswordBoxFunc(HWND hDlg, UINT message, WPARAM wPar } bool UserPasswordBox_GetStrings(HINSTANCE hInst, HWND hParent, const wchar_t *title, std::string *username, std::string *password) { - windowTitle = title; + g_params.windowTitle = title; INT_PTR value = DialogBox(hInst, (LPCWSTR)IDD_USERPASSWORDBOX, hParent, UserPasswordBoxFunc); if (value == IDOK) { - *username = g_userName; - *password = g_passWord; + *username = g_params.userName; + *password = g_params.passWord; return true; } else { return false; diff --git a/Windows/InputBox.h b/Windows/InputBox.h index 4617b1323d..9f5a805a98 100644 --- a/Windows/InputBox.h +++ b/Windows/InputBox.h @@ -2,11 +2,17 @@ #include #include "Common/CommonWindows.h" +#include "Common/Common.h" + +enum class InputBoxFlags { + Default = 0, + Selected = 1, + PasswordMasking = 2, +}; +ENUM_CLASS_BITOPS(InputBoxFlags); // All I/O is in UTF-8 -bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue, bool selected); -bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue); -bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue); +bool InputBox_GetString(HINSTANCE hInst, HWND hParent, const wchar_t *title, const std::string &defaultvalue, std::string &outvalue, InputBoxFlags flags = InputBoxFlags::Default); bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue); bool UserPasswordBox_GetStrings(HINSTANCE hInst, HWND hParent, const wchar_t *title, std::string *username, std::string *password); diff --git a/Windows/main.cpp b/Windows/main.cpp index cfd7d987e9..57e13bb7de 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -540,7 +540,14 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string case SystemRequestType::INPUT_TEXT_MODAL: std::thread([=] { std::string out; - if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(param1).c_str(), param2, out)) { + InputBoxFlags flags{}; + if (param3) { + flags |= InputBoxFlags::PasswordMasking; + } + if (!param2.empty()) { + flags |= InputBoxFlags::Selected; + } + if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(param1).c_str(), param2, out, flags)) { g_requestManager.PostSystemSuccess(requestId, out.c_str()); } else { g_requestManager.PostSystemFailure(requestId); diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 1011e599c5..1f5ca52f92 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -1120,6 +1120,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string PushCommand("copy_to_clipboard", param1); return true; case SystemRequestType::INPUT_TEXT_MODAL: + case SystemRequestType::INPUT_PASSWORD_MODAL: { std::string serialized = StringFromFormat("%d:@:%s:@:%s", requestId, param1.c_str(), param2.c_str()); PushCommand("inputbox", serialized.c_str()); From 1b158940ac8107981f90f43c4543effa7b691c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 26 Sep 2024 10:58:58 +0200 Subject: [PATCH 3/5] PPSSPP UI: Implement password masking in popup text inputs --- Common/UI/PopupScreens.cpp | 6 ++++-- Common/UI/PopupScreens.h | 5 +++++ Common/UI/View.cpp | 11 +++++++++-- Common/UI/View.h | 8 ++++++-- UI/ChatScreen.cpp | 2 +- UI/NativeApp.cpp | 2 +- UI/RetroAchievementScreens.cpp | 2 +- android/jni/app-android.cpp | 1 - 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index acc9c90372..02c2fd1856 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -528,7 +528,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) { // Choose method depending on platform capabilities. if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) { - System_InputBoxGetString(token_, text_, *value_, passwordDisplay_, [=](const std::string &enteredValue, int) { + System_InputBoxGetString(token_, text_, *value_, passwordMasking_, [=](const std::string &enteredValue, int) { *value_ = StripSpaces(enteredValue); EventParams params{}; OnChange.Trigger(params); @@ -537,6 +537,7 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) { } TextEditPopupScreen *popupScreen = new TextEditPopupScreen(value_, placeHolder_, ChopTitle(text_), maxLen_); + popupScreen->SetPasswordMasking(passwordMasking_); if (System_GetPropertyBool(SYSPROP_KEYBOARD_IS_SOFT)) { popupScreen->SetAlignTop(true); } @@ -570,6 +571,7 @@ void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { edit_ = new TextEdit(textEditValue_, Title(), placeholder_, new LinearLayoutParams(1.0f)); edit_->SetMaxLen(maxLen_); edit_->SetTextColor(dc.theme->popupStyle.fgColor); + edit_->SetPasswordMasking(passwordMasking_); lin->Add(edit_); UI::SetFocusedView(edit_); @@ -628,7 +630,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) { std::string valueText = ValueText(); - if (passwordDisplay_) { + if (passwordMasking_) { // Replace all characters with stars. memset(&valueText[0], '*', valueText.size()); } diff --git a/Common/UI/PopupScreens.h b/Common/UI/PopupScreens.h index 1eab264abf..73d130eda8 100644 --- a/Common/UI/PopupScreens.h +++ b/Common/UI/PopupScreens.h @@ -150,6 +150,10 @@ public: const char *tag() const override { return "TextEditPopup"; } + void SetPasswordMasking(bool masking) { + passwordMasking_ = masking; + } + Event OnChange; private: @@ -159,6 +163,7 @@ private: std::string textEditValue_; std::string placeholder_; int maxLen_; + bool passwordMasking_ = false; }; struct ContextMenuItem { diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 8075c4cdae..7a65c477ee 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -1142,18 +1142,25 @@ void TextEdit::Draw(UIContext &dc) { Bounds textBounds = bounds_; textBounds.x = textX - scrollPos_; + std::string textToDisplay = text_; + if (passwordMasking_) { + for (int i = 0; i < textToDisplay.size(); i++) { + textToDisplay[i] = '*'; + } + } + if (text_.empty()) { if (placeholderText_.size()) { uint32_t c = textColor & 0x50FFFFFF; dc.DrawTextRect(placeholderText_, bounds_, c, ALIGN_CENTER); } } else { - dc.DrawTextRect(text_, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_); + dc.DrawTextRect(textToDisplay, textBounds, textColor, ALIGN_VCENTER | ALIGN_LEFT | align_); } if (HasFocus()) { // Hack to find the caret position. Might want to find a better way... - dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_); + dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, textToDisplay.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_); float caretX = w - scrollPos_; if (caretX > bounds_.w) { scrollPos_ += caretX - bounds_.w; diff --git a/Common/UI/View.h b/Common/UI/View.h index e38c0fc819..814735d57f 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -825,14 +825,14 @@ public: void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; void SetPasswordDisplay() { - passwordDisplay_ = true; + passwordMasking_ = true; } protected: virtual std::string ValueText() const = 0; float CalculateValueScale(const UIContext &dc, std::string_view valueText, float availWidth) const; - bool passwordDisplay_ = false; + bool passwordMasking_ = false; }; class ChoiceWithCallbackValueDisplay : public AbstractChoiceWithValueDisplay { @@ -1026,6 +1026,9 @@ public: const std::string &GetText() const { return text_; } void SetMaxLen(size_t maxLen) { maxLen_ = maxLen; } void SetTextAlign(int align) { align_ = align; } // Only really useful for setting FLAG_DYNAMIC_ASCII + void SetPasswordMasking(bool masking) { + passwordMasking_ = masking; + } void FocusChanged(int focusFlags) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; @@ -1050,6 +1053,7 @@ private: int scrollPos_ = 0; size_t maxLen_; bool ctrlDown_ = false; // TODO: Make some global mechanism for this. + bool passwordMasking_ = false; int align_ = 0; // TODO: Selections }; diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 7c0a107719..3445767c77 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -97,7 +97,7 @@ UI::EventReturn ChatMenu::OnSubmit(UI::EventParams &e) { sendChat(chat); #elif PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) || PPSSPP_PLATFORM(IOS) auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(token_, n->T("Chat"), "", [](const std::string &value, int) { + System_InputBoxGetString(token_, n->T("Chat"), "", false, [](const std::string &value, int) { sendChat(value); }); #endif diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 96a53ea7ac..272ff35e16 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1546,7 +1546,7 @@ bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { if (data.empty() && File::Exists(path)) { return File::Delete(path); } else if (!File::WriteDataToFile(false, data.data(), data.size(), path)) { - WARN_LOG(Log::System, "Failed to write secret '%s' to path '%s'", nameOfSecret, path.c_str()); + WARN_LOG(Log::System, "Failed to write secret '%.*s' to path '%s'", (int)nameOfSecret.size(), nameOfSecret.data(), path.c_str()); return false; } return true; diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index 810d6757e0..d7022ef567 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -296,7 +296,7 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup) Achievements::Logout(); return UI::EVENT_DONE; }); - } else if (false && System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) { + } else if (System_GetPropertyBool(SYSPROP_HAS_LOGIN_DIALOG)) { viewGroup->Add(new Choice(di->T("Log in")))->OnClick.Add([=](UI::EventParams &) -> UI::EventReturn { std::string title = StringFromFormat("RetroAchievements: %s", di->T_cstr("Log in")); System_AskUsernamePassword(GetRequesterToken(), title, [](const std::string &value, int) { diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 1f5ca52f92..1011e599c5 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -1120,7 +1120,6 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string PushCommand("copy_to_clipboard", param1); return true; case SystemRequestType::INPUT_TEXT_MODAL: - case SystemRequestType::INPUT_PASSWORD_MODAL: { std::string serialized = StringFromFormat("%d:@:%s:@:%s", requestId, param1.c_str(), param2.c_str()); PushCommand("inputbox", serialized.c_str()); From 50baf6f8e3c9e0072836e0a69de0f03aee7f903d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 26 Sep 2024 12:02:18 +0200 Subject: [PATCH 4/5] Fix display of game titles, oops --- UI/MainScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index a4294c12b5..fb06e42c27 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -344,7 +344,7 @@ void GameButton::Draw(UIContext &dc) { dc.PushScissor(bounds_); const std::string currentTitle = ginfo->GetTitle(); if (!currentTitle.empty()) { - title_ = ReplaceAll(title_, "\n", " "); + title_ = ReplaceAll(currentTitle, "\n", " "); } dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, title_, &tw, &th, 0); From 66993c8ff26df8357799a4c395c22175b7f4bb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 26 Sep 2024 12:04:29 +0200 Subject: [PATCH 5/5] Android buildfix, warning fix --- UI/InstallZipScreen.cpp | 2 +- UI/MemStickScreen.cpp | 2 +- UI/SavedataScreen.cpp | 6 +++--- UI/SavedataScreen.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 30d4605619..2bd609d769 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -237,7 +237,7 @@ void InstallZipScreen::update() { if (existingSaveView_) { std::shared_ptr ginfo = g_gameInfoCache->GetInfo(screenManager()->getDrawContext(), savedataToOverwrite_, GameInfoFlags::FILE_TYPE | GameInfoFlags::PARAM_SFO | GameInfoFlags::ICON | GameInfoFlags::SIZE); - existingSaveView_->Update(ginfo.get()); + existingSaveView_->UpdateGame(ginfo.get()); } UIDialogScreenWithBackground::update(); } diff --git a/UI/MemStickScreen.cpp b/UI/MemStickScreen.cpp index 173206695d..5703238117 100644 --- a/UI/MemStickScreen.cpp +++ b/UI/MemStickScreen.cpp @@ -305,7 +305,7 @@ UI::EventReturn MemStickScreen::SetFolderManually(UI::EventParams ¶ms) { // The old way, from before scoped storage. Write in the full path. #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(SWITCH) auto sy = GetI18NCategory(I18NCat::SYSTEM); - System_InputBoxGetString(GetRequesterToken(), sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), [&](const std::string &value, int) { + System_InputBoxGetString(GetRequesterToken(), sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), false, [&](const std::string &value, int) { auto sy = GetI18NCategory(I18NCat::SYSTEM); auto di = GetI18NCategory(I18NCat::DIALOG); diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 3f349adfb0..7d193b8b66 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -92,7 +92,7 @@ SavedataView::SavedataView(UIContext &dc, const Path &savePath, IdentifiedFileTy } } -void SavedataView::Update(GameInfo *ginfo) { +void SavedataView::UpdateGame(GameInfo *ginfo) { if (!ginfo->Ready(GameInfoFlags::PARAM_SFO | GameInfoFlags::SIZE)) { return; } @@ -123,7 +123,7 @@ SavedataView::SavedataView(UIContext &dc, GameInfo *ginfo, IdentifiedFileType ty showIcon, layoutParams) { if (ginfo) { - Update(ginfo); + UpdateGame(ginfo); } } @@ -140,7 +140,7 @@ public: return; } if (savedataView_) { - savedataView_->Update(ginfo.get()); + savedataView_->UpdateGame(ginfo.get()); } } diff --git a/UI/SavedataScreen.h b/UI/SavedataScreen.h index 5980f370c8..9daae76c41 100644 --- a/UI/SavedataScreen.h +++ b/UI/SavedataScreen.h @@ -152,7 +152,7 @@ public: SavedataView(UIContext &dc, GameInfo *ginfo, IdentifiedFileType type, bool showIcon, UI::LayoutParams *layoutParams = nullptr); SavedataView(UIContext &dc, const Path &savePath, IdentifiedFileType type, std::string_view title, std::string_view savedataTitle, std::string_view savedataDetail, std::string_view fileSize, std::string_view mtime, bool showIcon, UI::LayoutParams *layoutParams = nullptr); - void Update(GameInfo *ginfo); + void UpdateGame(GameInfo *ginfo); private: UI::TextView *savedataTitle_ = nullptr; UI::TextView *detail_ = nullptr;