Skip to content

Commit

Permalink
REGRESSION (282524@main) (iOS): Tap and click events unresponsive aft…
Browse files Browse the repository at this point in the history
…er closing Safari and coming back

https://bugs.webkit.org/show_bug.cgi?id=279146
rdar://135211157

Reviewed by Abrar Rahman Protyasha.

In `PointerCaptureController`, there is logic which tries to not execute a mouse or pointer event
if there is a capturing event whose state is "Ready". However, prior to 282524@main, this logic
only worked to not execute pointer events, but would still in fact execute mouse events.

After 282524@main, since click, auxclick, and contextmenu are now pointer events, the `PointerCaptureController` logic
is now successful in preventing both mouse _and_ pointer events.

This in itself isn't a problem, and is the desired behavior when there is an active capture state.

However, in some cases (such as dismissing Safari), a touch event ends up beginning but never getting
cancelled properly. Specifically, while a `pointercancel` event is dispatched, the associated capture
data's state was never properly updated.

Fix this by calling `cancelPointer`, which properly updates the state and also more closely adheres to
the pointer event specification with regards to which events should be dispatched.

Fixing this then in turn fixes the original issue, since now there will no erroneous states which are active.

A test will be added in a follow up.

* Source/WebCore/page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):
(WebCore::PointerCaptureController::cancelPointer):
* Source/WebCore/page/PointerCaptureController.h:

Canonical link: https://commits.webkit.org/283187@main
  • Loading branch information
rr-codes committed Sep 5, 2024
1 parent 086f6c0 commit 4f5b133
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
19 changes: 16 additions & 3 deletions Source/WebCore/page/PointerCaptureController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,13 @@ void PointerCaptureController::dispatchEventForTouchAtIndex(EventTarget& target,
dispatchEnterOrLeaveEvent(eventNames().pointerenterEvent, *currentTarget);
}

#if PLATFORM(IOS_FAMILY)
if (pointerEvent->type() == eventNames().pointercancelEvent) {
cancelPointer(pointerEvent->pointerId(), platformTouchEvent.touchLocationAtIndex(index), pointerEvent.ptr());
return;
}
#endif

dispatchEvent(pointerEvent, &target);

if (pointerEvent->type() == eventNames().pointerupEvent) {
Expand Down Expand Up @@ -467,7 +474,7 @@ void PointerCaptureController::pointerEventWasDispatched(const PointerEvent& eve
capturingData->preventsCompatibilityMouseEvents = event.defaultPrevented();
}

void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint& documentPoint)
void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint& documentPoint, PointerEvent* existingCancelEvent)
{
// https://w3c.github.io/pointerevents/#the-pointercancel-event

Expand Down Expand Up @@ -517,8 +524,14 @@ void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint
// followed by firing a pointer event named pointerleave.
auto isPrimary = capturingData->isPrimary ? PointerEvent::IsPrimary::Yes : PointerEvent::IsPrimary::No;
auto& eventNames = WebCore::eventNames();
auto cancelEvent = PointerEvent::create(eventNames.pointercancelEvent, pointerId, capturingData->pointerType, isPrimary);
target->dispatchEvent(cancelEvent);

if (existingCancelEvent)
target->dispatchEvent(*existingCancelEvent);
else {
auto cancelEvent = PointerEvent::create(eventNames.pointercancelEvent, pointerId, capturingData->pointerType, isPrimary);
target->dispatchEvent(cancelEvent);
}

target->dispatchEvent(PointerEvent::create(eventNames.pointeroutEvent, pointerId, capturingData->pointerType, isPrimary));
target->dispatchEvent(PointerEvent::create(eventNames.pointerleaveEvent, pointerId, capturingData->pointerType, isPrimary));
processPendingPointerCapture(pointerId);
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/page/PointerCaptureController.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class PointerCaptureController {
bool hasCancelledPointerEventForIdentifier(PointerID) const;
bool preventsCompatibilityMouseEventsForIdentifier(PointerID) const;
void dispatchEvent(PointerEvent&, EventTarget*);
WEBCORE_EXPORT void cancelPointer(PointerID, const IntPoint&);
WEBCORE_EXPORT void cancelPointer(PointerID, const IntPoint&, PointerEvent* existingCancelEvent = nullptr);
void processPendingPointerCapture(PointerID);

private:
Expand Down

0 comments on commit 4f5b133

Please sign in to comment.