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

Incomplete docs and therefore different interpretations between platforms for QWindow::setMouse/KeyboardGrabEnabled

    XMLWordPrintable

Details

    Description

      The documentation says:

      "If the return value is true, the window receives all mouse events until setMouseGrabEnabled(false) is called; other windows get no mouse events at all. Keyboard events are not affected."

      The documentation does not say when should false be returned. And when things are left to the interpretation, then naturally there are different interpretations between platforms.

      Windows returns whatever was passed in as argument:

      bool QWindowsWindow::setMouseGrabEnabled(bool grab)
      {
          qCDebug(lcQpaWindows) << __FUNCTION__ << window() << grab;
          if (!m_data.hwnd) {
              qWarning("%s: No handle", __FUNCTION__);
              return false;
          }
          if (!isVisible() && grab) {
              qWarning("%s: Not setting mouse grab for invisible window %s/'%s'",
                       __FUNCTION__, window()->metaObject()->className(),
                       qPrintable(window()->objectName()));
              return false;
          }
          // release grab or an explicit grab overriding autocapture: Clear flag.
          clearFlag(QWindowsWindow::AutoMouseCapture);
          if (hasMouseCapture() != grab) {
              if (grab) {
                  SetCapture(m_data.hwnd);
              } else {
                  ReleaseCapture();
              }
          }
          return grab;
      }
      

      XCB always returns true for ungrab, which is opposite to Windows, which returns false.

      When grabbing via core protocol:

       
      xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
      return true;
      

      When grabbing via XI2 protocol we actually check if grab succeeded, see https://codereview.qt-project.org/#/c/214110/ (but logic is still opposite of what Windows does).

      Cocoa seems to interpret the return value similar to XCB:

      bool QCocoaWindow::setMouseGrabEnabled(bool grab)
      {
          qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setMouseGrabEnabled" << window() << grab;
          if (!isContentView())
              return false;
      
          if (grab && ![m_view.window isKeyWindow])
              [m_view.window makeKeyWindow];
      
          return true;
      }
      

      When adding new APIs we should add an auto test, then we could avoid unnecessary inconsistencies. This API was added by:

      commit 1f456b4cbb93e3fea699878d117900b703146213
      Author: Laszlo Agocs <laszlo.p.agocs@nokia.com>, Fri Jun 3 11:30:23 2011 +0200 (7 years ago)
      Committer: Laszlo Agocs <laszlo.p.agocs@nokia.com>, Fri Jun 3 11:59:15 2011 +0200 (7 years ago)
      Precedes: qt-v5.0.0-alpha1
      Branches: <Expand>
      
      Add support for mouse and keyboard grab.
      
      Reviewed-by: Samuel Rødal
      

      Summary:

      On Windows, QWindow::setMouseGrabEnabled(false) will return false on successful ungrab. Which is opposite of what XCB and Cocoa does. Documentation is missing, so there is no clarity which platform is doing it wrong, but thinking from users point of view, it makes sense that successful operation returns true, not false. So it looks like Windows is the bad platform here.

      Attachments

        Issue Links

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

          Activity

            People

              Unassigned Unassigned
              paeglis Gatis Paeglis
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes