Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CI/macos/build_qt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ _patch_product() {
if [ -z "${SKIP_UNPACK}" ]; then
step "Apply patches..."
apply_patch "${CHECKOUT_DIR}/CI/patches/QTBUG-74606.patch" "6ba73e94301505214b85e6014db23b042ae908f2439f0c18214e92644a356638"
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-70137-1.patch" "216be72245a80b7762dc2e2bd720a4ea9b9c423ce9d006cce3985b63c0269ba3"
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-70137-2.patch" "92d49352c321c653d6f5377e64603e48b38a9c1ec87a8956acba42459c151e42"
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-70137-3.patch" "f8b220a444fcd0e121b8643e7526af33a4f30e0c85d11c28d40fcc7072d56783"
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-88495.patch" "d60d663d2d940aa21cbcda65b1e60c4ecb1ec1900736e896367e5436d121206e"
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-97855.patch" "d8620262ad3f689fdfe6b6e277ddfdd3594db3de9dbc65810a871f142faa9966"
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-90370.patch" "277b16f02f113e60579b07ad93c35154d7738a296e3bf3452182692b53d29b85"
Expand Down
86 changes: 86 additions & 0 deletions CI/macos/patches/QTBUG-70137-1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
From 78b6050d60ba97ffb66e79bcde6ea306108e41dd Mon Sep 17 00:00:00 2001
From: Richard Moe Gustavsen <[email protected]>
Date: Tue, 11 May 2021 13:22:57 +0200
Subject: [PATCH] cocoa: be more careful about rejecting frame strut events

The m_buttons property is meant to hold the currently pressed mouse
buttons done on the contents part of a QNSView. But m_buttons can
sometimes get out of sync with AppKit (NSEvent.pressedMouseButtons).
One way this is shown to happen is if you do a mouse press on a native
child widget (that is backed by it's own QNSView), and then convert the
widget to a top-level window before the release. In that case, the
underlying QNSView will be reparented from one NSWindow to another,
which will result in the old NSWindow getting the mouseUp call instead
of the new window. The result is that we don't update m_buttons for
the reparented QNSView, which will instead be left as "pressed".

As a result of m_buttons being stuck in a faulty state, we also refuse
to send out QEvent::NonClientAreaMouseMove events to the top-level
widget. This because QNSView thinks that it's already in a dragging
state that started on the content part of the view (and not on the
strut). As a result, it can sometimes be impossible to dock a
QDockWidget back into a QMainWindow, since we basically don't send
out any frame-drag events to Qt for the new dock window.

We can reason that if you start a mouse press on the frame strut, you
cannot at the same time have an active mouse press on the view contents.
This patch will therefore remove the buttons that we know was pressed
on the frame strut from m_buttons. This will at least (be one way to)
clear the faulty pressed state, and will let us send mouse
press/drag/release (and after that, move) frame strut events to Qt.

Pick-to: 6.1 5.15
Task-number: QTBUG-70137
Change-Id: If51e1fe57d2531b659d39de85658893dae6391e3
Reviewed-by: Tor Arne Vestbø <[email protected]>
---

diff --git ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm
index d00cfb7..54a1f06 100644
--- ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm
+++ ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm
@@ -103,21 +103,14 @@
if (!m_platformWindow)
return;

- // get m_buttons in sync
- // Don't send frme strut events if we are in the middle of a mouse drag.
- if (m_buttons != Qt::NoButton)
- return;
-
switch (theEvent.type) {
case NSEventTypeLeftMouseDown:
- case NSEventTypeLeftMouseDragged:
m_frameStrutButtons |= Qt::LeftButton;
break;
case NSEventTypeLeftMouseUp:
m_frameStrutButtons &= ~Qt::LeftButton;
break;
case NSEventTypeRightMouseDown:
- case NSEventTypeRightMouseDragged:
m_frameStrutButtons |= Qt::RightButton;
break;
case NSEventTypeRightMouseUp:
@@ -132,6 +125,22 @@
break;
}

+ // m_buttons can sometimes get out of sync with the button state in AppKit
+ // E.g if the QNSView where a drag starts is reparented to another window
+ // while the drag is ongoing, it will not get the corresponding mouseUp
+ // call. This will result in m_buttons to be stuck on Qt::LeftButton.
+ // Since we know which buttons was pressed/released directly on the frame
+ // strut, we can rectify m_buttons here so that we at least don't return early
+ // from the drag test underneath because of the faulty m_buttons state.
+ // FIXME: get m_buttons in sync with AppKit/NSEvent all over in QNSView.
+ m_buttons &= ~m_frameStrutButtons;
+
+ if (m_buttons != Qt::NoButton) {
+ // Don't send frame strut events if we are in the middle of
+ // a mouse drag that didn't start on the frame strut.
+ return;
+ }
+
NSWindow *window = [self window];
NSPoint windowPoint = [theEvent locationInWindow];

63 changes: 63 additions & 0 deletions CI/macos/patches/QTBUG-70137-2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
From 3224c6d7d150164241c13ccf7d47377a39c0a6bb Mon Sep 17 00:00:00 2001
From: Richard Moe Gustavsen <[email protected]>
Date: Wed, 12 May 2021 11:21:07 +0200
Subject: [PATCH] QDockWidget, macOS: don't drag on native widgets

When using native dock widgets on macOS, it will currently
fail if you try to drag on a dock widget inside QMainWindow
to make it floating. The reason is that the drag will
basically start as as drag inside one NSWindow (QMainWindow),
but continue as a drag on another NSWindow (QDockWidget).
And this is not handled well by AppKit, especially since the
NSView where the drag was started is reparented into a new
NSWindow (the floating QDockWidget) while the dragging is
ongoing. And there seems to be no practical solution to how
we can support this from the cocoa QPA plugin

This patch will therefore change the logic in QDockWidget to
simply make the dock widget floating if you drag on it, rather
than actually starting a drag (but only for the described case).

Pick-to: 6.1 5.15
Fixes: QTBUG-70137
Change-Id: Ic309ee8f419b9c14894255205867bce11dc0c414
Reviewed-by: Volker Hilsheimer <[email protected]>
Reviewed-by: Tor Arne Vestbø <[email protected]>
---

diff --git ./qtbase/src/widgets/widgets/qdockwidget.cpp ./qtbase/src/widgets/widgets/qdockwidget.cpp
index 5480780..5016235 100644
--- ./qtbase/src/widgets/widgets/qdockwidget.cpp
+++ ./qtbase/src/widgets/widgets/qdockwidget.cpp
@@ -970,13 +970,27 @@
&& mwlayout->pluggingWidget == nullptr
&& (event->position().toPoint() - state->pressPos).manhattanLength()
> QApplication::startDragDistance()) {
- startDrag();
- q->grabMouse();
- ret = true;
+
+#ifdef Q_OS_MACOS
+ if (windowHandle()) {
+ // When using native widgets on mac, we have not yet been successful in
+ // starting a drag on an NSView that belongs to one window (QMainWindow),
+ // but continue the drag on another (QDockWidget). This is what happens if
+ // we try to make this widget floating during a drag. So as a fall back
+ // solution, we simply make this widget floating instead, when we would
+ // otherwise start a drag.
+ q->setFloating(true);
+ } else
+#endif
+ {
+ startDrag();
+ q->grabMouse();
+ ret = true;
+ }
}
}

- if (state->dragging && !state->nca) {
+ if (state && state->dragging && !state->nca) {
QMargins windowMargins = q->window()->windowHandle()->frameMargins();
QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top());
QPoint pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset;
33 changes: 33 additions & 0 deletions CI/macos/patches/QTBUG-70137-3.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
From ba3e1fe09b7d921985e21d857a1d566465095e69 Mon Sep 17 00:00:00 2001
From: Andy Shaw <[email protected]>
Date: Mon, 2 Aug 2021 14:43:21 +0200
Subject: [PATCH] Allow dragging of a floating dockwidget on macOS with a
custom titlebar
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This amends 3224c6d7d150164241c13ccf7d47377a39c0a6bb to account for the
case when the dockwidget is already floating.

Task-number: QTBUG-70137
Pick-to: 6.2 6.1 5.15
Change-Id: If8b345565b11b44beb3fb4b697cfe812c29c6396
Reviewed-by: Tor Arne Vestbø <[email protected]>
---
src/widgets/widgets/qdockwidget.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git ./qtbase/src/widgets/widgets/qdockwidget.cpp ./qtbase/src/widgets/widgets/qdockwidget.cpp
index 49390788700..4080a622f00 100644
--- ./qtbase/src/widgets/widgets/qdockwidget.cpp
+++ ./qtbase/src/widgets/widgets/qdockwidget.cpp
@@ -974,7 +974,7 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
> QApplication::startDragDistance()) {

#ifdef Q_OS_MACOS
- if (windowHandle()) {
+ if (windowHandle() && !q->isFloating()) {
// When using native widgets on mac, we have not yet been successful in
// starting a drag on an NSView that belongs to one window (QMainWindow),
// but continue the drag on another (QDockWidget). This is what happens if
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Scripts to build and package dependencies for OBS on CI
* mbedtls is patched to enable `pthread` functionality
* SpeexDSP is patched to allow macOS 10.13 compatibility
* Qt is patched to cross-compile ARM64 on x86_64 hosts
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-70137
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-74606
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-88495
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-90370
Expand Down