8#include <QtCore/QDateTime>
9#include <QtCore/QDebug>
10#include <QtGui/QPainter>
14#if defined(QX_WINDOW_ENABLE_SYSTEM_BORDERS)
38class WidgetBorderHandler :
public QObject,
public WindowNativeEventFilter,
public WindowSharedEventFilter
41 explicit WidgetBorderHandler(QWidget *widget, WindowContext *
ctx, QObject *parent =
nullptr)
46 widget->installEventFilter(
this);
50 static QVariant defaultMargins = QVariant::fromValue(QMargins(0, 1, 0, 0));
51 ctx->setWindowAttribute(QStringLiteral(
"extra-margins"), defaultMargins);
54 ctx->setWindowAttribute(QStringLiteral(
"dark-mode"),
true);
56 ctx->installNativeEventFilter(
this);
57 ctx->installSharedEventFilter(
this);
62 inline bool isNormalWindow()
const
64 return !(widget->windowState() & (Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen));
67 inline void updateGeometry()
69 if (isNormalWindow()) {
70 widget->setContentsMargins({0,
ctx->windowAttribute(QStringLiteral(
"border-thickness")).toInt(), 0, 0});
72 widget->setContentsMargins({});
76 inline void resumeWidgetEventAndDraw(QWidget *w, QEvent *event)
79 Private::ObjectHelper::sendEvent(w, event);
84 ctx->virtual_hook(WindowContext::DrawWindows10BorderHook2,
nullptr);
87 inline void resumeWindowEventAndDraw(QWindow *
window, QEvent *event)
90 Private::ObjectHelper::sendEvent(
window, event);
94 ctx->virtual_hook(WindowContext::DrawWindows10BorderHook2,
nullptr);
97 inline void updateExtraMargins(
bool windowActive)
101 static QVariant defaultMargins = QVariant::fromValue(QMargins(0, 1, 0, 0));
102 ctx->setWindowAttribute(QStringLiteral(
"extra-margins"), defaultMargins);
110 QRect frame =
ctx->windowAttribute(QStringLiteral(
"window-rect")).toRect();
111 QMargins margins{0, -frame.top(), 0, 0};
112 ctx->setWindowAttribute(QStringLiteral(
"extra-margins"), QVariant::fromValue(margins));
115 bool nativeEventFilter(
const QByteArray &eventType,
void *message, QT_NATIVE_EVENT_RESULT_TYPE *result)
override
120 const auto msg =
static_cast<const MSG *
>(message);
121 switch (msg->message) {
124 updateExtraMargins(widget->isActiveWindow());
129 updateExtraMargins(LOWORD(msg->wParam) != WA_INACTIVE);
139 bool sharedEventFilter(QObject *obj, QEvent *event)
override
143 auto window = widget->windowHandle();
152 if (event->type() == QEvent::Expose) {
153#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
156 auto ee =
static_cast<QExposeEvent *
>(event);
157 const bool hasRegion = !ee->region().isNull();
159 const bool hasRegion =
true;
161 if (
window->isExposed() && isNormalWindow() && hasRegion) {
162 resumeWindowEventAndDraw(
window, event);
170 bool eventFilter(QObject *obj, QEvent *event)
override
174 switch (event->type()) {
175 case QEvent::UpdateRequest: {
176 if (!isNormalWindow())
178 resumeWidgetEventAndDraw(widget, event);
182 case QEvent::WindowStateChange: {
187 case QEvent::WindowActivate:
188 case QEvent::WindowDeactivate: {
203void WindowAgentWidgetPrivate::setupWindows10BorderWorkaround()
206 auto ctx = m_context.get();
207 if (
ctx->windowAttribute(QStringLiteral(
"win10-border-needed")).toBool()) {
208 m_borderHandler = std::make_unique<WidgetBorderHandler>(m_hostWidget,
ctx);
#define QX_WINDOW_END_NAMESPACE
#define QX_WINDOW_BEGIN_NAMESPACE