<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    On 2020-05-26 16:07, Shawn Rutledge wrote:<br>
    <blockquote type="cite"
      cite="mid:4067B6F7-A562-41FC-A047-CB862BDCA80A@qt.io">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <div class="">When I started working with Qt Quick in 2011, it
        wasn't too</div>
      <div class="">long before I began to notice that our vaunted
        support for multitouch (which</div>
      <div class="">still felt like an innovative new feature at the
        time, even though it had</div>
      <div class="">already been 5 years since the introduction of the
        iPhone) was quite flawed.</div>
      <div class="">Everyone was using MouseArea and Flickable, and
        those were not very good</div>
      <div class="">companions for the only components that actually
        supported multitouch:</div>
      <div class="">MultiPointTouchArea and PinchArea.  At some point
        someone had made the decision</div>
      <div class="">that touch is enough like mouse, that it would
        simplify things if we just</div>
      <div class="">convert touch events to synthetic mouse events and
        reuse the same logic for</div>
      <div class="">both.  Maybe that was decided before multi-touch
        screens were invented; it</div>
      <div class="">would have been ok for the resistive ones from the
        QTopia days, for example.</div>
      <div class="">But I thought that Qt Quick was newer than that, so
        it was an immediate</div>
      <div class="">facepalm moment when I realized that mistake was
        perpetuated there.  Finding</div>
      <div class="">ways to work around it has dominated a lot of my
        time working on Qt Quick ever</div>
      <div class="">since.  But Qt 5 has had such a long lifespan, and
        it wasn't possible to fix it</div>
      <div class="">in a fundamental way, without increasing complexity
        in ways that you might have</div>
      <div class="">noticed.</div>
      <div class=""><br class="">
      </div>
      <div class="">First, I did some patches to handle actual
        QTouchEvents in Flickable and</div>
      <div class="">MouseArea.  This naturally increases the code size
        quite dramatically, because</div>
      <div class="">QMouseEvent and QTouchEvent have too little in
        common, and the delivery</div>
      <div class="">strategy needs to be different.  QTouchEvents are
        broken up according to item</div>
      <div class="">boundaries, so that you can touch multiple Items at
        the same time with</div>
      <div class="">different fingers.  This complexity was already
        there in QQuickWindow, but I</div>
      <div class="">had to add a lot more code to Flickable and
        MouseArea.  It took a really long</div>
      <div class="">time to get all the tests to pass again.  Frederik
        was supportive, understood</div>
      <div class="">the point of what I was doing, and helped with it.
         Finally this work was ready</div>
      <div class="">to go into 5.5, but then reviewers still had too
        many doubts.  From one side it</div>
      <div class="">doesn't make a lot of sense to take a component
        called MouseArea, with all the</div>
      <div class="">limitations that name implies, and try to make it do
        the right things with</div>
      <div class="">touch events too.  (Even though users already
        expected it to handle taps and</div>
      <div class="">drags on touchscreens, because the touch->mouse
        synthesis had always been</div>
      <div class="">there.)  It was a lot of code to read and
        understand.  So we left it broken.</div>
      <div class="">And customers keep asking for those patches, so they
        still exist on a personal</div>
      <div class="">branch somewhere, which I haven't updated for quite
        a while.  To this day, if</div>
      <div class="">you use any touch-handling Item or pointer handler
        inside a Flickable, the</div>
      <div class="">results are often not very satisfying.  If you turn
        on pressDelay, it gets</div>
      <div class="">worse.  (Flickable never saw the touch press, only a
        synth-mouse press.  So it</div>
      <div class="">cannot replay a touch press either.  So the children
        will see a synthetic mouse</div>
      <div class="">press followed by a series of touch events, and will
        be required to see through</div>
      <div class="">the synth-mouse crap and treat the whole series as
        if the press had been a</div>
      <div class="">touch event too.  But… should filtering events that
        would otherwise go to the</div>
      <div class="">children really be Flickable’s responsibility?  What
        about replaying events</div>
      <div class="">after a press delay: monolithic Flickable should
        really do that too?) And </div>
      <div class="">because of another architectural abomination, making
        Item Views inherit </div>
      <div class="">Flickable, that affects even more use cases with
        ListView and TableView </div>
      <div class="">delegates.  (I have some hope of eventually
        rewriting Flickable using </div>
      <div class="">Pointer Handlers (that’s what FakeFlickable.qml
        demonstrates), but </div>
      <div class="">keeping it working the same both for subclasses and
        for end-users is quite</div>
      <div class="">a high bar.)</div>
      <div class=""><br class="">
      </div>
      <div class="">That experience taught me that we can only fix touch
        and mouse and Wacom tablet</div>
      <div class="">event delivery by making it the same for all of
        them.  That means we must make</div>
      <div class="">the events look enough alike that the same delivery
        code will work for all of</div>
      <div class="">them.  It's not possible with the leftover
        QInputEvent hierarchy from Qt 4 and</div>
      <div class="">earlier.  There is not even a consistently-named set
        of accessors for getting</div>
      <div class="">the coordinates from the various event types.</div>
      <div class=""><br class="">
      </div>
      <div class="">Continuing with the touch->mouse synthesis
        approach could maybe have been</div>
      <div class="">justified if we had support for multiple mice in Qt
        (so that there could be a</div>
      <div class="">virtual mouse for each touchpoint), and if we could
        agree that it's ok to</div>
      <div class="">disassociate touchpoints from each other and deliver
        them as separate events.</div>
      <div class="">I had a series of patches to deliver touch events
        that way.  It worked fine in</div>
      <div class="">practice, but for that prototype I had done some
        non-BC modifications in</div>
      <div class="">qevent.h (which could have been mitigated with
        differently-designed wrapper</div>
      <div class="">events).  But when we discussed it with Lars, he was
        very much against the idea</div>
      <div class="">of disassociating touchpoints, feeling strongly that
        points which belong to the</div>
      <div class="">same gesture need to be kept together.  As said,
        touch events get broken up</div>
      <div class="">during delivery in QQuickWindow; but if PinchHandler
        for example received</div>
      <div class="">multiple events, one for each finger involved in the
        pinch, it would have to</div>
      <div class="">update the gesture each time.  We could have
        mitigated that by adding an</div>
      <div class="">incrementing frame counter so that touchpoints could
        be re-associated.</div>
      <div class=""><br class="">
      </div>
      <div class="">But at that time, we concluded that we will go the
        other way in Qt Quick: every</div>
      <div class="">"pointer event" will have API appropriate for
        multiple points.  QMouseEvent can</div>
      <div class="">have hard-coded accessors for the single point that
        it carries; but touch</div>
      <div class="">events carry multiple points.  This is how we can
        eventually refactor the</div>
      <div class="">delivery code so that mouse and touch events are
        delivered the same way.  And</div>
      <div class="">we agreed to make the Qt Quick events a prototype of
        how we would refactor the</div>
      <div class="">QEvents in Qt 6.  So since Qt 5.8, Qt Quick has been
        delivering wrapper events</div>
      <div class="">instead: QQuickPointerEvent which contains instances
        of QQuickEventPoint.  Some</div>
      <div class="">of the delivery refactoring has been done:
        conservatively, because although few</div>
      <div class="">are willing to help, a lot more complain loudly when
        any existing usecase</div>
      <div class="">breaks.  And there are so many applications already.
         But the wrapper events</div>
      <div class="">made it possible to develop Pointer Handlers; and
        the goal has always been that</div>
      <div class="">those would retain QML source compatibility in Qt 6.
         The delivery mechanism</div>
      <div class="">for those adds a lot of flexibility.  After enough
        use cases have been ported</div>
      <div class="">over to using them, maybe we can eventually
        deprecate some of the most</div>
      <div class="">pernicious features that depend on complex delivery
        code that I'd like to get</div>
      <div class="">rid of in QQuickWindow; but progress has been so
        slow in other modules outside</div>
      <div class="">of Qt Quick itself, that it still seems too early to
        consider doing that in Qt</div>
      <div class="">6, because it would require heroic effort by a
        number of people over a short</div>
      <div class="">time period.</div>
      <div class=""><br class="">
      </div>
      <div class="">Anyway, the time has come to at least get the QEvent
        refactoring done, so that</div>
      <div class="">Qt Quick can go back to delivering them without
        wrappers, and so that Items can</div>
      <div class="">receive pointer events directly.  We have discussed
        this a few times already at</div>
      <div class="">various events.  At one QtCS Qt 6 planning session,
        I think in 2018 (or was it</div>
      <div class="">earlier?), I promised to do the refactoring for Qt
        6.  The goal is to break</div>
      <div class="">nothing in widgets: that is, QMouseEvent needs to
        keep its existing accessors.</div>
      <div class="">We will add new ones, and deprecate the ones that
        are named inconsistently and</div>
      <div class="">the ones that provide integer coordinates.  The same
        for the other event types.</div>
      <div class=""> QTouchEvent::TouchPoint is a bit special: it will
        be replaced by the</div>
      <div class="">QEventPoint that every QPointerEvent contains at
        least one of.  So far it looks</div>
      <div class="">like I can use "using" to make
        QTouchEvent::TouchPoint an alias of QEventPoint,</div>
      <div class="">for the sake of source compatibility.</div>
      <div class=""><br class="">
      </div>
      <div class="">I think the result will look something like this:</div>
      <div class=""><br class="">
      </div>
      <div class=""><img apple-inline="yes"
          id="4B81B323-AB51-4D9D-8C3B-E9D1AD187F96"
          src="cid:part1.4D329614.AF7284E1@tungware.se" class=""></div>
      <div class=""><br class="">
      </div>
      <div class="">What I started with a few months ago was adding
        const QInputDevice *device() to</div>
      <div class="">QInputEvent.  We have seen that the MouseEventSource
        enum does not provide</div>
      <div class="">enough information.  E.g. in Controls we had to
        assume in some places that if a</div>
      <div class="">mouse event is SynthesizedByQt, then it's
        synthesized from a touchscreen by</div>
      <div class="">QQuickWindow during delivery of the original
        QTouchEvent.  That's not always</div>
      <div class="">true (there are other places where synthesis
        occurs), and resulted in some</div>
      <div class="">bugs.  Now that we're trying to fully support Wacom
        tablets in Qt Quick, a</div>
      <div class="">synth-mouse event could come from that.  So I want
        to completely replace</div>
      <div class="">MouseEventSource with the device pointer, so that
        the event consumer can see</div>
      <div class="">specifically which device the event came from, and
        thus can adjust behavior</div>
      <div class="">depending on the specific type of device, its
        capabilities, the screen area</div>
      <div class="">that the device can access (e.g. a touchscreen input
        device or Wacom tablet is</div>
      <div class="">probably mapped to a specific QScreen or QWindow),
        etc.  This way we can also</div>
      <div class="">begin to support multiple mice and multiple "seats"
        (in the Wayland sense) at</div>
      <div class="">the same time.  But it imposes a new requirement on
        platform plugins: to create</div>
      <div class="">the QInputDevice instances.  The plugins that I know
        about all do device</div>
      <div class="">discovery anyway, though; they have just been using
        internal ad-hoc data</div>
      <div class="">structures of their own, and not exposing those
        devices to</div>
      <div class="">QWindowSystemInterface.  I've been working on the
        xcb plugin so far, since I</div>
      <div class="">understand that one the best, and it already
        supports multiple seats after a</div>
      <div class="">fashion (there can be multiple core pointers and
        core keyboards, and they can</div>
      <div class="">be associated with each other; there just isn't a
        seat name, but I can make one</div>
      <div class="">up).</div>
      <div class=""><br class="">
      </div>
      <div class="">The fantastic result of that should be that event
        delivery code can finally be</div>
      <div class="">device-agnostic!  QQuickWindow and QQuickFlickable
        will no longer need to treat</div>
      <div class="">mouse and touch events differently, and Wacom tablet
        events will go through the</div>
      <div class="">same way too.  Flickable should be able to blindly
        replay a copy of whatever event</div>
      <div class="">it got when the pressDelay timer fires, without
        caring about every piece of data </div>
      <div class="">inside. Only the final event consumer (QQuickItem or
        Pointer Handler or even</div>
      <div class="">a QWidget subclass) will need to care about the
        device-specific details, and it</div>
      <div class="">will have all the information necessary for very
        finely-tuned behavior.  Now we</div>
      <div class="">can finally add virtual functions to QQuickItem to
        handle pointer events, so</div>
      <div class="">not only Pointer Handlers will be able to do that.
         And we will open the</div>
      <div class="">possibility to refactor event delivery code in other
        parts of Qt later on.  It</div>
      <div class="">should become possible to fix most of the open bugs
        related to handling mouse</div>
      <div class="">and touch events in Qt Quick and Controls during the
        Qt 6 series.</div>
      <div class=""><br class="">
      </div>
      <div class="">Because we will make QPointerEvent look as much as
        possible like</div>
      <div class="">QQuickPointerEvent, we will maintain QML source
        compatibility for anyone who</div>
      <div class="">just started using pointer handlers.  Of course the
        goal is for older stuff</div>
      <div class="">like MouseArea and Flickable and Controls that we
        can choose appropriate API</div>
      <div class="">changes, not be required to make them because of
        event changes.  QPointerEvent</div>
      <div class="">will be a gadget instead of a QObject wrapper, but
        it will have the same</div>
      <div class="">properties, so to the extent that it's exposed in
        QML API (which is not much),</div>
      <div class="">it will look the same.  It will also look enough
        like a QMouseEvent and enough</div>
      <div class="">like a QTouchEvent that we will have source
        compatibility in virtual functions</div>
      <div class="">that handle those, too.  Hopefully.</div>
      <div class=""><br class="">
      </div>
      <div class="">After proving that we have also maintained source
        compatibility as much as</div>
      <div class="">possible (including in the great heap of widget code
        in the world), we still</div>
      <div class="">end up with a lot of deprecated methods that should
        be replaced over time</div>
      <div class="">(QPoint pos() -> QPointF position() and such).
         For that purpose I want to add</div>
      <div class="">a feature to clazy or develop some other clang-based
        tooling which can fix all</div>
      <div class="">of our modules, and also be available to customers
        to make the same</div>
      <div class="">replacements in their code bases.  If we end up with
        any SC breaks, it's a</div>
      <div class="">possible fallback position that at least we can
        deliver a tool to fix them.</div>
      <div class=""><br class="">
      </div>
      <div class="">Beyond that, we probably ought to do something about
        native gestures.  Another</div>
      <div class="">reason Qt Quick is so complex is that it started out
        assuming it will be given</div>
      <div class="">only raw touch events and needs to do gesture
        recognition itself; but now</div>
      <div class="">gestures have gone mainstream on most platforms, so
        we could be getting</div>
      <div class="">QNativeGestureEvents from most of them, especially
        from touchpads.  But I</div>
      <div class="">didn't get as far as I should have over the last
        couple of years just exploring</div>
      <div class="">how to improve that aspect of Qt, and the platform
        plugin maintainers</div>
      <div class="">have not gotten around to adding support for native
        gestures to all the</div>
      <div class="">platforms that could have them, either.  I wish we
        could get rid of the gesture</div>
      <div class="">recognizer in the widgets module completely; but
        customers will not be</div>
      <div class="">satisfied unless we then have native gesture
        recognition on all platforms where</div>
      <div class="">it's possible.  Some of them want to continue doing
        custom gesture recognition,</div>
      <div class="">too.  But we have QGestureEvent (for the widget
        gesture recognizer) and</div>
      <div class="">QNativeGestureEvent (for gesture events that come
        from the QPA plugin) as</div>
      <div class="">separate types.  We're running out of time to figure
        out whether we can unify</div>
      <div class="">those two, just to make it less confusing for
        applications.  I guess it's not</div>
      <div class="">so terrible to keep the events separate if we still
        have to keep the old</div>
      <div class="">gesture framework intact; but do we?</div>
      <div class=""><br class="">
      </div>
      <div class="">So that's the status of pointer event handling.  And
        I'm still working mostly</div>
      <div class="">alone on it.  It seems with our schedule that the
        QEvent API, and all other</div>
      <div class="">APIs that need to change as a result of that, need
        to be stabilized by the end</div>
      <div class="">of June.  I still think I can get the broad strokes
        done if nobody and no</div>
      <div class="">unexpected bugs get in the way this time, and the
        +2's come quickly (keeping in</div>
      <div class="">mind that the perfect is the enemy of the good, and
        every change is subject to</div>
      <div class="">ongoing incremental changes later).  (It looks like
        my time is limited to make</div>
      <div class="">other API changes in Qt Quick, since this is taking
        most of it.)  Is anyone</div>
      <div class="">interested in helping?</div>
      <br>
    </blockquote>
    Hi, I tried some QGestureEvents this winter in my first Qt iOS app,
    and got bored having to use 3 fingers on my iPhone for swiping (1
    finger seems to be the norm on Android and iPhones). And I
    discovered that it was pretty easy to integrate the vanilla standard
    iOS 1-finger swiping with Qt, see
    <a class="moz-txt-link-freetext" href="https://bugreports.qt.io/browse/QTBUG-81042">https://bugreports.qt.io/browse/QTBUG-81042</a><br>
    <br>
    If you're thinking about refactoring also for iOS, maybe my
    suggestion can help...<br>
    <br>
    Rgrds Henry<br>
    <br>
  </body>
</html>