aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuhang Zhao <2546789017@qq.com>2020-02-12 20:03:11 +0800
committerYuhang Zhao <2546789017@qq.com>2020-07-23 20:15:33 +0800
commit2a0626a9cd544f66c8023881b4d534f5199d4e74 (patch)
treec8fedbde3d36d095b7ee2f68b7d7ebec8144b4f9
parent25bef605b47476ec670a5e57cb3fbbfc09e8a2f3 (diff)
Add a function to change non-client area rendering policy
Documentation and a manual test are added at the same time. Change-Id: I1e70e9b01fb13d0e67559024531f9ad015849032 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--src/imports/winextras/plugins.qmltypes9
-rw-r--r--src/imports/winextras/qquickdwmfeatures.cpp27
-rw-r--r--src/imports/winextras/qquickdwmfeatures_p.h4
-rw-r--r--src/imports/winextras/qquickdwmfeatures_p_p.h1
-rw-r--r--src/imports/winextras/qquickwin_p.h8
-rw-r--r--src/winextras/qwinfunctions.cpp97
-rw-r--r--src/winextras/qwinfunctions.h27
-rw-r--r--tests/manual/dwmfeatures/testwidget.cpp25
-rw-r--r--tests/manual/dwmfeatures/testwidget.h1
-rw-r--r--tests/manual/dwmfeatures/testwidget.ui68
10 files changed, 252 insertions, 15 deletions
diff --git a/src/imports/winextras/plugins.qmltypes b/src/imports/winextras/plugins.qmltypes
index 2c4c390..fff1181 100644
--- a/src/imports/winextras/plugins.qmltypes
+++ b/src/imports/winextras/plugins.qmltypes
@@ -26,6 +26,7 @@ Module {
Property { name: "excludedFromPeek"; type: "bool" }
Property { name: "peekDisallowed"; type: "bool" }
Property { name: "flip3DPolicy"; type: "QQuickWin::WindowFlip3DPolicy" }
+ Property { name: "nonClientAreaRenderingPolicy"; type: "QQuickWin::WindowNonClientRenderingPolicy" }
}
Component {
name: "QQuickJumpList"
@@ -144,6 +145,14 @@ Module {
"FlipExcludeAbove": 2
}
}
+ Enum {
+ name: "WindowNonClientRenderingPolicy"
+ values: {
+ "NonClientRenderingUseWindowStyle": 0,
+ "NonClientRenderingDisabled": 1,
+ "NonClientRenderingEnabled": 2
+ }
+ }
}
Component {
name: "QWinTaskbarProgress"
diff --git a/src/imports/winextras/qquickdwmfeatures.cpp b/src/imports/winextras/qquickdwmfeatures.cpp
index a7ca158..124d957 100644
--- a/src/imports/winextras/qquickdwmfeatures.cpp
+++ b/src/imports/winextras/qquickdwmfeatures.cpp
@@ -293,6 +293,32 @@ void QQuickDwmFeatures::setFlip3DPolicy(QQuickWin::WindowFlip3DPolicy policy)
emit flip3DPolicyChanged();
}
+/*!
+ \qmlproperty QtWin::WindowNonClientRenderingPolicy DwmFeatures::nonClientAreaRenderingPolicy
+
+ The current non-client area rendering policy for the window.
+ */
+QQuickWin::WindowNonClientRenderingPolicy QQuickDwmFeatures::nonClientAreaRenderingPolicy() const
+{
+ Q_D(const QQuickDwmFeatures);
+ if (window())
+ return static_cast<QQuickWin::WindowNonClientRenderingPolicy>(QtWin::windowNonClientAreaRenderingPolicy(window()));
+ else
+ return d->nonClientRenderingPolicy;
+}
+
+void QQuickDwmFeatures::setNonClientAreaRenderingPolicy(QQuickWin::WindowNonClientRenderingPolicy policy)
+{
+ Q_D(QQuickDwmFeatures);
+ if (d->nonClientRenderingPolicy == policy)
+ return;
+
+ d->nonClientRenderingPolicy = policy;
+ if (window())
+ QtWin::setWindowNonClientAreaRenderingPolicy(window(), static_cast<QtWin::WindowNonClientRenderingPolicy>(d->nonClientRenderingPolicy));
+ emit nonClientAreaRenderingPolicyChanged();
+}
+
bool QQuickDwmFeatures::eventFilter(QObject *object, QEvent *event)
{
Q_D(QQuickDwmFeatures);
@@ -349,6 +375,7 @@ void QQuickDwmFeaturesPrivate::updateAll()
QtWin::setWindowExcludedFromPeek(w, peekExcluded);
QtWin::setWindowDisallowPeek(w, peekDisallowed);
QtWin::setWindowFlip3DPolicy(w, static_cast<QtWin::WindowFlip3DPolicy>(flipPolicy));
+ QtWin::setWindowNonClientAreaRenderingPolicy(w, static_cast<QtWin::WindowNonClientRenderingPolicy>(nonClientRenderingPolicy));
if (blurBehindEnabled)
QtWin::enableBlurBehindWindow(w);
else
diff --git a/src/imports/winextras/qquickdwmfeatures_p.h b/src/imports/winextras/qquickdwmfeatures_p.h
index d98aa00..3887d24 100644
--- a/src/imports/winextras/qquickdwmfeatures_p.h
+++ b/src/imports/winextras/qquickdwmfeatures_p.h
@@ -77,6 +77,7 @@ class QQuickDwmFeatures : public QQuickItem
Q_PROPERTY(bool excludedFromPeek READ isExcludedFromPeek WRITE setExcludedFromPeek NOTIFY excludedFromPeekChanged)
Q_PROPERTY(bool peekDisallowed READ isPeekDisallowed WRITE setPeekDisallowed NOTIFY peekDisallowedChanged)
Q_PROPERTY(QQuickWin::WindowFlip3DPolicy flip3DPolicy READ flip3DPolicy WRITE setFlip3DPolicy NOTIFY flip3DPolicyChanged)
+ Q_PROPERTY(QQuickWin::WindowNonClientRenderingPolicy nonClientAreaRenderingPolicy READ nonClientAreaRenderingPolicy WRITE setNonClientAreaRenderingPolicy NOTIFY nonClientAreaRenderingPolicyChanged)
public:
explicit QQuickDwmFeatures(QQuickItem *parent = nullptr);
@@ -105,6 +106,8 @@ public:
void setPeekDisallowed(bool disallow);
QQuickWin::WindowFlip3DPolicy flip3DPolicy() const;
void setFlip3DPolicy(QQuickWin::WindowFlip3DPolicy policy);
+ QQuickWin::WindowNonClientRenderingPolicy nonClientAreaRenderingPolicy() const;
+ void setNonClientAreaRenderingPolicy(QQuickWin::WindowNonClientRenderingPolicy policy);
bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE;
@@ -123,6 +126,7 @@ Q_SIGNALS:
void excludedFromPeekChanged();
void peekDisallowedChanged();
void flip3DPolicyChanged();
+ void nonClientAreaRenderingPolicyChanged();
protected:
void itemChange(ItemChange, const ItemChangeData &) Q_DECL_OVERRIDE;
diff --git a/src/imports/winextras/qquickdwmfeatures_p_p.h b/src/imports/winextras/qquickdwmfeatures_p_p.h
index 4ec1244..acf9dd6 100644
--- a/src/imports/winextras/qquickdwmfeatures_p_p.h
+++ b/src/imports/winextras/qquickdwmfeatures_p_p.h
@@ -70,6 +70,7 @@ public:
bool peekDisallowed = false;
bool peekExcluded = false;
QQuickWin::WindowFlip3DPolicy flipPolicy = QQuickWin::FlipDefault;
+ QQuickWin::WindowNonClientRenderingPolicy nonClientRenderingPolicy = QQuickWin::NonClientRenderingUseWindowStyle;
QColor originalSurfaceColor;
void updateAll();
diff --git a/src/imports/winextras/qquickwin_p.h b/src/imports/winextras/qquickwin_p.h
index 0f4e510..4ed9015 100644
--- a/src/imports/winextras/qquickwin_p.h
+++ b/src/imports/winextras/qquickwin_p.h
@@ -77,6 +77,14 @@ public:
FlipExcludeAbove = QtWin::FlipExcludeAbove
};
Q_ENUM(WindowFlip3DPolicy)
+
+ enum WindowNonClientRenderingPolicy
+ {
+ NonClientRenderingUseWindowStyle = QtWin::NonClientRenderingUseWindowStyle,
+ NonClientRenderingDisabled = QtWin::NonClientRenderingDisabled,
+ NonClientRenderingEnabled = QtWin::NonClientRenderingEnabled
+ };
+ Q_ENUM(WindowNonClientRenderingPolicy)
};
QT_END_NAMESPACE
diff --git a/src/winextras/qwinfunctions.cpp b/src/winextras/qwinfunctions.cpp
index 4dcf8f0..68f2c99 100644
--- a/src/winextras/qwinfunctions.cpp
+++ b/src/winextras/qwinfunctions.cpp
@@ -1640,6 +1640,69 @@ QtWin::WindowFlip3DPolicy QtWin::windowFlip3DPolicy(QWindow *window)
return policy;
}
+/*!
+ \since 6.0
+
+ Sets the non-client area rendering policy \a policy for the specified \a window.
+
+ \note Disabling non-client area rendering will cause any previous calls to
+ QtWin::enableBlurBehindWindow() or to QtWin::extendFrameIntoClientArea() to be disabled.
+ */
+void QtWin::setWindowNonClientAreaRenderingPolicy(QWindow *window, QtWin::WindowNonClientRenderingPolicy policy)
+{
+ Q_ASSERT_X(window, Q_FUNC_INFO, "window is null");
+
+ HWND handle = reinterpret_cast<HWND>(window->winId());
+
+ DWORD value = DWMNCRP_USEWINDOWSTYLE;
+
+ switch (policy) {
+ default :
+ case NonClientRenderingUseWindowStyle :
+ break;
+ case NonClientRenderingDisabled :
+ value = DWMNCRP_DISABLED;
+ break;
+ case NonClientRenderingEnabled :
+ value = DWMNCRP_ENABLED;
+ break;
+ }
+
+ QtDwmApiDll::setWindowAttribute(handle, DWMWA_NCRENDERING_POLICY, value);
+}
+
+/*!
+ \fn QtWin::WindowNonClientRenderingPolicy QtWin::windowNonClientAreaRenderingPolicy(QWidget *window)
+ \since 6.0
+ \overload QtWin::windowNonClientAreaRenderingPolicy()
+ */
+
+/*!
+ \since 6.0
+
+ Returns the current non-client area rendering policy for the specified \a window.
+ */
+QtWin::WindowNonClientRenderingPolicy QtWin::windowNonClientAreaRenderingPolicy(QWindow *window)
+{
+ Q_ASSERT_X(window, Q_FUNC_INFO, "window is null");
+
+ const auto value =
+ QtDwmApiDll::windowAttribute<DWORD>(reinterpret_cast<HWND>(window->winId()),
+ DWMWA_NCRENDERING_POLICY, DWORD(DWMNCRP_USEWINDOWSTYLE));
+ WindowNonClientRenderingPolicy policy = NonClientRenderingUseWindowStyle;
+ switch (value) {
+ case DWMNCRP_DISABLED :
+ policy = NonClientRenderingDisabled;
+ break;
+ case DWMNCRP_ENABLED :
+ policy = NonClientRenderingEnabled;
+ break;
+ default :
+ break;
+ }
+ return policy;
+}
+
void qt_ExtendFrameIntoClientArea(QWindow *window, int left, int top, int right, int bottom)
{
QWinEventFilter::setup();
@@ -1659,7 +1722,9 @@ void qt_ExtendFrameIntoClientArea(QWindow *window, int left, int top, int right,
using the \a left, \a top, \a right, and \a bottom margin values.
Pass -1 as values for any of the four margins to fully extend the frame,
- creating a \e {sheet of glass} effect.
+ creating a \e {sheet of glass} effect. If it doesn't work, change
+ non-client area rendering policy to QtWin::NonClientRenderingEnabled and
+ try again.
If you want the extended frame to act like a standard window border, you
should handle that yourself.
@@ -1667,7 +1732,7 @@ void qt_ExtendFrameIntoClientArea(QWindow *window, int left, int top, int right,
\note Qt::WA_NoSystemBackground must not be set on widgets for
extendFrameIntoClientArea() to work.
- \sa resetExtendedFrame()
+ \sa resetExtendedFrame(), setWindowNonClientAreaRenderingPolicy()
*/
void QtWin::extendFrameIntoClientArea(QWindow *window, int left, int top, int right, int bottom)
{
@@ -2041,4 +2106,32 @@ void QtWin::taskbarDeleteTab(QWindow *window)
\sa setWindowFlip3DPolicy()
*/
+/*!
+ \enum QtWin::WindowNonClientRenderingPolicy
+
+ \since 6.0
+
+ This enum type specifies the non-client area rendering policy.
+
+ \value NonClientRenderingUseWindowStyle
+ The non-client rendering area is rendered based on the window
+ style.
+
+ \value NonClientRenderingDisabled
+ The non-client area rendering is disabled and the window style
+ is ignored.
+ Note that disabling non-client area rendering will cause any
+ previous calls to QtWin::enableBlurBehindWindow() or to
+ QtWin::extendFrameIntoClientArea() to be disabled.
+
+ \value NonClientRenderingEnabled
+ The non-client area rendering is enabled and the window style
+ is ignored.
+ If you want to bring frame shadow back to a frameless window,
+ enable this policy and call QtWin::extendFrameIntoClientArea()
+ with a negative height.
+
+ \sa setWindowNonClientAreaRenderingPolicy()
+ */
+
QT_END_NAMESPACE
diff --git a/src/winextras/qwinfunctions.h b/src/winextras/qwinfunctions.h
index ef2aece..8f27a6f 100644
--- a/src/winextras/qwinfunctions.h
+++ b/src/winextras/qwinfunctions.h
@@ -77,6 +77,13 @@ namespace QtWin
FlipExcludeAbove
};
+ enum WindowNonClientRenderingPolicy
+ {
+ NonClientRenderingUseWindowStyle,
+ NonClientRenderingDisabled,
+ NonClientRenderingEnabled
+ };
+
Q_WINEXTRAS_EXPORT HBITMAP createMask(const QBitmap &bitmap);
Q_WINEXTRAS_EXPORT HBITMAP toHBITMAP(const QPixmap &p, HBitmapFormat format = HBitmapNoAlpha);
Q_WINEXTRAS_EXPORT QPixmap fromHBITMAP(HBITMAP bitmap, HBitmapFormat format = HBitmapNoAlpha);
@@ -100,6 +107,8 @@ namespace QtWin
Q_WINEXTRAS_EXPORT bool isWindowPeekDisallowed(QWindow *window);
Q_WINEXTRAS_EXPORT void setWindowFlip3DPolicy(QWindow *window, WindowFlip3DPolicy policy);
Q_WINEXTRAS_EXPORT WindowFlip3DPolicy windowFlip3DPolicy(QWindow *);
+ Q_WINEXTRAS_EXPORT void setWindowNonClientAreaRenderingPolicy(QWindow *window, WindowNonClientRenderingPolicy policy);
+ Q_WINEXTRAS_EXPORT WindowNonClientRenderingPolicy windowNonClientAreaRenderingPolicy(QWindow *);
Q_WINEXTRAS_EXPORT void extendFrameIntoClientArea(QWindow *window, int left, int top, int right, int bottom);
Q_WINEXTRAS_EXPORT void extendFrameIntoClientArea(QWindow *window, const QMargins &margins);
@@ -155,10 +164,20 @@ namespace QtWin
inline WindowFlip3DPolicy windowFlip3DPolicy(QWidget *window)
{
- if (!window->windowHandle())
- return FlipDefault;
- else
- return windowFlip3DPolicy(window->windowHandle());
+ auto handle = window->windowHandle();
+ return handle ? windowFlip3DPolicy(handle) : FlipDefault;
+ }
+
+ inline void setWindowNonClientAreaRenderingPolicy(QWidget *window, WindowNonClientRenderingPolicy policy)
+ {
+ window->createWinId();
+ setWindowNonClientAreaRenderingPolicy(window->windowHandle(), policy);
+ }
+
+ inline WindowNonClientRenderingPolicy windowNonClientAreaRenderingPolicy(QWidget *window)
+ {
+ auto handle = window->windowHandle();
+ return handle ? windowNonClientAreaRenderingPolicy(handle) : NonClientRenderingUseWindowStyle;
}
inline void extendFrameIntoClientArea(QWidget *window, const QMargins &margins)
diff --git a/tests/manual/dwmfeatures/testwidget.cpp b/tests/manual/dwmfeatures/testwidget.cpp
index 09b25ac..e289946 100644
--- a/tests/manual/dwmfeatures/testwidget.cpp
+++ b/tests/manual/dwmfeatures/testwidget.cpp
@@ -40,11 +40,14 @@ TestWidget::TestWidget(QWidget *parent) :
{
ui->setupUi(this);
- connect(ui->btnPeekDisallow, &QAbstractButton::clicked, this, &TestWidget::onDisallowPeekClicked);
- connect(ui->btnPeekExclude, &QAbstractButton::clicked, this, &TestWidget::onExcludeFromPeekClicked);
- connect(ui->radioFlipDefault, &QAbstractButton::clicked, this, &TestWidget::onFlip3DPolicyChanged);
- connect(ui->radioFlipAbove, &QAbstractButton::clicked, this, &TestWidget::onFlip3DPolicyChanged);
- connect(ui->radioFlipBelow, &QAbstractButton::clicked, this, &TestWidget::onFlip3DPolicyChanged);
+ connect(ui->btnPeekDisallow, &QAbstractButton::clicked, this, &TestWidget::onDisallowPeekClicked);
+ connect(ui->btnPeekExclude, &QAbstractButton::clicked, this, &TestWidget::onExcludeFromPeekClicked);
+ connect(ui->radioFlipDefault, &QAbstractButton::clicked, this, &TestWidget::onFlip3DPolicyChanged);
+ connect(ui->radioFlipAbove, &QAbstractButton::clicked, this, &TestWidget::onFlip3DPolicyChanged);
+ connect(ui->radioFlipBelow, &QAbstractButton::clicked, this, &TestWidget::onFlip3DPolicyChanged);
+ connect(ui->radioNcrpUseWindowStyle, &QAbstractButton::clicked, this, &TestWidget::onNonClientAreaRenderingPolicyChanged);
+ connect(ui->radioNcrpDisable, &QAbstractButton::clicked, this, &TestWidget::onNonClientAreaRenderingPolicyChanged);
+ connect(ui->radioNcrpEnable, &QAbstractButton::clicked, this, &TestWidget::onNonClientAreaRenderingPolicyChanged);
connect(ui->btnFrameReset, &QAbstractButton::clicked, this, &TestWidget::onResetGlassFrameClicked);
connect(ui->frameTop, QOverload<int>::of(&QSpinBox::valueChanged),
this, &TestWidget::onGlassMarginsChanged);
@@ -106,6 +109,18 @@ void TestWidget::onFlip3DPolicyChanged()
QtWin::setWindowFlip3DPolicy(this, policy);
}
+void TestWidget::onNonClientAreaRenderingPolicyChanged()
+{
+ QtWin::WindowNonClientRenderingPolicy policy;
+ if (ui->radioNcrpDisable->isChecked())
+ policy = QtWin::NonClientRenderingDisabled;
+ else if (ui->radioNcrpEnable->isChecked())
+ policy = QtWin::NonClientRenderingEnabled;
+ else
+ policy = QtWin::NonClientRenderingUseWindowStyle;
+ QtWin::setWindowNonClientAreaRenderingPolicy(this, policy);
+}
+
void TestWidget::onGlassMarginsChanged()
{
if (!QtWin::isCompositionEnabled())
diff --git a/tests/manual/dwmfeatures/testwidget.h b/tests/manual/dwmfeatures/testwidget.h
index 137e8ce..70c39c6 100644
--- a/tests/manual/dwmfeatures/testwidget.h
+++ b/tests/manual/dwmfeatures/testwidget.h
@@ -60,6 +60,7 @@ private slots:
void onDisallowPeekClicked();
void onExcludeFromPeekClicked();
void onFlip3DPolicyChanged();
+ void onNonClientAreaRenderingPolicyChanged();
void onGlassMarginsChanged();
void onResetGlassFrameClicked();
};
diff --git a/tests/manual/dwmfeatures/testwidget.ui b/tests/manual/dwmfeatures/testwidget.ui
index 329ba61..2ef17d8 100644
--- a/tests/manual/dwmfeatures/testwidget.ui
+++ b/tests/manual/dwmfeatures/testwidget.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>569</width>
- <height>331</height>
+ <height>451</height>
</rect>
</property>
<property name="windowTitle">
@@ -31,7 +31,16 @@
<property name="spacing">
<number>3</number>
</property>
- <property name="margin">
+ <property name="leftMargin">
+ <number>4</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>4</number>
+ </property>
+ <property name="bottomMargin">
<number>4</number>
</property>
<item>
@@ -155,7 +164,16 @@
<property name="spacing">
<number>3</number>
</property>
- <property name="margin">
+ <property name="leftMargin">
+ <number>4</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>4</number>
+ </property>
+ <property name="bottomMargin">
<number>4</number>
</property>
<item>
@@ -186,6 +204,39 @@
</widget>
</item>
<item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Non-client area rendering</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QRadioButton" name="radioNcrpUseWindowStyle">
+ <property name="text">
+ <string>Use window style</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioNcrpDisable">
+ <property name="text">
+ <string>Disable</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioNcrpEnable">
+ <property name="text">
+ <string>Enable</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Glass frame</string>
@@ -197,7 +248,16 @@
<property name="verticalSpacing">
<number>3</number>
</property>
- <property name="margin">
+ <property name="leftMargin">
+ <number>4</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>4</number>
+ </property>
+ <property name="bottomMargin">
<number>4</number>
</property>
<item row="0" column="0">