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

wayland: bad modifiers

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.5
    • QPA: Wayland
    • None
    • Linux/Wayland

    Description

      Compositor: weston、kwin

      Attached is a simple program that outputs modifiers in wheelEvent using two ways.

      void Widget::wheelEvent(QWheelEvent *e)
      {
          qWarning() << "Widget::wheelEvent" << e->modifiers() << qApp->queryKeyboardModifiers();
      }
      

      weston:

      Run weston, run the test in the attachment.
      Click on the upper left corner in weston to open weston-termimal. weston-termimal gains focus, and the test window loses focus.
      Move the mouse over the test window, hold down ctrl and scroll the middle mouse button.
      You will get the following information:

      Widget::wheelEvent QFlags<Qt::KeyboardModifier>(ControlModifier) QFlags<Qt::KeyboardModifier>(NoModifier)
      e->modifiers()  != qApp->queryKeyboardModifiers()
      

      kwin:

      kwin has some differences, using the above steps, you will get two NoModifiers.
      Let's do it another way:
      Open kwin, run the attached test twice, you will get two windows.

      Mouse click on window A, activate window A, press ctrl (do not release), mouse click on window B, activate window B, release ctrl, move the mouse over window A (do not click, do not activate), then scroll the mouse key, you will get the following information:

      Widget::wheelEvent QFlags<Qt::KeyboardModifier>(ControlModifier) QFlags<Qt::KeyboardModifier>(NoModifier)
       
       e->modifiers()  != qApp->queryKeyboardModifiers()
      

      The point is that we didn't press ctrl at this time.

      Why these differences? I did a more detailed investigation. Modifiers updates rely on the wl_keyboard.modifiers message, which is then queried for modifiers via xkbcommon.

      kwin:

      Well understood. We press ctrl in window A, the modifiers are updated, and release ctrl in window B. Activate A again, the modifiers in window A still remain ControlModifier, why {{e->modifiers()=ControlModifier and queryKeyboardModifiers=NoModifier }}, this is because https://codereview.qt-project.org/c/qt/qtwayland/+/376058

       Qt::KeyboardModifiers QWaylandIntegration::queryKeyboardModifiers() const
       {
      -    if (auto *seat = mDisplay->currentInputDevice()) {
      +    if (auto *seat = mDisplay->currentInputDevice(); seat && seat->keyboardFocus()) {
               return seat->modifiers();
           }
           return Qt::NoModifier;
      

      Then, e->modifiers() is passed from qtwayland, so it's not the same.

      weston:

      The situation of weston is different. Before each wl_pointer.enter, weston sends wl_keyboard.modifiers, yes, the client can get the correct modifiers, but also because of the above code, the window has no keyboard focus, so qApp->queryKeyboardModifiers = NoModifier

      For this, I submitted a patch to modify it to return NoModifier when the window has no focus. 
      https://codereview.qt-project.org/c/qt/qtwayland/+/416601
      Seriously, I actually don't know if this is right, but I believe it would be better if the synth modified it.

      It's very complicated, I don't know if it's clear, if you have any questions, please ask me.

      Attachments

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

        Activity

          People

            davidedmundson David Edmundson
            tanghaixiang haixiang tang
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes