on 291ed4e help sign in
46 files changed+547−218
since splitsnapshots
unifiedsplit
CMakeLists.txt+2−2 Jenkinsfile+4−1 data/unity8-dash.conf−26 data/unity8-dash.service+15 data/unity8-filewatcher.conf−13 data/unity8-greeter-wrapper+7−23 data/unity8-session+81 data/unity8.conf−95 data/unity8.service+14 debian/changelog+1−1 debian/control+13−9 debian/rules+2−2 debian/unity8-tests.install+1 debian/unity8.install+3−2 plugins/Dash/abstractdashview.cpp+1−1 plugins/Dash/listviewwithpageheader.cpp+1−1 plugins/Greeter/Unity/Launcher/launcheritem.cpp+6 plugins/Greeter/Unity/Launcher/launcheritem.h+1 plugins/Unity/Launcher/appdrawermodel.cpp+68−7 plugins/Unity/Launcher/appdrawermodel.h+8 plugins/Unity/Launcher/dbusinterface.cpp+2 plugins/Unity/Launcher/launcheritem.cpp+13 plugins/Unity/Launcher/launcheritem.h+3 plugins/Unity/Launcher/launchermodel.cpp+1 plugins/Unity/Launcher/ualwrapper.cpp+12−2 plugins/Unity/Launcher/ualwrapper.h+6 plugins/Unity/Session/dbusunitysessionservice.cpp+5−11 tests/mocks/Unity/Launcher/MockLauncherItem.cpp+13 tests/mocks/Unity/Launcher/MockLauncherItem.h+3 tests/plugins/Ubuntu/CMakeLists.txt+1−1 tests/plugins/Ubuntu/Gestures/GestureTest.cpp+10−1 tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+10−1 tests/plugins/Unity/Launcher/CMakeLists.txt+34 tests/plugins/Unity/Launcher/appdrawermodeltest.cpp+53 tests/plugins/Unity/Launcher/ualwrapper.cpp+60 tests/plugins/Unity/Launcher/ualwrapper.h+55 tests/plugins/Unity/Session/CMakeLists.txt+1 tests/plugins/Unity/Session/LogindServer.cpp−5 tests/plugins/Unity/Session/LogindServer.h−1 tests/plugins/Unity/Session/interfaces.xml−4 tests/plugins/Unity/Session/server.cpp+1−1 tests/plugins/Unity/Session/sessionbackendtest.cpp+5−3 tests/qmltests/CMakeLists.txt+1−1 tests/qmltests/Components/tst_DragHandle.cpp+19−2 tests/utils/CMakeLists.txt+1−1 tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp+10−1
CMakeLists.txt+2−2
@@ -75,10 +75,10 @@ pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=27)
7575pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
7676pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
7777pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
78−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=12)
78+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=13)
7979pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
8080pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
81−pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2)
81+pkg_check_modules(UAL REQUIRED ubuntu-app-launch-3)
8282pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
8383pkg_check_modules(QTDBUSTEST REQUIRED
8484 libqtdbustest-1
Jenkinsfile+4−1
@@ -28,7 +28,7 @@ build-binary.sh'''
2828 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
2929 unstash 'source'
3030 sh '''export architecture="arm64"
31− build-binary.sh'''
31+ # build-binary.sh'''
3232 stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-arm64')
3333 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
3434 }
@@ -38,6 +38,9 @@ build-binary.sh'''
3838 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
3939 unstash 'source'
4040 sh '''export architecture="amd64"
41+ export DEBBUILDOPTS=-sa
42+export SKIP_ARCH_BUILD=false
43+export SKIP_SOURCE_REMOVAL=true
4144 build-binary.sh'''
4245 stash(includes: '*.gz,*.bz2,*.xz,*.deb,*.dsc,*.changes,*.buildinfo,lintian.txt', name: 'build-amd64')
4346 cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true, deleteDirs: true)
data/unity8-dash.confdeleted−26
@@ -1,26 +0,0 @@
1−description "Unity Shell v8 Dash"
2−author "Michael Zanetti <michael.zanetti@canonical.com>"
3−
4−emits scope-ui-starting
5−
6−start on started unity8
7−stop on stopping unity8
8−
9−kill timeout 120
10−
11−# Focused app is 100 so we want to be less likely to get
12−# killed than the focused app but more than Unity8
13−
14−## FIXME
15−#oom score 50
16−
17−respawn
18−respawn limit unlimited
19−
20−env APP_ID=unity8-dash
21−
22−pre-start script
23− initctl emit scope-ui-starting
24−end script
25−
26−exec ${BINARY:-unity8-dash} $ARGS --desktop_file_hint=unity8-dash.desktop
data/unity8-dash.servicenew file+15
@@ -0,0 +1,15 @@
1+[Unit]
2+Description=Unity Shell v8 Dash
3+PartOf=graphical-session.target
4+BindsTo=unity8.service
5+After=unity8.service
6+
7+[Service]
8+ExecStart=/usr/bin/unity8-dash --desktop_file_hint=unity8-dash
9+Restart=always
10+TimeoutStartSec=120
11+Environment=APP_ID=unity8-dash
12+
13+# Focused app is 100 so we want to be less likely to get
14+# killed than the focused app but more than Unity8
15+OOMScoreAdjust=50
data/unity8-filewatcher.confdeleted−13
@@ -1,13 +0,0 @@
1−description "File system watcher for unity8"
2−author "Michael Zanetti <michael.zanetti@canonical.com>"
3−
4−# This method of updating the launcher will not work in our new snappy world,
5−# neither for snaps installed in the system nor if we are running inside a snap.
6−# Plus it hardcodes the phablet user... To be replaced once bug 1630997 is
7−# fixed in ubuntu-app-launch.
8−
9−# Workaround for bug 1360208. ~ and * in one expression doesn't work currently
10−start on (file FILE=/home/phablet/.local/share/applications/*.desktop) or (file FILE=/usr/share/applications/*.desktop)
11−
12−exec dbus-send --type=method_call --dest=com.canonical.Unity.Launcher /com/canonical/Unity/Launcher com.canonical.Unity.Launcher.Refresh
13−
data/unity8-greeter-wrapper+7−23
@@ -20,8 +20,8 @@ cleanup()
2020{
2121 trap - TERM EXIT
2222 # Kill upstart and indicators
23− if [ -n "$INIT_PID" ]; then
24− kill "$INIT_PID"
23+ if [ -n "$IND_PID" ]; then
24+ kill "$IND_PID"
2525 fi
2626 if [ -n "$CMD_PID" ]; then
2727 kill "$CMD_PID"
@@ -32,10 +32,7 @@ cleanup()
3232set_greeter_var()
3333{
3434 export "$1=$2"
35− gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "{'$1': '$2'}"
36− if [ -n "$INIT_PID" ]; then
37− initctl set-env --global "$1=$2"
38− fi
35+ dbus-update-activation-environment --systemd "$1=$2"
3936}
4037
4138SUB_SOCKET=$XDG_RUNTIME_DIR/mir_socket
@@ -61,25 +58,12 @@ set_greeter_var QT_QPA_PLATFORM ubuntumirclient
6158# eventually need the greeter to play ringtones for users that aren't logged in.
6259set_greeter_var PA_DISABLED 1
6360
64−# Normal unity8 sessions are entirely driven by Upstart. But greeters
65−# are special. They need access to the file descriptors that lightdm
66−# creates for them and don't want to start all the services that a normal
67−# session would. So it's inconvenient to live within an upstart session.
68−# But... we still want to use Upstart for some services. So launch here.
69−MIR_SOCKET=$SUB_SOCKET $TOUCH_WRAPPER upstart --user --no-startup-event &
70−INIT_PID=$!
71−while [ ! -e "$XDG_RUNTIME_DIR/upstart/sessions/$INIT_PID.session" ]; do sleep 0.1; done
72−. "$XDG_RUNTIME_DIR/upstart/sessions/$INIT_PID.session"
73−export UPSTART_SESSION
74−
75−# Connect upstart to system, but do first command in a loop to avoid any
76−# race condition between the session file above being written and upstart being
77−# ready to handle requests.
78−while ! initctl notify-dbus-address "$DBUS_SESSION_BUS_ADDRESS"; do sleep 0.1; done
79−initctl start notify-cgmanager
61+# Start the indicators
62+/usr/lib/gnome-session/run-systemd-session indicators.target &
63+IND_PID=$!
8064
8165# Start any pre-greeter tasks if needed (like wizard)
82−initctl emit unity8-greeter-starting
66+#initctl emit unity8-greeter-starting FIXME
8367
8468# Define language here for phone if available. When phone user switches their
8569# language, they expect that to affect the greeter too. But the user doesn't
data/unity8-sessionnew file+81
@@ -0,0 +1,81 @@
1+#!/bin/bash
2+# -*- Mode: sh; indent-tabs-mode: nil; tab-width: 2 -*-
3+
4+# Ensure the shell always gets unthrottled touch events, so that applications
5+# who want full speed low-latency input can get it (LP: #1497105) and so that
6+# apps can use QML touch compression safely (the QML touch compression
7+# algorithm does not support nesting well - LP: #1486341, LP: #1556763 - so
8+# must be fed by the raw input event stream from Unity8).
9+export QML_NO_TOUCH_COMPRESSION=1
10+
11+export MIR_SERVER_PROMPT_FILE=1
12+
13+# Hard code socket path because our snappy apparmor profile
14+# only lets us put the socket in one place. And consumers expect it there.
15+# (XDG_RUNTIME_DIR isn't typical under snappy)
16+export MIR_SERVER_FILE=/run/user/$(id -u)/mir_socket
17+
18+rm -f "$MIR_SERVER_FILE"
19+rm -f "${MIR_SERVER_FILE}_trusted"
20+
21+if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
22+ # On Ubuntu Touch, we currently use a trick where we auto-login the
23+ # user without a LightDM greeter at all. In this case, we want to
24+ # start with the lockscreen visible. Once we switch to using a
25+ # proper greeter for the first login, we can remove this code path.
26+ MODE=full-greeter
27+else
28+ MODE=full-shell
29+fi
30+
31+# Add options for settings
32+if [ -f ~/.unity8/configs.conf ]; then
33+ source ~/.unity8/configs.conf
34+fi
35+
36+# Scale settings
37+isfloat='^[0-9]+([.][0-9]+)?$'
38+isint='^[0-9]+$'
39+if [[ $SCALE =~ $isfloat ]]; then
40+ if ! [ $SCALE == "0" ]; then
41+ export GRID_UNIT_PX=$(LC_ALL=C printf %.0f $((8 * ${SCALE})))
42+ export QT_WAYLAND_FORCE_DPI=$(LC_ALL=C printf %.0f $((96 * ${SCALE})))
43+ fi
44+fi
45+
46+if [[ $GRID_UNIT_PX =~ $isint ]]; then
47+ dbus-update-activation-environment --systemd GRID_UNIT_PX=${GRID_UNIT_PX}
48+fi
49+
50+if [[ $QT_WAYLAND_FORCE_DPI =~ $isint ]]; then
51+ dbus-update-activation-environment --systemd QT_WAYLAND_FORCE_DPI=${QT_WAYLAND_FORCE_DPI}
52+fi
53+
54+# Tell unity-mir to raise SIGSTOP after we start, which we use to tell
55+# systemd when we are done starting up.
56+export UNITY_MIR_EMITS_SIGSTOP=1
57+
58+# Set some envs
59+dbus-update-activation-environment --systemd QT_QPA_PLATFORM=wayland
60+dbus-update-activation-environment --systemd GDK_BACKEND=wayland
61+dbus-update-activation-environment --systemd SDL_VIDEODRIVER=wayland
62+dbus-update-activation-environment --systemd UNITY8_SHELL_QT_QPA_PLATFORM=mirserver
63+dbus-update-activation-environment --systemd QT_WAYLAND_DISABLE_WINDOWDECORATION=1
64+dbus-update-activation-environment --systemd QT_ACCESSIBILITY=1
65+dbus-update-activation-environment --systemd QT_AUTO_SCREEN_SCALE_FACTOR=0
66+dbus-update-activation-environment --systemd GTK_CSD=0
67+
68+# We need to be sure we dont use mir-on-mir
69+unset MIR_SERVER_HOST_SOCKET
70+
71+${BINARY:-unity8} --mode=$MODE "$@" &
72+child=$!
73+
74+# Wait for SIGSTOP in child
75+while [ $(ps --no-headers -o state $child) != "T" ]; do
76+ sleep 0.1
77+done
78+
79+kill -CONT $child
80+exit 0
81+
data/unity8.confdeleted−95
@@ -1,95 +0,0 @@
1−description "Unity Shell v8"
2−author "Ricardo Mendoza <ricmm@ubuntu.com>"
3−
4−emits indicator-services-start
5−
6−start on ((xsession SESSION=ubuntu-touch) or (xsession SESSION=unity8-mir) or (xsession SESSION=unity8)) and started dbus
7−stop on desktop-end
8−
9−kill timeout 120
10−
11−#
12−# Ensure the shell always gets unthrottled touch events, so that applications
13−# who want full speed low-latency input can get it (LP: #1497105) and so that
14−# apps can use QML touch compression safely (the QML touch compression
15−# algorithm does not support nesting well - LP: #1486341, LP: #1556763 - so
16−# must be fed by the raw input event stream from Unity8).
17−#
18−env QML_NO_TOUCH_COMPRESSION=1
19−
20−respawn
21−expect stop
22−
23−# FIXME Create an autopilot test that makes sure start+stop and restart
24−# work fine at least 2 times
25−
26−pre-start script
27− # Tell unity-mir to raise SIGSTOP after we start
28− initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
29−
30− # Save original value of MIR_SOCKET so that we can restore it when stopped,
31− # as we modify the variable for future jobs, including ourself.
32− initctl set-env UNITY_MIR_SOCKET=$MIR_SOCKET
33−
34− # Decide where we are going to put our own socket file
35− if [ -n "$SNAP" ]; then
36− # In snappy, we want to hard code our path because our apparmor profile
37− # only lets us put the socket in one place. And consumers expect it
38− # there.
39− MIR_SERVER_FILE=/run/user/$(id -u)/mir_socket
40− else
41− MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
42− fi
43− initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
44−
45− # Point all future jobs in this session to our Mir socket instead of
46− # unity-system-compositor's socket.
47− initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
48− gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
49−
50− # Remove the normal and trusted sockets if still there
51− if [ -S "$MIR_SERVER_FILE" ]; then
52− rm "$MIR_SERVER_FILE"
53− fi
54−
55− if [ -S "${MIR_SERVER_FILE}_trusted" ]; then
56− rm "${MIR_SERVER_FILE}_trusted"
57− fi
58−
59− initctl set-env --global MIR_SERVER_PROMPT_FILE=1
60−
61− # Disable Qt's stuttering 'touch compression' to fix scrolling smoothness
62− # issues (LP: #1486341, LP: #1556763). As a bonus, this eliminates most of
63− # the lag seen in the indicator panel pull-down (LP: #1488327) and also
64− # reduces lag seen in apps:
65− initctl set-env --global QML_NO_TOUCH_COMPRESSION=1
66−
67− # Workaround for text not rendering correctly
68− initctl set-env --global QT_ENABLE_GLYPH_CACHE_WORKAROUND=1
69−
70− if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
71− # On Ubuntu Touch, we currently use a trick where we auto-login the
72− # user without a LightDM greeter at all. In this case, we want to
73− # start with the lockscreen visible. Once we switch to using a
74− # proper greeter for the first login, we can remove this code path.
75− initctl set-env MODE=full-greeter
76− else
77− initctl set-env MODE=full-shell
78− fi
79−
80− # HACK! WORKAROUND FOR HALIUM MISSING UBUNTU_PLATFORM_API
81− initctl set-env --global UBUNTU_PLATFORM_API_BACKEND=test.so.3
82− initctl set-env --global UBUNTU_PLATFORM_API_SENSOR_TEST=/etc/ubuntusensors/test.sensors
83−end script
84−
85−exec ${BINARY:-unity8} --mode=$MODE $ARGS
86−
87−post-start script
88− initctl emit --no-wait indicator-services-start
89−end script
90−
91−post-stop script
92− initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
93− initctl unset-env --global MIR_SERVER_PROMPT_FILE
94− initctl emit application-end
95−end script
data/unity8.servicenew file+14
@@ -0,0 +1,14 @@
1+[Unit]
2+Description=Unity Shell v8
3+PartOf=graphical-session.target
4+Requires=dbus.socket
5+After=dbus.socket
6+Before=indicators.target
7+Wants=indicators.target
8+
9+[Service]
10+Type=forking
11+ExecStart=/usr/bin/unity8-session
12+ExecStopPost=/usr/bin/dbus-update-activation-environment --systemd MIR_SOCKET=
13+Restart=on-failure
14+TimeoutStartSec=120
debian/changelog+1−1
@@ -1,4 +1,4 @@
1−unity8 (8.16.1+ubports) xenial; urgency=medium
1+unity8 (8.16.1+ubports) bionic; urgency=medium
22
33 * Imported to UBports
44
debian/control+13−9
@@ -6,6 +6,7 @@ Build-Depends: cmake,
66 dbus-test-runner,
77 debhelper (>= 9),
88 dh-apparmor,
9+ dh-systemd,
910 doxyqml,
1011# To allow cross-compiling to work, we also must append :native
1112# to g++ so we don't try to run arm g++
@@ -34,13 +35,13 @@ Build-Depends: cmake,
3435 libqt5svg5-dev,
3536 libqt5xmlpatterns5-dev,
3637 libsystemsettings-dev,
37− libubuntu-app-launch2-dev,
38+ libubuntu-app-launch3-dev,
3839 libubuntu-download-manager-common-dev,
3940 libubuntugestures5-dev (>= 1.3.2030),
4041 libubuntugestures5-private-dev (>= 1.3.2030),
4142 libudev-dev,
4243 libudm-common-dev,
43− libunity-api-dev (>= 8.6),
44+ libunity-api-dev (>= 8.7),
4445 libusermetricsoutput1-dev,
4546# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
4647 libx11-dev[!arm64 !armhf],
@@ -61,7 +62,7 @@ Build-Depends: cmake,
6162 qml-module-qtsysteminfo,
6263 qml-module-qttest,
6364 qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
64− qml-module-ubuntu-web,
65+# qml-module-ubuntu-web,
6566 qt5-default,
6667 qtbase5-dev (>= 5.6),
6768 qtbase5-dev-tools,
@@ -71,6 +72,7 @@ Build-Depends: cmake,
7172 qtdeclarative5-private-dev (>= 5.6),
7273 qtdeclarative5-ubuntu-content1,
7374 qtdeclarative5-ubuntu-settings-components (>= 0.11),
75+ systemd,
7476 ttf-ubuntu-font-family,
7577 xvfb,
7678Standards-Version: 3.9.4
@@ -120,7 +122,8 @@ Description: Development tool for Unity scopes
120122Package: unity8
121123Architecture: any
122124Provides: indicator-renderer,
123−Depends: dmz-cursor-theme,
125+Depends: dbus,
126+ dmz-cursor-theme,
124127 gsettings-desktop-schemas,
125128 libcap2-bin,
126129 libglib2.0-bin,
@@ -131,11 +134,12 @@ Depends: dmz-cursor-theme,
131134 qml-module-qtqml-statemachine,
132135 qml-module-qtquick-xmllistmodel,
133136 qml-module-qtsysteminfo,
134− qml-module-ubuntu-web,
137+# qml-module-ubuntu-web,
135138 qtdeclarative5-qtmir-plugin (>= 0.4.8),
136139 qtdeclarative5-ubuntu-telephony0.1,
140+ qtwayland5,
137141 ubuntu-system-settings (>= 0.4),
138− unity-launcher-impl-12,
142+ unity-launcher-impl-13,
139143 unity8-common (= ${source:Version}),
140144 unity8-private (= ${binary:Version}),
141145 unity8-private | unity-launcher-impl,
@@ -167,8 +171,8 @@ Depends: qml-module-qtquick-layouts,
167171 ubuntu-wallpapers,
168172 unity-application-impl-27,
169173 unity-notifications-impl-3,
170− unity-plugin-scopes | unity-scopes-impl,
171− unity-scopes-impl-12,
174+# unity-plugin-scopes | unity-scopes-impl,
175+# unity-scopes-impl-12,
172176 unity8-tests | unity-application-impl,
173177 ${misc:Depends},
174178Breaks: unity8 (<< 7.86),
@@ -239,7 +243,7 @@ Depends: accountsservice-ubuntu-schemas (>= 0.0.7),
239243 ${misc:Depends},
240244 ${shlibs:Depends},
241245Provides: unity-launcher-impl,
242− unity-launcher-impl-12,
246+ unity-launcher-impl-13,
243247Description: Unity 8 private libs
244248 The Unity 8 shell is the primary user interface for Ubuntu devices.
245249 .
debian/rules+2−2
@@ -9,7 +9,7 @@ export DPKG_GENSYMBOLS_CHECK_LEVEL=4
99export NO_PNG_PKG_MANGLE=1
1010
1111%:
12− dh $@ --parallel --fail-missing --with python3
12+ dh $@ --parallel --fail-missing --with python3,systemd
1313
1414override_dh_auto_configure:
1515 # Debian defines CMAKE_INSTALL_LOCALSTATEDIR as /usr/var, which is wrong.
@@ -30,7 +30,7 @@ override_dh_install:
3030 dh_install -X'*.pyc' --fail-missing
3131
3232override_dh_installdeb:
33− dh_apparmor --profile-name=usr.bin.unity8-dash -punity8-dash
33+ #dh_apparmor --profile-name=usr.bin.unity8-dash -punity8-dash
3434 dh_installdeb
3535
3636# use private lib directories
debian/unity8-tests.install+1
@@ -3,6 +3,7 @@ usr/bin/unity-mock-indicator-service
33usr/lib/*/unity8/qml/mocks
44usr/lib/*/unity8/qml/nonmirplugins
55usr/lib/*/unity8/qml/scopefakes
6+usr/lib/*/unity8/qml/utils
67usr/lib/*/unity8/tests
78usr/lib/*/unity8/uqmlscene
89usr/share/unity8/mocks
debian/unity8.install+3−2
@@ -1,7 +1,8 @@
11debian/usr.bin.unity8-dash etc/apparmor.d
22var/lib/unity8/version
3−data/unity8-filewatcher.conf usr/share/upstart/sessions/
4−data/unity8.conf usr/share/upstart/sessions/
3+data/unity8.service usr/lib/systemd/user
4+data/unity8-dash.service usr/lib/systemd/user
5+data/unity8-session usr/bin
56data/devices.conf etc/ubuntu/
67data/test.sensors etc/ubuntusensors/
78usr/bin/unity8
plugins/Dash/abstractdashview.cpp+1−1
@@ -236,7 +236,7 @@ QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
236236 return nullptr;
237237
238238 m_asyncRequestedIndex = -1;
239− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
239+ QObject* object = m_delegateModel->object(modelIndex, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
240240 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
241241 if (!item) {
242242 if (object) {
plugins/Dash/listviewwithpageheader.cpp+1−1
@@ -871,7 +871,7 @@ ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIn
871871 return nullptr;
872872
873873 m_asyncRequestedIndex = -1;
874− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
874+ QObject* object = m_delegateModel->object(modelIndex, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
875875 QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
876876 if (!item) {
877877 if (object) {
plugins/Greeter/Unity/Launcher/launcheritem.cpp+6
@@ -89,6 +89,12 @@ void LauncherItem::setKeywords(const QStringList &keywords)
8989 }
9090}
9191
92+uint LauncherItem::popularity() const
93+{
94+ // Not exposing usage order in greeter session at this point.
95+ return 0;
96+}
97+
9298bool LauncherItem::pinned() const
9399{
94100 return m_pinned;
plugins/Greeter/Unity/Launcher/launcheritem.h+1
@@ -35,6 +35,7 @@ public:
3535 QString name() const override;
3636 QString icon() const override;
3737 QStringList keywords() const override;
38+ uint popularity() const override;
3839 bool pinned() const override;
3940 bool running() const override;
4041 bool recent() const override;
plugins/Unity/Launcher/appdrawermodel.cpp+68−7
@@ -21,7 +21,8 @@
2121#include <QDateTime>
2222
2323AppDrawerModel::AppDrawerModel(QObject *parent):
24− AppDrawerModelInterface(parent)
24+ AppDrawerModelInterface(parent),
25+ m_ual(new UalWrapper(this))
2526{
2627 Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
2728 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
@@ -29,10 +30,16 @@ AppDrawerModel::AppDrawerModel(QObject *parent):
2930 qWarning() << "Failed to get app info for app" << appId;
3031 continue;
3132 }
32− m_list.append(new LauncherItem(appId, info.name, info.icon, this));
33− m_list.last()->setKeywords(info.keywords);
33+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
34+ item->setKeywords(info.keywords);
35+ item->setPopularity(info.popularity);
36+ m_list.append(item);
3437 }
35− qsrand(QDateTime::currentMSecsSinceEpoch() / 100);
38+
39+ // keep this a queued connection as it's coming from another thread.
40+ connect(m_ual, &UalWrapper::appAdded, this, &AppDrawerModel::appAdded, Qt::QueuedConnection);
41+ connect(m_ual, &UalWrapper::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
42+ connect(m_ual, &UalWrapper::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
3643}
3744
3845int AppDrawerModel::rowCount(const QModelIndex &parent) const
@@ -53,10 +60,64 @@ QVariant AppDrawerModel::data(const QModelIndex &index, int role) const
5360 case RoleKeywords:
5461 return m_list.at(index.row())->keywords();
5562 case RoleUsage:
56− // FIXME: u-a-l needs to provide API for usage stats.
57− // don't forget to drop the qsrand() call in the ctor when dropping this.
58− return qrand();
63+ return m_list.at(index.row())->popularity();
5964 }
6065
6166 return QVariant();
6267}
68+
69+void AppDrawerModel::appAdded(const QString &appId)
70+{
71+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
72+ if (!info.valid) {
73+ qWarning() << "App added signal received but failed to get app info for app" << appId;
74+ return;
75+ }
76+
77+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
78+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
79+ item->setKeywords(info.keywords);
80+ item->setPopularity(info.popularity);
81+ m_list.append(item);
82+ endInsertRows();
83+}
84+
85+void AppDrawerModel::appRemoved(const QString &appId)
86+{
87+ int idx = -1;
88+ for (int i = 0; i < m_list.count(); i++) {
89+ if (m_list.at(i)->appId() == appId) {
90+ idx = i;
91+ break;
92+ }
93+ }
94+ if (idx < 0) {
95+ qWarning() << "App removed signal received but app doesn't seem to be in the drawer model";
96+ return;
97+ }
98+ beginRemoveRows(QModelIndex(), idx, idx);
99+ m_list.takeAt(idx)->deleteLater();
100+ endRemoveRows();
101+}
102+
103+void AppDrawerModel::appInfoChanged(const QString &appId)
104+{
105+ LauncherItem *item = nullptr;
106+ int idx = -1;
107+
108+ for(int i = 0; i < m_list.count(); i++) {
109+ if (m_list.at(i)->appId() == appId) {
110+ item = m_list.at(i);
111+ idx = i;
112+ break;
113+ }
114+ }
115+
116+ if (!item) {
117+ return;
118+ }
119+
120+ UalWrapper::AppInfo info = m_ual->getApplicationInfo(appId);
121+ item->setPopularity(info.popularity);
122+ Q_EMIT dataChanged(index(idx), index(idx), {AppDrawerModelInterface::RoleUsage});
123+}
plugins/Unity/Launcher/appdrawermodel.h+8
@@ -19,6 +19,8 @@
1919
2020#include "launcheritem.h"
2121
22+class UalWrapper;
23+
2224class AppDrawerModel: public AppDrawerModelInterface
2325{
2426 Q_OBJECT
@@ -28,6 +30,12 @@ public:
2830 int rowCount(const QModelIndex &parent) const override;
2931 QVariant data(const QModelIndex &index, int role) const override;
3032
33+private Q_SLOTS:
34+ void appAdded(const QString &appId);
35+ void appRemoved(const QString &appId);
36+ void appInfoChanged(const QString &appId);
37+
3138private:
3239 QList<LauncherItem*> m_list;
40+ UalWrapper *m_ual;
3341};
plugins/Unity/Launcher/dbusinterface.cpp+2
@@ -39,6 +39,8 @@ QString DBusInterface::introspect(const QString &path) const
3939 QString nodes;
4040
4141 // Add Refresh to introspect
42+ // TODO: Confirm this is still used anywhere and remove if not.
43+ // It used to be used in an upstart job when desktop fles changed.
4244 nodes = QStringLiteral("<interface name=\"com.canonical.Unity.Launcher\">"
4345 "<method name=\"Refresh\"/>"
4446 "</interface>");
plugins/Unity/Launcher/launcheritem.cpp+13
@@ -256,6 +256,19 @@ void LauncherItem::setSurfaces(const QList<QPair<QString, QString> > &surfaces)
256256 }
257257}
258258
259+uint LauncherItem::popularity() const
260+{
261+ return m_popularity;
262+}
263+
264+void LauncherItem::setPopularity(uint popularity)
265+{
266+ if (m_popularity != popularity) {
267+ m_popularity = popularity;
268+ Q_EMIT popularityChanged(popularity);
269+ }
270+}
271+
259272unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
260273{
261274 return m_quickList;
plugins/Unity/Launcher/launcheritem.h+3
@@ -39,6 +39,7 @@ public:
3939 QString name() const override;
4040 QString icon() const override;
4141 QStringList keywords() const override;
42+ uint popularity() const override;
4243 bool pinned() const override;
4344 bool running() const override;
4445 bool recent() const override;
@@ -55,6 +56,7 @@ private:
5556 void setName(const QString &name);
5657 void setIcon(const QString &icon);
5758 void setKeywords(const QStringList &keywords);
59+ void setPopularity(uint popularity);
5860 void setPinned(bool pinned);
5961 void setRunning(bool running);
6062 void setRecent(bool recent);
@@ -70,6 +72,7 @@ private:
7072 QString m_name;
7173 QString m_icon;
7274 QStringList m_keywords;
75+ uint m_popularity;
7376 bool m_pinned;
7477 bool m_running;
7578 bool m_recent;
plugins/Unity/Launcher/launchermodel.cpp+1
@@ -167,6 +167,7 @@ void LauncherModel::pin(const QString &appId, int index)
167167 appInfo.icon,
168168 this);
169169 item->setPinned(true);
170+ item->setPopularity(appInfo.popularity);
170171 m_list.insert(index, item);
171172 endInsertRows();
172173 }
plugins/Unity/Launcher/ualwrapper.cpp+12−2
@@ -24,7 +24,15 @@ using namespace ubuntu::app_launch;
2424UalWrapper::UalWrapper(QObject *parent):
2525 QObject(parent)
2626{
27−
27+ Registry::appAdded().connect([this](const std::shared_ptr<Application>&app) {
28+ Q_EMIT appAdded(QString::fromStdString(app->appId()));
29+ });
30+ Registry::appRemoved().connect([this](const AppID &appId) {
31+ Q_EMIT appRemoved(QString::fromStdString(appId));
32+ });
33+ Registry::appInfoUpdated().connect([this](const std::shared_ptr<Application>&app){
34+ Q_EMIT appInfoChanged(QString::fromStdString(app->appId()));
35+ });
2836}
2937
3038QStringList UalWrapper::installedApps()
@@ -39,7 +47,7 @@ QStringList UalWrapper::installedApps()
3947 }
4048 }
4149 } catch (const std::runtime_error &e) {
42− qWarning() << "ubuntu-all-launch threw an exception listing apps:" << e.what();
50+ qWarning() << "ubuntu-app-launch threw an exception listing apps:" << e.what();
4351 }
4452
4553 return appIds;
@@ -59,11 +67,13 @@ UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
5967 std::shared_ptr<Application> ualApp;
6068 ualApp = Application::create(ualAppId, Registry::getDefault());
6169
70+ info.appId = appId;
6271 info.name = QString::fromStdString(ualApp->info()->name());
6372 info.icon = QString::fromStdString(ualApp->info()->iconPath());
6473 for (const std::string &keyword : ualApp->info()->keywords().value()) {
6574 info.keywords << QString::fromStdString(keyword);
6675 }
76+ info.popularity = ualApp->info()->popularity();
6777 info.valid = true;
6878 } catch (const std::runtime_error &e) {
6979 qWarning() << "ubuntu-app-launch threw an exception getting app info for appId:" << appId << ":" << e.what();
plugins/Unity/Launcher/ualwrapper.h+6
@@ -21,10 +21,12 @@ class UalWrapper: public QObject
2121 Q_OBJECT
2222public:
2323 struct AppInfo {
24+ QString appId;
2425 bool valid = false;
2526 QString name;
2627 QString icon;
2728 QStringList keywords;
29+ uint popularity = 0;
2830 };
2931
3032 UalWrapper(QObject* parent = nullptr);
@@ -32,4 +34,8 @@ public:
3234 static QStringList installedApps();
3335 static AppInfo getApplicationInfo(const QString &appId);
3436
37+Q_SIGNALS:
38+ void appAdded(const QString &appId);
39+ void appRemoved(const QString &appId);
40+ void appInfoChanged(const QString &appId);
3541};
plugins/Unity/Session/dbusunitysessionservice.cpp+5−11
@@ -36,6 +36,7 @@
3636
3737#define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1")
3838#define LOGIN1_PATH QStringLiteral("/org/freedesktop/login1")
39+#define LOGIN1_SESSION_ROOT QStringLiteral("/org/freedesktop/login1/session/")
3940#define LOGIN1_IFACE QStringLiteral("org.freedesktop.login1.Manager")
4041#define LOGIN1_SESSION_IFACE QStringLiteral("org.freedesktop.login1.Session")
4142
@@ -58,16 +59,9 @@ public:
5859
5960 void init()
6061 {
61− // get our logind session path
62− QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE,
63− LOGIN1_PATH,
64− LOGIN1_IFACE,
65− QStringLiteral("GetSessionByPID"));
66− msg << (quint32) getpid();
67−
68− QDBusReply<QDBusObjectPath> reply = QDBusConnection::SM_BUSNAME().call(msg);
69− if (reply.isValid()) {
70− logindSessionPath = reply.value().path();
62+ QString sessionID = QString::fromLocal8Bit(qgetenv("XDG_SESSION_ID"));
63+ if (!sessionID.isEmpty()) {
64+ logindSessionPath = LOGIN1_SESSION_ROOT + sessionID;
7165
7266 // start watching the Active property
7367 QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, logindSessionPath, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("PropertiesChanged"),
@@ -79,7 +73,7 @@ public:
7973 QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, QStringLiteral("PrepareForSleep"),
8074 this, SLOT(onResuming(bool)));
8175 } else {
82− qWarning() << "Failed to get logind session path" << reply.error().message();
76+ qWarning() << "Failed to get logind session: XDG_SESSION_ID is not set";
8377 }
8478 }
8579
tests/mocks/Unity/Launcher/MockLauncherItem.cpp+13
@@ -72,6 +72,11 @@ QStringList MockLauncherItem::keywords() const
7272 return m_keywords;
7373}
7474
75+uint MockLauncherItem::popularity() const
76+{
77+ return m_popularity;
78+}
79+
7580bool MockLauncherItem::pinned() const
7681{
7782 return m_pinned;
@@ -201,6 +206,14 @@ void MockLauncherItem::setSurfaceCount(int surfaceCount)
201206 }
202207}
203208
209+void MockLauncherItem::setPopularity(uint popularity)
210+{
211+ if (m_popularity != popularity) {
212+ m_popularity = popularity;
213+ Q_EMIT popularityChanged(m_popularity);
214+ }
215+}
216+
204217unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
205218{
206219 return m_quickList;
tests/mocks/Unity/Launcher/MockLauncherItem.h+3
@@ -40,6 +40,7 @@ public:
4040 QString name() const override;
4141 QString icon() const override;
4242 QStringList keywords() const override;
43+ uint popularity() const override;
4344
4445 bool pinned() const override;
4546 bool running() const override;
@@ -55,6 +56,7 @@ public:
5556
5657private:
5758 void setKeywords(const QStringList &keywords);
59+ void setPopularity(uint popularity);
5860 void setPinned(bool pinned);
5961 void setRunning(bool running);
6062 void setRecent(bool recent);
@@ -70,6 +72,7 @@ private:
7072 QString m_name;
7173 QString m_icon;
7274 QStringList m_keywords;
75+ uint m_popularity;
7376 bool m_pinned;
7477 bool m_running;
7578 bool m_recent;
tests/plugins/Ubuntu/CMakeLists.txt+1−1
@@ -1 +1 @@
1−#add_subdirectory(Gestures) #FIXME broken with qt 5.9
1+add_subdirectory(Gestures)
tests/plugins/Ubuntu/Gestures/GestureTest.cpp+10−1
@@ -17,6 +17,7 @@
1717#include "GestureTest.h"
1818
1919#include <qpa/qwindowsysteminterface.h>
20+#include <private/qquickanimatorcontroller_p.h>
2021#include <private/qquickwindow_p.h>
2122#include <QQmlEngine>
2223#include <QQuickView>
@@ -108,7 +109,15 @@ void GestureTest::sendTouch(qint64 timestamp, int id, QPointF pos,
108109 QCoreApplication::sendEvent(m_view, &touchEvent);
109110
110111 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
111− windowPrivate->flushDelayedTouchEvent();
112+ if (windowPrivate->delayedTouch) {
113+ windowPrivate->deliverDelayedTouchEvent();
114+
115+ // Touch events which constantly start animations (such as a behavior tracking
116+ // the mouse point) need animations to start.
117+ QQmlAnimationTimer *ut = QQmlAnimationTimer::instance();
118+ if (ut && ut->hasStartAnimationPending())
119+ ut->startAnimations();
120+ }
112121}
113122
114123void GestureTest::passTime(qint64 timeSpanMs)
tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+10−1
@@ -19,6 +19,7 @@
1919#include <QQmlEngine>
2020#include <QQuickView>
2121#include <QSharedPointer>
22+#include <private/qquickanimatorcontroller_p.h>
2223#include <private/qquickwindow_p.h>
2324
2425// C++ std lib
@@ -191,7 +192,15 @@ void tst_TouchGate::holdsEventsUntilGainsOwnership()
191192 if (!ownershipAfterTouchEnd) {
192193 touchRegistry->removeCandidateOwnerForTouch(0, candidateItem);
193194 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(testItem->window());
194− wp->flushDelayedTouchEvent();
195+ if (wp->delayedTouch) {
196+ wp->deliverDelayedTouchEvent();
197+
198+ // Touch events which constantly start animations (such as a behavior tracking
199+ // the mouse point) need animations to start.
200+ QQmlAnimationTimer *ut = QQmlAnimationTimer::instance();
201+ if (ut && ut->hasStartAnimationPending())
202+ ut->startAnimations();
203+ }
195204 // TouchGate should now open its flood gates and let testItem get all
196205 // events from touch 0 produced so far
197206 QCOMPARE(testItem->touchEventsReceived.count(), 2);
tests/plugins/Unity/Launcher/CMakeLists.txt+34
@@ -61,6 +61,40 @@ add_unity8_unittest(LauncherModel dbus-test-runner
6161 --wait-for org.freedesktop.Accounts
6262)
6363
64+### AppDrawerModelTest
65+add_executable(appdrawermodeltestExec
66+ appdrawermodeltest.cpp
67+ ualwrapper.cpp
68+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/appdrawermodel.cpp
69+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h
70+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
71+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
72+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
73+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
74+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
75+ )
76+target_link_libraries(appdrawermodeltestExec
77+ unity8-private
78+ ${GSETTINGS_QT_LDFLAGS}
79+ ${GLIB_LIBRARIES}
80+ ${UAL_LIBRARIES}
81+ )
82+add_dependencies(appdrawermodeltestExec mock-server)
83+qt5_use_modules(appdrawermodeltestExec Test Core DBus Xml Gui Qml)
84+install(TARGETS appdrawermodeltestExec
85+ DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/plugins/Unity/Launcher"
86+ )
87+
88+add_unity8_unittest(AppDrawerModel dbus-test-runner
89+ ENVIRONMENT "APPDIR=${CMAKE_CURRENT_BINARY_DIR}/applications"
90+ ARG_PREFIX "--parameter"
91+ ARGS
92+ --task $<TARGET_FILE:mock-server>
93+ --ignore-return
94+ --task $<TARGET_FILE:appdrawermodeltestExec>
95+ --wait-for org.freedesktop.Accounts
96+)
97+
6498# copy sample application files into build directory for shadow builds
6599file(COPY applications
66100 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
tests/plugins/Unity/Launcher/appdrawermodeltest.cppnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright 2017 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 "ualwrapper.h"
18+#include "appdrawermodel.h"
19+
20+#include <QtTest>
21+
22+class AppDrawerModelTest : public QObject
23+{
24+ Q_OBJECT
25+
26+private:
27+ AppDrawerModel *appDrawerModel;
28+
29+private Q_SLOTS:
30+
31+ void initTestCase() {
32+ UalWrapper::s_list << QStringLiteral("app1") << QStringLiteral("app2");
33+ appDrawerModel = new AppDrawerModel(this);
34+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
35+ }
36+
37+ void testUalAppAddedRemoved() {
38+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
39+
40+ UalWrapper::instance()->addMockApp("app3");
41+ qApp->processEvents(); // ualwrapper is connected Queued
42+
43+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 3);
44+
45+ UalWrapper::instance()->removeMockApp("app3");
46+ qApp->processEvents();
47+
48+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
49+ }
50+};
51+
52+QTEST_GUILESS_MAIN(AppDrawerModelTest)
53+#include "appdrawermodeltest.moc"
tests/plugins/Unity/Launcher/ualwrapper.cppnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (C) 2017 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+#include "ualwrapper.h"
18+#include <QDebug>
19+
20+UalWrapper* UalWrapper::s_instance = nullptr;
21+QStringList UalWrapper::s_list;
22+
23+UalWrapper::UalWrapper(QObject *parent): QObject(parent)
24+{
25+ s_instance = this;
26+}
27+
28+UalWrapper* UalWrapper::instance()
29+{
30+ return s_instance;
31+}
32+
33+QStringList UalWrapper::installedApps()
34+{
35+ return s_list;
36+}
37+
38+UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
39+{
40+ AppInfo info;
41+ info.appId = appId;
42+ info.name = "App_" + appId;
43+ info.icon = "/dummy/icon/path/" + appId + ".png";
44+ info.keywords << QStringLiteral("keyword1") << QStringLiteral("keyword2");
45+ info.popularity = 1;
46+ info.valid = true;
47+ return info;
48+}
49+
50+void UalWrapper::addMockApp(const QString &appId)
51+{
52+ s_list.append(appId);
53+ Q_EMIT appAdded(appId);
54+}
55+
56+void UalWrapper::removeMockApp(const QString &appId)
57+{
58+ s_list.removeAll(appId);
59+ Q_EMIT appRemoved(appId);
60+}
tests/plugins/Unity/Launcher/ualwrapper.hnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2017 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+#include <QObject>
18+
19+// This is a mock implementation
20+
21+class UalWrapper: public QObject
22+{
23+ Q_OBJECT
24+public:
25+ struct AppInfo {
26+ QString appId;
27+ bool valid = false;
28+ QString name;
29+ QString icon;
30+ QStringList keywords;
31+ uint popularity = 0;
32+ };
33+
34+ UalWrapper(QObject* parent = nullptr);
35+
36+ static QStringList installedApps();
37+ static AppInfo getApplicationInfo(const QString &appId);
38+
39+ // for testing:
40+ static UalWrapper* instance();
41+ void addMockApp(const QString &appId);
42+ void removeMockApp(const QString &appId);
43+
44+Q_SIGNALS:
45+ void appAdded(const QString &appId);
46+ void appRemoved(const QString &appId);
47+ void appInfoChanged(const QString &appId);
48+
49+
50+private:
51+ static QStringList s_list;
52+ static UalWrapper *s_instance;
53+
54+ friend class AppDrawerModelTest;
55+};
tests/plugins/Unity/Session/CMakeLists.txt+1
@@ -60,6 +60,7 @@ install(TARGETS sessionbackendtestExec
6060
6161add_unity8_unittest(SessionBackend dbus-test-runner
6262 ENVIRONMENT LD_PRELOAD=$<TARGET_FILE:SessionBackendTestPreload>
63+ XDG_SESSION_ID=testing
6364 XDG_SESSION_PATH=/session
6465 ARG_PREFIX "--parameter"
6566 ARGS
tests/plugins/Unity/Session/LogindServer.cpp−5
@@ -22,11 +22,6 @@ LogindServer::LogindServer(QObject *parent)
2222{
2323}
2424
25−QDBusObjectPath LogindServer::GetSessionByPID(quint32)
26−{
27− return QDBusObjectPath("/logindsession");
28−}
29−
3025void LogindServer::Reboot(bool interactive)
3126{
3227 Q_EMIT RebootCalled(interactive);
tests/plugins/Unity/Session/LogindServer.h−1
@@ -30,7 +30,6 @@ public:
3030 explicit LogindServer(QObject *parent = nullptr);
3131
3232public Q_SLOTS:
33− QDBusObjectPath GetSessionByPID(quint32 pid);
3433 void Reboot(bool interactive);
3534 void PowerOff(bool interactive);
3635
tests/plugins/Unity/Session/interfaces.xml−4
@@ -3,10 +3,6 @@
33 <method name="Lock" />
44 </interface>
55 <interface name="org.freedesktop.login1.Manager">
6− <method name="GetSessionByPID">
7− <arg name="pid" type="u" direction="in" />
8− <arg name="session" type="o" direction="out" />
9− </method>
106 <method name="Reboot">
117 <arg name="interactive" type="b" direction="in" />
128 </method>
tests/plugins/Unity/Session/server.cpp+1−1
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
3737 auto connection = QDBusConnection::sessionBus();
3838 if (!connection.registerObject("/org/freedesktop/login1", logind))
3939 return 1;
40− if (!connection.registerObject("/logindsession", logind))
40+ if (!connection.registerObject("/org/freedesktop/login1/session/testing", logind))
4141 return 1;
4242 if (!connection.registerService("org.freedesktop.login1"))
4343 return 1;
tests/plugins/Unity/Session/sessionbackendtest.cpp+5−3
@@ -103,8 +103,8 @@ private Q_SLOTS:
103103 QCoreApplication::processEvents(); // to let the services register on DBus
104104
105105 QDBusInterface login1Interface("org.freedesktop.login1",
106− "/logindsession",
107− "org.freedesktop.login1.Manager");
106+ "/org/freedesktop/login1/session/testing",
107+ "org.freedesktop.login1.Manager");
108108 QSignalSpy spy(&login1Interface, signal.toUtf8().data());
109109
110110 QDBusInterface dbusGnomeSessionWrapper("org.gnome.SessionManager",
@@ -225,7 +225,9 @@ private Q_SLOTS:
225225 DBusUnitySessionService dbusUnitySessionService;
226226 QCoreApplication::processEvents(); // to let the service register on DBus
227227
228− QDBusInterface iface("org.freedesktop.login1", "/logindsession", "org.freedesktop.login1.Session");
228+ QDBusInterface iface("org.freedesktop.login1",
229+ "/org/freedesktop/login1/session/testing",
230+ "org.freedesktop.login1.Session");
229231 QVERIFY(iface.isValid());
230232
231233 QSignalSpy spy(&dbusUnitySessionService, SIGNAL(Unlocked()));
tests/qmltests/CMakeLists.txt+1−1
@@ -1,5 +1,5 @@
11
2−#add_subdirectory(Components) #FIXME broken with qt 5.9
2+add_subdirectory(Components)
33
44add_unity8_qmltest(. OrientedShell)
55add_unity8_qmltest(. DisabledScreenNotice)
tests/qmltests/Components/tst_DragHandle.cpp+19−2
@@ -20,6 +20,7 @@
2020#include <qpa/qwindowsysteminterface.h>
2121#include <QtQuick/QQuickView>
2222#include <QtQml/QQmlEngine>
23+#include <private/qquickanimatorcontroller_p.h>
2324#include <private/qquickwindow_p.h>
2425#include <UbuntuGestures/private/ucswipearea_p_p.h>
2526
@@ -179,7 +180,15 @@ void tst_DragHandle::flickAndHold(QQuickItem *dragHandle,
179180 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
180181
181182 QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(m_view);
182− windowPrivate->flushDelayedTouchEvent();
183+ if (windowPrivate->delayedTouch) {
184+ windowPrivate->deliverDelayedTouchEvent();
185+
186+ // Touch events which constantly start animations (such as a behavior tracking
187+ // the mouse point) need animations to start.
188+ QQmlAnimationTimer *ut = QQmlAnimationTimer::instance();
189+ if (ut && ut->hasStartAnimationPending())
190+ ut->startAnimations();
191+ }
183192}
184193
185194void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal distance,
@@ -194,7 +203,15 @@ void tst_DragHandle::drag(QPointF &touchPoint, const QPointF& direction, qreal d
194203 m_fakeTimeSource->m_msecsSinceReference += timeStep;
195204 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
196205
197− windowPrivate->flushDelayedTouchEvent();
206+ if (windowPrivate->delayedTouch) {
207+ windowPrivate->deliverDelayedTouchEvent();
208+
209+ // Touch events which constantly start animations (such as a behavior tracking
210+ // the mouse point) need animations to start.
211+ QQmlAnimationTimer *ut = QQmlAnimationTimer::instance();
212+ if (ut && ut->hasStartAnimationPending())
213+ ut->startAnimations();
214+ }
198215 }
199216}
200217
tests/utils/CMakeLists.txt+1−1
@@ -1 +1 @@
1−#add_subdirectory(modules) #FIXME broken with qt 5.9
1+add_subdirectory(modules)
tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp+10−1
@@ -15,6 +15,7 @@
1515 */
1616
1717#include "TouchEventSequenceWrapper.h"
18+#include <private/qquickanimatorcontroller_p.h>
1819#include <private/qquickwindow_p.h>
1920
2021TouchEventSequenceWrapper::TouchEventSequenceWrapper(QTest::QTouchEventSequence eventSequence, QQuickItem *item)
@@ -34,7 +35,15 @@ void TouchEventSequenceWrapper::commit(bool processEvents)
3435
3536 if (window) {
3637 QQuickWindowPrivate *wp = QQuickWindowPrivate::get(window);
37− wp->flushDelayedTouchEvent();
38+ if (wp->delayedTouch) {
39+ wp->deliverDelayedTouchEvent();
40+
41+ // Touch events which constantly start animations (such as a behavior tracking
42+ // the mouse point) need animations to start.
43+ QQmlAnimationTimer *ut = QQmlAnimationTimer::instance();
44+ if (ut && ut->hasStartAnimationPending())
45+ ut->startAnimations();
46+ }
3847 }
3948}
4049