on xenial help sign in
Laggy backends
4c49adaNick Dedekind
CMakeLists.txt+2
@@ -105,6 +105,8 @@ declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
105set(SHELL_APP unity8)
105set(SHELL_APP unity8)
106set(DASH_APP unity8-dash)
106set(DASH_APP unity8-dash)
107set(SCOPE_TOOL unity-scope-tool)
107set(SCOPE_TOOL unity-scope-tool)
108+set(INDICATORS_CLIENT_APP indicators-client)
109+set(INDICATOR_TEST_SERVICE_APP unity-indicator-test-service)
108
110
109include_directories(
111include_directories(
110 ${CMAKE_SOURCE_DIR}/include
112 ${CMAKE_SOURCE_DIR}/include
data/CMakeLists.txt+10
@@ -1,13 +1,23 @@
1# generate desktop files
1# generate desktop files
2configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
2configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
3configure_file(${DASH_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop @ONLY)
3configure_file(${DASH_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop @ONLY)
4+configure_file(${INDICATORS_CLIENT_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop @ONLY)
4
5
5# install desktop files
6# install desktop files
6install(FILES
7install(FILES
7 ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
8 ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
8 ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop
9 ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop
10+ ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop
9 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
11 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
10 )
12 )
11
13
14+# install upstart config files
15+install(FILES
16+ ${SHELL_APP}.conf
17+ ${DASH_APP}.conf
18+ ${INDICATOR_TEST_SERVICE_APP}.conf
19+ DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/sessions
20+ )
21+
12install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
22install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
13install(FILES unity8-dash.url-dispatcher DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
23install(FILES unity8-dash.url-dispatcher DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
data/indicators-client.desktop.innew file+9
@@ -0,0 +1,9 @@
1+[Desktop Entry]
2+Type=Application
3+Name=Indicators Client
4+Comment=An interface for using the Scopes system
5+Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/indicators-client
6+Terminal=false
7+Icon=
8+NoDisplay=false
9+X-Ubuntu-Touch=true
data/unity-indicator-test-service.confnew file+7
@@ -0,0 +1,7 @@
1+description "Unity Shell v8 Test Indicator"
2+author "Nick Dedekind <nick.dedekind@canonical.com>"
3+
4+respawn
5+respawn limit 2 10
6+
7+exec ${BINARY:-unity-indicator-test-service} $ARGS
debian/indicators-client.install+2
@@ -1 +1,3 @@
1+data/indicators-client.conf usr/share/upstart/sessions/
2+usr/share/applications/indicators-client.desktop
1/usr/bin/indicators-client
3/usr/bin/indicators-client
debian/unity8-autopilot.install+3−1
@@ -1,2 +1,4 @@
1+data/unity-indicator-test-service.conf usr/share/upstart/sessions/
2+usr/bin/unity-indicator-test-service
1usr/lib/python*/*/unity*
3usr/lib/python*/*/unity*
2−usr/share/unity8/unlock-device
4+usr/share/unity8/unlock-device
include/paths.h.in+1−6
@@ -92,12 +92,7 @@ inline QString mockPluginsDir() {
92
92
93inline QStringList shellDataDirs() {
93inline QStringList shellDataDirs() {
94 QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
94 QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
95− if (!isRunningInstalled()) {
95+ if (isRunningInstalled()) {
96− if (getenv("UNITY_TEST_ENV")==nullptr) {
97− dirs.prepend("@CMAKE_BINARY_DIR@/share");
98− }
99− }
100− else {
101 // append so by default we use xdg files.
96 // append so by default we use xdg files.
102 dirs.append(qmlDirectory());
97 dirs.append(qmlDirectory());
103 }
98 }
plugins/Utils/CMakeLists.txt+1
@@ -8,6 +8,7 @@ include_directories(
8)
8)
9
9
10set(QMLPLUGIN_SRC
10set(QMLPLUGIN_SRC
11+ constants.cpp
11 qlimitproxymodelqml.cpp
12 qlimitproxymodelqml.cpp
12 unitysortfilterproxymodelqml.cpp
13 unitysortfilterproxymodelqml.cpp
13 relativetimeformatter.cpp
14 relativetimeformatter.cpp
plugins/Utils/constants.cppnew file+27
@@ -0,0 +1,27 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+*/
16+
17+#include "constants.h"
18+
19+Constants::Constants(QObject *parent)
20+ : QObject(parent)
21+{
22+ if (qgetenv("QT_LOAD_TESTABILITY").isEmpty()) {
23+ m_indicatorValueTimeout = 30000;
24+ } else {
25+ m_indicatorValueTimeout = 5000;
26+ }
27+}
plugins/Utils/constants.hnew file+43
@@ -0,0 +1,43 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU Lesser General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+*/
16+
17+#ifndef CONSTANTS_H
18+#define CONSTANTS_H
19+
20+#include <QObject>
21+
22+/**
23+ * @brief The Constants class
24+ *
25+ * This singleton class exposes contants to Qml
26+ *
27+ */
28+
29+class Constants: public QObject
30+{
31+ Q_OBJECT
32+ Q_PROPERTY(int indicatorValueTimeout READ indicatorValueTimeout CONSTANT)
33+
34+public:
35+ Constants(QObject *parent = 0);
36+
37+ int indicatorValueTimeout() const { return m_indicatorValueTimeout; }
38+
39+private:
40+ int m_indicatorValueTimeout;
41+};
42+
43+#endif
plugins/Utils/plugin.cpp+11
@@ -34,6 +34,7 @@
34#include "windowkeysfilter.h"
34#include "windowkeysfilter.h"
35#include "easingcurve.h"
35#include "easingcurve.h"
36#include "windowstatestorage.h"
36#include "windowstatestorage.h"
37+#include "constants.h"
37
38
38static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
39static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
39{
40{
@@ -42,6 +43,14 @@ static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEn
42 return new WindowStateStorage();
43 return new WindowStateStorage();
43}
44}
44
45
46+static QObject *createConstants(QQmlEngine *engine, QJSEngine *scriptEngine)
47+{
48+ Q_UNUSED(engine)
49+ Q_UNUSED(scriptEngine)
50+ return new Constants();
51+}
52+
53+
45void UtilsPlugin::registerTypes(const char *uri)
54void UtilsPlugin::registerTypes(const char *uri)
46{
55{
47 Q_ASSERT(uri == QLatin1String("Utils"));
56 Q_ASSERT(uri == QLatin1String("Utils"));
@@ -55,6 +64,8 @@ void UtilsPlugin::registerTypes(const char *uri)
55 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
64 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
56 qmlRegisterType<RelativeTimeFormatter>(uri, 0, 1, "RelativeTimeFormatter");
65 qmlRegisterType<RelativeTimeFormatter>(uri, 0, 1, "RelativeTimeFormatter");
57 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
66 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
67+
68+ qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "Constants", createConstants);
58}
69}
59
70
60void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
71void UtilsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
qml/Panel/Indicators/MenuItemFactory.qml+71−48
@@ -19,6 +19,7 @@
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21import Ubuntu.Settings.Menus 0.1 as Menus
21import Ubuntu.Settings.Menus 0.1 as Menus
22+import Ubuntu.Settings.Components 0.1
22import QMenuModel 0.1
23import QMenuModel 0.1
23import Utils 0.1 as Utils
24import Utils 0.1 as Utils
24import Ubuntu.Components.ListItems 0.1 as ListItems
25import Ubuntu.Components.ListItems 0.1 as ListItems
@@ -84,6 +85,7 @@ Item {
84 id: sliderMenu;
85 id: sliderMenu;
85
86
86 Menus.SliderMenu {
87 Menus.SliderMenu {
88+ id: sliderItem
87 objectName: "sliderMenu"
89 objectName: "sliderMenu"
88 property QtObject menuData: null
90 property QtObject menuData: null
89 property var menuModel: menuFactory.menuModel
91 property var menuModel: menuFactory.menuModel
@@ -113,14 +115,8 @@ Item {
113 onMenuIndexChanged: {
115 onMenuIndexChanged: {
114 loadAttributes();
116 loadAttributes();
115 }
117 }
116− onServerValueChanged: {
117− // value can be changed by slider, so a binding won't work.
118− if (serverValue !== undefined) {
119− value = serverValue;
120− }
121− }
122 onUpdated: {
118 onUpdated: {
123− menuModel.changeState(menuIndex, value);
119+ sliderMenuSync.activate()
124 }
120 }
125
121
126 function loadAttributes() {
122 function loadAttributes() {
@@ -130,6 +126,23 @@ Item {
130 'min-icon': 'icon',
126 'min-icon': 'icon',
131 'max-icon': 'icon'});
127 'max-icon': 'icon'});
132 }
128 }
129+
130+ ServerActivationSync {
131+ id: sliderMenuSync
132+
133+ syncTimeout: Utils.Constants.indicatorValueTimeout
134+ bufferedSyncTimeout: true
135+
136+ userTarget: sliderItem
137+ userProperty: "value"
138+
139+ serverTarget: sliderItem
140+ serverProperty: "serverValue"
141+
142+ onActivated: {
143+ menuModel.changeState(menuIndex, value);
144+ }
145+ }
133 }
146 }
134 }
147 }
135
148
@@ -280,6 +293,7 @@ Item {
280 id: checkableMenu;
293 id: checkableMenu;
281
294
282 Menus.CheckableMenu {
295 Menus.CheckableMenu {
296+ id: checkItem
283 objectName: "checkableMenu"
297 objectName: "checkableMenu"
284 property QtObject menuData: null
298 property QtObject menuData: null
285 property int menuIndex: -1
299 property int menuIndex: -1
@@ -290,26 +304,23 @@ Item {
290 checked: serverChecked
304 checked: serverChecked
291 highlightWhenPressed: false
305 highlightWhenPressed: false
292
306
293− onServerCheckedChanged: updateFromServer()
294− onTriggered: {
307+ onTriggered: checkMenuSync.activate()
295− menuModel.activate(menuIndex);
296− resyncTimer.restart();
297− }
298
308
299− // value can be changed by menu, so a binding won't work.
309+ ServerActivationSync {
300− function updateFromServer() {
310+ id: checkMenuSync
301− resyncTimer.stop();
311+ objectName: "sync"
302− if (checked != serverChecked) {
312+
303− checked = serverChecked;
313+ syncTimeout: Utils.Constants.indicatorValueTimeout
304− }
305− }
306
314
307− // Server value is not guaranteed to change to what we expect from an activation.
315+ userTarget: checkItem
308− // In this case, we need to re-assert that we are presenting the UI with the set backend value.
316+ userProperty: "checked"
309− Timer {
317+
310− id: resyncTimer
318+ serverTarget: checkItem
311− interval: 1500
319+ serverProperty: "serverChecked"
312− onTriggered: updateFromServer()
320+
321+ onActivated: {
322+ menuModel.activate(checkItem.menuIndex);
323+ }
313 }
324 }
314 }
325 }
315 }
326 }
@@ -318,9 +329,11 @@ Item {
318 id: switchMenu;
329 id: switchMenu;
319
330
320 Menus.SwitchMenu {
331 Menus.SwitchMenu {
332+ id: switchItem
321 objectName: "switchMenu"
333 objectName: "switchMenu"
322 property QtObject menuData: null
334 property QtObject menuData: null
323 property int menuIndex: -1
335 property int menuIndex: -1
336+
324 property bool serverChecked: menuData && menuData.isToggled || false
337 property bool serverChecked: menuData && menuData.isToggled || false
325
338
326 text: menuData && menuData.label || ""
339 text: menuData && menuData.label || ""
@@ -329,26 +342,23 @@ Item {
329 checked: serverChecked
342 checked: serverChecked
330 highlightWhenPressed: false
343 highlightWhenPressed: false
331
344
332− onServerCheckedChanged: updateFromServer()
333− onTriggered: {
345+ onTriggered: switchMenuSync.activate()
334− menuModel.activate(menuIndex);
335− resyncTimer.restart();
336− }
337
346
338− // value can be changed by menu, so a binding won't work.
347+ ServerActivationSync {
339− function updateFromServer() {
348+ id: switchMenuSync
340− resyncTimer.stop();
349+ objectName: "sync"
341− if (checked != serverChecked) {
342− checked = serverChecked;
343− }
344− }
345
350
346− // Server value is not guaranteed to change to what we expect from an activation.
351+ syncTimeout: Utils.Constants.indicatorValueTimeout
347− // In this case, we need to re-assert that we are presenting the UI with the set backend value.
352+
348− Timer {
353+ userTarget: switchItem
349− id: resyncTimer
354+ userProperty: "checked"
350− interval: 1500
355+
351− onTriggered: updateFromServer()
356+ serverTarget: switchItem
357+ serverProperty: "serverChecked"
358+
359+ onActivated: {
360+ menuModel.activate(switchItem.menuIndex);
361+ }
352 }
362 }
353 }
363 }
354 }
364 }
@@ -464,6 +474,7 @@ Item {
464 id: accessPoint;
474 id: accessPoint;
465
475
466 Menus.AccessPointMenu {
476 Menus.AccessPointMenu {
477+ id: apItem
467 objectName: "accessPoint"
478 objectName: "accessPoint"
468 property QtObject menuData: null
479 property QtObject menuData: null
469 property var menuModel: menuFactory.menuModel
480 property var menuModel: menuFactory.menuModel
@@ -485,10 +496,6 @@ Item {
485 signalStrength: strengthAction.valid ? strengthAction.state : 0
496 signalStrength: strengthAction.valid ? strengthAction.state : 0
486 highlightWhenPressed: false
497 highlightWhenPressed: false
487
498
488− onServerCheckedChanged: {
489− // value can be changed by menu, so a binding won't work.
490− active = serverChecked;
491− }
492 onMenuModelChanged: {
499 onMenuModelChanged: {
493 loadAttributes();
500 loadAttributes();
494 }
501 }
@@ -496,7 +503,7 @@ Item {
496 loadAttributes();
503 loadAttributes();
497 }
504 }
498 onTriggered: {
505 onTriggered: {
499− menuModel.activate(menuIndex);
506+ apMenuSync.activate();
500 }
507 }
501
508
502 function loadAttributes() {
509 function loadAttributes() {
@@ -505,6 +512,22 @@ Item {
505 'x-canonical-wifi-ap-is-secure': 'bool',
512 'x-canonical-wifi-ap-is-secure': 'bool',
506 'x-canonical-wifi-ap-strength-action': 'string'});
513 'x-canonical-wifi-ap-strength-action': 'string'});
507 }
514 }
515+
516+ ServerActivationSync {
517+ id: apMenuSync
518+
519+ syncTimeout: Utils.Constants.indicatorValueTimeout
520+
521+ userTarget: apItem
522+ userProperty: "active"
523+
524+ serverTarget: apItem
525+ serverProperty: "serverChecked"
526+
527+ onActivated: {
528+ menuModel.activate(apItem.menuIndex);
529+ }
530+ }
508 }
531 }
509 }
532 }
510
533
qml/Panel/Indicators/client/IndicatorsList.qml+2−2
@@ -31,8 +31,8 @@ Page {
31
31
32 Indicators.IndicatorsModel {
32 Indicators.IndicatorsModel {
33 id: indicatorsModel
33 id: indicatorsModel
34−
34+ profile: page.profile
35− Component.onCompleted: load(profile)
35+ Component.onCompleted: load()
36 }
36 }
37
37
38 ListView {
38 ListView {
run.sh+1−1
@@ -65,6 +65,6 @@ else
65 echo "Unity8 is already running, please stop it first"
65 echo "Unity8 is already running, please stop it first"
66 exit 1
66 exit 1
67 fi
67 fi
68− /sbin/initctl start unity8 BINARY="`readlink -f $QML_PHONE_SHELL_PATH` $QML_PHONE_SHELL_ARGS $@" QML2_IMPORT_PATH=$QML2_IMPORT_PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH
68+ /sbin/initctl start unity8 BINARY="`readlink -f $QML_PHONE_SHELL_PATH` $QML_PHONE_SHELL_ARGS $@" XDG_DATA_DIRS=$XDG_DATA_DIRS QML2_IMPORT_PATH=$QML2_IMPORT_PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH
69 tailf -n 0 ~/.cache/upstart/unity8.log
69 tailf -n 0 ~/.cache/upstart/unity8.log
70fi
70fi
src/Panel/Indicators/CMakeLists.txt+1
@@ -1 +1,2 @@
1add_subdirectory(client)
1add_subdirectory(client)
2+add_subdirectory(indicator-test-service)
src/Panel/Indicators/client/CMakeLists.txt−2
@@ -1,5 +1,4 @@
1project(indicators_client)
1project(indicators_client)
2−set(INDICATORS_CLIENT_APP indicators-client)
3
2
4set(INDICATORS_CLIENT_SRC
3set(INDICATORS_CLIENT_SRC
5 main.cpp
4 main.cpp
@@ -15,7 +14,6 @@ add_executable(${INDICATORS_CLIENT_APP}
15)
14)
16
15
17qt5_use_modules(${INDICATORS_CLIENT_APP} Core Widgets Quick)
16qt5_use_modules(${INDICATORS_CLIENT_APP} Core Widgets Quick)
18−set_target_properties(${INDICATORS_CLIENT_APP} PROPERTIES COMPILE_FLAGS -fPIC)
19
17
20install(TARGETS ${INDICATORS_CLIENT_APP}
18install(TARGETS ${INDICATORS_CLIENT_APP}
21 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
19 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
src/Panel/Indicators/indicator-test-service/CMakeLists.txtnew file+24
@@ -0,0 +1,24 @@
1+project(indicator-test-service)
2+pkg_search_module(GIO REQUIRED gio-2.0)
3+
4+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
5+
6+include_directories(
7+ ${CMAKE_CURRENT_SOURCE_DIR}
8+ ${GIO_INCLUDE_DIRS}
9+)
10+
11+set(INDICATOR_TEST_SERVICE_SRC
12+ indicator-test-service.c
13+)
14+
15+add_executable(${INDICATOR_TEST_SERVICE_APP}
16+ ${INDICATOR_TEST_SERVICE_SRC}
17+)
18+
19+target_link_libraries(${INDICATOR_TEST_SERVICE_APP} ${GIO_LDFLAGS})
20+
21+set_target_properties(${INDICATOR_TEST_SERVICE_APP} PROPERTIES COMPILE_FLAGS -fPIC)
22+
23+install(TARGETS ${INDICATOR_TEST_SERVICE_APP}
24+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
src/Panel/Indicators/indicator-test-service/indicator-test-service.cnew file+241
@@ -0,0 +1,241 @@
1+#include <gio/gio.h>
2+#include <stdio.h>
3+#include <stdlib.h>
4+
5+G_DEFINE_QUARK (SLIDER_VALUE, slider_value)
6+
7+typedef struct
8+{
9+ GSimpleActionGroup *actions;
10+ GMenu *menu;
11+
12+ guint actions_export_id;
13+ guint menu_export_id;
14+ int action_delay;
15+} IndicatorTestService;
16+
17+static void
18+bus_acquired (GDBusConnection *connection,
19+ const gchar *name,
20+ gpointer user_data)
21+{
22+ (void) name;
23+ IndicatorTestService *indicator = user_data;
24+ GError *error = NULL;
25+
26+ indicator->actions_export_id = g_dbus_connection_export_action_group (connection,
27+ "/com/canonical/indicator/test",
28+ G_ACTION_GROUP (indicator->actions),
29+ &error);
30+ if (indicator->actions_export_id == 0)
31+ {
32+ g_warning ("cannot export action group: %s", error->message);
33+ g_error_free (error);
34+ return;
35+ }
36+
37+ indicator->menu_export_id = g_dbus_connection_export_menu_model (connection,
38+ "/com/canonical/indicator/test/desktop",
39+ G_MENU_MODEL (indicator->menu),
40+ &error);
41+ if (indicator->menu_export_id == 0)
42+ {
43+ g_warning ("cannot export menu: %s", error->message);
44+ g_error_free (error);
45+ return;
46+ }
47+}
48+
49+static void
50+name_lost (GDBusConnection *connection,
51+ const gchar *name,
52+ gpointer user_data)
53+{
54+ (void) name;
55+ IndicatorTestService *indicator = user_data;
56+
57+ if (indicator->actions_export_id)
58+ g_dbus_connection_unexport_action_group (connection, indicator->actions_export_id);
59+
60+ if (indicator->menu_export_id)
61+ g_dbus_connection_unexport_menu_model (connection, indicator->menu_export_id);
62+}
63+
64+static void
65+activate_show (GSimpleAction *action,
66+ GVariant *parameter,
67+ gpointer user_data)
68+{
69+ (void) action;
70+ (void) parameter;
71+ (void) user_data;
72+ g_message ("showing");
73+}
74+
75+static gboolean
76+actual_switch (gpointer user_data)
77+{
78+ GSimpleAction *action = user_data;
79+
80+ GVariant* v = g_action_get_state(G_ACTION(action));
81+ gboolean state = g_variant_get_boolean (v);
82+ GVariant *new_state = g_variant_new_boolean (state == TRUE ? FALSE : TRUE);
83+
84+ g_simple_action_set_state(G_SIMPLE_ACTION(action), new_state);
85+
86+ g_variant_unref (v);
87+ g_message ("switching");
88+ return FALSE;
89+}
90+
91+static void
92+activate_switch (GSimpleAction *action,
93+ GVariant *parameter,
94+ gpointer user_data)
95+{
96+ (void) action;
97+ (void) parameter;
98+
99+ IndicatorTestService *indicator = user_data;
100+
101+ g_timeout_add(indicator->action_delay, actual_switch, action);
102+ g_message ("switch delay");
103+}
104+
105+static gboolean
106+actual_slide (gpointer user_data)
107+{
108+ GSimpleAction *action = user_data;
109+
110+ GVariant* new_state = g_object_get_qdata (G_OBJECT (action), slider_value_quark ());
111+
112+ g_simple_action_set_state(G_SIMPLE_ACTION(action), new_state);
113+
114+ g_message ("switching");
115+ return FALSE;
116+}
117+
118+void change_slider (GSimpleAction *action,
119+ GVariant *value,
120+ gpointer user_data)
121+{
122+ IndicatorTestService *indicator = user_data;
123+
124+ g_object_set_qdata (G_OBJECT (action), slider_value_quark (), g_variant_ref(value));
125+
126+ g_timeout_add(indicator->action_delay, actual_slide, action);
127+ g_message ("slide delay %.03f", g_variant_get_double(value));
128+}
129+
130+int
131+main (int argc, char **argv)
132+{
133+ IndicatorTestService indicator = { 0 };
134+ indicator.action_delay = -1;
135+ GMenuItem *item;
136+ GMenu *submenu;
137+ GActionEntry entries[] = {
138+ { "_header", NULL, NULL, "{'title': <'Test'>,"
139+ " 'label': <'Test'>,"
140+ " 'visible': <true>,"
141+ " 'accessible-desc': <'Test indicator'> }", NULL },
142+ { "action.show", activate_show, NULL, NULL, NULL },
143+ { "action.switch", activate_switch, NULL, "true", NULL },
144+ { "action.accessPoint", activate_switch, NULL, "false", NULL },
145+ { "action.slider", NULL, NULL, "0.5", change_slider }
146+ };
147+ GMainLoop *loop;
148+
149+ int help = 0;
150+ if (argc > 1)
151+ {
152+ int i;
153+ for (i = 1; i < argc; i++) {
154+ const char *arg = argv[i];
155+
156+ if (arg[0] == '-') {
157+ switch (arg[1])
158+ {
159+ case 't':
160+ {
161+ arg += 2;
162+ if (!arg[0] && i < argc-1) {
163+ i++;
164+ int delay = -1;
165+
166+ if (sscanf(argv[i], "%d", &delay) == 1) {
167+ indicator.action_delay = delay;
168+ } else {
169+ printf("Invalid action delay value: %s\n", argv[i]);
170+ help = 1;
171+ }
172+ } else {
173+ printf("Invalid action delay value: %s\n", argv[i]);
174+ help = 1;
175+ }
176+ break;
177+ }
178+ case 'h':
179+ help = 1;
180+ break;
181+ }
182+ }
183+ }
184+ }
185+
186+ if (help) {
187+ printf("Usage: %s [<options>]\n"
188+ " -t DELAY Action activation delay\n"
189+ " -h Show this help text\n"
190+ , argv[0]);
191+ return 0;
192+ }
193+
194+ indicator.actions = g_simple_action_group_new ();
195+ g_action_map_add_action_entries (G_ACTION_MAP (indicator.actions), entries, G_N_ELEMENTS (entries), &indicator);
196+
197+ submenu = g_menu_new ();
198+ g_menu_append (submenu, "Show", "indicator.action.show");
199+
200+ // Switch
201+ item = g_menu_item_new("Switch", "indicator.action.switch");
202+ g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.switch");
203+ g_menu_append_item(submenu, item);
204+
205+ // Access Point
206+ item = g_menu_item_new("Slider", "indicator.action.slider");
207+ g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.slider");
208+ g_menu_append_item(submenu, item);
209+
210+ // Access Point
211+ item = g_menu_item_new("Access Point", "indicator.action.accessPoint");
212+ g_menu_item_set_attribute (item, "x-canonical-type", "s", "unity.widgets.systemsettings.tablet.accesspoint");
213+ g_menu_append_item(submenu, item);
214+
215+
216+ item = g_menu_item_new (NULL, "indicator._header");
217+ g_menu_item_set_attribute (item, "x-canonical-type", "s", "com.canonical.indicator.root");
218+ g_menu_item_set_submenu (item, G_MENU_MODEL (submenu));
219+ indicator.menu = g_menu_new ();
220+ g_menu_append_item (indicator.menu, item);
221+
222+ g_bus_own_name (G_BUS_TYPE_SESSION,
223+ "com.canonical.indicator.test",
224+ G_BUS_NAME_OWNER_FLAGS_NONE,
225+ bus_acquired,
226+ NULL,
227+ name_lost,
228+ &indicator,
229+ NULL);
230+
231+ loop = g_main_loop_new (NULL, FALSE);
232+ g_main_loop_run (loop);
233+
234+ g_object_unref (submenu);
235+ g_object_unref (item);
236+ g_object_unref (indicator.actions);
237+ g_object_unref (indicator.menu);
238+ g_object_unref (loop);
239+
240+ return 1;
241+}
tests/autopilot/unity8/fixture_setup.py+33
@@ -96,3 +96,36 @@ class DisplayRotationLock(fixtures.Fixture):
96 'rotation-lock', value_string
96 'rotation-lock', value_string
97 ]
97 ]
98 subprocess.check_output(command)
98 subprocess.check_output(command)
99+
100+class LaunchTestIndicatorService(fixtures.Fixture):
101+
102+ """Fixture to launch the indicator test service."""
103+
104+ def __init__(self, binary_path, variables):
105+ """Initialize an instance.
106+
107+ :param str binary_path: The path to the indicator test app binary.
108+ :param variables: The variables to use when launching the app.
109+ :type variables: A dictionary.
110+
111+ """
112+ super(LaunchTestIndicatorService, self).__init__()
113+ self.binary_path = binary_path
114+ self.variables = variables
115+
116+ def setUp(self):
117+ super(LaunchTestIndicatorService, self).setUp()
118+ self.addCleanup(self.stop_service)
119+ self.application_proxy = self.launch_service()
120+
121+ def launch_service(self):
122+ binary_arg = 'BINARY={}'.format(self.binary_path)
123+ testability_arg = 'QT_LOAD_TESTABILITY={}'.format(1)
124+ env_args = [
125+ '{}={}'.format(key, value) for key, value in self.variables.items()
126+ ]
127+ all_args = [binary_arg, testability_arg] + env_args
128+ process_helpers.start_job('unity-indicator-test-service', *all_args)
129+
130+ def stop_service(self):
131+ process_helpers.stop_job('unity-indicator-test-service')
tests/autopilot/unity8/indicators/__init__.py+54−10
@@ -16,9 +16,11 @@
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
18import ubuntuuitoolkit
18import ubuntuuitoolkit
19+import subprocess
19from autopilot import introspection
20from autopilot import introspection
20
21
21from unity8.shell import emulators
22from unity8.shell import emulators
23+from unity8 import fixture_setup
22
24
23
25
24class IndicatorPage(emulators.UnityEmulatorBase):
26class IndicatorPage(emulators.UnityEmulatorBase):
@@ -33,26 +35,25 @@ class IndicatorPage(emulators.UnityEmulatorBase):
33 def validate_dbus_object(cls, path, state):
35 def validate_dbus_object(cls, path, state):
34 return False
36 return False
35
37
38+class Indicator(object):
36
39
37−class DisplayIndicator(object):
38−
39− def __init__(self, main_window):
40+ def __init__(self, main_window, name):
40 self._main_window = main_window
41 self._main_window = main_window
42+ self._name = name
41
43
42 def is_indicator_icon_visible(self):
44 def is_indicator_icon_visible(self):
43 panel_item = self._main_window.wait_select_single(
45 panel_item = self._main_window.wait_select_single(
44− objectName='indicator-rotation-lock-panelItem')
46+ objectName=self._name+'-panelItem')
45 return panel_item.indicatorVisible
47 return panel_item.indicatorVisible
46
48
47 def open(self):
49 def open(self):
48− """Open the display indicator page.
50+ """Open the indicator page.
49
51
50− :return: The custom proxy object for the display indicator page.
52+ :return: The custom proxy object for the indicator page.
51
53
52 """
54 """
53 if self.is_indicator_icon_visible():
55 if self.is_indicator_icon_visible():
54− return self._main_window.open_indicator_page(
56+ return self._main_window.open_indicator_page(self._name)
55− 'indicator-rotation-lock')
56 else:
57 else:
57 return self._open_indicator_with_icon_not_visible()
58 return self._open_indicator_with_icon_not_visible()
58
59
@@ -61,10 +62,10 @@ class DisplayIndicator(object):
61 self._main_window.open_indicator_page('indicator-datetime')
62 self._main_window.open_indicator_page('indicator-datetime')
62 self._make_indicator_icon_visible()
63 self._make_indicator_icon_visible()
63 indicator_rotation_icon = self._main_window.select_single(
64 indicator_rotation_icon = self._main_window.select_single(
64− objectName='indicator-rotation-lock-panelItem')
65+ objectName=self._name+'-panelItem')
65 self._main_window.pointing_device.click_object(indicator_rotation_icon)
66 self._main_window.pointing_device.click_object(indicator_rotation_icon)
66 return self._main_window.wait_select_single(
67 return self._main_window.wait_select_single(
67− objectName='indicator-rotation-lock-page')
68+ objectName=self._name+'-page')
68
69
69 def _make_indicator_icon_visible(self):
70 def _make_indicator_icon_visible(self):
70 indicators_bar_flickable = self._main_window.select_single(
71 indicators_bar_flickable = self._main_window.select_single(
@@ -95,6 +96,13 @@ class DisplayIndicator(object):
95 self._main_window.close_indicator_page()
96 self._main_window.close_indicator_page()
96
97
97
98
99+class DisplayIndicator(Indicator):
100+
101+ def __init__(self, main_window):
102+ super(DisplayIndicator, self).__init__(main_window, 'indicator-rotation-lock')
103+ self._main_window = main_window
104+
105+
98class DisplayIndicatorPage(IndicatorPage):
106class DisplayIndicatorPage(IndicatorPage):
99
107
100 """Autopilot helper for the display indicator page."""
108 """Autopilot helper for the display indicator page."""
@@ -122,3 +130,39 @@ class DisplayIndicatorPage(IndicatorPage):
122 switcher = self._get_switcher()
130 switcher = self._get_switcher()
123 switcher.uncheck()
131 switcher.uncheck()
124 switcher.checked.wait_for(False)
132 switcher.checked.wait_for(False)
133+
134+
135+class TestIndicator(Indicator):
136+
137+ def __init__(self, main_window):
138+ super(TestIndicator, self).__init__(main_window, 'indicator-test')
139+ self._main_window = main_window
140+
141+
142+class TestIndicatorPage(IndicatorPage):
143+
144+ """Autopilot helper for the test indicator page."""
145+
146+ @classmethod
147+ def validate_dbus_object(cls, path, state):
148+ name = introspection.get_classname_from_path(path)
149+ if name == b'IndicatorPage':
150+ if state['objectName'][1] == 'indicator-test-page':
151+ return True
152+ return False
153+
154+ def get_switcher(self):
155+ return self.select_single(
156+ ubuntuuitoolkit.CheckBox, objectName='switcher')
157+
158+ def get_checkbox(self):
159+ return self.select_single(
160+ ubuntuuitoolkit.CheckBox, objectName='checkbox')
161+
162+ def get_switch_menu(self):
163+ return self.select_single(
164+ 'SwitchMenu', objectName='indicator.action.switch')
165+
166+ def get_checkbox_menu(self):
167+ return self.select_single(
168+ 'CheckableMenu', objectName='indicator.action.check')
tests/autopilot/unity8/indicators/tests/__init__.py+10−3
@@ -24,11 +24,18 @@ from unity8.shell import tests
24
24
25class IndicatorTestCase(tests.UnityTestCase):
25class IndicatorTestCase(tests.UnityTestCase):
26
26
27− device_emulation_scenarios = tests._get_device_emulation_scenarios()
27+ device_emulation_scenarios = tests._get_device_emulation_scenarios('Nexus4')
28
28
29 def setUp(self):
29 def setUp(self):
30− if platform.model() == 'Desktop':
31− self.skipTest('Test cannot be run on the desktop.')
32 super(IndicatorTestCase, self).setUp()
30 super(IndicatorTestCase, self).setUp()
33 self.unity_proxy = self.launch_unity()
31 self.unity_proxy = self.launch_unity()
34 process_helpers.unlock_unity(self.unity_proxy)
32 process_helpers.unlock_unity(self.unity_proxy)
33+
34+class DeviceIndicatorTestCase(IndicatorTestCase):
35+
36+ def setUp(self):
37+ # if platform.model() == 'Desktop':
38+ # self.skipTest('Test cannot be run on the desktop.')
39+ super(DeviceIndicatorTestCase, self).setUp()
40+ self.unity_proxy = self.launch_unity()
41+ process_helpers.unlock_unity(self.unity_proxy)
tests/autopilot/unity8/indicators/tests/test_display_indicator.py+3−1
@@ -23,7 +23,9 @@ from unity8 import (
23from unity8.indicators import tests
23from unity8.indicators import tests
24
24
25
25
26−class DisplayIndicatorTestCase(tests.IndicatorTestCase):
26+class DisplayIndicatorTestCase(tests.DeviceIndicatorTestCase):
27+
28+ scenarios = tests.IndicatorTestCase.device_emulation_scenarios
27
29
28 def test_indicator_icon_must_be_visible_after_rotation_locked(self):
30 def test_indicator_icon_must_be_visible_after_rotation_locked(self):
29 # TODO remove the skip when the bug is fixed. --elopio - 2015-01-20
31 # TODO remove the skip when the bug is fixed. --elopio - 2015-01-20
tests/autopilot/unity8/indicators/tests/test_indicators.py+2−2
@@ -25,7 +25,7 @@ from autopilot import platform
25from unity8.indicators import tests
25from unity8.indicators import tests
26
26
27
27
28−class IndicatorExistsTestCase(tests.IndicatorTestCase):
28+class IndicatorExistsTestCase(tests.DeviceIndicatorTestCase):
29
29
30 indicator_scenarios = [
30 indicator_scenarios = [
31 ('Bluetooth', dict(indicator_name='indicator-bluetooth')),
31 ('Bluetooth', dict(indicator_name='indicator-bluetooth')),
@@ -53,7 +53,7 @@ class IndicatorExistsTestCase(tests.IndicatorTestCase):
53 )
53 )
54
54
55
55
56−class IndicatorPageTitleMatchesWidgetTestCase(tests.IndicatorTestCase):
56+class IndicatorPageTitleMatchesWidgetTestCase(tests.DeviceIndicatorTestCase):
57
57
58 indicator_scenarios = [
58 indicator_scenarios = [
59 ('Bluetooth', dict(indicator_name='indicator-bluetooth',
59 ('Bluetooth', dict(indicator_name='indicator-bluetooth',
tests/autopilot/unity8/indicators/tests/test_test_indicator.pynew file+192
@@ -0,0 +1,192 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Indicators Autopilot Test Suite
4+# Copyright (C) 2015 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+from unity8 import (
20+ fixture_setup,
21+ indicators,
22+ get_binary_path,
23+ process_helpers
24+)
25+from unity8.indicators import tests
26+
27+from autopilot.matchers import Eventually
28+from testtools.matchers import Equals
29+import time
30+
31+class TestIndicatorBaseTestCase(tests.IndicatorTestCase):
32+
33+ scenarios = tests.IndicatorTestCase.device_emulation_scenarios
34+
35+ def setUp(self, action_delay=30000):
36+ """
37+ :parameter action_delay: number of milliseconds for indicator backend
38+ to wait before performing actions
39+ """
40+ super(TestIndicatorBaseTestCase, self).setUp()
41+
42+ self.ensure_service_not_running();
43+
44+ binary_path = get_binary_path('unity-indicator-test-service')
45+ environment = {}
46+ environment['ARGS'] = '-t {0}'\
47+ .format(action_delay)
48+ self.launch_indicator_service(binary_path, environment)
49+
50+ # wait for the indicator to appear in unity
51+ self.indicator = indicators.TestIndicator(self.main_window)
52+ self.assertThat(
53+ self.indicator.is_indicator_icon_visible(),
54+ Eventually(Equals(True), timeout=20)
55+ )
56+ self.indicator_page = self.indicator.open()
57+
58+ def launch_indicator_service(self, binary_path, variables):
59+ launch_service_fixture = fixture_setup.LaunchTestIndicatorService(binary_path, variables)
60+ self.useFixture(launch_service_fixture)
61+
62+ def ensure_service_not_running(self):
63+ if process_helpers.is_job_running('unity-indicator-test-service'):
64+ process_helpers.stop_job('unity-indicator-test-service')
65+
66+
67+class TestLowLatencyIndicator(TestIndicatorBaseTestCase):
68+
69+ def setUp(self):
70+ """Set up for indicator actions to take 50 milliseconds for be actioned"""
71+ super(TestLowLatencyIndicator, self).setUp(50)
72+
73+
74+ def test_switch_reaches_server_value(self):
75+ """Test that switching causes the server to update"""
76+ self.assertThat(
77+ self.indicator_page.get_switch_menu().serverChecked,
78+ Equals(self.indicator_page.get_switcher().checked)
79+ )
80+
81+ self.indicator_page.get_switcher().change_state()
82+
83+ self.assertThat(
84+ self.indicator_page.get_switch_menu().serverChecked,
85+ Eventually(Equals(self.indicator_page.get_switcher().checked), timeout=10)
86+ )
87+
88+class TestMediumLatencyIndicator(TestIndicatorBaseTestCase):
89+
90+ def setUp(self):
91+ """Set up for indicator actions to take 2.5 seconds for be actioned"""
92+ super(TestMediumLatencyIndicator, self).setUp(2500)
93+
94+ def test_buffered_switch(self):
95+ """Test that switching multiple times will buffer activations if
96+ within the activation timeout period
97+
98+ See https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1390136 .
99+ """
100+ self.indicator_page.get_switcher().change_state()
101+ # will buffer change until it receives the change from server
102+ self.indicator_page.get_switcher().change_state()
103+ new_value = self.indicator_page.get_switcher().checked;
104+
105+ # backend will respond to first switch. The buffered activation should have gone to server now.
106+ self.assertThat(
107+ self.indicator_page.get_switch_menu().serverChecked,
108+ Eventually(Equals(not new_value), timeout=15)
109+ )
110+
111+ # front-end should not change while it is buffered
112+ self.assertThat(
113+ self.indicator_page.get_switcher().checked,
114+ Equals(new_value)
115+ )
116+
117+ # server will respond to the second activate
118+ self.assertThat(
119+ self.indicator_page.get_switch_menu().serverChecked,
120+ Eventually(Equals(new_value), timeout=15)
121+ )
122+
123+ # make sure we've got the server value set.
124+ self.assertThat(
125+ self.indicator_page.get_switcher().checked,
126+ Equals(self.indicator_page.get_switch_menu().serverChecked)
127+ )
128+
129+
130+
131+class TestHighLatencyIndicator(TestIndicatorBaseTestCase):
132+
133+ def setUp(self):
134+ """Set up for indicator actions to take 8 seconds for be actioned"""
135+ super(TestHighLatencyIndicator, self).setUp(8000)
136+
137+ def test_switch_reverts_to_server_value(self):
138+ """Test that switching a high latency backend value will revert to original value
139+ if not actioned in time.
140+
141+ See https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1390136 .
142+ """
143+ self.assertThat(
144+ self.indicator_page.get_switch_menu().serverChecked,
145+ Equals(self.indicator_page.get_switcher().checked)
146+ )
147+
148+ original_value = self.indicator_page.get_switcher().checked;
149+ self.indicator_page.get_switcher().change_state()
150+
151+ # switch should revert to original value after 5 seconds (30 seconds in real usage)
152+ self.assertThat(
153+ self.indicator_page.get_switch_menu().serverChecked,
154+ Eventually(Equals(original_value), timeout=15)
155+ )
156+ # value will eventually switch back. See test_switch_always_reaches_server_value
157+
158+ def test_switch_always_reaches_server_value(self):
159+ """Test that switching a high latency backend value will always end up following the
160+ server value, even if had a reversion
161+
162+ See https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1390136 .
163+ """
164+ self.test_switch_reverts_to_server_value()
165+
166+ self.assertThat(
167+ self.indicator_page.get_switch_menu().serverChecked,
168+ Eventually(Equals(self.indicator_page.get_switcher().checked), timeout=15)
169+ )
170+
171+ def test_revert_on_late_response(self):
172+ """If the server does not respond in the given amount of time
173+ then we wont switch again even if the switch is buffered
174+
175+ See https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1390136 .
176+ """
177+ self.indicator_page.get_switcher().change_state()
178+ # will buffer change until it receives the change from server
179+ self.indicator_page.get_switcher().change_state()
180+ new_value = self.indicator_page.get_switcher().checked;
181+
182+ # backend will respond to first switch. The buffered activation will be discarded
183+ self.assertThat(
184+ self.indicator_page.get_switch_menu().serverChecked,
185+ Eventually(Equals(not new_value), timeout=15)
186+ )
187+
188+ # make sure we've got the server value set.
189+ self.assertThat(
190+ self.indicator_page.get_switcher().checked,
191+ Equals(self.indicator_page.get_switch_menu().serverChecked)
192+ )
tests/mocks/data/unity/indicators/com.canonical.indicator.testnew file+10
@@ -0,0 +1,10 @@
1+[Indicator Service]
2+Name=indicator-test
3+ObjectPath=/com/canonical/indicator/test
4+Position=0
5+
6+[phone]
7+ObjectPath=/com/canonical/indicator/test/desktop
8+
9+[desktop]
10+ObjectPath=/com/canonical/indicator/test/desktop
tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp−2
@@ -31,13 +31,11 @@ private Q_SLOTS:
31
31
32 void initTestCase()
32 void initTestCase()
33 {
33 {
34− setenv("UNITY_TEST_ENV", "1", 1);
35 setenv("XDG_DATA_DIRS", (sourceDirectory() + "/tests/data").toLatin1().data(), 1);
34 setenv("XDG_DATA_DIRS", (sourceDirectory() + "/tests/data").toLatin1().data(), 1);
36 }
35 }
37
36
38 void cleanupTestCase()
37 void cleanupTestCase()
39 {
38 {
40− unsetenv("UNITY_TEST_ENV");
41 }
39 }
42
40
43 /*
41 /*
tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp−2
@@ -32,13 +32,11 @@ private Q_SLOTS:
32
32
33 void initTestCase()
33 void initTestCase()
34 {
34 {
35− setenv("UNITY_TEST_ENV", "1", 1);
36 setenv("XDG_DATA_DIRS", (sourceDirectory() + "/tests/data").toLatin1().data(), 1);
35 setenv("XDG_DATA_DIRS", (sourceDirectory() + "/tests/data").toLatin1().data(), 1);
37 }
36 }
38
37
39 void cleanupTestCase()
38 void cleanupTestCase()
40 {
39 {
41− unsetenv("UNITY_TEST_ENV");
42 }
40 }
43
41
44 /*
42 /*
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml+4
@@ -819,6 +819,10 @@ Item {
819 loader.data = menuData;
819 loader.data = menuData;
820 loader.sourceComponent = factory.load(menuData);
820 loader.sourceComponent = factory.load(menuData);
821
821
822+ var sync = findInvisibleChild(loader.item, "sync");
823+ verify(sync);
824+ sync.syncTimeout = 500;
825+
822 compare(loader.item.checked, false, "Loader did not load check state");
826 compare(loader.item.checked, false, "Loader did not load check state");
823 mouseClick(loader.item,
827 mouseClick(loader.item,
824 loader.item.width / 2, loader.item.height / 2);
828 loader.item.width / 2, loader.item.height / 2);