KDDockWidgets API Documentation 1.7
Loading...
Searching...
No Matches
FloatingWindowQuick.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2019-2023 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 "FloatingWindowQuick_p.h"
13#include "MainWindowBase.h"
14#include "Config.h"
16
17#include "TitleBarQuick_p.h"
18
19#include "../Logging_p.h"
20#include "../Utils_p.h"
21#include "../DropArea_p.h"
22#include "../WidgetResizeHandler_p.h"
23
24#include <QQuickView>
25#include <QDebug>
26
27using namespace KDDockWidgets;
28
29namespace KDDockWidgets {
30
31class QuickView : public QQuickView
32{
33 Q_OBJECT
34public:
35 explicit QuickView(QQmlEngine *qmlEngine, FloatingWindow *floatingWindow)
36 : QQuickView(qmlEngine, nullptr)
37 , m_floatingWindow(floatingWindow)
38 {
40 setColor(QColor(Qt::transparent));
41
42 updateSize();
43
44 connect(m_floatingWindow, &QQuickItem::widthChanged, this, &QuickView::onRootItemWidthChanged);
45 connect(m_floatingWindow, &QQuickItem::heightChanged, this, &QuickView::onRootItemHeightChanged);
46 }
47
48 ~QuickView();
49
50 bool event(QEvent *ev) override
51 {
52 if (ev->type() == QEvent::FocusAboutToChange) {
53 // qquickwindow.cpp::event(FocusAboutToChange) removes the item grabber. Inibit that
54 return true;
55 } else if (ev->type() == QEvent::Resize) {
56 updateRootItemSize();
57 } else if (isNonClientMouseEvent(ev) || ev->type() == QEvent::Move) {
58 // Mimic QWidget behaviour: The non-client mouse events go to the QWidget not the QWindow. In our case the QQuickItem.
59 // I mean, they also go to QWindow, but for our QtWidgets impl we process them at the QWidget level, so use the same approach
60 // so we maintain a single code path for processing mouse events
61 qApp->sendEvent(m_floatingWindow, ev);
62 return true;
63 }
64
65 return QQuickView::event(ev);
66 }
67
68 void onRootItemWidthChanged()
69 {
70 setWidth(int(m_floatingWindow->width()));
71 }
72
73 void onRootItemHeightChanged()
74 {
75 setHeight(int(m_floatingWindow->height()));
76 }
77
78 void updateSize()
79 {
80 resize(m_floatingWindow->size());
81 }
82
83 void updateRootItemSize()
84 {
85 m_floatingWindow->setSize(size());
86 }
87
88#ifdef Q_OS_WIN
89 bool nativeEvent(const QByteArray &eventType, void *message, Qt5Qt6Compat::qintptr *result) override
90 {
91 // To enable aero snap we need to tell Windows where's our custom title bar
92 if (!m_floatingWindow->beingDeleted() && WidgetResizeHandler::handleWindowsNativeEvent(m_floatingWindow, eventType, message, result))
93 return true;
94
95 return QWindow::nativeEvent(eventType, message, result);
96 }
97#endif
98private:
99 FloatingWindow *const m_floatingWindow;
100};
101
102QuickView::~QuickView() = default;
103
104}
105
106
107FloatingWindowQuick::FloatingWindowQuick(MainWindowBase *parent, FloatingWindowFlags flags)
108 : FloatingWindow(QRect(), parent, flags)
109 , m_quickWindow(new QuickView(Config::self().qmlEngine(), this))
110{
111 init();
112}
113
114FloatingWindowQuick::FloatingWindowQuick(Frame *frame, QRect suggestedGeometry, MainWindowBase *parent)
115 : FloatingWindow(frame, QRect(), parent)
116 , m_quickWindow(new QuickView(Config::self().qmlEngine(), this))
117{
118 init();
119 // For QtQuick we need to set the suggested geometry only after we have the QWindow
120 setGeometry(suggestedGeometry);
121}
122
123FloatingWindowQuick::~FloatingWindowQuick()
124{
125 // Avoid a bunch of QML warnings and constraints being violated at destruction.
126 // Also simply avoiding unneeded work, as QML is destroying stuff 1 by 1
127 if (m_dropArea)
128 m_dropArea->setWindowIsBeingDestroyed(true);
129
130 QWidgetAdapter::setParent(nullptr);
131 if (qobject_cast<QQuickView *>(m_quickWindow)) // QObject cast just to make sure the QWindow is not in ~QObject already
132 delete m_quickWindow;
133}
134
135QSize FloatingWindowQuick::minimumSize() const
136{
137 // Doesn't matter if it's not visible. We don't want the min-size to jump around. Also not so
138 // easy to track as we don't have layouts
139 const int margins = contentsMargins();
140 return multiSplitter()->minimumSize() + QSize(0, titleBarHeight()) + QSize(margins * 2, margins * 2);
141}
142
143void FloatingWindowQuick::setGeometry(QRect geo)
144{
145 // Not needed with QtWidgets, but needed with QtQuick as we don't have layouts
146 geo.setSize(geo.size().expandedTo(minimumSize()));
147
148 parentItem()->setSize(geo.size());
149 m_quickWindow->setGeometry(geo);
150}
151
152int FloatingWindowQuick::contentsMargins() const
153{
154 return m_visualItem->property("margins").toInt();
155}
156
157int FloatingWindowQuick::titleBarHeight() const
158{
159 return m_visualItem->property("titleBarHeight").toInt();
160}
161
162QWindow *FloatingWindowQuick::candidateParentWindow() const
163{
164 if (auto mainWindow = qobject_cast<MainWindowBase *>(QObject::parent())) {
165 return mainWindow->QQuickItem::window();
166 }
167
168 return nullptr;
169}
170
171void FloatingWindowQuick::init()
172{
173 connect(this, &QQuickItem::visibleChanged, this, [this] {
174 if (!isVisible() && !beingDeleted()) {
175 scheduleDeleteLater();
176 }
177 });
178
179 /* for debug:
180 connect(m_quickWindow, &QQuickView::focusObjectChanged, this, [this] (QObject *object) {
181 qDebug() << "Focus object changed to " << object << this << m_quickWindow;
182 });*/
183
184
185 if (QWindow *transientParent = candidateParentWindow()) {
186 m_quickWindow->setTransientParent(candidateParentWindow());
187 // This mimics the QWidget behaviour, where we not only have a transient parent but also
188 // a parent for cleanup. Calling QWindow::setParent() here would clip it to the parent
189 m_quickWindow->QObject::setParent(transientParent);
190 m_quickWindow->setObjectName(QStringLiteral("Floating QWindow with parent")); // for debug
191 } else {
192 m_quickWindow->setObjectName(QStringLiteral("Floating QWindow"));
193 }
194
195 QWidgetAdapter::setParent(m_quickWindow->contentItem());
196 WidgetResizeHandler::setupWindow(m_quickWindow);
197 m_quickWindow->installEventFilter(this); // for window resizing
198 maybeCreateResizeHandler();
199
200 m_visualItem = createItem(m_quickWindow->engine(),
201 Config::self().frameworkWidgetFactory()->floatingWindowFilename().toString());
202 Q_ASSERT(m_visualItem);
203
204 // Ensure our window size is never smaller than our min-size
205 setSize(size().expandedTo(minimumSize()));
206
207 m_visualItem->setParent(this);
208 m_visualItem->setParentItem(this);
209
210 m_quickWindow->setFlags(windowFlags());
211
212 updateTitleAndIcon();
213
214 m_quickWindow->show();
215}
216
217#include "FloatingWindowQuick.moc"
Application-wide config to tune certain behaviours of the framework.
A factory class for allowing the user to customize some internal widgets.
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
Singleton to allow to choose certain behaviours of the framework.
Definition Config.h:75
@ InternalFlag_UseTransparentFloatingWindow
For QtQuick only. Allows to have round-corners. It's flaky when used with native Windows drop-shadow.
Definition Config.h:136
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition Config.cpp:145
static Config & self()
returns the singleton Config instance
Definition Config.cpp:84
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
FocusAboutToChange
QEvent::Type type() const const
void setObjectName(const QString &name)
QObject * parent() const const
void setSize(const QSize &size)
QSize size() const const
QSize expandedTo(const QSize &otherSize) const const
transparent
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result)

© 2019-2023 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 Wed Nov 1 2023 00:02:31 for KDDockWidgets API Documentation by doxygen 1.9.8