From 2be309de1df5e4262175fbcc58e6dd8de4e0e6d3 Mon Sep 17 00:00:00 2001 From: JS Deck Date: Mon, 4 Aug 2025 16:29:39 -0300 Subject: virtualkeyboard: Add options to skip releasing pressed keys on close and to skip sharing key states (#11214) --- src/protocols/VirtualKeyboard.cpp | 51 ++++++++++++++++++++++++++++++--------- src/protocols/VirtualKeyboard.hpp | 1 + src/protocols/core/Seat.cpp | 21 +++++++++------- src/protocols/core/Seat.hpp | 3 ++- 4 files changed, 54 insertions(+), 22 deletions(-) (limited to 'src/protocols') diff --git a/src/protocols/VirtualKeyboard.cpp b/src/protocols/VirtualKeyboard.cpp index 7512f9bd..3dc15d83 100644 --- a/src/protocols/VirtualKeyboard.cpp +++ b/src/protocols/VirtualKeyboard.cpp @@ -1,23 +1,42 @@ #include "VirtualKeyboard.hpp" +#include #include +#include "../config/ConfigValue.hpp" +#include "../config/ConfigManager.hpp" #include "../devices/IKeyboard.hpp" #include "../helpers/time/Time.hpp" +#include "../helpers/MiscFunctions.hpp" using namespace Hyprutils::OS; +static std::string virtualKeyboardNameForWlClient(wl_client* client) { + std::string name = "hl-virtual-keyboard"; + + static auto PVKNAMEPROC = CConfigValue("misc:name_vk_after_proc"); + if (!*PVKNAMEPROC) + return name; + + name += "-"; + const auto CLIENTNAME = binaryNameForWlClient(client); + if (CLIENTNAME.has_value()) { + const auto PATH = std::filesystem::path(CLIENTNAME.value()); + if (PATH.has_filename()) { + const auto FILENAME = PATH.filename(); + const auto NAME = deviceNameToInternalString(FILENAME); + name += NAME; + return name; + } + } + + name += "unknown"; + return name; +} + CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP resource_) : m_resource(resource_) { if UNLIKELY (!good()) return; - m_resource->setDestroy([this](CZwpVirtualKeyboardV1* r) { - releasePressed(); - m_events.destroy.emit(); - PROTO::virtualKeyboard->destroyResource(this); - }); - m_resource->setOnDestroy([this](CZwpVirtualKeyboardV1* r) { - releasePressed(); - m_events.destroy.emit(); - PROTO::virtualKeyboard->destroyResource(this); - }); + m_resource->setDestroy([this](CZwpVirtualKeyboardV1* r) { destroy(); }); + m_resource->setOnDestroy([this](CZwpVirtualKeyboardV1* r) { destroy(); }); m_resource->setKey([this](CZwpVirtualKeyboardV1* r, uint32_t timeMs, uint32_t key, uint32_t state) { if UNLIKELY (!m_hasKeymap) { @@ -31,7 +50,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP .state = (wl_keyboard_key_state)state, }); - const bool CONTAINS = std::ranges::find(m_pressed, key) != m_pressed.end(); + const bool CONTAINS = std::ranges::contains(m_pressed, key); if (state && !CONTAINS) m_pressed.emplace_back(key); else if (!state && CONTAINS) @@ -88,7 +107,7 @@ CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP xkb_context_unref(xkbContext); }); - m_name = "hl-virtual-keyboard"; + m_name = virtualKeyboardNameForWlClient(resource_->client()); } CVirtualKeyboardV1Resource::~CVirtualKeyboardV1Resource() { @@ -115,6 +134,14 @@ void CVirtualKeyboardV1Resource::releasePressed() { m_pressed.clear(); } +void CVirtualKeyboardV1Resource::destroy() { + const auto RELEASEPRESSED = g_pConfigManager->getDeviceInt(m_name, "release_pressed_on_close", "input:virtualkeyboard:release_pressed_on_close"); + if (RELEASEPRESSED) + releasePressed(); + m_events.destroy.emit(); + PROTO::virtualKeyboard->destroyResource(this); +} + CVirtualKeyboardProtocol::CVirtualKeyboardProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { ; } diff --git a/src/protocols/VirtualKeyboard.hpp b/src/protocols/VirtualKeyboard.hpp index c601c0fb..1ff9f161 100644 --- a/src/protocols/VirtualKeyboard.hpp +++ b/src/protocols/VirtualKeyboard.hpp @@ -30,6 +30,7 @@ class CVirtualKeyboardV1Resource { SP m_resource; void releasePressed(); + void destroy(); bool m_hasKeymap = false; diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index 53123abe..8aa2f36a 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -305,8 +305,14 @@ CWLKeyboardResource::CWLKeyboardResource(SP resource_, SPm_keyboard.lock()); repeatInfo(g_pSeatManager->m_keyboard->m_repeatRate, g_pSeatManager->m_keyboard->m_repeatDelay); - if (g_pSeatManager->m_state.keyboardFocus && g_pSeatManager->m_state.keyboardFocus->client() == m_resource->client()) - sendEnter(g_pSeatManager->m_state.keyboardFocus.lock()); + if (g_pSeatManager->m_state.keyboardFocus && g_pSeatManager->m_state.keyboardFocus->client() == m_resource->client()) { + wl_array keys; + wl_array_init(&keys); + + sendEnter(g_pSeatManager->m_state.keyboardFocus.lock(), &keys); + + wl_array_release(&keys); + } } bool CWLKeyboardResource::good() { @@ -334,7 +340,9 @@ void CWLKeyboardResource::sendKeymap(SP keyboard) { m_resource->sendKeymap(format, fd.get(), size); } -void CWLKeyboardResource::sendEnter(SP surface) { +void CWLKeyboardResource::sendEnter(SP surface, wl_array* keys) { + ASSERT(keys); + if (!m_owner || m_currentSurface == surface || !surface->getResource()->resource()) return; @@ -351,12 +359,7 @@ void CWLKeyboardResource::sendEnter(SP surface) { m_currentSurface = surface; m_listeners.destroySurface = surface->m_events.destroy.listen([this] { sendLeave(); }); - wl_array arr; - wl_array_init(&arr); - - m_resource->sendEnter(g_pSeatManager->nextSerial(m_owner.lock()), surface->getResource().get(), &arr); - - wl_array_release(&arr); + m_resource->sendEnter(g_pSeatManager->nextSerial(m_owner.lock()), surface->getResource().get(), keys); } void CWLKeyboardResource::sendLeave() { diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index 0c14e52a..8b8f6004 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -12,6 +12,7 @@ #include #include "../WaylandProtocol.hpp" #include +#include #include "wayland.hpp" #include "../../helpers/signal/Signal.hpp" #include "../../helpers/math/Math.hpp" @@ -104,7 +105,7 @@ class CWLKeyboardResource { bool good(); void sendKeymap(SP keeb); - void sendEnter(SP surface); + void sendEnter(SP surface, wl_array* keys); void sendLeave(); void sendKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state); void sendMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group); -- cgit v1.2.3