1*4882a593SmuzhiyunFrom d4bd42f942efbc2c93ccc420969c88ff20bfdaab Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Thu, 7 May 2020 09:12:08 +0800
4*4882a593SmuzhiyunSubject: [PATCH 07/17] qwaylandwindow: Support setting window flags and attrs
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunSupport setting window flags and attrs through app_id, for example:
7*4882a593Smuzhiyunapp_id = "attrs=alpha:0.5;flags=stay-on-top|stay-on-bottom|no-focus"
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
10*4882a593Smuzhiyun---
11*4882a593Smuzhiyun src/client/qwaylandwindow.cpp | 60 +++++++++++++++++++++++++++++++++++
12*4882a593Smuzhiyun src/client/qwaylandwindow_p.h |  6 ++++
13*4882a593Smuzhiyun 2 files changed, 66 insertions(+)
14*4882a593Smuzhiyun
15*4882a593Smuzhiyundiff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
16*4882a593Smuzhiyunindex 6ec9e99..7c18a72 100644
17*4882a593Smuzhiyun--- a/src/client/qwaylandwindow.cpp
18*4882a593Smuzhiyun+++ b/src/client/qwaylandwindow.cpp
19*4882a593Smuzhiyun@@ -117,6 +117,35 @@ void QWaylandWindow::ensureSize()
20*4882a593Smuzhiyun         mBackingStore->ensureSize();
21*4882a593Smuzhiyun }
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun+/* HACK: Set window status through app id */
24*4882a593Smuzhiyun+void QWaylandWindow::applyWindowStatus()
25*4882a593Smuzhiyun+{
26*4882a593Smuzhiyun+    char s[256];
27*4882a593Smuzhiyun+
28*4882a593Smuzhiyun+    if (!mShellSurface)
29*4882a593Smuzhiyun+        return;
30*4882a593Smuzhiyun+
31*4882a593Smuzhiyun+    snprintf(s, sizeof(s), "attrs=alpha:%f|", mOpacity);
32*4882a593Smuzhiyun+
33*4882a593Smuzhiyun+    strcat(s, ";flags=");
34*4882a593Smuzhiyun+
35*4882a593Smuzhiyun+    if (mBlocked)
36*4882a593Smuzhiyun+        strcat(s, "blocked|");
37*4882a593Smuzhiyun+    else
38*4882a593Smuzhiyun+        strcat(s, "-blocked|");
39*4882a593Smuzhiyun+
40*4882a593Smuzhiyun+#define SET_FLAG(flag, str) \
41*4882a593Smuzhiyun+    if (mFlags & (flag)) strcat(s, str "|"); \
42*4882a593Smuzhiyun+    else strcat(s, "-" str "|");
43*4882a593Smuzhiyun+
44*4882a593Smuzhiyun+    SET_FLAG(Qt::WindowStaysOnTopHint, "stay-on-top");
45*4882a593Smuzhiyun+    SET_FLAG(Qt::WindowStaysOnBottomHint, "stay-on-bottom");
46*4882a593Smuzhiyun+    SET_FLAG(Qt::WindowDoesNotAcceptFocus, "no-focus");
47*4882a593Smuzhiyun+    SET_FLAG(Qt::WindowTransparentForInput, "trans-input");
48*4882a593Smuzhiyun+
49*4882a593Smuzhiyun+    mShellSurface->setAppId(QLatin1String(s));
50*4882a593Smuzhiyun+}
51*4882a593Smuzhiyun+
52*4882a593Smuzhiyun void QWaylandWindow::initWindow()
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun     if (window()->type() == Qt::Desktop)
55*4882a593Smuzhiyun@@ -464,6 +493,13 @@ void QWaylandWindow::lower()
56*4882a593Smuzhiyun         mShellSurface->lower();
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun+void QWaylandWindow::setOpacity(qreal level)
60*4882a593Smuzhiyun+{
61*4882a593Smuzhiyun+    mOpacity = level;
62*4882a593Smuzhiyun+
63*4882a593Smuzhiyun+    applyWindowStatus();
64*4882a593Smuzhiyun+}
65*4882a593Smuzhiyun+
66*4882a593Smuzhiyun void QWaylandWindow::setMask(const QRegion &mask)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun     QReadLocker locker(&mSurfaceLock);
69*4882a593Smuzhiyun@@ -492,6 +528,28 @@ void QWaylandWindow::setMask(const QRegion &mask)
70*4882a593Smuzhiyun     mSurface->commit();
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun+bool QWaylandWindow::windowEvent(QEvent *event)
74*4882a593Smuzhiyun+{
75*4882a593Smuzhiyun+    switch (event->type()) {
76*4882a593Smuzhiyun+    case QEvent::WindowBlocked:
77*4882a593Smuzhiyun+        {
78*4882a593Smuzhiyun+            mBlocked = true;
79*4882a593Smuzhiyun+            applyWindowStatus();
80*4882a593Smuzhiyun+        }
81*4882a593Smuzhiyun+        break;
82*4882a593Smuzhiyun+    case QEvent::WindowUnblocked:
83*4882a593Smuzhiyun+        {
84*4882a593Smuzhiyun+            mBlocked = false;
85*4882a593Smuzhiyun+            applyWindowStatus();
86*4882a593Smuzhiyun+        }
87*4882a593Smuzhiyun+        break;
88*4882a593Smuzhiyun+    default:
89*4882a593Smuzhiyun+        break;
90*4882a593Smuzhiyun+    }
91*4882a593Smuzhiyun+
92*4882a593Smuzhiyun+    return QPlatformWindow::windowEvent(event);
93*4882a593Smuzhiyun+}
94*4882a593Smuzhiyun+
95*4882a593Smuzhiyun void QWaylandWindow::applyConfigureWhenPossible()
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun     QMutexLocker resizeLocker(&mResizeLock);
98*4882a593Smuzhiyun@@ -810,6 +868,8 @@ void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags)
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun     mFlags = flags;
101*4882a593Smuzhiyun     createDecoration();
102*4882a593Smuzhiyun+
103*4882a593Smuzhiyun+    applyWindowStatus();
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun bool QWaylandWindow::createDecoration()
107*4882a593Smuzhiyundiff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
108*4882a593Smuzhiyunindex c0a7634..afd318c 100644
109*4882a593Smuzhiyun--- a/src/client/qwaylandwindow_p.h
110*4882a593Smuzhiyun+++ b/src/client/qwaylandwindow_p.h
111*4882a593Smuzhiyun@@ -153,8 +153,11 @@ public:
112*4882a593Smuzhiyun     void raise() override;
113*4882a593Smuzhiyun     void lower() override;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun+    void setOpacity(qreal level) override;
116*4882a593Smuzhiyun     void setMask(const QRegion &region) override;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun+    bool windowEvent(QEvent *event) override;
119*4882a593Smuzhiyun+
120*4882a593Smuzhiyun     int scale() const;
121*4882a593Smuzhiyun     qreal devicePixelRatio() const override;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun@@ -257,12 +260,14 @@ protected:
124*4882a593Smuzhiyun     QRegion mMask;
125*4882a593Smuzhiyun     QRegion mOpaqueArea;
126*4882a593Smuzhiyun     Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
127*4882a593Smuzhiyun+    qreal mOpacity = 1.0f;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun     QWaylandShmBackingStore *mBackingStore = nullptr;
130*4882a593Smuzhiyun     QWaylandBuffer *mQueuedBuffer = nullptr;
131*4882a593Smuzhiyun     QRegion mQueuedBufferDamage;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun private:
134*4882a593Smuzhiyun+    void applyWindowStatus();
135*4882a593Smuzhiyun     void setGeometry_helper(const QRect &rect);
136*4882a593Smuzhiyun     void initWindow();
137*4882a593Smuzhiyun     void initializeWlSurface();
138*4882a593Smuzhiyun@@ -279,6 +284,7 @@ private:
139*4882a593Smuzhiyun     void handleScreensChanged();
140*4882a593Smuzhiyun     void sendRecursiveExposeEvent();
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun+    bool mBlocked = false;
143*4882a593Smuzhiyun     bool mInResizeFromApplyConfigure = false;
144*4882a593Smuzhiyun     bool lastVisible = false;
145*4882a593Smuzhiyun     QRect mLastExposeGeometry;
146*4882a593Smuzhiyun--
147*4882a593Smuzhiyun2.20.1
148*4882a593Smuzhiyun
149