KDDockWidgets API Documentation  1.6
FloatingWindowWidget.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 "FloatingWindowWidget_p.h"
13 #include "../DockRegistry_p.h"
14 #include "../DropArea_p.h"
15 #include "../Logging_p.h"
16 #include "../TitleBar_p.h"
17 #include "../Utils_p.h"
18 
19 #include <QApplication>
20 #include <QPainter>
21 #include <QVBoxLayout>
22 #include <QWindow>
23 #include <QWindowStateChangeEvent>
24 
25 using namespace KDDockWidgets;
26 
27 FloatingWindowWidget::FloatingWindowWidget(QRect suggestedGeometry, MainWindowBase *parent)
28  : FloatingWindow(suggestedGeometry, parent)
29  , m_vlayout(new QVBoxLayout(this))
30 {
31  init();
32 }
33 
34 FloatingWindowWidget::FloatingWindowWidget(Frame *frame, QRect suggestedGeometry, MainWindowBase *parent)
35  : FloatingWindow(frame, suggestedGeometry, parent)
36  , m_vlayout(new QVBoxLayout(this))
37 {
38  init();
39 }
40 
41 void FloatingWindowWidget::paintEvent(QPaintEvent *ev)
42 {
43  if (Config::self().disabledPaintEvents() & Config::CustomizableWidget_FloatingWindow) {
45  return;
46  }
47 
48  QPainter p(this);
49  QPen pen(0x666666);
50  pen.setWidth(1);
51  pen.setJoinStyle(Qt::MiterJoin);
52  p.setPen(pen);
53  const qreal halfPenWidth = p.pen().widthF() / 2;
54  const QRectF rectf = rect();
55  p.drawRect(rectf.adjusted(halfPenWidth, halfPenWidth, -halfPenWidth, -halfPenWidth));
56 }
57 
58 bool FloatingWindowWidget::event(QEvent *ev)
59 {
60  if (ev->type() == QEvent::NonClientAreaMouseButtonDblClick && (Config::self().flags() & Config::Flag_NativeTitleBar)) {
61  if ((windowFlags() & Qt::Tool) == Qt::Tool) {
62  if (Config::self().flags() & Config::Flag_DoubleClickMaximizes) {
63  // Let's refuse to maximize Qt::Tool. It's not natural.
64  // Just avoid this combination: Flag_NativeTitleBar + Qt::Tool + Flag_DoubleClickMaximizes
65  } else {
66  // Double clicking a Qt::Tool title-bar. Triggers a redocking.
67  if (m_titleBar->isFloating()) { // redocking nested floating windows aren't supported
68  m_titleBar->onFloatClicked();
69  return true;
70  }
71  }
72  } else {
73  // A normal Qt::Window window. The OS handles the double click.
74  // In general this will maximize the window, that's the native behaviour.
75  }
76  } else if (ev->type() == QEvent::Show && !m_screenChangedConnection) {
77  // We connect after QEvent::Show, so we have a QWindow. Qt doesn't offer much API to
78  // intercept screen events
79  m_screenChangedConnection =
80  connect(windowHandle(), &QWindow::screenChanged, DockRegistry::self(),
81  [this] { Q_EMIT DockRegistry::self()->windowChangedScreen(windowHandle()); });
82 
83  windowHandle()->installEventFilter(this);
84  }
85 
86  return FloatingWindow::event(ev);
87 }
88 
89 bool FloatingWindowWidget::eventFilter(QObject *o, QEvent *ev)
90 {
91  if (ev->type() == QEvent::WindowStateChange) {
92 
93  // TODOv2: Have this fix for QtQuick too
94 
95  // QWidget::windowState() is not reliable as it's emitted both for the spontaneous (async) event and non-spontaneous (sync)
96  // The sync one being useless, as the window manager can still have the old state.
97  // Only emit windowStateChanged once the window manager tells us the state has actually changed
98  // See also QTBUG-102430
99  if (ev->spontaneous()) {
100  m_lastWindowManagerState = windowHandle()->windowState();
101  Q_EMIT windowStateChanged();
102  }
103  }
104 
105  return FloatingWindow::eventFilter(o, ev);
106 }
107 
108 void FloatingWindowWidget::init()
109 {
110  m_vlayout->setSpacing(0);
111  updateMargins();
112  m_vlayout->addWidget(m_titleBar);
113  m_vlayout->addWidget(m_dropArea);
114 
115  connect(DockRegistry::self(), &DockRegistry::windowChangedScreen, this, [this](QWindow *w) {
116  if (w == window()->windowHandle())
117  updateMargins();
118  });
119 }
120 
121 void FloatingWindowWidget::updateMargins()
122 {
123  m_vlayout->setContentsMargins(QMargins(4, 4, 4, 4) * logicalDpiFactor(this));
124 }
QVBoxLayout
QEvent::NonClientAreaMouseButtonDblClick
NonClientAreaMouseButtonDblClick
QWidget::paintEvent
virtual void paintEvent(QPaintEvent *event)
QRect
Qt::MiterJoin
MiterJoin
QWindow
QRectF::adjusted
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const const
QPainter
QPen
Qt::Tool
Tool
QObject
QEvent::spontaneous
bool spontaneous() const const
QMargins
QWindow::screenChanged
void screenChanged(QScreen *screen)
QEvent::type
QEvent::Type type() const const
QEvent
QPaintEvent
QRectF
KDDockWidgets
Definition: Config.cpp:37
KDDockWidgets::MainWindowBase
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Definition: MainWindowBase.h:56

© 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 Thu Sep 15 2022 00:16:28 for KDDockWidgets API Documentation by doxygen 1.8.20