on xenial help sign in
Re-introduce interactive drawer blur (#421)
441abf2Alfred E. Neumayer
qml/Launcher/BackgroundBlur.qmlnew file+81
@@ -0,0 +1,81 @@
1+/*
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import QtGraphicalEffects 1.0
20+
21+Item {
22+ id: root
23+
24+ property int blurAmount: 32
25+ property Item sourceItem
26+ property rect blurRect: Qt.rect(0,0,0,0)
27+ property alias cached: fastBlur.cached
28+
29+ Rectangle {
30+ id: blurMask
31+ color: "yellow"
32+ x: blurRect.x
33+ y: blurRect.y
34+ width: blurRect.width
35+ height: blurRect.height
36+ }
37+
38+ ShaderEffect {
39+ id: maskedBlurEffect
40+ x: blurRect.x
41+ y: blurRect.y
42+ width: blurRect.width
43+ height: blurRect.height
44+
45+ property variant source: ShaderEffectSource {
46+ id: shaderEffectSource
47+ sourceItem: root.sourceItem
48+ hideSource: false
49+ sourceRect: root.blurRect
50+ }
51+
52+ property var mask: ShaderEffectSource {
53+ sourceItem: blurMask
54+ hideSource: true
55+ }
56+
57+ fragmentShader: "
58+ varying highp vec2 qt_TexCoord0;
59+ uniform sampler2D source;
60+ uniform sampler2D mask;
61+ void main(void)
62+ {
63+ highp vec4 sourceColor = texture2D(source, qt_TexCoord0);
64+ highp vec4 maskColor = texture2D(mask, qt_TexCoord0);
65+
66+ sourceColor *= maskColor.a;
67+
68+ gl_FragColor = sourceColor;
69+ }"
70+ }
71+
72+ FastBlur {
73+ id: fastBlur
74+ x: blurRect.x
75+ y: blurRect.y
76+ width: blurRect.width
77+ height: blurRect.height
78+ source: maskedBlurEffect
79+ radius: Math.min(blurAmount, 128)
80+ }
81+ }
qml/Launcher/Drawer.qml+8−2
@@ -34,6 +34,7 @@ FocusScope {
34 readonly property real delegateWidth: units.gu(10)
34 readonly property real delegateWidth: units.gu(10)
35 property url background
35 property url background
36 property alias backgroundSourceSize: background.sourceSize
36 property alias backgroundSourceSize: background.sourceSize
37+ property bool staticBlurEnabled : true
37 visible: x > -width
38 visible: x > -width
38 property var fullyOpen: x === 0
39 property var fullyOpen: x === 0
39 property var fullyClosed: x === -width
40 property var fullyClosed: x === -width
@@ -155,18 +156,21 @@ FocusScope {
155
156
156 Rectangle {
157 Rectangle {
157 anchors.fill: parent
158 anchors.fill: parent
158− color: "#111111"
159+ color: "#BF000000"
159− opacity: 0.99
160
160
161 Wallpaper {
161 Wallpaper {
162 id: background
162 id: background
163 objectName: "drawerBackground"
163 objectName: "drawerBackground"
164+ visible: staticBlurEnabled
165+ enabled: staticBlurEnabled
164 anchors.fill: parent
166 anchors.fill: parent
165 source: root.background
167 source: root.background
166 }
168 }
167
169
168 FastBlur {
170 FastBlur {
169 anchors.fill: background
171 anchors.fill: background
172+ visible: staticBlurEnabled
173+ enabled: staticBlurEnabled
170 source: background
174 source: background
171 radius: 64
175 radius: 64
172 cached: true
176 cached: true
@@ -175,6 +179,8 @@ FocusScope {
175 // Images with fastblur can't use opacity, so we'll put this on top
179 // Images with fastblur can't use opacity, so we'll put this on top
176 Rectangle {
180 Rectangle {
177 anchors.fill: background
181 anchors.fill: background
182+ visible: staticBlurEnabled
183+ enabled: staticBlurEnabled
178 color: parent.color
184 color: parent.color
179 opacity: 0.67
185 opacity: 0.67
180 }
186 }
qml/Launcher/Launcher.qml+17
@@ -31,6 +31,8 @@ FocusScope {
31 property bool lockedVisible: false
31 property bool lockedVisible: false
32 property bool available: true // can be used to disable all interactions
32 property bool available: true // can be used to disable all interactions
33 property alias inverted: panel.inverted
33 property alias inverted: panel.inverted
34+ property Item blurSource: null
35+ property bool interactiveBlur: false
34 property int topPanelHeight: 0
36 property int topPanelHeight: 0
35 property bool drawerEnabled: true
37 property bool drawerEnabled: true
36 property alias privateMode: panel.privateMode
38 property alias privateMode: panel.privateMode
@@ -364,6 +366,20 @@ FocusScope {
364 }
366 }
365 }
367 }
366
368
369+ BackgroundBlur {
370+ id: backgroundBlur
371+ anchors.fill: parent
372+ anchors.topMargin: root.inverted ? 0 : -root.topPanelHeight
373+ visible: root.interactiveBlur && root.blurSource && drawer.x > -drawer.width
374+ blurAmount: units.gu(6)
375+ sourceItem: root.blurSource
376+ blurRect: Qt.rect(panel.width,
377+ root.topPanelHeight,
378+ drawer.width + drawer.x - panel.width,
379+ height - root.topPanelHeight)
380+ cached: drawer.moving
381+ }
382+
367 Drawer {
383 Drawer {
368 id: drawer
384 id: drawer
369 objectName: "drawer"
385 objectName: "drawer"
@@ -377,6 +393,7 @@ FocusScope {
377 width: Math.min(root.width, units.gu(81))
393 width: Math.min(root.width, units.gu(81))
378 panelWidth: panel.width
394 panelWidth: panel.width
379 allowSlidingAnimation: !dragArea.dragging && !launcherDragArea.drag.active && panel.animate
395 allowSlidingAnimation: !dragArea.dragging && !launcherDragArea.drag.active && panel.animate
396+ staticBlurEnabled: !root.interactiveBlur
380
397
381 onApplicationSelected: {
398 onApplicationSelected: {
382 root.launcherApplicationSelected(appId)
399 root.launcherApplicationSelected(appId)
qml/OrientedShell.qml+1
@@ -273,6 +273,7 @@ Item {
273 nativeWidth: root.width
273 nativeWidth: root.width
274 nativeHeight: root.height
274 nativeHeight: root.height
275 mode: applicationArguments.mode
275 mode: applicationArguments.mode
276+ interactiveBlur: applicationArguments.interactiveBlur
276 hasMouse: pointerInputDevices > 0
277 hasMouse: pointerInputDevices > 0
277 hasKeyboard: keyboardsModel.count > 0
278 hasKeyboard: keyboardsModel.count > 0
278 hasTouchscreen: touchScreensModel.count > 0
279 hasTouchscreen: touchScreensModel.count > 0
qml/Shell.qml+3
@@ -59,6 +59,7 @@ StyledItem {
59 property alias panelAreaShowProgress: panel.panelAreaShowProgress
59 property alias panelAreaShowProgress: panel.panelAreaShowProgress
60 property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop"
60 property string usageScenario: "phone" // supported values: "phone", "tablet" or "desktop"
61 property string mode: "full-greeter"
61 property string mode: "full-greeter"
62+ property bool interactiveBlur: false
62 property alias oskEnabled: inputMethod.enabled
63 property alias oskEnabled: inputMethod.enabled
63 function updateFocusedAppOrientation() {
64 function updateFocusedAppOrientation() {
64 stage.updateFocusedAppOrientation();
65 stage.updateFocusedAppOrientation();
@@ -604,6 +605,8 @@ StyledItem {
604 superTabPressed: physicalKeysMapper.superTabPressed
605 superTabPressed: physicalKeysMapper.superTabPressed
605 panelWidth: units.gu(settings.launcherWidth)
606 panelWidth: units.gu(settings.launcherWidth)
606 lockedVisible: (lockedByUser || shell.atDesktop) && lockAllowed
607 lockedVisible: (lockedByUser || shell.atDesktop) && lockAllowed
608+ blurSource: greeter.shown ? greeter : stages
609+ interactiveBlur: shell.interactiveBlur
607 topPanelHeight: panel.panelHeight
610 topPanelHeight: panel.panelHeight
608 drawerEnabled: !greeter.active && tutorial.launcherLongSwipeEnabled
611 drawerEnabled: !greeter.active && tutorial.launcherLongSwipeEnabled
609 privateMode: greeter.active
612 privateMode: greeter.active
src/ApplicationArguments.h+5
@@ -28,6 +28,7 @@ class ApplicationArguments : public QObject
28 Q_OBJECT
28 Q_OBJECT
29 Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged)
29 Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged)
30 Q_PROPERTY(QString mode READ mode CONSTANT)
30 Q_PROPERTY(QString mode READ mode CONSTANT)
31+ Q_PROPERTY(bool interactiveBlur READ interactiveBlur CONSTANT)
31public:
32public:
32 ApplicationArguments(QObject *parent = nullptr);
33 ApplicationArguments(QObject *parent = nullptr);
33
34
@@ -42,12 +43,16 @@ public:
42 void setMode(const QString &mode) { m_mode = mode; }
43 void setMode(const QString &mode) { m_mode = mode; }
43 QString mode() const { return m_mode; }
44 QString mode() const { return m_mode; }
44
45
46+ void setInteractiveBlur(const bool &value) { m_interactiveBlur = value; }
47+ bool interactiveBlur() { return m_interactiveBlur; }
48+
45Q_SIGNALS:
49Q_SIGNALS:
46 void deviceNameChanged(const QString&);
50 void deviceNameChanged(const QString&);
47
51
48private:
52private:
49 QString m_deviceName;
53 QString m_deviceName;
50 QString m_mode;
54 QString m_mode;
55+ bool m_interactiveBlur;
51};
56};
52
57
53#endif // APPLICATION_ARGUMENTS_H
58#endif // APPLICATION_ARGUMENTS_H
src/ShellApplication.cpp+6
@@ -58,6 +58,12 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
58
58
59 m_qmlArgs.setMode(parser.mode());
59 m_qmlArgs.setMode(parser.mode());
60
60
61+ {
62+ char buffer[200];
63+ property_get("ubuntu.unity8.interactive_blur", buffer, "false");
64+ m_qmlArgs.setInteractiveBlur(QString(buffer) == QStringLiteral("true"));
65+ }
66+
61 // The testability driver is only loaded by QApplication but not by QGuiApplication.
67 // The testability driver is only loaded by QApplication but not by QGuiApplication.
62 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
68 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
63 if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
69 if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {