- From: Rick Byers <rbyers@chromium.org>
- Date: Wed, 22 Apr 2015 12:49:13 -0400
- To: Olli Pettay <olli@pettay.fi>
- Cc: "public-pointer-events@w3.org" <public-pointer-events@w3.org>, Jared Duke <jdduke@chromium.org>, Nathaniel Duca <nduca@chromium.org>
- Message-ID: <CAFUtAY9XnTPBOvv-xqb92E09VMJtSTeX8-SDoS8M__ArLcSH7w@mail.gmail.com>
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