KDDockWidgets API Documentation  1.6
DockRegistry.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5  Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6 
7  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8 
9  Contact KDAB at <info@kdab.com> for commercial licensing options.
10 */
11 
12 #include "DockRegistry_p.h"
13 #include "Config.h"
14 #include "DockWidgetBase.h"
15 #include "DockWidgetBase_p.h"
16 #include "FloatingWindow_p.h"
17 #include "LayoutWidget_p.h"
18 #include "Logging_p.h"
19 #include "MainWindowMDI.h"
20 #include "Position_p.h"
21 #include "QWidgetAdapter.h"
22 #include "SideBar_p.h"
23 #include "Utils_p.h"
24 #include "WidgetResizeHandler_p.h"
25 #include "WindowBeingDragged_p.h"
26 #include "multisplitter/Item_p.h"
27 
28 #include <QPointer>
29 #include <QDebug>
30 #include <QGuiApplication>
31 #include <QWindow>
32 
33 #ifdef KDDOCKWIDGETS_QTWIDGETS
34 #include "DebugWindow_p.h"
35 #else
36 #include "quick/QmlTypes.h"
37 #endif
38 
39 using namespace KDDockWidgets;
40 
42 {
43 #if defined(KDDOCKWIDGETS_STATICLIB) || defined(QT_STATIC)
44  Q_INIT_RESOURCE(kddockwidgets_resources);
45 #if defined(KDDOCKWIDGETS_QTQUICK)
46  Q_INIT_RESOURCE(kddockwidgets_qtquick);
47 #endif
48 #endif
49 }
50 
51 DockRegistry::DockRegistry(QObject *parent)
52  : QObject(parent)
53 {
54  qApp->installEventFilter(this);
55 
56 #ifdef KDDOCKWIDGETS_QTWIDGETS
57 
58 #ifdef DOCKS_DEVELOPER_MODE
59  if (qEnvironmentVariableIntValue("KDDOCKWIDGETS_SHOW_DEBUG_WINDOW") == 1) {
60  auto dv = new Debug::DebugWindow();
61  dv->show();
62  }
63 #endif
64 
65 #else
67  QQuickWindow::setDefaultAlphaBuffer(true);
68 #endif
69 
71  this, &DockRegistry::onFocusObjectChanged);
72 
74 }
75 
76 DockRegistry::~DockRegistry()
77 {
78 }
79 
80 void DockRegistry::maybeDelete()
81 {
82  if (isEmpty())
83  delete this;
84 }
85 
86 void DockRegistry::onFocusObjectChanged(QObject *obj)
87 {
88  auto p = qobject_cast<WidgetType *>(obj);
89  while (p) {
90  if (auto frame = qobject_cast<Frame *>(p)) {
91  // Special case: The focused widget is inside the frame but not inside the dockwidget.
92  // For example, it's a line edit in the QTabBar. We still need to send the signal for
93  // the current dw in the tab group
94  if (auto dw = frame->currentDockWidget()) {
95  setFocusedDockWidget(dw);
96  }
97 
98  return;
99  }
100 
101  if (auto dw = qobject_cast<DockWidgetBase *>(p)) {
102  DockRegistry::self()->setFocusedDockWidget(dw);
103  return;
104  }
105  p = KDDockWidgets::Private::parentWidget(p);
106  }
107 
108  setFocusedDockWidget(nullptr);
109 }
110 
111 void DockRegistry::setFocusedDockWidget(DockWidgetBase *dw)
112 {
113  if (m_focusedDockWidget.data() == dw)
114  return;
115 
116  if (m_focusedDockWidget)
117  Q_EMIT m_focusedDockWidget->isFocusedChanged(false);
118 
119  m_focusedDockWidget = dw;
120 
121  if (m_focusedDockWidget)
122  Q_EMIT m_focusedDockWidget->isFocusedChanged(true);
123 }
124 
125 bool DockRegistry::isEmpty(bool excludeBeingDeleted) const
126 {
127  if (!m_dockWidgets.isEmpty() || !m_mainWindows.isEmpty())
128  return false;
129 
130  return excludeBeingDeleted ? !hasFloatingWindows()
131  : m_floatingWindows.isEmpty();
132 }
133 
134 void DockRegistry::checkSanityAll(bool dumpLayout)
135 {
136  for (auto layout : qAsConst(m_layouts)) {
137  layout->checkSanity();
138  if (dumpLayout)
139  layout->dumpLayout();
140  }
141 }
142 
143 bool DockRegistry::isProcessingAppQuitEvent() const
144 {
145  return m_isProcessingAppQuitEvent;
146 }
147 
148 bool DockRegistry::affinitiesMatch(const QStringList &affinities1, const QStringList &affinities2) const
149 {
150  if (affinities1.isEmpty() && affinities2.isEmpty())
151  return true;
152 
153  for (const QString &a1 : affinities1) {
154  for (const QString &a2 : affinities2) {
155  if (a1 == a2)
156  return true;
157  }
158  }
159 
160  return false;
161 }
162 
163 QStringList DockRegistry::mainWindowsNames() const
164 {
165  QStringList names;
166  names.reserve(m_mainWindows.size());
167  for (auto mw : m_mainWindows)
168  names.push_back(mw->uniqueName());
169 
170  return names;
171 }
172 
173 QStringList DockRegistry::dockWidgetNames() const
174 {
175  QStringList names;
176  names.reserve(m_dockWidgets.size());
177  for (auto dw : m_dockWidgets)
178  names.push_back(dw->uniqueName());
179 
180  return names;
181 }
182 
183 bool DockRegistry::isProbablyObscured(QWindow *window, FloatingWindow *exclude) const
184 {
185  if (!window)
186  return false;
187 
188  const QRect geo = window->geometry();
189  for (FloatingWindow *fw : m_floatingWindows) {
190  QWindow *fwWindow = fw->QWidgetAdapter::windowHandle();
191  if (fw == exclude || fwWindow == window)
192  continue;
193 
194  if (fwWindow->geometry().intersects(geo)) {
195  // fw might be below, but we don't have a way to check. So be conservative and return true.
196  return true;
197  }
198  }
199 
200  // Floating windows are Tool (keep above), unless we disabled it in Config
201  const bool targetIsToolWindow = KDDockWidgets::usesUtilityWindows() && floatingWindowForHandle(window) != nullptr;
202 
203  for (MainWindowBase *mw : m_mainWindows) {
204  QWindow *mwWindow = mw->window()->windowHandle();
205 
206  if (mwWindow && mwWindow != window && !targetIsToolWindow && mwWindow->geometry().intersects(geo)) {
207  // Two main windows that intersect. Return true. If the target is a tool window it will be above, so we don't care.
208  return true;
209  }
210  }
211 
212  return false;
213 }
214 
215 bool DockRegistry::isProbablyObscured(QWindow *target, WindowBeingDragged *exclude) const
216 {
217  FloatingWindow *fw = exclude ? exclude->floatingWindow()
218  : nullptr; // It's null on Wayland. On wayland obscuring never happens anyway, so not a problem.
219 
220  return isProbablyObscured(target, fw);
221 }
222 
223 SideBarLocation DockRegistry::sideBarLocationForDockWidget(const DockWidgetBase *dw) const
224 {
225  if (SideBar *sb = sideBarForDockWidget(dw))
226  return sb->location();
227 
228  return SideBarLocation::None;
229 }
230 
231 SideBar *DockRegistry::sideBarForDockWidget(const DockWidgetBase *dw) const
232 {
233  for (auto mw : m_mainWindows) {
234  if (SideBar *sb = mw->sideBarForDockWidget(dw))
235  return sb;
236  }
237 
238  return nullptr;
239 }
240 
241 Frame *DockRegistry::frameInMDIResize() const
242 {
243  for (auto mw : m_mainWindows) {
244  if (!mw->isMDI())
245  continue;
246 
247  LayoutWidget *layout = mw->layoutWidget();
248  const QList<Frame *> frames = layout->frames();
249  for (Frame *frame : frames) {
250  if (WidgetResizeHandler *wrh = frame->resizeHandler()) {
251  if (wrh->isResizing())
252  return frame;
253  }
254  }
255  }
256 
257  return nullptr;
258 }
259 
260 MainWindowBase::List DockRegistry::mainWindowsWithAffinity(const QStringList &affinities) const
261 {
262  MainWindowBase::List result;
263  result.reserve(m_mainWindows.size());
264 
265  for (auto mw : m_mainWindows) {
266  const QStringList mwAffinities = mw->affinities();
267  if (affinitiesMatch(mwAffinities, affinities))
268  result << mw;
269  }
270 
271  return result;
272 }
273 
274 LayoutWidget *DockRegistry::layoutForItem(const Layouting::Item *item) const
275 {
276  if (!item->hostWidget())
277  return nullptr;
278 
279  if (auto ms = qobject_cast<LayoutWidget *>(item->hostWidget()->asQObject()))
280  return ms;
281 
282  return nullptr;
283 }
284 
285 bool DockRegistry::itemIsInMainWindow(const Layouting::Item *item) const
286 {
287  if (LayoutWidget *layout = layoutForItem(item)) {
288  return layout->isInMainWindow(/*honoursNesting=*/true);
289  }
290 
291  return false;
292 }
293 
294 DockRegistry *DockRegistry::self()
295 {
296  static QPointer<DockRegistry> s_dockRegistry;
297 
298  if (!s_dockRegistry) {
299  s_dockRegistry = new DockRegistry();
300  }
301 
302  return s_dockRegistry;
303 }
304 
305 void DockRegistry::registerDockWidget(DockWidgetBase *dock)
306 {
307  if (dock->uniqueName().isEmpty()) {
308  qWarning() << Q_FUNC_INFO << "DockWidget" << dock << " doesn't have an ID";
309  } else if (auto other = dockByName(dock->uniqueName())) {
310  qWarning() << Q_FUNC_INFO << "Another DockWidget" << other << "with name" << dock->uniqueName() << " already exists." << dock;
311  }
312 
313  m_dockWidgets << dock;
314 }
315 
316 void DockRegistry::unregisterDockWidget(DockWidgetBase *dock)
317 {
318  if (m_focusedDockWidget == dock)
319  m_focusedDockWidget = nullptr;
320 
321  m_dockWidgets.removeOne(dock);
322  maybeDelete();
323 }
324 
325 void DockRegistry::registerMainWindow(MainWindowBase *mainWindow)
326 {
327  if (mainWindow->uniqueName().isEmpty()) {
328  qWarning() << Q_FUNC_INFO << "MainWindow" << mainWindow << " doesn't have an ID";
329  } else if (auto other = mainWindowByName(mainWindow->uniqueName())) {
330  qWarning() << Q_FUNC_INFO << "Another MainWindow" << other << "with name" << mainWindow->uniqueName() << " already exists." << mainWindow;
331  }
332 
333  m_mainWindows << mainWindow;
334 }
335 
336 void DockRegistry::unregisterMainWindow(MainWindowBase *mainWindow)
337 {
338  m_mainWindows.removeOne(mainWindow);
339  maybeDelete();
340 }
341 
342 void DockRegistry::registerFloatingWindow(FloatingWindow *window)
343 {
344  m_floatingWindows << window;
345 }
346 
347 void DockRegistry::unregisterFloatingWindow(FloatingWindow *window)
348 {
349  m_floatingWindows.removeOne(window);
350  maybeDelete();
351 }
352 
353 void DockRegistry::registerLayout(LayoutWidget *layout)
354 {
355  m_layouts << layout;
356 }
357 
358 void DockRegistry::unregisterLayout(LayoutWidget *layout)
359 {
360  m_layouts.removeOne(layout);
361 }
362 
363 void DockRegistry::registerFrame(Frame *frame)
364 {
365  m_frames << frame;
366 }
367 
368 void DockRegistry::unregisterFrame(Frame *frame)
369 {
370  m_frames.removeOne(frame);
371 }
372 
373 DockWidgetBase *DockRegistry::focusedDockWidget() const
374 {
375  return m_focusedDockWidget;
376 }
377 
378 bool DockRegistry::containsDockWidget(const QString &uniqueName) const
379 {
380  return dockByName(uniqueName) != nullptr;
381 }
382 
383 bool DockRegistry::containsMainWindow(const QString &uniqueName) const
384 {
385  return mainWindowByName(uniqueName) != nullptr;
386 }
387 
388 DockWidgetBase *DockRegistry::dockByName(const QString &name, DockByNameFlags flags) const
389 {
390  for (auto dock : qAsConst(m_dockWidgets)) {
391  if (dock->uniqueName() == name)
392  return dock;
393  }
394 
395  if (flags.testFlag(DockByNameFlag::ConsultRemapping)) {
396  // Name doesn't exist, let's check if it was remapped during a layout restore.
397  const QString newName = m_dockWidgetIdRemapping.value(name);
398  if (!newName.isEmpty())
399  return dockByName(newName);
400  }
401 
402  if (flags.testFlag(DockByNameFlag::CreateIfNotFound)) {
403  // DockWidget doesn't exist, ask to create it
404  if (auto factoryFunc = Config::self().dockWidgetFactoryFunc()) {
405  auto dw = factoryFunc(name);
406  if (dw && dw->uniqueName() != name) {
407  // Very special case
408  // The user's factory function returned a dock widget with a different ID.
409  // We support it. Save the mapping though.
410  m_dockWidgetIdRemapping.insert(name, dw->uniqueName());
411  }
412  return dw;
413  } else {
414  qWarning() << Q_FUNC_INFO << "Couldn't find dock widget" << name;
415  }
416  }
417 
418  return nullptr;
419 }
420 
421 MainWindowBase *DockRegistry::mainWindowByName(const QString &name) const
422 {
423  for (auto mainWindow : qAsConst(m_mainWindows)) {
424  if (mainWindow->uniqueName() == name)
425  return mainWindow;
426  }
427 
428  return nullptr;
429 }
430 
431 MainWindowMDI *DockRegistry::mdiMainWindowByName(const QString &name) const
432 {
433  return qobject_cast<MainWindowMDI *>(mainWindowByName(name));
434 }
435 
436 DockWidgetBase *DockRegistry::dockWidgetForGuest(QWidgetOrQuick *guest) const
437 {
438  if (!guest)
439  return nullptr;
440 
441  for (DockWidgetBase *dw : m_dockWidgets) {
442  if (dw->widget() == guest)
443  return dw;
444  }
445 
446  return nullptr;
447 }
448 
449 bool DockRegistry::isSane() const
450 {
451  QSet<QString> names;
452  for (auto dock : qAsConst(m_dockWidgets)) {
453  const QString name = dock->uniqueName();
454  if (name.isEmpty()) {
455  qWarning() << "DockRegistry::isSane: DockWidget" << dock << "is missing a name";
456  return false;
457  } else if (names.contains(name)) {
458  qWarning() << "DockRegistry::isSane: dockWidgets with duplicate names:" << name;
459  return false;
460  } else {
461  names.insert(name);
462  }
463  }
464 
465  names.clear();
466  for (auto mainwindow : qAsConst(m_mainWindows)) {
467  const QString name = mainwindow->uniqueName();
468  if (name.isEmpty()) {
469  qWarning() << "DockRegistry::isSane: MainWindow" << mainwindow << "is missing a name";
470  return false;
471  } else if (names.contains(name)) {
472  qWarning() << "DockRegistry::isSane: mainWindow with duplicate names:" << name;
473  return false;
474  } else {
475  names.insert(name);
476  }
477 
478  if (!mainwindow->multiSplitter()->checkSanity())
479  return false;
480  }
481 
482  return true;
483 }
484 
485 const DockWidgetBase::List DockRegistry::dockwidgets() const
486 {
487  return m_dockWidgets;
488 }
489 
490 const DockWidgetBase::List DockRegistry::dockWidgets(const QStringList &names)
491 {
492  DockWidgetBase::List result;
493  result.reserve(names.size());
494 
495  for (auto dw : qAsConst(m_dockWidgets)) {
496  if (names.contains(dw->uniqueName()))
497  result.push_back(dw);
498  }
499 
500  return result;
501 }
502 
503 const MainWindowBase::List DockRegistry::mainWindows(const QStringList &names)
504 {
505  MainWindowBase::List result;
506  result.reserve(names.size());
507 
508  for (auto mw : qAsConst(m_mainWindows)) {
509  if (names.contains(mw->uniqueName()))
510  result.push_back(mw);
511  }
512 
513  return result;
514 }
515 
516 const DockWidgetBase::List DockRegistry::closedDockwidgets() const
517 {
518  DockWidgetBase::List result;
519  result.reserve(m_dockWidgets.size());
520 
521  for (DockWidgetBase *dw : m_dockWidgets) {
522  if (dw->parent() == nullptr && !dw->isVisible())
523  result.push_back(dw);
524  }
525 
526  return result;
527 }
528 
529 const MainWindowBase::List DockRegistry::mainwindows() const
530 {
531  return m_mainWindows;
532 }
533 
534 const QVector<LayoutWidget *> DockRegistry::layouts() const
535 {
536  return m_layouts;
537 }
538 
539 const Frame::List DockRegistry::frames() const
540 {
541  return m_frames;
542 }
543 
544 const QVector<FloatingWindow *> DockRegistry::floatingWindows(bool includeBeingDeleted) const
545 {
546  // Returns all the FloatingWindow which aren't being deleted
548  result.reserve(m_floatingWindows.size());
549  for (FloatingWindow *fw : m_floatingWindows) {
550  if (includeBeingDeleted || !fw->beingDeleted())
551  result.push_back(fw);
552  }
553 
554  return result;
555 }
556 
557 const QVector<QWindow *> DockRegistry::floatingQWindows() const
558 {
559  QVector<QWindow *> windows;
560  windows.reserve(m_floatingWindows.size());
561  for (FloatingWindow *fw : m_floatingWindows) {
562  if (!fw->beingDeleted()) {
563  if (QWindow *window = fw->windowHandle()) {
564  window->setProperty("kddockwidgets_qwidget", QVariant::fromValue<QWidgetOrQuick *>(fw)); // Since QWidgetWindow is private API
565  windows.push_back(window);
566  } else {
567  qWarning() << Q_FUNC_INFO << "FloatingWindow doesn't have QWindow";
568  }
569  }
570  }
571 
572  return windows;
573 }
574 
575 bool DockRegistry::hasFloatingWindows() const
576 {
577  return std::any_of(m_floatingWindows.begin(), m_floatingWindows.end(), [](FloatingWindow *fw) {
578  return !fw->beingDeleted();
579  });
580 }
581 
582 QWindow *DockRegistry::windowForHandle(WId id) const
583 {
584  const QWindowList windows = qApp->topLevelWindows();
585  for (QWindow *w : windows) {
586  if (w->isVisible() && w->handle()) {
587  if (w->winId() == id)
588  return w;
589  }
590  }
591  return nullptr;
592 }
593 
594 FloatingWindow *DockRegistry::floatingWindowForHandle(QWindow *windowHandle) const
595 {
596  for (FloatingWindow *fw : m_floatingWindows) {
597  if (fw->windowHandle() == windowHandle)
598  return fw;
599  }
600 
601  return nullptr;
602 }
603 
604 FloatingWindow *DockRegistry::floatingWindowForHandle(WId hwnd) const
605 {
606  for (FloatingWindow *fw : m_floatingWindows) {
607  if (fw->windowHandle() && fw->windowHandle()->winId() == hwnd)
608  return fw;
609  }
610 
611  return nullptr;
612 }
613 
614 MainWindowBase *DockRegistry::mainWindowForHandle(QWindow *windowHandle) const
615 {
616  for (MainWindowBase *mw : m_mainWindows) {
617  if (mw->windowHandle() == windowHandle)
618  return mw;
619  }
620 
621  return nullptr;
622 }
623 
624 QWidgetOrQuick *DockRegistry::topLevelForHandle(QWindow *windowHandle) const
625 {
626  if (auto fw = floatingWindowForHandle(windowHandle))
627  return fw;
628 
629  if (auto mw = mainWindowForHandle(windowHandle))
630  return mw;
631 
632  return nullptr;
633 }
634 
635 QVector<QWindow *> DockRegistry::topLevels(bool excludeFloatingDocks) const
636 {
637  QVector<QWindow *> windows;
638  windows.reserve(m_floatingWindows.size() + m_mainWindows.size());
639 
640  if (!excludeFloatingDocks) {
641  for (FloatingWindow *fw : m_floatingWindows) {
642  if (fw->isVisible()) {
643  if (QWindow *window = fw->windowHandle()) {
644  window->setProperty("kddockwidgets_qwidget", QVariant::fromValue<QWidgetOrQuick *>(fw)); // Since QWidgetWindow is private API
645  windows << window;
646  } else {
647  qWarning() << Q_FUNC_INFO << "FloatingWindow doesn't have QWindow";
648  }
649  }
650  }
651  }
652 
653  for (MainWindowBase *m : m_mainWindows) {
654  if (m->isVisible()) {
655  if (QWindow *window = m->window()->windowHandle()) {
656  window->setProperty("kddockwidgets_qwidget", QVariant::fromValue<QWidgetOrQuick *>(m));
657  windows << window;
658  } else {
659  qWarning() << Q_FUNC_INFO << "MainWindow doesn't have QWindow";
660  }
661  }
662  }
663 
664  return windows;
665 }
666 
667 void DockRegistry::clear(const QStringList &affinities)
668 {
669  // Clears everything
670  clear(m_dockWidgets, m_mainWindows, affinities);
671 }
672 
673 void DockRegistry::clear(const DockWidgetBase::List &dockWidgets,
674  const MainWindowBase::List &mainWindows,
675  const QStringList &affinities)
676 {
677  for (auto dw : qAsConst(dockWidgets)) {
678  if (affinities.isEmpty() || affinitiesMatch(affinities, dw->affinities())) {
679  dw->forceClose();
680  dw->d->lastPosition()->removePlaceholders();
681  }
682  }
683 
684  for (auto mw : qAsConst(mainWindows)) {
685  if (affinities.isEmpty() || affinitiesMatch(affinities, mw->affinities())) {
686  mw->multiSplitter()->clearLayout();
687  }
688  }
689 }
690 
691 void DockRegistry::ensureAllFloatingWidgetsAreMorphed()
692 {
693  for (DockWidgetBase *dw : qAsConst(m_dockWidgets)) {
694  if (dw->window() == dw && dw->isVisible())
695  dw->d->morphIntoFloatingWindow();
696  }
697 }
698 
699 bool DockRegistry::eventFilter(QObject *watched, QEvent *event)
700 {
701  if (event->type() == QEvent::Quit && !m_isProcessingAppQuitEvent) {
702  m_isProcessingAppQuitEvent = true;
703  qApp->sendEvent(qApp, event);
704  m_isProcessingAppQuitEvent = false;
705  return true;
706  } else if (event->type() == QEvent::Expose) {
707  if (auto windowHandle = qobject_cast<QWindow *>(watched)) {
708  if (FloatingWindow *fw = floatingWindowForHandle(windowHandle)) {
709  // This floating window was exposed
710  m_floatingWindows.removeOne(fw);
711  m_floatingWindows.append(fw);
712  }
713  }
714  } else if (event->type() == QEvent::MouseButtonPress) {
715  // When clicking on a MDI Frame we raise the window
716  if (Frame *f = firstParentOfType<Frame>(watched)) {
717  if (f->isMDI())
718  f->raise();
719  }
720 
721  // The following code is for hididng the overlay
722  if (!(Config::self().flags() & Config::Flag_AutoHideSupport))
723  return false;
724 
725  if (qobject_cast<Frame *>(watched)) {
726  // break recursion
727  return false;
728  }
729 
730  auto p = watched;
731  while (p) {
732  if (auto dw = qobject_cast<DockWidgetBase *>(p))
733  return onDockWidgetPressed(dw, static_cast<QMouseEvent *>(event));
734 
735  if (auto layoutWidget = qobject_cast<LayoutWidget *>(p)) {
736  if (auto mw = layoutWidget->mainWindow()) {
737  // The user clicked somewhere in the main window's drop area, but outside of the
738  // overlayed dock widget
739  mw->clearSideBarOverlay();
740  return false;
741  }
742  }
743 
744  p = p->parent();
745  }
746  }
747 
748  return false;
749 }
750 
751 bool DockRegistry::onDockWidgetPressed(DockWidgetBase *dw, QMouseEvent *ev)
752 {
753  // Here we implement "auto-hide". If there's a overlayed dock widget, we hide it if some other
754  // dock widget is clicked.
755 
756 #ifdef KDDOCKWIDGETS_QTWIDGETS
757  // Don't be sending mouse events around if a popup is open, they are sensitive
758  if (qApp->activePopupWidget())
759  return false;
760 #endif
761 
762  MainWindowBase *mainWindow = dw->mainWindow();
763  if (!mainWindow) // Only docked widgets are interesting
764  return false;
765 
766  if (DockWidgetBase *overlayedDockWidget = mainWindow->overlayedDockWidget()) {
767  ev->ignore();
768  qApp->sendEvent(overlayedDockWidget->d->frame(), ev);
769 
770  if (ev->isAccepted()) {
771  // The Frame accepted it. It means the user is resizing it. We allow for 4px outside for better resize.
772  return true; // don't propagate the event further
773  }
774  if (dw != overlayedDockWidget) {
775  // User clicked outside if the overlay, then we close the overlay.
776  mainWindow->clearSideBarOverlay();
777  return false;
778  }
779  }
780 
781  return false;
782 }
QPointer
KDDockWidgets::registerQmlTypes
void registerQmlTypes()
Definition: QmlTypes.cpp:26
KDDockWidgets::MainWindowBase::clearSideBarOverlay
Q_INVOKABLE void clearSideBarOverlay(bool deleteFrame=true)
closes any overlayed dock widget. The sidebar still displays them as button.
Definition: MainWindowBase.cpp:572
QSet
DockWidgetBase.h
The DockWidget base-class that's shared between QtWidgets and QtQuick stack.
KDDockWidgets::DockWidgetBase::mainWindow
MainWindowBase * mainWindow() const
Returns the main window this dock widget is in. nullptr if it's not inside a main window Also returns...
Definition: DockWidgetBase.cpp:427
QEvent::Quit
Quit
KDDockWidgets::DockWidgetBase::affinities
QStringList affinities() const
Returns the affinity name. Empty by default.
Definition: DockWidgetBase.cpp:385
QRect
QWindow::geometry
QRect geometry() const const
KDDockWidgets::DockWidgetBase::forceClose
Q_INVOKABLE void forceClose()
Like QWidget::close() but the hosted widget won't be asked if we should close.
Definition: DockWidgetBase.cpp:367
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QWindow
QVector::push_back
void push_back(const T &value)
QWidget
KDDockWidgets::DockWidgetBase::uniqueName
QString uniqueName
Definition: DockWidgetBase.h:65
QList::push_back
void push_back(const T &value)
QList
QMouseEvent
KDDockWidgets::DockWidgetBase::widget
QObject * widget
Definition: DockWidgetBase.h:67
QWidgetAdapter.h
Abstraction for supporting both QtWidgets and QtQuick.
QList::reserve
void reserve(int alloc)
QRect::intersects
bool intersects(const QRect &rectangle) const const
QList::size
int size() const const
QObject
QString
QEvent::isAccepted
bool isAccepted() const const
QObject::installEventFilter
void installEventFilter(QObject *filterObj)
QString::isEmpty
bool isEmpty() const const
KDDockWidgets::MainWindowBase::uniqueName
QString uniqueName
Definition: MainWindowBase.h:59
QList::isEmpty
bool isEmpty() const const
KDDockWidgets::DockWidgetBase::isFocusedChanged
void isFocusedChanged(bool)
emitted when isFocused changes
initKDDockWidgetResources
static void initKDDockWidgetResources()
Definition: DockRegistry.cpp:41
KDDockWidgets::SideBarLocation
SideBarLocation
Each main window supports 4 sidebars.
Definition: KDDockWidgets.h:208
QVector::reserve
void reserve(int size)
KDDockWidgets::MainWindowMDI
MainWindow sub-class which uses MDI as a layout.
Definition: MainWindowMDI.h:32
QSet::contains
bool contains(const T &value) const const
Config.h
Application-wide config to tune certain behaviours of the framework.
QGuiApplication::focusObjectChanged
void focusObjectChanged(QObject *focusObject)
QSet::clear
void clear()
QEvent::type
QEvent::Type type() const const
QEvent
QEvent::ignore
void ignore()
KDDockWidgets::DockWidgetBase
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
Definition: DockWidgetBase.h:61
KDDockWidgets
Definition: Config.cpp:37
QSet::insert
QSet::iterator insert(const T &value)
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56
QVector
MainWindowMDI.h
MainWindow sub-class which uses MDI as a layout.
QmlTypes.h
Namespace-level methods related to registering QML types.
QStringList
KDDockWidgets::MainWindowBase::overlayedDockWidget
DockWidgetBase * overlayedDockWidget() const
returns the dock widget which is currently overlayed. nullptr if none. This is only relevant when usi...
Definition: MainWindowBase.cpp:616

© 2019-2022 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated on Thu Sep 15 2022 00:16:27 for KDDockWidgets API Documentation by doxygen 1.8.20