Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. iOS (while updating) feeds touch events to QUIWindow -> weirdness!
Forum Updated to NodeBB v4.3 + New Features

iOS (while updating) feeds touch events to QUIWindow -> weirdness!

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
11 Posts 2 Posters 797 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    barbicels
    wrote on last edited by barbicels
    #1

    environment: Qt/QML 5.15.2, iOS 15.2.1

    To solve this bug, I need the help of a developer who really understands iOS event processing.

    My app’s QML code responds to a button press by opening a modal message dialog (QtQuick.Dialogs 1.2 MessageDialog). On iOS Simulator (all iPhone-model runtimes) and on all older-model iPhones, the dialog is painted as expected once processEvents is called and events are dispatched, but, on newer iPhones (12/13), the event loop never gets those focus and update events and just hangs, waiting for the user to interact with a dialog that wasn’t painted.

    To debug this, on those three platforms, I followed the traceback down to the point where iOS sends the synthesized touch event to Qt via its Objective-C QUIWindow object; there is no Qt code below this point in the stack, so it’s reasonable to think that the call stack from there to the bottom should be the same in all three cases. But it isn’t!

    In the (failure) case of the newer iPhones only, the call stack looks like this:

    -[QUIWindow sendEvent:]
    -[UIApplication sendEvent:]
    __dispatchPreprocessedEventFromEventQueue
    __processEventQueue
    updateCycleEntry
    _UIUpdateSequenceRun
    schedulerStepScheduledMainSection
    runloopSourceCallback
    __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
    …
    

    And in the other (success) cases, it looks like this:

    -[QUIWindow sendEvent:]
    -[UIApplication sendEvent:]
    __dispatchPreprocessedEventFromEventQueue
    __processEventQueue
    __eventFetcherSourceCallback
    __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
    …
    

    So, it appears, the problem occurs when iOS dispatches the touch event to Qt in the course of its own update cycle rather than the expected way (straight from CFRunLoop). My theory, then, is that Qt’s processEvents is blinded to the update events that result from opening its dialog, because iOS thinks its own update cycle isn’t done yet; indeed, if I stop processing Qt events myself and let the stack unwind to let iOS finish its own update cycle, the necessary Qt events are then generated and handled, and the dialog is painted.

    Caveat: There is C++ code and a nested event loop involved here, which is unavoidable because synchronous C++ code is signaling declarative QML code to run a modal dialog. (The C++ code is a multi-platform procedural library that signals QML in mobile versions, but more C++ code in computer versions, when it needs to interact with the user.) I’m aware that Nested Event Loops Are Bad in QML, but [a] the nested event loop is only created in response to this oddly dispatched touch event, and [b] this code has always worked perfectly on every other device (including Android) and even on iOS 15.2.1 on older devices. Further, it seems that dispatching touch events from inside iOS’s own update cycle (thus forcing any Qt-on-iOS code’s GUI response to eschew QEventLoop/processEvents) is bound to be a problem — the only question there being, did I bring on that questionable iOS habit somehow?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      @barbicels said in iOS (while updating) feeds touch events to QUIWindow -> weirdness!:

      5.12.2

      Not a direct answer sorry but did you try to test your issue with a more recent version of Qt to see if you get into the same kind of issue ? I understand you might be locked to that version of Qt but this would allow to ensure it's something that is affecting other versions of the 5.12 series as well as maybe the 5.15 or even 6.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      B 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        @barbicels said in iOS (while updating) feeds touch events to QUIWindow -> weirdness!:

        5.12.2

        Not a direct answer sorry but did you try to test your issue with a more recent version of Qt to see if you get into the same kind of issue ? I understand you might be locked to that version of Qt but this would allow to ensure it's something that is affecting other versions of the 5.12 series as well as maybe the 5.15 or even 6.

        B Offline
        B Offline
        barbicels
        wrote on last edited by
        #3

        @SGaist
        Argh, that was a typo, now edited. It’s 5.15.2 (LTS), open source.

        SGaistS 1 Reply Last reply
        0
        • B barbicels

          @SGaist
          Argh, that was a typo, now edited. It’s 5.15.2 (LTS), open source.

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @barbicels said in iOS (while updating) feeds touch events to QUIWindow -> weirdness!:

          @SGaist
          Argh, that was a typo, now edited. It’s 5.15.2 (LTS), open source.

          Damn ! So it's one less hope of it working on a later version. Can you try with 6.2 ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          B 1 Reply Last reply
          0
          • SGaistS SGaist

            @barbicels said in iOS (while updating) feeds touch events to QUIWindow -> weirdness!:

            @SGaist
            Argh, that was a typo, now edited. It’s 5.15.2 (LTS), open source.

            Damn ! So it's one less hope of it working on a later version. Can you try with 6.2 ?

            B Offline
            B Offline
            barbicels
            wrote on last edited by
            #5

            @SGaist
            I shall have to try that, but it seems profoundly weird that iOS would dispatch a touch event while spinning its own update cycle, and only on newer hardware (suggesting some sort of race condition). Hard to see how Qt could be responsible for that behaviour, or work around it in any way that doesn’t effectively preclude the use of a Qt event loop as part of the GUI response to the touch event.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Agreed

              By the way, since you can reliably reproduce that behaviour, I think you should consider opening a ticket on the Qt bug report system. Even if not directly Qt's problem, it will at least make it known and possibly pushed upstream as well.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              B 2 Replies Last reply
              1
              • SGaistS SGaist

                Agreed

                By the way, since you can reliably reproduce that behaviour, I think you should consider opening a ticket on the Qt bug report system. Even if not directly Qt's problem, it will at least make it known and possibly pushed upstream as well.

                B Offline
                B Offline
                barbicels
                wrote on last edited by
                #7

                @SGaist
                Will do.
                Meantime, searching for updateCycleEntry turned up some other very recent reports that likewise suggest a pattern of odd behavior on recent iPhones and with similar tracebacks, where GUI events are dispatched while inside updateCycleEntry:
                1
                2
                3

                1 Reply Last reply
                1
                • SGaistS SGaist

                  Agreed

                  By the way, since you can reliably reproduce that behaviour, I think you should consider opening a ticket on the Qt bug report system. Even if not directly Qt's problem, it will at least make it known and possibly pushed upstream as well.

                  B Offline
                  B Offline
                  barbicels
                  wrote on last edited by
                  #8

                  @SGaist
                  Using an event filter and category logging rules, I was able to distinguish the success (simulator and older iPhones) and failure (newer iPhones) cases:
                  The failure case results from the application window receiving an UpdateRequest event after the user touches the QML Switch item and before the resulting TouchEnd event causes that item’s onSwitchChanged handler to execute; in the success case, that update event is processed after the touch event.
                  That would explain why the iOS run loop is in its update cycle at the time, which in turn explains why the code that runs in response to the touch event doesn’t receive more update events in its nested Qt run loop as would be required to paint the confirmation dialog opened in response to the switch change.
                  Knowing that Nested Event Loops Are Bad, I have thrown a Qt.callLater into the onSwitchChanged handler so that the handler returns to the main event loop before JS invokes any QObject methods that could create a nested event loop leading to “stacked” QML event handling. This appears to work, so I’ll make the same change in other places where such event-handler “stacking” could happen, and hope for the best.
                  Thank you for the help and encouragement.

                  1 Reply Last reply
                  1
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Thanks for the detailed analysis and workaround !

                    I still think it's worth opening a ticket to make the situation known.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    B 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      Thanks for the detailed analysis and workaround !

                      I still think it's worth opening a ticket to make the situation known.

                      B Offline
                      B Offline
                      barbicels
                      wrote on last edited by
                      #10

                      @SGaist
                      Some later observations:

                      • Porting to Qt 6.2.2 did not fix the problem. A modal dialog (using QtQuick.Dialogs 1.2 MessageDialog) still does not paint if the C++ method (invoked by the onSwitchChanged event handler), which signaled QML to post the dialog, then spins its own event loop (to maintain its synchronous semantics, waiting for the user's response to the dialog) rather than returning to the main thread's base event loop. So, I can forget about that as a possible avenue for resolution.
                      • The workaround I described (using Qt.callLater so that the onSwitchChanged event handler can return to the base event loop, deferring the posting of the modal dialog and all logic that depends on the user's response to it) works to a degree, but a run of two or three of those dialogs in sequence causes some further event-handling weirdness that I still have to work out.
                      • Apple's recent macOS 12.2 update did not make any difference. My problem remains, though it's still only happening on newer iPhone models. As I wrote, above, there are other unresolved reports of odd crashes whose traceback shows touch events being dispatched from inside iOS's update cycle, which still strikes me as something that shouldn't happen. Maybe I'll bounce this off my old acquaintance Quinn at Apple Developer Support…

                      Thanks again for your interest!

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        Then I confirm that it is worth a report :-)

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved