diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp index b40d6cad..92b1173e 100644 --- a/src/managers/SeatManager.cpp +++ b/src/managers/SeatManager.cpp @@ -4,6 +4,7 @@ #include "../protocols/DataDeviceWlr.hpp" #include "../protocols/PrimarySelection.hpp" #include "../protocols/core/Compositor.hpp" +#include "../protocols/InputCapture.hpp" #include "../Compositor.hpp" #include "../devices/IKeyboard.hpp" #include "wlr-layer-shell-unstable-v1.hpp" @@ -98,6 +99,7 @@ void CSeatManager::updateActiveKeyboardData() { if (keyboard) PROTO::seat->updateRepeatInfo(keyboard->repeatRate, keyboard->repeatDelay); PROTO::seat->updateKeymap(); + PROTO::inputCapture->updateKeymap(); } void CSeatManager::setKeyboardFocus(SP surf) { diff --git a/src/protocols/InputCapture.cpp b/src/protocols/InputCapture.cpp index c2cfd6f2..0381d63c 100644 --- a/src/protocols/InputCapture.cpp +++ b/src/protocols/InputCapture.cpp @@ -1,11 +1,15 @@ #include "InputCapture.hpp" +#include "../devices/IKeyboard.hpp" +#include "managers/SeatManager.hpp" +#include + CInputCaptureProtocol::CInputCaptureProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { ; } void CInputCaptureProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)).get(); + const auto& RESOURCE = m_vManagers.emplace_back(std::make_unique(client, ver, id)); RESOURCE->setOnDestroy([this](CHyprlandInputCaptureManagerV1* p) { std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == p->resource(); }); }); @@ -17,50 +21,78 @@ void CInputCaptureProtocol::bindManager(wl_client* client, void* data, uint32_t Debug::log(LOG, "[input-capture] Input released"); active = false; }); + + sendKeymap(g_pSeatManager->keyboard.lock(), RESOURCE); } bool CInputCaptureProtocol::isCaptured() { return active; } +void CInputCaptureProtocol::updateKeymap() { + for (const auto& manager : m_vManagers) + sendKeymap(g_pSeatManager->keyboard.lock(), manager); +} + void CInputCaptureProtocol::sendMotion(const Vector2D& absolutePosition, const Vector2D& delta) { for (const auto& manager : m_vManagers) { manager->sendMotion(wl_fixed_from_double(absolutePosition.x), wl_fixed_from_double(absolutePosition.y), wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y)); } } -void CInputCaptureProtocol::sendKey(uint32_t keyCode, hyprlandInputCaptureManagerV1KeyState state) { - for (const auto& manager : m_vManagers) { - manager->sendKey(keyCode, state); +void CInputCaptureProtocol::sendKeymap(SP keyboard, const std::unique_ptr& manager) { + if (!keyboard) + return; + + hyprlandInputCaptureManagerV1KeymapFormat format; + int fd; + uint32_t size; + if (keyboard) { + format = HYPRLAND_INPUT_CAPTURE_MANAGER_V1_KEYMAP_FORMAT_XKB_V1; + fd = keyboard->xkbKeymapFD; + size = keyboard->xkbKeymapString.length() + 1; + } else { + format = HYPRLAND_INPUT_CAPTURE_MANAGER_V1_KEYMAP_FORMAT_NO_KEYMAP; + fd = open("/dev/null", O_RDONLY | O_CLOEXEC); + if (fd < 0) { + LOGM(ERR, "Failed to open /dev/null"); + return; + } + size = 0; } + + manager->sendKeymap(format, fd, size); + + if (!keyboard) + close(fd); +} + +void CInputCaptureProtocol::sendKey(uint32_t keyCode, hyprlandInputCaptureManagerV1KeyState state) { + for (const auto& manager : m_vManagers) + manager->sendKey(keyCode, state); } void CInputCaptureProtocol::sendButton(uint32_t button, hyprlandInputCaptureManagerV1ButtonState state) { - for (const auto& manager : m_vManagers) { + for (const auto& manager : m_vManagers) manager->sendButton(button, state); - } } void CInputCaptureProtocol::sendAxis(hyprlandInputCaptureManagerV1Axis axis, double value) { - for (const auto& manager : m_vManagers) { + for (const auto& manager : m_vManagers) manager->sendAxis(axis, value); - } } void CInputCaptureProtocol::sendAxisValue120(hyprlandInputCaptureManagerV1Axis axis, int32_t value120) { - for (const auto& manager : m_vManagers) { + for (const auto& manager : m_vManagers) manager->sendAxisValue120(axis, value120); - } } void CInputCaptureProtocol::sendAxisStop(hyprlandInputCaptureManagerV1Axis axis) { - for (const auto& manager : m_vManagers) { + for (const auto& manager : m_vManagers) manager->sendAxisStop(axis); - } } void CInputCaptureProtocol::sendFrame() { - for (const auto& manager : m_vManagers) { + for (const auto& manager : m_vManagers) manager->sendFrame(); - } } diff --git a/src/protocols/InputCapture.hpp b/src/protocols/InputCapture.hpp index 645c25ec..3f174448 100644 --- a/src/protocols/InputCapture.hpp +++ b/src/protocols/InputCapture.hpp @@ -9,9 +9,10 @@ class CInputCaptureProtocol : public IWaylandProtocol { CInputCaptureProtocol(const wl_interface* iface, const int& ver, const std::string& name); virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); - bool isCaptured(); - // + bool isCaptured(); + + void updateKeymap(); void sendMotion(const Vector2D& absolutePosition, const Vector2D& delta); void sendKey(uint32_t keyCode, hyprlandInputCaptureManagerV1KeyState state); void sendButton(uint32_t button, hyprlandInputCaptureManagerV1ButtonState state); @@ -22,6 +23,8 @@ class CInputCaptureProtocol : public IWaylandProtocol { void sendFrame(); private: + void sendKeymap(SP keyboard, const std::unique_ptr& manager); + bool active = false; // std::vector> m_vManagers; diff --git a/subprojects/hyprland-protocols b/subprojects/hyprland-protocols index 479cc226..d3674e1f 160000 --- a/subprojects/hyprland-protocols +++ b/subprojects/hyprland-protocols @@ -1 +1 @@ -Subproject commit 479cc226451c264396a4c442710d6b56dce2fa46 +Subproject commit d3674e1f4eac730efc01c08e794a988be31ec73e