diff --git a/CMakeLists.txt b/CMakeLists.txt index aa3219d9..009093ed 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -266,6 +266,7 @@ protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false) protocolNew("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false) protocolNew("unstable/idle-inhibit/idle-inhibit-unstable-v1.xml" "idle-inhibit-unstable-v1" false) +protocolNew("unstable/relative-pointer/relative-pointer-unstable-v1.xml" "relative-pointer-unstable-v1" false) # tools add_subdirectory(hyprctl) diff --git a/protocols/meson.build b/protocols/meson.build index dd2a2358..145863a0 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -44,6 +44,7 @@ new_protocols = [ [wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], [wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'], [wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'], + [wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], ] wl_protos_src = [] diff --git a/src/Compositor.cpp b/src/Compositor.cpp index f9ecb18e..40cf672a 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -217,8 +217,6 @@ void CCompositor::initServer() { m_sWLRPointerConstraints = wlr_pointer_constraints_v1_create(m_sWLDisplay); - m_sWLRRelPointerMgr = wlr_relative_pointer_manager_v1_create(m_sWLDisplay); - m_sWLRVKeyboardMgr = wlr_virtual_keyboard_manager_v1_create(m_sWLDisplay); m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index 96fee44e..812d38fb 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -64,7 +64,6 @@ class CCompositor { wlr_egl* m_sWLREGL; int m_iDRMFD; wlr_pointer_constraints_v1* m_sWLRPointerConstraints; - wlr_relative_pointer_manager_v1* m_sWLRRelPointerMgr; wlr_server_decoration_manager* m_sWLRServerDecoMgr; wlr_xdg_decoration_manager_v1* m_sWLRXDGDecoMgr; wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr; diff --git a/src/includes.hpp b/src/includes.hpp index d7cb7ce8..d62994db 100644 --- a/src/includes.hpp +++ b/src/includes.hpp @@ -83,7 +83,6 @@ extern "C" { #include #include #include -#include #include #include #include diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index 8bf7a0d9..77f5315c 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -5,20 +5,23 @@ #include "../protocols/XDGOutput.hpp" #include "../protocols/CursorShape.hpp" #include "../protocols/IdleInhibit.hpp" +#include "../protocols/RelativePointer.hpp" #include "tearing-control-v1.hpp" #include "fractional-scale-v1.hpp" #include "xdg-output-unstable-v1.hpp" #include "cursor-shape-v1.hpp" #include "idle-inhibit-unstable-v1.hpp" +#include "relative-pointer-unstable-v1.hpp" CProtocolManager::CProtocolManager() { - PROTO::tearing = std::make_unique(&wp_tearing_control_manager_v1_interface, 1, "TearingControl"); - PROTO::fractional = std::make_unique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale"); - PROTO::xdgOutput = std::make_unique(&zxdg_output_manager_v1_interface, 3, "XDGOutput"); - PROTO::cursorShape = std::make_unique(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape"); - PROTO::idleInhibit = std::make_unique(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit"); + PROTO::tearing = std::make_unique(&wp_tearing_control_manager_v1_interface, 1, "TearingControl"); + PROTO::fractional = std::make_unique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale"); + PROTO::xdgOutput = std::make_unique(&zxdg_output_manager_v1_interface, 3, "XDGOutput"); + PROTO::cursorShape = std::make_unique(&wp_cursor_shape_manager_v1_interface, 1, "CursorShape"); + PROTO::idleInhibit = std::make_unique(&zwp_idle_inhibit_manager_v1_interface, 1, "IdleInhibit"); + PROTO::relativePointer = std::make_unique(&zwp_relative_pointer_manager_v1_interface, 1, "RelativePointer"); // Old protocol implementations. // TODO: rewrite them to use hyprwayland-scanner. diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp index 114a6c83..0aad3189 100644 --- a/src/managers/input/InputManager.cpp +++ b/src/managers/input/InputManager.cpp @@ -6,6 +6,7 @@ #include "../../desktop/Window.hpp" #include "../../protocols/CursorShape.hpp" #include "../../protocols/IdleInhibit.hpp" +#include "../../protocols/RelativePointer.hpp" CInputManager::CInputManager() { m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) { @@ -54,11 +55,9 @@ void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) { const auto DELTA = *PNOACCEL == 1 ? Vector2D(e->unaccel_dx, e->unaccel_dy) : Vector2D(e->delta_x, e->delta_y); if (*PSENSTORAW == 1) - wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x * *PSENS, - DELTA.y * *PSENS, e->unaccel_dx * *PSENS, e->unaccel_dy * *PSENS); + PROTO::relativePointer->sendRelativeMotion((uint64_t)e->time_msec * 1000, DELTA * *PSENS, Vector2D{e->unaccel_dx, e->unaccel_dy} * *PSENS); else - wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x, DELTA.y, - e->unaccel_dx, e->unaccel_dy); + PROTO::relativePointer->sendRelativeMotion((uint64_t)e->time_msec * 1000, DELTA, Vector2D{e->unaccel_dx, e->unaccel_dy}); wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, DELTA.x * *PSENS, DELTA.y * *PSENS); @@ -188,7 +187,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, CLOSEST.x, CLOSEST.y); wlr_seat_pointer_send_motion(g_pCompositor->m_sSeat.seat, time, CLOSESTLOCAL.x, CLOSESTLOCAL.y); - wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)time * 1000, 0, 0, 0, 0); + PROTO::relativePointer->sendRelativeMotion((uint64_t)time * 1000, {}, {}); } return; diff --git a/src/protocols/RelativePointer.cpp b/src/protocols/RelativePointer.cpp new file mode 100644 index 00000000..c09ad0cf --- /dev/null +++ b/src/protocols/RelativePointer.cpp @@ -0,0 +1,72 @@ +#include "RelativePointer.hpp" +#include + +CRelativePointer::CRelativePointer(SP resource_) : resource(resource_) { + if (!resource_->resource()) + return; + + pClient = wl_resource_get_client(resource_->resource()); + + resource->setDestroy([this](CZwpRelativePointerV1* pMgr) { PROTO::relativePointer->destroyRelativePointer(this); }); + resource->setOnDestroy([this](CZwpRelativePointerV1* pMgr) { PROTO::relativePointer->destroyRelativePointer(this); }); +} + +bool CRelativePointer::good() { + return resource->resource(); +} + +wl_client* CRelativePointer::client() { + return pClient; +} + +void CRelativePointer::sendRelativeMotion(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) { + resource->sendRelativeMotion(time >> 32, time & 0xFFFFFFFF, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y), wl_fixed_from_double(deltaUnaccel.x), + wl_fixed_from_double(deltaUnaccel.y)); +} + +CRelativePointerProtocol::CRelativePointerProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CRelativePointerProtocol::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(); + RESOURCE->setOnDestroy([this](CZwpRelativePointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); + + RESOURCE->setDestroy([this](CZwpRelativePointerManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); + RESOURCE->setGetRelativePointer([this](CZwpRelativePointerManagerV1* pMgr, uint32_t id, wl_resource* pointer) { this->onGetRelativePointer(pMgr, id, pointer); }); +} + +void CRelativePointerProtocol::onManagerResourceDestroy(wl_resource* res) { + std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; }); +} + +void CRelativePointerProtocol::destroyRelativePointer(CRelativePointer* pointer) { + std::erase_if(m_vRelativePointers, [&](const auto& other) { return other.get() == pointer; }); +} + +void CRelativePointerProtocol::onGetRelativePointer(CZwpRelativePointerManagerV1* pMgr, uint32_t id, wl_resource* pointer) { + const auto CLIENT = wl_resource_get_client(pMgr->resource()); + const auto RESOURCE = + m_vRelativePointers.emplace_back(std::make_unique(std::make_shared(CLIENT, wl_resource_get_version(pMgr->resource()), id))).get(); + + if (!RESOURCE->good()) { + wl_resource_post_no_memory(pMgr->resource()); + m_vRelativePointers.pop_back(); + return; + } +} + +void CRelativePointerProtocol::sendRelativeMotion(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) { + + if (!g_pCompositor->m_sSeat.seat->pointer_state.focused_client) + return; + + const auto FOCUSED = g_pCompositor->m_sSeat.seat->pointer_state.focused_client->client; + + for (auto& rp : m_vRelativePointers) { + if (FOCUSED != rp->client()) + continue; + + rp->sendRelativeMotion(time, delta, deltaUnaccel); + } +} \ No newline at end of file diff --git a/src/protocols/RelativePointer.hpp b/src/protocols/RelativePointer.hpp new file mode 100644 index 00000000..93446e85 --- /dev/null +++ b/src/protocols/RelativePointer.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include "WaylandProtocol.hpp" +#include "relative-pointer-unstable-v1.hpp" +#include "../helpers/Vector2D.hpp" + +class CRelativePointer { + public: + CRelativePointer(SP resource_); + + void sendRelativeMotion(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel); + + bool good(); + wl_client* client(); + + private: + SP resource; + wl_client* pClient = nullptr; +}; + +class CRelativePointerProtocol : public IWaylandProtocol { + public: + CRelativePointerProtocol(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); + + void sendRelativeMotion(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel); + + private: + void onManagerResourceDestroy(wl_resource* res); + void destroyRelativePointer(CRelativePointer* pointer); + void onGetRelativePointer(CZwpRelativePointerManagerV1* pMgr, uint32_t id, wl_resource* pointer); + + // + std::vector> m_vManagers; + std::vector> m_vRelativePointers; + + friend class CRelativePointer; +}; + +namespace PROTO { + inline UP relativePointer; +}; \ No newline at end of file