From 785d0628876a4782759b13c25fa644c12f340356 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 17 Jun 2024 16:07:32 +0200 Subject: [PATCH] seat: track pressed pointer buttons releases them on leave, unless there is a dnd going on --- src/protocols/core/Seat.cpp | 26 ++++++++++++++++++++++++++ src/protocols/core/Seat.hpp | 2 ++ 2 files changed, 28 insertions(+) diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index be05955c..f578292a 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -1,5 +1,6 @@ #include "Seat.hpp" #include "Compositor.hpp" +#include "DataDevice.hpp" #include "../../devices/IKeyboard.hpp" #include "../../managers/SeatManager.hpp" #include "../../config/ConfigValue.hpp" @@ -128,6 +129,18 @@ void CWLPointerResource::sendLeave() { if (!owner || !currentSurface) return; + // release all buttons unless we have a dnd going on in which case + // the events shall be lost. + if (!PROTO::data->dndActive()) { + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + for (auto& b : pressedButtons) { + sendButton(now.tv_sec * 1000 + now.tv_nsec / 1000000, b, WL_POINTER_BUTTON_STATE_RELEASED); + } + } + + pressedButtons.clear(); + resource->sendLeave(g_pSeatManager->nextSerial(owner.lock()), currentSurface->getResource().get()); currentSurface.reset(); listeners.destroySurface.reset(); @@ -144,6 +157,19 @@ void CWLPointerResource::sendButton(uint32_t timeMs, uint32_t button, wl_pointer if (!owner || !currentSurface) return; + if (state == WL_POINTER_BUTTON_STATE_RELEASED && std::find(pressedButtons.begin(), pressedButtons.end(), button) == pressedButtons.end()) { + LOGM(ERR, "sendButton release on a non-pressed button"); + return; + } else if (state == WL_POINTER_BUTTON_STATE_PRESSED && std::find(pressedButtons.begin(), pressedButtons.end(), button) != pressedButtons.end()) { + LOGM(ERR, "sendButton press on a non-pressed button"); + return; + } + + if (state == WL_POINTER_BUTTON_STATE_RELEASED) + std::erase(pressedButtons, button); + else if (state == WL_POINTER_BUTTON_STATE_PRESSED) + pressedButtons.emplace_back(button); + resource->sendButton(g_pSeatManager->nextSerial(owner.lock()), timeMs, button, state); } diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index 625d3a98..0b563b8f 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -76,6 +76,8 @@ class CWLPointerResource { SP resource; WP currentSurface; + std::vector pressedButtons; + struct { CHyprSignalListener destroySurface; } listeners;