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->hasSingleGroup()) {
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->hasSingleGroup();
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 (hasSingleGroup()) {
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 (hasSingleGroup()) {
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#ifdef KDDW_FRONTEND_QT_WINDOWS
584 if (Platform::instance()->isQtQuick()) {
585 // We'll minimized it after the 1st frameSwap(), so it appears in alt-tab and taskbar thumbnails.
586 // Also fixes non-client area size, due to Qt not honouring WM_NCCALCSIZE correctly when showing minimized without a show normal before
587 d->m_minimizationPending = true;
588 } else {
589 // Workaround not implemented for QtWidgets, needs to be tested there.
590 view()->showMinimized();
591 }
592#else
593 view()->showMinimized();
594#endif
595 } else {
596 view()->showNormal();
597 }
598
599 d->numDockWidgetsChanged.emit();
600 return true;
601 }
602
603 return false;
604}
605
606LayoutSaver::FloatingWindow FloatingWindow::serialize() const
607{
608 LayoutSaver::FloatingWindow fw;
609
610 fw.geometry = geometry();
611 fw.normalGeometry = view()->normalGeometry();
612 fw.isVisible = isVisible();
613 fw.multiSplitterLayout = dropArea()->serialize();
614 fw.screenIndex = Platform::instance()->screenNumberForView(view());
615 fw.screenSize = Platform::instance()->screenSizeFor(view());
616 fw.affinities = affinities();
617 fw.windowState = windowStateOverride();
618 fw.flags = d->m_flags;
619
620 Window::Ptr transientParentWindow = view()->d->transientWindow();
621 auto transientMainWindow = DockRegistry::self()->mainWindowForHandle(transientParentWindow);
622 fw.parentIndex =
623 transientMainWindow ? DockRegistry::self()->mainwindows().indexOf(transientMainWindow) : -1;
624
625 return fw;
626}
627
629{
630 Rect rect;
631 if (m_titleBar->isVisible()) {
632 rect = m_titleBar->rect();
633 rect.moveTopLeft(m_titleBar->view()->mapToGlobal(Point(0, 0)));
634 } else if (hasSingleGroup()) {
635 rect = groups().constFirst()->dragRect();
636 } else {
637 KDDW_ERROR("Expected a title bar");
638 }
639
640 return rect;
641}
642
644{
645 const Core::Group::List groups = this->groups();
646 return std::all_of(groups.begin(), groups.end(), [option](Core::Group *group) {
647 return group->allDockWidgetsHave(option);
648 });
649}
650
652{
653 const Core::Group::List groups = this->groups();
654 return std::any_of(groups.begin(), groups.end(), [option](Core::Group *group) {
655 return group->anyDockWidgetsHas(option);
656 });
657}
658
660{
661 const Core::Group::List groups = this->groups();
662 return std::all_of(groups.begin(), groups.end(), [option](Core::Group *group) {
663 return group->allDockWidgetsHave(option);
664 });
665}
666
668{
669 const Core::Group::List groups = this->groups();
670 return std::any_of(groups.begin(), groups.end(), [option](Core::Group *group) {
671 return group->anyDockWidgetsHas(option);
672 });
673}
674
676 Core::DockWidget *relativeTo, const InitialOption &option)
677{
678 d->m_dropArea->addDockWidget(dw, location, relativeTo, option);
679}
680
682{
683 return false;
684}
685
687{
688 return true;
689}
690
692{
693 return view()->parentView()->asMainWindowController();
694}
695
697{
698 return { 4, 4, 4, 4 };
699}
700
705
707{
708 if (Core::Group *f = singleFrame())
709 return f->userType();
710 return 0;
711}
712
713void FloatingWindow::updateSizeConstraints()
714{
715#ifdef KDDW_FRONTEND_QT
716 // Doing a delayed call to make sure the layout has completed any ongoing operation.
717 QTimer::singleShot(0, this, [this] {
718 // Not simply using layout's max-size support because
719 // 1) that's not portable to QtQuick
720 // 2) QStackedLayout (from tab-widget) doesn't propagate size constraints up
721 // Doing it manually instead.
722 view()->setMaximumSize(maxSizeHint());
723 });
724#endif
725}
726
728{
729 const auto screens = Platform::instance()->screens();
730 if (screens.empty())
731 return;
732
733 int nearestDistSq = std::numeric_limits<int>::max();
734 int nearestIndex = -1;
735
736 const int screenCount = screens.count();
737 for (int i = 0; i < screenCount; i++) {
738 const Rect scrGeom = screens[i]->geometry();
739
740 // If the rectangle is visible at all, we need do nothing
741 if (scrGeom.intersects(geometry))
742 return;
743
744 // Find the nearest screen, so we can move the geometry onto it
745 const Point dist2D = geometry.center() - scrGeom.center();
746 const int distSq = (dist2D.x() * dist2D.x()) + (dist2D.y() * dist2D.y());
747 if (distSq < nearestDistSq) {
748 nearestDistSq = distSq;
749 nearestIndex = i;
750 }
751 }
752
753 // Move the rectangle to the nearest vertical and/or horizontal screen edge
754 auto scrGeom = screens[nearestIndex]->geometry();
755 scrGeom.moveTopLeft(scrGeom.topLeft() - screens[nearestIndex]->virtualGeometry().topLeft());
756
757 if (geometry.left() < scrGeom.left()) {
758 geometry.moveLeft(scrGeom.left());
759 } else if (geometry.left() > scrGeom.right()) {
760 geometry.moveRight(scrGeom.right());
761 }
762
763 if (geometry.top() < scrGeom.top()) {
764 geometry.moveTop(scrGeom.top());
765 } else if (geometry.top() > scrGeom.bottom()) {
766 geometry.moveBottom(scrGeom.bottom());
767 }
768}
769
774
779
784
786{
787 const bool dontUse = (d->m_flags & FloatingWindowFlag::DontUseParentForFloatingWindows) && (d->m_flags & FloatingWindowFlag::UseQtWindow);
788 return !dontUse;
789}
790
791FloatingWindowFlags FloatingWindow::floatingWindowFlags() const
792{
793 return d->m_flags;
794}
795
796FloatingWindow::Private *FloatingWindow::dptr() const
797{
798 return d;
799}
800
802{
803 const auto groups = this->groups();
804 if (groups.isEmpty())
805 return; // doesn't really happen
806
807 groups.constFirst()->focus(reason);
808}
809
810inline FloatingWindowFlags flagsForFloatingWindow(FloatingWindowFlags requestedFlags)
811{
812 if (!(requestedFlags & FloatingWindowFlag::FromGlobalConfig)) {
813 // User requested specific flags for this floating window
814 return requestedFlags;
815 }
816
817 // Use from KDDockWidgets::Config instead. This is app-wide and not per window.
818
819 FloatingWindowFlags flags = {};
820
824
827
830
833
836
839
842
845
846 return flags;
847}
848
849FloatingWindow::Private::Private(FloatingWindowFlags requestedFlags, FloatingWindow *q)
850 : m_flags(flagsForFloatingWindow(requestedFlags))
851 , m_dropArea(new DropArea(q->view(), MainWindowOption_None))
852{
853}
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:88
@ 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 hasSingleGro...
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.
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)
void addDockWidget(DockWidget *, KDDockWidgets::Location location, DockWidget *relativeTo, const InitialOption &={})
Adds the dock widget to the specified location.
Vector< DockWidget * > dockWidgets() const
bool beingDeleted() const
Returns whether a deleteLater has already been issued.
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 hasSingleGroup() const
checks if this FloatingWindow only has one group. If true it means there's no side-by-side dock widge...
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:320
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 int screenNumberForView(View *) const =0
Returns the screen index for the specified view or window. It's up to the platform to decide how scre...
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.
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