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

On Wed, Apr 22, 2015 at 12:44 PM, Olli Pettay <olli@pettay.fi> wrote:

> 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.
>

I see.  And what should the behavior be if the "hint" is violated (call
preventDefault in a handler which said it wouldn't)?  I'm just worried
about predictability here.  I think if a developer says they won't call
preventDefault in a handler, we should ensure they can't (i.e. the event is
uncancelable), otherwise we may not be able to depend on it without
triggering bugs.

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:50:04 UTC