diff options
| author | Vaxry <vaxry@vaxry.net> | 2024-06-17 16:07:32 +0200 |
|---|---|---|
| committer | Vaxry <vaxry@vaxry.net> | 2024-06-17 16:07:32 +0200 |
| commit | 785d0628876a4782759b13c25fa644c12f340356 (patch) | |
| tree | 5f0cdb824763ad7c035d2b23fe0b58e15a090450 /src/protocols/core/Seat.cpp | |
| parent | 1360677478e867034713e5d43d7a8a8f6bf1343d (diff) | |
seat: track pressed pointer buttons
releases them on leave, unless there is a dnd going on
Diffstat (limited to 'src/protocols/core/Seat.cpp')
| -rw-r--r-- | src/protocols/core/Seat.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
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); } |
