KDDockWidgets API Documentation  1.5
FloatingWindowQuick.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 "FloatingWindowQuick_p.h"
13 #include "MainWindowBase.h"
14 #include "Config.h"
15 #include "FrameworkWidgetFactory.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 
27 using namespace KDDockWidgets;
28 
29 namespace KDDockWidgets {
30 
31 class QuickView : public QQuickView
32 {
33  Q_OBJECT
34 public:
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
98 private:
99  FloatingWindow *const m_floatingWindow;
100 };
101 
102 QuickView::~QuickView() = default;
103 
104 }
105 
106 
107 FloatingWindowQuick::FloatingWindowQuick(MainWindowBase *parent)
108  : FloatingWindow(QRect(), parent)
109  , m_quickWindow(new QuickView(Config::self().qmlEngine(), this))
110 {
111  init();
112 }
113 
114 FloatingWindowQuick::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 
123 FloatingWindowQuick::~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 
135 QSize 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 
143 void 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 
152 int FloatingWindowQuick::contentsMargins() const
153 {
154  return m_visualItem->property("margins").toInt();
155 }
156 
157 int FloatingWindowQuick::titleBarHeight() const
158 {
159  return m_visualItem->property("titleBarHeight").toInt();
160 }
161 
162 QWindow *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 
171 void 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"
QColor
QRect::setSize
void setSize(const QSize &size)
QEvent::FocusAboutToChange
FocusAboutToChange
QRect::size
QSize size() const const
QRect
QWindow
QSize
MainWindowBase.h
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
KDDockWidgets::Config::InternalFlag_UseTransparentFloatingWindow
@ InternalFlag_UseTransparentFloatingWindow
For QtQuick only. Allows to have round-corners. It's flaky when used with native Windows drop-shadow.
Definition: Config.h:118
KDDockWidgets::Config
Singleton to allow to choose certain behaviours of the framework.
Definition: Config.h:55
Config.h
Application-wide config to tune certain behaviours of the framework.
QSize::expandedTo
QSize expandedTo(const QSize &otherSize) const const
QWindow::nativeEvent
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result)
QEvent::type
QEvent::Type type() const const
QEvent
QObject::setObjectName
void setObjectName(const QString &name)
KDDockWidgets
Definition: Config.cpp:36
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56
QObject::parent
QObject * parent() const const
Qt::transparent
transparent
QByteArray
KDDockWidgets::Config::self
static Config & self()
returns the singleton Config instance
Definition: Config.cpp:82
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.

© 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