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

© 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 Mon Mar 7 2022 02:01:20 for KDDockWidgets API Documentation by doxygen 1.8.20