35
35
#include < qmap.h>
36
36
#include < qtimer.h>
37
37
#include < qpointer.h>
38
+ #include < qobject.h>
39
+ #include < qaction.h>
38
40
39
41
#ifndef QT_NO_DEBUG_STREAM
40
42
# include < qdebug.h>
@@ -264,6 +266,20 @@ bool QDockWidgetGroupWindow::event(QEvent *e)
264
266
if (QDockWidget *dw = activeTabbedDockWidget ()) {
265
267
dw->close ();
266
268
adjustFlags ();
269
+ // when all child QDockWidgets' are closed, this QDockWidgetGroupWindow will be hidden
270
+ // after receiving the `LayoutRequest` event. This causes subsequent call to show
271
+ // on the current QDockWidget to fail. Hence, adding a connection to the
272
+ // QDockWidget's toggle action to re-show this QDockWidgetGroupWindow along with the
273
+ // current QDockWidget.
274
+ m_widgetConnections[dw] = connect (dw->toggleViewAction (), &QAction::toggled, [this , dw]() {
275
+ // show this QDockWidgetGroupWindow before showing the child QDockWidget.
276
+ show ();
277
+ dw->show ();
278
+ // once at least one child becomes visible, clear all listeners since we no longer need them..
279
+ for (const auto & pair : m_widgetConnections)
280
+ disconnect (pair.second );
281
+ m_widgetConnections.clear ();
282
+ });
267
283
}
268
284
#endif
269
285
return true ;
@@ -288,6 +304,10 @@ bool QDockWidgetGroupWindow::event(QEvent *e)
288
304
if (qobject_cast<QDockWidget *>(static_cast <QChildEvent*>(e)->child ()))
289
305
adjustFlags ();
290
306
break ;
307
+ case QEvent::ChildRemoved:
308
+ if (auto widget = qobject_cast<QDockWidget *>(static_cast <QChildEvent*>(e)->child ()))
309
+ m_widgetConnections.erase (widget);
310
+ break ;
291
311
case QEvent::LayoutRequest:
292
312
// We might need to show the widget again
293
313
destroyOrHideIfEmpty ();
@@ -2577,70 +2597,7 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
2577
2597
2578
2598
// unplug the widget first
2579
2599
dockWidget->d_func ()->unplug (widget->geometry ());
2580
-
2581
- // Create a floating tab, copy properties and generate layout info
2582
- QDockWidgetGroupWindow *floatingTabs = createTabbedDockWindow ();
2583
- const QInternal::DockPosition dockPos = groupWindow->layoutInfo ()->dockPos ;
2584
- QDockAreaLayoutInfo *info = floatingTabs->layoutInfo ();
2585
-
2586
- const QTabBar::Shape shape = tabwidgetPositionToTabBarShape (dockWidget);
2587
-
2588
- // Populate newly created DockAreaLayoutInfo of floating tabs
2589
- *info = QDockAreaLayoutInfo (&layoutState.dockAreaLayout .sep , dockPos,
2590
- Qt::Horizontal, shape,
2591
- layoutState.mainWindow );
2592
-
2593
- // Create tab and hide it as group window contains only one widget
2594
- info->tabbed = true ;
2595
- info->tabBar = getTabBar ();
2596
- info->tabBar ->hide ();
2597
- updateGapIndicator ();
2598
-
2599
- // Reparent it to a QDockWidgetGroupLayout
2600
- floatingTabs->setGeometry (dockWidget->geometry ());
2601
-
2602
- // Append reference to floatingTabs to the dock's item_list
2603
- parentItem.widgetItem = new QDockWidgetGroupWindowItem (floatingTabs);
2604
- layoutState.dockAreaLayout .docks [dockPos].item_list .append (parentItem);
2605
-
2606
- // use populated parentItem to set reference to dockWidget as the first item in own list
2607
- parentItem.widgetItem = new QDockWidgetItem (dockWidget);
2608
- info->item_list = {parentItem};
2609
-
2610
- // Add non-gap items of the dock to the tab bar
2611
- for (const auto &listItem : layoutState.dockAreaLayout .docks [dockPos].item_list ) {
2612
- if (listItem.GapItem || !listItem.widgetItem )
2613
- continue ;
2614
- info->tabBar ->addTab (listItem.widgetItem ->widget ()->objectName ());
2615
- }
2616
-
2617
- // Re-parent and fit
2618
- floatingTabs->setParent (layoutState.mainWindow );
2619
- floatingTabs->layoutInfo ()->fitItems ();
2620
- floatingTabs->layoutInfo ()->apply (dockOptions & QMainWindow::AnimatedDocks);
2621
- groupWindow->layoutInfo ()->fitItems ();
2622
- groupWindow->layoutInfo ()->apply (dockOptions & QMainWindow::AnimatedDocks);
2623
- dockWidget->d_func ()->tabPosition = layoutState.mainWindow ->tabPosition (toDockWidgetArea (dockPos));
2624
- info->reparentWidgets (floatingTabs);
2625
- dockWidget->setParent (floatingTabs);
2626
- info->updateTabBar ();
2627
-
2628
- // Show the new item
2629
- const QList<int > path = layoutState.indexOf (floatingTabs);
2630
- QRect r = layoutState.itemRect (path);
2631
- savedState = layoutState;
2632
- savedState.fitLayout ();
2633
-
2634
- // Update gap, fix orientation, raise and show
2635
- currentGapPos = path;
2636
- currentGapRect = r;
2637
- updateGapIndicator ();
2638
- fixToolBarOrientation (parentItem.widgetItem , currentGapPos.at (1 ));
2639
- floatingTabs->show ();
2640
- floatingTabs->raise ();
2641
-
2642
- qCDebug (lcQpaDockWidgets) << " Unplugged from floating dock:" << widget << " from" << parentItem.widgetItem ;
2643
- return parentItem.widgetItem ;
2600
+ return item;
2644
2601
}
2645
2602
}
2646
2603
#endif
@@ -2837,10 +2794,18 @@ void QMainWindowLayout::hover(QLayoutItem *hoverTarget,
2837
2794
info->tabBar = getTabBar ();
2838
2795
info->tabbed = true ;
2839
2796
QLayout *parentLayout = dropTo->parentWidget ()->layout ();
2840
- info->item_list .append (
2841
- QDockAreaLayoutItem (parentLayout->takeAt (parentLayout->indexOf (dropTo))));
2842
-
2797
+ auto parentItem = QDockAreaLayoutItem (parentLayout->takeAt (parentLayout->indexOf (dropTo)));
2798
+ if (!parentItem.widgetItem )
2799
+ parentItem.widgetItem = new QDockWidgetItem (dropTo);
2800
+ info->item_list .append (parentItem);
2801
+
2802
+ auto oldGroupWindow = qobject_cast<QDockWidgetGroupWindow *>(dropTo->parent ());
2843
2803
dropTo->setParent (floatingTabs);
2804
+ // just an early cleanup to if there are no other children.
2805
+ if (oldGroupWindow) {
2806
+ oldGroupWindow->destroyOrHideIfEmpty ();
2807
+ }
2808
+
2844
2809
qCDebug (lcQpaDockWidgets) << " Wrapping" << widget << " into floating tabs" << floatingTabs;
2845
2810
w = floatingTabs;
2846
2811
}
0 commit comments