-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Click event while a pointer event is captured #75
Comments
Only scenario 2 was unexpected to me. The relative order of A click occurs when a button is pressed and released on the same element. Because pressing either the green or blue element inherently means pressing the grey element, I expect the grey element to receive a click in all scenarios. Only the first scenario should have a target other than grey, because a descendant of grey was the target of both the press and release. There were also comments about this yesterday starting at #61 (comment). |
Why scenario 3 is correct? blue is getting pointerdown as well as pointerup. So how come grey is getting the click? Also in scenario 4 which is related to your first paragraph, I think either click
So I was not sure what you meant in your first paragraph. Which of these you think is the most reasonable? |
Sorry, I missed that after going back up and reading the summary. Scenario 3 should have blue as the target.
Well, given that the relative order of |
I modified the original issue to have the outputs right after each scenario to make it more clear. So basically in 3, what I'm saying is that if click is defined as an event that will be fired to the first common ancestor of pointerdown and pointerup targets then scenario 4 makes sense. However from my understanding of the current spec no event should be fired to an element that doesn't have capturing except the boundary events (which we are trying to remove that to in other issues anyway). So click is not allowed to be sent to grey if blue has capturing either. Solution 3 of mine suggests to just explicitly exclude click from this in the spec and let click always be sent to the first common ancestor of pointerdown/up targets as per definition. |
Even with the current spec, boundary events are not sent to other elements. What we're discussing removing is the boundary events that are sent to the captured element.
But the spec says "Immediately after firing the pointerup or pointercancel events, a user agent must run the steps as if the releasePointerCapture() method has been called with an argument equal to the pointerId property of the pointerup or pointercancel event just dispatched." so even though the timing of
I believe this is already the case, but I may have forgotten a place where we mention specific details about click. Is there a part of the spec that you think contradicts this? |
I am in agreement with Scott on this one. Scenario 2 seems like a bug to me - the click should follow the spec and move to grey as the first common ancestor. Also, Scenario 3 also seems like a bug - since blue experienced both the pointerdown and pointerup, blue should get the click. Regarding the ordering of click and lostpointercapture - I agree from the cleanliness and logical perspective that click should come after lostpointercapture. However, I am not sure it really matters. Can we come up with a scenario where this ordering hampers what a web developer is trying to accomplish? |
I agree that scenario 2 seems like a bug - click should be on grey (common ancestor of the target of pointerdown and pointerup). But if we agree on that, then what about scenario 3? Following the same principle, the pointerdown and pointerup targets are both |
Whoops sorry, I see that now - thanks. Great, that really makes for the most consistent model I think! We should give that a try in Chrome and see how it goes. |
It seems we have all agreed that the nearest common ancestor of pointerdown & pointerup should receive the click event, right? We shouldn't fire click for non-primary buttons, so we can restrict the events to primary buttons only ("pointerdown with button=0" and "pointerup with button=0" instead). This would cover the chorded buttons case but won't fire a click when the primary button doesn't cause pointerdown and/or pointerup. I think this is fine. Alternatively, we can somehow include "mousemove with button=0" to fire a click event even on chorded primary buttons. IMO, this would make the spec a bit counter-intuitive w.r.t. the UI event spec, which perhaps doesn't make sense for this rare corner case. |
For the original problem stated here (click target with capturing), I think the current spec wording is fine because we agreed to the UI Event spec definition of click target (= the nearest common ancestor of down & up events). Do we still need a note? (The other problem I mentioned in the last post is orthogonal to capturing, so I will create a new issue to cover that.) |
Yeah I think the current spec text is fine, but we need a test for this case and a bug filed against Edge for that test failing. |
Edge bug for tracking: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7951882/ |
Agreed on the call https://www.w3.org/2016/06/22-pointerevents-minutes.html that we can now close this, remainder of the work is tracked elsewhere (Edge bug and WPT change). |
@patrickkettner we talked about this issue before with Ted. You and Andrew were also on that thread. The last decision was to stick to what UI event spec says and follow the behavior that is explained in this chrome bug. I remember Ted mentioning you guys are implementing that solution as well for this Edge bug. I wanted to follow up with you guys regarding that and whether you hit any regressions with that or not. Particularly we hit a few regressions like this one. |
So the reason for our implementation was around the expected behavior for click interactions with buttons. If you click without releasing on an intractable element (e.g. button, anchors,etc), then drag off and release, the button does not trigger a click event. We can obviously special case for the literal <button>, elements, but we get into weird behavior when you are dealing with sites that have created their own links/buttons via divsoup |
We spent a long time discussing this specific scenario. We could not come up with a reason to use pointer capture on a button. |
Hi everyone. I would like to present a real world use-case from Chromium's codebase which is suffering from the fact that the 'cilck' event is fired on a non-capturing element. Consider the following element, where a switcher UI control lies within a container row. Requirements for this component are:
I created a more minimal repro example here, which I've only tried in Chrome. Please ignore the Polymer code, and just scroll down to the bottom of the JS code (line 163 to the end). When the user drags the toggle, then releases the pointer on top of the container box , the extraneous click event, is triggering the container's click handler, which unexpectedly toggles the switch. The hack we've resorted is to cache the last I would like to remove that hack, so trying to restart this conversation on why the current behavior of letting click events fire on non-capture element is useful. |
Hi @freshp86 . However, I don't quite agree with your definition of hack.
|
@NavidZ: Agreed that I could modify the click handler of the clickable row to call a method on the toggle button itself, instead of comparing the timestamps. But it is worth noting that being able to toggle the switch by simply setting/unsetting the Also, my point mainly is that the clickable row should not have received a 'click' event, when the toggle was the capturing element. And therefore just setting/unsetting the Edit: Also note that extraneous 'click' event does not have the |
Based on the previous resolution of this ticket, this seems like a browser bug. Both If the |
And here is the Chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=689158 |
Actually
I did not realize that this discussion has concluded. Thanks. |
I thought we re-closed this back in April but apparently not. @NavidZ @patrickhlauke Is there still debate about this? I thought the conclusion was that this is all standard behavior and we didn't need any special mention for dealing with clicks and pointer capture. |
I don't think that's correct behavior if you're trying to build a drop-in replacement for a checkbox. It is the row's responsibility to handle the composition since it is the composed widget. You cannot expect your building blocks to anticipate every possible composition. |
@scottgonzalez your conclusion is totally right. I believe there is no need to change in the spec to address this. But if not we may need to make an exception for the click case solely for the compat reasons which is not my favorite. Either way I'm happy with closing this for now and only keep the browser bugs open for this issue. |
FWIW, current FF does not do the same thing. Since pointer/mouseup happen on different element than pointer/mouseup in capturing case, click isn't dispatched. Note, current Blink doesn't really seem to capture anything if one tries to capture pointer in a different document. Gecko has also an bug there, but different. Edge behaves sanely. |
We talked about this issue in the call and we all agreed with the proposed solution here. Basically stick to sending click to the first common ancestor of pointerdown and pointerup targets and pointercapture might changed the targets of pointerup/down and consequently it might effect the click targets. Right now neither Chrome nor Edge is following this. But they are going to fix it. Adding a v3 to keep an eye on this. |
I'm in process of backing out a hack which was added to be compatible with Blink's old behavior. |
Do we need to add anything specific in the spec that defines/clarifies this @smaug---- ? |
Blink does seem to fire lostpointercapture at odd time, but that isn't about this bug. |
so, just checking scenario 2 from the OP. Chrome fires:
Firefox currently fires:
but based on what @smaug---- is saying, this will be changed to match Chrome? However, checking Safari/MacOS and Safari/iOS, I get the same event sequence as Firefox:
Also seeing completely differing results with scenarios 3 and 4 now between Chrome, Firefox, and Safari (all completely different). Is this a discrepancy that is also happening with "the original specification"? |
Aha, I hadn't tested Safari. I was planning to revert the change which was added to Firefox to follow Chrome's old behavior. |
Safari/MacOS
|
Consider these scenarios and their outputs in the following page.
The output of Edge (and it is the same in current Chrome canary with pointer event flags on):
1. Mousedown on blue. Mouseup on blue.
blue pointerdown
Set pointer capture to blue div
blue gotpointercapture
blue pointerup
blue click
blue lostpointercapture
2. Mousedown on green. Mouseup on green.
green pointerdown
Set pointer capture to blue div
blue gotpointercapture
blue pointerup
green click
blue lostpointercapture
3. Mousedown on blue. Move to green. Mouseup on green.
blue pointerdown
Set pointer capture to blue div
blue gotpointercapture
blue pointerup
grey click
blue lostpointercapture
4. Mousedown on green. Move to blue. Mouseup on blue.
green pointerdown
Set pointer capture to blue div
blue gotpointercapture
blue pointerup
grey click
blue lostpointercapture
The question here is about the click event. In scenarios 2, 3, and 4 they all go to an element that doesn't have capture. Is that expected? Do we like to also direct click/contextmenu event to the captured element or suppress it altogether if it is not targeted at the capturing element? Or do we want to maybe call out that click or context menu events are not considered pointer events so they don't need to be redirected like capturing?
I have a feeling that sending the click event as above is incorrect with the capturing scenarios as it is creating an inconsistent flow of events. I think maybe suppressing is the most reasonable action. what do you guys think?
The text was updated successfully, but these errors were encountered: