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

Virtual keyboard in the application can cause a general UI performance issue when focus change events occur

    XMLWordPrintable

Details

    Description

      The presence of a virtual keyboard in the application can cause a general UI
      performance issue when focus change events occur. On a focus change event when inputMethodHints is 0x0, the shiftKeyEnabled in the virtual keyboard is continually toggled causing delay in the main thread due to processing in QML code, presumably changing the keys from upper case to lowercase in the background.

      The virtual keyboard is part of a platform input context plugin. Every time a focus change event occurs, the platform input context (virtual keyboard) is notified of a focus change internally in qt. Inside the keyboard platform input context ShiftHandler::restart() is invoked as a result of the focus change. ShiftHandler::restart() can emit shiftChanged() twice, and on our target device each invocation of "emit shiftChanged()" can take 50-200ms depending on other events on the system. Since this 50-200ms signal/slot invocation is on the critical path in QGuiApplication it causes a major slowdown when focus change events are occurring e.g. scrolling through a settings menu / series of widgets. When no shiftChanged() signals are emitted the PlatformInputContext::setFocusObject invocation only takes nanoseconds in duration.

      The large chunk of time in "emit shiftChanged()" occurs in destination QML code.

      I think during a ShiftHandler::restart(), setShift should only be toggled once if needed, not be toggled twice e.g. from true to false to true.
      Also, I think the virtual keyboard should also not be delaying the main thread with QML processing when a focus event occurs and the keyboard is hidden.

      Setup: iMX6 device running qt 5.6.0 with virtual keyboard 2.0.0

      m_pKeyboardView = new QQuickView();
      m_pKeyboardView->setSource(QUrl::fromLocalFile("vkb.qml"));
      m_pKeyboardView->setFlags(Qt::FramelessWindowHint);
      

      Perform some widget focus changes without showing the QQuickView, observe that shiftChanged() is emitted twice during a focus change event which causes announces.

      vkb.qml:

      import QtQuick 2.4
      import QtQuick.Enterprise.VirtualKeyboard 2.0
      
      InputPanel
      {
          id: inputPanel
          x: 0
          y: 800
      }
      

      Conditions causing shiftChanged() to be emitted twice in ShiftHandler::restart() when focus change occurs:
      inputMethodHints() is Qt::ImhNone inputContext->cursorPosition() is 0

      This means during ShiftHandler::restart(): ShiftHandler::reset() calls setShift(false) and setAutoCapitalizationEnabled(true)
      ShiftHandler::autoCapitalize() calls setShift(!preferLowerCase) which ends up as setShift(true) since inputMethodHints() is Qt::ImhNone.

      As a quick workaround to this I disabled the autoCapitalize feature and also hardcoded setShift to false on a ShiftHandler::restart() call, this prevents
      shiftChanged() from being emitted on focus change events when the keyboard is in the background.

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-57082
          # Subject Branch Project Status CR V

          Activity

            People

              jakoivik Jarkko Koivikko
              karimpinter Karim Pinter (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes