summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvaxerski <vaxry@vaxry.net>2024-06-12 16:49:26 +0200
committervaxerski <vaxry@vaxry.net>2024-06-12 16:49:26 +0200
commitc7e85e26f761fb58db6692649e259589cdf55cf0 (patch)
tree15a665d22fdddbc22f50ea8029578c1a31927e17 /src
parent1bae19ce85ae9a25f2dddb6cee8bbd6ed3872ade (diff)
seat: fixup touch event handling
fixes #6353
Diffstat (limited to 'src')
-rw-r--r--src/managers/SeatManager.cpp50
-rw-r--r--src/managers/SeatManager.hpp1
-rw-r--r--src/protocols/core/Seat.cpp21
-rw-r--r--src/protocols/core/Seat.hpp2
4 files changed, 39 insertions, 35 deletions
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<CWLSurfaceResource> 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<CWLSurfaceResource> 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<CWLSurfaceResource> 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<CWlTouch> resource;
WP<CWLSurfaceResource> currentSurface;
+ int fingers = 0;
+
struct {
CHyprSignalListener destroySurface;
} listeners;