Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-94012

handlers in underlying or parent items should be able to avoid reacting when a higher-z or child item already handled it

    XMLWordPrintable

Details

    • d342b8f77658537c4fd3318982d2ae7a964b6426 (qt/qtdeclarative/dev), 29a2f67a8 (dev), 5855ba626 (6.4), 978bb5085 (6.5)

    Description

      In the Qt Quick 3D dynamictexture example, after fixing many other things, one remaining problem is that there is a TapHandler on the View3D item, and it tends to react regardless of what happened inside the 3D scene. But this is a general problem. Handlers are most often used on leaf items, but when you use them on parent/ancestor/underlying items, you often want it to be only as a last resort. But it turns out that accepting the event is not working so well, to stop propagation:

      1. the event must be pre-accepted, by tradition
      2. after delivering to one item (our first and best guess), we assume if the item did not reject the event, then we should stop
      3. but in case of touch events that wasn't sensible: items should be able to accept and reject individual touchpoints; so now there's a tangled mess of interactions between the event accept flag and the eventpoint accept flag
      4. we want to visit handlers even if the item has accepted, to give them a chance to take over the grab. Clearly, handlers cannot make much use of the flag then: if it was already accepted by an item, a handler can not make it "even more accepted".
      5. now we introduce subscenes for stuff like Qt Quick 3D. The View3D is an item subclass, which does picking and dispatches to subscenes. It could even happen that two fingers from one touchevent will be sent to two different subscenes. In practice, because of the old tradition that the event must be pre-accepted before visiting any item, we end up flip-flopping the accept flag(s) back and forth more times, until all possible long-term meaning is lost. About the only thing we can rely on now is that it's an old-fashioned way for an item subclass to indicate that it wants to handle the event, i.e. grab the eventpoint(s)... and that should be done sooner rather than later, while the flag state is fresh. It would be much better if items would just do the grab(s) explicitly, now that we have API for that in Qt 6.

      So one idea is for a handler to pay attention to whether the point(s) of interest already has an exclusive grabber. That's more concrete and specific and purposeful: a specific item or handler has explicitly taken responsibility by grabbing (or got the grab as a side effect of not-rejecting the event). But until now, we've been very permissive with handlers: the goal has been to let events propagate further, and handlers should be smart and conservative rather than "grabby". (E.g. DragHandler does not take the exclusive grab until you've dragged past the drag threshold in an allowed direction. Until then, it gets by with a passive grab.) So to avoid abrupt changes in behavior, this new flag will have to provide a way to opt-in to paying attention to the existing grabber. That TapHandler of last resort on View3D can set (or unset) it to indicate that it doesn't want to react if something else already has (unlike most TapHandlers, which can react in spite of whatever else is going on, as long as they receive the press event and are able to take a passive grab).

      Attachments

        Issue Links

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              srutledg Shawn Rutledge
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: