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

QXkbCommon: No Qt::KeypadModifier in QKeyEvents in QtWaylandCompositor

    XMLWordPrintable

Details

    • Linux/Wayland
    • 298c95091 (dev), 2041157d7 (6.5), f614fdfa5 (dev), b2de9e57f (6.5)

    Description

      For our software we use our own Wayland Compositor implemented with QtWaylandCompositor. Our Linux supports xkbcommon, so Qt is using it. Since we migrated from Qt 5.12 to Qt 5.15 the window of the compositor no longer receives the modifier Qt::KeypadModifier in QKeyEvents, when keys on the key pad/num pad are pressed. For our software it is essential that we can differentiate between the keys on the key pad and the ones that are not on the key pad. For example, we have to differentiate between the Page_Up key on the key pad and on the "normal" keyboard.

      I did a little investigation on what has changed between Qt 5.12 and Qt 5.15 and found the following bug. 

      The data of QKeyEvents (key code, modifiers, etc.) is retrieved from the xkbcommon library in WindowSystemEventHandler::handleKeyEvent() in qwaylandcompositor.cpp via a wrapper class for xkbcommon - QWaylandXkb in Qt 5.12, QXkbCommon in Qt 5.15.

      In Qt 5.12 the modifier data came from two different sources (methods): QWaylandXkb::modifiers() and QWaylandXkb::keysymToQtKey(). The Qt::KeypadModifier was added in QWaylandXkb::keysymToQtKey().
      This is how it was implemented in Qt 5.12:

          } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) {
              if (keysym >= XKB_KEY_KP_0) {
                  // numeric keypad keys
                  code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0);
              } else {
                  code = lookupKeysym(keysym);
              }
              modifiers |= Qt::KeypadModifier;
          }
      

      In Qt 5.15 it seems that QWaylandXkb was refactored to a new class QXkbCommon and moved to the platform support of QtBase. QXkbCommon::modifiers() is identical to QWaylandXkb::modifiers(). But QXkbCommon::keysymToQtKey() does no longer change the modifier flags. Therefore Qt::KeypadModifier is never set.
      This is how it is implemented in Qt 5.15:

          } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
                  // numeric keypad keys
                  qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
          }
      

      You can easily reproduce this with the minimal-cpp example of QtWaylandCompositor and a Linux device with a keyboard, that has a key pad. I extended the minimal-cpp example with traces to see the data of QKeyEvents received by the compositor window for reproducing the issue.

      I did a little patch for myself and extended QXkbCommon::modifiers() so that it can also set Qt::KeypadModifier when provided with the required information. You can find the patch in the attachments.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            liaqi Liang Qi
            marioroessel Mario Rössel
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes