diff --git a/pcsx2-qt/QtHost.cpp b/pcsx2-qt/QtHost.cpp index c29e7ef3e4..5c8226d4fc 100644 --- a/pcsx2-qt/QtHost.cpp +++ b/pcsx2-qt/QtHost.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include "fmt/core.h" @@ -1407,6 +1408,20 @@ bool Host::CopyTextToClipboard(const std::string_view& text) return true; } +void Host::BeginTextInput() +{ + QInputMethod* method = qApp->inputMethod(); + if (method) + QMetaObject::invokeMethod(method, "show", Qt::QueuedConnection); +} + +void Host::EndTextInput() +{ + QInputMethod* method = qApp->inputMethod(); + if (method) + QMetaObject::invokeMethod(method, "hide", Qt::QueuedConnection); +} + void Host::OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name) { emit g_emu_thread->onInputDeviceConnected( diff --git a/pcsx2/Frontend/ImGuiManager.cpp b/pcsx2/Frontend/ImGuiManager.cpp index 4f28134f3f..0bcef0d978 100644 --- a/pcsx2/Frontend/ImGuiManager.cpp +++ b/pcsx2/Frontend/ImGuiManager.cpp @@ -82,6 +82,7 @@ static Common::Timer s_last_render_time; // cached copies of WantCaptureKeyboard/Mouse, used to know when to dispatch events static std::atomic_bool s_imgui_wants_keyboard{false}; static std::atomic_bool s_imgui_wants_mouse{false}; +static std::atomic_bool s_imgui_wants_text{false}; // mapping of host key -> imgui key static std::unordered_map s_imgui_key_map; @@ -225,6 +226,16 @@ void ImGuiManager::NewFrame() ImGui::GetCurrentWindowRead()->Flags |= ImGuiWindowFlags_NoNavInputs; s_imgui_wants_keyboard.store(io.WantCaptureKeyboard, std::memory_order_relaxed); s_imgui_wants_mouse.store(io.WantCaptureMouse, std::memory_order_release); + + const bool want_text_input = io.WantTextInput; + if (s_imgui_wants_text.load(std::memory_order_relaxed) != want_text_input) + { + s_imgui_wants_text.store(want_text_input, std::memory_order_release); + if (want_text_input) + Host::BeginTextInput(); + else + Host::EndTextInput(); + } #endif } @@ -875,12 +886,12 @@ ImFont* ImGuiManager::GetLargeFont() bool ImGuiManager::WantsTextInput() { - return s_imgui_wants_keyboard.load(std::memory_order_acquire); + return s_imgui_wants_text.load(std::memory_order_acquire); } void ImGuiManager::AddTextInput(std::string str) { - if (!s_imgui_wants_keyboard.load(std::memory_order_acquire)) + if (!s_imgui_wants_text.load(std::memory_order_acquire)) return; // Has to go through the CPU -> GS thread :( diff --git a/pcsx2/Frontend/ImGuiManager.h b/pcsx2/Frontend/ImGuiManager.h index c50e7255bf..6dda9453d6 100644 --- a/pcsx2/Frontend/ImGuiManager.h +++ b/pcsx2/Frontend/ImGuiManager.h @@ -90,3 +90,12 @@ namespace ImGuiManager #endif } // namespace ImGuiManager +namespace Host +{ + /// Called by ImGuiManager when the cursor enters a text field. The host may choose to open an on-screen + /// keyboard for devices without a physical keyboard. + void BeginTextInput(); + + /// Called by ImGuiManager when the cursor leaves a text field. + void EndTextInput(); +} \ No newline at end of file