W3C home > Mailing lists > Public > public-pointer-events@w3.org > April to June 2015

Re: Non-scroll-blocking wheel events listeners / relationship to PEWG?

From: Olli Pettay <olli@pettay.fi>
Date: Wed, 22 Apr 2015 09:44:33 -0700
Message-ID: <5537CFF1.5000607@pettay.fi>
To: Rick Byers <rbyers@chromium.org>
CC: "public-pointer-events@w3.org" <public-pointer-events@w3.org>, Jared Duke <jdduke@chromium.org>, Nathaniel Duca <nduca@chromium.org>
I was thinking  { preventDefault: "never" } would be just a hint. In order to be backwards compatible it would not affect at all how any other parts 
of the DOM Events API works.
But it could affect to the behavior of the UA while it is dealing with possibly asynchronous stuff, like touch/mouse/wheel.


On 04/22/2015 09:13 AM, Rick Byers wrote:
> On Tue, Apr 21, 2015 at 11:24 AM, Olli Pettay <olli@pettay.fi <mailto:olli@pettay.fi>> wrote:
>
>     On 04/21/2015 08:00 AM, Olli Pettay wrote:
>
>         On 04/21/2015 07:10 AM, Rick Byers wrote:
>
>             On Tue, Apr 21, 2015 at 9:43 AM, Olli Pettay <olli@pettay.fi <mailto:olli@pettay.fi> <mailto:olli@pettay.fi <mailto:olli@pettay.fi>>> wrote:
>
>                  On 04/15/2015 08:31 AM, Rick Byers wrote:
>
>                      It's common for libraries (eg. ads frameworks) to want to passively track some notion of user interaction with the page.  For
>             touch, Pointer
>                      Events is
>                      a good API for this because the event listeners don't block scrolling.  But what about for wheel events?  Adding a document wheel
>             event
>                      handler for
>                      this (when none existed previously) is bad for scroll performance.
>
>
>                  I wonder how bad the performance issues actually are here. Comparing to pointer events, wheel events fire rarely, and there are just
>             couple of them
>                  in a row. So an implementation could have enough time to hit test and dispatch an event before the next animation frame tick.
>                  (I'm a bit worried making the platform more complicated than it needs to be.)
>
>
>             Why do you say there's just a couple of them in a row?
>
>         I'm comparing to touch events for example. But you're right, pixel level wheel events happen rather often.
>
>             I'm thinking primarily of scrolling on high-quality touchpads here (eg. macbooks,
>             chromebooks).  There wheel events are similar to touchmove events in terms of frequency and duration during a scroll.  That said, there
>             are some big
>             differences:
>             1) wheel scrolling tends to be done on much faster devices than touch scrolling
>             2) indirect manipulation is more forgiving psychologically than direct manipulation (since with touch your finger acts as a point of
>             reference that
>             makes at least latency substantially more noticeable, but I'm not sure how it affects the perception of smoothness).
>
>             So I agree it may not be that important.  But as we look to provide control over the blocking behavior of touch and scroll handlers (eg.
>             scroll-blocks-on proposal <https://docs.google.com/a/chromium.org/document/d/1aOQRw76C0enLBd0mCG_-IM6bso7DxXwvqTiRWgNdTn8/edit>), I'm
>             trying to
>             consider wheel handlers also for consistency and completeness.
>
>
>
>         Would wheel+ctrl behave differently to wheel? Or other event+modifier combinations? (I think events should be for consistency dispatched the
>         same way,
>         either always async or always sync, whether or not there are modifiers)
>
>
>                      Should PEWG consider trying to address this scenario?
>
>                      One option (that I think we've discussed a bit in some form) would be to have a new non-blocking event ('pointerwheel' maybe?)
>             and a new
>                      'wheel-action' CSS property (similar to touch-action) that declaratively says what sort of wheel movement should cause
>             scrolling.  This would
>                      be most
>                      like pointer events, but adding new event types for this seems unfortunate (now what about keyboard scrolling?).
>
>                  well, keyboard scrolling doesn't cause wheel events either.
>
>
>             Right, but the same problem exists there in theory.  Perhaps there should be some mechanism to permit keyboard event listeners that won't
>             block
>             scrolling?  But this is even less important than the wheel case IMHO.
>
>                      Another option would be to augment event handler registration with an options dictionary (instead of just the single 'capture'
>             boolean).  Eg:
>                      addEventListener('wheel', myHandler, {blocksScroll: false});
>
>                  Definitely not this. This is not a strong enough case to change an API which has existed for 15+ years, IMO.
>
>
>             Would you feel any better about this if the API had a new name?
>
>         Not really
>
>             Although I share your gut reaction that we shouldn't be messing with
>             addEventListener, in debates internally I haven't been able to formulate a clear technical argument against extending addEventListener to
>             have some
>             mechanism for additional options.  If what the developer wants to say is "I want to observe wheel events, but I'm never going to call
>             preventDefault
>             on them so please don't block scrolling"
>
>         Aha, if you formulate the behavior in a bit different way, then it becomes more generic...
>         So, "I'm not going to call preventDefault()" might be such, useful also in other cases than just with wheel.
>         A bit odd API, but might be useful, really useful.
>
>         enum PreventDefaultHints {
>             "never"
>             ""
>         };
>         addEventListener("wheel", listener, { preventDefault: "never",
>                                                 capture: true});
>
>
> That's an interesting idea. If all handlers say they they'll never preventDefault then Event.cancelable should be false so that preventDefault is
> ignored (Chrome also generates a console warning if you attempt to cancel an uncancelable event).  Perhaps we'd want to phrase the API as indicating
> whether you want cancelable events or not rather than a "prevent default hint".
>
> A couple issues:
> 1) What if one handler asks for cancelable events and other asks for uncancelable events?  Should 'Event.cancelable' just be true on the events that
> are fired?  That risks developers having bugs where their handler accidentally relies on being able to cancel an event they requested to be
> uncancelable (due to some other component on the test page asking for cancelable events).  Perhaps we should allow Event.cancelable to change for each
> handler receiving the event?
> 2) Only some event types support cancellation.  I think it's fine to request cancelable=false on events that are always cancelable (just indicating
> your intent not to cancel them yourself).  But what if a developer requests cancelable events of a type that can never be canceled (eg. scroll
> events)?  Should it fail somehow? Should a developer be able to feature detect this somehow?
>
> 3) The one thing my earlier proposal here (or my scroll-blocks-on design) could support that this can't is scroll event listeners that block
> scrolling.  scroll events should never be cancelable, but we argue (to much debate) that there are some limited scenarios where we should allow a site
> to opt-in to scroll event handlers that run in-sync with scrolling.  You could argue that scenario is different enough that it either should never be
> supported or should require a different API.
>
>     ...but unfortunately that is not backwards compatible. If we could find a nice backwards compatible syntax.
>     addEventListener("wheel", listener, true, { preventDefault: "never" }); would behave fine, but is a bit long.
>     Would it be good enough?
>
>
> Why not?  Couldn't we either use overloading <http://www.w3.org/TR/WebIDL/#idl-overloading> (boolean is "distinguishable" from dictionary) or union
> types <http://www.w3.org/TR/WebIDL/#idl-union>?
>
>             then it does feel most natural to allow them to say that at event handler registration time somehow.  Any
>             suggestion for how such a mechanism should look?
>
>                      A third option is to leave the event system unmodified and rely on a CSS property to independently control when events block
>             scrolling.  This
>                      is what
>                      my 'scroll-blocks-on
>             <https://docs.google.com/document/d/1aOQRw76C0enLBd0mCG_-IM6bso7DxXwvqTiRWgNdTn8/edit#heading=h.wi06xpj70hhd>' proposal
>                      does (for
>                      which I've landed an experimental partial implementation in blink).  A key downside here is the 'spooky action at a distance'
>             between event
>                      registration and CSS property application.  Eg. how to multiple components each putting wheel handlers on the document
>             effectively co-ordinate
>                      on what
>                      the combined effect on the document should be? For this particular scenario (not one of the original goals of scroll-blocks-on)
>             indicating
>                      intent at
>                      event registration time seems much better for composition.
>
>                  But this would work with keyboard events too.
>
>                  In fact, what do we actually want here. wheel/key event handling, or notification about what user just did?
>                  So, would some kind intentional event work here?
>
>                  addEventListener("userIntention", function(e) {
>                     if (e.intention == "scroll") {
>                       // do something
>                     }
>                  });
>                  Or should "scroll" event be extended so that it tells what triggered the action? That can be a bit difficult to implement, but might
>             be rather
>                  nice to have.
>
>
>             The main use case I've got in mind is activity tracking.  Most ad frameworks have some system (like it or not) of monitoring user activity
>             (where was
>             the mouse cursor, where on the page is the user touching, etc.).  Today this hurts scroll performance substantially.  Pointer events
>             solves this for
>             touch (although I'm not sure yet whether that's good enough - we may still pursue a solution with touch events), but no-one has proposed a
>             good design
>             that could also address the touchpad case (scroll-blocks-on gets awkward in the composition cases - all components on the page need to use
>             some
>             library/pattern to mediate the combination of desires from the different components).
>
>             So for that use case, I don't think a scroll intention is really adequate.  We could have some generic 'user activity' intention that
>             included a
>             screen co-ordinate, but that would quickly end up looking pretty redundant with pointer events.
>
>
>         well, pointer events don't deal with key events.
>
>         I can see non-ad use cases for user-activity events too (do some heavy clean up in the page while user isn't interacting with it and there are
>         no rAF
>         callbacks called and so.)
>
>
>
>
>
>
>
>                      See some more chromium-specific debate here <https://groups.google.com/a/chromium.org/forum/#!topic/input-dev/4B7VFPZvHY0>.
>
>                      Thoughts?  Out of scope for this group?
>
>
>                  Sounds like out of scope for this group, but I don't really mind whether discussed here or in WebApps.
>
>
>                  -Olli
>
>
>
>
>                      Rick
>
>
>
>
>
>
>
Received on Wednesday, 22 April 2015 16:45:09 UTC

This archive was generated by hypermail 2.3.1 : Saturday, 16 May 2015 00:31:59 UTC