Details

    • All

    Description

      As part of our key event and shortcut machinery we canonicalize the case of the Qt::Key.

      This is for example documented as part of QKeyEvent::key().

      Most Qt::Key enum values in the latin1 region are represented by their unicode upper case equivalents. For example, "a" is represented as Qt::Key_A, which has the unicode value of "A".

      But in some cases, upper casing the character brings it out of latin1, and more importantly, no longer maps to any of the Qt::Key enum values.

      • U+00B5 MICRO SIGN upper cases to U+039C GREEK CAPITAL LETTER MU
        • And there's no Qt::Key with value U+039C
          • But there is a Qt::Key_miro with value U+00B5
        • Also, U+039C GREEK CAPITAL LETTER MU does not lower case back to U+00B5 MICRO SIGN so the transformation isn't symmetric
      • LATIN SMALL LETTER Y WITH DIAERESIS U+00FF upper cases to LATIN CAPITAL LETTER Y WITH DIAERESIS U+0178
        • And there's no Qt::Key with value U+0178

      So we can't do a naive toUpper during canonicalization.

      We need to:

      • Let U+00B5 MICRO SIGN map to Qt::Key_micro
        • Ie not upper case
      • Leave U+039C GREEK CAPITAL LETTER MU unmapped
        • Ie no down case to Qt::Key_micro
      • Let LATIN SMALL LETTER Y WITH DIAERESIS U+00FF map to Qt::Key_ydiaeresis
        • Ie not upper case
      • Map LATIN CAPITAL LETTER Y WITH DIAERESIS U+0178 to Qt::Key_ydiaeresis
        • Ie down case

      For all other values in the Qt::Key enum, we should be good to do upper casing.

      For values outside the Qt::Key enum, we represent as the Qt::Key(unicodeValue), and still want to do upper casing, but we must ensure we do this only when there's a 1:1 symmetric transformation available:

      QChar QKeyMapperPrivate::canonicalizeCase(QChar ch)
      { 
          const QChar low = ch.toLower();
          const QChar up = ch.toUpper();
          if (low.toUpper() != ch && up.toLower() != ch)
              return ch;
          if (low.toLatin1() && !up.toLatin1())
              return low;
          return up;
      } 

      We also want to share this logic in a central place (QKeyMapperPrivate), that can be used both by QKeySequence, QShortcutMap, etc, as well as the key mapper machinery of each platform plugin (where we translate the incoming native key events to QKeyEvents with a canonicalized key() value).

      This helper should be tested extensively via a new tst_qkeymapper auto tests that verifies the beahvior outlined above (and catches any mistakes in the above logic).

      Attachments

        Issue Links

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

          Activity

            People

              amurzeau Alexis Murzeau
              vestbo Tor Arne Vestbø
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are 2 open Gerrit changes