seat: fixup touch event handling

fixes #6353
This commit is contained in:
Vaxry 2024-06-12 16:49:26 +02:00
parent 1bae19ce85
commit c7e85e26f7
4 changed files with 39 additions and 35 deletions

View File

@ -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) { void CSeatManager::sendTouchDown(SP<CWLSurfaceResource> surf, uint32_t timeMs, int32_t id, const Vector2D& local) {
if (state.touchFocus == surf)
return;
listeners.touchSurfaceDestroy.reset(); 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.touchFocusResource.reset();
state.touchFocus = surf; state.touchFocus = surf;
if (!surf) {
events.touchFocusChange.emit();
return;
}
auto client = surf->client(); auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) { for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client) 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); }); 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) { 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) { void CSeatManager::sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local) {

View File

@ -155,6 +155,7 @@ class CSeatManager {
} listeners; } listeners;
Vector2D lastLocalCoords; Vector2D lastLocalCoords;
int touchLocks = 0; // we assume there aint like 20 touch devices at once...
friend struct SSeatResourceContainer; friend struct SSeatResourceContainer;
friend class CSeatGrab; friend class CSeatGrab;

View File

@ -25,37 +25,38 @@ void CWLTouchResource::sendDown(SP<CWLSurfaceResource> surface, uint32_t timeMs,
if (!owner) if (!owner)
return; return;
if (currentSurface) {
LOGM(WARN, "requested CWLTouchResource::sendDown without sendUp first.");
sendUp(timeMs, id);
}
ASSERT(surface->client() == owner->client()); ASSERT(surface->client() == owner->client());
currentSurface = surface; currentSurface = surface;
listeners.destroySurface = surface->events.destroy.registerListener([this, timeMs, id](std::any d) { sendUp(timeMs + 10 /* hack */, id); }); 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)); 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) { void CWLTouchResource::sendUp(uint32_t timeMs, int32_t id) {
if (!owner || !currentSurface) if (!owner)
return; return;
resource->sendUp(g_pSeatManager->nextSerial(owner.lock()), timeMs, id); resource->sendUp(g_pSeatManager->nextSerial(owner.lock()), timeMs, id);
currentSurface.reset(); fingers--;
listeners.destroySurface.reset(); if (fingers <= 0) {
currentSurface.reset();
listeners.destroySurface.reset();
fingers = 0;
}
} }
void CWLTouchResource::sendMotion(uint32_t timeMs, int32_t id, const Vector2D& local) { void CWLTouchResource::sendMotion(uint32_t timeMs, int32_t id, const Vector2D& local) {
if (!owner || !currentSurface) if (!owner)
return; return;
resource->sendMotion(timeMs, id, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y)); resource->sendMotion(timeMs, id, wl_fixed_from_double(local.x), wl_fixed_from_double(local.y));
} }
void CWLTouchResource::sendFrame() { void CWLTouchResource::sendFrame() {
if (!owner || !currentSurface) if (!owner)
return; return;
resource->sendFrame(); resource->sendFrame();

View File

@ -46,6 +46,8 @@ class CWLTouchResource {
SP<CWlTouch> resource; SP<CWlTouch> resource;
WP<CWLSurfaceResource> currentSurface; WP<CWLSurfaceResource> currentSurface;
int fingers = 0;
struct { struct {
CHyprSignalListener destroySurface; CHyprSignalListener destroySurface;
} listeners; } listeners;