mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 01:34:17 +02:00
Qt/ImGui: Add clipboard support and fix modfier keys
Signed-off-by: SternXD <stern@sidestore.io>
This commit is contained in:
@@ -222,6 +222,11 @@ bool Host::CopyTextToClipboard(const std::string_view text)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Host::GetTextFromClipboard()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void Host::BeginTextInput()
|
||||
{
|
||||
// noop
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace QtHost
|
||||
static void SaveSettings();
|
||||
static void HookSignals();
|
||||
static void RegisterTypes();
|
||||
static void InitializeClipboard();
|
||||
static bool RunSetupWizard();
|
||||
std::optional<bool> DownloadFile(QWidget* parent, const QString& title, std::string url, std::vector<u8>* data);
|
||||
} // namespace QtHost
|
||||
@@ -96,6 +97,8 @@ static bool s_run_setup_wizard = false;
|
||||
static bool s_cleanup_after_update = false;
|
||||
static bool s_boot_and_debug = false;
|
||||
static std::atomic_int s_vm_locked_with_dialog = 0;
|
||||
static std::string s_clipboard_cache;
|
||||
static std::mutex s_clipboard_cache_mutex;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPU Thread
|
||||
@@ -1666,6 +1669,12 @@ bool Host::CopyTextToClipboard(const std::string_view text)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Host::GetTextFromClipboard()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_clipboard_cache_mutex);
|
||||
return s_clipboard_cache;
|
||||
}
|
||||
|
||||
void Host::BeginTextInput()
|
||||
{
|
||||
QInputMethod* method = qApp->inputMethod();
|
||||
@@ -2351,6 +2360,26 @@ void QtHost::RegisterTypes()
|
||||
qRegisterMetaType<Achievements::LoginRequestReason>();
|
||||
}
|
||||
|
||||
void QtHost::InitializeClipboard()
|
||||
{
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
if (clipboard)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_clipboard_cache_mutex);
|
||||
s_clipboard_cache = clipboard->text().toStdString();
|
||||
}
|
||||
QObject::connect(clipboard, &QClipboard::dataChanged, []() {
|
||||
QClipboard* cb = QGuiApplication::clipboard();
|
||||
if (cb)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_clipboard_cache_mutex);
|
||||
s_clipboard_cache = cb->text().toStdString();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool QtHost::RunSetupWizard()
|
||||
{
|
||||
SetupWizardDialog dialog;
|
||||
@@ -2399,6 +2428,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
PCSX2MainApplication app(argc, argv);
|
||||
|
||||
QtHost::InitializeClipboard();
|
||||
|
||||
#ifndef _WIN32
|
||||
if (!PerformEarlyHardwareChecks())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -75,6 +75,9 @@ namespace Host
|
||||
/// Copies the provided text to the host's clipboard, if present.
|
||||
bool CopyTextToClipboard(const std::string_view text);
|
||||
|
||||
/// Returns the current text from the host's clipboard, if present.
|
||||
std::string GetTextFromClipboard();
|
||||
|
||||
/// Requests settings reset. Can be called from any thread, will call back and apply on the CPU thread.
|
||||
bool RequestResetSettings(bool folders, bool core, bool controllers, bool hotkeys, bool ui);
|
||||
|
||||
|
||||
@@ -148,6 +148,17 @@ bool ImGuiManager::Initialize()
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
|
||||
io.KeyRepeatDelay = 0.5f;
|
||||
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext* ctx) -> const char* {
|
||||
static thread_local std::string s_clipboard_text;
|
||||
s_clipboard_text = Host::GetTextFromClipboard();
|
||||
return s_clipboard_text.c_str();
|
||||
};
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext* ctx, const char* text) {
|
||||
if (text)
|
||||
Host::CopyTextToClipboard(text);
|
||||
};
|
||||
|
||||
g.ConfigNavWindowingKeyNext = ImGuiKey_None;
|
||||
g.ConfigNavWindowingKeyPrev = ImGuiKey_None;
|
||||
g.ConfigNavWindowingWithGamepad = false;
|
||||
@@ -398,10 +409,10 @@ void ImGuiManager::SetKeyMap()
|
||||
static constexpr KeyMapping mapping[] = {{ImGuiKey_LeftArrow, "Left"}, {ImGuiKey_RightArrow, "Right"}, {ImGuiKey_UpArrow, "Up"},
|
||||
{ImGuiKey_DownArrow, "Down"}, {ImGuiKey_PageUp, "PageUp"}, {ImGuiKey_PageDown, "PageDown"}, {ImGuiKey_Home, "Home"},
|
||||
{ImGuiKey_End, "End"}, {ImGuiKey_Insert, "Insert"}, {ImGuiKey_Delete, "Delete"}, {ImGuiKey_Backspace, "Backspace"},
|
||||
{ImGuiKey_Space, "Space"}, {ImGuiKey_Enter, "Return"}, {ImGuiKey_Escape, "Escape"}, {ImGuiKey_LeftCtrl, "LeftCtrl", "Ctrl"},
|
||||
{ImGuiKey_LeftShift, "LeftShift", "Shift"}, {ImGuiKey_LeftAlt, "LeftAlt", "Alt"}, {ImGuiKey_LeftSuper, "LeftSuper", "Super"},
|
||||
{ImGuiKey_Space, "Space"}, {ImGuiKey_Enter, "Return"}, {ImGuiKey_Escape, "Escape"}, {ImGuiKey_LeftCtrl, "LeftCtrl", "Control"},
|
||||
{ImGuiKey_LeftShift, "LeftShift", "Shift"}, {ImGuiKey_LeftAlt, "LeftAlt", "Alt"}, {ImGuiKey_LeftSuper, "Meta", "Super_L"},
|
||||
{ImGuiKey_RightCtrl, "RightCtrl"}, {ImGuiKey_RightShift, "RightShift"}, {ImGuiKey_RightAlt, "RightAlt"},
|
||||
{ImGuiKey_RightSuper, "RightSuper"}, {ImGuiKey_Menu, "Menu"}, {ImGuiKey_0, "0"}, {ImGuiKey_1, "1"}, {ImGuiKey_2, "2"},
|
||||
{ImGuiKey_RightSuper, "Super_R"}, {ImGuiKey_Menu, "Menu"}, {ImGuiKey_0, "0"}, {ImGuiKey_1, "1"}, {ImGuiKey_2, "2"},
|
||||
{ImGuiKey_3, "3"}, {ImGuiKey_4, "4"}, {ImGuiKey_5, "5"}, {ImGuiKey_6, "6"}, {ImGuiKey_7, "7"}, {ImGuiKey_8, "8"}, {ImGuiKey_9, "9"},
|
||||
{ImGuiKey_A, "A"}, {ImGuiKey_B, "B"}, {ImGuiKey_C, "C"}, {ImGuiKey_D, "D"}, {ImGuiKey_E, "E"}, {ImGuiKey_F, "F"}, {ImGuiKey_G, "G"},
|
||||
{ImGuiKey_H, "H"}, {ImGuiKey_I, "I"}, {ImGuiKey_J, "J"}, {ImGuiKey_K, "K"}, {ImGuiKey_L, "L"}, {ImGuiKey_M, "M"}, {ImGuiKey_N, "N"},
|
||||
@@ -1122,14 +1133,45 @@ bool ImGuiManager::ProcessPointerAxisEvent(InputBindingKey key, float value)
|
||||
return s_imgui_wants_mouse.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
static ImGuiKey GetModifierForKey(ImGuiKey key)
|
||||
{
|
||||
static constexpr std::pair<ImGuiKey, ImGuiKey> modifier_map[] = {
|
||||
{ImGuiKey_LeftCtrl, ImGuiMod_Ctrl},
|
||||
{ImGuiKey_RightCtrl, ImGuiMod_Ctrl},
|
||||
{ImGuiKey_LeftShift, ImGuiMod_Shift},
|
||||
{ImGuiKey_RightShift, ImGuiMod_Shift},
|
||||
{ImGuiKey_LeftAlt, ImGuiMod_Alt},
|
||||
{ImGuiKey_RightAlt, ImGuiMod_Alt},
|
||||
{ImGuiKey_LeftSuper, ImGuiMod_Super},
|
||||
{ImGuiKey_RightSuper, ImGuiMod_Super},
|
||||
};
|
||||
|
||||
for (const auto& [k, mod] : modifier_map)
|
||||
{
|
||||
if (key == k)
|
||||
return mod;
|
||||
}
|
||||
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
||||
bool ImGuiManager::ProcessHostKeyEvent(InputBindingKey key, float value)
|
||||
{
|
||||
decltype(s_imgui_key_map)::iterator iter;
|
||||
if (!ImGui::GetCurrentContext() || (iter = s_imgui_key_map.find(key.data)) == s_imgui_key_map.end())
|
||||
if (!ImGui::GetCurrentContext())
|
||||
return false;
|
||||
|
||||
const auto iter = s_imgui_key_map.find(key.data);
|
||||
if (iter == s_imgui_key_map.end())
|
||||
return false;
|
||||
|
||||
// still update state anyway
|
||||
MTGS::RunOnGSThread([imkey = iter->second, down = (value != 0.0f)]() { ImGui::GetIO().AddKeyEvent(imkey, down); });
|
||||
MTGS::RunOnGSThread([imkey = iter->second, down = (value != 0.0f)]() {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(imkey, down);
|
||||
|
||||
if (const ImGuiKey mod = GetModifierForKey(imkey); mod != ImGuiKey_None)
|
||||
io.AddKeyEvent(mod, down);
|
||||
});
|
||||
|
||||
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,11 @@ bool Host::CopyTextToClipboard(const std::string_view text)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Host::GetTextFromClipboard()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void Host::BeginTextInput()
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user