diff options
| author | JS Deck <jsdeckerido@gmail.com> | 2025-08-04 16:29:39 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-04 21:29:39 +0200 |
| commit | 2be309de1df5e4262175fbcc58e6dd8de4e0e6d3 (patch) | |
| tree | 866629ba5a4b9b45d8720383e4332726444f3566 /src/managers/input/InputManager.cpp | |
| parent | 6491bb4fb7c7e86d9168a104d5b87ace4e1b978d (diff) | |
virtualkeyboard: Add options to skip releasing pressed keys on close and to skip sharing key states (#11214)
Diffstat (limited to 'src/managers/input/InputManager.cpp')
| -rw-r--r-- | src/managers/input/InputManager.cpp | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 6c23c493..cbb4c3cc 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -39,6 +39,7 @@ #include "../../managers/permissions/DynamicPermissionManager.hpp" #include "../../helpers/time/Time.hpp" +#include "../../helpers/MiscFunctions.hpp" #include <aquamarine/input/Input.hpp> @@ -931,6 +932,14 @@ Vector2D CInputManager::getMouseCoordsInternal() { return g_pPointerManager->position(); } +void CInputManager::newKeyboard(SP<IKeyboard> keeb) { + const auto PNEWKEYBOARD = m_keyboards.emplace_back(keeb); + + setupKeyboard(PNEWKEYBOARD); + + Debug::log(LOG, "New keyboard created, pointers Hypr: {:x}", (uintptr_t)PNEWKEYBOARD.get()); +} + void CInputManager::newKeyboard(SP<Aquamarine::IKeyboard> keyboard) { const auto PNEWKEYBOARD = m_keyboards.emplace_back(CKeyboard::create(keyboard)); @@ -1398,18 +1407,36 @@ void CInputManager::onKeyboardKey(const IKeyboard::SKeyEvent& event, SP<IKeyboar const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard); + const auto IME = m_relay.m_inputMethod.lock(); + const bool HASIME = IME && IME->hasGrab(); + const bool USEIME = HASIME && !DISALLOWACTION; + const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", event}}; EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP); - bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(event, pKeyboard); + bool passEvent = DISALLOWACTION; - if (passEvent) { - const auto IME = m_relay.m_inputMethod.lock(); + if (!DISALLOWACTION) + passEvent = g_pKeybindManager->onKeyEvent(event, pKeyboard); - if (IME && IME->hasGrab() && !DISALLOWACTION) { + if (passEvent) { + if (USEIME) { IME->setKeyboard(pKeyboard); IME->sendKey(event.timeMs, event.keycode, event.state); } else { + const auto PRESSED = shareKeyFromAllKBs(event.keycode, event.state == WL_KEYBOARD_KEY_STATE_PRESSED); + const auto CONTAINS = std::ranges::contains(m_pressed, event.keycode); + + if (CONTAINS && PRESSED) + return; + if (!CONTAINS && !PRESSED) + return; + + if (CONTAINS) + std::erase(m_pressed, event.keycode); + else + m_pressed.emplace_back(event.keycode); + g_pSeatManager->setKeyboard(pKeyboard); g_pSeatManager->sendKeyboardKey(event.timeMs, event.keycode, event.state); } @@ -1424,10 +1451,9 @@ void CInputManager::onKeyboardMod(SP<IKeyboard> pKeyboard) { const bool DISALLOWACTION = pKeyboard->isVirtual() && shouldIgnoreVirtualKeyboard(pKeyboard); - const auto ALLMODS = accumulateModsFromAllKBs(); - - auto MODS = pKeyboard->m_modifiersState; - MODS.depressed = ALLMODS; + auto MODS = pKeyboard->m_modifiersState; + const auto ALLMODS = shareModsFromAllKBs(MODS.depressed); + MODS.depressed = ALLMODS; const auto IME = m_relay.m_inputMethod.lock(); @@ -1437,6 +1463,7 @@ void CInputManager::onKeyboardMod(SP<IKeyboard> pKeyboard) { } else { g_pSeatManager->setKeyboard(pKeyboard); g_pSeatManager->sendKeyboardMods(MODS.depressed, MODS.latched, MODS.locked, MODS.group); + m_lastMods = MODS.depressed; } updateKeyboardsLeds(pKeyboard); @@ -1457,9 +1484,9 @@ bool CInputManager::shouldIgnoreVirtualKeyboard(SP<IKeyboard> pKeyboard) { if (!pKeyboard->isVirtual()) return false; - CVirtualKeyboard* vk = (CVirtualKeyboard*)pKeyboard.get(); + auto client = pKeyboard->getClient(); - return !pKeyboard || (!m_relay.m_inputMethod.expired() && m_relay.m_inputMethod->grabClient() == vk->getClient()); + return !pKeyboard || (client && !m_relay.m_inputMethod.expired() && m_relay.m_inputMethod->grabClient() == client); } void CInputManager::refocus() { @@ -1564,11 +1591,45 @@ void CInputManager::updateCapabilities() { m_capabilities = caps; } -uint32_t CInputManager::accumulateModsFromAllKBs() { +const std::vector<uint32_t>& CInputManager::getKeysFromAllKBs() { + return m_pressed; +} + +uint32_t CInputManager::getModsFromAllKBs() { + return m_lastMods; +} + +bool CInputManager::shareKeyFromAllKBs(uint32_t key, bool pressed) { + bool finalState = pressed; - uint32_t finalMask = 0; + if (finalState) + return finalState; for (auto const& kb : m_keyboards) { + if (!kb->shareStates()) + continue; + + if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb)) + continue; + + if (!kb->m_enabled) + continue; + + const bool PRESSED = kb->getPressed(key); + if (PRESSED) + return PRESSED; + } + + return finalState; +} + +uint32_t CInputManager::shareModsFromAllKBs(uint32_t depressed) { + uint32_t finalMask = depressed; + + for (auto const& kb : m_keyboards) { + if (!kb->shareStates()) + continue; + if (kb->isVirtual() && shouldIgnoreVirtualKeyboard(kb)) continue; @@ -1751,13 +1812,6 @@ void CInputManager::unsetCursorImage() { restoreCursorIconToApp(); } -std::string CInputManager::deviceNameToInternalString(std::string in) { - std::ranges::replace(in, ' ', '-'); - std::ranges::replace(in, '\n', '-'); - std::ranges::transform(in, in.begin(), ::tolower); - return in; -} - std::string CInputManager::getNameForNewDevice(std::string internalName) { auto proposedNewName = deviceNameToInternalString(internalName); |
