Skip to content

Commit 8386b0e

Browse files
gxalphaRytoEX
authored andcommitted
macos/patches: Backport Qt macOS docking fixes
Backports 78b6050 and 3224c6d from qt/qtbase, fixing the broken macOS docking and undocking.
1 parent c42c463 commit 8386b0e

File tree

5 files changed

+186
-0
lines changed

5 files changed

+186
-0
lines changed

CI/macos/build_qt.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ _patch_product() {
1717
if [ -z "${SKIP_UNPACK}" ]; then
1818
step "Apply patches..."
1919
apply_patch "${CHECKOUT_DIR}/CI/patches/QTBUG-74606.patch" "6ba73e94301505214b85e6014db23b042ae908f2439f0c18214e92644a356638"
20+
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-70137-1.patch" "216be72245a80b7762dc2e2bd720a4ea9b9c423ce9d006cce3985b63c0269ba3"
21+
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-70137-2.patch" "92d49352c321c653d6f5377e64603e48b38a9c1ec87a8956acba42459c151e42"
22+
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-70137-3.patch" "f8b220a444fcd0e121b8643e7526af33a4f30e0c85d11c28d40fcc7072d56783"
2023
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-88495.patch" "d60d663d2d940aa21cbcda65b1e60c4ecb1ec1900736e896367e5436d121206e"
2124
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-97855.patch" "d8620262ad3f689fdfe6b6e277ddfdd3594db3de9dbc65810a871f142faa9966"
2225
apply_patch "${CHECKOUT_DIR}/CI/macos/patches/QTBUG-90370.patch" "277b16f02f113e60579b07ad93c35154d7738a296e3bf3452182692b53d29b85"
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
From 78b6050d60ba97ffb66e79bcde6ea306108e41dd Mon Sep 17 00:00:00 2001
2+
From: Richard Moe Gustavsen <richard.gustavsen@qt.io>
3+
Date: Tue, 11 May 2021 13:22:57 +0200
4+
Subject: [PATCH] cocoa: be more careful about rejecting frame strut events
5+
6+
The m_buttons property is meant to hold the currently pressed mouse
7+
buttons done on the contents part of a QNSView. But m_buttons can
8+
sometimes get out of sync with AppKit (NSEvent.pressedMouseButtons).
9+
One way this is shown to happen is if you do a mouse press on a native
10+
child widget (that is backed by it's own QNSView), and then convert the
11+
widget to a top-level window before the release. In that case, the
12+
underlying QNSView will be reparented from one NSWindow to another,
13+
which will result in the old NSWindow getting the mouseUp call instead
14+
of the new window. The result is that we don't update m_buttons for
15+
the reparented QNSView, which will instead be left as "pressed".
16+
17+
As a result of m_buttons being stuck in a faulty state, we also refuse
18+
to send out QEvent::NonClientAreaMouseMove events to the top-level
19+
widget. This because QNSView thinks that it's already in a dragging
20+
state that started on the content part of the view (and not on the
21+
strut). As a result, it can sometimes be impossible to dock a
22+
QDockWidget back into a QMainWindow, since we basically don't send
23+
out any frame-drag events to Qt for the new dock window.
24+
25+
We can reason that if you start a mouse press on the frame strut, you
26+
cannot at the same time have an active mouse press on the view contents.
27+
This patch will therefore remove the buttons that we know was pressed
28+
on the frame strut from m_buttons. This will at least (be one way to)
29+
clear the faulty pressed state, and will let us send mouse
30+
press/drag/release (and after that, move) frame strut events to Qt.
31+
32+
Pick-to: 6.1 5.15
33+
Task-number: QTBUG-70137
34+
Change-Id: If51e1fe57d2531b659d39de85658893dae6391e3
35+
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
36+
---
37+
38+
diff --git ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm
39+
index d00cfb7..54a1f06 100644
40+
--- ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm
41+
+++ ./qtbase/src/plugins/platforms/cocoa/qnsview_mouse.mm
42+
@@ -103,21 +103,14 @@
43+
if (!m_platformWindow)
44+
return;
45+
46+
- // get m_buttons in sync
47+
- // Don't send frme strut events if we are in the middle of a mouse drag.
48+
- if (m_buttons != Qt::NoButton)
49+
- return;
50+
-
51+
switch (theEvent.type) {
52+
case NSEventTypeLeftMouseDown:
53+
- case NSEventTypeLeftMouseDragged:
54+
m_frameStrutButtons |= Qt::LeftButton;
55+
break;
56+
case NSEventTypeLeftMouseUp:
57+
m_frameStrutButtons &= ~Qt::LeftButton;
58+
break;
59+
case NSEventTypeRightMouseDown:
60+
- case NSEventTypeRightMouseDragged:
61+
m_frameStrutButtons |= Qt::RightButton;
62+
break;
63+
case NSEventTypeRightMouseUp:
64+
@@ -132,6 +125,22 @@
65+
break;
66+
}
67+
68+
+ // m_buttons can sometimes get out of sync with the button state in AppKit
69+
+ // E.g if the QNSView where a drag starts is reparented to another window
70+
+ // while the drag is ongoing, it will not get the corresponding mouseUp
71+
+ // call. This will result in m_buttons to be stuck on Qt::LeftButton.
72+
+ // Since we know which buttons was pressed/released directly on the frame
73+
+ // strut, we can rectify m_buttons here so that we at least don't return early
74+
+ // from the drag test underneath because of the faulty m_buttons state.
75+
+ // FIXME: get m_buttons in sync with AppKit/NSEvent all over in QNSView.
76+
+ m_buttons &= ~m_frameStrutButtons;
77+
+
78+
+ if (m_buttons != Qt::NoButton) {
79+
+ // Don't send frame strut events if we are in the middle of
80+
+ // a mouse drag that didn't start on the frame strut.
81+
+ return;
82+
+ }
83+
+
84+
NSWindow *window = [self window];
85+
NSPoint windowPoint = [theEvent locationInWindow];
86+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
From 3224c6d7d150164241c13ccf7d47377a39c0a6bb Mon Sep 17 00:00:00 2001
2+
From: Richard Moe Gustavsen <richard.gustavsen@qt.io>
3+
Date: Wed, 12 May 2021 11:21:07 +0200
4+
Subject: [PATCH] QDockWidget, macOS: don't drag on native widgets
5+
6+
When using native dock widgets on macOS, it will currently
7+
fail if you try to drag on a dock widget inside QMainWindow
8+
to make it floating. The reason is that the drag will
9+
basically start as as drag inside one NSWindow (QMainWindow),
10+
but continue as a drag on another NSWindow (QDockWidget).
11+
And this is not handled well by AppKit, especially since the
12+
NSView where the drag was started is reparented into a new
13+
NSWindow (the floating QDockWidget) while the dragging is
14+
ongoing. And there seems to be no practical solution to how
15+
we can support this from the cocoa QPA plugin
16+
17+
This patch will therefore change the logic in QDockWidget to
18+
simply make the dock widget floating if you drag on it, rather
19+
than actually starting a drag (but only for the described case).
20+
21+
Pick-to: 6.1 5.15
22+
Fixes: QTBUG-70137
23+
Change-Id: Ic309ee8f419b9c14894255205867bce11dc0c414
24+
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
25+
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
26+
---
27+
28+
diff --git ./qtbase/src/widgets/widgets/qdockwidget.cpp ./qtbase/src/widgets/widgets/qdockwidget.cpp
29+
index 5480780..5016235 100644
30+
--- ./qtbase/src/widgets/widgets/qdockwidget.cpp
31+
+++ ./qtbase/src/widgets/widgets/qdockwidget.cpp
32+
@@ -970,13 +970,27 @@
33+
&& mwlayout->pluggingWidget == nullptr
34+
&& (event->position().toPoint() - state->pressPos).manhattanLength()
35+
> QApplication::startDragDistance()) {
36+
- startDrag();
37+
- q->grabMouse();
38+
- ret = true;
39+
+
40+
+#ifdef Q_OS_MACOS
41+
+ if (windowHandle()) {
42+
+ // When using native widgets on mac, we have not yet been successful in
43+
+ // starting a drag on an NSView that belongs to one window (QMainWindow),
44+
+ // but continue the drag on another (QDockWidget). This is what happens if
45+
+ // we try to make this widget floating during a drag. So as a fall back
46+
+ // solution, we simply make this widget floating instead, when we would
47+
+ // otherwise start a drag.
48+
+ q->setFloating(true);
49+
+ } else
50+
+#endif
51+
+ {
52+
+ startDrag();
53+
+ q->grabMouse();
54+
+ ret = true;
55+
+ }
56+
}
57+
}
58+
59+
- if (state->dragging && !state->nca) {
60+
+ if (state && state->dragging && !state->nca) {
61+
QMargins windowMargins = q->window()->windowHandle()->frameMargins();
62+
QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top());
63+
QPoint pos = event->globalPosition().toPoint() - state->pressPos - windowMarginOffset;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
From ba3e1fe09b7d921985e21d857a1d566465095e69 Mon Sep 17 00:00:00 2001
2+
From: Andy Shaw <andy.shaw@qt.io>
3+
Date: Mon, 2 Aug 2021 14:43:21 +0200
4+
Subject: [PATCH] Allow dragging of a floating dockwidget on macOS with a
5+
custom titlebar
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset=UTF-8
8+
Content-Transfer-Encoding: 8bit
9+
10+
This amends 3224c6d7d150164241c13ccf7d47377a39c0a6bb to account for the
11+
case when the dockwidget is already floating.
12+
13+
Task-number: QTBUG-70137
14+
Pick-to: 6.2 6.1 5.15
15+
Change-Id: If8b345565b11b44beb3fb4b697cfe812c29c6396
16+
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
17+
---
18+
src/widgets/widgets/qdockwidget.cpp | 2 +-
19+
1 file changed, 1 insertion(+), 1 deletion(-)
20+
21+
diff --git ./qtbase/src/widgets/widgets/qdockwidget.cpp ./qtbase/src/widgets/widgets/qdockwidget.cpp
22+
index 49390788700..4080a622f00 100644
23+
--- ./qtbase/src/widgets/widgets/qdockwidget.cpp
24+
+++ ./qtbase/src/widgets/widgets/qdockwidget.cpp
25+
@@ -974,7 +974,7 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
26+
> QApplication::startDragDistance()) {
27+
28+
#ifdef Q_OS_MACOS
29+
- if (windowHandle()) {
30+
+ if (windowHandle() && !q->isFloating()) {
31+
// When using native widgets on mac, we have not yet been successful in
32+
// starting a drag on an NSView that belongs to one window (QMainWindow),
33+
// but continue the drag on another (QDockWidget). This is what happens if

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Scripts to build and package dependencies for OBS on CI
3131
* mbedtls is patched to enable `pthread` functionality
3232
* SpeexDSP is patched to allow macOS 10.13 compatibility
3333
* Qt is patched to cross-compile ARM64 on x86_64 hosts
34+
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-70137
3435
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-74606
3536
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-88495
3637
* Qt is patched to fix https://bugreports.qt.io/browse/QTBUG-90370

0 commit comments

Comments
 (0)