KDDockWidgets API Documentation 2.0
Loading...
Searching...
No Matches
core/FloatingWindow.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2020 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 "FloatingWindow.h"
13#include "FloatingWindow_p.h"
14#include "MainWindow.h"
15#include "core/Logging_p.h"
16#include "TitleBar.h"
17#include "Group.h"
18#include "Platform.h"
19#include "KDDockWidgets.h"
20#include "core/WindowBeingDragged_p.h"
21#include "core/Utils_p.h"
22#include "core/Controller_p.h"
23#include "core/WidgetResizeHandler_p.h"
24#include "DockRegistry.h"
25#include "Config.h"
26#include "Layout_p.h"
27#include "core/ViewFactory.h"
28#include "core/DelayedCall_p.h"
29#include "core/DragController_p.h"
30#include "core/LayoutSaver_p.h"
31#include "DockWidget_p.h"
32#include "DropArea.h"
33#include "core/ScopedValueRollback_p.h"
34#include "core/layouting/Item_p.h"
35#include "View.h"
36#include "core/View_p.h"
37
38#include "kdbindings/signal.h"
39
40#ifdef KDDW_FRONTEND_QT
41#include <QTimer>
42#ifdef Q_OS_WIN
43#include <QGuiApplication>
44#include <Windows.h>
45#endif
46#endif
47
48#include <limits>
49
50using namespace KDDockWidgets;
51using namespace KDDockWidgets::Core;
52
53static FloatingWindowFlags floatingWindowFlagsForGroup(Group *group)
54{
55 if (!group)
56 return FloatingWindowFlag::FromGlobalConfig;
57
58 const auto dockwidgets = group->dockWidgets();
59 if (!dockwidgets.isEmpty())
60 return dockwidgets.first()->floatingWindowFlags();
61
62 return FloatingWindowFlag::FromGlobalConfig;
63}
64
67
68static Qt::WindowFlags windowFlagsToUse(FloatingWindowFlags requestedFlags)
69{
70 if (requestedFlags & FloatingWindowFlag::UseQtTool) {
71 // User has explicitly chosen Qt::Tool for this FloatingWindow
72 return Qt::Tool;
73 }
74
75 if (requestedFlags & FloatingWindowFlag::UseQtWindow) {
76 // User has explicitly chosen Qt::Window for this FloatingWindow
77 return Qt::Window;
78 }
79
81 // User overridden the default for all FloatingWindows
83 }
84
85 if (KDDockWidgets::usesNativeDraggingAndResizing())
86 return Qt::Window;
87
88 if (Config::self().internalFlags()
90 return Qt::Window;
91
92 return Qt::Tool;
93}
94
95static MainWindow *hackFindParentHarder(Core::Group *group, MainWindow *candidateParent)
96{
97 const FloatingWindowFlags requestedFlags =
98 group ? group->requestedFloatingWindowFlags() : FloatingWindowFlag::FromGlobalConfig;
99 if (requestedFlags & FloatingWindowFlag::DontUseParentForFloatingWindows) {
100 // User explicitly requested no parent for this floating window
101 return nullptr;
102 }
103
105 return nullptr;
106 }
107
108 // Using a parent helps the floating windows stay in front of the main window always.
109 // We're not receiving the parent via ctor argument as the app can have multiple-main windows,
110 // so use a hack here.
111 // Not quite clear what to do if the app supports multiple main windows though.
112
113 if (candidateParent)
114 return candidateParent;
115
117
118 if (windows.isEmpty())
119 return nullptr;
120
121 if (windows.size() == 1)
122 return windows.first();
123
124 const Vector<QString> affinities = group ? group->affinities() : Vector<QString>();
125 const MainWindow::List mainWindows =
127
128 if (mainWindows.isEmpty()) {
129 KDDW_ERROR("No window with affinity={} found", affinities, "found");
130 return nullptr;
131 }
132
133 return mainWindows.first();
134}
135
137{
139 ? nullptr
140 : candidate;
141}
142
143FloatingWindow::FloatingWindow(Rect suggestedGeometry, MainWindow *parent,
144 FloatingWindowFlags requestedFlags)
146 Config::self().viewFactory()->createFloatingWindow(
147 this, actualParent(parent), windowFlagsToUse(requestedFlags)))
148 , Draggable(view(),
149 KDDockWidgets::usesNativeDraggingAndResizing()) // FloatingWindow is only draggable
150 // when using a native title bar.
151 // Otherwise the
152 // KDDockWidgets::TitleBar is the
153 // draggable
154 , d(new Private(requestedFlags, this))
155 , m_titleBar(new Core::TitleBar(this))
156{
157 view()->init();
158 if (!suggestedGeometry.isNull())
159 view()->setGeometry(suggestedGeometry);
160
161#if defined(Q_OS_WIN) && defined(KDDW_FRONTEND_QTWIDGETS)
162 // For QtQuick we do it a bit later, once we have the QQuickWindow
163 if (Platform::instance()->isQtWidgets()) {
164 view()->createPlatformWindow(); // QWidget::create
165
166 // Handle WM_NCHITTEST
167 m_nchittestFilter = new NCHITTESTEventFilter(view());
168 qGuiApp->installNativeEventFilter(m_nchittestFilter);
169
170 // Enables native drop-shadow
171 WidgetResizeHandler::setupWindow(view()->window());
172
173 // WM_NCCALCSIZE is handled in the views's nativeEvent(), not here.
174 }
175#endif
176
178
181
182 if (Platform::instance()->isQtWidgets()) {
183 // QtQuick will do it a bit later, once it has a QWindow
185 }
186
188
189 d->m_visibleWidgetCountConnection =
190 d->m_dropArea->d_ptr()->visibleWidgetCountChanged.connect([this](int count) {
191 onFrameCountChanged(count);
192 d->numGroupsChanged.emit();
193 onVisibleFrameCountChanged(count);
194 });
195
196 view()->d->closeRequested.connect([this](CloseEvent *ev) { onCloseEvent(ev); });
197
198 view()->d->layoutInvalidated.connect([this] { updateSizeConstraints(); });
199
200 d->m_layoutDestroyedConnection = d->m_dropArea->Controller::dptr()->aboutToBeDeleted.connect(&FloatingWindow::scheduleDeleteLater, this);
201
202 d->numGroupsChanged.connect([this] {
203 d->numDockWidgetsChanged.emit();
204 });
205}
206
207FloatingWindow::FloatingWindow(Core::Group *group, Rect suggestedGeometry,
208 MainWindow *parent)
210{
211 ScopedValueRollback guard(m_disableSetVisible, true);
212
213 if (group->hasNestedMDIDockWidgets()) {
214 // When using DockWidget::MDINestable, the docked MDI widget is wrapped by a drop area so we
215 // can drop things into it. When floating it, we can delete that helper drop area, as
216 // FloatingWindow already has one
217
218 if (group->dockWidgetCount() == 0) {
219 // doesn't happen
220 KDDW_ERROR("Unexpected empty group");
221 return;
222 }
223
224 DockWidget *dwMDIWrapper = group->dockWidgetAt(0);
225 DropArea *dropAreaMDIWrapper = dwMDIWrapper->d->mdiDropAreaWrapper();
226
227 if (dropAreaMDIWrapper->hasSingleFrame()) {
228 Core::Group *innerFrame = dropAreaMDIWrapper->groups().constFirst();
229 if (innerFrame->hasSingleDockWidget()) {
230 // When pressing the unfloat button, the dock widgets gets docked to the previous
231 // position it was at. Core::DockWidget::Private::m_lastPosition stores that
232 // location, however, when having nested MDI, we have an extra Dock Widget, the
233 // wrapper, and it contains the last position. So, when floating, we need to
234 // transfer that and not lose it.
235 DockWidget *dw = innerFrame->dockWidgetAt(0);
236 dw->d->lastPosition() = dwMDIWrapper->d->lastPosition();
237 }
238 }
239
240 d->m_dropArea->addMultiSplitter(dropAreaMDIWrapper, Location_OnTop);
241 dwMDIWrapper->setVisible(false);
242 if (!DragController::instance()->isIdle()) {
243 // We're dragging a MDI window and we reached the border, detaching it, and making it
244 // float. We can't delete the wrapper group just yet, as that would delete the title bar
245 // which is currently being dragged. Delete it once the drag finishes
246 d->m_currentStateChangedConnection = DragController::instance()->currentStateChanged.connect([this, dwMDIWrapper] {
247 if (DragController::instance()->isIdle()) {
248 d->m_currentStateChangedConnection = KDBindings::ScopedConnection();
249 delete dwMDIWrapper;
250 }
251 });
252 } else {
253 dwMDIWrapper->destroyLater();
254 }
255
256 } else {
257 // Adding a widget will trigger onFrameCountChanged, which triggers a setVisible(true).
258 // The problem with setVisible(true) will forget about or requested geometry and place the
259 // window at 0,0 So disable the setVisible(true) call while in the ctor.
260 d->m_dropArea->addWidget(group->view(), KDDockWidgets::Location_OnTop, {});
261 }
262
263 if (!suggestedGeometry.isNull())
264 view()->setGeometry(suggestedGeometry);
265}
266
268{
269 m_inDtor = true;
270 view()->d->setAboutToBeDestroyed();
271
272 if (auto da = dropArea()) {
273 // Avoid a bunch of QML warnings and constraints being violated at destruction.
274 // Also simply avoiding unneeded work, as QML is destroying stuff 1 by 1
275 da->view()->d->setAboutToBeDestroyed();
276 }
277
278 d->m_layoutDestroyedConnection = KDBindings::ScopedConnection();
279
280#ifdef KDDW_FRONTEND_QT_WINDOWS
281 delete m_nchittestFilter;
282#endif
283
285 delete m_titleBar;
286 delete d;
287}
288
290{
291 if (!KDDockWidgets::usesNativeDraggingAndResizing()) {
293 // EGLFS can't have different mouse cursors per window, needs global filter hack to unset
294 // when cursor leaves
295 const auto filterMode = isEGLFS() ? WidgetResizeHandler::EventFilterMode::Global
296 : WidgetResizeHandler::EventFilterMode::Local;
297 setWidgetResizeHandler(
298 new WidgetResizeHandler(filterMode, WidgetResizeHandler::WindowMode::TopLevel, view()));
299 }
300}
301
303{
304 return d->m_dropArea;
305}
306
307std::unique_ptr<WindowBeingDragged> FloatingWindow::makeWindow()
308{
309 return std::make_unique<WindowBeingDragged>(this, this);
310}
311
313{
314 const Core::Group::List groups = this->groups();
315 if (groups.size() == 1) {
316 Core::Group *group = groups.first();
317 if (group->hasSingleDockWidget())
318 return group->dockWidgetAt(0);
319 }
320
321 return nullptr;
322}
323
325{
326 return d->m_dropArea->dockWidgets();
327}
328
330{
331 assert(d->m_dropArea);
332 return d->m_dropArea->groups();
333}
334
335Size FloatingWindow::maxSizeHint() const
336{
337 Size result = Core::Item::hardcodedMaximumSize;
338
339 if (!d->m_dropArea) {
340 // Still early, no layout set
341 return result;
342 }
343
344 const Core::Group::List groups = this->groups();
345 if (groups.size() == 1) {
346 // Let's honour max-size when we have a single-group.
347 // multi-group cases are more complicated and we're not sure if we want the window to
348 // bounce around. single-group is the most common case, like floating a dock widget, so
349 // let's do that first, it's also easy.
350 Core::Group *group = groups[0];
351 if (group->dockWidgetCount() == 1) { // We don't support if there's tabbing
352 const Size waste =
353 (view()->minSize() - group->view()->minSize()).expandedTo(Size(0, 0));
354 result = group->view()->maxSizeHint() + waste;
355 }
356 }
357
358 // Semantically the result is fine, but bound it so we don't get:
359 // QWidget::setMaximumSize: (/KDDockWidgets::FloatingWindowWidget) The largest allowed size is
360 // (16777215,16777215)
361 return result.boundedTo(Core::Item::hardcodedMaximumSize);
362}
363
364void FloatingWindow::setSuggestedGeometry(Rect suggestedRect, SuggestedGeometryHints hint)
365{
366 const Size maxSize = maxSizeHint();
367 const bool hasMaxSize = maxSize != Core::Item::hardcodedMaximumSize;
368 if (hasMaxSize) {
369 // Resize to new size but preserve center
370 const Point originalCenter = suggestedRect.center();
371 suggestedRect.setSize(maxSize.boundedTo(suggestedRect.size()));
372
374 && (d->m_flags & FloatingWindowFlag::NativeTitleBar)) {
375 const auto margins = contentMargins();
376 suggestedRect.setHeight(suggestedRect.height() - m_titleBar->view()->height()
377 + margins.top() + margins.bottom());
378 }
379
381 suggestedRect.moveCenter(originalCenter);
382 }
383
384 ensureRectIsOnScreen(suggestedRect);
385
386 view()->setGeometry(suggestedRect);
387}
388
390{
391 m_deleteScheduled = true;
392 view()->d->setAboutToBeDestroyed();
394 destroyLater();
395}
396
398{
399 return d->m_dropArea;
400}
401
403{
404 return d->m_dropArea;
405}
406
407bool FloatingWindow::isInDragArea(Point globalPoint) const
408{
409#ifdef KDDW_FRONTEND_QT_WINDOWS
410 // A click near the border will still send a Qt::NonClientMousePressEvent. We shouldn't
411 // interpret that as a drag, as it's for a native resize.
412 // Keep track of how we handled the WM_NCHITTEST
413 if (usesAeroSnapWithCustomDecos())
414 return m_lastHitTest == HTCAPTION;
415#endif
416
417 return dragRect().contains(globalPoint);
418}
419
421{
422 const auto groups = this->groups();
423 for (Core::Group *group : groups) {
424 if (group->anyNonClosable())
425 return true;
426 }
427 return false;
428}
429
431{
432 const auto groups = this->groups();
433 for (Core::Group *group : groups) {
434 if (group->anyNonDockable())
435 return true;
436 }
437 return false;
438}
439
441{
442 return d->m_dropArea->hasSingleFrame();
443}
444
446{
447 const Core::Group::List groups = this->groups();
448 if (groups.size() != 1)
449 return false;
450
451 Core::Group *group = groups.first();
452 return group->dockWidgetCount() == 1;
453}
454
456{
457 const Core::Group::List groups = this->groups();
458 return groups.isEmpty() ? nullptr : groups.first();
459}
460
462{
463 if (m_deleteScheduled || m_inDtor)
464 return true;
465
466 const auto groups = this->groups();
467 for (Core::Group *f : groups) {
468 if (f->beingDeletedLater())
469 return true;
470 }
471
472 return false;
473}
474
475void FloatingWindow::onFrameCountChanged(int count)
476{
477 if (count == 0) {
479 } else {
481 if (count == 1) // if something was removed, then our single dock widget is floating, we
482 // need to check the Action
483 dropArea()->updateFloatingActions();
484 }
485}
486
487void FloatingWindow::onVisibleFrameCountChanged(int count)
488{
489 if (m_disableSetVisible)
490 return;
491
492 updateSizeConstraints();
493 setVisible(count > 0);
494}
495
496WindowState FloatingWindow::windowStateOverride() const
497{
499
500 if (view()->isMaximized())
502 else if (view()->isMinimized())
504
505 return state;
506}
507
509{
510 if (m_updatingTitleBarVisibility)
511 return; // Break recursion
512
513 ScopedValueRollback guard(m_updatingTitleBarVisibility, true);
515
516 bool visible = true;
517
518 const auto groups = this->groups();
519 for (Core::Group *group : groups)
521
522 if (KDDockWidgets::usesClientTitleBar()) {
525 if (hasSingleFrame()) {
526 visible = !groups.first()->hasTabsVisible();
527 }
528 }
529
531 } else {
532 visible = false;
533 }
534
535 m_titleBar->setVisible(visible);
536}
537
539{
540 auto groups = this->groups();
541 return groups.isEmpty() ? Vector<QString>() : groups.constFirst()->affinities();
542}
543
545{
546 QString title;
547 Icon icon;
548 if (hasSingleFrame()) {
549 const Core::Group *group = groups().constFirst();
550 title = group->title();
551 icon = group->icon();
552 } else {
554 }
555 m_titleBar->setTitle(title);
556 m_titleBar->setIcon(icon);
557
558 // Even without a native title bar it's nice to set the window title/icon, so it shows
559 // in the taskbar (when minimization is supported), or Alt-Tab (in supporting Window Managers)
560 view()->setWindowTitle(title);
561 view()->setWindowIcon(icon);
562}
563
564void FloatingWindow::onCloseEvent(CloseEvent *e)
565{
566 if (e->spontaneous() && anyNonClosable()) {
567 // Event from the window system won't close us
568 e->ignore();
569 return;
570 }
571
572 d->m_dropArea->onCloseEvent(e);
573}
574
575bool FloatingWindow::deserialize(const LayoutSaver::FloatingWindow &fw)
576{
577 if (dropArea()->deserialize(fw.multiSplitterLayout)) {
579
580 if (int(fw.windowState) & int(WindowState::Maximized)) {
581 view()->showMaximized();
582 } else if (int(fw.windowState) & int(WindowState::Minimized)) {
583 view()->showMinimized();
584 } else {
585 view()->showNormal();
586 }
587
588 d->numDockWidgetsChanged.emit();
589 return true;
590 }
591
592 return false;
593}
594
595LayoutSaver::FloatingWindow FloatingWindow::serialize() const
596{
597 LayoutSaver::FloatingWindow fw;
598
599 fw.geometry = geometry();
600 fw.normalGeometry = view()->normalGeometry();
601 fw.isVisible = isVisible();
602 fw.multiSplitterLayout = dropArea()->serialize();
603 fw.screenIndex = Platform::instance()->screenNumberFor(view());
604 fw.screenSize = Platform::instance()->screenSizeFor(view());
605 fw.affinities = affinities();
606 fw.windowState = windowStateOverride();
607 fw.flags = d->m_flags;
608
609 Window::Ptr transientParentWindow = view()->d->transientWindow();
610 auto transientMainWindow = DockRegistry::self()->mainWindowForHandle(transientParentWindow);
611 fw.parentIndex =
612 transientMainWindow ? DockRegistry::self()->mainwindows().indexOf(transientMainWindow) : -1;
613
614 return fw;
615}
616
618{
619 Rect rect;
620 if (m_titleBar->isVisible()) {
621 rect = m_titleBar->rect();
622 rect.moveTopLeft(m_titleBar->view()->mapToGlobal(Point(0, 0)));
623 } else if (hasSingleFrame()) {
624 rect = groups().constFirst()->dragRect();
625 } else {
626 KDDW_ERROR("Expected a title bar");
627 }
628
629 return rect;
630}
631
633{
634 const Core::Group::List groups = this->groups();
635 return std::all_of(groups.begin(), groups.end(), [option](Core::Group *group) {
636 return group->allDockWidgetsHave(option);
637 });
638}
639
641{
642 const Core::Group::List groups = this->groups();
643 return std::any_of(groups.begin(), groups.end(), [option](Core::Group *group) {
644 return group->anyDockWidgetsHas(option);
645 });
646}
647
649{
650 const Core::Group::List groups = this->groups();
651 return std::all_of(groups.begin(), groups.end(), [option](Core::Group *group) {
652 return group->allDockWidgetsHave(option);
653 });
654}
655
657{
658 const Core::Group::List groups = this->groups();
659 return std::any_of(groups.begin(), groups.end(), [option](Core::Group *group) {
660 return group->anyDockWidgetsHas(option);
661 });
662}
663
665 Core::DockWidget *relativeTo, InitialOption option)
666{
667 d->m_dropArea->addDockWidget(dw, location, relativeTo, option);
668}
669
671{
672 return false;
673}
674
676{
677 return true;
678}
679
681{
682 return view()->parentView()->asMainWindowController();
683}
684
686{
687 return { 4, 4, 4, 4 };
688}
689
694
696{
697 if (Core::Group *f = singleFrame())
698 return f->userType();
699 return 0;
700}
701
702void FloatingWindow::updateSizeConstraints()
703{
704#ifdef KDDW_FRONTEND_QT
705 // Doing a delayed call to make sure the layout has completed any ongoing operation.
706 QTimer::singleShot(0, this, [this] {
707 // Not simply using layout's max-size support because
708 // 1) that's not portable to QtQuick
709 // 2) QStackedLayout (from tab-widget) doesn't propagate size constraints up
710 // Doing it manually instead.
711 view()->setMaximumSize(maxSizeHint());
712 });
713#endif
714}
715
717{
718 const auto screens = Platform::instance()->screens();
719 if (screens.empty())
720 return;
721
722 int nearestDistSq = std::numeric_limits<int>::max();
723 int nearestIndex = -1;
724
725 const int screenCount = screens.count();
726 for (int i = 0; i < screenCount; i++) {
727 const Rect scrGeom = screens[i]->geometry();
728
729 // If the rectangle is visible at all, we need do nothing
730 if (scrGeom.intersects(geometry))
731 return;
732
733 // Find the nearest screen, so we can move the geometry onto it
734 const Point dist2D = geometry.center() - scrGeom.center();
735 const int distSq = (dist2D.x() * dist2D.x()) + (dist2D.y() * dist2D.y());
736 if (distSq < nearestDistSq) {
737 nearestDistSq = distSq;
738 nearestIndex = i;
739 }
740 }
741
742 // Move the rectangle to the nearest vertical and/or horizontal screen edge
743 auto scrGeom = screens[nearestIndex]->geometry();
744 scrGeom.moveTopLeft(scrGeom.topLeft() - screens[nearestIndex]->virtualGeometry().topLeft());
745
746 if (geometry.left() < scrGeom.left()) {
747 geometry.moveLeft(scrGeom.left());
748 } else if (geometry.left() > scrGeom.right()) {
749 geometry.moveRight(scrGeom.right());
750 }
751
752 if (geometry.top() < scrGeom.top()) {
753 geometry.moveTop(scrGeom.top());
754 } else if (geometry.top() > scrGeom.bottom()) {
755 geometry.moveBottom(scrGeom.bottom());
756 }
757}
758
763
768
773
775{
776 const bool dontUse = (d->m_flags & FloatingWindowFlag::DontUseParentForFloatingWindows) && (d->m_flags & FloatingWindowFlag::UseQtWindow);
777 return !dontUse;
778}
779
780FloatingWindowFlags FloatingWindow::floatingWindowFlags() const
781{
782 return d->m_flags;
783}
784
785FloatingWindow::Private *FloatingWindow::dptr() const
786{
787 return d;
788}
789
791{
792 const auto groups = this->groups();
793 if (groups.isEmpty())
794 return; // doesn't really happen
795
796 groups.constFirst()->focus(reason);
797}
798
799inline FloatingWindowFlags flagsForFloatingWindow(FloatingWindowFlags requestedFlags)
800{
801 if (!(requestedFlags & FloatingWindowFlag::FromGlobalConfig)) {
802 // User requested specific flags for this floating window
803 return requestedFlags;
804 }
805
806 // Use from KDDockWidgets::Config instead. This is app-wide and not per window.
807
808 FloatingWindowFlags flags = {};
809
813
816
819
822
825
828
831
834
835 return flags;
836}
837
838FloatingWindow::Private::Private(FloatingWindowFlags requestedFlags, FloatingWindow *q)
839 : m_flags(flagsForFloatingWindow(requestedFlags))
840 , m_dropArea(new DropArea(q->view(), MainWindowOption_None))
841{
842}
Application-wide config to tune certain behaviours of the framework.
File with KDDockWidgets namespace-level enums and methods.
A ScopedConnection is a RAII-style way to make sure a Connection is disconnected.
Definition signal.h:533
Singleton to allow to choose certain behaviours of the framework.
Definition Config.h:64
@ InternalFlag_DontUseQtToolWindowsForFloatingWindows
FloatingWindows will use Qt::Window instead of Qt::Tool.
Definition Config.h:160
@ InternalFlag_DontUseParentForFloatingWindows
FloatingWindows won't have a parent top-level.
Definition Config.h:158
static Config & self()
returns the singleton Config instance
Definition Config.cpp:87
@ Flag_HideTitleBarWhenTabsVisible
Definition Config.h:89
@ Flag_TitleBarHasMaximizeButton
Definition Config.h:97
@ Flag_KeepAboveIfNotUtilityWindow
Definition Config.h:119
@ Flag_AlwaysTitleBarWhenFloating
Definition Config.h:85
View * view() const
Returns the view associated with this controller, if any.
std::shared_ptr< View > window() const
The DockWidget base-class. DockWidget and Core::DockWidget are only split in two so we can share some...
Vector< Core::Group * > groups() const
bool hasSingleDockWidget() const
checks if this FloatingWindow only has one dockwidget. This is a more specific case than hasSingleFra...
bool supportsMaximizeButton() const
Returns whether this floating window supports showing a maximize button.
MainWindow * mainWindow() const
Returns the MainWindow which is the transient parent of this FloatingWindow Can be nullptr if you cre...
bool allDockWidgetsHave(DockWidgetOption) const
Returns whether all dock widgets have the specified option set.
void setSuggestedGeometry(Rect suggestedRect, SuggestedGeometryHints=SuggestedGeometryHint_None)
Equivalent to setGeometry(), but the value might be adjusted.
Core::DropArea * multiSplitter() const
Returns the MultiSplitter.
Margins contentMargins() const
Returns the contents margins.
bool anyDockWidgetsHas(DockWidgetOption) const
Returns whether at least one dock widget has the specified option set.
FloatingWindowFlags floatingWindowFlags() const
Returns the per-floating window flags.
bool hasSingleFrame() const
checks if this FloatingWindow only has one group. If true it means there's no side-by-side dock widge...
Core::DockWidget * singleDockWidget() const override final
bool isUtilityWindow() const
Returns whether this window is a tool window Tool windows don't usually appear in the task bar.
Core::Group * singleFrame() const
If this floating window has only one Frame, it's returned, otherwise nullptr.
std::unique_ptr< WindowBeingDragged > makeWindow() override
FloatingWindow(Rect suggestedGeometry, MainWindow *parent=nullptr, FloatingWindowFlags requestedFlags=FloatingWindowFlag::FromGlobalConfig)
Vector< DockWidget * > dockWidgets() const
bool beingDeleted() const
Returns whether a deleteLater has already been issued.
void addDockWidget(DockWidget *, KDDockWidgets::Location location, DockWidget *relativeTo, InitialOption={})
Adds the dock widget to the specified location.
static void ensureRectIsOnScreen(Rect &geometry)
bool isInDragArea(Point globalPoint) const
Returns whether globalPoint is inside the title bar (or, when there's no title-bar,...
void updateTitleAndIcon()
updates the title and the icon
Layout * layout() const
Returns the Layout.
static Qt::WindowFlags s_windowFlagsOverride
Allows the user app to specify which window flags to use, instead of KDDWs default ones Bugs caused b...
bool supportsMinimizeButton() const
Returns whether this floating window supports showing a minimize button.
void scheduleDeleteLater()
Equivalent to deleteLater() but sets beingDeleted() to true.
LayoutSaver::FloatingWindow serialize() const
bool deserialize(const LayoutSaver::FloatingWindow &)
bool hasSingleDockWidget() const
returns whether there's only 1 dock widget.
Definition core/Group.h:196
DockWidget * dockWidgetAt(int index) const
Returns the dock widget at index.
Vector< DockWidget * > dockWidgets() const
Vector< QString > affinities() const
FloatingWindowFlags requestedFloatingWindowFlags() const
User requested floating window flags for when this group floats.
int dockWidgetCount() const
returns the number of dock widgets inside the group
The widget (QWidget or QQuickItem) which holds a layout of dock widgets.
Definition Layout.h:57
LayoutSaver::MultiSplitter serialize() const
Definition Layout.cpp:323
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
virtual QString applicationName() const =0
Returns the application name This name will be used as title of floating dock widgets which contain m...
static Platform * instance()
Returns the platform singleton.
virtual Size screenSizeFor(View *) const =0
Returns the size of the screen where this view is in.
virtual Vector< std::shared_ptr< Screen > > screens() const =0
Returns all available screens.
virtual int screenNumberFor(View *) const =0
Returns the screen index for the specified view or window. It's up to the platform to decide how scre...
void setIcon(const Icon &icon)
void setTitle(const QString &title)
void updateButtons()
updates the close button enabled state
virtual void setMaximumSize(Size sz)=0
virtual Size minSize() const =0
virtual void setWindowIcon(const Icon &)=0
virtual void setWindowTitle(const QString &title)=0
virtual Size maxSizeHint() const =0
virtual std::shared_ptr< View > parentView() const =0
Returns the gui element's parent. Like QWidget::parentWidget()
virtual Rect normalGeometry() const =0
virtual void createPlatformWindow()
virtual Point mapToGlobal(Point) const =0
virtual void showMinimized()=0
virtual void setFlag(Qt::WindowType, bool=true)=0
virtual void showMaximized()=0
virtual void showNormal()=0
virtual void setGeometry(Rect)=0
Core::MainWindow * mainWindowForHandle(std::shared_ptr< Core::Window > windowHandle) const
returns the MainWindow with handle windowHandle
void unregisterFloatingWindow(Core::FloatingWindow *)
static DockRegistry * self()
Vector< Core::MainWindow * > mainWindowsWithAffinity(const Vector< QString > &affinities) const
Returns all main windows which match at least one of the affinities.
void registerFloatingWindow(Core::FloatingWindow *)
Vector< Core::MainWindow * > mainwindows() const
returns all MainWindow instances
static MainWindow * hackFindParentHarder(Core::Group *group, MainWindow *candidateParent)
static FloatingWindowFlags floatingWindowFlagsForGroup(Group *group)
FloatingWindowFlags flagsForFloatingWindow(FloatingWindowFlags requestedFlags)
MainWindow * actualParent(MainWindow *candidate)
static Qt::WindowFlags windowFlagsToUse(FloatingWindowFlags requestedFlags)
ViewType
Each View type also has a specific Controller associated with, except for ViewType::None.
Definition Controller.h:26
Class to abstract QAction, so code still works with QtQuick and Flutter.
@ Location_OnTop
‍Left docking location
@ SuggestedGeometryHint_PreserveCenter
@ SuggestedGeometryHint_GeometryIsFromDocked
DockWidgetOption
DockWidget options to pass at construction time.
LayoutSaverOption
Options which will affect LayoutSaver save/restore.
FocusReason
typedef WindowFlags
A MultiSplitter with support for drop indicators when hovering over.
QMainWindow sub-class to enable KDDockWidgets support.
Struct describing the preferred dock widget size and visibility when adding it to a layout.

© 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 by doxygen 1.9.8