OpenCoverage

qdbustrayicon.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/platformsupport/dbustray/qdbustrayicon.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5-
6-
7-
8const QLoggingCategory &qLcTray() { static const QLoggingCategory category("qt.qpa.tray"); return
executed 1 time by 1 test: return category;
Executed by:
  • tst_QSystemTrayIcon
category;
executed 1 time by 1 test: return category;
Executed by:
  • tst_QSystemTrayIcon
}
1
9-
10static const QString KDEItemFormat = ([]() -> QString { enum { Size = sizeof(u"" "org.kde.StatusNotifierItem-%1-%2")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "org.kde.StatusNotifierItem-%1-%2" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());-
11static const QString KDEWatcherService = ([]() -> QString { enum { Size = sizeof(u"" "org.kde.StatusNotifierWatcher")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "org.kde.StatusNotifierWatcher" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());-
12static const QString TempFileTemplate = QDir::tempPath() + QLatin1String("/qt-trayicon-XXXXXX.png");-
13static const QString XdgNotificationService = ([]() -> QString { enum { Size = sizeof(u"" "org.freedesktop.Notifications")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "org.freedesktop.Notifications" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());-
14static const QString XdgNotificationPath = ([]() -> QString { enum { Size = sizeof(u"" "/org/freedesktop/Notifications")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "/org/freedesktop/Notifications" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());-
15static const QString DefaultAction = ([]() -> QString { enum { Size = sizeof(u"" "default")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "default" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }());-
16static int instanceCount = 0;-
17-
18-
19-
20-
21-
22-
23QDBusTrayIcon::QDBusTrayIcon()-
24 : m_dbusConnection(nullptr)-
25 , m_adaptor(new QStatusNotifierItemAdaptor(this))-
26 , m_menuAdaptor(nullptr)-
27 , m_menu(nullptr)-
28 , m_notifier(nullptr)-
29 , m_instanceId(KDEItemFormat.arg(QCoreApplication::applicationPid()).arg(++instanceCount))-
30 , m_category(([]() -> QString { enum { Size = sizeof(u"" "ApplicationStatus")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "ApplicationStatus" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()))-
31 , m_defaultStatus(([]() -> QString { enum { Size = sizeof(u"" "Active")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "Active" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()))-
32 , m_status(m_defaultStatus)-
33 , m_tempIcon(nullptr)-
34 , m_tempAttentionIcon(nullptr)-
35 , m_registered(false)-
36{-
37 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 94, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug();
never executed: QMessageLogger(__FILE__, 94, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug();
0
38 if (instanceCount == 1
instanceCount == 1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
39 QDBusMenuItem::registerDBusTypes();-
40 qDBusRegisterMetaType<QXdgDBusImageStruct>();-
41 qDBusRegisterMetaType<QXdgDBusImageVector>();-
42 qDBusRegisterMetaType<QXdgDBusToolTipStruct>();-
43 }
never executed: end of block
0
44 connect(this, qFlagLocation("2""statusChanged(QString)" "\0" __FILE__ ":" "101"), m_adaptor, qFlagLocation("2""NewStatus(QString)" "\0" __FILE__ ":" "101"));-
45 connect(this, qFlagLocation("2""tooltipChanged()" "\0" __FILE__ ":" "102"), m_adaptor, qFlagLocation("2""NewToolTip()" "\0" __FILE__ ":" "102"));-
46 connect(this, qFlagLocation("2""iconChanged()" "\0" __FILE__ ":" "103"), m_adaptor, qFlagLocation("2""NewIcon()" "\0" __FILE__ ":" "103"));-
47 connect(this, qFlagLocation("2""attention()" "\0" __FILE__ ":" "104"), m_adaptor, qFlagLocation("2""NewAttentionIcon()" "\0" __FILE__ ":" "104"));-
48 connect(this, qFlagLocation("2""attention()" "\0" __FILE__ ":" "105"), m_adaptor, qFlagLocation("2""NewTitle()" "\0" __FILE__ ":" "105"));-
49 connect(&m_attentionTimer, qFlagLocation("2""timeout()" "\0" __FILE__ ":" "106"), this, qFlagLocation("1""attentionTimerExpired()" "\0" __FILE__ ":" "106"));-
50 m_attentionTimer.setSingleShot(true);-
51}
never executed: end of block
0
52-
53QDBusTrayIcon::~QDBusTrayIcon()-
54{-
55}-
56-
57void QDBusTrayIcon::init()-
58{-
59 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 116, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << "registering" << m_instanceId;
never executed: QMessageLogger(__FILE__, 116, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << "registering" << m_instanceId;
0
60 m_registered = dBusConnection()->registerTrayIcon(this);-
61}
never executed: end of block
0
62-
63void QDBusTrayIcon::cleanup()-
64{-
65 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 122, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << "unregistering" << m_instanceId;
never executed: QMessageLogger(__FILE__, 122, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << "unregistering" << m_instanceId;
0
66 if (m_registered
m_registeredDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
67 dBusConnection()->unregisterTrayIcon(this);
never executed: dBusConnection()->unregisterTrayIcon(this);
0
68 delete m_dbusConnection;-
69 m_dbusConnection = nullptr;-
70 delete m_notifier;-
71 m_notifier = nullptr;-
72 m_registered = false;-
73}
never executed: end of block
0
74-
75void QDBusTrayIcon::attentionTimerExpired()-
76{-
77 m_messageTitle = QString();-
78 m_message = QString();-
79 m_attentionIcon = QIcon();-
80 attention();-
81 tooltipChanged();-
82 setStatus(m_defaultStatus);-
83}
never executed: end of block
0
84-
85void QDBusTrayIcon::setStatus(const QString &status)-
86{-
87 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 144, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << status;
never executed: QMessageLogger(__FILE__, 144, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << status;
0
88 if (m_status == status
m_status == statusDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
89 return;
never executed: return;
0
90 m_status = status;-
91 statusChanged(m_status);-
92}
never executed: end of block
0
93-
94QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon)-
95{-
96-
97-
98 static bool necessity_checked = false;-
99 static bool necessary = false;-
100 if (!necessity_checked
!necessity_checkedDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
101 QDBusConnection session = QDBusConnection::sessionBus();-
102 uint pid = session.interface()->servicePid(KDEWatcherService).value();-
103 QString processName = QLockFilePrivate::processNameByPid(pid);-
104 necessary = processName.endsWith(QLatin1String("indicator-application-service"));-
105 necessity_checked = true;-
106 }
never executed: end of block
0
107 if (!necessary
!necessaryDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
108 return
never executed: return nullptr;
nullptr;
never executed: return nullptr;
0
109 qreal dpr = (static_cast<QGuiApplication *>(QCoreApplication::instance()))->devicePixelRatio();-
110 QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this);-
111 ret->open();-
112 icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret);-
113 ret->close();-
114 return
never executed: return ret;
ret;
never executed: return ret;
0
115}-
116-
117QDBusMenuConnection * QDBusTrayIcon::dBusConnection()-
118{-
119 if (!m_dbusConnection
!m_dbusConnectionDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
120 m_dbusConnection = new QDBusMenuConnection(this, m_instanceId);-
121 m_notifier = new QXdgNotificationInterface(XdgNotificationService,-
122 XdgNotificationPath, m_dbusConnection->connection(), this);-
123 connect(m_notifier, qFlagLocation("2""NotificationClosed(uint,uint)" "\0" __FILE__ ":" "180"), this, qFlagLocation("1""notificationClosed(uint,uint)" "\0" __FILE__ ":" "180"));-
124 connect(m_notifier, qFlagLocation("2""ActionInvoked(uint,QString)" "\0" __FILE__ ":" "181"), this, qFlagLocation("1""actionInvoked(uint,QString)" "\0" __FILE__ ":" "181"));-
125 }
never executed: end of block
0
126 return
never executed: return m_dbusConnection;
m_dbusConnection;
never executed: return m_dbusConnection;
0
127}-
128-
129void QDBusTrayIcon::updateIcon(const QIcon &icon)-
130{-
131 m_iconName = icon.name();-
132 m_icon = icon;-
133 if (m_iconName.isEmpty()
m_iconName.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
134 if (m_tempIcon
m_tempIconDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
135 delete m_tempIcon;
never executed: delete m_tempIcon;
0
136 m_tempIcon = tempIcon(icon);-
137 if (m_tempIcon
m_tempIconDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
138 m_iconName = m_tempIcon->fileName();
never executed: m_iconName = m_tempIcon->fileName();
0
139 }
never executed: end of block
0
140 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 197, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << m_iconName << icon.availableSizes();
never executed: QMessageLogger(__FILE__, 197, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << m_iconName << icon.availableSizes();
0
141 iconChanged();-
142}
never executed: end of block
0
143-
144void QDBusTrayIcon::updateToolTip(const QString &tooltip)-
145{-
146 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 203, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << tooltip;
never executed: QMessageLogger(__FILE__, 203, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << tooltip;
0
147 m_tooltip = tooltip;-
148 tooltipChanged();-
149}
never executed: end of block
0
150-
151QPlatformMenu *QDBusTrayIcon::createMenu() const-
152{-
153 return
never executed: return new QDBusPlatformMenu();
new QDBusPlatformMenu();
never executed: return new QDBusPlatformMenu();
0
154}-
155-
156void QDBusTrayIcon::updateMenu(QPlatformMenu * menu)-
157{-
158 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 215, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << menu;
never executed: QMessageLogger(__FILE__, 215, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << menu;
0
159 QDBusPlatformMenu *newMenu = qobject_cast<QDBusPlatformMenu *>(menu);-
160 if (m_menu != newMenu
m_menu != newMenuDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
161 if (m_menu
m_menuDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
162 dBusConnection()->unregisterTrayIconMenu(this);-
163 delete m_menuAdaptor;-
164 }
never executed: end of block
0
165 m_menu = newMenu;-
166 m_menuAdaptor = new QDBusMenuAdaptor(m_menu);-
167-
168 connect(m_menu, qFlagLocation("2""propertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)" "\0" __FILE__ ":" "225"),-
169 m_menuAdaptor, qFlagLocation("2""ItemsPropertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)" "\0" __FILE__ ":" "226"));-
170 connect(m_menu, qFlagLocation("2""updated(uint,int)" "\0" __FILE__ ":" "227"),-
171 m_menuAdaptor, qFlagLocation("2""LayoutUpdated(uint,int)" "\0" __FILE__ ":" "228"));-
172 dBusConnection()->registerTrayIconMenu(this);-
173 }
never executed: end of block
0
174}
never executed: end of block
0
175-
176void QDBusTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon,-
177 QPlatformSystemTrayIcon::MessageIcon iconType, int msecs)-
178{-
179 m_messageTitle = title;-
180 m_message = msg;-
181 m_attentionIcon = icon;-
182 QStringList notificationActions;-
183 switch (iconType) {-
184 case
never executed: case Information:
Information:
never executed: case Information:
0
185 m_attentionIconName = ([]() -> QString { enum { Size = sizeof(u"" "dialog-information")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "dialog-information" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return
never executed: return qstring_literal_temp;
qstring_literal_temp;
never executed: return qstring_literal_temp;
}());
0
186 break;
never executed: break;
0
187 case
never executed: case Warning:
Warning:
never executed: case Warning:
0
188 m_attentionIconName = ([]() -> QString { enum { Size = sizeof(u"" "dialog-warning")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "dialog-warning" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return
never executed: return qstring_literal_temp;
qstring_literal_temp;
never executed: return qstring_literal_temp;
}());
0
189 break;
never executed: break;
0
190 case
never executed: case Critical:
Critical:
never executed: case Critical:
0
191 m_attentionIconName = ([]() -> QString { enum { Size = sizeof(u"" "dialog-error")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "dialog-error" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return
never executed: return qstring_literal_temp;
qstring_literal_temp;
never executed: return qstring_literal_temp;
}());
0
192-
193-
194-
195 notificationActions << DefaultAction << tr("OK");-
196 break;
never executed: break;
0
197 default
never executed: default:
:
never executed: default:
0
198 m_attentionIconName.clear();-
199 break;
never executed: break;
0
200 }-
201 if (m_attentionIconName.isEmpty()
m_attentionIconName.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
202 if (m_tempAttentionIcon
m_tempAttentionIconDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
203 delete m_tempAttentionIcon;
never executed: delete m_tempAttentionIcon;
0
204 m_tempAttentionIcon = tempIcon(icon);-
205 if (m_tempAttentionIcon
m_tempAttentionIconDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
206 m_attentionIconName = m_tempAttentionIcon->fileName();
never executed: m_attentionIconName = m_tempAttentionIcon->fileName();
0
207 }
never executed: end of block
0
208 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg <<
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
209 QPlatformSystemTrayIcon::metaObject()->enumerator(
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
210 QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType)
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
211 << m_attentionIconName << msecs;
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
212 setStatus(([]() -> QString { enum { Size = sizeof(u"" "NeedsAttention")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "NeedsAttention" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return
never executed: return qstring_literal_temp;
qstring_literal_temp;
never executed: return qstring_literal_temp;
}()));
0
213 m_attentionTimer.start(msecs);-
214 tooltipChanged();-
215 attention();-
216-
217-
218 QVariantMap hints;-
219-
220-
221 int urgency = static_cast<int>(iconType) - 1;-
222 if (urgency < 0
urgency < 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
223 urgency = 0;
never executed: urgency = 0;
0
224 hints.insert(QLatin1String("urgency"), QVariant(urgency));-
225 m_notifier->notify(QCoreApplication::applicationName(), 0,-
226 m_attentionIconName, title, msg, notificationActions, hints, msecs);-
227}
never executed: end of block
0
228-
229void QDBusTrayIcon::actionInvoked(uint id, const QString &action)-
230{-
231 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 288, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << id << action;
never executed: QMessageLogger(__FILE__, 288, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << id << action;
0
232 messageClicked();-
233}
never executed: end of block
0
234-
235void QDBusTrayIcon::notificationClosed(uint id, uint reason)-
236{-
237 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 294, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << id << reason;
never executed: QMessageLogger(__FILE__, 294, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << id << reason;
0
238}
never executed: end of block
0
239-
240bool QDBusTrayIcon::isSystemTrayAvailable() const-
241{-
242 QDBusMenuConnection * conn = const_cast<QDBusTrayIcon *>(this)->dBusConnection();-
243 for (bool qt_category_enabled = qLcTray().isDebugEnabled(); qt_category_enabled
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
; qt_category_enabled = false) QMessageLogger(__FILE__, 300, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << conn->isStatusNotifierHostRegistered();
never executed: QMessageLogger(__FILE__, 300, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << conn->isStatusNotifierHostRegistered();
0
244 return
never executed: return conn->isStatusNotifierHostRegistered();
conn->isStatusNotifierHostRegistered();
never executed: return conn->isStatusNotifierHostRegistered();
0
245}-
246-
247-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9