mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 01:29:41 +01:00
ImDebugger: Add a soft keyboard toggle, implemented on Android
A "Show Keyboard" button in the menu bar brings up the soft keyboard and keeps it up, typing into the debugger. On Android, NativeSurfaceView acts as a text editor while it's forced, so showSoftInput actually works for it, and passes typed text and key presses on to the native side. Closing the keyboard with Back unticks the toggle. The Misc menu can hide the button (which also turns the keyboard off) and choose whether the keyboard comes back after switching apps. Other platforms can provide an implementation through ImDebugger_SetSoftKeyboardHook. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2d4e633fe6
commit
1c1b7c9f50
5 files changed
+252
No files matched your search
@@ -1,4 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cstring>
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
@@ -86,6 +87,28 @@ static constexpr bool kIsMobilePlatform = true;
|
||||
static constexpr bool kIsMobilePlatform = false;
|
||||
#endif
|
||||
|
||||
// Defined further down (see ImDebugger_SetSoftKeyboardHook).
|
||||
static std::function<void(bool)> g_softKeyboardHook;
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
void Android_SetKeyboardForced(bool forced); // Defined in android/jni/app-android.cpp.
|
||||
void Android_SetKeyboardPersist(bool persist); // Whether the keyboard comes back after an app switch.
|
||||
bool Android_ConsumeAppPaused(); // True once after the app was paused (switched away from).
|
||||
bool Android_ConsumeKeyboardDismissed(); // True once after the user closed the keyboard with Back.
|
||||
#endif
|
||||
|
||||
// Shows or hides the soft keyboard. A hook set through ImDebugger_SetSoftKeyboardHook takes priority; otherwise
|
||||
// Android uses its built-in implementation, and other platforms do nothing.
|
||||
static void ApplySoftKeyboard(bool show) {
|
||||
if (g_softKeyboardHook) {
|
||||
g_softKeyboardHook(show);
|
||||
return;
|
||||
}
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
Android_SetKeyboardForced(show);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShowInMemoryViewerMenuItem(uint32_t addr, ImControl &control) {
|
||||
if (ImGui::BeginMenu("Show in memory viewer")) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -2665,6 +2688,9 @@ ImDebugger::ImDebugger() {
|
||||
}
|
||||
|
||||
ImDebugger::~ImDebugger() {
|
||||
if (keyboardShown_) {
|
||||
ApplySoftKeyboard(false);
|
||||
}
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
@@ -2677,6 +2703,15 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
||||
const CoreState coreState = ::coreState;
|
||||
|
||||
const bool showDebugger = g_Config.bShowImDebugger && PSP_IsInited(); // This will be separated from showing the IM UI in general.
|
||||
// The debugger got hidden some other way (hotkey, settings...): drop the keyboard so it's off when reopened.
|
||||
if (!g_Config.bShowImDebugger && cfg_.forceKeyboard) {
|
||||
cfg_.forceKeyboard = false;
|
||||
if (keyboardShown_) {
|
||||
keyboardShown_ = false;
|
||||
ApplySoftKeyboard(false);
|
||||
}
|
||||
}
|
||||
|
||||
const bool allowSaveStates = !Achievements::HardcoreModeActive() && PSP_IsInited() && (!IsNetworkConnected() || g_Config.bAllowSavestateWhileConnected);
|
||||
|
||||
if (Achievements::HardcoreModeActive()) {
|
||||
@@ -2736,6 +2771,11 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
||||
};
|
||||
auto closeDebugger = [&]() {
|
||||
g_Config.bShowImDebugger = false;
|
||||
cfg_.forceKeyboard = false; // So the keyboard doesn't pop back up when the debugger is reopened.
|
||||
if (keyboardShown_) {
|
||||
keyboardShown_ = false;
|
||||
ApplySoftKeyboard(false);
|
||||
}
|
||||
};
|
||||
|
||||
auto menuFile = [&]() {
|
||||
@@ -3008,6 +3048,8 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
||||
ImGui::MenuItem("Dear ImGui Style editor", nullptr, &cfg_.styleEditorOpen);
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem("Quick scroll bar", nullptr, &cfg_.quickScrollEnabled);
|
||||
ImGui::MenuItem("Show keyboard toggle", nullptr, &cfg_.showKeyboardToggle);
|
||||
ImGui::MenuItem("Keep keyboard after switching apps", nullptr, &cfg_.keyboardPersist);
|
||||
ImGui::MenuItem("Compact menu", nullptr, &cfg_.compactMenu);
|
||||
ImGui::SetNextItemWidth(em * 10.0f);
|
||||
ImGui::SliderInt("Bar left margin", &cfg_.barLeftMargin, 0, 600, "%d%%"); // Percent of the text height.
|
||||
@@ -3077,9 +3119,40 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
||||
break;
|
||||
}
|
||||
|
||||
// Soft keyboard toggle (like the keyboard button in Winlator).
|
||||
if (cfg_.showKeyboardToggle) {
|
||||
ImGui::MenuItem(cfg_.forceKeyboard ? "Hide Keyboard" : "Show Keyboard", nullptr, &cfg_.forceKeyboard);
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
// Force the soft keyboard to show while the debugger is open (the platform side is a hook, see ImDebugger.h).
|
||||
{
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
// If the keyboard shouldn't survive an app switch, turn it off once we've been away.
|
||||
if (Android_ConsumeAppPaused() && !cfg_.keyboardPersist) {
|
||||
cfg_.forceKeyboard = false;
|
||||
}
|
||||
// The keyboard was closed from the system (Back button): keep the toggle in sync.
|
||||
if (Android_ConsumeKeyboardDismissed()) {
|
||||
cfg_.forceKeyboard = false;
|
||||
}
|
||||
const int persist = cfg_.keyboardPersist ? 1 : 0;
|
||||
if (persist != keyboardPersistSent_) {
|
||||
keyboardPersistSent_ = persist;
|
||||
Android_SetKeyboardPersist(persist != 0);
|
||||
}
|
||||
#endif
|
||||
// Hiding the toggle turns the keyboard off too, otherwise there'd be no way to dismiss it.
|
||||
const bool wantKeyboard = cfg_.forceKeyboard && cfg_.showKeyboardToggle && g_Config.bShowImDebugger;
|
||||
if (wantKeyboard != keyboardShown_) {
|
||||
keyboardShown_ = wantKeyboard;
|
||||
ApplySoftKeyboard(wantKeyboard);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cfg_.demoOpen) {
|
||||
ImGui::ShowDemoWindow(&cfg_.demoOpen);
|
||||
}
|
||||
@@ -3314,6 +3387,12 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
||||
}
|
||||
}
|
||||
|
||||
// Platform hook for forcing the soft keyboard. Left empty by default (no-op), so this builds on every platform.
|
||||
// Android: set it from native code to call InputMethodManager.showSoftInput / hideSoftInputFromWindow via the activity.
|
||||
void ImDebugger_SetSoftKeyboardHook(std::function<void(bool show)> hook) {
|
||||
g_softKeyboardHook = std::move(hook);
|
||||
}
|
||||
|
||||
// ---- Quick scroll strip ----
|
||||
|
||||
// The window to scroll, or the nearest parent that actually has something to scroll.
|
||||
@@ -3599,6 +3678,9 @@ void ImConfig::SyncConfig(IniFile *ini, bool save) {
|
||||
sync.Sync("realtimePixelPreview", &realtimePixelPreview, false);
|
||||
sync.Sync("quickScrollEnabled", &quickScrollEnabled, true);
|
||||
sync.Sync("quickScrollCollapsed", &quickScrollCollapsed, false);
|
||||
sync.Sync("forceKeyboard", &forceKeyboard, false);
|
||||
sync.Sync("showKeyboardToggle", &showKeyboardToggle, true);
|
||||
sync.Sync("keyboardPersist", &keyboardPersist, true);
|
||||
sync.Sync("compactMenu", &compactMenu, kIsMobilePlatform);
|
||||
sync.Sync("barLeftMargin", &barLeftMargin, kIsMobilePlatform ? 200 : 0);
|
||||
}
|
||||
Reference in new issue
Block a user