From 6ee8c98d0c28146c2f857d0d56cf05b8d77c73fc Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Thu, 7 May 2020 09:12:08 +0800 Subject: [PATCH 07/15] qwaylandwindow: Support setting window flags and attrs Support setting window flags and attrs through app_id, for example: app_id = "attrs=alpha:0.5;flags=stay-on-top|stay-on-bottom|no-focus" Signed-off-by: Jeffy Chen --- src/client/qwaylandwindow.cpp | 60 +++++++++++++++++++++++++++++++++++ src/client/qwaylandwindow_p.h | 6 ++++ 2 files changed, 66 insertions(+) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index d4a1b7e..b83be29 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -121,6 +121,35 @@ void QWaylandWindow::ensureSize() mBackingStore->ensureSize(); } +/* HACK: Set window status through app id */ +void QWaylandWindow::applyWindowStatus() +{ + char s[256]; + + if (!mShellSurface) + return; + + snprintf(s, sizeof(s), "attrs=alpha:%f|", mOpacity); + + strcat(s, ";flags="); + + if (mBlocked) + strcat(s, "blocked|"); + else + strcat(s, "-blocked|"); + +#define SET_FLAG(flag, str) \ + if (mFlags & (flag)) strcat(s, str "|"); \ + else strcat(s, "-" str "|"); + + SET_FLAG(Qt::WindowStaysOnTopHint, "stay-on-top"); + SET_FLAG(Qt::WindowStaysOnBottomHint, "stay-on-bottom"); + SET_FLAG(Qt::WindowDoesNotAcceptFocus, "no-focus"); + SET_FLAG(Qt::WindowTransparentForInput, "trans-input"); + + mShellSurface->setAppId(QLatin1String(s)); +} + void QWaylandWindow::initWindow() { if (window()->type() == Qt::Desktop) @@ -459,6 +488,13 @@ void QWaylandWindow::lower() mShellSurface->lower(); } +void QWaylandWindow::setOpacity(qreal level) +{ + mOpacity = level; + + applyWindowStatus(); +} + void QWaylandWindow::setMask(const QRegion &mask) { if (mMask == mask) @@ -487,6 +523,28 @@ void QWaylandWindow::setMask(const QRegion &mask) mSurface->commit(); } +bool QWaylandWindow::windowEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::WindowBlocked: + { + mBlocked = true; + applyWindowStatus(); + } + break; + case QEvent::WindowUnblocked: + { + mBlocked = false; + applyWindowStatus(); + } + break; + default: + break; + } + + return QPlatformWindow::windowEvent(event); +} + void QWaylandWindow::applyConfigureWhenPossible() { QMutexLocker resizeLocker(&mResizeLock); @@ -792,6 +850,8 @@ void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) mFlags = flags; createDecoration(); + + applyWindowStatus(); } bool QWaylandWindow::createDecoration() diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 01337cf..f1a461b 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -152,8 +152,11 @@ public: void raise() override; void lower() override; + void setOpacity(qreal level) override; void setMask(const QRegion ®ion) override; + bool windowEvent(QEvent *event) override; + int scale() const; qreal devicePixelRatio() const override; @@ -256,12 +259,14 @@ protected: QRegion mMask; QRegion mOpaqueArea; Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState; + qreal mOpacity = 1.0f; QWaylandShmBackingStore *mBackingStore = nullptr; QWaylandBuffer *mQueuedBuffer = nullptr; QRegion mQueuedBufferDamage; private: + void applyWindowStatus(); void setGeometry_helper(const QRect &rect); void initWindow(); void initializeWlSurface(); @@ -278,6 +283,7 @@ private: void handleScreensChanged(); void sendRecursiveExposeEvent(); + bool mBlocked = false; bool mInResizeFromApplyConfigure = false; bool lastVisible = false; QRect mLastExposeGeometry; -- 2.20.1