diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp index 862bd2b5..c1b13ccb 100644 --- a/src/managers/SeatManager.cpp +++ b/src/managers/SeatManager.cpp @@ -337,34 +337,11 @@ void CSeatManager::sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double } void CSeatManager::sendTouchDown(SP surf, uint32_t timeMs, int32_t id, const Vector2D& local) { - if (state.touchFocus == surf) - return; - listeners.touchSurfaceDestroy.reset(); - if (state.touchFocusResource) { - auto client = state.touchFocusResource->client(); - for (auto& s : seatResources) { - if (s->resource->client() != client) - continue; - - for (auto& t : s->resource->touches) { - if (!t) - continue; - - t->sendUp(timeMs, id); - } - } - } - state.touchFocusResource.reset(); state.touchFocus = surf; - if (!surf) { - events.touchFocusChange.emit(); - return; - } - auto client = surf->client(); for (auto& r : seatResources | std::views::reverse) { if (r->resource->client() != client) @@ -381,11 +358,34 @@ void CSeatManager::sendTouchDown(SP surf, uint32_t timeMs, i listeners.touchSurfaceDestroy = surf->events.destroy.registerListener([this, timeMs, id](std::any d) { sendTouchUp(timeMs + 10, id); }); - events.touchFocusChange.emit(); + touchLocks++; + + if (touchLocks <= 1) + events.touchFocusChange.emit(); } void CSeatManager::sendTouchUp(uint32_t timeMs, int32_t id) { - sendTouchDown(nullptr, timeMs, id, {}); + if (!state.touchFocusResource || touchLocks <= 0) + return; + + auto client = state.touchFocusResource->client(); + for (auto& r : seatResources | std::views::reverse) { + if (r->resource->client() != client) + continue; + + state.touchFocusResource = r->resource; + for (auto& t : r->resource->touches) { + if (!t) + continue; + + t->sendUp(timeMs, id); + } + } + + touchLocks--; + + if (touchLocks <= 0) + events.touchFocusChange.emit(); } void CSeatManager::sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local) { diff --git a/src/managers/SeatManager.hpp b/src/managers/SeatManager.hpp index e74d9ace..1a1df1d5 100644 --- a/src/managers/SeatManager.hpp +++ b/src/managers/SeatManager.hpp @@ -155,6 +155,7 @@ class CSeatManager { } listeners; Vector2D lastLocalCoords; + int touchLocks = 0; // we assume there aint like 20 touch devices at once... friend struct SSeatResourceContainer; friend class CSeatGrab; diff --git a/src/protocols/core/Seat.cpp b/src/protocols/core/Seat.cpp index 8bf03909..331eb15e 100644 --- a/src/protocols/core/Seat.cpp +++ b/src/protocols/core/Seat.cpp @@ -25,37 +25,38 @@ void CWLTouchResource::sendDown(SP surface, uint32_t timeMs, if (!owner) return; - if (currentSurface) { - LOGM(WARN, "requested CWLTouchResource::sendDown without sendUp first."); - sendUp(timeMs, id); - } - ASSERT(surface->client() == owner->client()); currentSurface = surface; listeners.destroySurface = surface->events.destroy.registerListener([this, timeMs, id](std::any d) { sendUp(timeMs + 10 /* hack */, id); }); resource->sendDown(g_pSeatManager->nextSerial(owner.lock()), timeMs, surface->getResource().get(), id, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y)); + + fingers++; } void CWLTouchResource::sendUp(uint32_t timeMs, int32_t id) { - if (!owner || !currentSurface) + if (!owner) return; resource->sendUp(g_pSeatManager->nextSerial(owner.lock()), timeMs, id); - currentSurface.reset(); - listeners.destroySurface.reset(); + fingers--; + if (fingers <= 0) { + currentSurface.reset(); + listeners.destroySurface.reset(); + fingers = 0; + } } void CWLTouchResource::sendMotion(uint32_t timeMs, int32_t id, const Vector2D& local) { - if (!owner || !currentSurface) + if (!owner) return; resource->sendMotion(timeMs, id, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y)); } void CWLTouchResource::sendFrame() { - if (!owner || !currentSurface) + if (!owner) return; resource->sendFrame(); diff --git a/src/protocols/core/Seat.hpp b/src/protocols/core/Seat.hpp index 524783f9..625d3a98 100644 --- a/src/protocols/core/Seat.hpp +++ b/src/protocols/core/Seat.hpp @@ -46,6 +46,8 @@ class CWLTouchResource { SP resource; WP currentSurface; + int fingers = 0; + struct { CHyprSignalListener destroySurface; } listeners;