- From: sb3nder via GitHub <noreply@w3.org>
- Date: Fri, 10 Oct 2025 11:09:00 +0000
- To: public-pointer-events@w3.org
sb3nder has just created a new issue for https://github.com/w3c/pointerevents: == Clarify drag and drop events == Pointer events seem different for every combination of pointer input and browser, so before filing bugs, I would like to know what is considered ok behavior. First, I have two questions: When the [Pointer Event spec says](https://w3c.github.io/pointerevents/#suppressing-a-pointer-event-stream): > <p>The <a data-link-type="dfn" data-cite="infra" data-cite-path="" data-cite-frag="user-agent" href="https://infra.spec.whatwg.org/#user-agent">user agent<!---0.272262%--></a> <em class="rfc2119">MUST<!---0.272262%--></em> run the following steps to <a href="#dfn-suppress-a-pointer-event-stream" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-suppress-a-pointer-event-stream-2">suppress a pointer event stream</a>:</p> > <ul> > <li>Fire a <!---0.272262%--><a data-link-type="idl" data-xref-type="attribute|dict-member|const" data-link-for="GlobalEventHandlers" data-xref-for="GlobalEventHandlers" href="#dfn-pointercancel" class="internalDFN" id="ref-for-dfn-pointercancel-2"><code>pointercancel<!---0.272262%--></code></a><!---0.272262%--> event.</li> > <li>Fire a <!---0.272262%--><a data-link-type="idl" data-xref-type="attribute|dict-member|const" data-link-for="GlobalEventHandlers" data-xref-for="GlobalEventHandlers" href="#dfn-pointerout" class="internalDFN" id="ref-for-dfn-pointerout-4"><code>pointerout<!---0.272262%--></code></a><!---0.272262%--> event.</li> > <li>Fire a <!---0.272262%--><a data-link-type="idl" data-xref-type="attribute|dict-member|const" data-link-for="GlobalEventHandlers" data-xref-for="GlobalEventHandlers" href="#dfn-pointerleave" class="internalDFN" id="ref-for-dfn-pointerleave-4"><code>pointerleave<!---0.272262%--></code></a><!---0.272262%--> event.</li> > <li><a href="#dfn-implicitly-release-the-pointer-capture" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-implicitly-release-the-pointer-capture-2">Implicitly release the pointer capture</a> if the pointer is currently captured.</li> > </ul> Is it fine even if pointerout and pointerleave aren't fired immediately, but after a while? Why would the source node match `:active` and `:hover`, and what is the purpose of that? I asked this in https://github.com/whatwg/html/issues/11771 , but maybe it's more of a CSS question. <details> <summary>Not knowing much, I would have expected something like this</summary> ``` pointerdown <DIV> section:active:hover div:active:hover pointermove <DIV> section:active:hover div:active:hover dragstart <DIV> section:active:hover div:active:hover pointercancel <DIV> pointerout <DIV> pointerleave <DIV> pointerleave <SECTION> dragenter <DIV> ... dragleave <SECTION> dragend <DIV> ``` </details> --- Test page: https://codepen.io/sb3nder/full/GgoEoLW Structure: ```html <section> <div draggable="true">drag me</div> </section> ``` Step to reproduce: drag div outside section. --- ## Chrome <details> <summary>mouse drag (desktop)</summary> ``` pointerdown <DIV> section:active:hover div:active:hover pointermove <DIV> section:active:hover div:active:hover dragstart <DIV> section:active:hover div:active:hover pointercancel <DIV> section:active:hover div:active:hover dragenter <DIV> section:active:hover div:active:hover ... dragleave <SECTION> section:active:hover div:active:hover dragend <DIV> pointerout <DIV> pointerleave <DIV> pointerleave <SECTION> ``` </details> --- <details> <summary>mouse drag fast (desktop)</summary> ``` pointerdown <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active pointerleave <DIV> section:active:hover div:active pointerover <SECTION> section:active:hover div:active pointermove <SECTION> section:active:hover div:active dragstart <DIV> section:active:hover div:active pointercancel <SECTION> section:active:hover div:active dragenter <SECTION> section:active:hover div:active ... dragleave <SECTION> section:active:hover div:active dragend <DIV> pointerout <SECTION> pointerleave <SECTION> ``` </details> Source node doesn't match `:hover`. --- </details> <details> <summary>touch drag (desktop)</summary> ``` pointerdown <DIV> pointerdown <DIV> gotpointercapture <DIV> section:active:hover div:active:hover pointermove <DIV> section:active:hover div:active:hover dragstart <DIV> section:active:hover div:active:hover dragenter <DIV> section:active:hover div:active:hover ... dragleave <SECTION> section:active:hover div:active:hover pointercancel <DIV> section:active:hover div:active:hover lostpointercapture <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerleave <SECTION> section:active:hover div:active:hover dragend <DIV> ``` </details> `pointercancel` is fired after the DND operation, instead of before, as the [living spec states](https://html.spec.whatwg.org/#drag-and-drop-processing-model): >10. <p><a id="drag-and-drop-processing-model:fire-a-pointer-event" href="https://w3c.github.io/pointerevents/#dfn-fire-a-pointer-event" data-x-internal="fire-a-pointer-event">Fire a pointer event</a> at the <a href="#source-node" id="drag-and-drop-processing-model:source-node-9">source node</a> named <code id="drag-and-drop-processing-model:event-pointercancel"><a data-x-internal="event-pointercancel" href="https://w3c.github.io/pointerevents/#the-pointercancel-event">pointercancel</a></code>, and fire any other follow-up events as required by <cite>Pointer Events</cite>. <a href="#refsPOINTEREVENTS">[POINTEREVENTS]</a></p> I don't think `dragend` timing is right. --- <details> <summary>pen drag (desktop)</summary> ``` pointerdown <DIV> section:hover div:hover gotpointercapture <DIV> section:hover div:hover pointermove <DIV> section:hover div:hover dragstart <DIV> section:active:hover div:active:hover dragenter <DIV> section:active:hover div:active:hover ... dragleave <SECTION> section:active:hover div:active:hover dragend <DIV> lostpointercapture <DIV> pointerout <DIV> pointerleave <DIV> pointerleave <SECTION> pointerout <DIV> pointerleave <DIV> pointerleave <SECTION> ``` </details> `pointercancel` is not fired as the living spec states. `pointerout` and `pointerleave` are fired a second time. --- <details> <summary>touch drag (Android)</summary> ``` pointerdown <DIV> dragstart <DIV> section:active:hover div:active:hover contextmenu <DIV> section:active:hover div:active:hover gotpointercapture <DIV> section:active:hover div:active:hover pointercancel <DIV> section:active:hover div:active:hover lostpointercapture <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerleave <SECTION> section:active:hover div:active:hover dragenter <DIV> section:active:hover div:active:hover dragover <DIV> section:active:hover div:active:hover dragenter <SECTION> section:active:hover div:active:hover dragleave <DIV> section:active:hover div:active:hover dragover <SECTION> section:active:hover div:active:hover dragleave <SECTION> section:active:hover div:active:hover dragend <DIV> ``` </details> This is more in line with what I would have expected. --- ## Firefox <details> <summary>mouse drag (desktop)</summary> ``` pointerdown <DIV> section:hover div:hover pointermove <DIV> section:active:hover div:active:hover dragstart <DIV> section:active:hover div:active:hover pointercancel <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerleave <SECTION> section:active:hover div:active:hover pointerover <DIV> section:active:hover div:active:hover pointerenter <SECTION> section:active:hover div:active:hover pointerenter <DIV> section:active:hover div:active:hover dragenter <DIV> section:active:hover div:active:hover ... dragleave <SECTION> section:active:hover div:active:hover dragend <DIV> section:active:hover div:active:hover pointermove <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerleave <SECTION> section:active:hover div:active:hover ``` </details> Pointer events after `dragstart` are strange. `:active` sticks. --- <details> <summary>mouse drag fast (desktop)</summary> ``` pointerdown <DIV> section:hover div:hover dragstart <DIV> section:active:hover div:active:hover pointercancel <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerleave <SECTION> section:active:hover div:active:hover pointerover <DIV> section:active:hover div:active:hover pointerenter <SECTION> section:active:hover div:active:hover pointerenter <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerover <SECTION> section:active:hover div:active:hover pointermove <SECTION> section:active:hover div:active:hover dragenter <SECTION> section:active:hover div:active ... dragleave <SECTION> section:active:hover div:active dragend <DIV> section:active:hover div:active pointermove <SECTION> section:active:hover div:active pointerout <SECTION> section:active:hover div:active pointerleave <SECTION> section:active:hover div:active ``` </details> Source node doesn't match `:hover`. --- <details> <summary>touch drag (tap & hold)(desktop)</summary> ``` pointerdown <DIV> gotpointercapture <DIV> pointerup <DIV> lostpointercapture <DIV> pointerout <DIV> pointerleave <DIV> pointerleave <SECTION> click <DIV> section:active:hover div:active:hover pointerover <DIV> section:active:hover div:active:hover pointerenter <SECTION> section:active:hover div:active:hover pointerenter <DIV> section:active:hover div:active:hover pointerdown <DIV> section:active:hover div:active:hover dragstart <DIV> section:active:hover div:active:hover dragenter <DIV> section:active:hover div:active:hover ... dragleave <SECTION> section:active:hover div:active:hover gotpointercapture <DIV> section:active:hover div:active:hover pointercancel <DIV> section:active:hover div:active:hover lostpointercapture <DIV> section:active:hover div:active:hover pointerout <DIV> section:active:hover div:active:hover pointerleave <DIV> section:active:hover div:active:hover pointerleave <SECTION> section:active:hover div:active:hover dragend <DIV> ``` </details> `pointercancel` is fired after the DND operation. I don't think `dragend` timing is right. --- Please view or discuss this issue at https://github.com/w3c/pointerevents/issues/555 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Friday, 10 October 2025 11:09:01 UTC