seat: track pressed pointer buttons

releases them on leave, unless there is a dnd going on
This commit is contained in:
Vaxry 2024-06-17 16:07:32 +02:00
parent 1360677478
commit 785d062887
2 changed files with 28 additions and 0 deletions

View file

@ -1,5 +1,6 @@
#include "Seat.hpp" #include "Seat.hpp"
#include "Compositor.hpp" #include "Compositor.hpp"
#include "DataDevice.hpp"
#include "../../devices/IKeyboard.hpp" #include "../../devices/IKeyboard.hpp"
#include "../../managers/SeatManager.hpp" #include "../../managers/SeatManager.hpp"
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
@ -128,6 +129,18 @@ void CWLPointerResource::sendLeave() {
if (!owner || !currentSurface) if (!owner || !currentSurface)
return; 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()); resource->sendLeave(g_pSeatManager->nextSerial(owner.lock()), currentSurface->getResource().get());
currentSurface.reset(); currentSurface.reset();
listeners.destroySurface.reset(); listeners.destroySurface.reset();
@ -144,6 +157,19 @@ void CWLPointerResource::sendButton(uint32_t timeMs, uint32_t button, wl_pointer
if (!owner || !currentSurface) if (!owner || !currentSurface)
return; 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); resource->sendButton(g_pSeatManager->nextSerial(owner.lock()), timeMs, button, state);
} }

View file

@ -76,6 +76,8 @@ class CWLPointerResource {
SP<CWlPointer> resource; SP<CWlPointer> resource;
WP<CWLSurfaceResource> currentSurface; WP<CWLSurfaceResource> currentSurface;
std::vector<uint32_t> pressedButtons;
struct { struct {
CHyprSignalListener destroySurface; CHyprSignalListener destroySurface;
} listeners; } listeners;