.bazaar/Makefiledeleted−6
@@ -1,6 +0,0 @@
2− mkdir -p ~/.bazaar/plugins
3− cp plugins/* ~/.bazaar/plugins
6− rm ~/.bazaar/plugins/makecheck_unity_phablet.py*
.bazaar/plugins/makecheck_unity_phablet.pydeleted−51
@@ -1,51 +0,0 @@
2−# Copyright 2013, 2014 Canonical Ltd.
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.
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.
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/>.
18−from bzrlib import branch
19−from bzrlib.urlutils import local_path_from_url
22−def execute_makecheck(
23− local_branch, master_branch, old_revision_number, old_revision_id,
24− future_revision_number, future_revision_id, tree_delta, future_tree):
25− if not master_branch.basis_tree().has_filename("qml/Shell.qml"):
28− os.chdir(local_path_from_url(master_branch.base))
30− print "Executing 'make -C builddir test'.."
31− os.environ['CTEST_OUTPUT_ON_FAILURE'] = "1"
32− if (subprocess.call("make -C builddir test", shell=True) != 0):
34− print("\n\n*** Warning ***\n\n"
35− "Basic tests failed. This commit will not pass continuous "
38− branch = local_branch or master_branch
39− revision = branch.repository.get_revision(future_revision_id)
40− msg_file = open('message.txt', 'w')
41− msg_file.write(revision.message)
44− print("\n\nSaved commit message to $SRC_DIR/message.txt.")
45− print("You can uncommit this revision, fix the tests and reuse your "
46− "message running:\n\nbzr commit -F message.txt\n\n")
47− elif os.path.isfile("message.txt"):
48− os.remove("message.txt")
50−branch.Branch.hooks.install_named_hook(
51− 'pre_commit', execute_makecheck, 'make check pre-commit')
.bzr-builddeb/default.confdeleted−2
@@ -1,7 +0,0 @@
3−# QtCreator project files
5−# Eclipse project files
.crossbuilder/post_deploynew file+1
@@ -2,8 +2,15 @@
3# QtCreator project files
3# QtCreator project files
5# Eclipse project files
7# Eclipse project files
9/.pydevproject
11/.pydevproject
12+# KDevelop project Files
@@ -40,6 +40,19 @@ if(cmake_build_type_lower MATCHES coverage)
40 ENABLE_COVERAGE_REPORT(TARGETS ${SHELL_APP} FILTER /usr/include ${CMAKE_SOURCE_DIR}/tests/* ${CMAKE_BINARY_DIR}/*)
40 ENABLE_COVERAGE_REPORT(TARGETS ${SHELL_APP} FILTER /usr/include ${CMAKE_SOURCE_DIR}/tests/* ${CMAKE_BINARY_DIR}/*)
43+find_package (ECM 1.7.0 QUIET NO_MODULE)
45+ # Provides us with -DECM_ENABLE_SANITIZERS='X'
46+ # Where X can be address, thread, memory, leak, undefined
47+ include("${ECM_MODULE_DIR}/ECMEnableSanitizers.cmake")
50+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
51+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0")
52+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override" )
43# Make sure we have all the needed symbols
56# Make sure we have all the needed symbols
44set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
57set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
45set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,defs")
58set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,defs")
@@ -49,21 +62,31 @@ add_custom_target(cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2
49 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
62 ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests)
51include(FindPkgConfig)
64include(FindPkgConfig)
52−find_package(Qt5Core 5.4 REQUIRED)
65+find_package(Qt5Core 5.6 REQUIRED)
53−find_package(Qt5Qml 5.4 REQUIRED)
66+find_package(Qt5Qml 5.6 REQUIRED)
54−find_package(Qt5Quick 5.4 REQUIRED)
67+find_package(Qt5Quick 5.6 REQUIRED)
55−find_package(Qt5Gui 5.4 REQUIRED)
68+find_package(Qt5Gui 5.6 REQUIRED)
56−find_package(Qt5DBus 5.4 REQUIRED)
69+find_package(Qt5DBus 5.6 REQUIRED)
57−find_package(Qt5Concurrent 5.4 REQUIRED)
70+find_package(Qt5Concurrent 5.6 REQUIRED)
58−find_package(Qt5Sql 5.4 REQUIRED)
71+find_package(Qt5Sql 5.6 REQUIRED)
59−
72+find_package(Qt5Test 5.6 REQUIRED)
73+find_package(Qt5Svg 5.6 REQUIRED)
74+find_package(Qt5Network 5.6 REQUIRED)
75+find_package(Qt5Xml 5.6 REQUIRED)
60−pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=17)
77+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=27)
61pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
78pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
62pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
79pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
63pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
80pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
81+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=13)
64pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
82pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
65−
83+pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
84+pkg_check_modules(UAL REQUIRED ubuntu-app-launch-2)
66pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
85pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
86+pkg_check_modules(QTDBUSTEST REQUIRED
68### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
91### Check UbuntuGestures private headers. No pkg-config (.pc) file is provided for them
69find_path(UBUNTUGESTUREPRIV
92find_path(UBUNTUGESTUREPRIV
@@ -125,9 +148,8 @@ include(autopilot)
125declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
148declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
127set(SHELL_APP unity8)
150set(SHELL_APP unity8)
128−set(DASH_APP unity8-dash)
129−set(SCOPE_TOOL unity-scope-tool)
130set(INDICATORS_CLIENT_APP indicators-client)
151set(INDICATORS_CLIENT_APP indicators-client)
152+set(GREETER_APP unity8-greeter)
131set(MOCK_INDICATOR_SERVICE_APP unity-mock-indicator-service)
153set(MOCK_INDICATOR_SERVICE_APP unity-mock-indicator-service)
133include_directories(
155include_directories(
@@ -15,23 +15,17 @@ download source
15 $ bzr branch lp:unity8 ~/unity8/trunk
15 $ bzr branch lp:unity8 ~/unity8/trunk
16 $ cd ~/unity8/trunk
16 $ cd ~/unity8/trunk
18−install dependencies
18+install dependencies and build Unity 8
19--------------------
19--------------------
20−If its your first time, install build dependencies
22$ cd ~/unity8/trunk
21$ cd ~/unity8/trunk
23−$ ./build.sh --setup
22+$ ./build.sh
26− - install the required dependencies to build, as well as run on the desktop
27− - it should also install unity-scope-home and unity-lens-application which
28− are technically "recommends", not strict dependencies
30−build Unity 8
24+ If its your first time, this will install the required dependencies to build and
31−-------------
25+ build it.
33−$ cd ~/unity8/trunk
27+ You might want to also install unity-scope-home and unity-scope-click which
34−$ ./build.sh
28+ are technically "recommends", not strict dependencies
36You may also rebuild with the -c for clean, which just deletes the build
30You may also rebuild with the -c for clean, which just deletes the build
@@ -43,13 +37,15 @@ Running Unity 8 on your desktop
43run the Unity 8 shell
37run the Unity 8 shell
44---------------------
38---------------------
45$ cd ~/unity8/trunk
39$ cd ~/unity8/trunk
46−$ ./run.sh
40+$ cd builddir
48−Options can be passed to test the lock screen
42+Each component of unity8 can be ran independently for development and testing
49−$ ./run.sh -p OR -k
43+For example:
51−-p is for pin lock, for which the default prompt answer is "1234"
48+Check out the tests/qmltests/ directory for a list of things that can be ran.
52−-k is for keylock passphrase, for which the default prompt answer is "password"
@@ -70,50 +66,15 @@ Notes
71Running Unity 8 on devices
67Running Unity 8 on devices
72==========================
68==========================
73−- Ubuntu Touch builds are currently only available in 14.04 flavour
74−- supported hardware should match one of those listed here
75− https://wiki.ubuntu.com/Touch/Devices#Running_fine
76−- follow the Ubuntu Touch install instructions for your chosen device
77− https://wiki.ubuntu.com/Touch/Install
78−- make sure your device is connected to a network
79−- also make sure you have your SSH key in ~/.ssh/id_rsa.pub (or install one
80− on the device yourself)
83−$ ./run_on_device.sh --setup
85− - install your public SSH key on the device
86− - install the needed dependencies
88−$ ./run_on_device.sh
70+Running unity8 on a device should be done using crossbuilder.
90− - rsync the code to the device
72+* https://launchpad.net/crossbuilder and
91− - build on the device
73+* https://wiki.ubuntu.com/Touch/Crossbuilder
92− - replace the running shell
74+for more details on crossbuilder.
94−Options can be passed to test the lock screen
95−$ ./run_on_device.sh -p OR -k
97−-p is for pin lock, for which the default prompt answer is "1234"
98−-k is for keylock passphrase, for which the default prompt answer is "password"
102−- using adb over TCP has some advantages, Google will be of help here
103− - NOTE: this is not yet available for flipped images
104− - TL;DR: `adb tcpip 5555; adb connect $your_device_ip`
105− - you can persist the above via `adb shell setprop persist.adb.tcp.port 5555`
106− - it's unsafe - anyone can connect to your device
107− - with TCP the Nexus 10 doesn't drop the adb connection when locking
109−- exporting ANDROID_SERIAL=$your_device_serial or
110− ANDROID_SERIAL=$your_device_ip:5555 will make adb not complain about
112−- you can export TARGET_IP=$your_device_ip TARGET_SSH_PORT=22 for run_on_device.sh
113− to not use adb forwarding - useful if you use multiple devices
114−- using Ninja (package ninja-build - run_on_device.sh -s installs this now)
115− will improve build times (especially in the nothing-to-build case)
76+unity8 will automatically restart on the phone once deployment
77+has finished due to post-build-steps set up in this repository.
118Coding guidelines
79Coding guidelines
119=================
80=================
@@ -201,3 +162,27 @@ $ PYTHONPATH=../tests/autopilot autopilot3 run unity8.some.very.long.test.name
201or run them all with
162or run them all with
203$ PYTHONPATH=../tests/autopilot autopilot3 run unity8
164$ PYTHONPATH=../tests/autopilot autopilot3 run unity8
169+Unity8 heavily uses Qt and with that Qt debugging techniques mostly apply in the
170+same fashion. There are, however, some additional unity8-specific notes:
172+* Enable/disable Qt scenegraph visualizer on the fly:
174+ $ qdbus com.canonical.Unity8.Debugging /com/canonical/Unity8/Debugging SetSceneGraphVisualizer <mode>
176+ This is equivalent to exporting QSG_VISUALIZE=<mode> before running unity8, except it does it on the
179+* Toggle slow animations on the fly:
181+ $ qdbus com.canonical.Unity8.Debugging /com/canonical/Unity8/Debugging SetSlowAnimations <true|false>
183+* Change logging filter rules on the fly:
185+ $ qdbus com.canonical.Unity8.Debugging /com/canonical/Unity8/Debugging SetLoggingFilterRules <filter>
187+ This is equivalent to exporting QT_LOGGING_RULES or defining them in QT_LOGGING_CONF, except it does
@@ -0,0 +1,2 @@
1+@Library('ubports-build-tools') _
2+buildAndProvideDebianPackage()
@@ -0,0 +1,31 @@
3+Lomiri is the operating environment for everywhere. It is able to span the gaps between touch, mouse, and keyboard; between phones, tablets, and workstations; and look good doing it.
5+If you want to contribute to Lomiri on Ubuntu Touch, you've come to the right place. If you want to package Lomiri for other operating systems, you'll be better served by the main branch on the repository that we're migrating to: https://gitlab.com/ubports/core/lomiri
7+Lomiri has been renamed from Unity8. Most of the software on-device in Ubuntu Touch based on Ubuntu 16.04 is still called `unity8`.
9+## Where to report issues
11+Issues related to the version of Lomiri that currently runs on Ubuntu Touch devices may still be reported on this repository. We will move these reports to the GitLab repository as part of our final migration.
13+## Developing Lomiri on Ubuntu Touch
15+This repository contains the code for Lomiri currently running on Ubuntu Touch. If you would like to modify this version of Lomiri, follow the steps below. If you would like to modify Lomiri in another operating system, check out our new repository: https://gitlab.com/ubports/core/lomiri
17+Lomiri can be built and its test suite run using [`clickable`](https://clickable-ut.dev). This is a convenient method to try out most graphical changes to Lomiri without an annoying redeployment process. If you wish to test your changes on your device or make changes that are more difficult to test without real hardware, check out [Making changes and testing locally on the UBports documentation](https://docs.ubports.com/en/latest/systemdev/testing-locally.html). If not, read on.
19+Before you start, [install Clickable](https://clickable-ut.dev/en/latest/install.html).
21+Now, clone this repository to your computer: `git clone https://github.com/ubports/unity8.git`
23+Move into this directory: `cd unity8`
25+Now you can use the full suite of tools provided by this repository's [clickable.yaml](clickable.yaml). For example:
27+* `clickable ide qtcreator` will open QtCreator with this repository open as a project. You can edit and build the project this way, but running the tests will be a bit difficult.
28+* `clickable build --libs --verbose` will build Lomiri in the same environment as it would receive in Ubuntu Touch.
29+* `clickable test --libs` will run the entire Lomiri test suite. This test suite includes graphical tests (which are run on a virtual, invisible desktop) and non-graphical unit tests. These tests make sure Lomiri functions as prescribed and prevents new bugs from being added. You should run them before you create a PR on this repository. This command takes about 7 minutes on an Intel i7-8550U, so plan your time accordingly and use the next two options to reduce the number of times you need to run the whole test suite...
30+* `clickable ide 'cd build/x86_64-linux-gnu/unity8/ && make tryShell'` and similar commands that replace the `Shell` with another test target defined in [tests/qmltests/CMakeLists.txt](tests/qmltests/CMakeLists.txt) allow trying out some Lomiri components in a mock environment. You can use this to try out your changes to Lomiri as you develop.
31+* `clickable ide 'cd build/x86_64-linux-gnu/unity8/ && make xvfbtestShell'` and similar commands that replace the `Shell` with another test target defined in [tests/qmltests/CMakeLists.txt](tests/qmltests/CMakeLists.txt) allow running a single TestCase. You can remove the `xvfb` part of the make target to run the test case graphically, which might help you see what is causing the test to fail.
@@ -1,5 +1,21 @@
4+# Copyright (C) 2017 Canonical Ltd
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License version 3 as
8+# published by the Free Software Foundation.
10+# This program is distributed in the hope that it will be useful,
11+# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+# GNU General Public License for more details.
15+# You should have received a copy of the GNU General Public License
16+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3SETUP=false
19SETUP=false
4CLEAN=false
20CLEAN=false
5NUM_JOBS=$(( `grep -c ^processor /proc/cpuinfo` + 1 ))
21NUM_JOBS=$(( `grep -c ^processor /proc/cpuinfo` + 1 ))
@@ -9,7 +25,6 @@ usage() {
9 echo "usage: build [OPTIONS] [BUILD_TYPE]\n" >&2
25 echo "usage: build [OPTIONS] [BUILD_TYPE]\n" >&2
10 echo "Script to build the shell. If BUILD_TYPE is not specified, it defaults to \"debug\".\n" >&2
26 echo "Script to build the shell. If BUILD_TYPE is not specified, it defaults to \"debug\".\n" >&2
11 echo "OPTIONS:" >&2
27 echo "OPTIONS:" >&2
12− echo " -s, --setup Setup the build environment and branch Unity" >&2
13 echo " -c, --clean Clean the build tree before building" >&2
28 echo " -c, --clean Clean the build tree before building" >&2
@@ -22,7 +37,6 @@ eval set -- "$ARGS"
22while [ $# -gt 0 ]
37while [ $# -gt 0 ]
24 case "$1" in
39 case "$1" in
25− -s|--setup) SETUP=true;;
26 -c|--clean) CLEAN=true;;
40 -c|--clean) CLEAN=true;;
27 -h|--help) usage;;
41 -h|--help) usage;;
28 --) shift;break;;
42 --) shift;break;;
@@ -35,31 +49,6 @@ done
35BUILD_TYPE="debug"
49BUILD_TYPE="debug"
36[ $# -eq 1 ] && BUILD_TYPE="$1"
50[ $# -eq 1 ] && BUILD_TYPE="$1"
38−install_dependencies() {
39− sudo apt-get update || exit 4
40− echo "Installing Unity 8 dependencies.."
41− sudo apt-get install devscripts \
43− gsettings-desktop-schemas \
44− gsettings-ubuntu-schemas \
47− qml-module-qtquick-layouts \
48− qml-module-qtquick-xmllistmodel \
49− qtdeclarative5-gsettings1.0 \
50− qtdeclarative5-ubuntu-ui-toolkit-plugin \
51− qtdeclarative5-ubuntu-settings-components \
52− qtdeclarative5-ubuntu-telephony0.1 \
53− qtdeclarative5-ubuntu-thumbnailer0.1 \
54− qtdeclarative5-unity-notifications-plugin \
55− qml-module-ubuntu-connectivity \
56− ubuntu-mobile-icons \
57− ubuntu-system-settings \
58− unity-plugin-scopes \
63mk_build_deps() {
52mk_build_deps() {
64 if [ ! -f control -o $CODE_DIR/debian/control -nt control ]; then
53 if [ ! -f control -o $CODE_DIR/debian/control -nt control ]; then
65 sed 's/\:native//g' $CODE_DIR/debian/control > control
54 sed 's/\:native//g' $CODE_DIR/debian/control > control
@@ -85,13 +74,9 @@ else
85 BUILD_COMMAND="make -j$NUM_JOBS"
74 BUILD_COMMAND="make -j$NUM_JOBS"
91− if $CLEAN; then rm -rf builddir; fi
77+if $CLEAN; then rm -rf builddir; fi
92− mkdir -p builddir
78+mkdir -p builddir
93− cd builddir
79+cd builddir
94− mk_build_deps
80+mk_build_deps
95− cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE $CODE_DIR ${GENERATOR} || exit 6
81+cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE $CODE_DIR ${GENERATOR} || exit 6
96− ${BUILD_COMMAND} || exit 7
82+${BUILD_COMMAND} || exit 7
clickable.yamlnew file+153
@@ -0,0 +1,153 @@
1+clickable_minimum_required: '7'
3+build: echo Run \'clickable build --libs --verbose\' to build && false
9+ test: make xvfballtests -j${NUM_PROCS}
21+ - gsettings-ubuntu-schemas
22+ - libandroid-properties-dev
23+ - libconnectivity-qt1-dev
30+ - libgnome-desktop-3-12
31+ - libgnome-desktop-3-dev
32+ - libgsettings-qt-dev
34+ - liblightdm-qt5-3-dev
40+ - libqt5xmlpatterns5-dev
43+ - libsystemsettings-dev
44+ - libubuntu-app-launch2-dev
45+ - libubuntu-download-manager-common-dev
46+ - libubuntugestures5-dev
47+ - libubuntugestures5-private-dev
51+ - libusermetricsoutput1-dev
57+ - python3-setuptools:native
58+ - qml-module-qt-labs-folderlistmodel
59+ - qml-module-qt-labs-settings
60+ - qml-module-qtmultimedia
61+ - qml-module-qtqml-statemachine
62+ - qml-module-qtquick-layouts
63+ - qml-module-qtquick-xmllistmodel
64+ - qml-module-qtquick2
65+ - qml-module-qtsysteminfo
67+ - qml-module-ubuntu-components
68+ - qml-module-ubuntu-layouts
69+ - qml-module-ubuntu-settings-components
70+ - qml-module-ubuntu-test
73+ - qtbase5-private-dev
76+ - qtdeclarative5-dev-tools
77+ - qtdeclarative5-private-dev
78+ - qtdeclarative5-ubuntu-content1
79+ - ttf-ubuntu-font-family
93+ - gsettings-ubuntu-schemas
94+ - libandroid-properties-dev
95+ - libconnectivity-qt1-dev
102+ - libgnome-desktop-3-12
103+ - libgnome-desktop-3-dev
104+ - libgsettings-qt-dev
106+ - liblightdm-qt5-3-dev
112+ - libqt5xmlpatterns5-dev
113+ - libqtdbusmock1-dev
114+ - libqtdbustest1-dev
115+ - libsystemsettings-dev
116+ - libubuntu-app-launch2-dev
117+ - libubuntu-download-manager-common-dev
118+ - libubuntugestures5-dev
119+ - libubuntugestures5-private-dev
123+ - libusermetricsoutput1-dev
129+ - python3-setuptools:native
130+ - qml-module-qt-labs-folderlistmodel
131+ - qml-module-qt-labs-settings
132+ - qml-module-qtmultimedia
133+ - qml-module-qtqml-statemachine
134+ - qml-module-qtquick-layouts
135+ - qml-module-qtquick-xmllistmodel
136+ - qml-module-qtquick2
137+ - qml-module-qtsysteminfo
139+ - qml-module-ubuntu-components
140+ - qml-module-ubuntu-layouts
141+ - qml-module-ubuntu-settings-components
142+ - qml-module-ubuntu-test
145+ - qtbase5-private-dev
147+ - qtdeclarative5-dev
148+ - qtdeclarative5-dev-tools
149+ - qtdeclarative5-private-dev
150+ - qtdeclarative5-ubuntu-content1
151+ - ttf-ubuntu-font-family
152+ - ubports-wallpapers
cmake/modules/QmlPlugins.cmakedeleted−148
@@ -1,148 +0,0 @@
1−# If you need to override the qmlplugindump binary, create the qmlplugin executable
2−# target before loading this plugin.
4−if(NOT TARGET qmlplugindump)
5− find_program(qmlplugindump_exe qmlplugindump)
7− if(NOT qmlplugindump_exe)
8− msg(FATAL_ERROR "Could not locate qmlplugindump.")
11− add_executable(qmlplugindump IMPORTED)
12− set_target_properties(qmlplugindump PROPERTIES IMPORTED_LOCATION ${qmlplugindump_exe})
16−# A custom target for building the qmltypes files manually.
18−if (NOT TARGET qmltypes)
19− add_custom_target(qmltypes)
22−# Creates a target for copying resource files into build dir and optionally installing them.
24−# Files will be copied into ${BINARY_DIR}/${path} or ${CMAKE_CURRENT_BINARY_DIR} and installed
25−# into ${DESTINATION}/${path}.
27−# Resource file names are matched against {*.{qml,js,jpg,png,sci,svg},qmldir}.
29−# export_qmlfiles(plugin path
30−# [SEARCH_PATH path] # Path to search for resources in (defaults to ${CMAKE_CURRENT_SOURCE_DIR})
33−# [TARGET_PREFIX string] # Will be prefixed to the target name
37−# - ${TARGET_PREFIX}${plugin}-qmlfiles - Copies resources into the binary dir.
39−macro(export_qmlfiles PLUGIN PATH)
40− set(single SEARCH_PATH BINARY_DIR DESTINATION TARGET_PREFIX)
41− cmake_parse_arguments(QMLFILES "" "${single}" "" ${ARGN})
43− if(NOT QMLFILES_SEARCH_PATH)
44− set(QMLFILES_SEARCH_PATH ${CMAKE_CURRENT_SOURCE_DIR})
47− if(QMLFILES_BINARY_DIR)
48− set(qmlfiles_dir ${QMLFILES_BINARY_DIR}/${PATH})
50− set(qmlfiles_dir ${CMAKE_CURRENT_BINARY_DIR})
54− ${QMLFILES_SEARCH_PATH}/*.qml
55− ${QMLFILES_SEARCH_PATH}/*.js
56− ${QMLFILES_SEARCH_PATH}/*.jpg
57− ${QMLFILES_SEARCH_PATH}/*.png
58− ${QMLFILES_SEARCH_PATH}/*.sci
59− ${QMLFILES_SEARCH_PATH}/*.svg
60− ${QMLFILES_SEARCH_PATH}/*.qmltypes
61− ${QMLFILES_SEARCH_PATH}/qmldir
64− execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${qmlfiles_dir})
67− add_custom_target(${QMLFILES_TARGET_PREFIX}${PLUGIN}-qmlfiles ALL
68− COMMAND cp ${QMLFILES} ${qmlfiles_dir}
73− if(QMLFILES_DESTINATION)
74− # install the qmlfiles file.
75− install(FILES ${QMLFILES}
76− DESTINATION ${QMLFILES_DESTINATION}/${PATH}
82−# Creates a target for generating the typeinfo file for a QML plugin and/or installs the plugin
85−# Files will be copied into ${BINARY_DIR}/${path} or ${CMAKE_CURRENT_BINARY_DIR} and installed
86−# into ${DESTINATION}/${path}. If you don't pass BINARY_DIR, it's assumed that current source
87−# path ends with ${path}.
89−# The generated file will be named after the last segment of the plugin name, e.g. Foo.qmltypes.
91−# export_qmlplugin(plugin version path
94−# [TARGET_PREFIX string] # Will be prefixed to the target name
95−# [ENVIRONMENT string] # Will be added to qmlplugindump's env
96−# [TARGETS target1 [target2 ...]] # Targets to depend on and install (e.g. the plugin shared object)
97−# [NO_TYPES] # Do not create the qmltypes target
101−# - ${TARGET_PREFIX}${plugin}-qmltypes - Generates the qmltypes file in the source dir.
102−# It will be made a dependency of the "qmltypes" target.
104−macro(export_qmlplugin PLUGIN VERSION PATH)
105− set(options NO_TYPES)
106− set(single BINARY_DIR DESTINATION TARGET_PREFIX ENVIRONMENT)
108− cmake_parse_arguments(QMLPLUGIN "${options}" "${single}" "${multi}" ${ARGN})
110− if(QMLPLUGIN_BINARY_DIR)
111− set(qmlplugin_dir ${QMLPLUGIN_BINARY_DIR}/${PATH})
113− # Find import path to point qmlplugindump at
114− string(REGEX REPLACE "/${PATH}$" "" QMLPLUGIN_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
115− set(qmlplugin_dir ${CMAKE_CURRENT_BINARY_DIR})
118− if(NOT QMLPLUGIN_NO_TYPES)
119− # Relative path for the module
120− string(REPLACE "${CMAKE_BINARY_DIR}/" "" QMLPLUGIN_MODULE_DIR "${QMLPLUGIN_BINARY_DIR}")
122− # Find the last segment of the plugin name to use as qmltypes basename
123− string(REGEX MATCH "[^.]+$" plugin_suffix ${PLUGIN})
124− set(target_prefix ${QMLPLUGIN_TARGET_PREFIX}${PLUGIN})
125− set(qmltypes_path ${CMAKE_CURRENT_SOURCE_DIR}/${plugin_suffix}.qmltypes)
127− add_custom_target(${target_prefix}-qmltypes
128− COMMAND env ${QMLPLUGIN_ENVIRONMENT} $<TARGET_FILE:qmlplugindump> -notrelocatable
129− ${PLUGIN} ${VERSION} ${QMLPLUGIN_MODULE_DIR} > ${qmltypes_path}
130− WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
132− add_dependencies(${target_prefix}-qmltypes ${target_prefix}-qmlfiles ${QMLPLUGIN_TARGETS})
133− add_dependencies(qmltypes ${target_prefix}-qmltypes)
136− set_target_properties(${QMLPLUGIN_TARGETS} PROPERTIES
137− ARCHIVE_OUTPUT_DIRECTORY ${qmlplugin_dir}
138− LIBRARY_OUTPUT_DIRECTORY ${qmlplugin_dir}
139− RUNTIME_OUTPUT_DIRECTORY ${qmlplugin_dir}
142− if (QMLPLUGIN_DESTINATION)
143− # Install additional targets
144− install(TARGETS ${QMLPLUGIN_TARGETS}
145− DESTINATION ${QMLPLUGIN_DESTINATION}/${PATH}
cmake/modules/QmlTest.cmake+20−8
@@ -201,7 +201,7 @@ function(add_executable_test COMPONENT_NAME TARGET)
201 add_qmltest_target(xvfbtest${COMPONENT_NAME} ${TARGET}
201 add_qmltest_target(xvfbtest${COMPONENT_NAME} ${TARGET}
202 COMMAND $<TARGET_FILE:xvfb-run> --server-args "-screen 0 1024x768x24" --auto-servernum ${qmltest_command}
202 COMMAND $<TARGET_FILE:xvfb-run> --server-args "-screen 0 1024x768x24" --auto-servernum ${qmltest_command}
203 ${depends}
203 ${depends}
204− ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1
204+ ENVIRONMENT QT_QPA_PLATFORM=xcb QML2_IMPORT_PATH=${imports} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1 ${QMLTEST_ENVIRONMENT}
205 TARGETS ${xvfb_targets}
205 TARGETS ${xvfb_targets}
@@ -264,12 +264,16 @@ endfunction()
264# installed system.
264# installed system.
266function(add_meta_test TARGET_NAME)
266function(add_meta_test TARGET_NAME)
267− cmake_parse_arguments(TEST "" "" "DEPENDS" ${ARGN})
267+ cmake_parse_arguments(TEST "SERIAL" "" "DEPENDS" ${ARGN})
269 add_custom_target(${TARGET_NAME})
269 add_custom_target(${TARGET_NAME})
271 set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
271 set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
272− file(WRITE "${filename}" "#!/bin/sh\n\nset -e\n\n")
273+ file(WRITE "${filename}" "#!/bin/sh\n\n")
275+ file(WRITE "${filename}" "#!/usr/bin/parallel --shebang --no-notice\n\n")
274 add_meta_dependencies(${TARGET_NAME} DEPENDS ${TEST_DEPENDS})
278 add_meta_dependencies(${TARGET_NAME} DEPENDS ${TEST_DEPENDS})
275 # else we will write the rest of the script as we add cmake targets
279 # else we will write the rest of the script as we add cmake targets
@@ -290,7 +294,7 @@ function(install_test_script TARGET_NAME)
291 # Now write the above test into a shell script that we can run on an
295 # Now write the above test into a shell script that we can run on an
292 # installed system.
296 # installed system.
293− set(script "#!/bin/sh\n\n")
297+ set(script "#!/bin/sh\n\nset -x\n\n")
294 foreach(ONE_ENV ${TEST_ENVIRONMENT})
298 foreach(ONE_ENV ${TEST_ENVIRONMENT})
295 set(script "${script}export ${ONE_ENV}\n")
299 set(script "${script}export ${ONE_ENV}\n")
296 endforeach()
300 endforeach()
@@ -300,11 +304,14 @@ function(install_test_script TARGET_NAME)
300 set(script "${script}XML_ARGS=\n")
304 set(script "${script}XML_ARGS=\n")
301 set(script "${script}if [ -n \"\$ARTIFACTS_DIR\" ]; then\n")
305 set(script "${script}if [ -n \"\$ARTIFACTS_DIR\" ]; then\n")
302 set(script "${script} XML_ARGS=\"@XML_ARGS@\"\n")
306 set(script "${script} XML_ARGS=\"@XML_ARGS@\"\n")
307+ set(script "${script} mkdir -p \"@XML_DIR@\"\n")
308+ set(script "${script} touch \"@XML_FILE@\"\n")
303 set(script "${script}fi\n")
309 set(script "${script}fi\n")
304 set(script "${script}\n")
310 set(script "${script}\n")
305 foreach(ONE_CMD ${TEST_COMMAND})
311 foreach(ONE_CMD ${TEST_COMMAND})
306 set(script "${script}'${ONE_CMD}' ")
312 set(script "${script}'${ONE_CMD}' ")
307 endforeach()
313 endforeach()
314+ set(script "${script}\"\$@\"") # Allow passing arguments if desired
309 set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
316 set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
@@ -326,10 +333,15 @@ function(install_test_script TARGET_NAME)
327 # Now some replacements...
334 # Now some replacements...
328 # tests like to write xml output to our builddir; we don't need that, but we do want them in ARTIFACTS_DIR
335 # tests like to write xml output to our builddir; we don't need that, but we do want them in ARTIFACTS_DIR
329− string(REGEX MATCH \"( '--parameter')? '-o'( '--parameter')? '[^ ]*,xunitxml' \" xmlargs \"\${replacestr}\")
336+ string(REGEX MATCH \"( '--parameter')? '-o'( '--parameter')? '[^']*,xunitxml' \" xmlargs \"\${replacestr}\")
330− string(REGEX REPLACE \"( '--parameter')? '-o'( '--parameter')? '[^ ]*,xunitxml' \" \" \\\$XML_ARGS \" replacestr \"\${replacestr}\")
337+ string(REGEX REPLACE \"( '--parameter')? '-o'( '--parameter')? '[^']*,xunitxml' \" \" \\\$XML_ARGS \" replacestr \"\${replacestr}\")
331− string(REGEX REPLACE \"${CMAKE_BINARY_DIR}\" \"\\\$ARTIFACTS_DIR\" xmlargs \"\${xmlargs}\")
338+ string(REGEX REPLACE \"'[^']*/tests/\" \"'\\\$ARTIFACTS_DIR/tests/\" xmlargs \"\${xmlargs}\")
339+ string(REGEX REPLACE \".*'([^']*),xunitxml'.*\" \"\\\\1\" xmlfile \"\${xmlargs}\")
340+ string(REGEX REPLACE \"(.*)/[^/]*\" \"\\\\1\" xmldir \"\${xmlfile}\")
341+ string(REGEX REPLACE \"'\" \"\" xmlargs \"\${xmlargs}\") # strip single quotes
332 string(REGEX REPLACE \"@XML_ARGS@\" \"\${xmlargs}\" replacestr \"\${replacestr}\")
342 string(REGEX REPLACE \"@XML_ARGS@\" \"\${xmlargs}\" replacestr \"\${replacestr}\")
343+ string(REGEX REPLACE \"@XML_DIR@\" \"\${xmldir}\" replacestr \"\${replacestr}\")
344+ string(REGEX REPLACE \"@XML_FILE@\" \"\${xmlfile}\" replacestr \"\${replacestr}\")
333 # replace build/source roots with their install paths
345 # replace build/source roots with their install paths
334 string(REPLACE \"${CMAKE_BINARY_DIR}/libs\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\" replacestr \"\${replacestr}\")
346 string(REPLACE \"${CMAKE_BINARY_DIR}/libs\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\" replacestr \"\${replacestr}\")
335 string(REPLACE \"${CMAKE_BINARY_DIR}/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}\" replacestr \"\${replacestr}\")
347 string(REPLACE \"${CMAKE_BINARY_DIR}/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}\" replacestr \"\${replacestr}\")
@@ -363,7 +375,7 @@ function(add_meta_dependencies UPSTREAM_TARGET)
363 # add depend to the meta test script that we will install on system
375 # add depend to the meta test script that we will install on system
364 set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${UPSTREAM_TARGET}.sh")
376 set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${UPSTREAM_TARGET}.sh")
365 if (EXISTS "${filename}")
377 if (EXISTS "${filename}")
366− file(APPEND "${filename}" "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/scripts/${depend}.sh\n")
378+ file(APPEND "${filename}" "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/scripts/${depend}.sh \"\$@\" 2>&1\n")
368 endforeach()
380 endforeach()
369endfunction()
381endfunction()
data/51-unity8-greeter.confnew file+2
@@ -0,0 +1,2 @@
2+greeter-session=unity8-greeter
@@ -1,24 +1,27 @@
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)
3−configure_file(${DASH_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop @ONLY)
4configure_file(${INDICATORS_CLIENT_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop @ONLY)
3configure_file(${INDICATORS_CLIENT_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop @ONLY)
4+configure_file(${GREETER_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${GREETER_APP}.desktop @ONLY)
6# install desktop files
6# install desktop files
7install(FILES
7install(FILES
8 ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
8 ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
9− ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop
10 ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop
9 ${CMAKE_CURRENT_BINARY_DIR}/${INDICATORS_CLIENT_APP}.desktop
11 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
10 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
15install(FILES
13install(FILES
16− ${CMAKE_CURRENT_SOURCE_DIR}/${DASH_APP}.png
14+ ${CMAKE_CURRENT_BINARY_DIR}/${GREETER_APP}.desktop
17− DESTINATION ${SHELL_APP_DIR}/Dash/
15+ DESTINATION ${CMAKE_INSTALL_DATADIR}/lightdm/greeters
19+ 51-unity8-greeter.conf
20+ DESTINATION ${CMAKE_INSTALL_DATADIR}/lightdm/lightdm.conf.d
20add_custom_target(pkgversion ALL COMMAND dpkg-parsechangelog -l${CMAKE_SOURCE_DIR}/debian/changelog --show-field version > ${CMAKE_CURRENT_BINARY_DIR}/version)
23add_custom_target(pkgversion ALL COMMAND dpkg-parsechangelog -l${CMAKE_SOURCE_DIR}/debian/changelog --show-field version > ${CMAKE_CURRENT_BINARY_DIR}/version)
22install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
25install(FILES com.canonical.Unity8.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
23−install(FILES unity8-dash.url-dispatcher DESTINATION ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
26+install(FILES com.canonical.Unity.gschema.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/glib-2.0/schemas)
24install(FILES ${CMAKE_CURRENT_BINARY_DIR}/version DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/lib/unity8)
27install(FILES ${CMAKE_CURRENT_BINARY_DIR}/version DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/lib/unity8)
data/com.canonical.Unity.gschema.xmlnew file+255
@@ -0,0 +1,255 @@
2+ <enum id="form-factor-enum">
3+ <value nick="Automatic" value="0" />
4+ <value nick="Desktop" value="1" />
5+ <value nick="Netbook" value="2" />
6+ <value nick="TV" value="3" />
8+ <enum id="home-expanded-enum">
9+ <value nick="Not Expanded" value="0" />
10+ <value nick="Expanded" value="1" />
12+ <enum id="launcher-position-enum">
13+ <value nick="Left" value="0" />
14+ <value nick="Bottom" value="1" />
16+ <enum id="desktop-type-enum">
17+ <value nick="Ubuntu" value="0" />
18+ <value nick="UbuntuKylin" value="1" />
21+ <schema path="/com/canonical/unity/" id="com.canonical.Unity" gettext-domain="unity">
22+ <key enum="form-factor-enum" name="form-factor">
23+ <default>"Automatic"</default>
24+ <summary>The form factor Unity should target.</summary>
25+ <description>The form factor chosen will affect the size and appearance of the Dash, Launcher and also the Window Management behaviour.</description>
27+ <key enum="home-expanded-enum" name="home-expanded">
28+ <default>"Expanded"</default>
29+ <summary>Whether the home screen should be expanded.</summary>
30+ <description>Whether the home screen should be expanded.</description>
32+ <key enum="desktop-type-enum" name="desktop-type">
33+ <default>"Ubuntu"</default>
34+ <summary>The current desktop name.</summary>
35+ <description>The current desktop name.</description>
37+ <key type="i" name="minimize-count">
39+ <summary>Number of times a normal window has been minimized.</summary>
40+ <description>This is used to adjust the animation speed by making it progressively faster the more it is used.</description>
42+ <key type="i" name="minimize-fast-duration">
43+ <default>300</default>
44+ <summary>The duration for the minimize animation when it is at its fastest setting.</summary>
45+ <description>This is the duration that the minimize animation will have when it has been used more than an number of times equal minimize-speed-threshold.</description>
47+ <key type="i" name="minimize-slow-duration">
48+ <default>800</default>
49+ <summary>The duration for the minimize animation when it is at its slowest setting.</summary>
50+ <description>This is the duration that the minimize animation will have when it has never been used.</description>
52+ <key type="i" name="minimize-speed-threshold">
53+ <default>100</default>
54+ <summary>The number of minimizations required to reach maximum speed.</summary>
55+ <description>The speed of the minimize animation will progressively get faster as minimize-count approaches this value.</description>
57+ <key type="b" name="double-click-activate">
58+ <default>true</default>
59+ <summary>Enable/Disable dash result double-click activation.</summary>
60+ <description>This is used to enable/disable double-click result activation in the dash. Double-click to activate, single click preview</description>
62+ <key type="b" name="integrated-menus">
63+ <default>false</default>
64+ <summary>Enable/Disable the integrated menus in Unity.</summary>
65+ <description>When this is enabled, the application menus will be shown
66+ on the window decoration, otherwise they will be always shown on the
67+ unity top panel</description>
69+ <key type="u" name="show-menus-now-delay">
70+ <default>180</default>
71+ <range min="0" max="5000"/>
72+ <summary>Delay (in ms) before showing the menus when pressing Alt</summary>
73+ <description>This allows tune the delay before presenting unity menus
74+ (in non always-show-menus mode).</description>
76+ <key type="b" name="always-show-menus">
77+ <default>false</default>
78+ <summary>Toggle the menu visibility based on mouse hovering.</summary>
79+ <description>When this is enabled, the application menus will be always
80+ shown (on the window decoration or in the unity panel, depending whether
81+ integrated menus are enabled), otherwise they will be shown only when
82+ the mouse cursor is over the relative mouse area.</description>
84+ <key type="as" name="whitelist-repeated-keys">
86+ 'XF86KbdBrightnessUp',
87+ 'XF86KbdBrightnessDown',
88+ 'XF86MonBrightnessUp',
89+ 'XF86MonBrightnessDown',
90+ 'XF86AudioRaiseVolume',
91+ 'XF86AudioLowerVolume'
93+ <summary>List of keycodes that should be processed even if auto-repated.</summary>
94+ <description>These keycodes are processed even if they are auto-repeated.</description>
96+ <key type="b" name="pam-check-account-type">
97+ <default>false</default>
98+ <summary>Enable/Disable PAM account checking</summary>
99+ <description>Whether PAM should check the result of account modules
100+ when authenticating. Only do this if you have account
101+ configured properly on your system.</description>
103+ <key type="b" name="lowgfx">
104+ <default>false</default>
105+ <summary>Enable/Disable Low Graphics Mode</summary>
106+ <description>Whether Unity runs in Low Graphics Mode.</description>
109+ <schema path="/com/canonical/unity/interface/" id="com.canonical.Unity.Interface" gettext-domain="unity">
110+ <key type="d" name="text-scale-factor">
111+ <default>1.0</default>
112+ <range min="0.5" max="3.0"/>
113+ <summary>Font scaling for unity and applications.</summary>
114+ <description>This value defines the global font scaling used by both
115+ unity and applications. It will match the current system font scaling.</description>
117+ <key type="d" name="cursor-scale-factor">
118+ <default>1.0</default>
119+ <range min="0.5" max="3.0"/>
120+ <summary>Mouse cursor scaling.</summary>
121+ <description>This value defines the global mouse cursor scaling used by both
122+ unity and applications. Changing this value allows to use a custom scaling
123+ for the mouse cursor.</description>
125+ <key type="s" name="app-scale-factor-monitor">
126+ <default>''</default>
127+ <summary>The name of the monitor that controls the global app scaling factor.</summary>
128+ <description>This value defines the monitor that unity will use (if found) as reference
129+ for scaling all the applications.</description>
131+ <key type="b" name="app-fallback-to-maximum-scale-factor">
132+ <default>true</default>
133+ <summary>Use the maximum per-monitor scale-factor as application scale factor if no target monitor is found.</summary>
134+ <description>When this is enabled, the applications scale factor will match
135+ the scale factor of the monitor with the greater value, in case the monitor
136+ defined in 'app-scale-factor-monitor' is not provided or available.</description>
139+ <schema path="/com/canonical/unity/launcher/" id="com.canonical.Unity.Launcher" gettext-domain="unity">
140+ <key type="as" name="favorites">
142+ 'application://ubiquity.desktop',
143+ 'application://org.gnome.Nautilus.desktop',
144+ 'application://firefox.desktop',
145+ 'application://libreoffice-writer.desktop',
146+ 'application://libreoffice-calc.desktop',
147+ 'application://libreoffice-impress.desktop',
148+ 'application://org.gnome.Software.desktop',
149+ 'application://ubuntu-amazon-default.desktop',
150+ 'application://unity-control-center.desktop',
151+ 'unity://running-apps',
152+ 'unity://expo-icon',
155+ <summary>List of items that should be shown by default in the launcher</summary>
156+ <description>These items can be: application://desktop-id.desktop, device://uiid and unity://special-id (including: unity://running-apps (icons of running applications) unity://devices (icons of attached devices), unity://expo-icon (icon of the workspace switcher) and unity://desktop-icon (the show-desktop icon)); the order of this list determines the launcher item's position.</description>
158+ <key type="as" name="items">
160+ 'application:///dialer-app.desktop',
161+ 'application:///messaging-app.desktop',
162+ 'application:///address-book-app.desktop',
163+ 'application:///ubuntu-system-settings.desktop',
164+ 'appid://openstore.openstore-team/openstore/current-user-version',
165+ 'appid://com.ubuntu.camera/camera/current-user-version',
166+ 'appid://com.ubuntu.gallery/gallery/current-user-version',
167+ 'application:///morph-browser.desktop'
169+ <summary>List of items that should be shown by default in the launcher</summary>
170+ <description>These items can be: application:///desktop-id.desktop or appid://package/app/current-user-version.</description>
172+ <key type="s" name="favorite-migration">
173+ <default>''</default>
174+ <summary>Version of last migration done</summary>
175+ <description>This is a detection key for the favorite migration script to know whether the needed migration is done or not.</description>
177+ <key enum="launcher-position-enum" name="launcher-position">
178+ <default>"Left"</default>
179+ <summary>The position of launcher.</summary>
180+ <description>The position of launcher.</description>
183+ <schema path="/com/canonical/unity/devices/" id="com.canonical.Unity.Devices" gettext-domain="unity">
184+ <key type="as" name="blacklist">
185+ <default>[]</default>
186+ <summary>List of device uuid blacklist from the launcher.</summary>
187+ <description>These devices are not shown in the launcher by default.</description>
190+ <schema path="/com/canonical/unity/dash/" id="com.canonical.Unity.Dash" gettext-domain="unity">
191+ <key type="as" name="scopes">
192+ <default>[ 'home.scope', 'applications.scope', 'files.scope', 'video.scope', 'music.scope', 'photos.scope', 'social.scope' ]</default>
193+ <summary>List of scope ids specifying which scopes should be created and the order to display them in.</summary>
194+ <description>The scopes listed in the scope bar will be ordered according to this list.</description>
196+ <key type="as" name="favorite-scopes">
197+ <default>[ 'scope://clickscope', 'scope://musicaggregator', 'scope://videoaggregator' ]</default>
198+ <summary>List of scope queries specifying what should be displayed in the dash.</summary>
199+ <description>List of favorite scopes displayed in the dash.</description>
202+ <schema path="/com/canonical/unity/decorations/" id="com.canonical.Unity.Decorations" gettext-domain="unity">
203+ <key type="u" name="grab-wait">
204+ <default>175</default>
205+ <range min="0" max="1000"/>
206+ <summary>Milliseconds to wait before considering a mouse pressure a grab</summary>
207+ <description>The number of ms to wait before starting the window movement (and then
208+ showing the proper mouse cursor, and grabbing the window)</description>
211+ <schema path="/com/canonical/unity/integrated-menus/" id="com.canonical.Unity.IntegratedMenus" gettext-domain="unity">
212+ <key type="u" name="click-movement-threshold">
213+ <default>15</default>
214+ <range min="0" max="30"/>
215+ <summary>Number of pixels to ignore on mouse pressure</summary>
216+ <description>This value define how many pixels the user can move the mouse
217+ when holding the mouse button, before we consider his action a movement
218+ (to grab the window).</description>
220+ <key type="u" name="double-click-wait">
221+ <default>0</default>
222+ <range min="0" max="300"/>
223+ <summary>Milliseconds to wait before activating a menu after mouse release</summary>
224+ <description>The number of ms to wait after a mouse button release event before considering
225+ it a click. When this value is greater than 0, then it's possible to maximize
226+ a window by double-clicking on its menus if the second click happens before the
227+ specified value of ms is elapsed</description>
229+ <key type="b" name="unfocused-windows-popup">
230+ <default>true</default>
231+ <summary>Whether to pop-up a menu when clicking over unfocused windows entries</summary>
232+ <description>By disabling this setting you can make unity to only focus a window
233+ when clicking over unfocused menu entries</description>
236+ <schema path="/com/canonical/unity/gestures/" id="com.canonical.Unity.Gestures" gettext-domain="unity">
237+ <key type="b" name="launcher-drag">
238+ <default>true</default>
239+ <summary>Multi-touch gesture to reveal the launcher.</summary>
240+ <description>When this is enabled, a 4 finger swipe from left to right will reveal launcher,
241+ provided that the launcher is set to auto-hide.</description>
243+ <key type="b" name="dash-tap">
244+ <default>true</default>
245+ <summary>Multi-touch gesture to open the dash.</summary>
246+ <description>When this is enabled, a 4 finger tap will open the dash.</description>
248+ <key type="b" name="windows-drag-pinch">
249+ <default>true</default>
250+ <summary>Multi-touch gestures to manage the windows.</summary>
251+ <description>When this is enabled, 3 finger gestures such as drag, and pinch, will
252+ help manage the windows.</description>
data/com.canonical.Unity8.gschema.xml+24−4
@@ -11,8 +11,8 @@
11 <summary>The usage mode.</summary>
11 <summary>The usage mode.</summary>
12 <description>The usage mode chosen will affect the Window Management behaviour.</description>
12 <description>The usage mode chosen will affect the Window Management behaviour.</description>
14− <key type="y" name="edge-barrier-sensitivity">
14+ <key type="u" name="edge-barrier-sensitivity">
15− <default>35</default>
15+ <default>50</default>
16 <range min="1" max="100"/>
16 <range min="1" max="100"/>
17 <summary>Sensitivity of screen edge barriers for the mouse pointer.</summary>
17 <summary>Sensitivity of screen edge barriers for the mouse pointer.</summary>
18 <description>Some UI actions like revealing the launcher or the applications spread are triggered by pushing the mouse pointer against a screen edge. This key defines how much you have to push in order to trigger the associated action.</description>
18 <description>Some UI actions like revealing the launcher or the applications spread are triggered by pushing the mouse pointer against a screen edge. This key defines how much you have to push in order to trigger the associated action.</description>
@@ -23,7 +23,7 @@
23 <description>How much you have to push (in grid units)the mouse against an edge barrier when sensibility is 100.</description>
23 <description>How much you have to push (in grid units)the mouse against an edge barrier when sensibility is 100.</description>
25 <key type="u" name="edge-barrier-max-push">
25 <key type="u" name="edge-barrier-max-push">
26− <default>60</default>
26+ <default>120</default>
27 <summary>Maximum push needed to overcome edge barrier</summary>
27 <summary>Maximum push needed to overcome edge barrier</summary>
28 <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description>
28 <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description>
@@ -33,7 +33,7 @@
33 <description>How big (in grid units) the edge-drag sensitive area should be.</description>
33 <description>How big (in grid units) the edge-drag sensitive area should be.</description>
35 <key type="b" name="autohide-launcher">
35 <key type="b" name="autohide-launcher">
36− <default>true</default>
36+ <default>false</default>
37 <summary>Autohide the launcher</summary>
37 <summary>Autohide the launcher</summary>
38 <description>This will only be applied in windowed mode. In staged mode, the launcher will always hide.</description>
38 <description>This will only be applied in windowed mode. In staged mode, the launcher will always hide.</description>
@@ -43,6 +43,26 @@
43 <summary>Width of the launcher in grid units.</summary>
43 <summary>Width of the launcher in grid units.</summary>
44 <description>Changes the width of the launcher in all usage modes.</description>
44 <description>Changes the width of the launcher in all usage modes.</description>
46+ <key type="b" name="enable-indicator-menu">
47+ <default>true</default>
48+ <summary>Enable or disable the indicator pull down menus</summary>
49+ <description>Toggle the availability of the indicator pull down menus</description>
51+ <key type="s" name="appstore-uri">
52+ <default>'appid://openstore.openstore-team/openstore/current-user-version'</default>
53+ <summary>The uri to the app store</summary>
54+ <description>This will be used whenever the user triggers an action to open the app store.</description>
56+ <key type="b" name="always-show-osk">
57+ <default>false</default>
58+ <summary>Force showing/hiding the OSK</summary>
59+ <description>Toggle the visibility of the On Screen Keyboard unconditionally</description>
61+ <key type="b" name="osk-switch-visible">
62+ <default>false</default>
63+ <summary>Whether the OSK switch should be visible</summary>
64+ <description>Toggle the visibility of the OSK switch</description>
48 <schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8">
68 <schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8">
data/test.sensorsnew file+12
@@ -0,0 +1,12 @@
2+create accel 0 1000 0.1
7+# simulate crash on the ground
data/unity8-dash.confdeleted−25
@@ -1,25 +0,0 @@
1−description "Unity Shell v8 Dash"
2−author "Michael Zanetti <michael.zanetti@canonical.com>"
4−emits scope-ui-starting
6−start on started unity8
7−stop on stopping unity8
11−# Focused app is 100 so we want to be less likely to get
12−# killed than the focused app but more than Unity8
17−respawn limit unlimited
19−env APP_ID=unity8-dash
22− initctl emit scope-ui-starting
25−exec ${BINARY:-unity8-dash} $ARGS --desktop_file_hint=/usr/share/applications/unity8-dash.desktop
data/unity8-dash.desktop.indeleted−9
@@ -1,9 +0,0 @@
4−Comment=An interface for using the Scopes system
5−Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8-dash
7−Icon=@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/Dash/unity8-dash.png
data/unity8-dash.pngdeleted
Binary file not shown.
data/unity8-dash.svgdeleted−326
@@ -1,326 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2−<!-- Created with Inkscape (http://www.inkscape.org/) -->
5− xmlns:dc="http://purl.org/dc/elements/1.1/"
6− xmlns:cc="http://creativecommons.org/ns#"
7− xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8− xmlns:svg="http://www.w3.org/2000/svg"
9− xmlns="http://www.w3.org/2000/svg"
10− xmlns:xlink="http://www.w3.org/1999/xlink"
11− xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12− xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13− viewBox="0 0 512 512"
14− style="enable-background:new"
15− inkscape:export-ydpi="180"
16− inkscape:export-xdpi="180"
17− inkscape:export-filename="app_shape02.png"
18− sodipodi:docname="apps-scope.svg"
19− inkscape:version="0.91+devel r"
25− inkscape:snap-global="false"
26− fit-margin-bottom="18"
30− inkscape:snap-grids="true"
31− inkscape:guide-bbox="true"
33− inkscape:snap-center="true"
34− inkscape:snap-object-midpoints="true"
35− inkscape:snap-midpoints="true"
36− inkscape:snap-smooth-nodes="true"
37− inkscape:snap-intersection-paths="true"
38− inkscape:object-nodes="true"
39− inkscape:object-paths="true"
40− inkscape:snap-bbox-midpoints="true"
41− inkscape:snap-bbox-edge-midpoints="true"
42− inkscape:bbox-nodes="true"
43− inkscape:bbox-paths="true"
44− inkscape:snap-bbox="true"
46− inkscape:showpageshadow="false"
47− inkscape:snap-page="true"
48− inkscape:window-maximized="1"
49− inkscape:window-y="24"
50− inkscape:window-x="0"
51− inkscape:window-height="1029"
52− inkscape:window-width="1920"
54− inkscape:current-layer="layer3"
55− inkscape:document-units="px"
56− inkscape:cy="204.04409"
57− inkscape:cx="-384.5809"
59− inkscape:pageshadow="2"
60− inkscape:pageopacity="0"
62− bordercolor="#666666"
114− originy="16.999996" />
132− orientation="-0.70710678,0.70710678"
137− position="256,-32.000001"
144− orientation="0.70710678,0.70710678"
145− position="544,-32.000001"
149− position="248,15.999999"
172− position="180.48,-96"
175− </sodipodi:namedview>
179− inkscape:collect="always"
180− id="linearGradient4203">
182− style="stop-color:#ea5420;stop-opacity:1"
186− style="stop-color:#f37e40;stop-opacity:1"
191− clipPathUnits="userSpaceOnUse"
194− style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.24899998;fill:#5e2c73;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
195− d="M 360,50 594,284 V 215.89844 C 594,70.73665 573.2426,50 427.94531,50 Z"
197− inkscape:connector-curvature="0" />
200− clipPathUnits="userSpaceOnUse"
203− style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#f6f6f6;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
204− d="M 543.8125,454.1875 312.18945,685.81055 367.94531,681 C 512.70468,668.50896 526.55393,654.72881 539,510.10156 Z"
206− inkscape:connector-curvature="0" />
209− inkscape:collect="always"
210− xlink:href="#linearGradient4203"
211− id="linearGradient4209"
216− gradientUnits="userSpaceOnUse" />
218− inkscape:collect="always"
219− style="color-interpolation-filters:sRGB"
226− inkscape:collect="always"
227− stdDeviation="1.4390401"
228− id="feGaussianBlur4222" />
231− inkscape:collect="always"
232− xlink:href="#linearGradient4226"
233− id="linearGradient4232"
238− gradientUnits="userSpaceOnUse"
239− spreadMethod="reflect" />
241− inkscape:collect="always"
242− id="linearGradient4226">
244− style="stop-color:#a73812;stop-opacity:1"
248− style="stop-color:#973310;stop-opacity:0"
253− inkscape:collect="always"
254− style="color-interpolation-filters:sRGB"
261− inkscape:collect="always"
262− stdDeviation="11.512321"
263− id="feGaussianBlur4236" />
271− <dc:format>image/svg+xml</dc:format>
273− rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
274− <dc:title></dc:title>
279− inkscape:groupmode="layer"
281− inkscape:label="Background">
283− style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient4209);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;enable-background:accumulate"
284− d="M 0 0 L 0 183.89844 L 0 328.10156 L 0 512 L 512 512 L 512 328.10156 L 512 183.89844 L 512 0 L 0 0 z "
287− style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
288− d="M 0 256 L 0 328.10156 L 0 462.53516 C 0 479.69677 0.052846476 496.03174 0.13085938 512 L 511.86914 512 C 511.94715 496.03174 512 479.69677 512 462.53516 L 512 256 L 0 256 z "
292− inkscape:groupmode="layer"
294− inkscape:label="Pictogram"
295− style="display:inline"
296− transform="translate(-32,-32)">
298− style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:#d04616;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.99999952;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;filter:url(#filter4220);enable-background:accumulate"
303− transform="rotate(90,-7.1132638e-7,31.999996)" />
305− transform="rotate(90,-7.1132638e-7,31.999996)"
310− style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient4232);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.99999952;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;filter:url(#filter4234);enable-background:accumulate" />
312− transform="rotate(90)"
317− style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.99999952;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
319− style="display:inline;fill:#ea5420;fill-opacity:1;stroke-width:2.9398191;enable-background:new"
321− d="m 193.9963,269.54024 c -10.19878,0 -18.46137,8.2634 -18.46137,18.46139 0,10.19309 8.26259,18.45568 18.46137,18.45568 10.19311,0 18.45569,-8.26259 18.45569,-18.45568 0,-10.19799 -8.26258,-18.46139 -18.45569,-18.46139 z m 131.78525,83.88906 c -8.82832,5.09898 -11.85536,16.38129 -6.75557,25.20475 5.0933,8.82834 16.37561,11.85455 25.20393,6.75556 8.82752,-5.0933 11.85457,-16.37561 6.75559,-25.20475 -5.0933,-8.82263 -16.38212,-11.84887 -25.20395,-6.75556 z m -91.69319,-65.42767 c 0,-18.24028 9.05999,-34.35498 22.92309,-44.11321 l -13.49406,-22.6012 c -16.14883,10.79461 -28.16435,27.28971 -33.15766,46.60863 5.82648,4.75434 9.55584,11.99194 9.55584,20.10497 0,8.10813 -3.72936,15.34572 -9.55584,20.10006 4.98681,19.32463 17.00232,35.82055 33.15766,46.61514 l 13.49406,-22.60689 c -13.8631,-9.75253 -22.92309,-25.86641 -22.92309,-44.1075 z m 53.91207,-53.91776 c 28.16514,0 51.27274,21.59491 53.69828,49.13495 l 26.30048,-0.38772 c -1.29405,-20.33173 -10.17604,-38.58421 -23.82372,-52.00594 -7.01814,2.65149 -15.12464,2.2459 -22.13139,-1.79314 -7.01894,-4.0504 -11.41969,-10.88319 -12.62271,-18.30044 -6.8214,-1.88254 -14.00046,-2.91323 -21.42257,-2.91323 -12.75925,0 -24.82271,2.99695 -35.53359,8.29836 l 12.82509,22.98243 c 6.89944,-3.21075 14.5963,-5.01526 22.71013,-5.01526 z m 0,107.82982 c -8.11383,0 -15.81069,-1.80533 -22.70931,-5.01528 l -12.82511,22.98163 c 10.71088,5.3079 22.77434,8.30568 35.53442,8.30568 7.42211,0 14.60118,-1.0315 21.42177,-2.91975 1.20301,-7.41724 5.60537,-14.24352 12.6227,-18.30125 7.01161,-4.04555 15.11326,-4.44382 22.13137,-1.79232 13.64769,-13.42174 22.52968,-31.67421 23.82372,-52.00595 l -26.30696,-0.38772 c -2.41986,27.54738 -25.52665,49.13496 -53.6926,49.13496 z m 37.77461,-119.35113 c 8.82834,5.09818 20.11145,2.07845 25.20475,-6.74987 5.099,-8.82833 2.07928,-20.11145 -6.74988,-25.21126 -8.82832,-5.0933 -20.11063,-2.06705 -25.21125,6.76127 -5.09247,8.82345 -2.06625,20.10657 6.75638,25.19986 z"
322− inkscape:connector-curvature="0"
323− inkscape:transform-center-x="16.232534"
324− inkscape:transform-center-y="-0.0024900663" />
data/unity8-dash.url-dispatcherdeleted−6
data/unity8-filewatcher.conf+5
@@ -1,6 +1,11 @@
1description "File system watcher for unity8"
1description "File system watcher for unity8"
2author "Michael Zanetti <michael.zanetti@canonical.com>"
2author "Michael Zanetti <michael.zanetti@canonical.com>"
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.
4# Workaround for bug 1360208. ~ and * in one expression doesn't work currently
9# Workaround for bug 1360208. ~ and * in one expression doesn't work currently
5start on (file FILE=/home/phablet/.local/share/applications/*.desktop) or (file FILE=/usr/share/applications/*.desktop)
10start on (file FILE=/home/phablet/.local/share/applications/*.desktop) or (file FILE=/usr/share/applications/*.desktop)
data/unity8-greeter-init.confnew file+12
@@ -0,0 +1,12 @@
1+description "Unity 8 Greeter initialization"
2+author "Michael Terry <mterry@ubuntu.com>"
4+start on unity8-greeter-started
6+emits indicator-services-start
9+ start --no-wait ofono-setup || true
10+ initctl emit --no-wait indicator-services-start || true
11+ start --no-wait maliit-server || true
data/unity8-greeter-wrappernew file+109
@@ -0,0 +1,109 @@
2+# -*- Mode: sh; indent-tabs-mode: nil; tab-width: 4 -*-
4+# Copyright (C) 2011,2013,2016 Canonical Ltd
6+# This program is free software: you can redistribute it and/or modify it under
7+# the terms of the GNU General Public License as published by the Free Software
8+# Foundation, version 3 of the License.
10+# See http://www.gnu.org/copyleft/gpl.html the full text of the license.
12+# This wrapper merely ensures that init and friends live only as long as this
13+# script does. Otherwise, it's very easy for some processes to not notice that
14+# the session died. We could try to do this in-process, but we want to do this
15+# cleanup even if the greeter aborts.
17+trap cleanup TERM EXIT
22+ # Kill upstart and indicators
23+ if [ -n "$INIT_PID" ]; then
26+ if [ -n "$CMD_PID" ]; then
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"
41+SUB_SOCKET=$XDG_RUNTIME_DIR/mir_socket
42+rm -f $SUB_SOCKET # clear socket in case we were hard shut down
44+echo "DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}" >"$XDG_RUNTIME_DIR/dbus-session"
46+# If touch session script (which sets up grid units and mir variables) is available, use it
48+if which ubuntu-touch-session >/dev/null; then
49+ TOUCH_WRAPPER=ubuntu-touch-session
52+# Advertise as a unity8 session, so that indicator-network will start.
53+export XDG_SESSION_DESKTOP=unity8
54+export DESKTOP_SESSION=$XDG_SESSION_DESKTOP
56+set_greeter_var QT_IM_MODULE maliitphablet
57+set_greeter_var QT_QPA_PLATFORM ubuntumirclient
59+# We disable ofono using pulse. It causes problems with racing with the user's
60+# pulse. We need to come up with a better long-term fix for this, because we
61+# eventually need the greeter to play ringtones for users that aren't logged in.
62+set_greeter_var PA_DISABLED 1
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 &
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
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
81+# Start any pre-greeter tasks if needed (like wizard)
82+initctl emit unity8-greeter-starting
84+# Define language here for phone if available. When phone user switches their
85+# language, they expect that to affect the greeter too. But the user doesn't
86+# have permission to switch system language, only their own. So we notice if
87+# the phablet user exists and use their language if so. TODO: talk to design
88+# about whether we should switch language on fly as users are selected (this
89+# is very hard to do technically).
91+# Do this after unity8-greeter-starting, in case a customization upstart job
93+if [ "$(id -u phablet 2>/dev/null)" = "32011" ]; then
94+ USER_LANG=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User Language | cut -d\' -f2)
95+ if [ -n "$USER_LANG" ]; then
96+ set_greeter_var LANGUAGE "$USER_LANG"
98+ USER_LOCALE=$(gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Get org.freedesktop.Accounts.User FormatsLocale | cut -d\' -f2)
99+ if [ -n "$USER_LOCALE" ]; then
100+ set_greeter_var LANG "$USER_LOCALE"
101+ set_greeter_var LC_ALL "$USER_LOCALE"
105+# And finally actually start the greeter
106+exec env MIR_SERVER_FILE=$SUB_SOCKET $TOUCH_WRAPPER $@ &
data/unity8-greeter.desktop.innew file+7
@@ -0,0 +1,7 @@
4+Comment=The converged Unity shell's Greeter
5+Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8-greeter-wrapper @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8 --mode=greeter
6+X-LightDM-Session-Type=mir
data/unity8-greeter.pklanew file+44
@@ -0,0 +1,44 @@
1+# DO NOT EDIT THIS FILE, it will be overwritten on update
2+# Place your local configurations under /etc/polkit-1/localauthority/
4+[Disable Controlling of Network Devices]
5+Identity=unix-user:lightdm
6+Action=org.freedesktop.NetworkManager.enable-disable-network;org.freedesktop.NetworkManager.enable-disable-wifi;org.freedesktop.NetworkManager.enable-disable-wwan;org.freedesktop.NetworkManager.enable-disable-wimax;
11+[Disable Sleep and Wake]
12+Identity=unix-user:lightdm
13+Action=org.freedesktop.NetworkManager.sleep-wake
18+[Disable WiFi Sharing]
19+Identity=unix-user:lightdm
20+Action=org.freedesktop.NetworkManager.wifi.share.protected;org.freedesktop.NetworkManager.wifi.share.open
25+[Disable Settings Modifications]
26+Identity=unix-user:lightdm
27+Action=org.freedesktop.NetworkManager.settings.modify.own;org.freedesktop.NetworkManager.settings.modify.system;org.freedesktop.NetworkManager.settings.modify.hostname
32+[Disable User Connections]
33+Identity=unix-user:lightdm
34+Action=org.freedesktop.NetworkManager.use-user-connections
39+[Enable Controlling of Network Connections]
40+Identity=unix-user:lightdm
41+Action=org.freedesktop.NetworkManager.network-control
@@ -2,37 +2,51 @@ description "Unity Shell v8"
2author "Ricardo Mendoza <ricmm@ubuntu.com>"
2author "Ricardo Mendoza <ricmm@ubuntu.com>"
4emits indicator-services-start
4emits indicator-services-start
5+emits indicator-services-end
6−start on ((xsession SESSION=ubuntu-touch) or (xsession SESSION=unity8-mir)) and started dbus
7+start on ((xsession SESSION=ubuntu-touch) or (xsession SESSION=unity8-mir) or (xsession SESSION=unity8)) and started dbus
7stop on desktop-end
8stop on desktop-end
9kill timeout 120
10kill timeout 120
13+# Ensure the shell always gets unthrottled touch events, so that applications
14+# who want full speed low-latency input can get it (LP: #1497105) and so that
15+# apps can use QML touch compression safely (the QML touch compression
16+# algorithm does not support nesting well - LP: #1486341, LP: #1556763 - so
17+# must be fed by the raw input event stream from Unity8).
19+env QML_NO_TOUCH_COMPRESSION=1
12expect stop
22expect stop
24+# FIXME Create an autopilot test that makes sure start+stop and restart
25+# work fine at least 2 times
14pre-start script
27pre-start script
15 # Tell unity-mir to raise SIGSTOP after we start
28 # Tell unity-mir to raise SIGSTOP after we start
16 initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
29 initctl set-env UNITY_MIR_EMITS_SIGSTOP=1
18− if [ -n "$MIR_SOCKET" ]; then
19− # FIXME Create an autopilot test that makes sure start+stop and restart
20− # work fine at least 2 times
21− # Save original value of MIR_SOCKET in case we are stopped,
31+ # Save original value of MIR_SOCKET so that we can restore it when stopped,
22− # as we modify the variable for future jobs, including ourself.
32+ # as we modify the variable for future jobs, including ourself.
23− UNITY_MIR_SOCKET=$(initctl get-env --global MIR_SOCKET)
24− initctl set-env --global UNITY_MIR_SOCKET=$UNITY_MIR_SOCKET
33+ initctl set-env UNITY_MIR_SOCKET=$MIR_SOCKET
26− # Point unity8 at unity-system-compositor
35+ # Decide where we are going to put our own socket file
36+ if [ -n "$SNAP" ]; then
37+ # In snappy, we want to hard code our path because our apparmor profile
38+ # only lets us put the socket in one place. And consumers expect it
40+ MIR_SERVER_FILE=/run/user/$(id -u)/mir_socket
27 MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
42 MIR_SERVER_FILE=$XDG_RUNTIME_DIR/mir_socket
28− initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
29− initctl set-env MIR_SERVER_HOST_SOCKET=$UNITY_MIR_SOCKET
31− # Point all future jobs in this session to our Mir socket instead of
32− # unity-system-compositor's socket.
33− initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
34− gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
44+ initctl set-env MIR_SERVER_FILE=$MIR_SERVER_FILE
46+ # Point all future jobs in this session to our Mir socket instead of
47+ # unity-system-compositor's socket.
48+ initctl set-env --global MIR_SOCKET=$MIR_SERVER_FILE
49+ gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}"
37 # Remove the normal and trusted sockets if still there
51 # Remove the normal and trusted sockets if still there
38 if [ -S "$MIR_SERVER_FILE" ]; then
52 if [ -S "$MIR_SERVER_FILE" ]; then
@@ -50,9 +64,28 @@ pre-start script
50 # the lag seen in the indicator panel pull-down (LP: #1488327) and also
64 # the lag seen in the indicator panel pull-down (LP: #1488327) and also
51 # reduces lag seen in apps:
65 # reduces lag seen in apps:
52 initctl set-env --global QML_NO_TOUCH_COMPRESSION=1
66 initctl set-env --global QML_NO_TOUCH_COMPRESSION=1
68+ # Workaround for text not rendering correctly
69+ initctl set-env --global QT_ENABLE_GLYPH_CACHE_WORKAROUND=1
71+ if [ "$XDG_SESSION_DESKTOP" = "ubuntu-touch" ]; then
72+ # On Ubuntu Touch, we currently use a trick where we auto-login the
73+ # user without a LightDM greeter at all. In this case, we want to
74+ # start with the lockscreen visible. Once we switch to using a
75+ # proper greeter for the first login, we can remove this code path.
76+ initctl set-env MODE=full-greeter
78+ initctl set-env MODE=full-shell
81+ # HACK! WORKAROUND FOR HALIUM MISSING UBUNTU_PLATFORM_API
82+ if [ ! -f /system/lib/libubuntu_application_api.so ]; then
83+ initctl set-env --global UBUNTU_PLATFORM_API_BACKEND=test.so.3
84+ initctl set-env --global UBUNTU_PLATFORM_API_SENSOR_TEST=/etc/ubuntusensors/test.sensors
55−exec ${BINARY:-unity8} $ARGS
88+exec ${BINARY:-unity8} --mode=$MODE $ARGS
57post-start script
90post-start script
58 initctl emit --no-wait indicator-services-start
91 initctl emit --no-wait indicator-services-start
@@ -60,7 +93,7 @@ end script
61post-stop script
94post-stop script
62 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
95 initctl set-env --global MIR_SOCKET=$UNITY_MIR_SOCKET
63− initctl unset-env --global UNITY_MIR_SOCKET
64 initctl unset-env --global MIR_SERVER_PROMPT_FILE
96 initctl unset-env --global MIR_SERVER_PROMPT_FILE
65 initctl emit application-end
97 initctl emit application-end
98+ initctl emit indicator-services-end
@@ -1,3 +1,973 @@
1+unity8 (8.20+ubports) xenial; urgency=medium
3+ * Replace dependency on ubuntu-wallpapers with ubports-wallpapers
5+ -- Dalton Durst <dalton@ubports.com> Fri, 5 Oct 2018 13:28:20 -0500
7+unity8 (8.17+ubports3) xenial; urgency=medium
11+ -- UBports auto importer <infra@ubports.com> Mon, 31 Jul 2017 03:12:43 +0200
13+unity8 (8.15+17.04.20170404.7-0ubuntu2) zesty; urgency=medium
16+ * Make the default store uri point to gnome software center
18+ -- Timo Jyrinki <timo-jyrinki@ubuntu.com> Thu, 06 Apr 2017 10:49:29 +0300
20+unity8 (8.15+17.04.20170404.7-0ubuntu1) zesty; urgency=medium
22+ [ Albert Astals Cid ]
23+ * Tweak app drawer a bit (LP: #1667570)
26+ * Make some small changes to the greeter's session list
27+ * Handle a user in the greeter having never selected a session better
31+ * Do not occlude windows with an ongoing unmaximize transition (LP:
33+ * Show and implement close buttons for child windows (LP: #1668053)
34+ * Sanitize the logic for pointer vs. touch menus, fixes hiding the
35+ window title in staged mode, when hovering the panel with mouse and
39+ * Don't hide the launcher on super press if it's locked visible (LP:
41+ * fix searchfield selection in drawer (LP: #1677259)
42+ * make sure the stage has focus when going to spread (LP: #1672053,
44+ * don't autostart the dash app, but show its .desktop file instead
46+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 04 Apr 2017 22:56:06 +0000
48+unity8 (8.15+17.04.20170328.3-0ubuntu1) zesty; urgency=medium
50+ [ Albert Astals Cid ]
51+ * mock: Remove empty property and move invokable
52+ * Tune quicklist item selection
53+ * Fix unminimizing going to the wrong position the second time (LP:
55+ * Remove unclickable gaps on the menubar (LP: #1672722)
56+ * indicators client is a tool
57+ * Make sure we destroy the popups when the item goes away (LP:
59+ * UnityApplicationMocks: Initialize m_state and m_requestedState
60+ * Don't use appInfo after checking it if is null
61+ * Initialize m_privateMode
62+ * Hook up aboutToShow for overflow menus (LP: #1676016)
65+ * Give active focus to child surface qml items (LP: #1671072)
66+ * Satellite child windows (LP: #1673415)
67+ * Tell qtmir/miral about the available desktop area
70+ * WindowStateStorage: use a private QThreadPool to ensure that
71+ WindowStateStorage::saveValue always has a thread available to
72+ execute the query in. (LP: #1675424)
75+ * Protect against loading invalid window geometry (LP: #1674262)
76+ * Remove usage of the deprecated (and non-functional) system-image-
78+ * Implement Ctrl+Alt+T to launch the terminal app (LP: #1673500)
79+ * Only take normal and dialog surface types into account for launcher
81+ * Fix the shutdown dialog after recent refactoring in
82+ DBusUnitySessionService (LP: #1676426)
85+ * drop the grey background behind icons in the drawer (LP: #1675688)
88+ * Fix Unity/Platform::isPC, and add tests (LP: #1670657)
90+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 28 Mar 2017 21:50:20 +0000
92+unity8 (8.15+17.04.20170321-0ubuntu1) zesty; urgency=medium
94+ [ Albert Astals Cid ]
95+ * Signal aboutToShow (LP: #1664578)
96+ * Support Panel top level items to be disabled (LP: #1670694)
97+ * Improve Launcher ←→ touch menu interaction (LP: #1667620, #1671069)
98+ * Fix real world submenus (e.g. kate) not getting their first item
99+ selected on open (LP: #1666859)
101+ [ Daniel d'Andrada ]
102+ * Really disable the window decoration when in staged mode (LP:
104+ * Don't let clients resize their surfaces while in staged
105+ (phone/tablet) mode (LP: #1670390)
106+ * TopLevelWindowModel: don't put hidden windows in the model (LP:
110+ * Reset always-show-osk gsetting on startup to default value (false
112+ * Fix the restored-to position with Miral due to the state changes
113+ being async (LP: #1669819)
114+ * Add a cursor name fallback mapping "grabbing" -> "closedhand" for
116+ * Fix unsnapping a maximized window from the panel (LP: #1671721)
117+ * Disable altDrag feature outside windowed mode
120+ * Don't lock the screen for guest users or users in the nopasswdlogin
121+ group. (LP: #1644237)
122+ * Support GNOME-style logout DBus API (making the Logout, Reboot, and
123+ Shutdown launcher commands work) (LP: #1673229)
126+ * Add support for closing apps from the spread with "Q" (LP: #1670327)
127+ * hide "private" launcher quicklist entries when the greeter is locked
129+ * add surface titles to launcher's quicklist (LP: #1661668)
130+ * properly reset the drawer state when cancelling a horizontal drag
132+ * fix the focus moving correctly between launcher and drawer (LP:
134+ * unfocus the drawer's textfield when it is moved (LP: #1669839)
137+ * Fix up indicators-client after refactoring (LP: #1672797)
139+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 21 Mar 2017 10:58:13 +0000
141+unity8 (8.15+17.04.20170308-0ubuntu1) zesty; urgency=medium
143+ [ Albert Astals Cid ]
144+ * Let's follow the keyboard order
145+ * Enable the license check (LP: #1590044)
146+ * Show a barebones error message if loading the QML doesn't work
147+ * Make sure cursor is back to normal when closing the window (LP:
149+ * Fix small warning when sensitive is undefined
150+ * Remove unused member variable
151+ * Initialize m_msecsSinceReference
152+ * Add warning if registerService fails
153+ * Move menus Component {} out of the repeater
154+ * Add tool to browse menus of a running app
156+ [ Daniel d'Andrada ]
157+ * Drag child windows with Alt+LeftMouseButton (LP: #1664947)
160+ * TopLevelWindowModel: connect to the OSK surface to know when it goes
161+ away so we can clean up after it. (LP: #1670681)
164+ * Initialize sessionMode to single when mock is reset (LP: #1667463)
167+ * Make the menu string "Back" translatable
168+ * Let the OSK be driven by a switch in indicator-keyboard (LP:
170+ * Disable the tutorial when there's no touchscreen (LP: #1661557)
171+ * Shell chrome fixes (LP: #1658117, #1665723, #1665724, #1669010)
172+ * Cancel the drag as soon as we're entering the spread (LP: #1668642)
173+ * Fix being unable to use window control buttons or menus with touch
174+ (LP: #1667604, #1668387)
177+ * Set QT_IM_MODULE in the greeter so that the OSK can come up. (LP:
179+ * Simplify our startup handling of Mir environment variables and set
180+ the right socket path in snappy.
183+ * Cancel the home key activation if something else is pressed along
184+ with Meta (LP: #1670678)
185+ * close the drawer when something is launched from the launcher (LP:
187+ * use a svg instead of a png for the Launcher's BFB (LP: #1668057)
188+ * change the default setting for the launcher autohiding (LP:
192+ * Split up Shell::test_spreadDisabled to ensure initial state for each
195+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 08 Mar 2017 09:56:46 +0000
197+unity8 (8.15+17.04.20170221-0ubuntu1) zesty; urgency=medium
199+ * Handle ubuntu-app-launch API/ABI break
201+ -- Ken VanDine <ken.vandine@canonical.com> Tue, 21 Feb 2017 13:23:23 +0000
203+unity8 (8.15+17.04.20170216.1-0ubuntu1) zesty; urgency=medium
205+ [ Albert Astals Cid ]
206+ * Make menus items close the menu when clicking on them (LP: #1657082,
208+ * Clicking on an open menu closes it + test
209+ * Make the menus and submenus do not go outside the screen when
211+ * Auto open submenus on hover (LP: #1657085)
212+ * Make the double click on a menu not be maximize the window below
214+ * Make the MenuBar InverseMouseArea eat hover events when there's a
215+ popup open (LP: #1657763)
216+ * Make double click on the window decoration maximize (LP: #1657758)
217+ * Eat hover events when the launcher quicklist is open (LP: #1640776)
218+ * Remove TODO now that we require Qt > 5.5
219+ * Serialize two make targets that want to cp to the same target file
221+ * Remove variable that is always false (LP: #1585910)
223+ [ Daniel d'Andrada ]
224+ * Consolidate launcher API checks
227+ * Fixes for activating minimized windows and restoring fullscreen ones
228+ (LP: #1656808, #1658937, #1658938)
231+ * move right edge push area up some levels so it can be used on top of
233+ * fix minimizing/restoring transitions (LP: #1658936)
234+ * fix some glitches with spread positioning
235+ * fix jumpy animation when closing an item from the spread
236+ * Show the wallpaper while the focused app is moving in staged mode
238+ * Update the tutorial to mention the app drawer instead of the dash on
239+ long left edge swipe (LP: #1658932)
240+ * prevent hiding the launcher when the mouse hover event is eaten by
241+ the EdgePushArea (LP: #1657045)
242+ * properly invalidate the whole model (LP: #1658190)
243+ * stabilize OrientedShell test (LP: #1658994)
246+ * Added overflow support to application menus.
247+ * Updated menu colors
249+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 16 Feb 2017 13:49:18 +0000
251+unity8 (8.15+17.04.20170206-0ubuntu1) zesty; urgency=medium
253+ [ Daniel d'Andrada ]
254+ * Initial support for child windows (menus, dialogs, tooltips) (LP:
255+ #1543467, #1591384, #1656727)
257+ -- Albert Astals Cid <albert.astals@canonical.com> Mon, 06 Feb 2017 09:12:23 +0000
259+unity8 (8.15+17.04.20170131.1-0ubuntu1) zesty; urgency=medium
262+ * Remove dependencies on clickscope.
264+ -- Albert Astals Cid <albert.astals@canonical.com> Tue, 31 Jan 2017 14:40:33 +0000
266+unity8 (8.15+17.04.20170124-0ubuntu1) zesty; urgency=medium
268+ [ Albert Astals Cid ]
269+ * Limit tab-focus travelling on dialogs with a fence
270+ * Restore focus to where it was when our ShellDialogs get unloaded
271+ * Update current session after changing the user
272+ * Add keyboard navigation for Indicators
273+ * a window -> the current window
274+ * There's no spreadDelegate_ anymore
276+ [ Daniel d'Andrada ]
277+ * Simplify DecoratedWindow
278+ * Remove unnecessary warning message
281+ * Add a test for the session chooser icon in the greeter's sessions
285+ * Fix keymap not being applied on the shell itself (LP: #1626435)
286+ * Shell dialog improvements (kbd focus, mouse eater)
287+ * Start searching directly as you type, w/o having to first
288+ focus/click the search field.
289+ * Add a test for the real implementation of WindowStateStorage
290+ * Use a four finger gesture to open the drawer, much like in u7
293+ * Simplify the lightdm mock to make future greeter improvements easier
295+ * Add support for guest sessions in unity8-greeter.
296+ * Use a model for PAM prompts, supporting more possible interactions.
297+ * Fix grouping of autopkg output and allow optionally passing
298+ arguments to installed test scripts.
299+ * Add support for LightDM hints for manual logins and hiding normal
303+ * hint the launcher to indicate a successful size change to the user
305+ * Improvements for the appdrawer (LP: #1648173)
306+ * Adjust home key to still focus the dash instead of messing with the
308+ * allow 4 finger simulation with mousetouchadaptor
311+ * Added Alt+F10 shortcut to open app menus. (LP: #1656896)
312+ * Fixed menu layout width calculations. (LP: #1657050)
313+ * Skip Panel::test_drag_indicator_item_down_shows_menu
315+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 24 Jan 2017 07:46:58 +0000
317+unity8 (8.15+17.04.20170110.4-0ubuntu1) zesty; urgency=medium
319+ [ Albert Astals Cid ]
320+ * Give focus to one of the buttons of the dialog
321+ * tst_WindowResizeArea: Use default values for mouseFlick speed and
322+ iterations (LP: #1651580)
323+ * Require Qt 5.6 & misc fixes
326+ * Deprecate usage of Mir's input resampling, instead opting for: (LP:
330+ * Allow the scopes list to automatically scroll when a scope is being
331+ dragged past the bounds of the screen. (LP: #1575319)
334+ * Fix touch window controls being unreachable when the overlay is
335+ being displayed (LP: #1648167)
336+ * Fixup paths for window state storage in snappy environment
337+ * Add Unity.Platform mock for our tests (LP: #1655336)
340+ * PreviewRatingInput: Use displayText instead of text to
341+ enable/disable the Send button (LP: #1595910)
342+ * Add a D-Bus interface to control some debug facilities on the fly
343+ * some launcher workarounds for the snapping
346+ * Nuke leftover Platform in IndicatorsManager
349+ * Added registry for application menus
351+ [ Michael Terry, Nick Dedekind ]
352+ * Run the qmluitests.sh autopkg test against the installed package.
354+ [ Michał Sawicz, Nick Dedekind ]
358+ * Remove the payments widget and dependency on libpay as no longer
361+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 10 Jan 2017 14:48:42 +0000
363+unity8 (8.15+17.04.20161215-0ubuntu2~1) zesty; urgency=medium
367+ -- Timo Jyrinki <timo-jyrinki@ubuntu.com> Wed, 04 Jan 2017 10:54:32 +0200
369+unity8 (8.15+17.04.20161215-0ubuntu1) zesty; urgency=medium
371+ * Let the model deal with some window management decisions (LP:
374+ -- Daniel d'Andrada <daniel.dandrada@canonical.com> Thu, 15 Dec 2016 16:17:29 +0000
376+unity8 (8.15+17.04.20161207.1-0ubuntu1) zesty; urgency=medium
378+ [ Albert Astals Cid ]
379+ * Add the Wsuggest-override flag to gcc
380+ * Add support for compiler sanitizers via ECM
381+ * Use timeStep as delay time (LP: #1642919)
382+ * Bring back fix for 1517830 (LP: #1517830)
383+ * Fix compile warnings in mocks
384+ * Do not hide panel when launching an application if the mouse is on
385+ the panel (LP: #1591311)
387+ [ Daniel d'Andrada ]
388+ * Fix "make tryApplicationWindow"
389+ * Take save/restore functions out of WindowResizeArea
392+ * Enable the greeter to remember which session the user last logged
396+ * Fix the Super key not invoking the dash scope home (LP: #1607427)
399+ * Add the ApplicationDrawer
400+ * tune right edge push (LP: #1646094)
401+ * improve close button visiblity when hovering with the mouse
402+ * Update virtual touchpad visuals and add a tutorial. (LP: #1585220)
405+ * MenuItemFactory: Add subtitle support to SwitchItem widget
407+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 07 Dec 2016 13:49:24 +0000
409+unity8 (8.15+17.04.20161129-0ubuntu1) zesty; urgency=medium
411+ [ Albert Astals Cid ]
412+ * Fix PreviewProgress implicitHeight (LP: #1641943)
413+ * Adapt to dummy notification being gone
414+ * Fix autopilot test_lock_screen tests
415+ * Autopilot: Add more applications to the list for wider screens
416+ * Fix autopilot DashHelperTestCase.test_search
417+ * Also install the Screens mock
418+ * Give default value to gu-px size
421+ * Set Mir.cursorName to "grabbing" on first mouse press on a window
422+ decoration. Don't wait for press+motion. (LP: #1618078)
423+ * Do not show a divider between each quicklist entry but just between
424+ each section, similar to how unity7 does. (LP: #1637478)
427+ * Fix white text (LP: #1644468)
428+ * Make MascotLoader in CardCreator flat
429+ * Make the remaining UbuntuShape flat
430+ * added dropshadow from panel indicators to dash page header extra
431+ panel, so there is right shadow when the extra panel is narrow
432+ * Look up for expandable template dash category flag
435+ * Added a setting to enable/disable the indicator dropdown menu.
437+ [ Daniel d'Andrada ]
438+ * There's no need for WindowDecoration to access the appDelegate
441+ * Enable brightness (laptop backlight) handling on desktop/laptop PCs
445+ * disable spread interaction while locked (LP: #1641578)
447+ [ Andrea Azzarone, Michał Sawicz ]
448+ * Implement launcher tooltips.
451+ * Remove dependency on transitional package. (LP: #1583079)
453+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 29 Nov 2016 09:43:33 +0000
455+unity8 (8.15+17.04.20161116.1-0ubuntu1) zesty; urgency=medium
457+ [ Marco Trevisan (Treviño) ]
458+ * MenuItemFactory: bind calendar backend properties to calendarMenu item
460+ Adds support for showing the calendar at the requested date, marking days
461+ with events properly and toggling the visibility of the week number.
463+ * MenuItemFactory: use Menus.RadioMenu and Menus.ButtonMenu
465+ * Bump version as USC breaks with unity8 << 8.14
467+ [ Albert Astals Cid ]
468+ * [Hopefully] Fix infinite loop in some of the GSV tests (LP:
471+ [ Marco Trevisan (Treviño) ]
472+ * testLauncher: use tryCompare to check launcher contentY
475+ * Stabilize OrientedShell tests
477+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Wed, 16 Nov 2016 10:44:59 +0000
479+unity8 (8.14+17.04.20161109-0ubuntu1) zesty; urgency=medium
481+ [ Albert Astals Cid ]
482+ * Make more CardTool properties readonly
483+ * Make the > in Dash Section Header be after text (LP: #1508905)
484+ * Rework Dash Preview column margins
485+ * Improve LVWPH <-> GenericScopeView interaction (LP: #1508905,
487+ * Make the PreviewButtons be of the width of the button and not half
489+ * Fix first column of the preview table to be 25%
492+ * Remove background under header pagination dots, update dots assets,
493+ remove dash paper background, update bottom edge asset
494+ * Few styling changes for cards
495+ * various tweaks to fonts inside previews
496+ * More visual tweaks
499+ * Add a new setting to enable/disable the launcher
502+ * Stabilize test_doubleTapToMaximizeWindow()
503+ * Enable loading the main Qt catalog which in turn allows for using
505+ * Fix the pixelated notification icon by setting sourceSize (LP:
509+ * More path lookup fixes for running inside of a snap. (LP: #1629009)
512+ * Added blur and darkening to wallpaper while in spread
513+ * Fixes in the spread after design review (LP: #1637502, #1638848)
514+ * More fixes to the unified stages code (LP: #1637205, #1637249,
516+ * Delay alt tab for tiny bit in order to avoid flickering on quick alt-
520+ * Reload Infographics userdata when the day changes (LP: #1378814)
522+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 09 Nov 2016 15:10:32 +0000
524+unity8 (8.14+17.04.20161027-0ubuntu1) zesty; urgency=medium
526+ * MenuItemFactory: activate item on calendar selection change (LP:
529+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Thu, 27 Oct 2016 12:32:25 +0000
531+unity8 (8.14+17.04.20161024-0ubuntu1) zesty; urgency=medium
533+ [ Albert Astals Cid ]
534+ * Make PreviewProgress be thicker again (LP: #1629382)
535+ * tst_PreviewZoomableImage: Wait for LazyImage transitions on init()
539+ * Remove UbuntuShapeForItem and replace its use with the more standard
540+ Ubuntu.Components.UbuntuShape.
543+ * Restore the double tap decoration to maximize feature (LP: #1627281)
544+ * Hide the cursor for fullscreen apps after 3 seconds of inactivity
545+ * Implement moving windows by Alt + left mouse button
547+ [ Marco Trevisan (Treviño) ]
548+ * MenuItemFactory: use more features from SlotsLayout based settings
552+ * Grab launcher icon information from ubuntu-app-launch, not directly
554+ * Adjust root paths if we're running inside a snap. (LP: #1629009)
557+ * Merge all Stages into one single codebase. Apply new spread visuals.
558+ (LP: #1489517, #1603914, #1635800)
560+ -- Michael Zanetti <michael.zanetti@canonical.com> Mon, 24 Oct 2016 11:37:28 +0000
562+unity8 (8.14+16.10.20160922-0ubuntu2) yakkety; urgency=medium
565+ - Drop unity-scope-mediascanner2 to a Suggests rather than a Recommends,
566+ to ease our transition to main. It's already seeded directly in
567+ Touch, so this will only affect the Desktop variant of unity8.
569+ -- Michael Terry <mterry@ubuntu.com> Mon, 03 Oct 2016 10:43:25 -0400
571+unity8 (8.14+16.10.20160922-0ubuntu1) yakkety; urgency=medium
573+ [ Albert Astals Cid ]
574+ * LVWPH: update clipItem height when list height changes (LP:
576+ * Put the touchdown shape inside a loader
577+ * No need for the touchdown in the card for the cardtool
578+ * Add bottom gradient to the Show Less floating button
579+ * Remove artShapeSize from non cardtool cards
580+ * LVWPH: Fix case in which header was shown incorrectly
581+ * LVWPH: Fix items cut on top in the dash (or at least some instances
583+ * Reduce calls to CardCreatorCache.getCardComponent while the
584+ component is being created (LP: #1615675)
585+ * Dash::test_cardIconStyle change compare into tryCompareFunction
586+ * Make PreviewActionsTest::test_comboButton more stable
587+ * Adapt onShiftedContentXChanged to work when the content changes very
589+ * Make tryGenericScopeView show the scope correctly
590+ * Make sure the spinner does not get too close to the title text (LP:
592+ * Show "Pull to refresh" in white when overlaid in low luminance
593+ colors (LP: #1596849)
594+ * Make test_Shell non ultra slow again (LP: #1597366)
595+ * Improve findChild calls inside tryCompareFunction.
598+ * override some Qt Components definitions so we can have sane default
599+ values for flick speeds
600+ * Elide the label text inside recent searches panel (LP: #1611796)
601+ * Add a PreviewSingleton module to store some data for previews (LP:
603+ * Use PreviewSingleton for PreviewRatingInput and PreviewCommentInput
605+ * rework GenericScopeView PullToRefresh test
606+ * use mouseFlick instead touchFlick for manage_dash_move_current
607+ * add a couple of waiting tricks for a flaky dash test
609+ [ Daniel d'Andrada ]
610+ * Set progress bar indeterminate when processing signal received. (LP:
612+ * Implement cursor confinement (LP: #1590099)
615+ * Add a frontend to the sessions model and enable a session chooser in
619+ * Implement edge maximizing (aka window snapping) (LP: #1602628)
620+ * On the PC platform (as opposed to running on $devices), use the
621+ "mute" action instead of silent mode
622+ * Respect Fitt's law wrt the window control buttons in panel (LP:
624+ * Fix 2 failing color-related tests
626+ [ Marco Trevisan (Treviño) ]
627+ * Indicators, mocks: add fake indicators menuitem to populate mocks
628+ with different menu types
629+ * IndicatorsClient: use PageHeader and ListItemLayout's
632+ * Support launching apps inside a unity8 session from the greeter and
633+ support emergency dialing inside the greeter.
634+ * Fix tryShell to actually show appropriate backgrounds for each mock
636+ * Add an indicator to the greeter when a user is logged in (only shown
637+ if we have more than one user)
638+ * Hide the greeter OSK if indicators are open and don't show the edge
639+ tutorial during an emergency call.
640+ * Switch from lockscreen PIN pad to a passcode entry box that uses the
642+ * Use the default system wallpaper instead of our custom one.
643+ * Update look of infographic a bit
644+ * Make infographic bubbles white even on the default wallpaper.
646+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 22 Sep 2016 07:46:57 +0000
648+unity8 (8.14+16.10.20160831.3-0ubuntu1) yakkety; urgency=medium
650+ [ Daniel d'Andrada ]
651+ * Added implementation for MirSurfaceInterface::persistentId
653+ -- Ken VanDine <ken.vandine@canonical.com> Wed, 31 Aug 2016 11:56:09 +0000
655+unity8 (8.14+16.10.20160826-0ubuntu1) yakkety; urgency=medium
657+ * Make sure we emit sounds when taking a screenshot even after media-
660+ -- Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com> Fri, 26 Aug 2016 08:14:14 +0000
662+unity8 (8.14+16.10.20160819-0ubuntu1) yakkety; urgency=medium
665+ * Reset topmostIsFullscreen to correctly rotate the shell when
666+ dismissing SIM PIN screen (LP: #1614070)
668+ -- Michał Sawicz <michal.sawicz@canonical.com> Fri, 19 Aug 2016 14:16:54 +0000
670+unity8 (8.14+16.10.20160811.1-0ubuntu1) yakkety; urgency=medium
672+ [ Albert Astals Cid ]
673+ * Take into account carousel selectedItemScaleFactor when setting card
674+ fixedArtShapeSize (LP: #1599238)
675+ * Remove unused LimitProxyModel
676+ * Do not calculate implicitHeight for Cards in a CardGrid
679+ [ Daniel d'Andrada ]
680+ * Remove stage property from Application
683+ * Allow libertine-scope to show empty search result hint unmodified.
687+ * Open the quicklist (context) menu also using the Menu key (LP:
689+ * Fix incorrect SIM PIN dialog position when entering a wrong PIN (LP:
691+ * Apply the correct keymap also on prompt surfaces (LP: #1610124)
692+ * Implement an optional system update feature during OOBE wizard (LP:
694+ * Implement a page for choosing HW keyboard layout in OOBE wizard
697+ * Clean up some build script legacy
698+ * Add a crossbuilder_post file to make crossbuilder restart unity8
700+ * fixes for the automatic switching between usage modes (LP: #1590944)
703+ * Add object names for setup wizard
705+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 11 Aug 2016 06:28:20 +0000
707+unity8 (8.14+16.10.20160803-0ubuntu1) yakkety; urgency=medium
709+ [ Albert Astals Cid ]
710+ * Fix DisabledScreenNotice::test_rotation
711+ * Make the delegate of DashNavigationList an async Loader
712+ * unity-scope-tool: Use parse instead of process
713+ * VerticalJournal improvements regarding model insertions and item
714+ height changes (LP: #1599754)
715+ * Add math.h includes for compilation in yakkety (LP: #1605502)
718+ * Unfocus the search text field in the dash page header when requested
720+ * Use binding for filter popover contentWidth (LP: #1595116)
721+ * Add few sourceSize for Image we forgot (LP: #1595113)
722+ * Replace Flickable with an Item inside DashPageHeader for
723+ headerContainer (LP: #1599235)
725+ [ Albert Astals Cid, Andrea Cimitan ]
726+ * Unbox the artshapeLoader
728+ [ Daniel d'Andrada ]
729+ * Fix splashscreen orientation when app rotates own contents (LP:
731+ * tst_PreviewIconActions: Make test name match filename
732+ * Cursor: make its size grid unit based (LP: #1604014)
733+ * TouchEventSequenceWrapper: item might get deleted when touch
734+ sequence is committed (LP: #1607686)
737+ * Implement frontend support for running keyboard indicator
738+ * Provide window/surface close shortcuts across all the stages (LP:
740+ * Restart the location trust prompt service when exiting the wizard
742+ * Implement clearing the search and closing the panel on pressing
743+ Escape key in the dash header
744+ * Fix log timestamps (LP: #1602196)
745+ * Don't display the mode switch warning dialog on tablets (LP:
749+ * Fix indicator profile bug that caused sound indicator to say Mute
750+ instead of Silent Mode. (LP: #1604205)
751+ * Fix lockscreen appearing right after unlocking a locked session on
752+ the desktop. (LP: #1604374)
755+ * Add arm64 support, drop unnecessary B-D on web plugin
757+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 03 Aug 2016 15:56:27 +0000
759+unity8 (8.14+16.10.20160728-0ubuntu1) yakkety; urgency=medium
762+ * Bump the version to secure UITK compatibility
764+ [ Albert Astals Cid ]
765+ * Pass the correct number of arguments to mapToItem (LP: #1606835)
767+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 28 Jul 2016 08:17:13 +0000
769+unity8 (8.13+16.10.20160714+fix1-0ubuntu2~1) yakkety; urgency=medium
771+ * Rebuild against Qt 5.6.
772+ * Add https://code.launchpad.net/~aacid/unity8/floor_includes/+merge/300850
774+ -- Timo Jyrinki <timo-jyrinki@ubuntu.com> Fri, 22 Jul 2016 09:03:54 +0300
776+unity8 (8.13+16.10.20160714-0ubuntu1) yakkety; urgency=medium
778+ [ Daniel d'Andrada ]
779+ * Make use of MirSurface::inputBounds and drop UbuntuKeyboardInfo hack
781+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 14 Jul 2016 07:09:29 +0000
783+unity8 (8.12+16.10.20160711-0ubuntu1) yakkety; urgency=medium
786+ * Add a SessionsModel to lightdm to support the greeter's session
788+ * Add unity8-greeter package which contains a basic, but usable
789+ LightDM greeter. (LP: #1324602)
792+ * Make sure indicators and launcher hide when power button is pressed
793+ on greeter. (LP: #1595569)
794+ * Fix tablet greeter focus to be always-on, no longer hiding the OSK
795+ or forcing a mouse click to type a password. (LP: #1435923)
797+ -- Michael Terry <michael.terry@canonical.com> Mon, 11 Jul 2016 17:24:20 +0000
799+unity8 (8.12+16.10.20160707-0ubuntu1) yakkety; urgency=medium
802+ * emit the correct role changed signal on count visible changed (LP:
805+ -- Michał Sawicz <michal.sawicz@canonical.com> Thu, 07 Jul 2016 16:49:32 +0000
807+unity8 (8.12+16.10.20160705-0ubuntu1) yakkety; urgency=medium
810+ * don't displace windows if the OSK is on another screen (LP:
813+ -- Michał Sawicz <michal.sawicz@canonical.com> Tue, 05 Jul 2016 10:00:57 +0000
815+unity8 (8.12+16.10.20160627.5-0ubuntu1) yakkety; urgency=medium
817+ [ Albert Astals Cid ]
818+ * Stop watching the old header item height once it's not our header
820+ * LVWPH: cull the header item when not on view to save some painting
821+ * Adapt test to new mock behaviour
822+ * Don't let the mouse go outside the parentItem (LP: #1525350)
823+ * Use non deprecated package names
824+ * Mark system includes as such
825+ * Fix initialization order warning
826+ * Do not rely on deleteLater not crashing on null pointers
827+ * Add more headers of classes we use for automoc to be run
828+ * CardTool: Fix the fallback value to be a size and not an integer
829+ * CardTool: Include Ubuntu Components since we're using units.gu
830+ * Rework tst_PreviewRatingDisplayCreationRanges
832+ [ Daniel d'Andrada ]
833+ * Cursor: Let AnimatedSprite run only on animated cursors and while
834+ the display is on (LP: #1588873, #1594358)
835+ * Fix missing screenshot when orientation changes while shell rotation
836+ ongoing (LP: #1587796)
839+ * Make PreviewRatingSingleDisplay visible again after editing a
840+ review. (LP: #1587097)
841+ * Correct errors in all png images to prevent libpng warnings.
844+ * Fix some smaller issues with OOBE wizard password pages (LP:
846+ * Prevent mouse wheel events from going through shell elements (LP:
848+ * Do not let mouse and wheel events pass thru the titlebar (LP:
850+ * Hide the maximize window button based on size restrictions (LP:
853+ [ Marco Trevisan (Treviño) ]
854+ * Unity8.conf: ensure MIR_SOCKET is set for future customers (such as
856+ * ClientIndicator: be more informative about loading failures for
857+ dynamically created objects
860+ * Stop unity8 from getting in a "switch-to-greeter" loop when locking
861+ on a desktop. (LP: #1593718)
864+ * set minimum window sizes on dash
865+ * displace application windows when the OSK would cover them
868+ * Force dash to always stay in the main stage. (lp:#1592404) (LP:
870+ * Save the last surface stage on stage drop. (LP: #1579003)
871+ * Default portrait only apps to the side stage. (LP: #1573153)
873+ [ Albert Astals Cid, Andrea Cimitan, Michał Sawicz, Nick Dedekind ]
874+ * Added live video playback in dash previews
876+ -- Michael Zanetti <michael.zanetti@canonical.com> Mon, 27 Jun 2016 18:48:59 +0000
878+unity8 (8.12+16.10.20160620.3-0ubuntu1) yakkety; urgency=medium
880+ [ Michael Terry, Michał Sawicz ]
881+ * Support unlocking via fingerprint, if one is registered.
883+ -- Michael Terry <michael.terry@canonical.com> Mon, 20 Jun 2016 20:25:25 +0000
885+unity8 (8.12+16.10.20160617-0ubuntu1) yakkety; urgency=medium
888+ * Do not create Label/Icon if we don't need it
889+ * Fix Z-ordering of prompt surfaces (LP: #1586219)
890+ * Drop bottom edge tutorials completely and small fixes for other
891+ edges. (LP: #1565103)
892+ * Redo visuals for greeter prompt box. (LP: #1435923)
893+ * Make tutorial qmltests more robust. (LP: #1590810)
894+ * Stop showing an extra lockscreen in desktop unity8 sessions. (LP:
897+ [ Albert Astals Cid ]
898+ * Improve dash plugin mock
899+ * Stabilize PreviewExpandableTest::test_all_widgets_height
900+ * Workaround QTBUG-53460
901+ * Split artShape code for cardTool card and regular card
902+ * Simplify the code since fixedArtSize code is mandatory for regular
904+ * Desktop stage: Support rotatesWindowContents (LP: #1547481)
905+ * Turn if if else into if elseif else
906+ * Fix leaks in QInputDeviceManagerPrivate::addDevice
907+ * Do not call |= on uninitialized sigterm.sa_flags
908+ * initialize udevMonitor
909+ * Make notifier and notifierFd function local variables
910+ * Fix crash if a component that is not an Item is given to
912+ * Tests: Do not use dynamic_cast if we're not going to test it anyway
913+ * Minor coverity fixes
914+ * Fix warning about anchors.fill in ProportionalShape (LP: #1590963)
915+ * Make wait in cleanup() wait for snapTo animation to have finished
917+ [ Alexandros Frantzis ]
918+ * Improve the way notifications interact with power management (LP:
922+ * Correctly refresh cardcreator cache on artshapestyle changes (LP:
924+ * Same tweaks we have for click scope now for libertine
925+ * add a timer to pull to refresh to work on small windows (LP:
928+ [ Daniel d'Andrada ]
929+ * Clean up debug leftovers
930+ * Ensure mouse and window movement are pixel-aligned (LP: #1510382)
931+ * Fix SpreadDelegate rotation animations
932+ * No point in version-controlling files that are automatically
934+ * Center cursor on screen when it's first shown
935+ * Custom cursor name just have to start with "custom"
936+ * Work around AnimatedSprite infinite loop bug (LP: #1588929)
939+ * Disable showDash when it is already shown. (LP: #1506708)
940+ * Add a timestamp to the dash log (LP: #1580074)
941+ * Add timestamp to unity8 log (LP: #1498169)
944+ * Implement keyboard shortcuts info panel
945+ * Implement window controls overlay activatable with 3 fingers tap
947+ * Select correct Chinese input method for OSK in the wizard (LP:
951+ * Add support for the launcher surface pips displaying the correct
953+ * Add support for the persistent alert state. (LP: #1575147, #1584348,
955+ * send a Alt-release event on alt+tab instead of delaying it
956+ completely and invoking it later (LP: #1565236)
959+ * added a new upstart $SESSION for unity8-desktop-session (LP:
962+ -- Michael Terry <michael.terry@canonical.com> Fri, 17 Jun 2016 01:22:57 +0000
964+unity8 (8.12+16.10.20160601.1-0ubuntu1) yakkety; urgency=medium
967+ * Added apparmor profile for unity8-dash.
969+ -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 01 Jun 2016 20:59:03 +0000
1unity8 (8.12+16.10.20160527-0ubuntu1) yakkety; urgency=medium
971unity8 (8.12+16.10.20160527-0ubuntu1) yakkety; urgency=medium
3 [ Albert Astals Cid ]
973 [ Albert Astals Cid ]
@@ -254,7 +1224,7 @@ unity8 (8.12+16.04.20160330-0ubuntu1) xenial; urgency=medium
254unity8 (8.12+16.04.20160323.2-0ubuntu1) xenial; urgency=medium
1224unity8 (8.12+16.04.20160323.2-0ubuntu1) xenial; urgency=medium
256 [ Michael Terry ]
1226 [ Michael Terry ]
258 * Fix setting OSK layout in OOBE wizard
1228 * Fix setting OSK layout in OOBE wizard
259 * Stop the left edge tutorial from being shown when the bottom edge
1229 * Stop the left edge tutorial from being shown when the bottom edge
260 tutorial wants to be shown after receiving a call.
1230 tutorial wants to be shown after receiving a call.
@@ -2966,7 +3936,7 @@ unity8 (8.00+14.10.20140729-0ubuntu1) utopic; urgency=medium
2966 * Re-architecture unity8 to use the QtMirCompositor library so that
3936 * Re-architecture unity8 to use the QtMirCompositor library so that
2967 the Qt scenegraph renderer is used as the Mir compositor, and
3937 the Qt scenegraph renderer is used as the Mir compositor, and
2968 application surfaces are added to the QML scene as items.
3938 application surfaces are added to the QML scene as items.
2970 [ Michael Zanetti ]
3940 [ Michael Zanetti ]
2971 * Port phone right-edge spread code to use QtCompositor
3941 * Port phone right-edge spread code to use QtCompositor
2972 * Add right-edge spread animation for tablet
3942 * Add right-edge spread animation for tablet
@@ -3240,8 +4210,8 @@ unity8 (7.90+14.10.20140703.1-0ubuntu1) utopic; urgency=low
3241unity8 (7.90+14.10.20140701.2-0ubuntu2) utopic; urgency=medium
4211unity8 (7.90+14.10.20140701.2-0ubuntu2) utopic; urgency=medium
3243− * debian/control:
4213+ * debian/control:
3244− list qtdeclarative5-ubuntu-ui-toolkit-plugin-gles as an alternative
4214+ list qtdeclarative5-ubuntu-ui-toolkit-plugin-gles as an alternative
3245 choice, since provides are not versionned, should restore installability
4215 choice, since provides are not versionned, should restore installability
3246 on amd64 and i386
4216 on amd64 and i386
@@ -6343,7 +7313,7 @@ unity8 (7.81.2) saucy; urgency=low
6343 [ Michał Sawicz ]
7313 [ Michał Sawicz ]
6344 * Fix icons in ApplicationsFilterGrid.qml.
7314 * Fix icons in ApplicationsFilterGrid.qml.
6345 * Support flipped image in run_on_device.
7315 * Support flipped image in run_on_device.
6347 [ Michael Zanetti ]
7317 [ Michael Zanetti ]
6348 * Don't clear lockscreen when it's fading out.
7318 * Don't clear lockscreen when it's fading out.
6349 * Reworked Launcher folding.
7319 * Reworked Launcher folding.
@@ -6428,7 +7398,7 @@ qml-phone-shell (1.79) raring; urgency=low
6429 [ Michael Terry ]
7399 [ Michael Terry ]
6430 * Make greeter look like the desktop one
7400 * Make greeter look like the desktop one
6432 [ Gerry Boland ]
7402 [ Gerry Boland ]
6433 * Fix a bug where a minimized app gets focus after closing another app
7403 * Fix a bug where a minimized app gets focus after closing another app
6434 * Applied a workaround to reduce flickering when launching apps
7404 * Applied a workaround to reduce flickering when launching apps
@@ -6444,7 +7414,7 @@ qml-phone-shell (1.79) raring; urgency=low
6444qml-phone-shell (1.78) raring; urgency=low
7414qml-phone-shell (1.78) raring; urgency=low
6446 [ Sergio Schvezov ]
7416 [ Sergio Schvezov ]
6447− * Replacing the music and ski safari mock apps with calendar and weather in
7417+ * Replacing the music and ski safari mock apps with calendar and weather in
6448 the launcher (LP: #1178262).
7418 the launcher (LP: #1178262).
6450 [ Daniel d'Andrada ]
7420 [ Daniel d'Andrada ]
@@ -6486,7 +7456,7 @@ qml-phone-shell (1.77) raring; urgency=low
6486 [ Mathieu Trudel-Lapierre ]
7456 [ Mathieu Trudel-Lapierre ]
6487 * debian/control:
7457 * debian/control:
6488 - Drop indicators-client-plugin* Depends for qml-phone-shell to Recommends.
7458 - Drop indicators-client-plugin* Depends for qml-phone-shell to Recommends.
6489− - Add/update Vcs-Browser, Vcs-Bzr and add a notice to uploaders.
7459+ - Add/update Vcs-Browser, Vcs-Bzr and add a notice to uploaders.
6490 * debian/copyright: fix syntax.
7460 * debian/copyright: fix syntax.
6492 [ Michał Sawicz ]
7462 [ Michał Sawicz ]
@@ -6496,7 +7466,7 @@ qml-phone-shell (1.77) raring; urgency=low
6496 * Renamed Media player files to match with new application name.
7466 * Renamed Media player files to match with new application name.
6498 [ Daniel d'Andrada ]
7468 [ Daniel d'Andrada ]
6499− * New: DirectionalDragArea component. An area that detects axis-aligned
7469+ * New: DirectionalDragArea component. An area that detects axis-aligned
6500 single-finger drag gestures.
7470 single-finger drag gestures.
6501 * Make it possible to send touch events from within QML test code.
7471 * Make it possible to send touch events from within QML test code.
@@ -6933,7 +7903,7 @@ qml-phone-shell (1.39) quantal; urgency=low
6934qml-phone-shell (1.38) quantal; urgency=low
7904qml-phone-shell (1.38) quantal; urgency=low
6936− * fix launching of notepad
7906+ * fix launching of notepad
6938 -- Bill Filler <bill.filler@canonical.com> Fri, 01 Feb 2013 03:21:29 -0500
7908 -- Bill Filler <bill.filler@canonical.com> Fri, 01 Feb 2013 03:21:29 -0500
@@ -6946,14 +7916,14 @@ qml-phone-shell (1.37) quantal; urgency=low
6947qml-phone-shell (1.36) quantal; urgency=low
7917qml-phone-shell (1.36) quantal; urgency=low
6949− * launch real notepad app
7919+ * launch real notepad app
6950 * fix launching of mock apps
7920 * fix launching of mock apps
6952 -- Bill Filler <bill.filler@canonical.com> Thu, 31 Jan 2013 21:36:05 -0500
7922 -- Bill Filler <bill.filler@canonical.com> Thu, 31 Jan 2013 21:36:05 -0500
6954qml-phone-shell (1.35) quantal; urgency=low
7924qml-phone-shell (1.35) quantal; urgency=low
6956− * integrate ubuntu-browser instead of snowshoe
7926+ * integrate ubuntu-browser instead of snowshoe
6958 -- Bill Filler <bill.filler@canonical.com> Thu, 31 Jan 2013 17:33:37 -0500
7928 -- Bill Filler <bill.filler@canonical.com> Thu, 31 Jan 2013 17:33:37 -0500
@@ -7037,7 +8007,7 @@ qml-phone-shell (1.22) quantal; urgency=low
7038qml-phone-shell (1.21) quantal; urgency=low
8008qml-phone-shell (1.21) quantal; urgency=low
7040− * New release with fullscreen launcher fixes
8010+ * New release with fullscreen launcher fixes
7042 -- Bill Filler <bill.filler@canonical.com> Fri, 07 Dec 2012 09:36:37 +0000
8012 -- Bill Filler <bill.filler@canonical.com> Fri, 07 Dec 2012 09:36:37 +0000
@@ -7049,7 +8019,7 @@ qml-phone-shell (1.20) quantal; urgency=low
7050qml-phone-shell (1.19) quantal; urgency=low
8020qml-phone-shell (1.19) quantal; urgency=low
7052− * enable multi-threaded render for apps
8022+ * enable multi-threaded render for apps
7054 -- Bill Filler <bill.filler@canonical.com> Wed, 05 Dec 2012 17:34:09 +0000
8024 -- Bill Filler <bill.filler@canonical.com> Wed, 05 Dec 2012 17:34:09 +0000
@@ -7057,7 +8027,7 @@ qml-phone-shell (1.18) quantal; urgency=low
7058 [ Bill Filler ]
8028 [ Bill Filler ]
7059 * update launcher to use wk2-render (chromeless webkit) for facebook
8029 * update launcher to use wk2-render (chromeless webkit) for facebook
7060− and twitter
8030+ and twitter
7062 -- Florian Boucault <florian.boucault@canonical.com> Wed, 05 Dec 2012 12:20:50 +0000
8032 -- Florian Boucault <florian.boucault@canonical.com> Wed, 05 Dec 2012 12:20:50 +0000
@@ -7069,7 +8039,7 @@ qml-phone-shell (1.17) quantal; urgency=low
7070qml-phone-shell (1.16) quantal; urgency=low
8040qml-phone-shell (1.16) quantal; urgency=low
7072− * fix to launch new gallery with correct args
8042+ * fix to launch new gallery with correct args
7074 -- Bill Filler <bill.filler@canonical.com> Thu, 29 Nov 2012 17:04:36 -0500
8044 -- Bill Filler <bill.filler@canonical.com> Thu, 29 Nov 2012 17:04:36 -0500
@@ -7131,7 +8101,7 @@ qml-phone-shell (1.2) quantal; urgency=low
7132qml-phone-shell (1.1) quantal; urgency=low
8102qml-phone-shell (1.1) quantal; urgency=low
7134− * comment out console.log() to prevent crash
8104+ * comment out console.log() to prevent crash
7136 -- Bill Filler <bill.filler@canonical.com> Sun, 28 Oct 2012 22:18:36 +0100
8106 -- Bill Filler <bill.filler@canonical.com> Sun, 28 Oct 2012 22:18:36 +0100
@@ -7159,19 +8129,19 @@ qml-phone-shell (0.7) quantal; urgency=low
7159 * qml-phone-shell.conf: better setup of env vars and launch
8129 * qml-phone-shell.conf: better setup of env vars and launch
7160 via dbus-luanch to properly setup session bus
8130 via dbus-luanch to properly setup session bus
7161 * shellapplication.cpp: don't setup custom env before launching
8131 * shellapplication.cpp: don't setup custom env before launching
7162− processes
8132+ processes
7164 -- Bill Filler <bill.filler@canonical.com> Sun, 21 Oct 2012 11:32:42 +0200
8134 -- Bill Filler <bill.filler@canonical.com> Sun, 21 Oct 2012 11:32:42 +0200
7166qml-phone-shell (0.6) quantal; urgency=low
8136qml-phone-shell (0.6) quantal; urgency=low
7168− * added additional Android env vars to upstart script
8138+ * added additional Android env vars to upstart script
7170 -- Bill Filler <bill.filler@canonical.com> Fri, 19 Oct 2012 09:35:25 -0400
8140 -- Bill Filler <bill.filler@canonical.com> Fri, 19 Oct 2012 09:35:25 -0400
7172qml-phone-shell (0.5) quantal; urgency=low
8142qml-phone-shell (0.5) quantal; urgency=low
7174− * added support to launch telephony-app
8144+ * added support to launch telephony-app
7176 -- Bill Filler <bill.filler@canonical.com> Thu, 18 Oct 2012 13:45:25 -0400
8146 -- Bill Filler <bill.filler@canonical.com> Thu, 18 Oct 2012 13:45:25 -0400
@@ -7198,3 +8168,8 @@ qml-phone-shell (0.1) quantal; urgency=low
7198 * Initial release
8168 * Initial release
7200 -- Bill Filler <bill.filler@canonical.com> Wed, 10 Oct 2012 10:19:53 -0400
8170 -- Bill Filler <bill.filler@canonical.com> Wed, 10 Oct 2012 10:19:53 -0400
8171+unity8 (8.15+17.04.20170404.7-0ubuntu2) zesty; urgency=medium
8173+ [ Michael Zanetti ]
8174+ * Make the default store uri point to gnome software center
@@ -2,196 +2,224 @@ Source: unity8
2Section: x11
2Section: x11
3Priority: optional
3Priority: optional
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5−Build-Depends: cmake,
5+Build-Depends:
6− dbus-test-runner,
9+ dbus-test-runner,
7− debhelper (>= 9),
10+ debhelper (>= 9),
9−# To allow cross-compiling to work, we also must append :native
10−# to g++ so we don't try to run armhf g++
11−# on an x86 CPU for example, when cross-compiling.
12− g++:native,
13+ g++:native,
14− graphviz,
15+ graphviz,
15− gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
16+ gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
16− libandroid-properties-dev,
17+ libandroid-properties-dev,
17− libconnectivity-qt1-dev (>= 0.7.1),
18+ libconnectivity-qt1-dev (>= 0.7.1),
18− libevdev-dev,
19+ libevdev-dev,
19− libgeonames-dev (>= 0.2),
20+ libgeonames-dev (>= 0.2),
20− libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
21+ libgl1-mesa-dev[!arm64 !armhf] | libgl-dev[!arm64 !armhf],
21− libgl1-mesa-dri,
22+ libgl1-mesa-dri,
22− libgles2-mesa-dev[armhf],
23+ libgles2-mesa-dev[arm64 armhf],
23− libglib2.0-dev,
24+ libglib2.0-dev,
25+ libgnome-desktop-3-dev,
24− libgsettings-qt-dev,
26+ libgsettings-qt-dev,
25− libhardware-dev,
27+ libhardware-dev,
28+ liblightdm-qt5-3-dev,
26− libpam0g-dev,
29+ libpam0g-dev,
28− libpulse-dev,
30+ libpulse-dev,
29− libqmenumodel-dev (>= 0.2.9),
31+ libqmenumodel-dev (>= 0.2.12),
30− libqt5svg5-dev,
33+ libqt5svg5-dev,
31− libqt5xmlpatterns5-dev,
34+ libqt5xmlpatterns5-dev,
35+ libqtdbusmock1-dev (>= 0.7),
32− libsystemsettings-dev,
37+ libsystemsettings-dev,
38+ libubuntu-app-launch2-dev,
39+ libubuntu-download-manager-common-dev,
33− libubuntugestures5-dev,
40+ libubuntugestures5-dev (>= 1.3.2030),
34− libubuntugestures5-private-dev,
41+ libubuntugestures5-private-dev (>= 1.3.2030),
35− libudev-dev,
42+ libudev-dev,
36− libunity-api-dev (>= 7.113),
44+ libunity-api-dev (>= 8.7),
37− libusermetricsoutput1-dev,
45+ libusermetricsoutput1-dev,
38−# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
39− libx11-dev[!armhf],
46+ libx11-dev[!arm64 !armhf],
40− libxcb1-dev[!armhf],
47+ libxcb1-dev[!arm64 !armhf],
41− libxi-dev[!armhf],
48+ libxi-dev[!arm64 !armhf],
43− pkg-config,
49+ pkg-config,
44− python3-all:any,
50+ python3-all:any,
45− python3-setuptools,
51+ python3-setuptools,
46− qml-module-qt-labs-folderlistmodel,
52+ qml-module-qt-labs-folderlistmodel,
53+ qml-module-qt-labs-settings,
54+ qml-module-qtmultimedia (>= 5.6),
55+ qml-module-qtqml-statemachine,
47− qml-module-qtquick-layouts,
56+ qml-module-qtquick-layouts,
48− qml-module-qtquick-xmllistmodel,
57+ qml-module-qtquick-xmllistmodel,
49− qml-module-qtquick2,
58+ qml-module-qtquick2,
50− qml-module-qtsysteminfo,
59+ qml-module-qtsysteminfo,
51− qml-module-qttest,
60+ qml-module-qttest,
52− qt5-default,
61+ qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
62+ qml-module-ubuntu-layouts,
63+ qml-module-ubuntu-settings-components,
64+ qml-module-ubuntu-test,
53− qtbase5-dev (>= 5.4),
65+ qtbase5-dev (>= 5.6),
54− qtbase5-dev-tools,
66+ qtbase5-dev-tools,
55− qtbase5-private-dev (>= 5.4),
67+ qtbase5-private-dev (>= 5.6),
56− qtdeclarative5-dev (>= 5.4),
69+ qtdeclarative5-dev (>= 5.6),
57− qtdeclarative5-dev-tools,
70+ qtdeclarative5-dev-tools,
58− qtdeclarative5-private-dev (>= 5.4),
71+ qtdeclarative5-private-dev (>= 5.6),
59− qtdeclarative5-qtmultimedia-plugin (>= 5.4.1-1ubuntu19~overlay2),
60− qtdeclarative5-ubuntu-content1,
72+ qtdeclarative5-ubuntu-content1,
61− qtdeclarative5-ubuntu-settings-components (>= 0.7),
62− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
63− qtdeclarative5-ubuntu-web-plugin,
64− ttf-ubuntu-font-family,
73+ ttf-ubuntu-font-family,
66Standards-Version: 3.9.4
76Standards-Version: 3.9.4
67−Homepage: http://launchpad.net/unity
77+Homepage: https://github.com/ubports/unity8
68−# If you aren't a member of ~unity-team but need to upload
78+Vcs-Git: https://github.com/ubports/unity8
69−# packaging changes, just go ahead. ~unity-team will notice
70−# and sync up the code again.
71−Vcs-Bzr: https://code.launchpad.net/unity8
72−Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
73XS-Testsuite: autopkgtest
79XS-Testsuite: autopkgtest
74X-Ubuntu-Use-Langpack: yes
80X-Ubuntu-Use-Langpack: yes
76Package: indicators-client
82Package: indicators-client
77−Architecture: amd64 armhf i386
83+Architecture: any
78−Depends: qmenumodel-qml (>= 0.2.9),
85+ qmenumodel-qml (>= 0.2.11),
79− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
86+ qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
80− unity8 (= ${binary:Version}),
87+ unity8 (= ${binary:Version}),
81− ${misc:Depends},
88+ ${misc:Depends},
82− ${shlibs:Depends},
89+ ${shlibs:Depends},
83Description: Indicators client test application
90Description: Indicators client test application
84 This package contains the client application for indicators used by autopilot
91 This package contains the client application for indicators used by autopilot
86−Package: unity-scope-tool
93+Package: unity8-greeter
87Architecture: any
94Architecture: any
88−Depends: unity8-common (= ${source:Version}),
95+Depends:
96+ unity-system-compositor,
89− unity8-private (= ${binary:Version}),
97+ unity8 (= ${binary:Version}),
90− ${misc:Depends},
98+ ${misc:Depends},
91− ${shlibs:Depends},
99+ ${shlibs:Depends},
92−# We do call pkg-config libunity-scopes from the code
100+Recommends:
93− pkg-config,
101+ lightdm,
94− libunity-scopes-dev,
102+Provides:
95−Description: Development tool for Unity scopes
103+ lightdm-greeter,
96− This package contains the development tool for new generation Unity scopes, based
104+Description: The Unity8 Greeter
97− on Unity8.
105+ The Unity 8 greeter is the primary login greeter for Ubuntu devices.
99Package: unity8
107Package: unity8
100Architecture: any
108Architecture: any
101−Provides: indicator-renderer,
110+ indicator-renderer,
102−Depends: dmz-cursor-theme,
112+ dmz-cursor-theme,
103− gsettings-desktop-schemas,
113+ gsettings-desktop-schemas,
104− libcap2-bin,
114+ libcap2-bin,
105− libglib2.0-bin,
115+ libglib2.0-bin,
106− qmenumodel-qml (>= 0.2.9),
116+ qmenumodel-qml (>= 0.2.11),
117+ qml-module-biometryd,
107− qml-module-qt-labs-folderlistmodel,
118+ qml-module-qt-labs-folderlistmodel,
119+ qml-module-qt-labs-settings,
120+ qml-module-qtqml-statemachine,
108− qml-module-qtquick-xmllistmodel,
121+ qml-module-qtquick-xmllistmodel,
109− qml-module-qtsysteminfo,
122+ qml-module-qtsysteminfo,
110− qtdeclarative5-qtmir-plugin (>= 0.4.8),
123+ qtdeclarative5-qtmir-plugin (>= 0.4.8),
111− qtdeclarative5-ubuntu-telephony0.1,
124+ qtdeclarative5-ubuntu-telephony0.1,
112− qtdeclarative5-ubuntu-web-plugin,
113− ubuntu-system-settings (>= 0.4),
125+ ubuntu-system-settings (>= 0.4),
114− unity-launcher-impl-7,
126+ unity-launcher-impl-13,
115− unity8-common (= ${source:Version}),
127+ unity8-common (= ${source:Version}),
116− unity8-private (= ${binary:Version}),
128+ unity8-private (= ${binary:Version}),
117− unity8-private | unity-launcher-impl,
129+ unity8-private | unity-launcher-impl,
118− ${misc:Depends},
130+ ${misc:Depends},
119− ${shlibs:Depends},
131+ ${shlibs:Depends},
120−Recommends: indicator-session,
132+Recommends:
121− unity-scope-click,
133+ indicator-keyboard,
122− unity-scope-mediascanner2,
134+ indicator-session,
135+ unity-greeter-session-broadcast,
123−Breaks: indicator-network (<< 0.5.1+14.10.20141014),
137+ indicator-network (<< 0.5.1+14.10.20141014),
138+ ubuntu-keyboard (<< 0.100),
124− ubuntu-touch-session (<< 0.107),
139+ ubuntu-touch-session (<< 0.107),
125− unity8-greeter (<< 7.89),
141+ unity8-greeter (<< 7.89),
126−Replaces: ubuntu-touch-session (<< 0.82~),
143+ ubuntu-touch-session (<< 0.82~),
127− unity8-greeter (<< 7.89),
145+ unity8-greeter (<< 7.89),
128−Conflicts: ubuntu-system-settings-wizard,
147+ ubuntu-system-settings-wizard,
129Description: Unity 8 shell
148Description: Unity 8 shell
130 The Unity 8 shell is the primary user interface for Ubuntu devices.
149 The Unity 8 shell is the primary user interface for Ubuntu devices.
132Package: unity8-common
151Package: unity8-common
133Architecture: all
152Architecture: all
134−Depends: qml-module-qtquick-layouts,
154+ qml-module-qtquick-layouts,
155+ qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
135− qtdeclarative5-ubuntu-settings-components (>= 0.7),
156+ qml-module-ubuntu-settings-components,
136− qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
157+ qml-module-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
137− qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
138− qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
158+ qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
159+ qttranslations5-l10n,
139− ubuntu-thumbnailer-impl-0,
160+ ubuntu-thumbnailer-impl-0,
140− unity-application-impl-17,
161+ unity-application-impl-27,
141− unity-notifications-impl-3,
162+ unity-notifications-impl-3,
142− unity-plugin-scopes | unity-scopes-impl,
163+ unity8-schemas,
143− unity-scopes-impl-12,
144− unity8-tests | unity-application-impl,
164+ unity8-tests | unity-application-impl,
145− ${misc:Depends},
165+ ${misc:Depends},
146−Breaks: unity8 (<< 7.86),
167+ unity8 (<< 7.86),
147−Replaces: unity8 (<< 7.86),
169+ unity8 (<< 7.86),
148Description: Unity 8 shell (common files)
170Description: Unity 8 shell (common files)
149 The Unity 8 shell is the primary user interface for Ubuntu devices.
171 The Unity 8 shell is the primary user interface for Ubuntu devices.
151− This package contains the QML, graphics and locale files shared between
173+ This package contains the QML, graphics and locale files for unity8.
152− unity8 and unity-scope-tool.
154Package: unity8-autopilot
175Package: unity8-autopilot
155Architecture: all
176Architecture: all
156−Depends: autopilot-qt5 (>= 1.4),
178+ autopilot-qt5 (>= 1.4),
157− gir1.2-glib-2.0,
179+ gir1.2-glib-2.0,
158− gir1.2-notify-0.7,
180+ gir1.2-notify-0.7,
159− libqt5test5,
181+ libqt5test5,
160− libqt5widgets5,
182+ libqt5widgets5,
161− ofono-phonesim,
183+ ofono-phonesim,
162− python3-autopilot,
184+ python3-autopilot,
163− python3-evdev,
185+ python3-evdev,
164− python3-fixtures,
186+ python3-fixtures,
165− python3-gi,
187+ python3-gi,
166− qttestability-autopilot (>= 1.4),
188+ qttestability-autopilot (>= 1.4),
167− ubuntu-ui-toolkit-autopilot (>= 1.3.1845),
189+ ubuntu-ui-toolkit-autopilot (>= 1.3.2030),
169− unity8 (= ${source:Version}),
190+ unity8 (= ${source:Version}),
170− unity8-tests (= ${source:Version}),
191+ unity8-tests (= ${source:Version}),
171− url-dispatcher-tools,
192+ url-dispatcher-tools,
173− ${misc:Depends},
194+ ${misc:Depends},
174− ${python3:Depends},
195+ ${python3:Depends},
175Description: Test package for Unity 8 shell
196Description: Test package for Unity 8 shell
176 Autopilot tests for the unity8 package
197 Autopilot tests for the unity8 package
178Package: unity8-tests
199Package: unity8-tests
179Architecture: any
200Architecture: any
180Multi-Arch: same
201Multi-Arch: same
181−Pre-Depends: ${misc:Pre-Depends},
203+ ${misc:Pre-Depends},
182−Depends: dbus-test-runner,
205+ dbus-test-runner,
183− qt5-default,
207+ qt5-default,
184− qtdeclarative5-dev-tools,
209+ qtdeclarative5-dev-tools,
185− unity8 (= ${source:Version}),
210+ unity8 (= ${source:Version}),
187− ${misc:Depends},
212+ ${misc:Depends},
188− ${shlibs:Depends},
213+ ${shlibs:Depends},
189−Provides: unity-application-impl,
215+ unity-application-impl,
190− unity-application-impl-16,
216+ unity-application-impl-27,
191− unity8-fake-env,
217+ unity8-fake-env,
192−Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1),
219+ unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1),
193− unity8-fake-env,
220+ unity8-fake-env,
194−Conflicts: unity8-fake-env,
222+ unity8-fake-env,
195Description: Scripts and mocks for running Unity 8 shell tests
223Description: Scripts and mocks for running Unity 8 shell tests
196 Provides fake implementations of some QML modules used by Unity 8 shell
224 Provides fake implementations of some QML modules used by Unity 8 shell
197 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment
225 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment
@@ -200,28 +228,45 @@ Description: Scripts and mocks for running Unity 8 shell tests
200Package: unity8-private
228Package: unity8-private
201Architecture: any
229Architecture: any
202Multi-Arch: same
230Multi-Arch: same
203−Pre-Depends: ${misc:Pre-Depends},
232+ ${misc:Pre-Depends},
204−Depends: accountsservice-ubuntu-schemas (>= 0.0.5),
234+ accountsservice-ubuntu-schemas (>= 0.0.7),
205− gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
235+ gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
206− libhardware2,
236+ libhardware2,
208− unity-schemas (>= 7.3.1+14.10.20140915),
209− qtdeclarative5-gsettings1.0,
210− qml-module-qtmultimedia,
237+ qml-module-qtmultimedia,
238+ qtdeclarative5-gsettings1.0,
211− ${misc:Depends},
240+ ${misc:Depends},
212− ${shlibs:Depends},
241+ ${shlibs:Depends},
213−Provides: unity-launcher-impl,
243+ unity-launcher-impl,
214− unity-launcher-impl-7,
244+ unity-launcher-impl-13,
215Description: Unity 8 private libs
245Description: Unity 8 private libs
216 The Unity 8 shell is the primary user interface for Ubuntu devices.
246 The Unity 8 shell is the primary user interface for Ubuntu devices.
218 This package contains the private libraries for QML and other components
248 This package contains the private libraries for QML and other components
219 only used by the shell.
249 only used by the shell.
251+Package: unity8-schemas
257+ unity-schemas (>= 7.3.1+14.10.20140915),
259+ unity-schemas (>= 7.3.1+14.10.20140915),
260+Description: Unity 8 schemas
261+ The Unity 8 shell is the primary user interface for Ubuntu devices.
263+ This package contains the configuration schemas used by unity.
221Package: unity8-doc
265Package: unity8-doc
222Section: doc
266Section: doc
223Architecture: all
267Architecture: all
224Multi-Arch: foreign
268Multi-Arch: foreign
225−Depends: ${misc:Depends},
270+ ${misc:Depends},
226Description: Documentation for Unity8
271Description: Documentation for Unity8
227 The Unity 8 shell is the primary user interface for Ubuntu devices. (documentation)
272 The Unity 8 shell is the primary user interface for Ubuntu devices. (documentation)
@@ -7,6 +7,12 @@ include /usr/share/dpkg/default.mk
7#export DH_VERBOSE=1
7#export DH_VERBOSE=1
8export DPKG_GENSYMBOLS_CHECK_LEVEL=4
8export DPKG_GENSYMBOLS_CHECK_LEVEL=4
9export NO_PNG_PKG_MANGLE=1
9export NO_PNG_PKG_MANGLE=1
12+DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
14+# Skip tests on the archs they are known to be flaky with current configuration
15+testskip_architectures := arm64 powerpc ppc64el s390x
12 dh $@ --parallel --fail-missing --with python3
18 dh $@ --parallel --fail-missing --with python3
@@ -18,7 +24,19 @@ override_dh_auto_configure:
19override_dh_auto_build:
25override_dh_auto_build:
20 # doc is not a default target
26 # doc is not a default target
21− dh_auto_build -- all doc
27+ dh_auto_build -- -O all doc
29+override_dh_auto_test:
30+ # Run the entire test battery
31+ # Parallel tests have a risk of starting xvfb on the same DISPLAY multiple times,
32+ # causing the whole battery to fail.
33+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
34+ifneq (,$(filter $(DEB_HOST_ARCH),$(testskip_architectures)))
35+ -dh_auto_test --no-parallel -- -O -k xvfballtests
37+ dh_auto_test --no-parallel -- -O -k xvfballtests
23override_dh_install:
41override_dh_install:
24 # install autopilot tests
42 # install autopilot tests
@@ -33,6 +51,7 @@ override_dh_install:
33override_dh_makeshlibs:
51override_dh_makeshlibs:
34 dh_makeshlibs -Nunity8-private -Nunity8-tests
52 dh_makeshlibs -Nunity8-private -Nunity8-tests
36−# libMockLightDM-qml.so links against liblightdm-qt5-2.so which doesn't exist
37override_dh_shlibdeps:
54override_dh_shlibdeps:
55+ # Some mock libraries link against liblightdm-qt5-3.so which we want to
56+ # avoid, since we only really link against our mock one, not the system one.
38− dh_shlibdeps -XlibMockLightDM-qml.so -Lunity8-private
57+ dh_shlibdeps -XlibMockAccountsService-qml.so -Lunity8-private
debian/source/formatdeleted−1
@@ -1,10 +1,11 @@
1Tests: qmluitests.sh
1Tests: qmluitests.sh
2Restrictions: allow-stderr
2Restrictions: allow-stderr
3−Depends: dpkg-dev,
3+Depends:
5− unity8-tests,
5+ unity8-tests,
7Tests: autopilot.sh
7Tests: autopilot.sh
8Restrictions: allow-stderr,
8Restrictions: allow-stderr,
9 isolation-machine,
9 isolation-machine,
10−Depends: unity8-autopilot,
11+ unity8-autopilot,
debian/tests/qmluitests.sh+1−1
@@ -8,4 +8,4 @@ DEB_HOST_MULTIARCH=$(dpkg-architecture -qDEB_HOST_MULTIARCH)
9export ARTIFACTS_DIR="${ADT_ARTIFACTS}"
9export ARTIFACTS_DIR="${ADT_ARTIFACTS}"
11−parallel --shebang /usr/lib/$DEB_HOST_MULTIARCH/unity8/tests/scripts/xvfballtests.sh
11+/usr/lib/$DEB_HOST_MULTIARCH/unity8/tests/scripts/xvfballtests.sh
debian/unity-scope-tool.installdeleted−2
@@ -1,2 +0,0 @@
1−usr/bin/unity-scope-tool
2−usr/share/unity8/ScopeTool.qml
debian/unity8-common.install−2
@@ -1,7 +1,5 @@
1−usr/share/glib-2.0/schemas
2usr/share/locale
1usr/share/locale
3usr/share/unity8/Components
2usr/share/unity8/Components
5usr/share/unity8/Notifications
3usr/share/unity8/Notifications
6usr/share/unity8/graphics
4usr/share/unity8/graphics
7var/lib/polkit-1/localauthority/10-vendor.d
5var/lib/polkit-1/localauthority/10-vendor.d
debian/unity8-greeter.installnew file+5
@@ -0,0 +1,5 @@
1+data/unity8-greeter-init.conf usr/share/upstart/sessions/
2+data/unity8-greeter-wrapper usr/bin/
3+data/unity8-greeter.pkla /var/lib/polkit-1/localauthority/10-vendor.d/
4+usr/share/lightdm/greeters/unity8-greeter.desktop
5+usr/share/lightdm/lightdm.conf.d/51-unity8-greeter.conf
debian/unity8-private.install+2−3
@@ -1,17 +1,16 @@
1usr/lib/*/libunity8-private.*
1usr/lib/*/libunity8-private.*
2usr/lib/*/unity8/qml/AccountsService
2usr/lib/*/unity8/qml/AccountsService
3usr/lib/*/unity8/qml/Cursor
3usr/lib/*/unity8/qml/Cursor
4−usr/lib/*/unity8/qml/Dash
5usr/lib/*/unity8/qml/GlobalShortcut
4usr/lib/*/unity8/qml/GlobalShortcut
6usr/lib/*/unity8/qml/Greeter
5usr/lib/*/unity8/qml/Greeter
7−usr/lib/*/unity8/qml/IntegratedLightDM
6+usr/lib/*/unity8/qml/LightDM
8usr/lib/*/unity8/qml/Lights
7usr/lib/*/unity8/qml/Lights
9usr/lib/*/unity8/qml/Powerd
8usr/lib/*/unity8/qml/Powerd
10usr/lib/*/unity8/qml/ScreenshotDirectory
9usr/lib/*/unity8/qml/ScreenshotDirectory
11usr/lib/*/unity8/qml/SessionBroadcast
10usr/lib/*/unity8/qml/SessionBroadcast
11+usr/lib/*/unity8/qml/UInput
12usr/lib/*/unity8/qml/Ubuntu
12usr/lib/*/unity8/qml/Ubuntu
13usr/lib/*/unity8/qml/Unity
13usr/lib/*/unity8/qml/Unity
14−usr/lib/*/unity8/qml/UInput
15usr/lib/*/unity8/qml/Utils
14usr/lib/*/unity8/qml/Utils
16usr/lib/*/unity8/qml/WindowManager
15usr/lib/*/unity8/qml/WindowManager
17usr/lib/*/unity8/qml/Wizard
16usr/lib/*/unity8/qml/Wizard
debian/unity8-schemas.installnew file+1
@@ -0,0 +1 @@
1+usr/share/glib-2.0/schemas
debian/unity8-tests.install−1
@@ -2,7 +2,6 @@ data/unity-mock-indicator-service.conf usr/share/upstart/sessions/
2usr/bin/unity-mock-indicator-service
2usr/bin/unity-mock-indicator-service
3usr/lib/*/unity8/qml/mocks
3usr/lib/*/unity8/qml/mocks
4usr/lib/*/unity8/qml/nonmirplugins
4usr/lib/*/unity8/qml/nonmirplugins
5−usr/lib/*/unity8/qml/scopefakes
6usr/lib/*/unity8/qml/utils
5usr/lib/*/unity8/qml/utils
7usr/lib/*/unity8/tests
6usr/lib/*/unity8/tests
8usr/lib/*/unity8/uqmlscene
7usr/lib/*/unity8/uqmlscene
debian/unity8-tests.lintian-overridesnew file+1
@@ -0,0 +1 @@
1+unity8-tests: unusual-interpreter usr/lib/*/unity8/tests/scripts/*.sh #!/usr/bin/parallel
debian/unity8.install+8−10
@@ -1,21 +1,19 @@
1−var/lib/unity8/version
1+data/devices.conf etc/ubuntu/
2−data/unity8-dash.conf usr/share/upstart/sessions/
2+data/test.sensors etc/ubuntusensors/
3data/unity8-filewatcher.conf usr/share/upstart/sessions/
3data/unity8-filewatcher.conf usr/share/upstart/sessions/
4data/unity8.conf usr/share/upstart/sessions/
4data/unity8.conf usr/share/upstart/sessions/
5−data/devices.conf etc/ubuntu/
6usr/bin/unity8
5usr/bin/unity8
8−usr/share/applications/unity8-dash.desktop
9usr/share/applications/unity8.desktop
6usr/share/applications/unity8.desktop
7+usr/share/unity8/ApplicationMenus
8+usr/share/unity8/DeviceConfiguration.qml
9+usr/share/unity8/DisabledScreenNotice.qml
10usr/share/unity8/Greeter
10usr/share/unity8/Greeter
11usr/share/unity8/Launcher
11usr/share/unity8/Launcher
12+usr/share/unity8/OrientedShell.qml
12usr/share/unity8/Panel
13usr/share/unity8/Panel
13usr/share/unity8/Rotation
14usr/share/unity8/Rotation
14−usr/share/unity8/DeviceConfiguration.qml
15−usr/share/unity8/OrientedShell.qml
16−usr/share/unity8/DisabledScreenNotice.qml
17usr/share/unity8/Shell.qml
15usr/share/unity8/Shell.qml
18−usr/share/unity8/Stages
16+usr/share/unity8/Stage
19usr/share/unity8/Tutorial
17usr/share/unity8/Tutorial
20usr/share/unity8/Wizard
18usr/share/unity8/Wizard
21−usr/share/url-dispatcher/urls/unity8-dash.url-dispatcher
19+var/lib/unity8/version
@@ -1,8 +1,5 @@
2− * Copyright (C) 2012 Canonical, Ltd.
2+ * Copyright (C) 2012-2016 Canonical, Ltd.
5− * Ugo Riboni <ugo.riboni@canonical.com>
7 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -17,8 +14,7 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20−#ifndef PATHS_H
17+#pragma once
24#include <QtCore/QCoreApplication>
20#include <QtCore/QCoreApplication>
@@ -27,13 +23,28 @@
27#include <QtQml/QQmlEngine>
23#include <QtQml/QQmlEngine>
28#include <QStandardPaths>
24#include <QStandardPaths>
26+inline QString installRoot() {
27+ static QString installRoot;
28+ static bool installRootSet = false;
29+ if (!installRootSet) {
30+ QString snapRoot = QFile::decodeName(qgetenv("SNAP"));
31+ if (!snapRoot.isEmpty() && QCoreApplication::applicationDirPath() ==
32+ QDir(snapRoot + QStringLiteral("@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@")).canonicalPath()) {
33+ installRoot = snapRoot;
34+ } else if (QCoreApplication::applicationDirPath() ==
35+ QDir(QStringLiteral("@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@")).canonicalPath()) {
36+ installRoot = QStringLiteral("");
38+ installRootSet = true;
30inline bool isRunningInstalled() {
43inline bool isRunningInstalled() {
31 // Tests don't use the normal binary, so we want to check binary *and*
44 // Tests don't use the normal binary, so we want to check binary *and*
32 // the environment. Installed tests have UNITY_TESTING_DATADIR set.
45 // the environment. Installed tests have UNITY_TESTING_DATADIR set.
33− static bool installed = (QCoreApplication::applicationDirPath() ==
34− QDir(QStringLiteral("@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@")).canonicalPath());
35 static bool installed_test_env = !qgetenv("UNITY_TESTING_DATADIR").isEmpty();
46 static bool installed_test_env = !qgetenv("UNITY_TESTING_DATADIR").isEmpty();
36− return installed || installed_test_env;
47+ return !installRoot().isNull() || installed_test_env;
39inline QString buildDirectory() {
50inline QString buildDirectory() {
@@ -48,9 +59,9 @@ inline QString sourceDirectory() {
49inline QString translationDirectory() {
60inline QString translationDirectory() {
50 if (isRunningInstalled()) {
61 if (isRunningInstalled()) {
51− return QStringLiteral("@CMAKE_INSTALL_PREFIX@/share/locale");
62+ return installRoot() + QStringLiteral("@CMAKE_INSTALL_PREFIX@/share/locale");
53− return QString(buildDirectory() + "/po/locale");
64+ return buildDirectory() + QStringLiteral("/po/locale");
@@ -78,16 +89,16 @@ inline QString testLibDir() {
79inline QString qmlDirectory() {
90inline QString qmlDirectory() {
80 if (isRunningInstalled()) {
91 if (isRunningInstalled()) {
81− return QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/");
92+ return installRoot() + QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_APP_DIR@/");
83− return QString(sourceDirectory() + "/qml");
94+ return sourceDirectory() + QStringLiteral("/qml");
87inline QStringList overrideImportPaths() {
98inline QStringList overrideImportPaths() {
88 QStringList paths;
99 QStringList paths;
89 if (!isRunningInstalled()) {
100 if (!isRunningInstalled()) {
90− paths << QString(buildDirectory() + "/plugins");
101+ paths << buildDirectory() + QStringLiteral("/plugins");
92 return paths;
103 return paths;
@@ -95,9 +106,9 @@ inline QStringList overrideImportPaths() {
95inline QStringList nonMirImportPaths() {
106inline QStringList nonMirImportPaths() {
96 QStringList paths;
107 QStringList paths;
97 if (isRunningInstalled()) {
108 if (isRunningInstalled()) {
98− paths << QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/nonmirplugins");
109+ paths << installRoot() + QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/nonmirplugins");
100− paths << QString(buildDirectory() + "/nonmirplugins");
111+ paths << buildDirectory() + QStringLiteral("/nonmirplugins");
102 return paths;
113 return paths;
@@ -105,23 +116,23 @@ inline QStringList nonMirImportPaths() {
105inline QStringList fallbackImportPaths() {
116inline QStringList fallbackImportPaths() {
106 QStringList paths;
117 QStringList paths;
107 if (isRunningInstalled()) {
118 if (isRunningInstalled()) {
108− paths << QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@");
119+ paths << installRoot() + QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@");
109− paths << QStringLiteral("@USS_PRIVATE_PLUGINDIR@");
120+ paths << installRoot() + QStringLiteral("@USS_PRIVATE_PLUGINDIR@");
110− paths << QStringLiteral("@SHELL_PLUGINDIR@");
121+ paths << installRoot() + QStringLiteral("@SHELL_PLUGINDIR@");
111− paths << QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/mocks");
122+ paths << installRoot() + QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/mocks");
113 paths << QStringLiteral("@USS_PRIVATE_PLUGINDIR@");
124 paths << QStringLiteral("@USS_PRIVATE_PLUGINDIR@");
114 paths << QStringLiteral("@SHELL_PLUGINDIR@");
125 paths << QStringLiteral("@SHELL_PLUGINDIR@");
115− paths << QString(buildDirectory() + "/tests/mocks");
126+ paths << buildDirectory() + QStringLiteral("/tests/mocks");
117 return paths;
128 return paths;
120inline QString mockPluginsDir() {
131inline QString mockPluginsDir() {
121 if (isRunningInstalled()) {
132 if (isRunningInstalled()) {
122− return QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/mocks");
133+ return installRoot() + QStringLiteral("@CMAKE_INSTALL_PREFIX@/@SHELL_INSTALL_QML@/mocks");
124− return QString(buildDirectory() + "/tests/mocks");
135+ return buildDirectory() + QStringLiteral("/tests/mocks");
@@ -162,5 +173,3 @@ inline void appendImportPaths(QQmlEngine *engine, const QStringList &paths)
163 engine->setImportPathList(importPathList);
174 engine->setImportPathList(importPathList);
plugins/AccountsService/AccountsService.cpp+42−33
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013, 2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,6 @@
25#include <glib.h>
25#include <glib.h>
27#define IFACE_ACCOUNTS_USER QStringLiteral("org.freedesktop.Accounts.User")
27#define IFACE_ACCOUNTS_USER QStringLiteral("org.freedesktop.Accounts.User")
28−#define IFACE_LOCATION_HERE QStringLiteral("com.ubuntu.location.providers.here.AccountsService")
29#define IFACE_UBUNTU_INPUT QStringLiteral("com.ubuntu.AccountsService.Input")
28#define IFACE_UBUNTU_INPUT QStringLiteral("com.ubuntu.AccountsService.Input")
30#define IFACE_UBUNTU_SECURITY QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy")
29#define IFACE_UBUNTU_SECURITY QStringLiteral("com.ubuntu.AccountsService.SecurityPrivacy")
31#define IFACE_UBUNTU_SECURITY_OLD QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy")
30#define IFACE_UBUNTU_SECURITY_OLD QStringLiteral("com.ubuntu.touch.AccountsService.SecurityPrivacy")
@@ -33,11 +32,13 @@
33#define IFACE_UNITY_PRIVATE QStringLiteral("com.canonical.unity.AccountsService.Private")
32#define IFACE_UNITY_PRIVATE QStringLiteral("com.canonical.unity.AccountsService.Private")
35#define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile")
34#define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile")
36−#define PROP_DEMO_EDGES QStringLiteral("demo-edges")
35+#define PROP_DEMO_EDGES QStringLiteral("DemoEdges2")
37#define PROP_DEMO_EDGES_COMPLETED QStringLiteral("DemoEdgesCompleted")
36#define PROP_DEMO_EDGES_COMPLETED QStringLiteral("DemoEdgesCompleted")
38#define PROP_EMAIL QStringLiteral("Email")
37#define PROP_EMAIL QStringLiteral("Email")
38+#define PROP_ENABLE_FINGERPRINT_IDENTIFICATION QStringLiteral("EnableFingerprintIdentification")
39#define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked")
39#define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked")
40#define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked")
40#define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked")
41+#define PROP_FAILED_FINGERPRINT_LOGINS QStringLiteral("FailedFingerprintLogins")
41#define PROP_FAILED_LOGINS QStringLiteral("FailedLogins")
42#define PROP_FAILED_LOGINS QStringLiteral("FailedLogins")
42#define PROP_INPUT_SOURCES QStringLiteral("InputSources")
43#define PROP_INPUT_SOURCES QStringLiteral("InputSources")
43#define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted")
44#define PROP_LICENSE_ACCEPTED QStringLiteral("LicenseAccepted")
@@ -66,9 +67,9 @@ Q_DECLARE_METATYPE(StringMapList)
66QVariant primaryButtonConverter(const QVariant &value)
67QVariant primaryButtonConverter(const QVariant &value)
68 QString stringValue = value.toString();
69 QString stringValue = value.toString();
69− if (stringValue == "left") {
70+ if (stringValue == QLatin1String("left")) {
70 return QVariant::fromValue(0);
71 return QVariant::fromValue(0);
71− } else if (stringValue == "right") {
72+ } else if (stringValue == QLatin1String("right")) {
72 return QVariant::fromValue(1); // Mir is less clear on this -- any non-zero value is the same
73 return QVariant::fromValue(1); // Mir is less clear on this -- any non-zero value is the same
74 return QVariant::fromValue(0); // default to left
75 return QVariant::fromValue(0); // default to left
@@ -91,14 +92,14 @@ AccountsService::AccountsService(QObject* parent, const QString &user)
91 registerProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL, QStringLiteral("emailChanged"));
92 registerProperty(IFACE_ACCOUNTS_USER, PROP_EMAIL, QStringLiteral("emailChanged"));
92 registerProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME, QStringLiteral("realNameChanged"));
93 registerProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME, QStringLiteral("realNameChanged"));
93 registerProperty(IFACE_ACCOUNTS_USER, PROP_INPUT_SOURCES, QStringLiteral("keymapsChanged"));
94 registerProperty(IFACE_ACCOUNTS_USER, PROP_INPUT_SOURCES, QStringLiteral("keymapsChanged"));
94− registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, QStringLiteral("hereEnabledChanged"));
95+ registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_FINGERPRINT_IDENTIFICATION, QStringLiteral("enableFingerprintIdentificationChanged"));
95− registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH, QStringLiteral("hereLicensePathChanged"));
96 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral("enableLauncherWhileLockedChanged"));
96 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral("enableLauncherWhileLockedChanged"));
97 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral("enableIndicatorsWhileLockedChanged"));
97 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral("enableIndicatorsWhileLockedChanged"));
98 registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral("passwordDisplayHintChanged"));
98 registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral("passwordDisplayHintChanged"));
99 registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral("statsWelcomeScreenChanged"));
99 registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral("statsWelcomeScreenChanged"));
100 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral("demoEdgesChanged"));
100 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral("demoEdgesChanged"));
101 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, QStringLiteral("demoEdgesCompletedChanged"));
101 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, QStringLiteral("demoEdgesCompletedChanged"));
102+ registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_FINGERPRINT_LOGINS, QStringLiteral("failedFingerprintLoginsChanged"));
102 registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral("failedLoginsChanged"));
103 registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral("failedLoginsChanged"));
104 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
105 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
@@ -176,6 +177,12 @@ void AccountsService::markDemoEdgeCompleted(const QString &edge)
180+bool AccountsService::enableFingerprintIdentification() const
182+ auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_FINGERPRINT_IDENTIFICATION);
183+ return value.toBool();
179bool AccountsService::enableLauncherWhileLocked() const
186bool AccountsService::enableLauncherWhileLocked() const
181 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
188 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
@@ -206,32 +213,6 @@ AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() cons
206 return (PasswordDisplayHint)value.toInt();
213 return (PasswordDisplayHint)value.toInt();
209−bool AccountsService::hereEnabled() const
211− auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED);
212− return value.toBool();
215−void AccountsService::setHereEnabled(bool enabled)
217− setProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, enabled);
220−QString AccountsService::hereLicensePath() const
222− auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
223− QString hereLicensePath = value.toString();
224− if (hereLicensePath.isEmpty() || !QFile::exists(hereLicensePath))
225− hereLicensePath = QStringLiteral("");
226− return hereLicensePath;
229−bool AccountsService::hereLicensePathValid() const
231− auto value = getProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH);
232− return !value.toString().isNull();
235QString AccountsService::realName() const
216QString AccountsService::realName() const
237 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME);
218 auto value = getProperty(IFACE_ACCOUNTS_USER, PROP_REAL_NAME);
@@ -274,6 +255,34 @@ QStringList AccountsService::keymaps() const
274 return {QStringLiteral("us")};
255 return {QStringLiteral("us")};
258+void AccountsService::setKeymaps(const QStringList &keymaps)
260+ if (keymaps.isEmpty()) {
261+ qWarning() << "Setting empty keymaps is not supported";
265+ StringMapList result;
266+ Q_FOREACH(const QString &keymap, keymaps) {
268+ map.insert(QStringLiteral("xkb"), keymap);
272+ setProperty(IFACE_ACCOUNTS_USER, PROP_INPUT_SOURCES, QVariant::fromValue(result));
273+ Q_EMIT keymapsChanged();
276+uint AccountsService::failedFingerprintLogins() const
278+ return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_FINGERPRINT_LOGINS).toUInt();
281+void AccountsService::setFailedFingerprintLogins(uint failedFingerprintLogins)
283+ setProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_FINGERPRINT_LOGINS, failedFingerprintLogins);
277uint AccountsService::failedLogins() const
286uint AccountsService::failedLogins() const
279 return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS).toUInt();
288 return getProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS).toUInt();
plugins/AccountsService/AccountsService.h+16−21
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013, 2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@ class QDBusInterface;
29class AccountsService: public QObject
29class AccountsService: public QObject
32− Q_ENUMS(PasswordDisplayHint)
33 Q_PROPERTY (QString user
32 Q_PROPERTY (QString user
35 WRITE setUser
34 WRITE setUser
@@ -41,6 +40,9 @@ class AccountsService: public QObject
41 Q_PROPERTY (QStringList demoEdgesCompleted
40 Q_PROPERTY (QStringList demoEdgesCompleted
42 READ demoEdgesCompleted
41 READ demoEdgesCompleted
43 NOTIFY demoEdgesCompletedChanged)
42 NOTIFY demoEdgesCompletedChanged)
43+ Q_PROPERTY (bool enableFingerprintIdentification
44+ READ enableFingerprintIdentification
45+ NOTIFY enableFingerprintIdentificationChanged)
44 Q_PROPERTY (bool enableLauncherWhileLocked
46 Q_PROPERTY (bool enableLauncherWhileLocked
45 READ enableLauncherWhileLocked
47 READ enableLauncherWhileLocked
46 NOTIFY enableLauncherWhileLockedChanged)
48 NOTIFY enableLauncherWhileLockedChanged)
@@ -60,27 +62,20 @@ class AccountsService: public QObject
60 READ failedLogins
62 READ failedLogins
61 WRITE setFailedLogins
63 WRITE setFailedLogins
62 NOTIFY failedLoginsChanged)
64 NOTIFY failedLoginsChanged)
63− Q_PROPERTY(bool hereEnabled
65+ Q_PROPERTY (uint failedFingerprintLogins
64− READ hereEnabled
66+ READ failedFingerprintLogins
65− WRITE setHereEnabled
67+ WRITE setFailedFingerprintLogins
66− NOTIFY hereEnabledChanged)
68+ NOTIFY failedFingerprintLoginsChanged)
67− Q_PROPERTY(QString hereLicensePath
69− NOTIFY hereLicensePathChanged)
70− Q_PROPERTY(bool hereLicensePathValid // qml sees a null string as "", so we use proxy setting for that
71− READ hereLicensePathValid
72− NOTIFY hereLicensePathChanged)
73 Q_PROPERTY(QString realName READ realName WRITE setRealName NOTIFY realNameChanged)
69 Q_PROPERTY(QString realName READ realName WRITE setRealName NOTIFY realNameChanged)
74 Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged)
70 Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged)
75− Q_PROPERTY(QStringList keymaps
71+ Q_PROPERTY(QStringList keymaps READ keymaps WRITE setKeymaps NOTIFY keymapsChanged)
77− NOTIFY keymapsChanged)
80 enum PasswordDisplayHint {
74 enum PasswordDisplayHint {
78+ Q_ENUM(PasswordDisplayHint)
85 explicit AccountsService(QObject *parent = 0, const QString & user = QString());
80 explicit AccountsService(QObject *parent = 0, const QString & user = QString());
86 ~AccountsService() = default;
81 ~AccountsService() = default;
@@ -91,6 +86,7 @@ public:
91 void setDemoEdges(bool demoEdges);
86 void setDemoEdges(bool demoEdges);
92 QStringList demoEdgesCompleted() const;
87 QStringList demoEdgesCompleted() const;
93 Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
88 Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
89+ bool enableFingerprintIdentification() const;
94 bool enableLauncherWhileLocked() const;
90 bool enableLauncherWhileLocked() const;
95 bool enableIndicatorsWhileLocked() const;
91 bool enableIndicatorsWhileLocked() const;
96 QString backgroundFile() const;
92 QString backgroundFile() const;
@@ -98,28 +94,27 @@ public:
98 PasswordDisplayHint passwordDisplayHint() const;
94 PasswordDisplayHint passwordDisplayHint() const;
99 uint failedLogins() const;
95 uint failedLogins() const;
100 void setFailedLogins(uint failedLogins);
96 void setFailedLogins(uint failedLogins);
101− bool hereEnabled() const;
97+ uint failedFingerprintLogins() const;
102− void setHereEnabled(bool enabled);
98+ void setFailedFingerprintLogins(uint failedFingerprintLogins);
103− QString hereLicensePath() const;
104− bool hereLicensePathValid() const;
105 QString realName() const;
99 QString realName() const;
106 void setRealName(const QString &realName);
100 void setRealName(const QString &realName);
107 QString email() const;
101 QString email() const;
108 void setEmail(const QString &email);
102 void setEmail(const QString &email);
109 QStringList keymaps() const;
103 QStringList keymaps() const;
104+ void setKeymaps(const QStringList &keymaps);
111Q_SIGNALS:
106Q_SIGNALS:
112 void userChanged();
107 void userChanged();
113 void demoEdgesChanged();
108 void demoEdgesChanged();
114 void demoEdgesCompletedChanged();
109 void demoEdgesCompletedChanged();
110+ void enableFingerprintIdentificationChanged();
115 void enableLauncherWhileLockedChanged();
111 void enableLauncherWhileLockedChanged();
116 void enableIndicatorsWhileLockedChanged();
112 void enableIndicatorsWhileLockedChanged();
117 void backgroundFileChanged();
113 void backgroundFileChanged();
118 void statsWelcomeScreenChanged();
114 void statsWelcomeScreenChanged();
119 void passwordDisplayHintChanged();
115 void passwordDisplayHintChanged();
120 void failedLoginsChanged();
116 void failedLoginsChanged();
121− void hereEnabledChanged();
117+ void failedFingerprintLoginsChanged();
122− void hereLicensePathChanged();
123 void realNameChanged();
118 void realNameChanged();
124 void emailChanged();
119 void emailChanged();
125 void keymapsChanged();
120 void keymapsChanged();
plugins/AccountsService/AccountsService.qmltypesdeleted−41
@@ -1,41 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable AccountsService 0.1 plugins'
11− name: "AccountsService"
13− exports: ["AccountsService/AccountsService 0.1"]
16− exportMetaObjectRevisions: [0]
18− name: "PasswordDisplayHint"
24− Property { name: "user"; type: "string" }
25− Property { name: "demoEdges"; type: "bool" }
26− Property { name: "demoEdgesCompleted"; type: "QStringList"; isReadonly: true }
27− Property { name: "enableLauncherWhileLocked"; type: "bool"; isReadonly: true }
28− Property { name: "enableIndicatorsWhileLocked"; type: "bool"; isReadonly: true }
29− Property { name: "backgroundFile"; type: "string"; isReadonly: true }
30− Property { name: "statsWelcomeScreen"; type: "bool"; isReadonly: true }
31− Property { name: "passwordDisplayHint"; type: "PasswordDisplayHint"; isReadonly: true }
32− Property { name: "failedLogins"; type: "uint" }
33− Property { name: "hereEnabled"; type: "bool" }
34− Property { name: "hereLicensePath"; type: "string"; isReadonly: true }
35− Property { name: "hereLicensePathValid"; type: "bool"; isReadonly: true }
37− name: "markDemoEdgeCompleted"
38− Parameter { name: "edge"; type: "string" }
plugins/AccountsService/CMakeLists.txt+1−2
@@ -7,9 +7,8 @@ add_library(AccountsService-qml MODULE
10−qt5_use_modules(AccountsService-qml DBus Qml)
12target_link_libraries(AccountsService-qml
10target_link_libraries(AccountsService-qml
13 ${GLIB_LIBRARIES}
12 ${GLIB_LIBRARIES}
plugins/AccountsService/com.canonical.unity.AccountsService.xml+10
@@ -9,11 +9,17 @@
9 <annotation name="org.freedesktop.Accounts.Authentication.ChangeAny"
9 <annotation name="org.freedesktop.Accounts.Authentication.ChangeAny"
10 value="com.ubuntu.AccountsService.GreeterChangeAny"/>
10 value="com.ubuntu.AccountsService.GreeterChangeAny"/>
12+ <!-- Marks that V1 (pre-8.21) edge demos have been run. Legacy value. -->
12 <!-- Should have been named DemoEdges, sorry folks. -mterry -->
13 <!-- Should have been named DemoEdges, sorry folks. -mterry -->
13 <property name="demo-edges" type="b" access="readwrite">
14 <property name="demo-edges" type="b" access="readwrite">
14 <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
15 <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
15 </property>
16 </property>
18+ <!-- Marks that V2 (post-8.21) edge demos have been run -->
19+ <property name="DemoEdges2" type="b" access="readwrite">
20+ <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
17 <!-- List of tutorial pages that have been completed by the user -->
23 <!-- List of tutorial pages that have been completed by the user -->
18 <property name="DemoEdgesCompleted" type="as" access="readwrite">
24 <property name="DemoEdgesCompleted" type="as" access="readwrite">
19 <annotation name="org.freedesktop.Accounts.DefaultValue" value="[]"/>
25 <annotation name="org.freedesktop.Accounts.DefaultValue" value="[]"/>
@@ -47,5 +53,9 @@
47 <annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
53 <annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
48 </property>
54 </property>
56+ <property name="FailedFingerprintLogins" type="u" access="readwrite">
57+ <annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
50 </interface>
60 </interface>
plugins/CMakeLists.txt+2−3
@@ -1,4 +1,4 @@
1−include(QmlPlugins)
1+find_package(QmlPlugins)
3# Set up and install a plugin for unity8.
3# Set up and install a plugin for unity8.
@@ -15,9 +15,8 @@ add_subdirectory(AccountsService)
15add_subdirectory(Cursor)
15add_subdirectory(Cursor)
16add_subdirectory(GlobalShortcut)
16add_subdirectory(GlobalShortcut)
17add_subdirectory(Greeter)
17add_subdirectory(Greeter)
18−add_subdirectory(IntegratedLightDM)
18+add_subdirectory(LightDM)
19add_subdirectory(Lights)
19add_subdirectory(Lights)
20−add_subdirectory(Dash)
21add_subdirectory(Powerd)
20add_subdirectory(Powerd)
22add_subdirectory(ScreenshotDirectory)
21add_subdirectory(ScreenshotDirectory)
23add_subdirectory(SessionBroadcast)
22add_subdirectory(SessionBroadcast)
plugins/Cursor/CMakeLists.txt+6−3
@@ -3,6 +3,10 @@ add_subdirectory(3rd_party)
3include_directories(
3include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}
4 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/xcursor
5 ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/xcursor
6 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
10 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
@@ -22,8 +26,7 @@ add_library(Cursor-qml SHARED
22target_link_libraries(Cursor-qml
26target_link_libraries(Cursor-qml
23 xcursorloader-static
27 xcursorloader-static
24 ${QT5PLATFORM_SUPPORT_LDFLAGS}
28 ${QT5PLATFORM_SUPPORT_LDFLAGS}
29+ Qt5::Qml Qt5::Quick Qt5::Svg
27−qt5_use_modules(Cursor-qml Qml Quick DBus Network Gui Sql Concurrent Svg)
29−add_unity8_plugin(Cursor 1.0 Cursor TARGETS Cursor-qml)
32+add_unity8_plugin(Cursor 1.1 Cursor TARGETS Cursor-qml)
plugins/Cursor/Cursor.qml+29−11
@@ -16,6 +16,7 @@
17import QtQuick 2.4
17import QtQuick 2.4
18import Cursor 1.1
18import Cursor 1.1
20MousePointer {
21MousePointer {
21 id: mousePointer
22 id: mousePointer
@@ -24,21 +25,38 @@ MousePointer {
24 id: imageInfo
25 id: imageInfo
25 themeName: mousePointer.themeName
26 themeName: mousePointer.themeName
26 cursorName: mousePointer.cursorName
27 cursorName: mousePointer.cursorName
28+ cursorHeight: mousePointer.height
32+ active: mousePointer.visible && imageInfo.frameCount > 1
29− AnimatedSprite {
33+ sourceComponent: AnimatedSprite {
30− x: -imageInfo.hotspot.x
34+ x: -imageInfo.hotspot.x
31− y: -imageInfo.hotspot.y
35+ y: -imageInfo.hotspot.y
32− source: "image://cursor/" + mousePointer.themeName + "/" + mousePointer.cursorName
36+ source: imageInfo.imageSource
34− interpolate: false
38+ interpolate: false
36− width: imageInfo.frameWidth
40+ width: imageInfo.frameWidth
37− height: imageInfo.frameHeight
41+ height: imageInfo.frameHeight
39− frameCount: imageInfo.frameCount
43+ frameCount: imageInfo.frameCount
40− frameDuration: imageInfo.frameDuration
44+ frameDuration: imageInfo.frameDuration
41− frameWidth: imageInfo.frameWidth
45+ frameWidth: imageInfo.frameWidth
42− frameHeight: imageInfo.frameHeight
46+ frameHeight: imageInfo.frameHeight
48+ running: Powerd.status === Powerd.On
53+ active: mousePointer.visible && imageInfo.frameCount === 1
54+ sourceComponent: Image {
55+ x: -imageInfo.hotspot.x
56+ y: -imageInfo.hotspot.y
57+ source: imageInfo.imageSource
58+ width: sourceSize.width
59+ height: sourceSize.height
plugins/Cursor/CursorImageInfo.cpp+22−13
@@ -19,17 +19,23 @@
19CursorImageInfo::CursorImageInfo(QObject *parent)
19CursorImageInfo::CursorImageInfo(QObject *parent)
20 : QObject(parent)
20 : QObject(parent)
22− m_updateTimer.setInterval(0);
23− m_updateTimer.setSingleShot(true);
24− connect(&m_updateTimer, &QTimer::timeout, this, &CursorImageInfo::update);
27void CursorImageInfo::setCursorName(const QString &cursorName)
24void CursorImageInfo::setCursorName(const QString &cursorName)
29 if (cursorName != m_cursorName) {
26 if (cursorName != m_cursorName) {
30 m_cursorName = cursorName;
27 m_cursorName = cursorName;
31 Q_EMIT cursorNameChanged();
29 Q_EMIT cursorNameChanged();
32− scheduleUpdate();
30+ }
33+void CursorImageInfo::setCursorHeight(qreal cursorHeight)
35+ if (cursorHeight != m_cursorHeight) {
36+ m_cursorHeight = cursorHeight;
38+ Q_EMIT cursorHeightChanged();
@@ -37,27 +43,21 @@ void CursorImageInfo::setThemeName(const QString &themeName)
38 if (m_themeName != themeName) {
44 if (m_themeName != themeName) {
39 m_themeName = themeName;
45 m_themeName = themeName;
40 Q_EMIT themeNameChanged();
47 Q_EMIT themeNameChanged();
45−void CursorImageInfo::scheduleUpdate()
47− if (!m_updateTimer.isActive()) {
48− m_updateTimer.start();
52void CursorImageInfo::update()
51void CursorImageInfo::update()
54− m_cursorImage = CursorImageProvider::instance()->fetchCursor(m_themeName, m_cursorName);
53+ m_cursorImage = CursorImageProvider::instance()->fetchCursor(m_themeName, m_cursorName, (int) m_cursorHeight);
56 Q_EMIT hotspotChanged();
55 Q_EMIT hotspotChanged();
57 Q_EMIT frameWidthChanged();
56 Q_EMIT frameWidthChanged();
58 Q_EMIT frameHeightChanged();
57 Q_EMIT frameHeightChanged();
59 Q_EMIT frameCountChanged();
58 Q_EMIT frameCountChanged();
60 Q_EMIT frameDurationChanged();
59 Q_EMIT frameDurationChanged();
60+ Q_EMIT imageSourceChanged();
63QPoint CursorImageInfo::hotspot() const
63QPoint CursorImageInfo::hotspot() const
@@ -104,3 +104,12 @@ int CursorImageInfo::frameDuration() const
104 return 0;
104 return 0;
108+QUrl CursorImageInfo::imageSource() const
110+ auto urlString = QString("image://cursor/%1/%2/%3")
111+ .arg(m_themeName, m_cursorName)
112+ .arg(m_cursorHeight);
114+ return QUrl(urlString);
plugins/Cursor/CursorImageInfo.h+10−4
@@ -21,7 +21,7 @@
22#include <QObject>
22#include <QObject>
23#include <QString>
23#include <QString>
24−#include <QTimer>
24+#include <QUrl>
26class CursorImageInfo : public QObject
26class CursorImageInfo : public QObject
@@ -29,12 +29,14 @@ class CursorImageInfo : public QObject
30 Q_PROPERTY(QString themeName READ themeName WRITE setThemeName NOTIFY themeNameChanged)
30 Q_PROPERTY(QString themeName READ themeName WRITE setThemeName NOTIFY themeNameChanged)
31 Q_PROPERTY(QString cursorName READ cursorName WRITE setCursorName NOTIFY cursorNameChanged)
31 Q_PROPERTY(QString cursorName READ cursorName WRITE setCursorName NOTIFY cursorNameChanged)
32+ Q_PROPERTY(qreal cursorHeight READ cursorHeight WRITE setCursorHeight NOTIFY cursorHeightChanged)
33 Q_PROPERTY(QPoint hotspot READ hotspot NOTIFY hotspotChanged)
34 Q_PROPERTY(QPoint hotspot READ hotspot NOTIFY hotspotChanged)
34 Q_PROPERTY(qreal frameWidth READ frameWidth NOTIFY frameWidthChanged)
35 Q_PROPERTY(qreal frameWidth READ frameWidth NOTIFY frameWidthChanged)
35 Q_PROPERTY(qreal frameHeight READ frameHeight NOTIFY frameHeightChanged)
36 Q_PROPERTY(qreal frameHeight READ frameHeight NOTIFY frameHeightChanged)
36 Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
37 Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
37 Q_PROPERTY(int frameDuration READ frameDuration NOTIFY frameDurationChanged)
38 Q_PROPERTY(int frameDuration READ frameDuration NOTIFY frameDurationChanged)
39+ Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
40 CursorImageInfo(QObject *parent = nullptr);
42 CursorImageInfo(QObject *parent = nullptr);
@@ -45,30 +47,34 @@ public:
45 QString cursorName() const { return m_cursorName; }
47 QString cursorName() const { return m_cursorName; }
46 void setCursorName(const QString &);
48 void setCursorName(const QString &);
50+ qreal cursorHeight() const { return m_cursorHeight; }
51+ void setCursorHeight(qreal);
48 QPoint hotspot() const;
53 QPoint hotspot() const;
49 qreal frameWidth() const;
54 qreal frameWidth() const;
50 qreal frameHeight() const;
55 qreal frameHeight() const;
51 int frameCount() const;
56 int frameCount() const;
52 int frameDuration() const;
57 int frameDuration() const;
58+ QUrl imageSource() const;
55 void themeNameChanged();
61 void themeNameChanged();
56 void cursorNameChanged();
62 void cursorNameChanged();
63+ void cursorHeightChanged();
57 void hotspotChanged();
64 void hotspotChanged();
58 void frameWidthChanged();
65 void frameWidthChanged();
59 void frameHeightChanged();
66 void frameHeightChanged();
60 void frameCountChanged();
67 void frameCountChanged();
61 void frameDurationChanged();
68 void frameDurationChanged();
69+ void imageSourceChanged();
63private Q_SLOTS:
71private Q_SLOTS:
64 void update();
72 void update();
67− void scheduleUpdate();
68− QTimer m_updateTimer;
70 QString m_themeName;
75 QString m_themeName;
71 QString m_cursorName;
76 QString m_cursorName;
77+ qreal m_cursorHeight{0};
73 CursorImage *m_cursorImage{nullptr};
79 CursorImage *m_cursorImage{nullptr};
plugins/Cursor/CursorImageProvider.cpp+36−22
@@ -27,7 +27,7 @@ CursorImageProvider *CursorImageProvider::m_instance = nullptr;
28// BuiltInCursorImage
28// BuiltInCursorImage
30−BuiltInCursorImage::BuiltInCursorImage()
30+BuiltInCursorImage::BuiltInCursorImage(int cursorHeight)
32 const char *svgString =
32 const char *svgString =
33 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
33 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
@@ -42,12 +42,14 @@ BuiltInCursorImage::BuiltInCursorImage()
42 " d=\"M 20.504,50.94931 460.42533,518.14486 266.47603,515.61948 366.48114,719.16522 274.05218,770.68296 172.53185,559.56112 20.504,716.13476 Z\" />"
42 " d=\"M 20.504,50.94931 460.42533,518.14486 266.47603,515.61948 366.48114,719.16522 274.05218,770.68296 172.53185,559.56112 20.504,716.13476 Z\" />"
45+ // NB: Original image dimension is 20x32. Ensure aspect ratio is kept
45− qimage = QImage(20, 32, QImage::Format_ARGB32);
46+ qimage = QImage((20./32.)*cursorHeight, cursorHeight, QImage::Format_ARGB32);
46 qimage.fill(Qt::transparent);
47 qimage.fill(Qt::transparent);
47 QPainter imagePainter(&qimage);
48 QPainter imagePainter(&qimage);
49 frameWidth = qimage.width();
50 frameWidth = qimage.width();
50 frameHeight = qimage.height();
51 frameHeight = qimage.height();
52+ requestedHeight = cursorHeight;
52 QSvgRenderer *svgRenderer = new QSvgRenderer(QByteArray(svgString));
54 QSvgRenderer *svgRenderer = new QSvgRenderer(QByteArray(svgString));
53 svgRenderer->render(&imagePainter);
55 svgRenderer->render(&imagePainter);
@@ -81,11 +83,9 @@ CustomCursorImage::CustomCursorImage(const QCursor &cursor)
82// XCursorImage
84// XCursorImage
84−XCursorImage::XCursorImage(const QString &theme, const QString &file)
86+XCursorImage::XCursorImage(const QString &theme, const QString &file, int preferredCursorHeightPx)
86− // TODO: Consider grid unit value
87− // Hardcoding to a medium size for now
88− int preferredCursorHeightPx = 32;
88+ requestedHeight = preferredCursorHeightPx;
90 XcursorImages *xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme),
90 XcursorImages *xcursorImages = XcursorLibraryLoadImages(QFile::encodeName(file), QFile::encodeName(theme),
91 preferredCursorHeightPx);
91 preferredCursorHeightPx);
@@ -96,7 +96,7 @@ XCursorImage::XCursorImage(const QString &theme, const QString &file)
96 frameCount = xcursorImages->nimage;
96 frameCount = xcursorImages->nimage;
98 for (int i = 0; i < xcursorImages->nimage; ++i) {
98 for (int i = 0; i < xcursorImages->nimage; ++i) {
99− XcursorImage *xcursorImage = xcursorImages->images[0];
99+ XcursorImage *xcursorImage = xcursorImages->images[i];
100 if (frameWidth < (int)xcursorImage->width) {
100 if (frameWidth < (int)xcursorImage->width) {
101 frameWidth = xcursorImage->width;
101 frameWidth = xcursorImage->width;
@@ -174,6 +174,8 @@ CursorImageProvider::CursorImageProvider()
174 m_fallbackNames[QStringLiteral("forbidden")].append(QStringLiteral("not-allowed"));
174 m_fallbackNames[QStringLiteral("forbidden")].append(QStringLiteral("not-allowed"));
175 m_fallbackNames[QStringLiteral("forbidden")].append(QStringLiteral("circle"));
175 m_fallbackNames[QStringLiteral("forbidden")].append(QStringLiteral("circle"));
177+ m_fallbackNames[QStringLiteral("grabbing")].append(QStringLiteral("closedhand")); // Breeze
177 m_fallbackNames[QStringLiteral("hand")].append(QStringLiteral("pointing_hand"));
179 m_fallbackNames[QStringLiteral("hand")].append(QStringLiteral("pointing_hand"));
178 m_fallbackNames[QStringLiteral("hand")].append(QStringLiteral("pointer"));
180 m_fallbackNames[QStringLiteral("hand")].append(QStringLiteral("pointer"));
@@ -235,34 +237,43 @@ CursorImageProvider::~CursorImageProvider()
235 m_instance = nullptr;
237 m_instance = nullptr;
238−QImage CursorImageProvider::requestImage(const QString &cursorThemeAndName, QSize *size, const QSize & /*requestedSize*/)
240+QImage CursorImageProvider::requestImage(const QString &cursorThemeAndNameAndHeight, QSize *size, const QSize & /*requestedSize*/)
240− CursorImage *cursorImage = fetchCursor(cursorThemeAndName);
242+ CursorImage *cursorImage = fetchCursor(cursorThemeAndNameAndHeight);
241 size->setWidth(cursorImage->qimage.width());
243 size->setWidth(cursorImage->qimage.width());
242 size->setHeight(cursorImage->qimage.height());
244 size->setHeight(cursorImage->qimage.height());
244 return cursorImage->qimage;
246 return cursorImage->qimage;
247−CursorImage *CursorImageProvider::fetchCursor(const QString &cursorThemeAndName)
249+CursorImage *CursorImageProvider::fetchCursor(const QString &cursorThemeAndNameAndHeight)
249 QString themeName;
251 QString themeName;
250 QString cursorName;
252 QString cursorName;
252− QStringList themeAndNameList = cursorThemeAndName.split('/');
255+ QStringList themeAndNameList = cursorThemeAndNameAndHeight.split('/');
253− if (themeAndNameList.size() != 2) {
256+ if (themeAndNameList.size() != 3) {
254 return nullptr;
257 return nullptr;
256 themeName = themeAndNameList[0];
259 themeName = themeAndNameList[0];
257 cursorName = themeAndNameList[1];
260 cursorName = themeAndNameList[1];
263+ cursorHeight = themeAndNameList[2].toInt(&ok);
266+ qWarning().nospace() << "CursorImageProvider: invalid cursor height ("<<themeAndNameList[2]<<")."
267+ " Falling back to "<<cursorHeight<<" pixels";
260− return fetchCursor(themeName, cursorName);
271+ return fetchCursor(themeName, cursorName, cursorHeight);
263−CursorImage *CursorImageProvider::fetchCursor(const QString &themeName, const QString &cursorName)
274+CursorImage *CursorImageProvider::fetchCursor(const QString &themeName, const QString &cursorName, int cursorHeight)
265− CursorImage *cursorImage = fetchCursorHelper(themeName, cursorName);
276+ CursorImage *cursorImage = fetchCursorHelper(themeName, cursorName, cursorHeight);
267 // Try some fallbacks
278 // Try some fallbacks
268 if (cursorImage->qimage.isNull()) {
279 if (cursorImage->qimage.isNull()) {
@@ -271,7 +282,7 @@ CursorImage *CursorImageProvider::fetchCursor(const QString &themeName, const QS
271 int i = 0;
282 int i = 0;
272 while (cursorImage->qimage.isNull() && i < fallbackNames.count()) {
283 while (cursorImage->qimage.isNull() && i < fallbackNames.count()) {
273 qDebug().nospace() << "CursorImageProvider: "<< cursorName <<" not found, trying " << fallbackNames.at(i);
284 qDebug().nospace() << "CursorImageProvider: "<< cursorName <<" not found, trying " << fallbackNames.at(i);
274− cursorImage = fetchCursorHelper(themeName, fallbackNames.at(i));
285+ cursorImage = fetchCursorHelper(themeName, fallbackNames.at(i), cursorHeight);
@@ -281,14 +292,14 @@ CursorImage *CursorImageProvider::fetchCursor(const QString &themeName, const QS
281 if (cursorImage->qimage.isNull() && cursorName != QLatin1String("left_ptr")) {
292 if (cursorImage->qimage.isNull() && cursorName != QLatin1String("left_ptr")) {
282 qDebug() << "CursorImageProvider:" << cursorName
293 qDebug() << "CursorImageProvider:" << cursorName
283 << "not found (nor its fallbacks, if any). Going for \"left_ptr\" as a last resort.";
294 << "not found (nor its fallbacks, if any). Going for \"left_ptr\" as a last resort.";
284− cursorImage = fetchCursorHelper(themeName, QStringLiteral("left_ptr"));
295+ cursorImage = fetchCursorHelper(themeName, QStringLiteral("left_ptr"), cursorHeight);
287 if (cursorImage->qimage.isNull()) {
298 if (cursorImage->qimage.isNull()) {
288 // finally, go for the built-in cursor
299 // finally, go for the built-in cursor
289 qWarning() << "CursorImageProvider: couldn't find any cursors. Using the built-in one";
300 qWarning() << "CursorImageProvider: couldn't find any cursors. Using the built-in one";
290− if (!m_builtInCursorImage) {
301+ if (!m_builtInCursorImage || m_builtInCursorImage->requestedHeight != cursorHeight) {
291− m_builtInCursorImage.reset(new BuiltInCursorImage);
302+ m_builtInCursorImage.reset(new BuiltInCursorImage(cursorHeight));
293 cursorImage = m_builtInCursorImage.data();
304 cursorImage = m_builtInCursorImage.data();
@@ -296,17 +307,20 @@ CursorImage *CursorImageProvider::fetchCursor(const QString &themeName, const QS
296 return cursorImage;
307 return cursorImage;
299−CursorImage *CursorImageProvider::fetchCursorHelper(const QString &themeName, const QString &cursorName)
310+CursorImage *CursorImageProvider::fetchCursorHelper(const QString &themeName, const QString &cursorName, int cursorHeight)
301 if (cursorName == QLatin1String("blank")) {
312 if (cursorName == QLatin1String("blank")) {
302 return &m_blankCursorImage;
313 return &m_blankCursorImage;
303− } else if (cursorName == QLatin1String("custom")) {
314+ } else if (cursorName.startsWith(QLatin1String("custom"))) {
304 return m_customCursorImage.data();
315 return m_customCursorImage.data();
306 QMap<QString, CursorImage*> &themeCursors = m_cursors[themeName];
317 QMap<QString, CursorImage*> &themeCursors = m_cursors[themeName];
308 if (!themeCursors.contains(cursorName)) {
319 if (!themeCursors.contains(cursorName)) {
309− themeCursors[cursorName] = new XCursorImage(themeName, cursorName);
320+ themeCursors[cursorName] = new XCursorImage(themeName, cursorName, cursorHeight);
321+ } else if (themeCursors[cursorName]->requestedHeight != cursorHeight) {
322+ delete themeCursors.take(cursorName);
323+ themeCursors[cursorName] = new XCursorImage(themeName, cursorName, cursorHeight);
312 return themeCursors[cursorName];
326 return themeCursors[cursorName];
plugins/Cursor/CursorImageProvider.h+9−6
@@ -42,17 +42,20 @@ public:
42 int frameHeight{0};
42 int frameHeight{0};
43 int frameCount{1};
43 int frameCount{1};
44 int frameDuration{40};
44 int frameDuration{40};
46+ // Requested height when creating this cursor.
47+ int requestedHeight{0};
47class XCursorImage : public CursorImage {
50class XCursorImage : public CursorImage {
49− XCursorImage(const QString &theme, const QString &file);
52+ XCursorImage(const QString &theme, const QString &file, int preferredCursorHeightPx);
50 virtual ~XCursorImage();
53 virtual ~XCursorImage();
53class BuiltInCursorImage : public CursorImage {
56class BuiltInCursorImage : public CursorImage {
55− BuiltInCursorImage();
58+ BuiltInCursorImage(int cursorHeight);
58class BlankCursorImage : public CursorImage {
61class BlankCursorImage : public CursorImage {
@@ -74,15 +77,15 @@ public:
74 static CursorImageProvider *instance() { return m_instance; }
77 static CursorImageProvider *instance() { return m_instance; }
77− QImage requestImage(const QString &cursorName, QSize *size, const QSize &requestedSize) override;
80+ QImage requestImage(const QString &cursorThemeAndNameAndHeight, QSize *size, const QSize &requestedSize) override;
79− CursorImage *fetchCursor(const QString &themeName, const QString &cursorName);
82+ CursorImage *fetchCursor(const QString &themeName, const QString &cursorName, int cursorHeight);
81 void setCustomCursor(const QCursor &customCursor);
84 void setCustomCursor(const QCursor &customCursor);
84− CursorImage *fetchCursor(const QString &cursorThemeAndName);
87+ CursorImage *fetchCursor(const QString &cursorThemeAndNameAndHeight);
85− CursorImage *fetchCursorHelper(const QString &themeName, const QString &cursorName);
88+ CursorImage *fetchCursorHelper(const QString &themeName, const QString &cursorName, int cursorHeight);
87 // themeName -> (cursorName -> cursorImage)
90 // themeName -> (cursorName -> cursorImage)
88 // TODO: discard old, unused, cursors
91 // TODO: discard old, unused, cursors
plugins/Cursor/MousePointer.cpp+97−15
@@ -1,5 +1,5 @@
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
4 * This program is free software: you can redistribute it and/or modify it under
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
5 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -22,6 +22,7 @@
23#include <QQuickWindow>
23#include <QQuickWindow>
24#include <QGuiApplication>
24#include <QGuiApplication>
26#include <qpa/qwindowsysteminterface.h>
27#include <qpa/qwindowsysteminterface.h>
@@ -43,29 +44,83 @@ void MousePointer::handleMouseEvent(ulong timestamp, QPointF movement, Qt::Mouse
43 Q_EMIT mouseMoved();
44 Q_EMIT mouseMoved();
46− qreal newX = x() + movement.x();
47+ m_accumulatedMovement += movement;
47− if (newX < 0) {
48+ // don't apply the fractional part
49+ QPointF appliedMovement(int(m_accumulatedMovement.x()), int(m_accumulatedMovement.y()));
50+ m_accumulatedMovement -= appliedMovement;
52+ qreal newX = x() + appliedMovement.x();
53+ qreal newY = y() + appliedMovement.y();
54+ const qreal sceneWidth = parentItem()->width();
55+ const qreal sceneHeight = parentItem()->height();
57+ if (newX <= 0 && newY < m_topBoundaryOffset) { // top left corner
58+ const auto distance = qSqrt(qPow(newX, 2) + qPow(newY-m_topBoundaryOffset, 2));
59+ Q_EMIT pushedTopLeftCorner(qAbs(distance), buttons);
61+ } else if (newX >= sceneWidth-1 && newY < m_topBoundaryOffset) { // top right corner
62+ const auto distance = qSqrt(qPow(newX-sceneWidth, 2) + qPow(newY-m_topBoundaryOffset, 2));
63+ Q_EMIT pushedTopRightCorner(qAbs(distance), buttons);
65+ } else if (newX < 0 && newY >= sceneHeight-1) { // bottom left corner
66+ const auto distance = qSqrt(qPow(newX, 2) + qPow(newY-sceneHeight, 2));
67+ Q_EMIT pushedBottomLeftCorner(qAbs(distance), buttons);
69+ } else if (newX >= sceneWidth-1 && newY >= sceneHeight-1) { // bottom right corner
70+ const auto distance = qSqrt(qPow(newX-sceneWidth, 2) + qPow(newY-sceneHeight, 2));
71+ Q_EMIT pushedBottomRightCorner(qAbs(distance), buttons);
73+ } else if (newX < 0) { // left edge
48 Q_EMIT pushedLeftBoundary(qAbs(newX), buttons);
74 Q_EMIT pushedLeftBoundary(qAbs(newX), buttons);
49− newX = 0;
75+ m_pushing = true;
50− } else if (newX > parentItem()->width()) {
76+ } else if (newX >= sceneWidth) { // right edge
51− Q_EMIT pushedRightBoundary(newX - parentItem()->width(), buttons);
77+ Q_EMIT pushedRightBoundary(newX - (sceneWidth - 1), buttons);
52− newX = parentItem()->width();
78+ m_pushing = true;
79+ } else if (newY < m_topBoundaryOffset) { // top edge
80+ Q_EMIT pushedTopBoundary(qAbs(newY - m_topBoundaryOffset), buttons);
82+ } else if (Q_LIKELY(newX > 0 && newX < sceneWidth-1 && newY > 0 && newY < sceneHeight-1)) { // normal pos, not pushing
84+ Q_EMIT pushStopped();
56− qreal newY = y() + movement.y();
89+ applyItemConfinement(newX, newY);
58− newY = 0;
91+ setX(qBound(0.0, newX, sceneWidth - 1));
59− } else if (newY > parentItem()->height()) {
60− newY = parentItem()->height();
62− setY(newY);
92+ setY(qBound(0.0, newY, sceneHeight - 1));
64 QPointF scenePosition = mapToItem(nullptr, QPointF(0, 0));
94 QPointF scenePosition = mapToItem(nullptr, QPointF(0, 0));
65 QWindowSystemInterface::handleMouseEvent(window(), timestamp, scenePosition /*local*/, scenePosition /*global*/,
95 QWindowSystemInterface::handleMouseEvent(window(), timestamp, scenePosition /*local*/, scenePosition /*global*/,
66 buttons, modifiers);
96 buttons, modifiers);
99+void MousePointer::applyItemConfinement(qreal &newX, qreal &newY)
101+ Q_ASSERT(parentItem() != nullptr);
103+ if (m_confiningItem.isNull()) {
107+ QRectF confiningItemGeometry(0, 0, m_confiningItem->width(), m_confiningItem->height());
109+ QRectF confiningRect = m_confiningItem->mapRectToItem(parentItem(), confiningItemGeometry);
111+ if (newX < confiningRect.x()) {
112+ newX = confiningRect.x();
113+ } else if (newX > confiningRect.right()) {
114+ newX = confiningRect.right();
117+ if (newY < confiningRect.y()) {
118+ newY = confiningRect.y();
119+ } else if (newY > confiningRect.bottom()) {
120+ newY = confiningRect.bottom();
69void MousePointer::handleWheelEvent(ulong timestamp, QPoint angleDelta, Qt::KeyboardModifiers modifiers)
124void MousePointer::handleWheelEvent(ulong timestamp, QPoint angleDelta, Qt::KeyboardModifiers modifiers)
71 if (!parentItem()) {
126 if (!parentItem()) {
@@ -77,6 +132,20 @@ void MousePointer::handleWheelEvent(ulong timestamp, QPoint angleDelta, Qt::Keyb
77 QPoint() /* pixelDelta */, angleDelta, modifiers, Qt::ScrollUpdate);
132 QPoint() /* pixelDelta */, angleDelta, modifiers, Qt::ScrollUpdate);
135+int MousePointer::topBoundaryOffset() const
137+ return m_topBoundaryOffset;
140+void MousePointer::setTopBoundaryOffset(int topBoundaryOffset)
142+ if (m_topBoundaryOffset == topBoundaryOffset)
145+ m_topBoundaryOffset = topBoundaryOffset;
146+ Q_EMIT topBoundaryOffsetChanged(topBoundaryOffset);
80void MousePointer::itemChange(ItemChange change, const ItemChangeData &value)
149void MousePointer::itemChange(ItemChange change, const ItemChangeData &value)
82 if (change == ItemSceneChange) {
151 if (change == ItemSceneChange) {
@@ -151,3 +220,16 @@ void MousePointer::setCustomCursor(const QCursor &customCursor)
152 CursorImageProvider::instance()->setCustomCursor(customCursor);
221 CursorImageProvider::instance()->setCustomCursor(customCursor);
224+QQuickItem* MousePointer::confiningItem() const
226+ return m_confiningItem.data();
229+void MousePointer::setConfiningItem(QQuickItem *item)
231+ if (item != m_confiningItem) {
232+ m_confiningItem = item;
233+ Q_EMIT confiningItemChanged();
plugins/Cursor/MousePointer.h+27−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
4 * This program is free software: you can redistribute it and/or modify it under
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
5 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -27,6 +27,8 @@
28class MousePointer : public MirMousePointerInterface {
28class MousePointer : public MirMousePointerInterface {
30+ Q_PROPERTY(QQuickItem* confiningItem READ confiningItem WRITE setConfiningItem NOTIFY confiningItemChanged)
31+ Q_PROPERTY(int topBoundaryOffset READ topBoundaryOffset WRITE setTopBoundaryOffset NOTIFY topBoundaryOffsetChanged)
31 MousePointer(QQuickItem *parent = nullptr);
33 MousePointer(QQuickItem *parent = nullptr);
@@ -38,6 +40,12 @@ public:
39 void setCustomCursor(const QCursor &) override;
41 void setCustomCursor(const QCursor &) override;
43+ QQuickItem* confiningItem() const;
44+ void setConfiningItem(QQuickItem*);
46+ int topBoundaryOffset() const;
47+ void setTopBoundaryOffset(int topBoundaryOffset);
41public Q_SLOTS:
49public Q_SLOTS:
42 void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
50 void handleMouseEvent(ulong timestamp, QPointF movement, Qt::MouseButtons buttons,
43 Qt::KeyboardModifiers modifiers) override;
51 Qt::KeyboardModifiers modifiers) override;
@@ -46,7 +54,16 @@ public Q_SLOTS:
47 void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons);
55 void pushedLeftBoundary(qreal amount, Qt::MouseButtons buttons);
48 void pushedRightBoundary(qreal amount, Qt::MouseButtons buttons);
56 void pushedRightBoundary(qreal amount, Qt::MouseButtons buttons);
57+ void pushedTopBoundary(qreal amount, Qt::MouseButtons buttons);
58+ void pushedTopLeftCorner(qreal amount, Qt::MouseButtons buttons);
59+ void pushedTopRightCorner(qreal amount, Qt::MouseButtons buttons);
60+ void pushedBottomLeftCorner(qreal amount, Qt::MouseButtons buttons);
61+ void pushedBottomRightCorner(qreal amount, Qt::MouseButtons buttons);
49 void mouseMoved();
63 void mouseMoved();
64+ void confiningItemChanged();
66+ void topBoundaryOffsetChanged(int topBoundaryOffset);
52 void itemChange(ItemChange change, const ItemChangeData &value) override;
69 void itemChange(ItemChange change, const ItemChangeData &value) override;
@@ -56,11 +73,20 @@ private Q_SLOTS:
58 void registerWindow(QWindow *window);
75 void registerWindow(QWindow *window);
76+ void applyItemConfinement(qreal &newX, qreal &newY);
60 QPointer<QWindow> m_registeredWindow;
78 QPointer<QWindow> m_registeredWindow;
61 QPointer<QScreen> m_registeredScreen;
79 QPointer<QScreen> m_registeredScreen;
62 QString m_cursorName;
80 QString m_cursorName;
63 QString m_themeName;
81 QString m_themeName;
83+ // Accumulated, unapplied, mouse movement.
84+ QPointF m_accumulatedMovement;
86+ QPointer<QQuickItem> m_confiningItem;
88+ int m_topBoundaryOffset{0};
89+ bool m_pushing{false};
66#endif // MOUSEPOINTER_H
92#endif // MOUSEPOINTER_H
plugins/Dash/AudioProgressBar.qmldeleted−54
@@ -1,54 +0,0 @@
2− * Copyright 2015 Canonical Ltd.
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.
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.
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/>.
18−import Ubuntu.Components 1.3
24− implicitHeight: progressBarImage.height
27− readonly property double progress: AudioUrlComparer.compare(source, DashAudioPlayer.currentSource) ? DashAudioPlayer.progress : 0
31− anchors { left: parent.left; right: parent.right }
33− source: "graphics/music_progress_bg.png"
35− sourceSize.width: width
36− sourceSize.height: height
41− objectName: "progressBarFill"
43− readonly property int maxWidth: progressBarImage.width
46− left: progressBarImage.left
47− right: progressBarImage.right
48− verticalCenter: progressBarImage.verticalCenter
49− rightMargin: maxWidth - (maxWidth * root.progress)
52− backgroundColor: theme.palette.normal.activity
plugins/Dash/CMakeLists.txtdeleted−43
@@ -1,43 +0,0 @@
1−# There's no cmake var for v8 include path :-/
3−LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
4−if(${Qt5Core_VERSION_STRING} VERSION_LESS "5.1.0")
5− SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/../QtV8/${Qt5Core_VERSION_STRING}/QtV8)
7− SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
11− ${CMAKE_CURRENT_SOURCE_DIR}
12− ${CMAKE_CURRENT_BINARY_DIR}
13− ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
14− ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
15− ${Qt5V8_PRIVATE_INCLUDE_DIR}
18−remove_definitions(-DQT_NO_KEYWORDS)
22− listviewwithpageheader.cpp
25− horizontaljournal.cpp
29−add_library(Dash-qml MODULE
33−target_link_libraries(Dash-qml
35− ${Qt5Quick_LIBRARIES}
38−qt5_use_modules(Dash-qml Qml Quick Concurrent)
40−add_unity8_plugin(Dash 0.1 Dash TARGETS Dash-qml)
42−install(FILES graphics/music_progress_bg.png DESTINATION ${SHELL_INSTALL_QML}/Dash/graphics/)
43−file(COPY graphics/music_progress_bg.png DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/graphics/)
plugins/Dash/CardAttributes.qmldeleted−71
@@ -1,71 +0,0 @@
2− * Copyright 2014 Canonical Ltd.
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.
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.
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/>.
18−import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.3
27− columns: 2 + repeater.count % 2
28− rowSpacing: units.gu(.5)
29− property alias model: repeater.model
30− property color color: theme.palette.normal.baseText
31− property real fontScale: 1.0
36− spacing: units.gu(0.5)
37− readonly property int column: index % grid.columns;
39− if (column == 0) return Qt.AlignLeft;
40− if (column == grid.columns - 1 || index == repeater.count - 1) return Qt.AlignRight;
41− if (column == 1) return Qt.AlignHCenter;
43− Layout.column: index % grid.columns
44− Layout.row: index / grid.columns
45− Layout.columnSpan: index == repeater.count - 1 && grid.columns == 3 && column == 1 ? 2 : 1
46− Layout.maximumWidth: Math.max(icon.width, label.x + label.implicitWidth)
47− Layout.fillWidth: true
52− // FIXME Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293
53− width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth
54− source: "icon" in modelData && modelData["icon"] || ""
59− width: parent.width - x
60− anchors.verticalCenter: parent.verticalCenter
61− text: "value" in modelData && modelData["value"] || "";
62− elide: Text.ElideRight
64− font.weight: "style" in modelData && modelData["style"] === "highlighted" ? Font.Bold : Font.Light
66− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale)
plugins/Dash/CardAudioProgress.qmldeleted−59
@@ -1,59 +0,0 @@
2− * Copyright 2015 Canonical Ltd.
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.
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.
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/>.
18−import Ubuntu.Components 1.3
24− implicitHeight: positionLabel.y + positionLabel.height
25− visible: AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)
27− property int duration: 0
28− property alias source: progress.source
29− property color color: theme.palette.normal.baseText
30− readonly property int position: root.visible ? DashAudioPlayer.position / 1000 : 0
34− anchors { left: parent.left; right: parent.right }
43− verticalAlignment: Text.AlignBottom
45− text: DashAudioPlayer.lengthToString(root.position)
54− verticalAlignment: Text.AlignBottom
56− text: DashAudioPlayer.lengthToString(duration)
plugins/Dash/CardCreator.jsdeleted−965
@@ -1,965 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
19−// %1 is the template["card-background"]["elements"][0]
20−// %2 is the template["card-background"]["elements"][1]
21−// %3 is whether the loader should be asynchronous or not
22−// %4 is the template["card-background"] string
23−var kBackgroundLoaderCode = 'Loader {\n\
24− id: backgroundLoader; \n\
25− objectName: "backgroundLoader"; \n\
26− anchors.fill: parent; \n\
27− asynchronous: %3; \n\
28− visible: status == Loader.Ready; \n\
29− sourceComponent: UbuntuShape { \n\
30− objectName: "background"; \n\
31− radius: "medium"; \n\
33− switch (root.backgroundShapeStyle) { \n\
34− case "inset": return UbuntuShape.Inset; \n\
35− case "shadow": return UbuntuShape.DropShadow; \n\
37− case "flat": return UbuntuShape.Flat; \n\
40− backgroundColor: getColor(0) || "white"; \n\
41− secondaryBackgroundColor: getColor(1) || backgroundColor; \n\
42− backgroundMode: UbuntuShape.VerticalGradient; \n\
43− anchors.fill: parent; \n\
44− source: backgroundImage.source ? backgroundImage : null; \n\
45− property real luminance: Style.luminance(backgroundColor); \n\
46− property Image backgroundImage: Image { \n\
47− objectName: "backgroundImage"; \n\
49− if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
53− function getColor(index) { \n\
54− if (cardData && typeof cardData["background"] === "object" \n\
55− && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
56− return cardData["background"]["elements"][index]; \n\
57− } else return index === 0 ? %1 : %2; \n\
62−// %1 is the aspect of the UbuntuShape
63−var kArtUbuntuShapeCode = 'UbuntuShape { \n\
64− anchors.fill: parent; \n\
65− source: artImage; \n\
66− sourceFillMode: UbuntuShape.PreserveAspectCrop; \n\
67− radius: "medium"; \n\
71−var kArtProportionalShapeCode = 'ProportionalShape { \n\
72− anchors.fill: parent; \n\
73− source: artImage; \n\
74− aspect: UbuntuShape.DropShadow; \n\
77−// %1 is used as anchors of artShapeHolder
78−// %2 is used as image width
79−// %3 is used as image height
80−// %4 is whether the image should be visible
81−// %5 is used as aspect ratio fallback
82−// %6 is whether the loader should be asynchronous or not
83−// %7 is the shape code we want to use
84−// %8 is injected as code to artImage
85−// %9 is used as image fallback
86−var kArtShapeHolderCode = 'Item { \n\
87− id: artShapeHolder; \n\
88− height: root.fixedArtShapeSize.height > 0 ? root.fixedArtShapeSize.height : artShapeLoader.height; \n\
89− width: root.fixedArtShapeSize.width > 0 ? root.fixedArtShapeSize.width : artShapeLoader.width; \n\
92− id: artShapeLoader; \n\
93− objectName: "artShapeLoader"; \n\
94− readonly property string cardArt: cardData && cardData["art"] || %9; \n\
95− onCardArtChanged: { if (item) { item.image.source = cardArt; } } \n\
96− active: cardArt != ""; \n\
97− asynchronous: %6; \n\
98− visible: status == Loader.Ready; \n\
99− sourceComponent: Item { \n\
101− objectName: "artShape"; \n\
102− visible: image.status == Image.Ready; \n\
103− readonly property alias image: artImage; \n\
105− readonly property real fixedArtShapeSizeAspect: (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) ? root.fixedArtShapeSize.width / root.fixedArtShapeSize.height : -1; \n\
106− readonly property real aspect: fixedArtShapeSizeAspect > 0 ? fixedArtShapeSizeAspect : %5; \n\
107− Component.onCompleted: { updateWidthHeightBindings(); } \n\
108− Connections { target: root; onFixedArtShapeSizeChanged: updateWidthHeightBindings(); } \n\
109− function updateWidthHeightBindings() { \n\
110− if (root.fixedArtShapeSize.height > 0 && root.fixedArtShapeSize.width > 0) { \n\
111− width = root.fixedArtShapeSize.width; \n\
112− height = root.fixedArtShapeSize.height; \n\
114− width = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.width }); \n\
115− height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height }); \n\
118− CroppedImageMinimumSourceSize { \n\
120− objectName: "artImage"; \n\
121− source: artShapeLoader.cardArt; \n\
122− asynchronous: %6; \n\
132−// %1 is anchors.fill
135−// %4 is whether the icon should be asynchronous or not
136−var kAudioButtonCode = 'AbstractButton { \n\
137− id: audioButton; \n\
138− anchors.fill: %1; \n\
141− readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
143− anchors.fill: parent; \n\
144− visible: parent.pressed; \n\
145− radius: "medium"; \n\
148− color: Qt.rgba(0, 0, 0, 0.5); \n\
149− anchors.centerIn: parent; \n\
150− width: parent.width * 0.5; \n\
152− radius: width / 2; \n\
155− anchors.centerIn: parent; \n\
156− width: parent.width * 0.3; \n\
159− name: DashAudioPlayer.playing && AudioUrlComparer.compare(parent.source, DashAudioPlayer.currentSource) ? "media-playback-pause" : "media-playback-start"; \n\
161− asynchronous: %4; \n\
164− if (AudioUrlComparer.compare(source, DashAudioPlayer.currentSource)) { \n\
165− if (DashAudioPlayer.playing) { \n\
166− DashAudioPlayer.pause(); \n\
168− DashAudioPlayer.play(); \n\
171− var playlist = (cardData["quickPreviewData"] && cardData["quickPreviewData"]["playlist"]) || null; \n\
172− DashAudioPlayer.playSource(source, playlist); \n\
175− onPressAndHold: { \n\
176− root.pressAndHold(); \n\
180−// %1 is whether the loader should be asynchronous or not
181−// %2 is the header height code
182−var kOverlayLoaderCode = 'Loader { \n\
183− id: overlayLoader; \n\
184− readonly property real overlayHeight: %2 + units.gu(2); \n\
185− anchors.fill: artShapeHolder; \n\
186− active: artShapeLoader.active && artShapeLoader.item && artShapeLoader.item.image.status === Image.Ready || false; \n\
187− asynchronous: %1; \n\
188− visible: showHeader && status == Loader.Ready; \n\
189− sourceComponent: UbuntuShapeOverlay { \n\
191− property real luminance: Style.luminance(overlayColor); \n\
192− aspect: UbuntuShape.Flat; \n\
193− radius: "medium"; \n\
194− overlayColor: cardData && cardData["overlayColor"] || "#99000000"; \n\
195− overlayRect: Qt.rect(0, 1 - overlayLoader.overlayHeight / height, 1, 1); \n\
199−// multiple row version of HeaderRowCode
200−function kHeaderRowCodeGenerator() {
201− var kHeaderRowCodeTemplate = 'Row { \n\
203− objectName: "outerRow"; \n\
204− property real margins: units.gu(1); \n\
205− spacing: margins; \n\
208− anchors.right: parent.right; \n\
209− anchors.margins: margins; \n\
210− anchors.rightMargin: 0; \n\
215− var args = Array.prototype.slice.call(arguments);
216− var isCardTool = args.shift();
217− var heightCode = isCardTool ? "" : "height: root.fixedHeaderHeight; \n";
218− var code = kHeaderRowCodeTemplate.arg(args.shift()).arg(heightCode).arg(args.join(',\n'));
222−// multiple item version of kHeaderContainerCode
223−function kHeaderContainerCodeGenerator() {
224− var headerContainerCodeTemplate = 'Item { \n\
225− id: headerTitleContainer; \n\
227− width: parent.width - x; \n\
228− implicitHeight: %2; \n\
233− var args = Array.prototype.slice.call(arguments);
234− var code = headerContainerCodeTemplate.arg(args.shift()).arg(args.shift()).arg(args.join(',\n'));
238−// %1 is used as anchors of mascotShapeLoader
239−// %2 is whether the loader should be asynchronous or not
240−var kMascotShapeLoaderCode = 'Loader { \n\
241− id: mascotShapeLoader; \n\
242− objectName: "mascotShapeLoader"; \n\
243− asynchronous: %2; \n\
244− active: mascotImage.status === Image.Ready; \n\
245− visible: showHeader && active && status == Loader.Ready; \n\
246− width: units.gu(6); \n\
247− height: units.gu(5.625); \n\
248− sourceComponent: UbuntuShape { image: mascotImage } \n\
252−// %1 is used as anchors of mascotImage
253−// %2 is used as visible of mascotImage
254−// %3 is injected as code to mascotImage
255−// %4 is used as fallback image
256−var kMascotImageCode = 'CroppedImageMinimumSourceSize { \n\
257− id: mascotImage; \n\
258− objectName: "mascotImage"; \n\
260− source: cardData && cardData["mascot"] || %4; \n\
261− width: units.gu(6); \n\
262− height: units.gu(5.625); \n\
263− horizontalAlignment: Image.AlignHCenter; \n\
264− verticalAlignment: Image.AlignVCenter; \n\
269−// %1 is used as anchors of titleLabel
270−// %2 is used as color of titleLabel
271−// %3 is used as extra condition for visible of titleLabel
272−// %4 is used as title width
273−// %5 is used as horizontal alignment
274−var kTitleLabelCode = 'Label { \n\
276− objectName: "titleLabel"; \n\
278− elide: Text.ElideRight; \n\
279− fontSize: "small"; \n\
280− wrapMode: Text.Wrap; \n\
281− maximumLineCount: 2; \n\
282− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
284− visible: showHeader %3; \n\
286− text: root.title; \n\
287− font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal; \n\
288− horizontalAlignment: %5; \n\
291−// %1 is used as extra anchors of emblemIcon
292−// %2 is used as color of emblemIcon
293−// FIXME The width code is a
294−// Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293
295−var kEmblemIconCode = 'Icon { \n\
297− objectName: "emblemIcon"; \n\
299− bottom: titleLabel.baseline; \n\
300− right: parent.right; \n\
303− source: cardData && cardData["emblem"] || ""; \n\
305− height: source != "" ? titleLabel.font.pixelSize : 0; \n\
306− width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth; \n\
309−// %1 is used as anchors of touchdown effect
310−var kTouchdownCode = 'UbuntuShape { \n\
312− objectName: "touchdown"; \n\
314− visible: root.pressed; \n\
315− radius: "medium"; \n\
316− borderSource: "radius_pressed.sci" \n\
319−// %1 is used as anchors of subtitleLabel
320−// %2 is used as color of subtitleLabel
321−var kSubtitleLabelCode = 'Label { \n\
322− id: subtitleLabel; \n\
323− objectName: "subtitleLabel"; \n\
325− anchors.topMargin: units.dp(2); \n\
326− elide: Text.ElideRight; \n\
327− maximumLineCount: 1; \n\
328− fontSize: "x-small"; \n\
329− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale); \n\
331− visible: titleLabel.visible && titleLabel.text; \n\
332− text: cardData && cardData["subtitle"] || ""; \n\
333− font.weight: Font.Light; \n\
336−// %1 is used as anchors of attributesRow
337−// %2 is used as color of attributesRow
338−var kAttributesRowCode = 'CardAttributes { \n\
339− id: attributesRow; \n\
340− objectName: "attributesRow"; \n\
343− fontScale: root.fontScale; \n\
344− model: cardData && cardData["attributes"]; \n\
347−// %1 is used as anchors of socialActionsRow
348−// %2 is used as color of socialActionsRow
349−var kSocialActionsRowCode = 'CardSocialActions { \n\
350− id: socialActionsRow; \n\
351− objectName: "socialActionsRow"; \n\
354− model: cardData && cardData["socialActions"]; \n\
355− onClicked: root.action(actionId); \n\
358−// %1 is used as top anchor of summary
359−// %2 is used as topMargin anchor of summary
360−// %3 is used as color of summary
361−var kSummaryLabelCode = 'Label { \n\
363− objectName: "summaryLabel"; \n\
366− left: parent.left; \n\
367− right: parent.right; \n\
368− margins: units.gu(1); \n\
371− wrapMode: Text.Wrap; \n\
372− maximumLineCount: 5; \n\
373− elide: Text.ElideRight; \n\
374− text: cardData && cardData["summary"] || ""; \n\
375− height: text ? implicitHeight : 0; \n\
376− fontSize: "small"; \n\
380−// %1 is used as bottom anchor of audio progress bar
381−// %2 is used as left anchor of audio progress bar
382−// %3 is used as text color
383−var kAudioProgressBarCode = 'CardAudioProgress { \n\
384− id: audioProgressBar; \n\
385− duration: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["duration"]) || 0; \n\
386− source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
390− right: parent.right; \n\
391− margins: units.gu(1); \n\
396−function sanitizeColor(colorString) {
397− if (colorString !== undefined) {
398− if (colorString.match(/^[#a-z0-9]*$/i) === null) {
399− // This is not the perfect regexp for color
400− // but what we're trying to do here is just protect
401− // against injection so it's ok
408−function cardString(template, components, isCardTool, artShapeStyle) {
411− var templateInteractive = (template == null ? true : (template["non-interactive"] !== undefined ? !template["non-interactive"] : true)) ? "true" : "false";
413− code = 'AbstractButton { \n\
415− property var cardData; \n\
416− property string backgroundShapeStyle: "inset"; \n\
417− property real fontScale: 1.0; \n\
418− property var scopeStyle: null; \n\
420− property size fixedArtShapeSize: Qt.size(-1, -1); \n\
421− readonly property string title: cardData && cardData["title"] || ""; \n\
422− property bool showHeader: true; \n\
423− implicitWidth: childrenRect.width; \n\
425− \n'.arg(templateInteractive);
427− code = code.arg(isCardTool ? "" : "property int fixedHeaderHeight: -1; \n");
429− var hasArt = components["art"] && components["art"]["field"] || false;
430− var hasSummary = components["summary"] || false;
431− var isConciergeMode = components["art"] && components["art"]["conciergeMode"] || false;
432− var artAndSummary = hasArt && hasSummary && !isConciergeMode;
433− var isHorizontal = template["card-layout"] === "horizontal";
434− var hasBackground = (!isHorizontal && (template["card-background"] || components["background"] || artAndSummary)) ||
435− (hasSummary && (template["card-background"] || components["background"]));
436− var hasTitle = components["title"] || false;
437− var hasMascot = components["mascot"] || false;
438− var hasEmblem = components["emblem"] && !(hasMascot && template["card-size"] === "small") || false;
439− var headerAsOverlay = hasArt && template && template["overlay"] === true && (hasTitle || hasMascot);
440− var hasSubtitle = hasTitle && components["subtitle"] || false;
441− var hasHeaderRow = hasMascot && hasTitle;
442− var hasAttributes = hasTitle && components["attributes"] && components["attributes"]["field"] || false;
443− var hasSocialActions = hasTitle && components["social-actions"] || false;
444− var isAudio = template["quick-preview-type"] === "audio";
445− var asynchronous = isCardTool ? "false" : "true";
447− code += 'signal action(var actionId);\n';
449− // For now we only support audio cards with [optional] art, title, subtitle
450− // in horizontal mode
451− // Anything else makes it behave not like an audio card
452− if (hasSummary) isAudio = false;
453− if (!isHorizontal) isAudio = false;
454− if (hasMascot) isAudio = false;
455− if (hasEmblem) isAudio = false;
456− if (headerAsOverlay) isAudio = false;
457− if (hasAttributes) isAudio = false;
460− if (hasBackground) {
461− var templateCardBackground;
462− if (template && typeof template["card-background"] === "string") {
463− templateCardBackground = 'decodeURI("' + encodeURI(template["card-background"]) + '")';
465− templateCardBackground = '""';
468− var backgroundElements0;
469− var backgroundElements1;
470− if (template && typeof template["card-background"] === "object" && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
471− var element0 = sanitizeColor(template["card-background"]["elements"][0]);
472− var element1 = sanitizeColor(template["card-background"]["elements"][1]);
473− if (element0 !== undefined) {
474− backgroundElements0 = '"%1"'.arg(element0);
476− if (element1 !== undefined) {
477− backgroundElements1 = '"%1"'.arg(element1);
480− code += kBackgroundLoaderCode.arg(backgroundElements0).arg(backgroundElements1).arg(asynchronous).arg(templateCardBackground);
484− code += 'readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);\n';
486− var widthCode, heightCode;
489− artAnchors = 'left: parent.left';
490− if (hasMascot || hasTitle) {
491− widthCode = 'height * artShape.aspect'
492− heightCode = 'headerHeight + 2 * units.gu(1)';
494− // This side of the else is a bit silly, who wants an horizontal layout without mascot and title?
495− // So we define a "random" height of the image height + 2 gu for the margins
496− widthCode = 'height * artShape.aspect'
497− heightCode = 'units.gu(7.625)';
500− artAnchors = 'horizontalCenter: parent.horizontalCenter;';
501− widthCode = 'root.width'
502− heightCode = 'width / artShape.aspect';
505− var aspectRatio = components["art"] && components["art"]["aspect-ratio"] || 1;
506− if (isNaN(aspectRatio)) {
509− var fallback = !isCardTool && components["art"] && components["art"]["fallback"] || "";
510− fallback = encodeURI(fallback);
511− var fallbackStatusCode = "";
512− var fallbackURICode = '""';
513− if (fallback !== "") {
514− // fallbackStatusCode has %9 in it because we want to substitute it for fallbackURICode
515− // which in kArtShapeHolderCode is %9
516− fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %9;';
517− fallbackURICode = 'decodeURI("%1")'.arg(fallback);
519− var artShapeHolderShapeCode;
520− if (!isConciergeMode) {
521− if (artShapeStyle === "icon") {
522− artShapeHolderShapeCode = kArtProportionalShapeCode;
524− var artShapeHolderShapeAspect;
525− switch (artShapeStyle) {
526− case "inset": artShapeHolderShapeAspect = "UbuntuShape.Inset"; break;
527− case "shadow": artShapeHolderShapeAspect = "UbuntuShape.DropShadow"; break;
529− case "flat": artShapeHolderShapeAspect = "UbuntuShape.Flat"; break;
531− artShapeHolderShapeCode = kArtUbuntuShapeCode.arg(artShapeHolderShapeAspect);
534− artShapeHolderShapeCode = "";
536− code += kArtShapeHolderCode.arg(artAnchors)
539− .arg(isConciergeMode ? "true" : "false")
542− .arg(artShapeHolderShapeCode)
543− .arg(fallbackStatusCode)
544− .arg(fallbackURICode);
546− code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
549− if (headerAsOverlay) {
550− var headerHeightCode = isCardTool ? "headerHeight" : "root.fixedHeaderHeight";
551− code += kOverlayLoaderCode.arg(asynchronous).arg(headerHeightCode);
554− var headerVerticalAnchors;
555− if (headerAsOverlay) {
556− headerVerticalAnchors = 'bottom: artShapeHolder.bottom; \n\
557− bottomMargin: units.gu(1);\n';
561− headerVerticalAnchors = 'top: artShapeHolder.top; \n\
562− topMargin: units.gu(1);\n';
564− headerVerticalAnchors = 'top: artShapeHolder.bottom; \n\
565− topMargin: units.gu(1);\n';
568− headerVerticalAnchors = 'top: parent.top; \n\
569− topMargin: units.gu(1);\n';
573− var headerLeftAnchor;
574− var headerLeftAnchorHasMargin = false;
575− if (isHorizontal && hasArt) {
576− headerLeftAnchor = 'left: artShapeHolder.right; \n\
577− leftMargin: units.gu(1);\n';
578− headerLeftAnchorHasMargin = true;
579− } else if (isHorizontal && isAudio) {
580− headerLeftAnchor = 'left: audioButton.right; \n\
581− leftMargin: units.gu(1);\n';
582− headerLeftAnchorHasMargin = true;
584− headerLeftAnchor = 'left: parent.left;\n';
587− var touchdownOnArtShape = !hasBackground && hasArt && !hasMascot && !hasSummary && !isAudio;
590− code += 'readonly property int headerHeight: row.height;\n'
591− } else if (hasMascot) {
592− code += 'readonly property int headerHeight: mascotImage.height;\n'
593− } else if (hasAttributes) {
594− if (hasTitle && hasSubtitle) {
595− code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + attributesRow.height + attributesRow.anchors.topMargin;\n'
596− } else if (hasTitle) {
597− code += 'readonly property int headerHeight: titleLabel.height + attributesRow.height + attributesRow.anchors.topMargin;\n'
599− code += 'readonly property int headerHeight: attributesRow.height;\n'
601− } else if (isAudio) {
603− code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + audioProgressBar.height + audioProgressBar.anchors.topMargin;\n'
604− } else if (hasTitle) {
605− code += 'readonly property int headerHeight: titleLabel.height + audioProgressBar.height + audioProgressBar.anchors.topMargin;\n'
607− code += 'readonly property int headerHeight: audioProgressBar.height;\n'
609− } else if (hasSubtitle) {
610− code += 'readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin;\n'
611− } else if (hasTitle) {
612− code += 'readonly property int headerHeight: titleLabel.height;\n'
614− code += 'readonly property int headerHeight: 0;\n'
617− var mascotShapeCode = '';
618− var mascotCode = '';
620− var useMascotShape = !hasBackground && !headerAsOverlay;
621− var mascotAnchors = '';
622− if (!hasHeaderRow) {
623− mascotAnchors += headerLeftAnchor;
624− mascotAnchors += headerVerticalAnchors;
625− if (!headerLeftAnchorHasMargin) {
626− mascotAnchors += 'leftMargin: units.gu(1);\n'
629− mascotAnchors = 'verticalCenter: parent.verticalCenter;'
632− if (useMascotShape) {
633− mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors).arg(asynchronous);
636− var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
637− var fallback = !isCardTool && components["mascot"] && components["mascot"]["fallback"] || "";
638− fallback = encodeURI(fallback);
639− var fallbackStatusCode = "";
640− var fallbackURICode = '""';
641− if (fallback !== "") {
642− // fallbackStatusCode has %4 in it because we want to substitute it for fallbackURICode
643− // which in kMascotImageCode is %4
644− fallbackStatusCode += 'onStatusChanged: if (status === Image.Error) source = %4;';
645− fallbackURICode = 'decodeURI("%1")'.arg(fallback);
647− mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible).arg(fallbackStatusCode).arg(fallbackURICode);
650− var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
652− var hasTitleContainer = hasTitle && (hasEmblem || (hasMascot && (hasSubtitle || hasAttributes)));
653− var titleSubtitleCode = '';
656− if (headerAsOverlay) {
657− titleColor = 'root.scopeStyle && overlayLoader.item ? root.scopeStyle.getTextColor(overlayLoader.item.luminance) : (overlayLoader.item && overlayLoader.item.luminance > 0.7 ? theme.palette.normal.baseText : "white")';
658− } else if (hasSummary) {
659− titleColor = 'summary.color';
660− } else if (hasBackground) {
661− titleColor = summaryColorWithBackground;
663− titleColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
667− var subtitleAnchors;
668− var attributesAnchors;
669− var titleContainerAnchors;
670− var titleRightAnchor;
671− var titleWidth = "undefined";
673− var extraRightAnchor = '';
674− var extraLeftAnchor = '';
675− if (!touchdownOnArtShape) {
676− extraRightAnchor = 'rightMargin: units.gu(1); \n';
677− extraLeftAnchor = 'leftMargin: units.gu(1); \n';
678− } else if (headerAsOverlay && !hasEmblem) {
679− extraRightAnchor = 'rightMargin: units.gu(1); \n';
683− titleContainerAnchors = 'verticalCenter: parent.verticalCenter; ';
685− titleContainerAnchors = 'right: parent.right; ';
686− titleContainerAnchors += headerLeftAnchor;
687− titleContainerAnchors += headerVerticalAnchors;
688− if (!headerLeftAnchorHasMargin) {
689− titleContainerAnchors += extraLeftAnchor;
693− titleRightAnchor = 'right: emblemIcon.left; \n\
694− rightMargin: emblemIcon.width > 0 ? units.gu(0.5) : 0; \n';
696− titleRightAnchor = 'right: parent.right; \n'
697− titleRightAnchor += extraRightAnchor;
700− if (hasTitleContainer) {
701− // Using headerTitleContainer
702− titleAnchors = titleRightAnchor;
703− titleAnchors += 'left: parent.left; \n\
705− subtitleAnchors = 'right: parent.right; \n\
706− left: parent.left; \n';
707− subtitleAnchors += extraRightAnchor;
709− attributesAnchors = subtitleAnchors + 'top: subtitleLabel.bottom;\n';
710− subtitleAnchors += 'top: titleLabel.bottom;\n';
712− attributesAnchors = subtitleAnchors + 'top: titleLabel.bottom;\n';
714− } else if (hasMascot) {
715− // Using row without titleContainer
716− titleAnchors = 'verticalCenter: parent.verticalCenter;\n';
717− titleWidth = "parent.width - x";
719− if (headerAsOverlay) {
720− // Using anchors to the overlay
721− titleAnchors = titleRightAnchor;
722− titleAnchors += 'left: parent.left; \n\
723− leftMargin: units.gu(1); \n\
724− top: overlayLoader.top; \n\
725− topMargin: units.gu(1) + overlayLoader.height - overlayLoader.overlayHeight; \n';
727− // Using anchors to the mascot/parent
728− titleAnchors = titleRightAnchor;
729− titleAnchors += headerLeftAnchor;
730− titleAnchors += headerVerticalAnchors;
731− if (!headerLeftAnchorHasMargin) {
732− titleAnchors += extraLeftAnchor;
735− subtitleAnchors = 'left: titleLabel.left; \n\
736− leftMargin: titleLabel.leftMargin; \n';
737− subtitleAnchors += extraRightAnchor;
740− subtitleAnchors += 'right: parent.right; \n';
742− subtitleAnchors += 'right: titleLabel.right; \n';
746− attributesAnchors = subtitleAnchors + 'top: subtitleLabel.bottom;\n';
747− subtitleAnchors += 'top: titleLabel.bottom;\n';
749− attributesAnchors = subtitleAnchors + 'top: titleLabel.bottom;\n';
753− var titleAlignment = "Text.AlignHCenter";
754− if (template["card-layout"] === "horizontal"
755− || typeof components["title"] !== "object"
756− || components["title"]["align"] === "left") titleAlignment = "Text.AlignLeft";
757− var keys = ["mascot", "emblem", "subtitle", "attributes", "summary"];
758− for (var key in keys) {
761− if (typeof components[key] === "string"
762− || typeof components[key]["field"] === "string") titleAlignment = "Text.AlignLeft";
768− // code for different elements
769− var titleLabelVisibleExtra = (headerAsOverlay ? '&& overlayLoader.active': '');
770− var titleCode = kTitleLabelCode.arg(titleAnchors).arg(titleColor).arg(titleLabelVisibleExtra).arg(titleWidth).arg(titleAlignment);
774− // code for the title container
775− var containerCode = [];
776− var containerHeight = 'titleLabel.height';
777− containerCode.push(titleCode);
779− subtitleCode = kSubtitleLabelCode.arg(subtitleAnchors).arg(titleColor);
780− containerCode.push(subtitleCode);
781− containerHeight += ' + subtitleLabel.height';
784− containerCode.push(kEmblemIconCode.arg(extraRightAnchor).arg(titleColor));
786− if (hasAttributes) {
787− attributesCode = kAttributesRowCode.arg(attributesAnchors).arg(titleColor);
788− containerCode.push(attributesCode);
789− containerHeight += ' + attributesRow.height';
792− if (hasTitleContainer) {
794− titleSubtitleCode = kHeaderContainerCodeGenerator(titleContainerAnchors, containerHeight, containerCode);
797− titleSubtitleCode = titleCode;
799− titleSubtitleCode += subtitleCode;
801− if (hasAttributes) {
802− titleSubtitleCode += attributesCode;
808− var rowCode = [mascotCode, titleSubtitleCode];
809− if (mascotShapeCode != '') {
810− rowCode.unshift(mascotShapeCode);
812− code += kHeaderRowCodeGenerator(isCardTool, headerVerticalAnchors + headerLeftAnchor, rowCode)
814− code += mascotShapeCode + mascotCode + titleSubtitleCode;
818− var audioProgressBarLeftAnchor = 'audioButton.right';
819− var audioProgressBarBottomAnchor = 'audioButton.bottom';
820− var audioProgressBarTextColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
822− code += kAudioProgressBarCode.arg(audioProgressBarBottomAnchor)
823− .arg(audioProgressBarLeftAnchor)
824− .arg(audioProgressBarTextColor);
826− var audioButtonAnchorsFill;
827− var audioButtonWidth;
828− var audioButtonHeight;
830− audioButtonAnchorsFill = 'artShapeHolder';
831− audioButtonWidth = 'undefined';
832− audioButtonHeight = 'undefined';
834− audioButtonAnchorsFill = 'undefined';
835− audioButtonWidth = 'height';
836− audioButtonHeight = isCardTool ? 'headerHeight + 2 * units.gu(1)'
837− : 'root.fixedHeaderHeight + 2 * units.gu(1)';
839− code += kAudioButtonCode.arg(audioButtonAnchorsFill).arg(audioButtonWidth).arg(audioButtonHeight).arg(asynchronous);
843− var summaryTopAnchor;
844− if (isHorizontal && hasArt) summaryTopAnchor = 'artShapeHolder.bottom';
845− else if (headerAsOverlay && hasArt) summaryTopAnchor = 'artShapeHolder.bottom';
846− else if (hasHeaderRow) summaryTopAnchor = 'row.bottom';
847− else if (hasTitleContainer) summaryTopAnchor = 'headerTitleContainer.bottom';
848− else if (hasMascot) summaryTopAnchor = 'mascotImage.bottom';
849− else if (hasAttributes) summaryTopAnchor = 'attributesRow.bottom';
850− else if (hasSubtitle) summaryTopAnchor = 'subtitleLabel.bottom';
851− else if (hasTitle) summaryTopAnchor = 'titleLabel.bottom';
852− else if (hasArt) summaryTopAnchor = 'artShapeHolder.bottom';
853− else summaryTopAnchor = 'parent.top';
856− if (hasBackground) {
857− summaryColor = summaryColorWithBackground;
859− summaryColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
862− var summaryTopMargin = (hasMascot || hasSubtitle || hasAttributes ? 'anchors.margins' : '0');
864− code += kSummaryLabelCode.arg(summaryTopAnchor).arg(summaryTopMargin).arg(summaryColor);
868−// if (artShapeStyle != "shadow" && artShapeStyle != "icon") {
869−// var touchdownAnchors;
871− if (hasSocialActions) {
873− var socialTopAnchor;
875− if (hasSummary) socialTopAnchor = 'summary.bottom;';
876− else if (isHorizontal && hasArt) socialTopAnchor = 'artShapeHolder.bottom;';
877− else if (headerAsOverlay && hasArt) socialTopAnchor = 'artShapeHolder.bottom;';
878− else if (hasHeaderRow) socialTopAnchor = 'row.bottom;';
879− else if (hasTitleContainer) socialTopAnchor = 'headerTitleContainer.bottom;';
880− else if (hasMascot) socialTopAnchor = 'mascotImage.bottom;';
881− else if (hasAttributes) socialTopAnchor = 'attributesRow.bottom;';
882− else if (hasSubtitle) socialTopAnchor = 'subtitleLabel.bottom;';
883− else if (hasTitle) socialTopAnchor = 'titleLabel.bottom;';
884− else if (hasArt) socialTopAnchor = 'artShapeHolder.bottom;';
885− else socialTopAnchor = 'parent.top';
887− socialAnchors = 'top: ' + socialTopAnchor + ' left: parent.left; right: parent.right; topMargin: units.gu(1);'
890− if (hasBackground) {
891− socialColor = summaryColorWithBackground;
893− socialColor = 'root.scopeStyle ? root.scopeStyle.foreground : theme.palette.normal.baseText';
896− code += kSocialActionsRowCode.arg(socialAnchors).arg(socialColor);
899− if (artShapeStyle != "shadow" && artShapeStyle != "icon") {
900− var touchdownAnchors;
901− if (hasBackground) {
902− touchdownAnchors = 'fill: backgroundLoader';
903− } else if (touchdownOnArtShape) {
904− touchdownAnchors = 'fill: artShapeHolder';
906− touchdownAnchors = 'fill: root'
908− code += kTouchdownCode.arg(touchdownAnchors);
911− var implicitHeight = 'implicitHeight: ';
912− if (hasSocialActions) {
913− implicitHeight += 'socialActionsRow.y + socialActionsRow.height + units.gu(1);\n';
914− } else if (hasSummary) {
915− implicitHeight += 'summary.y + summary.height + units.gu(1);\n';
916− } else if (isAudio) {
917− implicitHeight += 'audioButton.height;\n';
918− } else if (headerAsOverlay) {
919− implicitHeight += 'artShapeHolder.height;\n';
920− } else if (hasHeaderRow) {
921− implicitHeight += 'row.y + row.height + units.gu(1);\n';
922− } else if (hasMascot) {
923− implicitHeight += 'mascotImage.y + mascotImage.height;\n';
924− } else if (hasTitleContainer) {
925− implicitHeight += 'headerTitleContainer.y + headerTitleContainer.height + units.gu(1);\n';
926− } else if (hasAttributes) {
927− implicitHeight += 'attributesRow.y + attributesRow.height + units.gu(1);\n';
928− } else if (hasSubtitle) {
929− implicitHeight += 'subtitleLabel.y + subtitleLabel.height + units.gu(1);\n';
930− } else if (hasTitle) {
931− implicitHeight += 'titleLabel.y + titleLabel.height + units.gu(1);\n';
932− } else if (hasArt) {
933− implicitHeight += 'artShapeHolder.height;\n';
935− implicitHeight = '';
938− // Close the AbstractButton
939− code += implicitHeight + '}\n';
944−function createCardComponent(parent, template, components, isCardTool, artShapeStyle, identifier) {
945− var imports = 'import QtQuick 2.4; \n\
946− import Ubuntu.Components 1.3; \n\
947− import Ubuntu.Settings.Components 0.1; \n\
949− import Utils 0.1;\n';
950− var card = cardString(template, components, isCardTool, artShapeStyle);
951− var code = imports + 'Component {\n' + card + '}\n';
954− return Qt.createQmlObject(code, parent, identifier);
956− console.error("ERROR: Invalid component created.");
957− console.error("Template:");
958− console.error(JSON.stringify(template));
959− console.error("Components:");
960− console.error(JSON.stringify(components));
961− console.error("Code:");
962− console.error(code);
plugins/Dash/CardCreatorCache.qmldeleted−40
@@ -1,40 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
19−import "CardCreator.js" as CardCreator
24− property var cache: new Object();
26− function getCardComponent(template, components, isCardTool, artShapeStyle) {
27− if (template === undefined || components === undefined)
30− var tString = JSON.stringify(template);
31− var cString = JSON.stringify(components);
32− var allString = tString + cString + isCardTool;
33− var component = cache[allString];
34− if (component === undefined) {
35− component = CardCreator.createCardComponent(root, template, components, isCardTool, artShapeStyle, allString);
36− cache[allString] = component;
plugins/Dash/CardSocialActions.qmldeleted−94
@@ -1,94 +0,0 @@
2− * Copyright 2016 Canonical Ltd.
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.
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.
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/>.
18−import QtQuick.Layouts 1.1
19−import Ubuntu.Components 1.3
23− spacing: units.gu(0.5)
25− property alias model: repeater.model
26− property color color: theme.palette.normal.baseText
28− signal clicked(var actionId)
32− visible: repeater.count > 0
36− leftMargin:units.dp(1);
37− rightMargin: units.dp(1);
39− color: Qt.darker(theme.palette.normal.background, 1.12)
40− height: visible ? units.dp(1) : 0
48− leftMargin: units.gu(1)
49− rightMargin: units.gu(1)
52− readonly property int visibleItems: {
53− if (width <= units.gu(12)) // small card
55− else if (width <= units.gu(21)) // medium card
57− else // large or horizontal card
65− active: index < row.visibleItems
66− sourceComponent: AbstractButton {
67− objectName: "delegate" + index
74− readonly property url urlIcon: modelData && modelData["icon"] || ""
75− readonly property url urlTemporaryIcon: "temporaryIcon" in modelData && modelData["temporaryIcon"] || ""
78− // FIXME Workaround for bug https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1421293
79− width: implicitWidth > 0 && implicitHeight > 0 ? (implicitWidth / implicitHeight * height) : implicitWidth
81− color: socialActions.color
84− if (urlIcon) source = urlIcon
88− onClicked: socialActions.clicked(modelData["id"]);
89− onPressedChanged: if (pressed && icon.urlTemporaryIcon != "") icon.source = icon.urlTemporaryIcon
plugins/Dash/CroppedImageMinimumSourceSize.qmldeleted−38
@@ -1,38 +0,0 @@
2− * Copyright (C) 2014, 2015 Canonical, Ltd.
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.
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.
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/>.
22− fillMode: Image.PreserveAspectCrop
24− property bool useHeight: false
25− function updateUseHeight()
27− // Do not turn into a binding since otherwise the qml
28− // engine complains about binding loops
29− useHeight = (implicitWidth / implicitHeight) > (width / height);
32− onHeightChanged: updateUseHeight();
33− onWidthChanged: updateUseHeight();
34− onImplicitHeightChanged: updateUseHeight();
35− onImplicitWidthChanged: updateUseHeight();
37− sourceSize: useHeight ? Qt.size(0, height) : Qt.size(width, 0)
plugins/Dash/Dash.qmltypesdeleted−100
@@ -1,100 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Dash 0.1 plugins'
11− name: "AbstractDashView"
12− defaultProperty: "data"
13− prototype: "QQuickItem"
14− Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
15− Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
16− Property { name: "columnSpacing"; type: "double" }
17− Property { name: "rowSpacing"; type: "double" }
18− Property { name: "cacheBuffer"; type: "int" }
19− Property { name: "displayMarginBeginning"; type: "double" }
20− Property { name: "displayMarginEnd"; type: "double" }
23− name: "HorizontalJournal"
24− defaultProperty: "data"
25− prototype: "AbstractDashView"
26− exports: ["Dash/HorizontalJournal 0.1"]
27− exportMetaObjectRevisions: [0]
28− Property { name: "rowHeight"; type: "double" }
31− name: "ListViewWithPageHeader"
32− defaultProperty: "flickableData"
33− prototype: "QQuickFlickable"
34− exports: ["Dash/ListViewWithPageHeader 0.1"]
35− exportMetaObjectRevisions: [0]
36− Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
37− Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
38− Property { name: "pageHeader"; type: "QQuickItem"; isPointer: true }
39− Property { name: "sectionDelegate"; type: "QQmlComponent"; isPointer: true }
40− Property { name: "sectionProperty"; type: "string" }
41− Property { name: "forceNoClip"; type: "bool" }
42− Property { name: "stickyHeaderHeight"; type: "int"; isReadonly: true }
43− Property { name: "headerItemShownHeight"; type: "double"; isReadonly: true }
44− Property { name: "cacheBuffer"; type: "int" }
45− Signal { name: "headerChanged" }
46− Method { name: "positionAtBeginning" }
47− Method { name: "showHeader" }
48− Method { name: "firstCreatedIndex"; type: "int" }
49− Method { name: "createdItemCount"; type: "int" }
53− Parameter { name: "modelIndex"; type: "int" }
56− name: "maximizeVisibleArea"
58− Parameter { name: "modelIndex"; type: "int" }
61− name: "maximizeVisibleArea"
63− Parameter { name: "modelIndex"; type: "int" }
64− Parameter { name: "itemHeight"; type: "int" }
69− defaultProperty: "data"
70− prototype: "AbstractDashView"
71− exports: ["Dash/OrganicGrid 0.1"]
72− exportMetaObjectRevisions: [0]
73− Property { name: "smallDelegateSize"; type: "QSizeF" }
74− Property { name: "bigDelegateSize"; type: "QSizeF" }
77− name: "VerticalJournal"
78− defaultProperty: "data"
79− prototype: "AbstractDashView"
80− exports: ["Dash/VerticalJournal 0.1"]
81− exportMetaObjectRevisions: [0]
82− Property { name: "columnWidth"; type: "double" }
86− name: "CardCreatorCache"
87− exports: ["CardCreatorCache -1.-1"]
88− exportMetaObjectRevisions: [-1]
92− Property { name: "cache"; type: "QVariant" }
94− name: "getCardComponent"
96− Parameter { name: "template"; type: "QVariant" }
97− Parameter { name: "components"; type: "QVariant" }
plugins/Dash/DashAudioPlayer.qmldeleted−96
@@ -1,96 +0,0 @@
2− * Copyright (C) 2015 Canonical, Ltd.
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.
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.
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/>.
19−import QtMultimedia 5.6
23− readonly property real progress: audio.position / audio.duration
24− readonly property bool playing: audio.playbackState === Audio.PlayingState
25− readonly property bool paused: audio.playbackState === Audio.PausedState
26− readonly property bool stopped: audio.playbackState === Audio.StoppedState
27− readonly property alias position: audio.position
28− readonly property url currentSource: audio.playlist.currentItemSource
30− function playSource(newSource, newPlaylist) {
32− audio.playlist.clear();
34− // Look for newSource in newPlaylist
35− var sourceIndex = -1;
36− for (var i in newPlaylist) {
37− if (AudioUrlComparer.compare(newSource, newPlaylist[i])) {
43− if (sourceIndex === -1 && newSource != "") {
44− // If the playing song is not in the playlist, add it
45− urls.push(newSource);
48− for (var i in newPlaylist) {
49− urls.push(newPlaylist[i]);
51− audio.playlist.addItems(urls);
52− audio.playlist.currentIndex = sourceIndex;
54− audio.playlist.addItem(newSource);
55− audio.playlist.currentIndex = 0;
72− property QtObject audio: Audio {
76− objectName: "playlist"
79− onErrorStringChanged: console.warn("Dash Audio player error:", errorString)
82− function lengthToString(s) {
83− if (typeof(s) !== "number" || s < 0) return "";
85− var sec = "" + s % 60;
86− if (sec.length == 1) sec = "0" + sec;
87− var hour = Math.floor(s / 3600);
89− return Math.floor(s / 60) + ":" + sec;
91− var min = "" + Math.floor(s / 60) % 60;
92− if (min.length == 1) min = "0" + min;
93− return hour + ":" + min + ":" + sec;
plugins/Dash/ScopeStyle.qmldeleted−95
@@ -1,95 +0,0 @@
2− * Copyright 2014 Canonical Ltd.
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.
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.
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/>.
19−import Ubuntu.Components 1.3
21−/*! \brief Helper for processing scope customization options.
23− It will take the customizations object passed by the scope and
24− process it to provide the scope UI with data such as colors or
29− /// Style object passed from the scope
30− property var style: Object()
32− /// Color used for text and symbolic icons
33− readonly property color foreground: "foreground-color" in style ? style["foreground-color"] : d.defaultDark
35− /// Luminance of the foreground color
36− readonly property real foregroundLuminance: foreground ? Style.luminance(foreground) : Style.luminance(d.defaultDark)
38− /// Color used for the overall background
39− readonly property color background: "background-color" in style ? style["background-color"] : "#00f5f5f5"
41− /// Luminance of the background color
42− readonly property real backgroundLuminance: background ? Style.luminance(background) : Style.luminance(d.defaultLight)
44− /*! \brief Get the most contrasting available color based on luminance
46− * If background color is transparent, theme provided colors are taken into account
48− function getTextColor(luminance) {
49− if (Math.abs(foregroundLuminance - luminance) >
50− Math.abs(d.opaqueBackgroundLuminance - luminance)) {
53− return d.opaqueBackground;
57− /// Source of the logo image for the header
58− readonly property url headerLogo: "logo" in d.headerStyle ? d.headerStyle["logo"] : ""
60− /// Background style for the header
61− readonly property url headerBackground: "background" in d.headerStyle ? d.headerStyle["background"] : "color:///#ffffff"
63− /// Foreground color for the header
64− readonly property color headerForeground: "foreground-color" in d.headerStyle ? d.headerStyle["foreground-color"] : foreground
66− /// Color of the header divider
67− readonly property color headerDividerColor: "divider-color" in d.headerStyle ? d.headerStyle["divider-color"] : "#e0e0e0"
69− /// Background style for the navigation
70− readonly property url navigationBackground: "navigation-background" in d.headerStyle ? d.headerStyle["navigation-background"] : "color:///#f5f5f5"
72− /// Color of the primary preview button
73− readonly property color previewButtonColor: "preview-button-color" in style ? style["preview-button-color"] : theme.palette.normal.positive
76− property var d: QtObject {
77− // FIXME: should be taken from the theme
78− readonly property color defaultLight: "white"
79− readonly property color defaultDark: UbuntuColors.darkGrey
80− readonly property real defaultLightLuminance: Style.luminance(defaultLight)
81− readonly property real defaultDarkLuminance: Style.luminance(defaultDark)
83− readonly property color opaqueBackground: {
86− (Math.abs(foregroundLuminance - defaultLightLuminance) >
87− Math.abs(foregroundLuminance - defaultDarkLuminance)) ?
88− defaultLight : defaultDark
90− readonly property real opaqueBackgroundLuminance: Style.luminance(opaqueBackground)
92− readonly property var headerStyle: "page-header" in style ? style["page-header"] : { }
plugins/Dash/abstractdashview.cppdeleted−346
@@ -1,346 +0,0 @@
2− * Copyright (C) 2013, 2014 Canonical, Ltd.
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.
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.
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/>.
17−#include "abstractdashview.h"
19−AbstractDashView::AbstractDashView()
20− : m_delegateModel(nullptr)
21− , m_asyncRequestedIndex(-1)
24− , m_buffer(320) // Same value used in qquickitemview.cpp in Qt 5.4
25− , m_displayMarginBeginning(0)
26− , m_displayMarginEnd(0)
27− , m_needsRelayout(false)
28− , m_delegateValidated(false)
29− , m_implicitHeightDirty(false)
31− connect(this, &AbstractDashView::widthChanged, this, &AbstractDashView::relayout);
32− connect(this, &AbstractDashView::heightChanged, this, &AbstractDashView::onHeightChanged);
35−QAbstractItemModel *AbstractDashView::model() const
37− return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr;
40−void AbstractDashView::setModel(QAbstractItemModel *model)
42− if (model != this->model()) {
43− if (!m_delegateModel) {
44− createDelegateModel();
46− disconnect(m_delegateModel, &QQmlDelegateModel::modelUpdated, this, &AbstractDashView::onModelUpdated);
48− m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
49− connect(m_delegateModel, &QQmlDelegateModel::modelUpdated, this, &AbstractDashView::onModelUpdated);
51− cleanupExistingItems();
53− Q_EMIT modelChanged();
58−QQmlComponent *AbstractDashView::delegate() const
60− return m_delegateModel ? m_delegateModel->delegate() : nullptr;
63−void AbstractDashView::setDelegate(QQmlComponent *delegate)
65− if (delegate != this->delegate()) {
66− if (!m_delegateModel) {
67− createDelegateModel();
70− cleanupExistingItems();
72− m_delegateModel->setDelegate(delegate);
74− Q_EMIT delegateChanged();
75− m_delegateValidated = false;
80−qreal AbstractDashView::columnSpacing() const
82− return m_columnSpacing;
85−void AbstractDashView::setColumnSpacing(qreal columnSpacing)
87− if (columnSpacing != m_columnSpacing) {
88− m_columnSpacing = columnSpacing;
89− Q_EMIT columnSpacingChanged();
91− if (isComponentComplete()) {
97−qreal AbstractDashView::rowSpacing() const
102−void AbstractDashView::setRowSpacing(qreal rowSpacing)
104− if (rowSpacing != m_rowSpacing) {
105− m_rowSpacing = rowSpacing;
106− Q_EMIT rowSpacingChanged();
108− if (isComponentComplete()) {
114−int AbstractDashView::cacheBuffer() const
119−void AbstractDashView::setCacheBuffer(int buffer)
122− qmlInfo(this) << "Cannot set a negative cache buffer";
126− if (m_buffer != buffer) {
128− if (isComponentComplete()) {
131− emit cacheBufferChanged();
135−qreal AbstractDashView::displayMarginBeginning() const
137− return m_displayMarginBeginning;
140−void AbstractDashView::setDisplayMarginBeginning(qreal begin)
142− if (m_displayMarginBeginning == begin)
144− m_displayMarginBeginning = begin;
145− if (isComponentComplete()) {
148− emit displayMarginBeginningChanged();
151−qreal AbstractDashView::displayMarginEnd() const
153− return m_displayMarginEnd;
156−void AbstractDashView::setDisplayMarginEnd(qreal end)
158− if (m_displayMarginEnd == end)
160− m_displayMarginEnd = end;
161− if (isComponentComplete()) {
164− emit displayMarginEndChanged();
167−void AbstractDashView::createDelegateModel()
169− m_delegateModel = new QQmlDelegateModel(qmlContext(this), this);
170− connect(m_delegateModel, &QQmlDelegateModel::createdItem, this, &AbstractDashView::itemCreated);
171− if (isComponentComplete())
172− m_delegateModel->componentComplete();
175−void AbstractDashView::refill()
177− if (!isComponentComplete() || height() < 0) {
181− const qreal from = -m_displayMarginBeginning;
182− const qreal to = height() + m_displayMarginEnd;
183− const qreal bufferFrom = from - m_buffer;
184− const qreal bufferTo = to + m_buffer;
186− bool added = addVisibleItems(from, to, false);
187− bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
188− added |= addVisibleItems(bufferFrom, bufferTo, true);
190− if (added || removed) {
191− m_implicitHeightDirty = true;
196−bool AbstractDashView::addVisibleItems(qreal fillFromY, qreal fillToY, bool asynchronous)
198− if (fillToY <= fillFromY)
204− if (m_delegateModel->count() == 0)
209− findBottomModelIndexToAdd(&modelIndex, &yPos);
210− bool changed = false;
211− while (modelIndex < m_delegateModel->count() && yPos <= fillToY) {
212− if (!createItem(modelIndex, asynchronous))
216− findBottomModelIndexToAdd(&modelIndex, &yPos);
219− findTopModelIndexToAdd(&modelIndex, &yPos);
220− while (modelIndex >= 0 && yPos > fillFromY) {
221− if (!createItem(modelIndex, asynchronous))
225− findTopModelIndexToAdd(&modelIndex, &yPos);
231−QQuickItem *AbstractDashView::createItem(int modelIndex, bool asynchronous)
233− if (asynchronous && m_asyncRequestedIndex != -1)
236− m_asyncRequestedIndex = -1;
237− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
238− QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
241− m_delegateModel->release(object);
242− if (!m_delegateValidated) {
243− m_delegateValidated = true;
244− QObject* delegateObj = delegate();
245− qmlInfo(delegateObj ? delegateObj : this) << "Delegate must be of Item type";
248− m_asyncRequestedIndex = modelIndex;
252− addItemToView(modelIndex, item);
257−void AbstractDashView::releaseItem(QQuickItem *item)
259− QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
260− if (flags & QQmlDelegateModel::Destroyed) {
261− item->setParentItem(nullptr);
265−void AbstractDashView::setImplicitHeightDirty()
267− m_implicitHeightDirty = true;
270−void AbstractDashView::itemCreated(int modelIndex, QObject *object)
272− QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
274− qWarning() << "AbstractDashView::itemCreated got a non item for index" << modelIndex;
277− item->setParentItem(this);
279− // We only need to call createItem if we are here because of an asynchronous generation
280− // otherwise we are in this slot because createItem is creating the item sync
281− // and thus we don't need to call createItem again, nor need to set m_implicitHeightDirty
282− // and call polish because the sync createItem was called from addVisibleItems that
283− // is called from refill that will already do those if an item was added
284− if (modelIndex == m_asyncRequestedIndex) {
285− createItem(modelIndex, false);
286− m_implicitHeightDirty = true;
291−void AbstractDashView::onModelUpdated(const QQmlChangeSet &changeSet, bool reset)
294− cleanupExistingItems();
296− processModelRemoves(changeSet.removes());
302−void AbstractDashView::relayout()
304− m_needsRelayout = true;
308−void AbstractDashView::onHeightChanged()
313−void AbstractDashView::updatePolish()
318− if (m_needsRelayout) {
320− m_needsRelayout = false;
321− m_implicitHeightDirty = true;
326− const qreal from = -m_displayMarginBeginning;
327− const qreal to = height() + m_displayMarginEnd;
328− updateItemCulling(from, to);
330− if (m_implicitHeightDirty) {
331− calculateImplicitHeight();
332− m_implicitHeightDirty = false;
336−void AbstractDashView::componentComplete()
338− if (m_delegateModel)
339− m_delegateModel->componentComplete();
341− QQuickItem::componentComplete();
343− m_needsRelayout = true;
plugins/Dash/abstractdashview.hdeleted−129
@@ -1,129 +0,0 @@
2− * Copyright (C) 2013, 2014 Canonical, Ltd.
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.
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.
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/>.
17−#ifndef ABSTRACTDASHVIEW_H
18−#define ABSTRACTDASHVIEW_H
22−class QAbstractItemModel;
24−#pragma GCC diagnostic push
25−#pragma GCC diagnostic ignored "-pedantic"
26−#include <private/qqmldelegatemodel_p.h>
28−#pragma GCC diagnostic pop
30−class AbstractDashView : public QQuickItem
34− Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
35− Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
36− Q_PROPERTY(qreal columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged)
37− Q_PROPERTY(qreal rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged)
38− Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
39− Q_PROPERTY(qreal displayMarginBeginning READ displayMarginBeginning
40− WRITE setDisplayMarginBeginning
41− NOTIFY displayMarginBeginningChanged)
42− Q_PROPERTY(qreal displayMarginEnd READ displayMarginEnd
43− WRITE setDisplayMarginEnd
44− NOTIFY displayMarginEndChanged)
46−friend class VerticalJournalTest;
47−friend class HorizontalJournalTest;
48−friend class OrganicGridTest;
53− QAbstractItemModel *model() const;
54− void setModel(QAbstractItemModel *model);
56− QQmlComponent *delegate() const;
57− void setDelegate(QQmlComponent *delegate);
59− qreal columnSpacing() const;
60− void setColumnSpacing(qreal columnSpacing);
62− qreal rowSpacing() const;
63− void setRowSpacing(qreal rowSpacing);
65− int cacheBuffer() const;
66− void setCacheBuffer(int);
68− qreal displayMarginBeginning() const;
69− void setDisplayMarginBeginning(qreal);
71− qreal displayMarginEnd() const;
72− void setDisplayMarginEnd(qreal);
76− void delegateChanged();
77− void columnSpacingChanged();
78− void rowSpacingChanged();
79− void cacheBufferChanged();
80− void displayMarginBeginningChanged();
81− void displayMarginEndChanged();
87− void updatePolish() override;
88− void componentComplete() override;
90− void releaseItem(QQuickItem *item);
91− void setImplicitHeightDirty();
94− void itemCreated(int modelIndex, QObject *object);
95− void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
96− void onHeightChanged();
99− void createDelegateModel();
101− bool addVisibleItems(qreal fillFromY, qreal fillToY, bool asynchronous);
102− QQuickItem *createItem(int modelIndex, bool asynchronous);
104− virtual void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) = 0;
105− virtual void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) = 0;
106− virtual void addItemToView(int modelIndex, QQuickItem *item) = 0;
107− virtual bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) = 0;
108− virtual void cleanupExistingItems() = 0;
109− virtual void doRelayout() = 0;
110− virtual void updateItemCulling(qreal visibleFromY, qreal visibleToY) = 0;
111− virtual void calculateImplicitHeight() = 0;
112− virtual void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) = 0;
114− QQmlDelegateModel *m_delegateModel;
116− // Index we are waiting because we requested it asynchronously
117− int m_asyncRequestedIndex;
119− int m_columnSpacing;
122− qreal m_displayMarginBeginning;
123− qreal m_displayMarginEnd;
124− bool m_needsRelayout;
125− bool m_delegateValidated;
126− bool m_implicitHeightDirty;
plugins/Dash/graphics/music_progress_bg.pngdeleted
Binary file not shown.
plugins/Dash/horizontaljournal.cppdeleted−242
@@ -1,242 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
18− * The implementation is centered around m_visibleItems
19− * that a list for each of the items in the view.
20− * m_firstVisibleIndex is the index of the first item in m_visibleItems
21− * m_lastInRowIndexPosition is a map that contains the x position
22− * of items that are the last ones of a row so we can reconstruct the rows
26−#include "horizontaljournal.h"
28−#include <qqmlengine.h>
29−#pragma GCC diagnostic push
30−#pragma GCC diagnostic ignored "-pedantic"
31−#include <private/qqmldelegatemodel_p.h>
33−#include <private/qquickitem_p.h>
34−#pragma GCC diagnostic pop
36−HorizontalJournal::HorizontalJournal()
37− : m_firstVisibleIndex(-1)
42−qreal HorizontalJournal::rowHeight() const
47−void HorizontalJournal::setRowHeight(qreal rowHeight)
49− if (rowHeight != m_rowHeight) {
50− m_rowHeight = rowHeight;
51− Q_EMIT rowHeightChanged();
53− if (isComponentComplete()) {
54− Q_FOREACH(QQuickItem *item, m_visibleItems) {
55− item->setHeight(rowHeight);
62−void HorizontalJournal::findBottomModelIndexToAdd(int *modelIndex, qreal *yPos)
64− if (m_visibleItems.isEmpty()) {
68− *modelIndex = m_firstVisibleIndex + m_visibleItems.count();
69− if (m_lastInRowIndexPosition.contains(*modelIndex - 1)) {
70− *yPos = m_visibleItems.last()->y() + m_rowHeight + rowSpacing();
72− *yPos = m_visibleItems.last()->y();
77−void HorizontalJournal::findTopModelIndexToAdd(int *modelIndex, qreal *yPos)
79− if (m_visibleItems.isEmpty()) {
83− *modelIndex = m_firstVisibleIndex - 1;
84− if (m_lastInRowIndexPosition.contains(*modelIndex)) {
85− *yPos = m_visibleItems.first()->y() - rowSpacing() - m_rowHeight;
87− *yPos = m_visibleItems.first()->y();
92−bool HorizontalJournal::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
94− bool changed = false;
96− while (!m_visibleItems.isEmpty() && m_visibleItems.first()->y() + m_rowHeight < bufferFromY) {
97− releaseItem(m_visibleItems.takeFirst());
99− m_firstVisibleIndex++;
102− while (!m_visibleItems.isEmpty() && m_visibleItems.last()->y() > bufferToY) {
103− releaseItem(m_visibleItems.takeLast());
105− m_lastInRowIndexPosition.remove(m_firstVisibleIndex + m_visibleItems.count());
108− if (m_visibleItems.isEmpty()) {
109− m_firstVisibleIndex = -1;
115−void HorizontalJournal::addItemToView(int modelIndex, QQuickItem *item)
117− if (item->height() != m_rowHeight) {
118− qWarning() << "Item" << modelIndex << "height is not the one that the rowHeight mandates, resetting it";
119− item->setHeight(m_rowHeight);
122− if (m_visibleItems.isEmpty()) {
123− Q_ASSERT(modelIndex == 0);
126− m_visibleItems << item;
127− m_firstVisibleIndex = 0;
129− // modelIndex has to be either m_firstVisibleIndex - 1 or m_firstVisibleIndex + m_visibleItems.count()
130− if (modelIndex == m_firstVisibleIndex + m_visibleItems.count()) {
131− QQuickItem *lastItem = m_visibleItems.last();
132− if (lastItem->x() + lastItem->width() + columnSpacing() + item->width() <= width()) {
134− item->setY(lastItem->y());
135− item->setX(lastItem->x() + lastItem->width() + columnSpacing());
138− item->setY(lastItem->y() + m_rowHeight + rowSpacing());
140− m_lastInRowIndexPosition[modelIndex - 1] = lastItem->x();
142− m_visibleItems << item;
143− } else if (modelIndex == m_firstVisibleIndex - 1) {
144− QQuickItem *firstItem = m_visibleItems.first();
145− if (m_lastInRowIndexPosition.contains(modelIndex)) {
146− // It is the last item of its row, so start a new one since we're going back
147− item->setY(firstItem->y() - rowSpacing() - m_rowHeight);
148− item->setX(m_lastInRowIndexPosition[modelIndex]);
150− item->setY(firstItem->y());
151− item->setX(firstItem->x() - columnSpacing() - item->width());
153− m_firstVisibleIndex = modelIndex;
154− m_visibleItems.prepend(item);
156− qWarning() << "HorizontalJournal::addItemToView - Got unexpected modelIndex"
157− << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
162−void HorizontalJournal::cleanupExistingItems()
164− // Cleanup the existing items
165− Q_FOREACH(QQuickItem *item, m_visibleItems)
167− m_visibleItems.clear();
168− m_lastInRowIndexPosition.clear();
169− m_firstVisibleIndex = -1;
170− setImplicitHeightDirty();
173−void HorizontalJournal::calculateImplicitHeight()
175− if (m_firstVisibleIndex >= 0) {
176− const int nIndexes = m_firstVisibleIndex + m_visibleItems.count();
177− const double bottomMostY = m_visibleItems.last()->y() + m_rowHeight;
178− const double averageHeight = bottomMostY / nIndexes;
179− setImplicitHeight(bottomMostY + averageHeight * (model()->rowCount() - nIndexes));
181− setImplicitHeight(0);
185−void HorizontalJournal::processModelRemoves(const QVector<QQmlChangeSet::Change> &removes)
187− Q_FOREACH(const QQmlChangeSet::Change remove, removes) {
188− for (int i = remove.count - 1; i >= 0; --i) {
189− const int indexToRemove = remove.index + i;
190− // We only support removing from the end so
191− // any of the last items of a column has to be indexToRemove
192− const int lastIndex = m_firstVisibleIndex + m_visibleItems.count() - 1;
193− if (indexToRemove == lastIndex) {
194− releaseItem(m_visibleItems.takeLast());
195− m_lastInRowIndexPosition.remove(indexToRemove);
197− if (indexToRemove < lastIndex) {
198− qDebug() << "HorizontalJournal only supports removal from the end of the model, resetting instead";
199− cleanupExistingItems();
202− setImplicitHeightDirty();
207− if (m_visibleItems.isEmpty()) {
208− m_firstVisibleIndex = -1;
213−void HorizontalJournal::doRelayout()
215− // If m_firstVisibleIndex is not 0 we need to drop all the delegates
216− // since we can't consistently relayout without the first item being there
218− if (m_firstVisibleIndex == 0) {
220− const QList<QQuickItem*> allItems = m_visibleItems;
221− m_visibleItems.clear();
222− m_lastInRowIndexPosition.clear();
223− Q_FOREACH(QQuickItem *item, allItems) {
224− addItemToView(i, item);
228− Q_FOREACH(QQuickItem *item, m_visibleItems) {
231− m_visibleItems.clear();
232− m_lastInRowIndexPosition.clear();
233− m_firstVisibleIndex = -1;
237−void HorizontalJournal::updateItemCulling(qreal visibleFromY, qreal visibleToY)
239− Q_FOREACH(QQuickItem *item, m_visibleItems) {
240− QQuickItemPrivate::get(item)->setCulled(item->y() + m_rowHeight <= visibleFromY || item->y() >= visibleToY);
plugins/Dash/horizontaljournal.hdeleted−63
@@ -1,63 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
17−#ifndef HORIZONTALJOURNAL_H
18−#define HORIZONTALJOURNAL_H
20−#include "abstractdashview.h"
22− /** A horizontal journal is a view that creates delegates
23− * based on a model and layouts them one after the other
24− * in the same row until there is no more free space for the next item
25− * and so that item is layouted in the next row
27− * All delegates are forced to rowHeight if they don't have it.
29− class HorizontalJournal : public AbstractDashView
33− Q_PROPERTY(qreal rowHeight READ rowHeight WRITE setRowHeight NOTIFY rowHeightChanged)
35−friend class HorizontalJournalTest;
40− qreal rowHeight() const;
41− void setRowHeight(qreal rowHeight);
44− void rowHeightChanged();
47− void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
48− void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
49− bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
50− void addItemToView(int modelIndex, QQuickItem *item) override;
51− void cleanupExistingItems() override;
52− void calculateImplicitHeight() override;
53− void doRelayout() override;
54− void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
55− void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) override;
57− int m_firstVisibleIndex;
58− QList<QQuickItem*> m_visibleItems;
59− QMap<int, double> m_lastInRowIndexPosition;
plugins/Dash/listviewwithpageheader.cppdeleted−1395
@@ -1,1395 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
18− * Some documentation on how this thing works:
20− * A flickable has two very important concepts that define the top and
21− * height of the flickable area.
22− * The top is returned in minYExtent()
23− * The height is set using setContentHeight()
24− * By changing those two values we can make the list grow up or down
25− * as needed. e.g. if we are in the middle of the list
26− * and something that is above the viewport grows, since we do not
27− * want to change the viewport because of that we just adjust the
28− * minYExtent so that the list grows up.
30− * The implementation on the list relies on the delegateModel doing
31− * most of the instantiation work. You call createItem() when you
32− * need to create an item asking for it async or not. If returns null
33− * it means the item will be created async and the model will call the
34− * itemCreated slot with the item.
36− * updatePolish is the central point of dispatch for the work of the
37− * class. It is called by the scene graph just before drawing the class.
39− * * Make sure all items are positioned correctly
40− * * Add/Remove items if needed
41− * * Update the content height if it was dirty
43− * m_visibleItems contains all the items we have created at the moment.
44− * Actually not all of them are visible since it includes the ones
45− * in the cache area we create asynchronously to help performance.
46− * The first item in m_visibleItems has the m_firstVisibleIndex in
47− * the model. If you actually want to know what is the first
48− * item in the viewport you have to find the first non culled element
51− * All the items (except the header) are childs of m_clipItem which
52− * is a child of the contentItem() of the flickable (The contentItem()
53− * is what actually 'moves' in a a flickable). This way
54− * we can implement the clipping needed so we can have the header
55− * shown in the middle of the list over the items without the items
56− * leaking under the header in case it is transparent.
58− * The first item of m_visibleItems is the one that defines the
59− * positions of all the rest of items (see updatePolish()) and
60− * this is why sometimes we move it even if it's not the item
61− * that has triggered the function (i.e. in itemGeometryChanged())
63− * m_visibleItems is a list of ListItem. Each ListItem
64− * will contain a item and potentially a sectionItem. The sectionItem
65− * is only there when the list is using sectionDelegate+sectionProperty
66− * and this is the first item of the section. Each ListItem is vertically
67− * layouted with the sectionItem first and then the item.
69− * For sectioning we also have a section item alone (m_topSectionItem)
70− * that is used for the cases we need to show the sticky section item at
71− * the top of the view.
73− * Each delegate item has a context property called heightToClip that is
74− * used to communicate to the delegate implementation in case it has to
75− * clip itself because of overlapping with the top sticky section item.
76− * This is an implementation decision since it has been agreed it
77− * is easier to implement the clipping in QML with this info than to
78− * do it at the C++ level.
80− * Note that minYExtent and height are not always totally accurate, since
81− * we don't have the items created we can't guess their heights
82− * so we can only guarantee the values are correct when the first/last
83− * items of the list are visible, otherwise we just live with good enough
84− * values that make the list scrollable
86− * There are a few things that are not really implemented or tested properly
87− * which we don't use at the moment like changing the model, changing
88− * the section delegate, having a section delegate that changes its size, etc.
89− * The known missing features are marked with TODOs along the code.
92−#include "listviewwithpageheader.h"
94−#include <QCoreApplication>
97−#include <qqmlengine.h>
98−#pragma GCC diagnostic push
99−#pragma GCC diagnostic ignored "-pedantic"
100−#include <private/qqmlcontext_p.h>
101−#include <private/qqmldelegatemodel_p.h>
102−#include <private/qqmlglobal_p.h>
103−#include <private/qquickitem_p.h>
104−#include <private/qquickanimation_p.h>
105−#pragma GCC diagnostic pop
106−// #include <private/qquickrectangle_p.h>
108−qreal ListViewWithPageHeader::ListItem::height() const
110− return m_item->height() + (m_sectionItem ? m_sectionItem->height() : 0);
113−qreal ListViewWithPageHeader::ListItem::y() const
115− return m_item->y() - (m_sectionItem ? m_sectionItem->height() : 0);
118−void ListViewWithPageHeader::ListItem::setY(qreal newY)
120− if (m_sectionItem) {
121− m_sectionItem->setY(newY);
122− m_item->setY(newY + m_sectionItem->height());
128−bool ListViewWithPageHeader::ListItem::culled() const
130− return QQuickItemPrivate::get(m_item)->culled;
133−void ListViewWithPageHeader::ListItem::setCulled(bool culled)
135− QQuickItemPrivate::get(m_item)->setCulled(culled);
137− QQuickItemPrivate::get(m_sectionItem)->setCulled(culled);
140−void ListViewWithPageHeader::ListItem::setSectionItem(QQuickItem *sectionItem)
142− m_sectionItem = sectionItem;
145−ListViewWithPageHeader::ListViewWithPageHeader()
146− : m_delegateModel(nullptr)
147− , m_asyncRequestedIndex(-1)
148− , m_delegateValidated(false)
149− , m_firstVisibleIndex(-1)
151− , m_contentHeightDirty(false)
152− , m_headerItem(nullptr)
153− , m_previousContentY(0)
154− , m_headerItemShownHeight(0)
155− , m_sectionDelegate(nullptr)
156− , m_topSectionItem(nullptr)
157− , m_forceNoClip(false)
159− , m_inContentHeightKeepHeaderShown(false)
162− m_clipItem = new QQuickItem(contentItem());
163−// m_clipItem = new QQuickRectangle(contentItem());
164−// ((QQuickRectangle*)m_clipItem)->setColor(Qt::gray);
166− m_contentYAnimation = new QQuickNumberAnimation(this);
167− m_contentYAnimation->setEasing(QEasingCurve::OutQuad);
168− m_contentYAnimation->setProperty(QStringLiteral("contentY"));
169− m_contentYAnimation->setDuration(200);
170− m_contentYAnimation->setTargetObject(this);
172− connect(contentItem(), &QQuickItem::widthChanged, this, &ListViewWithPageHeader::onContentWidthChanged);
173− connect(this, &ListViewWithPageHeader::contentHeightChanged, this, &ListViewWithPageHeader::onContentHeightChanged);
174− connect(this, &ListViewWithPageHeader::heightChanged, this, &ListViewWithPageHeader::onHeightChanged);
175− connect(m_contentYAnimation, &QQuickNumberAnimation::runningChanged, this, &ListViewWithPageHeader::contentYAnimationRunningChanged);
177− setFlickableDirection(VerticalFlick);
180−ListViewWithPageHeader::~ListViewWithPageHeader()
184−QAbstractItemModel *ListViewWithPageHeader::model() const
186− return m_delegateModel ? m_delegateModel->model().value<QAbstractItemModel *>() : nullptr;
189−void ListViewWithPageHeader::setModel(QAbstractItemModel *model)
191− if (model != this->model()) {
192− if (!m_delegateModel) {
193− createDelegateModel();
195− disconnect(m_delegateModel, &QQmlDelegateModel::modelUpdated, this, &ListViewWithPageHeader::onModelUpdated);
197− m_delegateModel->setModel(QVariant::fromValue<QAbstractItemModel *>(model));
198− connect(m_delegateModel, &QQmlDelegateModel::modelUpdated, this, &ListViewWithPageHeader::onModelUpdated);
199− Q_EMIT modelChanged();
202−// Q_EMIT contentHeightChanged();
203−// Q_EMIT contentYChanged();
207−QQmlComponent *ListViewWithPageHeader::delegate() const
209− return m_delegateModel ? m_delegateModel->delegate() : nullptr;
212−void ListViewWithPageHeader::setDelegate(QQmlComponent *delegate)
214− if (delegate != this->delegate()) {
215− if (!m_delegateModel) {
216− createDelegateModel();
219− // Cleanup the existing items
220− Q_FOREACH(ListItem *item, m_visibleItems)
222− m_visibleItems.clear();
223− initializeValuesForEmptyList();
225− m_delegateModel->setDelegate(delegate);
227− Q_EMIT delegateChanged();
228− m_delegateValidated = false;
229− m_contentHeightDirty = true;
234−void ListViewWithPageHeader::initializeValuesForEmptyList()
236− m_firstVisibleIndex = -1;
239− m_clipItem->setY(0);
240− if (m_topSectionItem) {
241− QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
245−QQuickItem *ListViewWithPageHeader::header() const
247− return m_headerItem;
250−void ListViewWithPageHeader::setHeader(QQuickItem *headerItem)
252− if (m_headerItem != headerItem) {
253− qreal oldHeaderHeight = 0;
254− qreal oldHeaderY = 0;
256− oldHeaderHeight = m_headerItem->height();
257− oldHeaderY = m_headerItem->y();
258− m_headerItem->setParentItem(nullptr);
260− m_headerItem = headerItem;
262− m_headerItem->setParentItem(contentItem());
263− m_headerItem->setZ(1);
264− m_previousHeaderImplicitHeight = m_headerItem->implicitHeight();
265− QQuickItemPrivate::get(m_headerItem)->addItemChangeListener(this, QQuickItemPrivate::ImplicitHeight);
267− qreal newHeaderHeight = m_headerItem ? m_headerItem->height() : 0;
268− if (!m_visibleItems.isEmpty() && newHeaderHeight != oldHeaderHeight) {
269− headerHeightChanged(newHeaderHeight, oldHeaderHeight, oldHeaderY);
271− m_contentHeightDirty = true;
273− Q_EMIT headerChanged();
277−QQmlComponent *ListViewWithPageHeader::sectionDelegate() const
279− return m_sectionDelegate;
282−void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
284− if (delegate != m_sectionDelegate) {
285− // TODO clean existing sections
287− m_sectionDelegate = delegate;
289− m_topSectionItem = getSectionItem(QString(), false /*watchGeometry*/);
290− m_topSectionItem->setZ(3);
291− QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
292− connect(m_topSectionItem, &QQuickItem::heightChanged, this, &ListViewWithPageHeader::stickyHeaderHeightChanged);
294− // TODO create sections for existing items
296− Q_EMIT sectionDelegateChanged();
297− Q_EMIT stickyHeaderHeightChanged();
301−QString ListViewWithPageHeader::sectionProperty() const
303− return m_sectionProperty;
306−void ListViewWithPageHeader::setSectionProperty(const QString &property)
308− if (property != m_sectionProperty) {
309− m_sectionProperty = property;
311− updateWatchedRoles();
313− // TODO recreate sections
315− Q_EMIT sectionPropertyChanged();
319−bool ListViewWithPageHeader::forceNoClip() const
321− return m_forceNoClip;
324−void ListViewWithPageHeader::setForceNoClip(bool noClip)
326− if (noClip != m_forceNoClip) {
327− m_forceNoClip = noClip;
329− Q_EMIT forceNoClipChanged();
333−int ListViewWithPageHeader::stickyHeaderHeight() const
335− return m_topSectionItem ? m_topSectionItem->height() : 0;
338−qreal ListViewWithPageHeader::headerItemShownHeight() const
340− return m_headerItemShownHeight;
343−int ListViewWithPageHeader::cacheBuffer() const
345− return m_cacheBuffer;
348−void ListViewWithPageHeader::setCacheBuffer(int cacheBuffer)
350− if (cacheBuffer < 0) {
351− qmlInfo(this) << "Cannot set a negative cache buffer";
355− if (cacheBuffer != m_cacheBuffer) {
356− m_cacheBuffer = cacheBuffer;
357− Q_EMIT cacheBufferChanged();
362−void ListViewWithPageHeader::positionAtBeginning()
364− if (m_delegateModel->count() <= 0)
367− qreal headerHeight = (m_headerItem ? m_headerItem->height() : 0);
368− if (m_firstVisibleIndex != 0) {
369− // TODO This could be optimized by trying to reuse the interesection
370− // of items that may end up intersecting between the existing
371− // m_visibleItems and the items we are creating in the next loop
372− Q_FOREACH(ListItem *item, m_visibleItems)
374− m_visibleItems.clear();
375− m_firstVisibleIndex = -1;
377− // Create the item 0, it will be already correctly positioned at createItem()
378− m_clipItem->setY(0);
379− ListItem *item = createItem(0, false);
380− // Create the subsequent items
382− qreal pos = item->y() + item->height();
383− const qreal bufferTo = height() + m_cacheBuffer;
384− while (modelIndex < m_delegateModel->count() && pos <= bufferTo) {
385− if (!(item = createItem(modelIndex, false)))
387− pos += item->height();
391− m_previousContentY = m_visibleItems.first()->y() - headerHeight;
393− setContentY(m_visibleItems.first()->y() + m_clipItem->y() - headerHeight);
395− // TODO This should not be needed and the code that adjust the m_headerItem position
396− // in viewportMoved() should be enough but in some cases we have not found a way to reproduce
397− // yet the code of viewportMoved() fails so here we make sure that at least if we are calling
398− // positionAtBeginning the header item will be correctly positioned
399− m_headerItem->setY(-m_minYExtent);
403−static inline bool uFuzzyCompare(qreal r1, qreal r2)
405− return qFuzzyCompare(r1, r2) || (qFuzzyIsNull(r1) && qFuzzyIsNull(r2));
408−void ListViewWithPageHeader::showHeader()
413− const auto to = qMax(-minYExtent(), contentY() - m_headerItem->height() + m_headerItemShownHeight);
414− if (!uFuzzyCompare(to, contentY())) {
415− const bool headerShownByItsOwn = contentY() < m_headerItem->y() + m_headerItem->height();
416− if (headerShownByItsOwn && m_headerItemShownHeight == 0) {
417− // We are not clipping since we are just at the top of the viewport
418− // but because of the showHeader animation we will need to, so
419− // enable the clipping without logically moving the items
420− m_headerItemShownHeight = m_headerItem->y() + m_headerItem->height() - contentY();
421− if (!m_visibleItems.isEmpty()) {
423− ListItem *firstItem = m_visibleItems.first();
424− firstItem->setY(firstItem->y() - m_headerItemShownHeight);
427− Q_EMIT headerItemShownHeightChanged();
429− m_contentYAnimation->setTo(to);
430− contentYAnimationType = ContentYAnimationShowHeader;
431− m_contentYAnimation->start();
435−int ListViewWithPageHeader::firstCreatedIndex() const
437− return m_firstVisibleIndex;
440−int ListViewWithPageHeader::createdItemCount() const
442− return m_visibleItems.count();
445−QQuickItem *ListViewWithPageHeader::item(int modelIndex) const
447− ListItem *item = itemAtIndex(modelIndex);
449− return item->m_item;
454−bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex)
456− ListItem *listItem = itemAtIndex(modelIndex);
458− return maximizeVisibleArea(listItem, listItem->height());
464−bool ListViewWithPageHeader::maximizeVisibleArea(int modelIndex, int itemHeight)
469− ListItem *listItem = itemAtIndex(modelIndex);
471− return maximizeVisibleArea(listItem, itemHeight + (listItem->sectionItem() ? listItem->sectionItem()->height() : 0));
477−bool ListViewWithPageHeader::maximizeVisibleArea(ListItem *listItem, int listItemHeight)
481− const auto listItemY = m_clipItem->y() + listItem->y();
482− if (listItemY > contentY() && listItemY + listItemHeight > contentY() + height()) {
483− // we can scroll the list up to show more stuff
484− const auto to = qMin(listItemY, listItemY + listItemHeight - height());
485− m_contentYAnimation->setTo(to);
486− contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
487− m_contentYAnimation->start();
488− } else if ((listItemY < contentY() && listItemY + listItemHeight < contentY() + height()) ||
489− (m_topSectionItem && !listItem->sectionItem() && listItemY - m_topSectionItem->height() < contentY() && listItemY + listItemHeight < contentY() + height()))
491− // we can scroll the list down to show more stuff
492− auto realVisibleListItemY = listItemY;
493− if (m_topSectionItem) {
494− // If we are showing the top section sticky item and this item doesn't have a section
495− // item we have to make sure to scroll it a bit more so that it is not underlapping
496− // the top section sticky item
497− bool topSectionShown = !QQuickItemPrivate::get(m_topSectionItem)->culled;
498− if (topSectionShown && !listItem->sectionItem()) {
499− realVisibleListItemY -= m_topSectionItem->height();
502− const auto to = qMax(realVisibleListItemY, listItemY + listItemHeight - height());
503− m_contentYAnimation->setTo(to);
504− contentYAnimationType = ContentYAnimationMaximizeVisibleArea;
505− m_contentYAnimation->start();
512−qreal ListViewWithPageHeader::minYExtent() const
514−// qDebug() << "ListViewWithPageHeader::minYExtent" << m_minYExtent;
515− return m_minYExtent;
518−qreal ListViewWithPageHeader::maxYExtent() const
520− return height() - contentHeight();
523−void ListViewWithPageHeader::componentComplete()
525− if (m_delegateModel)
526− m_delegateModel->componentComplete();
528− QQuickFlickable::componentComplete();
533−void ListViewWithPageHeader::viewportMoved(Qt::Orientations orient)
535− // Check we are not being taken down and don't paint anything
536− // TODO Check if we still need this in 5.2
537− // For reproduction just inifnite loop testDash or testDashContent
538− if (!QQmlEngine::contextForObject(this)->parentContext())
541− QQuickFlickable::viewportMoved(orient);
542−// qDebug() << "ListViewWithPageHeader::viewportMoved" << contentY();
543− const qreal diff = m_previousContentY - contentY();
545− m_previousContentY = contentY();
550−void ListViewWithPageHeader::adjustHeader(qreal diff)
552− const bool showHeaderAnimationRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationShowHeader;
554− const auto oldHeaderItemShownHeight = m_headerItemShownHeight;
555− if (uFuzzyCompare(contentY(), -m_minYExtent) || contentY() > -m_minYExtent) {
556− m_headerItem->setHeight(m_headerItem->implicitHeight());
557− // We are going down (but it's not because of the rebound at the end)
558− // (but the header was not shown by it's own position)
559− // or the header is partially shown and we are not doing a maximizeVisibleArea either
560− const bool scrolledUp = m_previousContentY > contentY();
561− const bool notRebounding = qRound(contentY() + height()) < qRound(contentHeight());
562− const bool notShownByItsOwn = contentY() + diff >= m_headerItem->y() + m_headerItem->height();
563− const bool maximizeVisibleAreaRunning = m_contentYAnimation->isRunning() && contentYAnimationType == ContentYAnimationMaximizeVisibleArea;
565− if (!scrolledUp && (contentY() == -m_minYExtent || (m_headerItemShownHeight == 0 && m_previousContentY == m_headerItem->y()))) {
566− m_headerItemShownHeight = 0;
567− m_headerItem->setY(-m_minYExtent);
568− } else if ((scrolledUp && notRebounding && notShownByItsOwn && !maximizeVisibleAreaRunning) || (m_headerItemShownHeight > 0) || m_inContentHeightKeepHeaderShown) {
569− if (maximizeVisibleAreaRunning && diff > 0) {
570− // If we are maximizing and the header was shown, make sure we hide it
571− m_headerItemShownHeight -= diff;
573− m_headerItemShownHeight += diff;
575− if (uFuzzyCompare(contentY(), -m_minYExtent)) {
576− m_headerItemShownHeight = 0;
578− m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, m_headerItem->height());
580− if (m_headerItemShownHeight > 0) {
581− if (uFuzzyCompare(m_headerItem->height(), m_headerItemShownHeight)) {
582− m_headerItem->setY(contentY());
583− m_headerItemShownHeight = m_headerItem->height();
585− m_headerItem->setY(contentY() - m_headerItem->height() + m_headerItemShownHeight);
588− m_headerItem->setY(-m_minYExtent);
591− Q_EMIT headerItemShownHeightChanged();
593− // Stick the header item to the top when dragging down
594− m_headerItem->setY(contentY());
595− m_headerItem->setHeight(m_headerItem->implicitHeight() + (-m_minYExtent - contentY()));
597− // We will be changing the clip item, need to accomadate for it
598− // otherwise we move the firstItem down/up twice (unless the
599− // show header animation is running, where we want to keep the viewport stable)
600− if (!showHeaderAnimationRunning) {
601− diff += oldHeaderItemShownHeight - m_headerItemShownHeight;
606− if (!m_visibleItems.isEmpty()) {
608− ListItem *firstItem = m_visibleItems.first();
609− firstItem->setY(firstItem->y() + diff);
610− if (showHeaderAnimationRunning) {
616−void ListViewWithPageHeader::createDelegateModel()
618− m_delegateModel = new QQmlDelegateModel(qmlContext(this), this);
619− connect(m_delegateModel, &QQmlDelegateModel::createdItem, this, &ListViewWithPageHeader::itemCreated);
620− if (isComponentComplete())
621− m_delegateModel->componentComplete();
622− updateWatchedRoles();
625−void ListViewWithPageHeader::refill()
630− if (!isComponentComplete()) {
634− const qreal from = contentY();
635− const qreal to = from + height();
636− const qreal bufferFrom = from - m_cacheBuffer;
637− const qreal bufferTo = to + m_cacheBuffer;
639− bool added = addVisibleItems(from, to, false);
640− bool removed = removeNonVisibleItems(bufferFrom, bufferTo);
641− added |= addVisibleItems(bufferFrom, bufferTo, true);
643− if (added || removed) {
644− m_contentHeightDirty = true;
648−bool ListViewWithPageHeader::addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous)
653− if (m_delegateModel->count() == 0)
657−// qDebug() << "ListViewWithPageHeader::addVisibleItems" << fillFrom << fillTo << asynchronous;
661− if (!m_visibleItems.isEmpty()) {
662− modelIndex = m_firstVisibleIndex + m_visibleItems.count();
663− item = m_visibleItems.last();
664− pos = item->y() + item->height() + m_clipItem->y();
666− bool changed = false;
667−// qDebug() << (modelIndex < m_delegateModel->count()) << pos << fillTo;
668− while (modelIndex < m_delegateModel->count() && pos <= fillTo) {
669−// qDebug() << "refill: append item" << modelIndex << "pos" << pos << "asynchronous" << asynchronous;
670− if (!(item = createItem(modelIndex, asynchronous)))
672− pos += item->height();
679− if (!m_visibleItems.isEmpty()) {
680− modelIndex = m_firstVisibleIndex - 1;
681− item = m_visibleItems.first();
682− pos = item->y() + m_clipItem->y();
684− while (modelIndex >= 0 && pos > fillFrom) {
685−// qDebug() << "refill: prepend item" << modelIndex << "pos" << pos << "fillFrom" << fillFrom << "asynchronous" << asynchronous;
686− if (!(item = createItem(modelIndex, asynchronous)))
688− pos -= item->height();
696−void ListViewWithPageHeader::reallyReleaseItem(ListItem *listItem)
698− QQuickItem *item = listItem->m_item;
699− QQmlDelegateModel::ReleaseFlags flags = m_delegateModel->release(item);
700− if (flags & QQmlDelegateModel::Destroyed) {
701− item->setParentItem(nullptr);
703− listItem->sectionItem()->deleteLater();
707−void ListViewWithPageHeader::releaseItem(ListItem *listItem)
709− QQuickItemPrivate::get(listItem->m_item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
710− if (listItem->sectionItem()) {
711− QQuickItemPrivate::get(listItem->sectionItem())->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
713− m_itemsToRelease << listItem;
716−void ListViewWithPageHeader::updateWatchedRoles()
718− if (m_delegateModel) {
719− QList<QByteArray> roles;
720− if (!m_sectionProperty.isEmpty())
721− roles << m_sectionProperty.toUtf8();
722− m_delegateModel->setWatchedRoles(roles);
726−QQuickItem *ListViewWithPageHeader::getSectionItem(int modelIndex, bool alreadyInserted)
728− if (!m_sectionDelegate)
731− const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
733− if (modelIndex > 0) {
734− const QString prevSection = m_delegateModel->stringValue(modelIndex - 1, m_sectionProperty);
735− if (section == prevSection)
738− if (modelIndex + 1 < model()->rowCount() && !alreadyInserted) {
739− // Already inserted items can't steal next section header
740− const QString nextSection = m_delegateModel->stringValue(modelIndex + 1, m_sectionProperty);
741− if (section == nextSection) {
742− // Steal the section header
743− ListItem *nextItem = itemAtIndex(modelIndex); // Not +1 since not yet inserted into m_visibleItems
745− QQuickItem *sectionItem = nextItem->sectionItem();
746− nextItem->setSectionItem(nullptr);
752− return getSectionItem(section);
755−QQuickItem *ListViewWithPageHeader::getSectionItem(const QString §ionText, bool watchGeometry)
757− QQuickItem *sectionItem = nullptr;
759− QQmlContext *creationContext = m_sectionDelegate->creationContext();
760− QQmlContext *context = new QQmlContext(creationContext ? creationContext : qmlContext(this));
761− QObject *nobj = m_sectionDelegate->beginCreate(context);
763− QQml_setParent_noEvent(context, nobj);
764− sectionItem = qobject_cast<QQuickItem *>(nobj);
768− sectionItem->setProperty("text", sectionText);
769− sectionItem->setProperty("delegateIndex", -1);
770− sectionItem->setZ(2);
771− QQml_setParent_noEvent(sectionItem, m_clipItem);
772− sectionItem->setParentItem(m_clipItem);
777− m_sectionDelegate->completeCreate();
779− if (watchGeometry) {
780− QQuickItemPrivate::get(sectionItem)->addItemChangeListener(this, QQuickItemPrivate::Geometry);
786−void ListViewWithPageHeader::updateSectionItem(int modelIndex)
788− ListItem *item = itemAtIndex(modelIndex);
790− const QString sectionText = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
792− bool needSectionHeader = true;
793− // if it is the same section as the previous item need to drop the section
794− if (modelIndex > 0) {
795− const QString prevSection = m_delegateModel->stringValue(modelIndex - 1, m_sectionProperty);
796− if (sectionText == prevSection) {
797− needSectionHeader = false;
801− if (needSectionHeader) {
802− if (!item->sectionItem()) {
803− item->setSectionItem(getSectionItem(sectionText));
805− item->sectionItem()->setProperty("text", sectionText);
808− if (item->sectionItem()) {
809− item->sectionItem()->deleteLater();
810− item->setSectionItem(nullptr);
816−bool ListViewWithPageHeader::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
818−// qDebug() << "ListViewWithPageHeader::removeNonVisibleItems" << bufferFrom << bufferTo;
819− // Do not remove items if we are overshooting up or down, since we'll come back
820− // to the "stable" position and delete/create items without any reason
821− if (contentY() < -m_minYExtent) {
823− } else if (contentY() + height() > contentHeight()) {
826− bool changed = false;
828− bool foundVisible = false;
830− int removedItems = 0;
831− const auto oldFirstVisibleIndex = m_firstVisibleIndex;
832− while (i < m_visibleItems.count()) {
833− ListItem *item = m_visibleItems[i];
834− const qreal pos = item->y() + m_clipItem->y();
835−// qDebug() << i << pos << (pos + item->height()) << bufferFrom << bufferTo;
836− if (pos + item->height() < bufferFrom || pos > bufferTo) {
837−// qDebug() << "Releasing" << i << (pos + item->height() < bufferFrom) << pos + item->height() << bufferFrom << (pos > bufferTo) << pos << bufferTo;
839− m_visibleItems.removeAt(i);
843− if (!foundVisible) {
844− foundVisible = true;
845− const int itemIndex = m_firstVisibleIndex + removedItems + i;
846− m_firstVisibleIndex = itemIndex;
851− if (!foundVisible) {
852− initializeValuesForEmptyList();
854− if (m_firstVisibleIndex != oldFirstVisibleIndex) {
861−ListViewWithPageHeader::ListItem *ListViewWithPageHeader::createItem(int modelIndex, bool asynchronous)
863−// qDebug() << "CREATE ITEM" << modelIndex;
864− if (asynchronous && m_asyncRequestedIndex != -1)
867− m_asyncRequestedIndex = -1;
868− QObject* object = m_delegateModel->object(modelIndex, asynchronous);
869− QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
872− m_delegateModel->release(object);
873− if (!m_delegateValidated) {
874− m_delegateValidated = true;
875− QObject* delegateObj = delegate();
876− qmlInfo(delegateObj ? delegateObj : this) << "Delegate must be of Item type";
879− m_asyncRequestedIndex = modelIndex;
883−// qDebug() << "ListViewWithPageHeader::createItem::We have the item" << modelIndex << item;
884− ListItem *listItem = new ListItem;
885− listItem->m_item = item;
886− listItem->setSectionItem(getSectionItem(modelIndex, false /*Not yet inserted into m_visibleItems*/));
887− QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry);
888− ListItem *prevItem = itemAtIndex(modelIndex - 1);
889− bool lostItem = false; // Is an item that we requested async but because of model changes
890− // it is no longer attached to any of the existing items (has no prev nor next item)
891− // nor is the first item
893− listItem->setY(prevItem->y() + prevItem->height());
895− ListItem *currItem = itemAtIndex(modelIndex);
897− // There's something already in m_visibleItems at out index, meaning this is an insert, so attach to its top
898− listItem->setY(currItem->y() - listItem->height());
900− ListItem *nextItem = itemAtIndex(modelIndex + 1);
902− listItem->setY(nextItem->y() - listItem->height());
903− } else if (modelIndex == 0) {
904− listItem->setY(-m_clipItem->y() + (m_headerItem ? m_headerItem->height() : 0));
905− } else if (!m_visibleItems.isEmpty()) {
911− listItem->setCulled(true);
912− releaseItem(listItem);
915− listItem->setCulled(listItem->y() + listItem->height() + m_clipItem->y() <= contentY() || listItem->y() + m_clipItem->y() >= contentY() + height());
916− if (m_visibleItems.isEmpty()) {
917− m_visibleItems << listItem;
919− m_visibleItems.insert(modelIndex - m_firstVisibleIndex, listItem);
921− if (m_firstVisibleIndex < 0 || modelIndex < m_firstVisibleIndex) {
922− m_firstVisibleIndex = modelIndex;
925− if (listItem->sectionItem()) {
926− listItem->sectionItem()->setProperty("delegateIndex", modelIndex);
929− m_contentHeightDirty = true;
935−void ListViewWithPageHeader::itemCreated(int modelIndex, QObject *object)
937− QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
939− qWarning() << "ListViewWithPageHeader::itemCreated got a non item for index" << modelIndex;
942−// qDebug() << "ListViewWithPageHeader::itemCreated" << modelIndex << item;
943− // Check we are not being taken down and don't paint anything
944− // TODO Check if we still need this in 5.2
945− // For reproduction just inifnite loop testDash or testDashContent
946− if (!QQmlEngine::contextForObject(this)->parentContext())
949− item->setParentItem(m_clipItem);
950− // FIXME Why do we need the refreshExpressions call?
951− QQmlContext *context = QQmlEngine::contextForObject(item)->parentContext();
952− QQmlContextPrivate::get(context)->data->refreshExpressions();
953− item->setProperty("heightToClip", QVariant::fromValue<int>(0));
954− if (modelIndex == m_asyncRequestedIndex) {
955− createItem(modelIndex, false);
960−void ListViewWithPageHeader::updateClipItem()
962− m_clipItem->setHeight(height() - m_headerItemShownHeight);
963− m_clipItem->setY(contentY() + m_headerItemShownHeight);
964− m_clipItem->setClip(!m_forceNoClip && m_headerItemShownHeight > 0);
967−void ListViewWithPageHeader::onContentHeightChanged()
972−void ListViewWithPageHeader::onContentWidthChanged()
974− m_clipItem->setWidth(contentItem()->width());
977−void ListViewWithPageHeader::onHeightChanged()
983−void ListViewWithPageHeader::onModelUpdated(const QQmlChangeSet &changeSet, bool /*reset*/)
985− // TODO Do something with reset
986−// qDebug() << "ListViewWithPageHeader::onModelUpdated" << changeSet << reset;
987− const auto oldFirstVisibleIndex = m_firstVisibleIndex;
989− Q_FOREACH(const QQmlChangeSet::Change remove, changeSet.removes()) {
990−// qDebug() << "ListViewWithPageHeader::onModelUpdated Remove" << remove.index << remove.count;
991− if (remove.index + remove.count > m_firstVisibleIndex && remove.index < m_firstVisibleIndex + m_visibleItems.count()) {
992− const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
993− // If all the items we are removing are either not created or culled
994− // we have to grow down to avoid viewport changing
995− bool growDown = true;
996− for (int i = 0; growDown && i < remove.count; ++i) {
997− const int modelIndex = remove.index + i;
998− ListItem *item = itemAtIndex(modelIndex);
999− if (item && !item->culled()) {
1003− for (int i = remove.count - 1; i >= 0; --i) {
1004− const int visibleIndex = remove.index + i - m_firstVisibleIndex;
1005− if (visibleIndex >= 0 && visibleIndex < m_visibleItems.count()) {
1006− ListItem *item = m_visibleItems[visibleIndex];
1007− // Pass the section item down if needed
1008− if (item->sectionItem() && visibleIndex + 1 < m_visibleItems.count()) {
1009− ListItem *nextItem = m_visibleItems[visibleIndex + 1];
1010− if (!nextItem->sectionItem()) {
1011− nextItem->setSectionItem(item->sectionItem());
1012− item->setSectionItem(nullptr);
1016− m_visibleItems.removeAt(visibleIndex);
1020− adjustMinYExtent();
1021− } else if (remove.index <= m_firstVisibleIndex && !m_visibleItems.isEmpty()) {
1022− m_visibleItems.first()->setY(oldFirstValidIndexPos);
1024− if (m_visibleItems.isEmpty()) {
1025− m_firstVisibleIndex = -1;
1027− m_firstVisibleIndex -= qMax(0, m_firstVisibleIndex - remove.index);
1029− } else if (remove.index + remove.count <= m_firstVisibleIndex) {
1030− m_firstVisibleIndex -= remove.count;
1032− for (int i = remove.count - 1; i >= 0; --i) {
1033− const int modelIndex = remove.index + i;
1034− if (modelIndex == m_asyncRequestedIndex) {
1035− m_asyncRequestedIndex = -1;
1036− } else if (modelIndex < m_asyncRequestedIndex) {
1037− m_asyncRequestedIndex--;
1042− Q_FOREACH(const QQmlChangeSet::Change insert, changeSet.inserts()) {
1043−// qDebug() << "ListViewWithPageHeader::onModelUpdated Insert" << insert.index << insert.count;
1044− const bool insertingInValidIndexes = insert.index > m_firstVisibleIndex && insert.index < m_firstVisibleIndex + m_visibleItems.count();
1045− const bool firstItemWithViewOnTop = insert.index == 0 && m_firstVisibleIndex == 0 && m_visibleItems.first()->y() + m_clipItem->y() > contentY();
1046− if (insertingInValidIndexes || firstItemWithViewOnTop)
1048− // If the items we are adding won't be really visible
1049− // we grow up instead of down to not change the viewport
1050− bool growUp = false;
1051− if (!firstItemWithViewOnTop) {
1052− for (int i = 0; i < m_visibleItems.count(); ++i) {
1053− if (!m_visibleItems[i]->culled()) {
1054− if (insert.index <= m_firstVisibleIndex + i) {
1062− const qreal oldFirstValidIndexPos = m_visibleItems.first()->y();
1063− for (int i = insert.count - 1; i >= 0; --i) {
1064− const int modelIndex = insert.index + i;
1065− ListItem *item = createItem(modelIndex, false);
1067− ListItem *firstItem = m_visibleItems.first();
1068− firstItem->setY(firstItem->y() - item->height());
1070− // Adding an item may break a "same section" chain, so check
1071− // if we need adding a new section item
1072− if (m_sectionDelegate) {
1073− ListItem *nextItem = itemAtIndex(modelIndex + 1);
1074− if (nextItem && !nextItem->sectionItem()) {
1075− nextItem->setSectionItem(getSectionItem(modelIndex + 1, true /* alredy inserted into m_visibleItems*/));
1076− if (growUp && nextItem->sectionItem()) {
1077− ListItem *firstItem = m_visibleItems.first();
1078− firstItem->setY(firstItem->y() - nextItem->sectionItem()->height());
1083− if (firstItemWithViewOnTop) {
1084− ListItem *firstItem = m_visibleItems.first();
1085− firstItem->setY(oldFirstValidIndexPos);
1087− adjustMinYExtent();
1088− } else if (insert.index <= m_firstVisibleIndex) {
1089− m_firstVisibleIndex += insert.count;
1092− for (int i = insert.count - 1; i >= 0; --i) {
1093− const int modelIndex = insert.index + i;
1094− if (modelIndex <= m_asyncRequestedIndex) {
1095− m_asyncRequestedIndex++;
1100− Q_FOREACH(const QQmlChangeSet::Change change, changeSet.changes()) {
1101− for (int i = change.start(); i < change.end(); ++i) {
1102− updateSectionItem(i);
1104− // Also update the section header for the next item after the change since it may be influenced
1105− updateSectionItem(change.end());
1108− if (m_firstVisibleIndex != oldFirstVisibleIndex) {
1109− if (m_visibleItems.isEmpty()) {
1110− initializeValuesForEmptyList();
1112− adjustMinYExtent();
1116− for (int i = 0; i < m_visibleItems.count(); ++i) {
1117− ListItem *item = m_visibleItems[i];
1118− if (item->sectionItem()) {
1119− item->sectionItem()->setProperty("delegateIndex", m_firstVisibleIndex + i);
1125− m_contentHeightDirty = true;
1128−void ListViewWithPageHeader::contentYAnimationRunningChanged(bool running)
1130− setInteractive(!running);
1132− m_contentHeightDirty = true;
1137−void ListViewWithPageHeader::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
1139− const qreal heightDiff = newGeometry.height() - oldGeometry.height();
1140− if (heightDiff != 0) {
1141− if (!m_visibleItems.isEmpty()) {
1142− ListItem *firstItem = m_visibleItems.first();
1143− const auto prevFirstItemY = firstItem->y();
1144− if (!m_inContentHeightKeepHeaderShown && oldGeometry.y() + oldGeometry.height() + m_clipItem->y() <= contentY()) {
1145− firstItem->setY(firstItem->y() - heightDiff);
1146− } else if (item == firstItem->sectionItem()) {
1147− firstItem->setY(firstItem->y() + heightDiff);
1150− if (firstItem->y() != prevFirstItemY) {
1151− adjustMinYExtent();
1156− adjustMinYExtent();
1158− m_contentHeightDirty = true;
1162−void ListViewWithPageHeader::itemImplicitHeightChanged(QQuickItem *item)
1164− if (item == m_headerItem) {
1165− const qreal diff = m_headerItem->implicitHeight() - m_previousHeaderImplicitHeight;
1167− adjustHeader(diff);
1168− m_previousHeaderImplicitHeight = m_headerItem->implicitHeight();
1171− m_contentHeightDirty = true;
1176−void ListViewWithPageHeader::headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY)
1178− const qreal heightDiff = newHeaderHeight - oldHeaderHeight;
1179− if (m_headerItemShownHeight > 0) {
1180− // If the header is shown because of the clip
1182− m_headerItemShownHeight += heightDiff;
1183− m_headerItemShownHeight = qBound(static_cast<qreal>(0.), m_headerItemShownHeight, newHeaderHeight);
1185− adjustMinYExtent();
1186− Q_EMIT headerItemShownHeightChanged();
1188− if (oldHeaderY + oldHeaderHeight > contentY()) {
1189− // If the header is shown because its position
1191− ListItem *firstItem = m_visibleItems.first();
1192− firstItem->setY(firstItem->y() + heightDiff);
1195− // If the header is not on screen, just change the start of the list
1196− // so the viewport is not changed
1197− adjustMinYExtent();
1203−void ListViewWithPageHeader::adjustMinYExtent()
1205− if (m_visibleItems.isEmpty() || (contentHeight() + m_minYExtent < height())) {
1208− qreal nonCreatedHeight = 0;
1209− if (m_firstVisibleIndex != 0) {
1210− // Calculate the average height of items to estimate the position of the list start
1211− const int visibleItems = m_visibleItems.count();
1212− qreal visibleItemsHeight = 0;
1213− Q_FOREACH(ListItem *item, m_visibleItems) {
1214− visibleItemsHeight += item->height();
1216− nonCreatedHeight = m_firstVisibleIndex * visibleItemsHeight / visibleItems;
1217−// qDebug() << m_firstVisibleIndex << visibleItemsHeight << visibleItems << nonCreatedHeight;
1219− const qreal headerHeight = (m_headerItem ? m_headerItem->implicitHeight() : 0);
1220− m_minYExtent = nonCreatedHeight - m_visibleItems.first()->y() - m_clipItem->y() + headerHeight;
1221− if (m_minYExtent != 0 && qFuzzyIsNull(m_minYExtent)) {
1223− m_visibleItems.first()->setY(nonCreatedHeight - m_clipItem->y() + headerHeight);
1228−ListViewWithPageHeader::ListItem *ListViewWithPageHeader::itemAtIndex(int modelIndex) const
1230− const int visibleIndexedModelIndex = modelIndex - m_firstVisibleIndex;
1231− if (visibleIndexedModelIndex >= 0 && visibleIndexedModelIndex < m_visibleItems.count())
1232− return m_visibleItems[visibleIndexedModelIndex];
1237−void ListViewWithPageHeader::layout()
1243− if (!m_visibleItems.isEmpty()) {
1244− const qreal visibleFrom = contentY() - m_clipItem->y() + m_headerItemShownHeight;
1245− const qreal visibleTo = contentY() + height() - m_clipItem->y();
1247− qreal pos = m_visibleItems.first()->y();
1249−// qDebug() << "ListViewWithPageHeader::layout Updating positions and heights. contentY" << contentY() << "minYExtent" << minYExtent();
1250− int firstReallyVisibleItem = -1;
1251− int modelIndex = m_firstVisibleIndex;
1252− Q_FOREACH(ListItem *item, m_visibleItems) {
1253− const bool cull = pos + item->height() <= visibleFrom || pos >= visibleTo;
1254− item->setCulled(cull);
1256− if (!cull && firstReallyVisibleItem == -1) {
1257− firstReallyVisibleItem = modelIndex;
1258− if (m_topSectionItem) {
1259− // Positing the top section sticky item is a two step process
1260− // First we set it either we cull it (because it doesn't need to be sticked to the top)
1261− // or stick it to the top
1262− // Then after the loop we'll make sure that if there's another section just below it
1263− // pushed the sticky section up to make it disappear
1264− const qreal topSectionStickPos = m_headerItemShownHeight + contentY() - m_clipItem->y();
1265− bool showStickySectionItem;
1266− // We need to show the "top section sticky item" when the position at the "top" of the
1267− // viewport is bigger than the start of the position of the first visible item
1268− // i.e. the first visible item starts before the viewport, or when the first
1269− // visible item starts just at the viewport start and it does not have its own section item
1270− if (topSectionStickPos > pos) {
1271− showStickySectionItem = true;
1272− } else if (topSectionStickPos == pos) {
1273− showStickySectionItem = !item->sectionItem();
1275− showStickySectionItem = false;
1277− if (!showStickySectionItem) {
1278− QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
1279− if (item->sectionItem()) {
1280− // This seems it should happen since why would we cull the top section
1281− // if the first visible item has no section header? This only happens briefly
1282− // when increasing the height of a list that is at the bottom, the m_topSectionItem
1283− // gets shown shortly in the next polish call
1284− QQuickItemPrivate::get(item->sectionItem())->setCulled(false);
1287− // Update the top sticky section header
1288− const QString section = m_delegateModel->stringValue(modelIndex, m_sectionProperty);
1289− m_topSectionItem->setProperty("text", section);
1291− QQuickItemPrivate::get(m_topSectionItem)->setCulled(false);
1292− m_topSectionItem->setY(topSectionStickPos);
1293− int delegateIndex = modelIndex;
1294− // Look for the first index with this section text
1295− while (delegateIndex > 0) {
1296− const QString prevSection = m_delegateModel->stringValue(delegateIndex - 1, m_sectionProperty);
1297− if (prevSection != section)
1301− m_topSectionItem->setProperty("delegateIndex", delegateIndex);
1302− if (item->sectionItem()) {
1303− QQuickItemPrivate::get(item->sectionItem())->setCulled(true);
1308− const qreal clipFrom = visibleFrom + (!item->sectionItem() && m_topSectionItem && !QQuickItemPrivate::get(m_topSectionItem)->culled ? m_topSectionItem->height() : 0);
1309− if (!cull && pos < clipFrom) {
1310− item->m_item->setProperty("heightToClip", clipFrom - pos);
1312− item->m_item->setProperty("heightToClip", QVariant::fromValue<int>(0));
1314−// qDebug() << "ListViewWithPageHeader::layout" << item->m_item;
1315− pos += item->height();
1319− // Second step of section sticky item positioning
1320− // Look at the next section header, check if it's pushing up the sticky one
1321− if (m_topSectionItem) {
1322− if (firstReallyVisibleItem >= 0) {
1323− for (int i = firstReallyVisibleItem - m_firstVisibleIndex + 1; i < m_visibleItems.count(); ++i) {
1324− ListItem *item = m_visibleItems[i];
1325− if (item->sectionItem()) {
1326− if (m_topSectionItem->y() + m_topSectionItem->height() > item->y()) {
1327− m_topSectionItem->setY(item->y() - m_topSectionItem->height());
1335− m_inLayout = false;
1338−void ListViewWithPageHeader::updatePolish()
1340− // Check we are not being taken down and don't paint anything
1341− // TODO Check if we still need this in 5.2
1342− // For reproduction just inifnite loop testDash or testDashContent
1343− if (!QQmlEngine::contextForObject(this)->parentContext())
1346− Q_FOREACH(ListItem *item, m_itemsToRelease)
1347− reallyReleaseItem(item);
1348− m_itemsToRelease.clear();
1357− if (m_contentHeightDirty) {
1358− qreal contentHeight;
1359− if (m_visibleItems.isEmpty()) {
1360− contentHeight = m_headerItem ? m_headerItem->height() : 0;
1362− const int modelCount = model()->rowCount();
1363− const int visibleItems = m_visibleItems.count();
1364− const int lastValidIndex = m_firstVisibleIndex + visibleItems - 1;
1365− qreal nonCreatedHeight = 0;
1366− if (lastValidIndex != modelCount - 1) {
1367− const int visibleItems = m_visibleItems.count();
1368− qreal visibleItemsHeight = 0;
1369− Q_FOREACH(ListItem *item, m_visibleItems) {
1370− visibleItemsHeight += item->height();
1372− const int unknownSizes = modelCount - (m_firstVisibleIndex + visibleItems);
1373− nonCreatedHeight = unknownSizes * visibleItemsHeight / visibleItems;
1375− ListItem *item = m_visibleItems.last();
1376− contentHeight = nonCreatedHeight + item->y() + item->height() + m_clipItem->y();
1377− if (m_firstVisibleIndex != 0) {
1378− // Make sure that if we are shrinking we tell the view we still fit
1379− m_minYExtent = qMax(m_minYExtent, -(contentHeight - height()));
1383− m_contentHeightDirty = false;
1384− adjustMinYExtent();
1385− if (contentHeight + m_minYExtent < height()) {
1386− // need this since in the previous call to adjustMinYExtent contentHeight is not set yet
1389− m_inContentHeightKeepHeaderShown = m_headerItem && m_headerItem->y() == contentY();
1390− setContentHeight(contentHeight);
1391− m_inContentHeightKeepHeaderShown = false;
1395−#include "moc_listviewwithpageheader.cpp"
plugins/Dash/listviewwithpageheader.hdeleted−218
@@ -1,218 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
17−#ifndef LISTVIEWWITHPAGEHEADER_H
18−#define LISTVIEWWITHPAGEHEADER_H
20−#include <private/qquickitemchangelistener_p.h>
21−#include <private/qquickflickable_p.h>
23−class QAbstractItemModel;
24−class QQuickNumberAnimation;
26−class QQmlDelegateModel;
30− Note for users of this class
32− ListViewWithPageHeader already loads delegates async when appropiate so if
33− your delegate uses a Loader you should not enable the asynchronous feature since
34− that will need to introduce sizing problems
36− With the double async it may happen what while we are scrolling down
37− we reach to a point where given the size of the just created delegate with loader not yet loaded (which will be very close to 0)
38− we are already "at the end" of the list, but then a few milliseconds later the loader finishes loading and we could
39− have kept scrolling. This is specially visible at the end of the list where you realize
40− that scrolling ended a bit before the end of the list but the speed of the flicking was good
43− By not having the second async we get a better sizing when the delegate is created and things work better
46−class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeListener
49− Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged)
50− Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
51− Q_PROPERTY(QQuickItem *pageHeader READ header WRITE setHeader NOTIFY headerChanged)
52− Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
53− Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
54− Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
55− Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
56− Q_PROPERTY(qreal headerItemShownHeight READ headerItemShownHeight NOTIFY headerItemShownHeightChanged)
57− Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
59− friend class ListViewWithPageHeaderTest;
60− friend class ListViewWithPageHeaderTestSection;
61− friend class ListViewWithPageHeaderTestExternalModel;
64− ListViewWithPageHeader();
65− ~ListViewWithPageHeader();
67− QAbstractItemModel *model() const;
68− void setModel(QAbstractItemModel *model);
70− QQmlComponent *delegate() const;
71− void setDelegate(QQmlComponent *delegate);
73− QQuickItem *header() const;
74− void setHeader(QQuickItem *header);
76− QQmlComponent *sectionDelegate() const;
77− void setSectionDelegate(QQmlComponent *delegate);
79− QString sectionProperty() const;
80− void setSectionProperty(const QString &property);
82− bool forceNoClip() const;
83− void setForceNoClip(bool noClip);
85− int stickyHeaderHeight() const;
86− qreal headerItemShownHeight() const;
88− int cacheBuffer() const;
89− void setCacheBuffer(int cacheBuffer);
91− Q_INVOKABLE void positionAtBeginning();
92− Q_INVOKABLE void showHeader();
93− Q_INVOKABLE int firstCreatedIndex() const;
94− Q_INVOKABLE int createdItemCount() const;
95− Q_INVOKABLE QQuickItem *item(int modelIndex) const;
97− // The index has to be created for this to try to do something
98− // Created items are those visible and the precached ones
99− // Returns if the item existed or not
100− Q_INVOKABLE bool maximizeVisibleArea(int modelIndex);
101− Q_INVOKABLE bool maximizeVisibleArea(int modelIndex, int itemHeight);
104− void modelChanged();
105− void delegateChanged();
106− void headerChanged();
107− void sectionDelegateChanged();
108− void sectionPropertyChanged();
109− void forceNoClipChanged();
110− void stickyHeaderHeightChanged();
111− void headerItemShownHeightChanged();
112− void cacheBufferChanged();
115− void componentComplete() override;
116− void viewportMoved(Qt::Orientations orient) override;
117− qreal minYExtent() const override;
118− qreal maxYExtent() const override;
119− void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) override;
120− void itemImplicitHeightChanged(QQuickItem *item) override;
121− void updatePolish() override;
124− void itemCreated(int modelIndex, QObject *object);
125− void onContentHeightChanged();
126− void onContentWidthChanged();
127− void onHeightChanged();
128− void onModelUpdated(const QQmlChangeSet &changeSet, bool reset);
129− void contentYAnimationRunningChanged(bool running);
135− qreal height() const;
138− void setY(qreal newY);
140− bool culled() const;
141− void setCulled(bool culled);
143− QQuickItem *sectionItem() const { return m_sectionItem; }
144− void setSectionItem(QQuickItem *sectionItem);
148− QQuickItem *m_sectionItem;
151− bool maximizeVisibleArea(ListItem *listItem, int listItemHeight);
153− void createDelegateModel();
157− bool addVisibleItems(qreal fillFrom, qreal fillTo, bool asynchronous);
158− bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
159− ListItem *createItem(int modelIndex, bool asynchronous);
161− void adjustHeader(qreal diff);
162− void adjustMinYExtent();
163− void updateClipItem();
164− void headerHeightChanged(qreal newHeaderHeight, qreal oldHeaderHeight, qreal oldHeaderY);
165− ListItem *itemAtIndex(int modelIndex) const; // Returns the item at modelIndex if has been created
166− void releaseItem(ListItem *item);
167− void reallyReleaseItem(ListItem *item);
168− void updateWatchedRoles();
169− QQuickItem *getSectionItem(int modelIndex, bool alreadyInserted);
170− QQuickItem *getSectionItem(const QString §ionText, bool watchGeometry = true);
171− void updateSectionItem(int modelIndex);
172− void initializeValuesForEmptyList();
174− QQmlDelegateModel *m_delegateModel;
176− // Index we are waiting because we requested it asynchronously
177− int m_asyncRequestedIndex;
179− // Used to only give a warning once if the delegate does not return objects
180− bool m_delegateValidated;
182− // Visible indexes, [0] is m_firstValidIndex, [0+1] is m_firstValidIndex +1, ...
183− QList<ListItem *> m_visibleItems;
184− int m_firstVisibleIndex;
188− QQuickItem *m_clipItem;
190− // If any of the heights has changed
191− // or new items have been added/removed
192− bool m_contentHeightDirty;
194− QQuickItem *m_headerItem;
195− qreal m_previousContentY;
196− qreal m_previousHeaderImplicitHeight;
197− qreal m_headerItemShownHeight; // The height of header shown when the header is shown outside its topmost position
198− // i.e. it's being shown after dragging down in the middle of the list
199− enum ContentYAnimationType { ContentYAnimationShowHeader, ContentYAnimationMaximizeVisibleArea };
200− ContentYAnimationType contentYAnimationType;
201− QQuickNumberAnimation *m_contentYAnimation;
203− QQmlComponent *m_sectionDelegate;
204− QString m_sectionProperty;
205− QQuickItem *m_topSectionItem;
209− bool m_inContentHeightKeepHeaderShown;
212− // Qt 5.0 doesn't like releasing the items just after itemCreated
213− // so we delay the releasing until the next updatePolish
214− QList<ListItem *> m_itemsToRelease;
plugins/Dash/organicgrid.cppdeleted−260
@@ -1,260 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
17−#include "organicgrid.h"
19−#pragma GCC diagnostic push
20−#pragma GCC diagnostic ignored "-pedantic"
21−#include <private/qquickitem_p.h>
22−#pragma GCC diagnostic pop
24−OrganicGrid::OrganicGrid()
25− : m_firstVisibleIndex(-1)
26− , m_numberOfModulesPerRow(-1)
30−QSizeF OrganicGrid::smallDelegateSize() const
32− return m_smallDelegateSize;
35−void OrganicGrid::setSmallDelegateSize(const QSizeF size)
37− if (m_smallDelegateSize != size) {
38− m_smallDelegateSize = size;
39− Q_EMIT smallDelegateSizeChanged();
41− if (isComponentComplete()) {
47−QSizeF OrganicGrid::bigDelegateSize() const
49− return m_bigDelegateSize;
52−void OrganicGrid::setBigDelegateSize(const QSizeF size)
54− if (m_bigDelegateSize != size) {
55− m_bigDelegateSize = size;
56− Q_EMIT bigDelegateSizeChanged();
58− if (isComponentComplete()) {
64−QPointF OrganicGrid::positionForIndex(int modelIndex) const
66− const qreal moduleHeight = m_smallDelegateSize.height() + rowSpacing() + m_bigDelegateSize.height();
67− const qreal moduleWidth = m_smallDelegateSize.width() * 2 + columnSpacing() * 2 + m_bigDelegateSize.width();
68− const int itemsPerRow = m_numberOfModulesPerRow * 6;
69− const int rowIndex = floor(modelIndex / itemsPerRow);
70− const int columnIndex = floor((modelIndex - rowIndex * itemsPerRow) / 6);
72− qreal yPos = (moduleHeight + rowSpacing()) * rowIndex;
73− const int moduleIndex = modelIndex % 6;
74− if (moduleIndex == 2) {
75− yPos += m_smallDelegateSize.height() + rowSpacing();
76− } else if (moduleIndex == 3 || moduleIndex == 5) {
77− yPos += m_bigDelegateSize.height() + rowSpacing();
80− qreal xPos = (moduleWidth + columnSpacing()) * columnIndex;
81− if (moduleIndex == 1) {
82− xPos += m_smallDelegateSize.width() + columnSpacing();
83− } else if (moduleIndex == 3) {
84− xPos += m_bigDelegateSize.width() + columnSpacing();
85− } else if (moduleIndex == 4) {
86− xPos += (m_smallDelegateSize.width() + columnSpacing()) * 2;
87− } else if (moduleIndex == 5) {
88− xPos += m_bigDelegateSize.width() + m_smallDelegateSize.width() + columnSpacing() * 2;
91− return QPointF(xPos, yPos);
94−QSizeF OrganicGrid::sizeForIndex(int modelIndex) const
96− const int moduleIndex = modelIndex % 6;
97− if (moduleIndex == 0 || moduleIndex == 1 || moduleIndex == 3 || moduleIndex == 5) {
98− return m_smallDelegateSize;
100− return m_bigDelegateSize;
104−void OrganicGrid::findBottomModelIndexToAdd(int *modelIndex, qreal *yPos)
106− if (m_visibleItems.isEmpty()) {
110− *modelIndex = m_firstVisibleIndex + m_visibleItems.count();
111− // We create stuff in a 6-module basis, so always return back
112− // the y position of the first item
113− const int firstModuleIndex = ((*modelIndex) / 6) * 6;
114− *yPos = positionForIndex(firstModuleIndex).y();
118−void OrganicGrid::findTopModelIndexToAdd(int *modelIndex, qreal *yPos)
120− if (m_visibleItems.isEmpty()) {
124− *modelIndex = m_firstVisibleIndex - 1;
125− // We create stuff in a 6-module basis, so always return back
126− // the y position of the last item bottom
127− const int lastModuleIndex = ((*modelIndex) / 6) * 6 + 5;
128− *yPos = positionForIndex(lastModuleIndex).y();
129− *yPos += sizeForIndex(lastModuleIndex).height();
133−void OrganicGrid::addItemToView(int modelIndex, QQuickItem *item)
135− // modelIndex has to be either m_firstVisibleIndex - 1 or m_firstVisibleIndex + m_visibleItems.count() or the first
136− if (modelIndex == m_firstVisibleIndex + m_visibleItems.count()) {
137− m_visibleItems << item;
138− } else if (modelIndex == m_firstVisibleIndex - 1) {
139− m_firstVisibleIndex = modelIndex;
140− m_visibleItems.prepend(item);
141− } else if (modelIndex == 0) {
142− m_firstVisibleIndex = 0;
143− m_visibleItems << item;
145− qWarning() << "OrganicGrid::addItemToView - Got unexpected modelIndex"
146− << modelIndex << m_firstVisibleIndex << m_visibleItems.count();
150− const QPointF pos = positionForIndex(modelIndex);
151− item->setPosition(pos);
153− item->setSize(sizeForIndex(modelIndex));
156−bool OrganicGrid::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
158− bool changed = false;
160− // As adding, we also remove in a 6-module basis
161− int lastModuleIndex = (m_firstVisibleIndex / 6) * 6 + 5;
162− bool removeIndex = positionForIndex(lastModuleIndex).y() + sizeForIndex(lastModuleIndex).height() < bufferFromY;
163− while (removeIndex && !m_visibleItems.isEmpty()) {
164− releaseItem(m_visibleItems.takeFirst());
166− m_firstVisibleIndex++;
168− lastModuleIndex = (m_firstVisibleIndex / 6) * 6 + 5;
169− removeIndex = positionForIndex(lastModuleIndex).y() + sizeForIndex(lastModuleIndex).height() < bufferFromY;
172− int firstModuleIndex = ((m_firstVisibleIndex + m_visibleItems.count() - 1) / 6) * 6;
173− removeIndex = positionForIndex(firstModuleIndex).y() > bufferToY;
174− while (removeIndex && !m_visibleItems.isEmpty()) {
175− releaseItem(m_visibleItems.takeLast());
178− firstModuleIndex = ((m_firstVisibleIndex + m_visibleItems.count() - 1) / 6) * 6;
179− removeIndex = positionForIndex(firstModuleIndex).y() > bufferToY;
182− if (m_visibleItems.isEmpty()) {
183− m_firstVisibleIndex = -1;
189−void OrganicGrid::cleanupExistingItems()
191− Q_FOREACH(QQuickItem *item, m_visibleItems)
193− m_visibleItems.clear();
194− m_firstVisibleIndex = -1;
195− setImplicitHeightDirty();
198−void OrganicGrid::doRelayout()
200− const qreal moduleWidth = m_smallDelegateSize.width() * 2 + columnSpacing() * 2 + m_bigDelegateSize.width();
201− m_numberOfModulesPerRow = floor((width() + columnSpacing()) / (moduleWidth + columnSpacing()));
202− m_numberOfModulesPerRow = qMax(1, m_numberOfModulesPerRow);
204− int i = m_firstVisibleIndex;
205− const QList<QQuickItem*> allItems = m_visibleItems;
206− m_visibleItems.clear();
207− Q_FOREACH(QQuickItem *item, allItems) {
208− addItemToView(i, item);
213−void OrganicGrid::updateItemCulling(qreal visibleFromY, qreal visibleToY)
215− Q_FOREACH(QQuickItem *item, m_visibleItems) {
216− QQuickItemPrivate::get(item)->setCulled(item->y() + item->height() <= visibleFromY || item->y() >= visibleToY);
220−void OrganicGrid::calculateImplicitHeight()
222− const qreal moduleHeight = m_smallDelegateSize.height() + rowSpacing() + m_bigDelegateSize.height();
223− const int itemCount = !model() ? 0 : model()->rowCount();
224− const int itemsPerRow = m_numberOfModulesPerRow * 6;
225− const int fullRows = floor(itemCount / itemsPerRow);
226− const qreal fullRowsHeight = fullRows == 0 ? 0 : fullRows * moduleHeight + rowSpacing() * (fullRows - 1);
228− const int remainingItems = itemCount - fullRows * itemsPerRow;
229− if (remainingItems == 0) {
230− setImplicitHeight(fullRowsHeight);
231− } else if (remainingItems <= 2) {
232− setImplicitHeight(fullRowsHeight + m_smallDelegateSize.height() + rowSpacing());
234− setImplicitHeight(fullRowsHeight + rowSpacing() + moduleHeight);
238−void OrganicGrid::processModelRemoves(const QVector<QQmlChangeSet::Change> &removes)
240− Q_FOREACH(const QQmlChangeSet::Change remove, removes) {
241− for (int i = remove.count - 1; i >= 0; --i) {
242− const int indexToRemove = remove.index + i;
243− // We only support removing from the end
244− const int lastIndex = m_firstVisibleIndex + m_visibleItems.count() - 1;
245− if (indexToRemove == lastIndex) {
246− releaseItem(m_visibleItems.takeLast());
248− if (indexToRemove < lastIndex) {
249− qDebug() << "OrganicGrid only supports removal from the end of the model, resetting instead";
250− cleanupExistingItems();
256− if (m_visibleItems.isEmpty()) {
257− m_firstVisibleIndex = -1;
259− setImplicitHeightDirty();
plugins/Dash/organicgrid.hdeleted−91
@@ -1,91 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
20−#include "abstractdashview.h"
22− /** An Organic Grid is is a view that creates delegates
23− * based on a model and layouts them in groups of six items (called module).
25− * In each module there are 4 items that are forced to the small delegate size
26− * and two that are forced to the big delegate size.
30− * +---+ +---+ +-----+
37− * +-----+ +---+ +---+
39− * Modules are positioned one after the other in a grid like fashion, i.e.
49−class OrganicGrid : public AbstractDashView
53− Q_PROPERTY(QSizeF smallDelegateSize READ smallDelegateSize WRITE setSmallDelegateSize NOTIFY smallDelegateSizeChanged)
54− Q_PROPERTY(QSizeF bigDelegateSize READ bigDelegateSize WRITE setBigDelegateSize NOTIFY bigDelegateSizeChanged)
56−friend class OrganicGridTest;
61− QSizeF smallDelegateSize() const;
62− void setSmallDelegateSize(const QSizeF size);
64− QSizeF bigDelegateSize() const;
65− void setBigDelegateSize(const QSizeF size);
68− void smallDelegateSizeChanged();
69− void bigDelegateSizeChanged();
71− QPointF positionForIndex(int modelIndex) const;
72− QSizeF sizeForIndex(int modelIndex) const;
74− void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
75− void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
76− void addItemToView(int modelIndex, QQuickItem *item) override;
77− bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
78− void cleanupExistingItems() override;
79− void doRelayout() override;
80− void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
81− void calculateImplicitHeight() override;
82− void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) override;
84− QSizeF m_smallDelegateSize;
85− QSizeF m_bigDelegateSize;
86− int m_firstVisibleIndex;
87− int m_numberOfModulesPerRow;
88− QList<QQuickItem*> m_visibleItems;
plugins/Dash/plugin.cppdeleted−70
@@ -1,70 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
20−#include "horizontaljournal.h"
21−#include "listviewwithpageheader.h"
22−#include "organicgrid.h"
23−#include "verticaljournal.h"
25−#include <QAbstractItemModel>
28−static QUrl oauthCleanedUrl(QUrl u)
31− q.removeQueryItem(QStringLiteral("oauth_nonce"));
32− q.removeQueryItem(QStringLiteral("oauth_timestamp"));
33− q.removeQueryItem(QStringLiteral("oauth_consumer_key"));
34− q.removeQueryItem(QStringLiteral("oauth_signature_method"));
35− q.removeQueryItem(QStringLiteral("oauth_version"));
36− q.removeQueryItem(QStringLiteral("oauth_signature"));
41−class AudioComparer : public QObject
45− Q_INVOKABLE bool compare(const QUrl &url1, const QUrl &url2)
47− return oauthCleanedUrl(url1) == oauthCleanedUrl(url2);
51−static QObject *audio_comparer_singleton_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
54− Q_UNUSED(scriptEngine)
56− return new AudioComparer();
59−void DashPlugin::registerTypes(const char *uri)
61− Q_ASSERT(uri == QLatin1String("Dash"));
62− qmlRegisterType<QAbstractItemModel>();
63− qmlRegisterType<HorizontalJournal>(uri, 0, 1, "HorizontalJournal");
64− qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
65− qmlRegisterType<OrganicGrid>(uri, 0, 1, "OrganicGrid");
66− qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
67− qmlRegisterSingletonType<AudioComparer>(uri, 0, 1, "AudioUrlComparer", audio_comparer_singleton_provider);
plugins/Dash/qmldirdeleted−11
@@ -1,11 +0,0 @@
4−singleton CardCreatorCache 0.1 CardCreatorCache.qml
5−singleton DashAudioPlayer 0.1 DashAudioPlayer.qml
6−ScopeStyle 0.1 ScopeStyle.qml
7−CardAttributes 0.1 CardAttributes.qml
8−CardSocialActions 0.1 CardSocialActions.qml
9−CroppedImageMinimumSourceSize 0.1 CroppedImageMinimumSourceSize.qml
10−AudioProgressBar 0.1 AudioProgressBar.qml
11−CardAudioProgress 0.1 CardAudioProgress.qml
plugins/Dash/verticaljournal.cppdeleted−273
@@ -1,273 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
18− * The implementation is centered around m_columnVisibleItems
19− * that holds a vector of lists. There's a list for each of the
20− * columns the view has. In the list the items of the column are
21− * ordered as they appear topdown in the view. m_indexColumnMap is
22− * used when re-building the list up since given a position
23− * in the middle of the list and the need to create the previous does
24− * not give us enough information to know in which column we have
25− * to position the item so that when we reach the item the view is
26− * correctly layouted at 0 for all the columns
28−#include "verticaljournal.h"
30−#pragma GCC diagnostic push
31−#pragma GCC diagnostic ignored "-pedantic"
32−#include <private/qquickitem_p.h>
33−#pragma GCC diagnostic pop
35−VerticalJournal::VerticalJournal()
40−qreal VerticalJournal::columnWidth() const
42− return m_columnWidth;
45−void VerticalJournal::setColumnWidth(qreal columnWidth)
47− if (columnWidth != m_columnWidth) {
48− m_columnWidth = columnWidth;
49− Q_EMIT columnWidthChanged();
51− if (isComponentComplete()) {
52− Q_FOREACH(const auto &column, m_columnVisibleItems) {
53− Q_FOREACH(const ViewItem item, column) {
54− item.m_item->setWidth(columnWidth);
62−void VerticalJournal::findBottomModelIndexToAdd(int *modelIndex, qreal *yPos)
65− *yPos = std::numeric_limits<qreal>::max();
67− Q_FOREACH(const auto &column, m_columnVisibleItems) {
68− if (!column.isEmpty()) {
69− const ViewItem &item = column.last();
70− *yPos = qMin(*yPos, item.y() + item.height() + rowSpacing());
71− *modelIndex = qMax(*modelIndex, item.m_modelIndex + 1);
78−void VerticalJournal::findTopModelIndexToAdd(int *modelIndex, qreal *yPos)
81− *yPos = std::numeric_limits<qreal>::lowest();
82− int columnToAddTo = -1;
84− // Find the topmost free column
85− for (int i = 0; i < m_columnVisibleItems.count(); ++i) {
86− const auto &column = m_columnVisibleItems[i];
87− if (!column.isEmpty()) {
88− const ViewItem &item = column.first();
89− const auto itemTopPos = item.y() - rowSpacing();
90− if (itemTopPos > *yPos) {
92− *modelIndex = item.m_modelIndex - 1;
98− if (*modelIndex > 0) {
99− Q_ASSERT(m_indexColumnMap.contains(*modelIndex));
100− while (m_indexColumnMap[*modelIndex] != columnToAddTo) {
101− // We found out that we have to add to columnToAddTo
102− // and thought that we had to add *modelIndex, but history tells
103− // it is not correct, so find up from *modelIndex until we found the index
104− // that has to end up in columnToAddTo
105− *modelIndex = *modelIndex - 1;
106− Q_ASSERT(m_indexColumnMap.contains(*modelIndex));
111−bool VerticalJournal::removeNonVisibleItems(qreal bufferFromY, qreal bufferToY)
113− bool changed = false;
115− for (int i = 0; i < m_columnVisibleItems.count(); ++i) {
116− QList<ViewItem> &column = m_columnVisibleItems[i];
117− while (!column.isEmpty() && column.first().y() + column.first().height() < bufferFromY) {
118− releaseItem(column.takeFirst().m_item);
122− while (!column.isEmpty() && column.last().y() > bufferToY) {
123− releaseItem(column.takeLast().m_item);
131−void VerticalJournal::addItemToView(int modelIndex, QQuickItem *item)
133− if (item->width() != m_columnWidth) {
134− qWarning() << "Item" << modelIndex << "width is not the one that the columnWidth mandates, resetting it";
135− item->setWidth(m_columnWidth);
138− // Check if we add it to the bottom of existing column items
139− const QList<ViewItem> &firstColumn = m_columnVisibleItems[0];
140− qreal columnToAddY = !firstColumn.isEmpty() ? firstColumn.last().y() + firstColumn.last().height() : -rowSpacing();
141− int columnToAddTo = 0;
142− for (int i = 1; i < m_columnVisibleItems.count(); ++i) {
143− const QList<ViewItem> &column = m_columnVisibleItems[i];
144− const qreal iY = !column.isEmpty() ? column.last().y() + column.last().height() : -rowSpacing();
145− if (iY < columnToAddY) {
151− const QList<ViewItem> &columnToAdd = m_columnVisibleItems[columnToAddTo];
152− if (columnToAdd.isEmpty() || columnToAdd.last().m_modelIndex < modelIndex) {
153− item->setX(columnToAddTo * (m_columnWidth + columnSpacing()));
154− item->setY(columnToAddY + rowSpacing());
156− m_columnVisibleItems[columnToAddTo] << ViewItem(item, modelIndex);
157− m_indexColumnMap[modelIndex] = columnToAddTo;
159− Q_ASSERT(m_indexColumnMap.contains(modelIndex));
160− columnToAddTo = m_indexColumnMap[modelIndex];
161− columnToAddY = m_columnVisibleItems[columnToAddTo].first().y();
163− item->setX(columnToAddTo * (m_columnWidth + columnSpacing()));
164− item->setY(columnToAddY - rowSpacing() - item->height());
166− m_columnVisibleItems[columnToAddTo].prepend(ViewItem(item, modelIndex));
170−void VerticalJournal::cleanupExistingItems()
172− // Cleanup the existing items
173− for (int i = 0; i < m_columnVisibleItems.count(); ++i) {
174− QList<ViewItem> &column = m_columnVisibleItems[i];
175− Q_FOREACH(const ViewItem item, column)
176− releaseItem(item.m_item);
179− m_indexColumnMap.clear();
180− setImplicitHeightDirty();
183−void VerticalJournal::calculateImplicitHeight()
185− int lastModelIndex = -1;
186− qreal bottomMostY = 0;
187− Q_FOREACH(const auto &column, m_columnVisibleItems) {
188− if (!column.isEmpty()) {
189− const ViewItem &item = column.last();
190− lastModelIndex = qMax(lastModelIndex, item.m_modelIndex);
191− bottomMostY = qMax(bottomMostY, item.y() + item.height());
194− if (lastModelIndex >= 0) {
195− const double averageHeight = bottomMostY / (lastModelIndex + 1);
196− setImplicitHeight(bottomMostY + averageHeight * (model()->rowCount() - lastModelIndex - 1));
198− setImplicitHeight(0);
202−void VerticalJournal::doRelayout()
204− QList<ViewItem> allItems;
205− Q_FOREACH(const auto &column, m_columnVisibleItems)
210− const int nColumns = qMax(1., floor((double)(width() + columnSpacing()) / (m_columnWidth + columnSpacing())));
211− m_columnVisibleItems.resize(nColumns);
212− m_indexColumnMap.clear();
213− for (int i = 0; i < nColumns; ++i)
214− m_columnVisibleItems[i].clear();
216− // If the first of allItems doesn't contain index 0 we need to drop them
217− // all since we can't consistently relayout without the first item being there
219− if (!allItems.isEmpty()) {
220− if (allItems.first().m_modelIndex == 0) {
221− Q_FOREACH(const ViewItem item, allItems)
222− addItemToView(item.m_modelIndex, item.m_item);
224− Q_FOREACH(const ViewItem item, allItems)
225− releaseItem(item.m_item);
230−void VerticalJournal::updateItemCulling(qreal visibleFromY, qreal visibleToY)
232− Q_FOREACH(const auto &column, m_columnVisibleItems) {
233− Q_FOREACH(const ViewItem item, column) {
234− const bool cull = item.y() + item.height() <= visibleFromY || item.y() >= visibleToY;
235− QQuickItemPrivate::get(item.m_item)->setCulled(cull);
240−void VerticalJournal::processModelRemoves(const QVector<QQmlChangeSet::Change> &removes)
242− Q_FOREACH(const QQmlChangeSet::Change remove, removes) {
243− for (int i = remove.count - 1; i >= 0; --i) {
244− const int indexToRemove = remove.index + i;
245− // Since we only support removing from the end, indexToRemove
246− // must refer to the last item of one of the columns or
247− // be bigger than them (because it's not in the viewport and
248− // thus we have not created a delegate for it)
250− int lastCreatedIndex = INT_MIN;
251− for (int i = 0; !found && i < m_columnVisibleItems.count(); ++i) {
252− QList<ViewItem> &column = m_columnVisibleItems[i];
253− if (!column.isEmpty()) {
254− const int lastColumnIndex = column.last().m_modelIndex;
255− if (lastColumnIndex == indexToRemove) {
256− releaseItem(column.takeLast().m_item);
259− lastCreatedIndex = qMax(lastCreatedIndex, lastColumnIndex);
263− if (indexToRemove < lastCreatedIndex) {
264− qDebug() << "VerticalJournal only supports removal from the end of the model, resetting instead";
265− cleanupExistingItems();
268− setImplicitHeightDirty();
plugins/Dash/verticaljournal.hdeleted−100
@@ -1,100 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
17−#ifndef VERTICALJOURNAL_H
18−#define VERTICALJOURNAL_H
20−#include "abstractdashview.h"
22− /** A vertical journal is a view that creates delegates
23− * based on a model and layouts them in columns following
24− * a top-left most position rule.
26− * The number of columns is calculated using the width of
27− * the view itself, the columnWidth (i.e. the width of each individual delegate)
28− * and the columnSpacing between columns.
30− * All delegates are forced to columnWidth if they don't have it.
32− * The first nColumns items are layouted at row 0 from column 0
33− * to column nColumns-1 in order. After that every new item
34− * is positioned in the column which provides the free topmost
35− * position as possible. If more than one column tie in providing
36− * the topmost free position the leftmost column will be used.
40− * +-----+ +-----+ +-----+
43− * | 1 | +-----+ | 3 |
46− * +-----+ | 4 | +-----+
54−class VerticalJournal : public AbstractDashView
58− Q_PROPERTY(qreal columnWidth READ columnWidth WRITE setColumnWidth NOTIFY columnWidthChanged)
60−friend class VerticalJournalTest;
65− qreal columnWidth() const;
66− void setColumnWidth(qreal columnWidth);
69− void columnWidthChanged();
75− ViewItem(QQuickItem *item, int modelIndex) : m_item(item), m_modelIndex(modelIndex) {}
76− qreal x() const { return m_item->x(); }
77− qreal y() const { return m_item->y(); }
78− qreal height() const { return m_item->height(); }
79− bool operator<(const ViewItem v) const { return m_modelIndex < v.m_modelIndex; }
85− void findBottomModelIndexToAdd(int *modelIndex, qreal *yPos) override;
86− void findTopModelIndexToAdd(int *modelIndex, qreal *yPos) override;
87− bool removeNonVisibleItems(qreal bufferFromY, qreal bufferToY) override;
88− void addItemToView(int modelIndex, QQuickItem *item) override;
89− void cleanupExistingItems() override;
90− void calculateImplicitHeight() override;
91− void doRelayout() override;
92− void updateItemCulling(qreal visibleFromY, qreal visibleToY) override;
93− void processModelRemoves(const QVector<QQmlChangeSet::Change> &removes) override;
95− QVector<QList<ViewItem>> m_columnVisibleItems;
96− QHash<int, int> m_indexColumnMap;
plugins/GlobalShortcut/CMakeLists.txt+1−1
@@ -5,6 +5,6 @@ set(globalshortcutplugin_SRCS
6add_library(GlobalShortcut-qml SHARED ${globalshortcutplugin_SRCS})
6add_library(GlobalShortcut-qml SHARED ${globalshortcutplugin_SRCS})
8−qt5_use_modules(GlobalShortcut-qml Quick Gui)
8+target_link_libraries(GlobalShortcut-qml Qt5::Quick Qt5::Gui)
10add_unity8_plugin(GlobalShortcut 1.0 GlobalShortcut TARGETS GlobalShortcut-qml)
10add_unity8_plugin(GlobalShortcut 1.0 GlobalShortcut TARGETS GlobalShortcut-qml)
plugins/GlobalShortcut/GlobalShortcut.qmltypesdeleted−31
@@ -1,31 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable GlobalShortcut 1.0 plugins'
11− name: "GlobalShortcut"
12− defaultProperty: "data"
13− prototype: "QQuickItem"
14− exports: ["GlobalShortcut/GlobalShortcut 1.0"]
15− exportMetaObjectRevisions: [0]
16− Property { name: "shortcut"; type: "QVariant" }
17− Property { name: "active"; type: "bool" }
19− name: "shortcutChanged"
20− Parameter { name: "shortcut"; type: "QVariant" }
24− Parameter { name: "shortcut"; type: "string" }
27− name: "activeChanged"
28− Parameter { name: "active"; type: "bool" }
plugins/GlobalShortcut/globalshortcut.cpp+15−4
@@ -58,15 +58,26 @@ void GlobalShortcut::setActive(bool active)
59void GlobalShortcut::componentComplete()
59void GlobalShortcut::componentComplete()
61+ if (this->window()) {
62+ QMetaObject::invokeMethod(this, "setupFilterOnWindow", Q_ARG(QQuickWindow*, this->window()));
61 connect(this, &QQuickItem::windowChanged, this, &GlobalShortcut::setupFilterOnWindow);
64 connect(this, &QQuickItem::windowChanged, this, &GlobalShortcut::setupFilterOnWindow);
64void GlobalShortcut::keyPressEvent(QKeyEvent * event)
67void GlobalShortcut::keyPressEvent(QKeyEvent * event)
67− if (m_active) {
69+ if (!m_active) return;
68− Q_EMIT triggered(m_shortcut.toString());
72+ Q_EMIT triggered(m_shortcut.toString());
75+void GlobalShortcut::keyReleaseEvent(QKeyEvent * event)
77+ if (!m_active) return;
80+ Q_EMIT released(m_shortcut.toString());
72void GlobalShortcut::setupFilterOnWindow(QQuickWindow *window)
83void GlobalShortcut::setupFilterOnWindow(QQuickWindow *window)
plugins/GlobalShortcut/globalshortcut.h+5
@@ -55,6 +55,7 @@ public:
56 void componentComplete() override;
56 void componentComplete() override;
57 void keyPressEvent(QKeyEvent * event) override;
57 void keyPressEvent(QKeyEvent * event) override;
58+ void keyReleaseEvent(QKeyEvent * event) override;
60 void shortcutChanged(const QVariant &shortcut);
61 void shortcutChanged(const QVariant &shortcut);
@@ -62,6 +63,10 @@ Q_SIGNALS:
62 * Emitted when a global keypress of @p shortcut is detected
63 * Emitted when a global keypress of @p shortcut is detected
64 void triggered(const QString &shortcut);
65 void triggered(const QString &shortcut);
67+ * Emitted when a global keypress of @p shortcut is released
69+ void released(const QString &shortcut);
65 void activeChanged(bool active);
70 void activeChanged(bool active);
67private Q_SLOTS:
72private Q_SLOTS:
plugins/GlobalShortcut/globalshortcutregistry.cpp+14−4
@@ -73,20 +73,30 @@ bool GlobalShortcutRegistry::eventFilter(QObject *obj, QEvent *event)
73 Q_ASSERT(m_filteredWindow);
73 Q_ASSERT(m_filteredWindow);
74 Q_ASSERT(obj == static_cast<QObject*>(m_filteredWindow.data()));
74 Q_ASSERT(obj == static_cast<QObject*>(m_filteredWindow.data()));
76− if (event->type() == QEvent::KeyPress) {
76+ if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
77 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
78 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
80+ // Make a copy of the event so we don't alter it for passing on.
81+ QKeyEvent eCopy(keyEvent->type(),
83+ keyEvent->modifiers(),
85+ keyEvent->isAutoRepeat(),
78 int seq = keyEvent->key() + keyEvent->modifiers();
89 int seq = keyEvent->key() + keyEvent->modifiers();
79 if (m_shortcuts.contains(seq)) {
90 if (m_shortcuts.contains(seq)) {
80 const auto shortcuts = m_shortcuts.value(seq);
91 const auto shortcuts = m_shortcuts.value(seq);
81 Q_FOREACH(const auto &shortcut, shortcuts) {
92 Q_FOREACH(const auto &shortcut, shortcuts) {
82 if (shortcut) {
93 if (shortcut) {
83− qApp->sendEvent(shortcut, keyEvent);
94+ qApp->sendEvent(shortcut, &eCopy);
89− return event->isAccepted();
99+ return eCopy.isAccepted();
92 return QObject::eventFilter(obj, event);
102 return QObject::eventFilter(obj, event);
plugins/Greeter/Unity/Launcher/CMakeLists.txt+1−3
@@ -1,4 +1,3 @@
1−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
4add_definitions(-DSM_BUSNAME=systemBus)
3add_definitions(-DSM_BUSNAME=systemBus)
@@ -30,8 +29,7 @@ add_library(UnityLauncherAS-qml MODULE
30target_link_libraries(UnityLauncherAS-qml
29target_link_libraries(UnityLauncherAS-qml
31 unity8-private
30 unity8-private
32 ${GSETTINGS_QT_LDFLAGS}
31 ${GSETTINGS_QT_LDFLAGS}
32+ Qt5::DBus Qt5::Qml Qt5::Gui
35−qt5_use_modules(UnityLauncherAS-qml DBus Qml Gui)
37add_unity8_greeter_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncherAS-qml)
35add_unity8_greeter_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncherAS-qml)
plugins/Greeter/Unity/Launcher/Launcher.qmltypesdeleted−182
@@ -1,182 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.Launcher 0.1 plugins/Greeter'
12− prototype: "unity::shell::launcher::LauncherItemInterface"
13− exports: ["Unity.Launcher/LauncherItem 0.1"]
15− exportMetaObjectRevisions: [0]
18− name: "LauncherModel"
19− prototype: "unity::shell::launcher::LauncherModelInterface"
20− exports: ["Unity.Launcher/LauncherModel 0.1"]
23− exportMetaObjectRevisions: [0]
25− name: "requestRemove"
26− Parameter { name: "appId"; type: "string" }
28− Method { name: "refresh" }
31− type: "unity::shell::launcher::LauncherItemInterface*"
32− Parameter { name: "index"; type: "int" }
36− Parameter { name: "oldIndex"; type: "int" }
37− Parameter { name: "newIndex"; type: "int" }
41− Parameter { name: "appId"; type: "string" }
42− Parameter { name: "index"; type: "int" }
46− Parameter { name: "appId"; type: "string" }
49− name: "quickListActionInvoked"
50− Parameter { name: "appId"; type: "string" }
51− Parameter { name: "actionIndex"; type: "int" }
55− Parameter { name: "username"; type: "string" }
58− name: "getUrlForAppId"
60− Parameter { name: "appId"; type: "string" }
64− name: "QuickListModel"
65− prototype: "unity::shell::launcher::QuickListModelInterface"
66− exports: ["Unity.Launcher/QuickListModel 0.1"]
68− exportMetaObjectRevisions: [0]
71− name: "unity::shell::launcher::LauncherItemInterface"
73− exports: ["Unity.Launcher/LauncherItemInterface 0.1"]
75− exportMetaObjectRevisions: [0]
76− Property { name: "appId"; type: "string"; isReadonly: true }
77− Property { name: "name"; type: "string"; isReadonly: true }
78− Property { name: "icon"; type: "string"; isReadonly: true }
79− Property { name: "pinned"; type: "bool"; isReadonly: true }
80− Property { name: "running"; type: "bool"; isReadonly: true }
81− Property { name: "recent"; type: "bool"; isReadonly: true }
82− Property { name: "progress"; type: "int"; isReadonly: true }
83− Property { name: "count"; type: "int"; isReadonly: true }
84− Property { name: "countVisible"; type: "bool"; isReadonly: true }
85− Property { name: "focused"; type: "bool"; isReadonly: true }
88− type: "unity::shell::launcher::QuickListModelInterface"
94− Parameter { name: "name"; type: "string" }
98− Parameter { name: "icon"; type: "string" }
101− name: "pinnedChanged"
102− Parameter { name: "pinned"; type: "bool" }
105− name: "runningChanged"
106− Parameter { name: "running"; type: "bool" }
109− name: "recentChanged"
110− Parameter { name: "running"; type: "bool" }
113− name: "progressChanged"
114− Parameter { name: "progress"; type: "int" }
117− name: "countChanged"
118− Parameter { name: "count"; type: "int" }
121− name: "countVisibleChanged"
122− Parameter { name: "countVisible"; type: "bool" }
125− name: "focusedChanged"
126− Parameter { name: "focused"; type: "bool" }
130− name: "unity::shell::launcher::LauncherModelInterface"
131− prototype: "QAbstractListModel"
132− exports: ["Unity.Launcher/LauncherModelInterface 0.1"]
134− exportMetaObjectRevisions: [0]
136− name: "applicationManager"
137− type: "unity::shell::application::ApplicationManagerInterface"
140− Property { name: "onlyPinned"; type: "bool" }
141− Signal { name: "hint" }
144− Parameter { name: "oldIndex"; type: "int" }
145− Parameter { name: "newIndex"; type: "int" }
149− type: "unity::shell::launcher::LauncherItemInterface*"
150− Parameter { name: "index"; type: "int" }
154− Parameter { name: "appId"; type: "string" }
155− Parameter { name: "index"; type: "int" }
159− Parameter { name: "appId"; type: "string" }
162− name: "requestRemove"
163− Parameter { name: "appId"; type: "string" }
166− name: "quickListActionInvoked"
167− Parameter { name: "appId"; type: "string" }
168− Parameter { name: "actionIndex"; type: "int" }
172− Parameter { name: "username"; type: "string" }
176− name: "unity::shell::launcher::QuickListModelInterface"
177− prototype: "QAbstractListModel"
178− exports: ["Unity.Launcher/QuickListInterface 0.1"]
180− exportMetaObjectRevisions: [0]
plugins/Greeter/Unity/Launcher/launcheritem.cpp+33
@@ -32,6 +32,7 @@ LauncherItem::LauncherItem(const QString &appId, const QString &name, const QStr
32 m_countVisible(false),
32 m_countVisible(false),
33 m_focused(false),
33 m_focused(false),
34 m_alerting(false),
34 m_alerting(false),
35 m_quickList(new QuickListModel(this))
36 m_quickList(new QuickListModel(this))
37 QuickListEntry nameAction;
38 QuickListEntry nameAction;
@@ -75,6 +76,25 @@ void LauncherItem::setIcon(const QString &icon)
79+QStringList LauncherItem::keywords() const
84+void LauncherItem::setKeywords(const QStringList &keywords)
86+ if (m_keywords != keywords) {
87+ m_keywords = keywords;
88+ Q_EMIT keywordsChanged(keywords);
92+uint LauncherItem::popularity() const
94+ // Not exposing usage order in greeter session at this point.
78bool LauncherItem::pinned() const
98bool LauncherItem::pinned() const
80 return m_pinned;
100 return m_pinned;
@@ -179,6 +199,19 @@ void LauncherItem::setAlerting(bool alerting)
202+int LauncherItem::surfaceCount() const
204+ return m_surfaceCount;
207+void LauncherItem::setSurfaceCount(int surfaceCount)
209+ if (m_surfaceCount != surfaceCount) {
210+ m_surfaceCount = surfaceCount;
211+ Q_EMIT surfaceCountChanged(surfaceCount);
182unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
215unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
184 return m_quickList;
217 return m_quickList;
plugins/Greeter/Unity/Launcher/launcheritem.h+7−1
@@ -34,6 +34,8 @@ public:
34 QString appId() const override;
34 QString appId() const override;
35 QString name() const override;
35 QString name() const override;
36 QString icon() const override;
36 QString icon() const override;
37+ QStringList keywords() const override;
38+ uint popularity() const override;
37 bool pinned() const override;
39 bool pinned() const override;
38 bool running() const override;
40 bool running() const override;
39 bool recent() const override;
41 bool recent() const override;
@@ -42,12 +44,14 @@ public:
42 bool countVisible() const override;
44 bool countVisible() const override;
43 bool focused() const override;
45 bool focused() const override;
44 bool alerting() const override;
46 bool alerting() const override;
47+ int surfaceCount() const override;
46 unity::shell::launcher::QuickListModelInterface *quickList() const override;
49 unity::shell::launcher::QuickListModelInterface *quickList() const override;
49 void setName(const QString &name);
52 void setName(const QString &name);
50 void setIcon(const QString &icon);
53 void setIcon(const QString &icon);
54+ void setKeywords(const QStringList &keywords);
51 void setPinned(bool pinned);
55 void setPinned(bool pinned);
52 void setRunning(bool running);
56 void setRunning(bool running);
53 void setRecent(bool recent);
57 void setRecent(bool recent);
@@ -56,12 +60,13 @@ private:
56 void setCountVisible(bool countVisible);
60 void setCountVisible(bool countVisible);
57 void setFocused(bool focused);
61 void setFocused(bool focused);
58 void setAlerting(bool alerting);
62 void setAlerting(bool alerting);
59−
63+ void setSurfaceCount(int surfaceCount);
62 QString m_appId;
66 QString m_appId;
63 QString m_name;
67 QString m_name;
64 QString m_icon;
68 QString m_icon;
69+ QStringList m_keywords;
65 bool m_pinned;
70 bool m_pinned;
66 bool m_running;
71 bool m_running;
67 bool m_recent;
72 bool m_recent;
@@ -70,6 +75,7 @@ private:
70 bool m_countVisible;
75 bool m_countVisible;
71 bool m_focused;
76 bool m_focused;
72 bool m_alerting;
77 bool m_alerting;
73 QuickListModel *m_quickList;
79 QuickListModel *m_quickList;
75 friend class LauncherModel;
81 friend class LauncherModel;
plugins/Greeter/Unity/Launcher/launchermodelas.cpp+2−7
@@ -69,18 +69,13 @@ QVariant LauncherModel::data(const QModelIndex &index, int role) const
69 return item->focused();
69 return item->focused();
70 case RoleRunning:
70 case RoleRunning:
71 return item->running();
71 return item->running();
72+ case RoleSurfaceCount:
73+ return item->surfaceCount();
74 return QVariant();
76 return QVariant();
77−void LauncherModel::setAlerting(const QString &appId, bool alerting)
81− qWarning() << "This is a read only implementation. Cannot set alert-state of items.";
84unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
79unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
86 if (index < 0 || index >= m_list.count()) {
81 if (index < 0 || index >= m_list.count()) {
plugins/Greeter/Unity/Launcher/launchermodelas.h−1
@@ -41,7 +41,6 @@ public:
42 QVariant data(const QModelIndex &index, int role) const override;
42 QVariant data(const QModelIndex &index, int role) const override;
44− Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override;
45 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;
44 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;
46 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
45 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
47 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
46 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
plugins/Greeter/Unity/Launcher/quicklistmodel.cpp+2
@@ -65,6 +65,8 @@ QVariant QuickListModel::data(const QModelIndex &index, int role) const
65 return m_list.at(index.row()).icon();
65 return m_list.at(index.row()).icon();
66 case RoleClickable:
66 case RoleClickable:
67 return m_list.at(index.row()).clickable();
67 return m_list.at(index.row()).clickable();
69+ return false; // The greeter plugin would just not add any private entries
69 return QVariant();
71 return QVariant();
plugins/IntegratedLightDM/CMakeLists.txtdeleted−40
@@ -1,40 +0,0 @@
1−pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
2−# TODO: Once we split out a separate greeter process, uncomment these lines
3−#pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-2)
5−add_subdirectory(liblightdm)
8− ${CMAKE_CURRENT_SOURCE_DIR}
9− ${CMAKE_CURRENT_BINARY_DIR}
10− ${CMAKE_SOURCE_DIR}/plugins/Utils
11− ${CMAKE_SOURCE_DIR}/tests/mocks/IntegratedLightDM
12− #${LIBLIGHTDM_INCLUDE_DIRS}
13− ${libunity8-private_SOURCE_DIR}
14− ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
18− ../Utils/unitysortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
26−add_library(IntegratedLightDM-qml MODULE
30−target_link_libraries(IntegratedLightDM-qml
33−# TODO: Once we split out a separate greeter process, uncomment these lines
34−# ${LIBLIGHTDM_LDFLAGS}
35− ${LIBUSERMETRICSOUTPUT_LDFLAGS}
38−qt5_use_modules(IntegratedLightDM-qml DBus Gui Qml)
40−add_unity8_plugin(IntegratedLightDM 0.1 IntegratedLightDM TARGETS IntegratedLightDM-qml)
plugins/IntegratedLightDM/Greeter.cppdeleted−138
@@ -1,138 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
16− * Author: Michael Terry <michael.terry@canonical.com>
20−#include "GreeterPrivate.h"
23−GreeterPrivate::GreeterPrivate(Greeter* parent)
24− : m_greeter(new QLightDM::Greeter(parent)),
32−Greeter::Greeter(QObject* parent)
34− d_ptr(new GreeterPrivate(this))
38− connect(d->m_greeter, &QLightDM::Greeter::showMessage,
39− this, &Greeter::showMessageFilter);
40− connect(d->m_greeter, &QLightDM::Greeter::showPrompt,
41− this, &Greeter::showPromptFilter);
42− connect(d->m_greeter, &QLightDM::Greeter::authenticationComplete,
43− this, &Greeter::authenticationCompleteFilter);
45− d->m_greeter->connectSync();
48−bool Greeter::isActive() const
54−void Greeter::setIsActive(bool active)
57− if (d->m_active != active) {
58− d->m_active = active;
59− Q_EMIT isActiveChanged();
63−bool Greeter::isAuthenticated() const
66− return d->m_greeter->isAuthenticated();
69−QString Greeter::authenticationUser() const
72− return d->m_greeter->authenticationUser();
75−bool Greeter::promptless() const
78− return d->promptless;
81−void Greeter::authenticate(const QString &username)
84− d->wasPrompted = false;
86− d->promptless = false;
87− Q_EMIT promptlessChanged();
90− d->m_greeter->authenticate(username);
91− Q_EMIT isAuthenticatedChanged();
92− Q_EMIT authenticationUserChanged(username);
95−void Greeter::respond(const QString &response)
98− d->m_greeter->respond(response);
101−bool Greeter::startSessionSync(const QString &session)
104− return d->m_greeter->startSessionSync(session);
107−void Greeter::showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type)
110− d->wasPrompted = true;
112− bool isDefaultPrompt = (text == dgettext("Linux-PAM", "Password: "));
114− // Strip prompt of any colons at the end
115− QString trimmedText = text.trimmed();
116− if (trimmedText.endsWith(':') || trimmedText.endsWith(QStringLiteral(":"))) {
117− trimmedText.chop(1);
120− Q_EMIT showPrompt(trimmedText, type == QLightDM::Greeter::PromptTypeSecret, isDefaultPrompt);
123−void Greeter::showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type)
125− Q_EMIT showMessage(text, type == QLightDM::Greeter::MessageTypeError);
128−void Greeter::authenticationCompleteFilter()
131− if (!d->wasPrompted) {
132− d->promptless = true;
133− Q_EMIT promptlessChanged();
136− Q_EMIT isAuthenticatedChanged();
137− Q_EMIT authenticationComplete();
plugins/IntegratedLightDM/IntegratedLightDM.qmltypesdeleted−251
@@ -1,251 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable LightDM 0.1 plugins'
13− exports: ["LightDM/Greeter 0.1"]
16− exportMetaObjectRevisions: [0]
17− Property { name: "active"; type: "bool" }
18− Property { name: "authenticated"; type: "bool"; isReadonly: true }
19− Property { name: "authenticationUser"; type: "string"; isReadonly: true }
20− Property { name: "promptless"; type: "bool"; isReadonly: true }
23− Parameter { name: "text"; type: "string" }
24− Parameter { name: "isError"; type: "bool" }
28− Parameter { name: "text"; type: "string" }
29− Parameter { name: "isSecret"; type: "bool" }
30− Parameter { name: "isDefaultPrompt"; type: "bool" }
32− Signal { name: "authenticationComplete" }
34− name: "authenticationUserChanged"
35− Parameter { name: "user"; type: "string" }
37− Signal { name: "isActiveChanged" }
38− Signal { name: "isAuthenticatedChanged" }
39− Signal { name: "showGreeter" }
40− Signal { name: "hideGreeter" }
42− name: "requestAuthenticationUser"
43− Parameter { name: "user"; type: "string" }
47− Parameter { name: "username"; type: "string" }
49− Method { name: "authenticate" }
52− Parameter { name: "response"; type: "string" }
55− name: "startSessionSync"
57− Parameter { name: "session"; type: "string" }
59− Method { name: "startSessionSync"; type: "bool" }
62− Parameter { name: "isActive"; type: "bool" }
66− name: "QAbstractProxyModel"
67− prototype: "QAbstractItemModel"
68− Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
71− name: "QLightDM::UsersModel"
72− prototype: "QAbstractListModel"
73− exports: ["LightDM/UserRoles 0.1"]
75− exportMetaObjectRevisions: [0]
77− name: "UserModelRoles"
82− "BackgroundRole": 259,
84− "HasMessagesRole": 261,
85− "ImagePathRole": 262,
86− "BackgroundPathRole": 263
91− name: "QSortFilterProxyModel"
92− prototype: "QAbstractProxyModel"
93− Property { name: "filterRegExp"; type: "QRegExp" }
94− Property { name: "filterKeyColumn"; type: "int" }
95− Property { name: "dynamicSortFilter"; type: "bool" }
96− Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
97− Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
98− Property { name: "isSortLocaleAware"; type: "bool" }
99− Property { name: "sortRole"; type: "int" }
100− Property { name: "filterRole"; type: "int" }
102− name: "setFilterRegExp"
103− Parameter { name: "pattern"; type: "string" }
106− name: "setFilterWildcard"
107− Parameter { name: "pattern"; type: "string" }
110− name: "setFilterFixedString"
111− Parameter { name: "pattern"; type: "string" }
113− Method { name: "clear" }
114− Method { name: "invalidate" }
117− name: "UnitySortFilterProxyModelQML"
118− prototype: "QSortFilterProxyModel"
119− Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
120− Property { name: "totalCount"; type: "int"; isReadonly: true }
121− Property { name: "count"; type: "int"; isReadonly: true }
122− Property { name: "invertMatch"; type: "bool" }
124− name: "invertMatchChanged"
125− Parameter { type: "bool" }
130− Parameter { name: "row"; type: "int" }
135− Parameter { name: "row"; type: "int" }
136− Parameter { name: "role"; type: "int" }
138− Method { name: "count"; type: "int" }
142− Parameter { name: "role"; type: "int" }
143− Parameter { name: "value"; type: "QVariant" }
146− name: "mapRowToSource"
148− Parameter { name: "row"; type: "int" }
151− name: "mapFromSource"
153− Parameter { name: "row"; type: "int" }
158− Parameter { name: "row"; type: "int" }
162− name: "UserMetricsOutput::ColorTheme"
163− prototype: "QObject"
164− Property { name: "start"; type: "QColor"; isReadonly: true }
165− Property { name: "main"; type: "QColor"; isReadonly: true }
166− Property { name: "end"; type: "QColor"; isReadonly: true }
168− name: "startChanged"
169− Parameter { name: "color"; type: "QColor" }
173− Parameter { name: "color"; type: "QColor" }
177− Parameter { name: "color"; type: "QColor" }
181− name: "UserMetricsOutput::UserMetrics"
182− prototype: "QObject"
183− exports: ["LightDM/Infographic 0.1"]
186− exportMetaObjectRevisions: [0]
187− Property { name: "label"; type: "string"; isReadonly: true }
188− Property { name: "username"; type: "string" }
191− type: "UserMetricsOutput::ColorTheme"
197− type: "UserMetricsOutput::ColorTheme"
201− Property { name: "firstMonth"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
202− Property { name: "secondMonth"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true }
203− Property { name: "currentDay"; type: "int"; isReadonly: true }
205− name: "labelChanged"
206− Parameter { name: "label"; type: "string" }
209− name: "usernameChanged"
210− Parameter { name: "username"; type: "string" }
213− name: "firstColorChanged"
214− Parameter { name: "color"; type: "ColorTheme"; isPointer: true }
217− name: "firstMonthChanged"
218− Parameter { name: "firstMonth"; type: "QAbstractItemModel"; isPointer: true }
221− name: "currentDayChanged"
222− Parameter { name: "currentDay"; type: "int" }
225− name: "secondColorChanged"
226− Parameter { name: "color"; type: "ColorTheme"; isPointer: true }
229− name: "secondMonthChanged"
230− Parameter { name: "secondMonth"; type: "QAbstractItemModel"; isPointer: true }
232− Signal { name: "nextDataSource" }
233− Signal { name: "readyForDataChange" }
234− Signal { name: "dataAboutToAppear" }
235− Signal { name: "dataAppeared" }
236− Signal { name: "dataAboutToChange" }
237− Signal { name: "dataChanged" }
238− Signal { name: "dataAboutToDisappear" }
239− Signal { name: "dataDisappeared" }
240− Method { name: "nextDataSourceSlot" }
241− Method { name: "readyForDataChangeSlot" }
245− prototype: "UnitySortFilterProxyModelQML"
246− exports: ["LightDM/Users 0.1"]
249− exportMetaObjectRevisions: [0]
plugins/IntegratedLightDM/UsersModel.cppdeleted−71
@@ -1,71 +0,0 @@
2− * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
16− * Author: Michael Terry <michael.terry@canonical.com>
19−#include "UsersModel.h"
20−#include <QLightDM/UsersModel>
21−#include <QtCore/QSortFilterProxyModel>
23−// First, we define an internal class that wraps LightDM's UsersModel. This
24−// class will modify some of the data coming from LightDM. For example, we
25−// modify any empty Real Names into just normal Names.
26−// (We can't modify the data directly in UsersModel below because it won't sort
27−// using the modified data.)
28−class MangleModel : public QSortFilterProxyModel
33− explicit MangleModel(QObject* parent=0);
35− QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38−MangleModel::MangleModel(QObject* parent)
39− : QSortFilterProxyModel(parent)
41− setSourceModel(new QLightDM::UsersModel(this));
44−QVariant MangleModel::data(const QModelIndex &index, int role) const
46− QVariant variantData = QSortFilterProxyModel::data(index, role);
48− // If user's real name is empty, switch to unix name
49− if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
50− variantData = QSortFilterProxyModel::data(index, QLightDM::UsersModel::NameRole);
51− } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
52− const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
53− variantData = stringData;
59−// **** Now we continue with actual UsersModel class ****
61−UsersModel::UsersModel(QObject* parent)
62− : UnitySortFilterProxyModelQML(parent)
64− setModel(new MangleModel(this));
65− setSortCaseSensitivity(Qt::CaseInsensitive);
66− setSortLocaleAware(true);
67− setSortRole(QLightDM::UsersModel::RealNameRole);
71−#include "UsersModel.moc"
plugins/LightDM/CMakeLists.txtnew file+26
@@ -0,0 +1,26 @@
1+pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
3+find_package(Qt5Core REQUIRED)
4+find_package(Qt5Quick REQUIRED)
7+ ${CMAKE_CURRENT_SOURCE_DIR}
8+ ${CMAKE_CURRENT_BINARY_DIR}
9+ ${CMAKE_SOURCE_DIR}/plugins/Utils
10+ ${libunity8-private_SOURCE_DIR}
11+ ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
15+ ../Utils/unitysortfilterproxymodelqml.cpp
25+add_subdirectory(FullLightDM)
26+add_subdirectory(IntegratedLightDM)
plugins/IntegratedLightDM/DBusGreeter.cpp → plugins/LightDM/DBusGreeter.cpprenamed+5−4
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014, 2015 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -24,7 +24,8 @@ DBusGreeter::DBusGreeter(Greeter *greeter, const QString &path)
24 : UnityDBusObject(path, QStringLiteral("com.canonical.UnityGreeter"), true, greeter),
24 : UnityDBusObject(path, QStringLiteral("com.canonical.UnityGreeter"), true, greeter),
25 m_greeter(greeter)
25 m_greeter(greeter)
27− connect(m_greeter, &Greeter::isActiveChanged, this, &DBusGreeter::isActiveChangedHandler);
27+ connect(m_greeter, &Greeter::isActiveChanged,
28+ this, &DBusGreeter::isActiveChangedHandler);
30bool DBusGreeter::isActive() const
31bool DBusGreeter::isActive() const
@@ -34,12 +35,12 @@ bool DBusGreeter::isActive() const
35void DBusGreeter::ShowGreeter()
36void DBusGreeter::ShowGreeter()
37− return Q_EMIT m_greeter->showGreeter();
38+ Q_EMIT m_greeter->showGreeter();
40void DBusGreeter::HideGreeter()
41void DBusGreeter::HideGreeter()
42− return Q_EMIT m_greeter->hideGreeter();
43+ Q_EMIT m_greeter->hideGreeter();
45void DBusGreeter::isActiveChangedHandler()
46void DBusGreeter::isActiveChangedHandler()
plugins/IntegratedLightDM/DBusGreeter.h → plugins/LightDM/DBusGreeter.hrenamed
The content is the same.
plugins/IntegratedLightDM/DBusGreeterList.cpp → plugins/LightDM/DBusGreeterList.cpprenamed+3−3
@@ -43,10 +43,10 @@ bool DBusGreeterList::entryIsLocked() const
43 return !m_greeter->promptless();
43 return !m_greeter->promptless();
46−void DBusGreeterList::authenticationUserChangedHandler(const QString &user)
46+void DBusGreeterList::authenticationUserChangedHandler()
48− notifyPropertyChanged(QStringLiteral("ActiveEntry"), user);
48+ notifyPropertyChanged(QStringLiteral("ActiveEntry"), m_greeter->authenticationUser());
49− Q_EMIT EntrySelected(user);
49+ Q_EMIT EntrySelected(m_greeter->authenticationUser());
52void DBusGreeterList::promptlessChangedHandler()
52void DBusGreeterList::promptlessChangedHandler()
plugins/IntegratedLightDM/DBusGreeterList.h → plugins/LightDM/DBusGreeterList.hrenamed+1−1
@@ -47,7 +47,7 @@ Q_SIGNALS:
47 void entryIsLockedChanged();
47 void entryIsLockedChanged();
49private Q_SLOTS:
49private Q_SLOTS:
50− void authenticationUserChangedHandler(const QString &user);
50+ void authenticationUserChangedHandler();
51 void promptlessChangedHandler();
51 void promptlessChangedHandler();
plugins/LightDM/FullLightDM/CMakeLists.txtnew file+32
@@ -0,0 +1,32 @@
1+pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-3)
3+set(PLUGIN_CLASSNAME "FullLightDM")
5+add_definitions(-DFULL_LIGHTDM)
9+ ${CMAKE_CURRENT_BINARY_DIR}
14+ ${LIBLIGHTDM_INCLUDE_DIRS}
17+foreach(source_file ${QMLPLUGIN_SRC})
18+ list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
21+add_library(FullLightDM-qml MODULE
22+ ${RELATIVE_QMLPLUGIN_SRC}
25+target_link_libraries(FullLightDM-qml
27+ ${LIBLIGHTDM_LDFLAGS}
28+ ${LIBUSERMETRICSOUTPUT_LDFLAGS}
29+ Qt5::DBus Qt5::Gui Qt5::Qml
32+add_unity8_plugin(FullLightDM 0.1 LightDM/FullLightDM TARGETS FullLightDM-qml)
plugins/LightDM/FullLightDM/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module LightDM.FullLightDM
3+typeinfo FullLightDM.qmltypes
plugins/LightDM/Greeter.cppnew file+279
@@ -0,0 +1,279 @@
2+ * Copyright (C) 2013-2017 Canonical, Ltd.
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.
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.
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/>.
19+#include "GreeterPrivate.h"
20+#include <QCoreApplication>
23+static Greeter *singleton = nullptr;
25+GreeterPrivate::GreeterPrivate(Greeter* parent)
26+ : m_greeter(new QLightDM::Greeter(parent)),
29+ everResponded(false),
35+Greeter::Greeter(QObject* parent)
37+ d_ptr(new GreeterPrivate(this))
41+ connect(d->m_greeter, &QLightDM::Greeter::showMessage,
42+ this, &Greeter::showMessageFilter);
43+ connect(d->m_greeter, &QLightDM::Greeter::showPrompt,
44+ this, &Greeter::showPromptFilter);
45+ connect(d->m_greeter, &QLightDM::Greeter::authenticationComplete,
46+ this, &Greeter::authenticationCompleteFilter);
48+ // Don't get stuck waiting for PAM as we shut down.
49+ connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
50+ d->m_greeter, &QLightDM::Greeter::cancelAuthentication);
52+ d->m_greeter->connectSync();
60+Greeter *Greeter::instance()
63+ singleton = new Greeter;
68+PromptsModel *Greeter::promptsModel()
74+bool Greeter::isActive() const
80+void Greeter::setIsActive(bool active)
83+ if (d->m_active != active) {
84+ d->m_active = active;
85+ Q_EMIT isActiveChanged();
89+bool Greeter::isAuthenticated() const
92+ return d->m_greeter->isAuthenticated();
95+QString Greeter::authenticationUser() const
98+ return d->cachedAuthUser;
101+void Greeter::checkAuthenticationUser()
104+ if (d->cachedAuthUser != d->m_greeter->authenticationUser()) {
105+ d->cachedAuthUser = d->m_greeter->authenticationUser();
106+ Q_EMIT authenticationUserChanged();
110+QString Greeter::defaultSessionHint() const
113+ return d->m_greeter->defaultSessionHint();
116+bool Greeter::promptless() const
119+ return d->promptless;
122+QString Greeter::selectUser() const
125+ if (hasGuestAccount() && d->m_greeter->selectGuestHint()) {
126+ return QStringLiteral("*guest");
128+ return d->m_greeter->selectUserHint();
132+bool Greeter::hasGuestAccount() const
135+ return d->m_greeter->hasGuestAccountHint();
138+bool Greeter::showManualLoginHint() const
141+ return d->m_greeter->showManualLoginHint();
144+bool Greeter::hideUsersHint() const
147+ return d->m_greeter->hideUsersHint();
150+void Greeter::authenticate(const QString &username)
154+ d->responded = false;
155+ d->everResponded = false;
156+ if (d->promptless) {
157+ d->promptless = false;
158+ Q_EMIT promptlessChanged();
161+ if (authenticationUser() == username) {
162+ d->prompts = d->leftovers;
164+ d->leftovers.clear();
166+ if (username == QStringLiteral("*guest")) {
167+ d->m_greeter->authenticateAsGuest();
168+ } else if (username == QStringLiteral("*other")) {
169+ d->m_greeter->authenticate(nullptr);
171+ d->m_greeter->authenticate(username);
174+ Q_EMIT authenticationStarted();
175+ Q_EMIT isAuthenticatedChanged();
176+ checkAuthenticationUser();
179+void Greeter::respond(const QString &response)
182+ d->responded = true;
183+ d->everResponded = true;
184+ d->m_greeter->respond(response);
187+bool Greeter::startSessionSync(const QString &session)
190+ return d->m_greeter->startSessionSync(session);
193+void Greeter::showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type)
197+ checkAuthenticationUser(); // may have changed in liblightdm
199+ bool isDefaultPrompt = (text == dgettext("Linux-PAM", "Password: "));
200+ bool isSecret = type == QLightDM::Greeter::PromptTypeSecret;
202+ QString trimmedText;
203+ if (!isDefaultPrompt)
204+ trimmedText = text.trimmed();
206+ // Strip prompt of any colons at the end
207+ if (trimmedText.endsWith(':') || trimmedText.endsWith(QStringLiteral(":"))) {
208+ trimmedText.chop(1);
211+ if (trimmedText == "login") {
212+ // 'login' is provided untranslated by LightDM when asking for a manual
214+ trimmedText = gettext("Username");
219+ d->responded = false;
222+ d->prompts.append(trimmedText, isSecret ? PromptsModel::Secret : PromptsModel::Question);
225+void Greeter::showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type)
229+ checkAuthenticationUser(); // may have changed in liblightdm
231+ bool isError = type == QLightDM::Greeter::MessageTypeError;
235+ d->responded = false;
237+ d->prompts.append(text, isError? PromptsModel::Error : PromptsModel::Message);
240+void Greeter::authenticationCompleteFilter()
244+ Q_EMIT isAuthenticatedChanged();
246+ bool automatic = !d->everResponded;
247+ bool pamHasLeftoverMessages = !d->prompts.hasPrompt() && d->prompts.rowCount() > 0;
249+ if (isAuthenticated() && automatic) {
250+ d->promptless = true;
251+ Q_EMIT promptlessChanged();
254+ if (!isAuthenticated()) {
255+ if (pamHasLeftoverMessages) {
256+ d->leftovers = d->prompts; // Prefer PAM's messages
257+ } else if (automatic) {
258+ d->leftovers.append(gettext("Failed to authenticate"), PromptsModel::Error);
260+ d->leftovers.append(gettext("Invalid password, please try again"), PromptsModel::Error);
262+ } else if (pamHasLeftoverMessages) {
263+ automatic = true; // treat this successful login as automatic, so user sees message
264+ d->leftovers = d->prompts;
268+ d->prompts = d->leftovers; // OK, we'll just use these now
269+ d->leftovers.clear();
270+ d->prompts.append(isAuthenticated() ? gettext("Log In") : gettext("Retry"),
271+ PromptsModel::Button);
274+ if (isAuthenticated()) {
275+ Q_EMIT loginSuccess(automatic);
277+ Q_EMIT loginError(automatic);
plugins/IntegratedLightDM/Greeter.h → plugins/LightDM/Greeter.hrenamed+21−11
@@ -1,5 +1,5 @@
2− * Copyright (C) 2012,2013 Canonical, Ltd.
2+ * Copyright (C) 2012-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -13,7 +13,6 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16− * Authors: Michael Terry <michael.terry@canonical.com>
19/* This class is a really tiny filter around QLightDM::Greeter. There are some
18/* This class is a really tiny filter around QLightDM::Greeter. There are some
@@ -22,13 +21,13 @@
22 such edits in the future, and by inserting ourselves here, we have more
21 such edits in the future, and by inserting ourselves here, we have more
23 control. */
22 control. */
25−#ifndef UNITY_GREETER_H
24+#pragma once
26−#define UNITY_GREETER_H
28#include <QLightDM/Greeter>
26#include <QLightDM/Greeter>
29#include <QtCore/QObject>
27#include <QtCore/QObject>
31class GreeterPrivate;
29class GreeterPrivate;
33class Greeter : public QObject
32class Greeter : public QObject
@@ -37,15 +36,25 @@ class Greeter : public QObject
37 Q_PROPERTY(bool active READ isActive WRITE setIsActive NOTIFY isActiveChanged)
36 Q_PROPERTY(bool active READ isActive WRITE setIsActive NOTIFY isActiveChanged)
38 Q_PROPERTY(bool authenticated READ isAuthenticated NOTIFY isAuthenticatedChanged)
37 Q_PROPERTY(bool authenticated READ isAuthenticated NOTIFY isAuthenticatedChanged)
39 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
38 Q_PROPERTY(QString authenticationUser READ authenticationUser NOTIFY authenticationUserChanged)
39+ Q_PROPERTY(QString defaultSession READ defaultSessionHint CONSTANT)
40 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
40 Q_PROPERTY(bool promptless READ promptless NOTIFY promptlessChanged)
41+ Q_PROPERTY(QString selectUser READ selectUser CONSTANT)
43− explicit Greeter(QObject* parent=0);
44+ static Greeter *instance();
45 bool isActive() const;
47 bool isActive() const;
46 bool isAuthenticated() const;
48 bool isAuthenticated() const;
47 QString authenticationUser() const;
49 QString authenticationUser() const;
50+ QString defaultSessionHint() const;
48 bool promptless() const;
51 bool promptless() const;
52+ QString selectUser() const;
53+ bool hasGuestAccount() const;
54+ bool showManualLoginHint() const;
55+ bool hideUsersHint() const;
57+ PromptsModel *promptsModel();
50public Q_SLOTS:
59public Q_SLOTS:
51 void authenticate(const QString &username=QString());
60 void authenticate(const QString &username=QString());
@@ -54,21 +63,23 @@ public Q_SLOTS:
54 void setIsActive(bool isActive);
63 void setIsActive(bool isActive);
57− void showMessage(const QString &text, bool isError);
58− void showPrompt(const QString &text, bool isSecret, bool isDefaultPrompt);
59− void authenticationComplete();
60− void authenticationUserChanged(const QString &user);
66+ void authenticationUserChanged();
61 void isActiveChanged();
67 void isActiveChanged();
62 void isAuthenticatedChanged();
68 void isAuthenticatedChanged();
63 void promptlessChanged();
69 void promptlessChanged();
64 void showGreeter();
70 void showGreeter();
65 void hideGreeter();
71 void hideGreeter();
72+ void loginError(bool automatic);
73+ void loginSuccess(bool automatic);
74+ void authenticationStarted(); // useful for testing
67 // This signal is emitted by external agents like indicators, and the UI
76 // This signal is emitted by external agents like indicators, and the UI
68 // should switch to this user if possible.
77 // should switch to this user if possible.
69 void requestAuthenticationUser(const QString &user);
78 void requestAuthenticationUser(const QString &user);
81+ explicit Greeter(QObject* parent=0);
72 GreeterPrivate * const d_ptr;
83 GreeterPrivate * const d_ptr;
74 Q_DECLARE_PRIVATE(Greeter)
85 Q_DECLARE_PRIVATE(Greeter)
@@ -77,6 +88,5 @@ private Q_SLOTS:
77 void showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type);
88 void showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type);
78 void showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type);
89 void showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type);
79 void authenticationCompleteFilter();
90 void authenticationCompleteFilter();
91+ void checkAuthenticationUser();
plugins/IntegratedLightDM/GreeterPrivate.h → plugins/LightDM/GreeterPrivate.hrenamed+13−7
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2015-2017 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -14,10 +14,14 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#ifndef UNITY_GREETER_PRIVATE_H
17+#pragma once
18−#define UNITY_GREETER_PRIVATE_H
19+#include "PromptsModel.h"
20−#include <QLightDM/Greeter>
22+namespace QLightDM {
22class GreeterPrivate
26class GreeterPrivate
@@ -26,8 +30,12 @@ public:
27 QLightDM::Greeter *m_greeter;
31 QLightDM::Greeter *m_greeter;
28 bool m_active;
32 bool m_active;
29− bool wasPrompted;
33+ PromptsModel prompts;
34+ PromptsModel leftovers; // prompts to show during next auth for same user
30 bool promptless;
37 bool promptless;
38+ QString cachedAuthUser;
33 Greeter * const q_ptr;
41 Greeter * const q_ptr;
@@ -35,5 +43,3 @@ protected:
36 Q_DECLARE_PUBLIC(Greeter)
44 Q_DECLARE_PUBLIC(Greeter)
39−#endif // UNITY_GREETER_PRIVATE_H
plugins/LightDM/IntegratedLightDM/CMakeLists.txtnew file+33
@@ -0,0 +1,33 @@
1+set(PLUGIN_CLASSNAME "IntegratedLightDM")
3+add_definitions(-DINTEGRATED_LIGHTDM)
5+foreach(include_directory ${QMLPLUGIN_INCLUDES})
6+ list(APPEND RELATIVE_QMLPLUGIN_INCLUDES ../${include_directory})
11+ ${QMLPLUGIN_INCLUDES}
12+ ${libunity8-private_SOURCE_DIR}
13+ ${CMAKE_CURRENT_BINARY_DIR}
16+foreach(source_file ${QMLPLUGIN_SRC})
17+ list(APPEND RELATIVE_QMLPLUGIN_SRC ../${source_file})
20+add_library(IntegratedLightDM-qml MODULE
21+ ${RELATIVE_QMLPLUGIN_SRC}
24+target_link_libraries(IntegratedLightDM-qml
27+ ${LIBUSERMETRICSOUTPUT_LDFLAGS}
28+ Qt5::DBus Qt5::Gui Qt5::Qml
31+add_unity8_plugin(IntegratedLightDM 0.1 LightDM/IntegratedLightDM TARGETS IntegratedLightDM-qml)
33+add_subdirectory(liblightdm)
tests/mocks/IntegratedLightDM/QLightDM/Greeter → plugins/LightDM/IntegratedLightDM/QLightDM/Greeterrenamed+1−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
qml/Dash/ScopeSettings/ScopeSettingNumber.qml → plugins/LightDM/IntegratedLightDM/QLightDM/SessionsModelrenamed+2−6
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -14,8 +14,4 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−import QtQuick 2.4
17+#include "../liblightdm/SessionsModel.h"
tests/mocks/IntegratedLightDM/QLightDM/UsersModel → plugins/LightDM/IntegratedLightDM/QLightDM/UsersModelrenamed+1−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
plugins/IntegratedLightDM/liblightdm/CMakeLists.txt → plugins/LightDM/IntegratedLightDM/liblightdm/CMakeLists.txtrenamed+7−6
@@ -2,8 +2,10 @@ pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
3set(LibLightDM_SOURCES
3set(LibLightDM_SOURCES
4 Greeter.cpp
4 Greeter.cpp
5 UsersModel.cpp
6 UsersModel.cpp
6 GreeterPrivate.cpp
7 GreeterPrivate.cpp
8+ SessionsModelPrivate.cpp
7 UsersModelPrivate.cpp
9 UsersModelPrivate.cpp
8 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
10 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
9 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
11 ${CMAKE_SOURCE_DIR}/plugins/Utils/qvariantlistmodel.cpp
@@ -24,30 +26,29 @@ target_link_libraries(integratedLightDM
24 ${GLIB_LIBRARIES}
26 ${GLIB_LIBRARIES}
25 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
27 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
29+ Qt5::Concurrent Qt5::DBus Qt5::Gui
28target_link_libraries(integratedLightDMSession
31target_link_libraries(integratedLightDMSession
29 ${GLIB_LIBRARIES}
32 ${GLIB_LIBRARIES}
30 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
33 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
35+ Qt5::Concurrent Qt5::DBus Qt5::Gui
33target_link_libraries(MockLightDM-demo-shared
37target_link_libraries(MockLightDM-demo-shared
34 ${GLIB_LIBRARIES}
38 ${GLIB_LIBRARIES}
35 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
39 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
41+ Qt5::Concurrent Qt5::DBus Qt5::Gui
39−qt5_use_modules(integratedLightDM Concurrent DBus Gui)
40−qt5_use_modules(integratedLightDMSession Concurrent DBus Gui)
41−qt5_use_modules(MockLightDM-demo-shared Concurrent DBus Gui)
43set_target_properties(integratedLightDM PROPERTIES
44set_target_properties(integratedLightDM PROPERTIES
44 COMPILE_FLAGS "-DSM_BUSNAME=systemBus -fPIC")
45 COMPILE_FLAGS "-DSM_BUSNAME=systemBus -fPIC")
45set_target_properties(integratedLightDMSession PROPERTIES
46set_target_properties(integratedLightDMSession PROPERTIES
46 COMPILE_FLAGS "-DSM_BUSNAME=sessionBus -fPIC")
47 COMPILE_FLAGS "-DSM_BUSNAME=sessionBus -fPIC")
47set_target_properties(MockLightDM-demo-shared PROPERTIES
48set_target_properties(MockLightDM-demo-shared PROPERTIES
48 COMPILE_FLAGS "-DSM_BUSNAME=systemBus"
49 COMPILE_FLAGS "-DSM_BUSNAME=systemBus"
49− OUTPUT_NAME lightdm-qt5-2)
50+ OUTPUT_NAME lightdm-qt5-3)
51install(TARGETS MockLightDM-demo-shared
52install(TARGETS MockLightDM-demo-shared
52− DESTINATION ${SHELL_INSTALL_QML}/mocks/IntegratedLightDM/demo
53+ DESTINATION ${SHELL_INSTALL_QML}/mocks/LightDM/IntegratedLightDM/demo
plugins/IntegratedLightDM/liblightdm/Greeter.cpp → plugins/LightDM/IntegratedLightDM/liblightdm/Greeter.cpprenamed+6−8
@@ -49,7 +49,7 @@ QString Greeter::authenticationUser() const
50bool Greeter::hasGuestAccountHint() const
50bool Greeter::hasGuestAccountHint() const
52− return true;
52+ return false;
55QString Greeter::getHint(const QString &name) const
55QString Greeter::getHint(const QString &name) const
@@ -70,15 +70,10 @@ bool Greeter::hideUsersHint() const
71bool Greeter::showManualLoginHint() const
71bool Greeter::showManualLoginHint() const
73− return true;
73+ return false;
76bool Greeter::showRemoteLoginHint() const
76bool Greeter::showRemoteLoginHint() const
81−bool Greeter::lockHint () const
83 return false;
78 return false;
@@ -151,7 +146,10 @@ void Greeter::authenticateRemote(const QString &session, const QString &username
153void Greeter::cancelAuthentication()
148void Greeter::cancelAuthentication()
151+ d->cancelAuthentication();
156void Greeter::setLanguage (const QString &language)
154void Greeter::setLanguage (const QString &language)
plugins/IntegratedLightDM/liblightdm/Greeter.h → plugins/LightDM/IntegratedLightDM/liblightdm/Greeter.hrenamed+2−4
@@ -45,20 +45,19 @@ class Q_DECL_EXPORT Greeter : public QObject
46 Q_PROPERTY(QString hostname READ hostname CONSTANT)
46 Q_PROPERTY(QString hostname READ hostname CONSTANT)
47 Q_PROPERTY(bool hasGuestAccount READ hasGuestAccountHint CONSTANT)
47 Q_PROPERTY(bool hasGuestAccount READ hasGuestAccountHint CONSTANT)
48− Q_PROPERTY(bool locked READ lockHint CONSTANT)
50− Q_ENUMS(PromptType MessageType)
53 enum PromptType {
50 enum PromptType {
54 PromptTypeQuestion,
51 PromptTypeQuestion,
55 PromptTypeSecret
52 PromptTypeSecret
58 enum MessageType {
56 enum MessageType {
59 MessageTypeInfo,
57 MessageTypeInfo,
60 MessageTypeError
58 MessageTypeError
63 explicit Greeter(QObject* parent=0);
62 explicit Greeter(QObject* parent=0);
64 virtual ~Greeter();
63 virtual ~Greeter();
@@ -68,7 +67,6 @@ public:
68 bool hideUsersHint() const;
67 bool hideUsersHint() const;
69 bool showManualLoginHint() const;
68 bool showManualLoginHint() const;
70 bool showRemoteLoginHint() const;
69 bool showRemoteLoginHint() const;
71− bool lockHint () const;
72 bool hasGuestAccountHint() const;
70 bool hasGuestAccountHint() const;
73 QString selectUserHint() const;
71 QString selectUserHint() const;
74 bool selectGuestHint() const;
72 bool selectGuestHint() const;
plugins/IntegratedLightDM/liblightdm/GreeterPrivate.cpp → plugins/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.cpprenamed+28−24
@@ -50,8 +50,7 @@ public:
51 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
51 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
53− connect(&futureWatcher, &QFutureWatcher<int>::finished,
53+ connect(&futureWatcher, &QFutureWatcher<int>::finished, this, &GreeterImpl::finishPam);
54− this, &GreeterImpl::finishPam);
55 connect(this, SIGNAL(showMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)),
54 connect(this, SIGNAL(showMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)),
56 this, SLOT(handleMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)));
55 this, SLOT(handleMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)));
57 // This next connect is how we pass ResponseFutures between threads
56 // This next connect is how we pass ResponseFutures between threads
@@ -207,6 +206,28 @@ public Q_SLOTS:
211+ if (pamHandle != nullptr) {
212+ QFuture<int> pamFuture = futureWatcher.future();
213+ pam_handle *handle = pamHandle;
214+ pamHandle = nullptr; // to disable normal finishPam() handling
217+ // Note the empty loop, we just want to clear the futures queue.
218+ // Any further prompts from the pam thread will be immediately
219+ // responded to/dismissed in handlePrompt().
220+ while (respond(QString()));
222+ // Now let signal/slot handling happen so the thread can finish
223+ while (!pamFuture.isFinished()) {
224+ QCoreApplication::processEvents();
227+ pam_end(handle, PAM_CONV_ERR);
210Q_SIGNALS:
231Q_SIGNALS:
211 void showMessage(pam_handle *handle, QString text, QLightDM::Greeter::MessageType type);
232 void showMessage(pam_handle *handle, QString text, QLightDM::Greeter::MessageType type);
212 void showPrompt(pam_handle *handle, QString text, QLightDM::Greeter::PromptType type, QLightDM::GreeterImpl::ResponseFuture response);
233 void showPrompt(pam_handle *handle, QString text, QLightDM::Greeter::PromptType type, QLightDM::GreeterImpl::ResponseFuture response);
@@ -248,28 +269,6 @@ private Q_SLOTS:
253− if (pamHandle != nullptr) {
254− QFuture<int> pamFuture = futureWatcher.future();
255− pam_handle *handle = pamHandle;
256− pamHandle = nullptr; // to disable normal finishPam() handling
259− // Note the empty loop, we just want to clear the futures queue.
260− // Any further prompts from the pam thread will be immediately
261− // responded to/dismissed in handlePrompt().
262− while (respond(QString()));
264− // Now let signal/slot handling happen so the thread can finish
265− while (!pamFuture.isFinished()) {
266− QCoreApplication::processEvents();
269− pam_end(handle, PAM_CONV_ERR);
273 Greeter *greeter;
272 Greeter *greeter;
274 GreeterPrivate *greeterPrivate;
273 GreeterPrivate *greeterPrivate;
275 pam_handle* pamHandle;
274 pam_handle* pamHandle;
@@ -300,6 +299,11 @@ void GreeterPrivate::handleRespond(const QString &response)
300 m_impl->respond(response);
299 m_impl->respond(response);
302+void GreeterPrivate::cancelAuthentication()
304+ m_impl->cancelPam();
305#include "GreeterPrivate.moc"
309#include "GreeterPrivate.moc"
plugins/IntegratedLightDM/liblightdm/GreeterPrivate.h → plugins/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.hrenamed+1
@@ -38,6 +38,7 @@ public:
39 void handleAuthenticate();
39 void handleAuthenticate();
40 void handleRespond(const QString &response);
40 void handleRespond(const QString &response);
41+ void cancelAuthentication();
43 GreeterImpl *m_impl; // if the backend needs more private data
44 GreeterImpl *m_impl; // if the backend needs more private data
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModel.cppnew file+87
@@ -0,0 +1,87 @@
2+ * Copyright (C) 2015 Canonical, Ltd.
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.
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.
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/>.
19+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
20+ * CHANGES MADE HERE MUST BE REFLECTED ON THE MOCK LIB
21+ * COUNTERPART IN tests/mocks/LightDM/IntegratedLightDM/liblightdm
22+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
24+// LightDM currently is Qt4 compatible, and so doesn't define setRoleNames.
25+// To use the same method of setting role name that it does, we
26+// set our compatibility to Qt4 here too.
27+#define QT_DISABLE_DEPRECATED_BEFORE QT_VERSION_CHECK(4, 0, 0)
29+#include "SessionsModel.h"
30+#include "SessionsModelPrivate.h"
31+#include <QtCore/QDir>
32+#include <QtCore/QString>
37+SessionsModel::SessionsModel(QObject* parent) :
38+ QAbstractListModel(parent),
39+ d_ptr(new SessionsModelPrivate(this))
41+ m_roleNames = QAbstractListModel::roleNames();
42+ m_roleNames[KeyRole] = "key";
43+ m_roleNames[TypeRole] = "type";
46+SessionsModel::~SessionsModel()
51+QVariant SessionsModel::data(const QModelIndex& index, int role) const
53+ Q_D(const SessionsModel);
55+ if(!index.isValid()) {
59+ int row = index.row();
62+ case QLightDM::SessionsModel::KeyRole:
63+ return d->sessionItems[row].key;
64+ case Qt::DisplayRole:
65+ return d->sessionItems[row].name;
71+QHash<int, QByteArray> SessionsModel::roleNames() const
76+int SessionsModel::rowCount(const QModelIndex& parent) const
78+ Q_D(const SessionsModel);
80+ if (parent.isValid()) {
82+ } else { // parent is root
83+ return d->sessionItems.size();
87+} // namespace QLightDM
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModel.hnew file+72
@@ -0,0 +1,72 @@
2+ * Copyright (C) 2015 Canonical, Ltd.
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.
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.
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/>.
18+#ifndef UNITY_INTEGRATED_SESSIONSMODEL_H
19+#define UNITY_INTEGRATED_SESSIONSMODEL_H
21+#include <QtCore/QAbstractListModel>
22+#include <QtCore/QString>
24+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
25+ * CHANGES MADE HERE MUST BE REFLECTED ON THE MOCK LIB
26+ * COUNTERPART IN tests/mocks/LightDM/IntegratedLightDM/liblightdm
27+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
29+// This is taken from liblightdm and modified to confirm to our syle conventions
32+class SessionsModelPrivate;
34+class Q_DECL_EXPORT SessionsModel : public QAbstractListModel
40+ enum SessionModelRoles {
41+ //name is exposed as Qt::DisplayRole
42+ //comment is exposed as Qt::TooltipRole
43+ KeyRole = Qt::UserRole,
44+ IdRole = KeyRole, /** Deprecated */
47+ Q_ENUM(SessionModelRoles)
55+ explicit SessionsModel(QObject* parent=0); /** Deprecated. Loads local sessions*/
56+ explicit SessionsModel(SessionsModel::SessionType, QObject* parent=0);
57+ virtual ~SessionsModel();
59+ QHash<int, QByteArray> roleNames() const override;
60+ int rowCount(const QModelIndex& parent) const override;
61+ QVariant data(const QModelIndex& index, int role) const override;
64+ SessionsModelPrivate* const d_ptr;
67+ QHash<int, QByteArray> m_roleNames;
68+ Q_DECLARE_PRIVATE(SessionsModel)
72+#endif // UNITY_INTEGRATED_SESSIONSMODEL_H
plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.cppnew file+36
@@ -0,0 +1,36 @@
2+ * Copyright (C) 2015 Canonical, Ltd.
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.
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.
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/>.
18+#include "SessionsModelPrivate.h"
22+#include <QStringList>
27+SessionsModelPrivate::SessionsModelPrivate(SessionsModel* parent)
30+ // Since this model is never visible, as there is only 1 session,
31+ // just use the session name as the key
32+ QString sessionName = qgetenv("XDG_SESSION_DESKTOP");
33+ sessionItems.append({sessionName, "", sessionName, ""});
36+} // namespace QLightDM
tests/mocks/Unity/fake_filters.h → plugins/LightDM/IntegratedLightDM/liblightdm/SessionsModelPrivate.hrenamed+26−18
@@ -12,35 +12,43 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#ifndef FAKE_FILTERS_H
18+#ifndef UNITY_INTEGRATED_SESSIONSMODEL_PRIVATE_H
18−#define FAKE_FILTERS_H
19+#define UNITY_INTEGRATED_SESSIONSMODEL_PRIVATE_H
20−#include <unity/shell/scopes/FiltersInterface.h>
21+#include <QtCore/QList>
21−#include <unity/shell/scopes/FilterBaseInterface.h>
22+#include <QtCore/QString>
23−class Filters : public unity::shell::scopes::FiltersInterface
24+namespace QLightDM
25− Q_OBJECT
26+class SessionsModel;
28− Filters(QObject* parent);
31+ QString key;
32+ QString type; // unused
34+ QString comment; // unused
30− int rowCount(const QModelIndex &parent) const override;
37+class SessionsModelPrivate
31− QVariant data(const QModelIndex &index, int role) const override;
38+{
40+ explicit SessionsModelPrivate(SessionsModel* parent=0);
41+ virtual ~SessionsModelPrivate() = default;
33− // Mock API
43+ QList<SessionItem> sessionItems;
34− int activeFiltersCount() const;
35− void addFakeFilters();
36− void addFilter(unity::shell::scopes::FilterBaseInterface* f);
38−Q_SIGNALS:
45+protected:
39− void activeFiltersCountChanged();
46+ SessionsModel* const q_ptr;
42−
49+ Q_DECLARE_PUBLIC(SessionsModel)
43− QVector<unity::shell::scopes::FilterBaseInterface*> m_filters;
46−#endif
52+} // namespace QLightDM
54+#endif // UNITY_INTEGRATED_SESSIONSMODEL_PRIVATE_H
plugins/IntegratedLightDM/liblightdm/UsersModel.cpp → plugins/LightDM/IntegratedLightDM/liblightdm/UsersModel.cpprenamed+4−3
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -40,8 +40,6 @@ UsersModel::UsersModel(QObject *parent) :
40 QAbstractListModel(parent),
40 QAbstractListModel(parent),
41 d_ptr(new UsersModelPrivate(this))
41 d_ptr(new UsersModelPrivate(this))
45 // Extend roleNames (we want to keep the "display" role)
43 // Extend roleNames (we want to keep the "display" role)
46 QHash<int, QByteArray> roles = roleNames();
44 QHash<int, QByteArray> roles = roleNames();
47 roles[NameRole] = "name";
45 roles[NameRole] = "name";
@@ -52,6 +50,7 @@ UsersModel::UsersModel(QObject *parent) :
52 roles[SessionRole] = "session";
50 roles[SessionRole] = "session";
53 roles[HasMessagesRole] = "hasMessages";
51 roles[HasMessagesRole] = "hasMessages";
54 roles[ImagePathRole] = "imagePath";
52 roles[ImagePathRole] = "imagePath";
53+ roles[UidRole] = "uid";
55 setRoleNames(roles);
54 setRoleNames(roles);
57 connect(d_ptr, &UsersModelPrivate::dataChanged, this, [this](int i) {
56 connect(d_ptr, &UsersModelPrivate::dataChanged, this, [this](int i) {
@@ -101,6 +100,8 @@ QVariant UsersModel::data(const QModelIndex &index, int role) const
101 return d->entries[row].has_messages;
100 return d->entries[row].has_messages;
102 case UsersModel::ImagePathRole:
101 case UsersModel::ImagePathRole:
103 return "";
102 return "";
103+ case UsersModel::UidRole:
104+ return d->entries[row].uid;
105 return QVariant();
106 return QVariant();
plugins/IntegratedLightDM/liblightdm/UsersModel.h → plugins/LightDM/IntegratedLightDM/liblightdm/UsersModel.hrenamed+3−3
@@ -37,8 +37,6 @@ class Q_DECL_EXPORT UsersModel : public QAbstractListModel
40− Q_ENUMS(UserModelRoles)
43 explicit UsersModel(QObject *parent = 0);
41 explicit UsersModel(QObject *parent = 0);
44 virtual ~UsersModel() = default;
42 virtual ~UsersModel() = default;
@@ -50,8 +48,10 @@ public:
50 SessionRole,
48 SessionRole,
51 HasMessagesRole,
49 HasMessagesRole,
52 ImagePathRole,
50 ImagePathRole,
53− BackgroundPathRole
51+ BackgroundPathRole,
54+ Q_ENUM(UserModelRoles)
56 int rowCount(const QModelIndex &parent) const override;
56 int rowCount(const QModelIndex &parent) const override;
57 QVariant data(const QModelIndex &index, int role) const override;
57 QVariant data(const QModelIndex &index, int role) const override;
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp → plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.cpprenamed+5−3
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
26#include <QDir>
26#include <QDir>
27#include <QSettings>
27#include <QSettings>
28#include <QStringList>
28#include <QStringList>
30namespace QLightDM
31namespace QLightDM
@@ -37,6 +38,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
38 QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo");
39 QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo");
39 QString currentUser = g_get_user_name();
40 QString currentUser = g_get_user_name();
41+ uid_t currentUid = getuid();
41 if (demoFile.exists()) {
43 if (demoFile.exists()) {
42 QSettings settings(demoFile.filePath(), QSettings::NativeFormat);
44 QSettings settings(demoFile.filePath(), QSettings::NativeFormat);
@@ -46,10 +48,10 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
46 Q_FOREACH(const QString &user, users)
48 Q_FOREACH(const QString &user, users)
48 QString name = settings.value(user + "/name", user).toString();
50 QString name = settings.value(user + "/name", user).toString();
49− entries.append({user, name, 0, 0, false, false, 0, 0});
51+ entries.append({user, name, 0, 0, false, false, 0, 0, currentUid++});
52− entries.append({currentUser, 0, 0, 0, false, false, 0, 0});
54+ entries.append({currentUser, 0, 0, 0, false, false, 0, 0, currentUid});
54 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged,
56 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged,
55 this, [this](const QString &user) {
57 this, [this](const QString &user) {
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h → plugins/LightDM/IntegratedLightDM/liblightdm/UsersModelPrivate.hrenamed+2−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ public:
40 bool has_messages;
40 bool has_messages;
41 QString session;
41 QString session;
42 QString infographic;
42 QString infographic;
45class UsersModelPrivate : public QObject
46class UsersModelPrivate : public QObject
plugins/LightDM/IntegratedLightDM/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module LightDM.IntegratedLightDM
2+plugin IntegratedLightDM-qml
3+typeinfo IntegratedLightDM.qmltypes
plugins/LightDM/PromptsModel.cppnew file+97
@@ -0,0 +1,97 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
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.
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.
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/>.
18+#include "PromptsModel.h"
20+PromptsModel::PromptsModel(QObject* parent)
21+ : QAbstractListModel(parent)
23+ m_roleNames[TypeRole] = "type";
24+ m_roleNames[TextRole] = "text";
27+PromptsModel& PromptsModel::operator=(const PromptsModel &other)
30+ m_prompts = other.m_prompts;
32+ Q_EMIT countChanged();
36+int PromptsModel::rowCount(const QModelIndex &parent) const
38+ if (parent.isValid())
41+ return m_prompts.size();
44+QVariant PromptsModel::data(const QModelIndex &index, int role) const
46+ if (!index.isValid() || index.column() > 0 || index.row() >= m_prompts.size())
50+ case Qt::DisplayRole: // fallthrough
51+ case TextRole: return m_prompts[index.row()].prompt;
52+ case TypeRole: return m_prompts[index.row()].type;
53+ default: return QVariant();
57+QHash<int, QByteArray> PromptsModel::roleNames() const
62+void PromptsModel::prepend(const QString &text, PromptType type)
64+ beginInsertRows(QModelIndex(), 0, 0);
65+ m_prompts.prepend(PromptInfo{text, type});
68+ Q_EMIT countChanged();
71+void PromptsModel::append(const QString &text, PromptType type)
73+ beginInsertRows(QModelIndex(), m_prompts.size(), m_prompts.size());
74+ m_prompts.append(PromptInfo{text, type});
77+ Q_EMIT countChanged();
80+void PromptsModel::clear()
86+ Q_EMIT countChanged();
89+bool PromptsModel::hasPrompt() const
91+ Q_FOREACH(const PromptInfo &info, m_prompts) {
92+ if (info.type == PromptType::Secret || info.type == PromptType::Question) {
plugins/LightDM/PromptsModel.hnew file+70
@@ -0,0 +1,70 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
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.
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.
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/>.
20+#include <QAbstractListModel>
22+class PromptsModel : public QAbstractListModel
26+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
29+ enum PromptsModelRoles {
30+ TypeRole = Qt::UserRole,
33+ Q_ENUM(PromptsModelRoles)
44+ explicit PromptsModel(QObject* parent=0);
46+ PromptsModel& operator=(const PromptsModel &other);
48+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
49+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
50+ QHash<int, QByteArray> roleNames() const override;
52+ Q_INVOKABLE void prepend(const QString &text, PromptType type);
53+ Q_INVOKABLE void append(const QString &text, PromptType type);
57+ bool hasPrompt() const;
68+ QList<PromptInfo> m_prompts;
69+ QHash<int, QByteArray> m_roleNames;
plugins/LightDM/SessionsModel.cppnew file+135
@@ -0,0 +1,135 @@
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
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.
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.
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/>.
18+#include "SessionsModel.h"
19+#include <QtCore/QFile>
20+#include <QtCore/QSortFilterProxyModel>
22+QHash<int, QByteArray> SessionsModel::roleNames() const
27+int SessionsModel::rowCount(const QModelIndex& parent) const
29+ return m_model->rowCount(parent);
32+QList<QUrl> SessionsModel::iconSearchDirectories() const
34+ return m_iconSearchDirectories;
37+void SessionsModel::setIconSearchDirectories(const QList<QUrl> searchDirectories)
39+ // QML gives us a url with file:// prepended which breaks QFile::exists()
40+ // so convert the url to a local file
41+ QList<QUrl> localList = {};
42+ Q_FOREACH(const QUrl& searchDirectory, searchDirectories)
44+ localList.append(searchDirectory.toLocalFile());
46+ m_iconSearchDirectories = localList;
47+ Q_EMIT iconSearchDirectoriesChanged();
50+QUrl SessionsModel::iconUrl(const QString sessionKey) const
52+ Q_FOREACH(const QUrl& searchDirectory, m_iconSearchDirectories)
54+ // This is an established icon naming convention
55+ QString customIconUrl = searchDirectory.toString(QUrl::StripTrailingSlash) +
56+ "/custom_" + sessionKey + "_badge.png";
57+ QString iconUrl = searchDirectory.toString(QUrl::StripTrailingSlash) +
58+ "/" + sessionKey + "_badge.png";
60+ QFile customIconFile(customIconUrl);
61+ QFile iconFile(iconUrl);
62+ if (customIconFile.exists()) {
63+ return QUrl(customIconUrl);
64+ } else if (iconFile.exists()) {
65+ return QUrl(iconUrl);
67+ // Search the legacy way
68+ QString path = searchDirectory.toString(QUrl::StripTrailingSlash) + "/";
69+ bool iconFound = false;
70+ if (sessionKey == "ubuntu" || sessionKey == "ubuntu-2d") {
71+ path += "ubuntu_badge.png";
74+ sessionKey == "gnome-classic" ||
75+ sessionKey == "gnome-flashback-compiz" ||
76+ sessionKey == "gnome-flashback-metacity" ||
77+ sessionKey == "gnome-shell" ||
78+ sessionKey == "gnome-wayland" ||
79+ sessionKey == "gnome"
81+ path += "gnome_badge.png";
83+ } else if (sessionKey == "plasma") {
84+ path += "kde_badge.png";
86+ } else if (sessionKey == "xterm") {
87+ path += "recovery_console_badge.png";
89+ } else if (sessionKey == "remote-login") {
90+ path += "remote_login_help.png";
94+ if (QFile(path).exists() && iconFound) {
100+ // FIXME make this smarter
101+ return QUrl("./graphics/session_icons/unknown_badge.png");
104+QVariant SessionsModel::data(const QModelIndex& index, int role) const
107+ case SessionsModel::IconRole:
108+ return iconUrl(m_model->data(index, QLightDM::SessionsModel::KeyRole).toString());
110+ return m_model->data(index, role);
114+SessionsModel::SessionsModel(QObject* parent)
115+ : UnitySortFilterProxyModelQML(parent)
117+ // Add a custom IconRole that isn't in either of the lightdm implementations
118+ m_model = new QLightDM::SessionsModel(this);
119+ m_roleNames = m_model->roleNames();
120+ m_roleNames[IconRole] = "icon_url";
122+ // Update search locations to use $SNAP prefix if specified
123+ auto snapRoot = QFile::decodeName(qgetenv("SNAP"));
124+ if (!snapRoot.isEmpty()) {
125+ for (int i = 0; i < m_iconSearchDirectories.size(); i++) {
126+ m_iconSearchDirectories[i] = snapRoot + m_iconSearchDirectories[i].path();
131+ setSortCaseSensitivity(Qt::CaseInsensitive);
132+ setSortLocaleAware(true);
133+ setSortRole(Qt::DisplayRole);
plugins/LightDM/SessionsModel.hnew file+66
@@ -0,0 +1,66 @@
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
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.
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.
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/>.
20+#include <unitysortfilterproxymodelqml.h>
21+#include <QLightDM/SessionsModel>
22+#include <QtCore/QHash>
23+#include <QtCore/QObject>
24+#include <QtCore/QUrl>
26+class SessionsModel : public UnitySortFilterProxyModelQML
30+ Q_PROPERTY(QList<QUrl> iconSearchDirectories READ iconSearchDirectories
31+ WRITE setIconSearchDirectories NOTIFY iconSearchDirectoriesChanged)
34+ void iconSearchDirectoriesChanged();
37+ enum SessionModelRoles {
38+ /* This is tricky / ugly. Since we are ultimately chaining 3 enums together,
39+ * the _first_ value of this enum MUST be the _last_ value of
40+ * QLightDM::SessionsModel::SessionModelRoles and consquently, this must
41+ * also match the last value in the corresponding enum of the integrated lib
43+ TypeRole = QLightDM::SessionsModel::SessionModelRoles::TypeRole,
46+ Q_ENUM(SessionModelRoles)
48+ explicit SessionsModel(QObject* parent=nullptr);
50+ QHash<int, QByteArray> roleNames() const override;
51+ int rowCount(const QModelIndex& parent) const override;
52+ QVariant data(const QModelIndex& index, int role) const override;
53+ QList<QUrl> iconSearchDirectories() const;
54+ Q_INVOKABLE QUrl iconUrl(const QString sessionName) const;
56+ void setIconSearchDirectories(const QList<QUrl> searchDirectories);
59+ QLightDM::SessionsModel* m_model;
60+ QHash<int, QByteArray> m_roleNames;
61+ QList<QUrl> m_iconSearchDirectories{
62+ QUrl("/usr/share/unity8/Greeter/graphics/session_icons"),
63+ QUrl("/usr/local/share/unity-greeter"),
64+ QUrl("/usr/share/unity-greeter/")};
plugins/LightDM/UsersModel.cppnew file+238
@@ -0,0 +1,238 @@
2+ * Copyright (C) 2013,2015-2016 Canonical, Ltd.
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.
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.
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/>.
18+#include "UsersModel.h"
19+#include <QIdentityProxyModel>
20+#include <QLightDM/UsersModel>
24+// First, we define an internal class that wraps LightDM's UsersModel. This
25+// class will modify some of the data coming from LightDM. For example, we
26+// modify any empty Real Names into just normal Names. We also add optional
27+// rows, depending on configuration.
28+// (We can't modify the data directly in UsersModel below because it won't sort
29+// using the modified data.)
30+class MangleModel : public QIdentityProxyModel
35+ explicit MangleModel(QObject* parent=0);
37+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
38+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
39+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
47+ int sourceRowCount() const;
49+ void updateGuestRow();
50+ void updateManualRow();
51+ void updateCustomRows();
53+ void addCustomRow(const CustomRow &newRow);
54+ void removeCustomRow(const QString &rowName);
56+ QList<CustomRow> m_customRows;
57+ bool m_updatingCustomRows;
60+MangleModel::MangleModel(QObject* parent)
61+ : QIdentityProxyModel(parent)
62+ , m_updatingCustomRows(false)
64+ setSourceModel(new QLightDM::UsersModel(this));
68+ // Would be nice if there were a rowCountChanged signal in the base class.
69+ // We redo all custom rows on any row count change, because (A) some of
70+ // custom rows (manual login) use row count information and (B) when
71+ // testing, we use a modelReset signal as a way to indicate that a custom
72+ // row has been toggled off or on.
73+ connect(this, &QIdentityProxyModel::modelReset,
74+ this, &MangleModel::updateCustomRows);
75+ connect(this, &QIdentityProxyModel::rowsInserted,
76+ this, &MangleModel::updateCustomRows);
77+ connect(this, &QIdentityProxyModel::rowsRemoved,
78+ this, &MangleModel::updateCustomRows);
81+QVariant MangleModel::data(const QModelIndex &index, int role) const
83+ QVariant variantData;
85+ if (index.row() >= rowCount())
88+ bool isCustomRow = index.row() >= sourceRowCount();
89+ if (isCustomRow && index.column() == 0) {
90+ int customIndex = index.row() - sourceRowCount();
91+ if (role == QLightDM::UsersModel::NameRole) {
92+ variantData = m_customRows[customIndex].name;
93+ } else if (role == QLightDM::UsersModel::RealNameRole) {
94+ variantData = m_customRows[customIndex].realName;
95+ } else if (role == QLightDM::UsersModel::LoggedInRole) {
97+ } else if (role == QLightDM::UsersModel::SessionRole) {
98+ variantData = Greeter::instance()->defaultSessionHint();
101+ variantData = QIdentityProxyModel::data(index, role);
104+ // If user's real name is empty, switch to unix name
105+ if (role == QLightDM::UsersModel::RealNameRole && variantData.toString().isEmpty()) {
106+ variantData = data(index, QLightDM::UsersModel::NameRole);
107+ } else if (role == QLightDM::UsersModel::BackgroundPathRole && variantData.toString().startsWith('#')) {
108+ const QString stringData = "data:image/svg+xml,<svg><rect width='100%' height='100%' fill='" + variantData.toString() + "'/></svg>";
109+ variantData = stringData;
112+ // Workaround for liblightdm returning "" when a user has no default session
113+ if (Q_UNLIKELY(role == QLightDM::UsersModel::SessionRole && variantData.toString().isEmpty())) {
114+ variantData = Greeter::instance()->defaultSessionHint();
120+void MangleModel::addCustomRow(const CustomRow &newRow)
122+ for (int i = 0; i < m_customRows.size(); i++) {
123+ if (m_customRows[i].name == newRow.name) {
124+ return; // we don't have custom rows that change content yet
128+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
129+ m_customRows << newRow;
133+void MangleModel::removeCustomRow(const QString &rowName)
135+ for (int i = 0; i < m_customRows.size(); i++) {
136+ if (m_customRows[i].name == rowName) {
137+ int rowNum = sourceRowCount() + i;
138+ beginRemoveRows(QModelIndex(), rowNum, rowNum);
139+ m_customRows.removeAt(i);
146+void MangleModel::updateManualRow()
148+ bool hasAnotherEntry = sourceRowCount() > 0;
149+ for (int i = 0; !hasAnotherEntry && i < m_customRows.size(); i++) {
150+ if (m_customRows[i].name != QStringLiteral("*other")) {
151+ hasAnotherEntry = true;
155+ // Show manual login if we are asked to OR if no other entry exists
156+ if (Greeter::instance()->showManualLoginHint() || !hasAnotherEntry)
157+ addCustomRow({QStringLiteral("*other"), gettext("Login")});
159+ removeCustomRow(QStringLiteral("*other"));
162+void MangleModel::updateGuestRow()
164+ if (Greeter::instance()->hasGuestAccount())
165+ addCustomRow({QStringLiteral("*guest"), gettext("Guest Session")});
167+ removeCustomRow(QStringLiteral("*guest"));
170+void MangleModel::updateCustomRows()
172+ // We update when rowCount changes, but we also insert/remove rows here.
173+ // So guard this function to avoid recursion.
174+ if (m_updatingCustomRows)
177+ m_updatingCustomRows = true;
180+ m_updatingCustomRows = false;
183+int MangleModel::rowCount(const QModelIndex &parent) const
185+ if (parent.isValid())
188+ return sourceRowCount() + m_customRows.size();
191+int MangleModel::sourceRowCount() const
193+ return Greeter::instance()->hideUsersHint() ? 0 : sourceModel()->rowCount();
196+QModelIndex MangleModel::index(int row, int column, const QModelIndex &parent) const
198+ if (row >= rowCount())
199+ return QModelIndex();
201+ bool isCustomRow = row >= sourceRowCount();
202+ if (isCustomRow && !parent.isValid()) {
203+ return createIndex(row, column);
205+ return QIdentityProxyModel::index(row, column, parent);
209+// **** Now we continue with actual UsersModel class ****
211+UsersModel::UsersModel(QObject* parent)
212+ : UnitySortFilterProxyModelQML(parent)
214+ setModel(new MangleModel(this));
215+ setSortCaseSensitivity(Qt::CaseInsensitive);
216+ setSortLocaleAware(true);
217+ setSortRole(QLightDM::UsersModel::RealNameRole);
221+bool UsersModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
223+ auto leftName = source_left.data(QLightDM::UsersModel::NameRole);
224+ auto rightName = source_right.data(QLightDM::UsersModel::NameRole);
226+ if (leftName == QStringLiteral("*guest"))
228+ if (rightName == QStringLiteral("*guest"))
230+ if (leftName == QStringLiteral("*other"))
232+ if (rightName == QStringLiteral("*other"))
235+ return UnitySortFilterProxyModelQML::lessThan(source_left, source_right);
238+#include "UsersModel.moc"
plugins/IntegratedLightDM/UsersModel.h → plugins/LightDM/UsersModel.hrenamed+6−8
@@ -1,5 +1,5 @@
2− * Copyright (C) 2012,2013 Canonical, Ltd.
2+ * Copyright (C) 2012-2013,2015-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,19 +12,16 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16− * Authors: Michael Terry <michael.terry@canonical.com>
19/* This class is a really tiny filter around QLightDM::UsersModel. There are
17/* This class is a really tiny filter around QLightDM::UsersModel. There are
20 some operations that we want to edit a bit for the benefit of Qml.
18 some operations that we want to edit a bit for the benefit of Qml.
21 Specifically, we want to sort users according to realName. */
19 Specifically, we want to sort users according to realName. */
23−#ifndef UNITY_USERSMODEL_H
21+#pragma once
24−#define UNITY_USERSMODEL_H
26#include <unitysortfilterproxymodelqml.h>
23#include <unitysortfilterproxymodelqml.h>
27−#include <QtCore/QObject>
24+#include <QObject>
29class UsersModel : public UnitySortFilterProxyModelQML
26class UsersModel : public UnitySortFilterProxyModelQML
@@ -32,6 +29,7 @@ class UsersModel : public UnitySortFilterProxyModelQML
34 explicit UsersModel(QObject* parent=0);
31 explicit UsersModel(QObject* parent=0);
34+ bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
plugins/IntegratedLightDM/plugin.cpp → plugins/LightDM/plugin.cpprenamed+37−7
@@ -1,5 +1,5 @@
2− * Copyright (C) 2012,2013, 2015 Canonical, Ltd.
2+ * Copyright (C) 2012,2013,2015 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -19,9 +19,12 @@
19#include "DBusGreeter.h"
19#include "DBusGreeter.h"
20#include "DBusGreeterList.h"
20#include "DBusGreeterList.h"
21#include "Greeter.h"
21#include "Greeter.h"
22+#include "PromptsModel.h"
23+#include "SessionsModel.h"
22#include "UsersModel.h"
24#include "UsersModel.h"
23#include <libusermetricsoutput/ColorTheme.h>
25#include <libusermetricsoutput/ColorTheme.h>
24#include <libusermetricsoutput/UserMetrics.h>
26#include <libusermetricsoutput/UserMetrics.h>
27+#include <QLightDM/SessionsModel>
25#include <QLightDM/UsersModel>
28#include <QLightDM/UsersModel>
27#include <QAbstractItemModel>
30#include <QAbstractItemModel>
@@ -30,16 +33,31 @@
31static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
34static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
34 Q_UNUSED(scriptEngine)
36 Q_UNUSED(scriptEngine)
36− Greeter *greeter = new Greeter();
38+ Greeter *greeter = Greeter::instance();
37 new DBusGreeter(greeter, QStringLiteral("/"));
39 new DBusGreeter(greeter, QStringLiteral("/"));
38 new DBusGreeterList(greeter, QStringLiteral("/list"));
40 new DBusGreeterList(greeter, QStringLiteral("/list"));
42+ engine->setObjectOwnership(greeter, QQmlEngine::CppOwnership);
40 return greeter;
44 return greeter;
47+static QObject *prompts_provider(QQmlEngine *engine, QJSEngine *)
49+ auto model = Greeter::instance()->promptsModel();
50+ engine->setObjectOwnership(model, QQmlEngine::CppOwnership);
54+static QObject *sessions_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
57+ Q_UNUSED(scriptEngine)
58+ return new SessionsModel();
43static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
61static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
45 Q_UNUSED(engine)
63 Q_UNUSED(engine)
@@ -54,16 +72,28 @@ static QObject *infographic_provider(QQmlEngine *engine, QJSEngine *scriptEngine
54 return UserMetricsOutput::UserMetrics::getInstance();
72 return UserMetricsOutput::UserMetrics::getInstance();
57−void IntegratedLightDMPlugin::registerTypes(const char *uri)
75+void PLUGIN_CLASSNAME::registerTypes(const char *uri)
59 qmlRegisterType<QAbstractItemModel>();
77 qmlRegisterType<QAbstractItemModel>();
60 qmlRegisterType<UserMetricsOutput::ColorTheme>();
78 qmlRegisterType<UserMetricsOutput::ColorTheme>();
80+#if defined INTEGRATED_LIGHTDM
62− Q_ASSERT(uri == QLatin1String("IntegratedLightDM"));
81+ Q_ASSERT(uri == QLatin1String("LightDM.IntegratedLightDM"));
63− qRegisterMetaType<QLightDM::Greeter::MessageType>("QLightDM::Greeter::MessageType");
64− qRegisterMetaType<QLightDM::Greeter::PromptType>("QLightDM::Greeter::PromptType");
65 qmlRegisterSingletonType<Greeter>(uri, 0, 1, "Greeter", greeter_provider);
82 qmlRegisterSingletonType<Greeter>(uri, 0, 1, "Greeter", greeter_provider);
83+#elif defined FULL_LIGHTDM
84+ Q_ASSERT(uri == QLatin1String("LightDM.FullLightDM"));
85+ qmlRegisterSingletonType<QLightDM::Greeter>(uri, 0, 1, "Greeter", greeter_provider);
87+ #error No library defined in LightDM plugin
90+ qmlRegisterSingletonType<PromptsModel>(uri, 0, 1, "Prompts", prompts_provider);
92+ qmlRegisterSingletonType<SessionsModel>(uri, 0, 1, "Sessions", sessions_provider);
93+ qmlRegisterUncreatableType<QLightDM::SessionsModel>(uri, 0, 1, "SessionRoles", QStringLiteral("Type is not instantiable"));
66 qmlRegisterSingletonType<UsersModel>(uri, 0, 1, "Users", users_provider);
95 qmlRegisterSingletonType<UsersModel>(uri, 0, 1, "Users", users_provider);
67 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", QStringLiteral("Type is not instantiable"));
96 qmlRegisterUncreatableType<QLightDM::UsersModel>(uri, 0, 1, "UserRoles", QStringLiteral("Type is not instantiable"));
68 qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
98 qmlRegisterSingletonType<UserMetricsOutput::UserMetrics>(uri, 0, 1, "Infographic", infographic_provider);
tests/mocks/IntegratedLightDM/plugin.h → plugins/LightDM/plugin.hrenamed+6−5
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014, 2015 Canonical, Ltd.
2+ * Copyright (C) 2012,2013,2015 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,15 +12,16 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#ifndef MOCK_LIGHTDM_PLUGIN_H
18+#ifndef LIGHTDM_PLUGIN_H
18−#define MOCK_LIGHTDM_PLUGIN_H
19+#define LIGHTDM_PLUGIN_H
20#include <QtQml/QQmlEngine>
21#include <QtQml/QQmlEngine>
21#include <QtQml/QQmlExtensionPlugin>
22#include <QtQml/QQmlExtensionPlugin>
23−class IntegratedLightDMPlugin : public QQmlExtensionPlugin
24+class PLUGIN_CLASSNAME : public QQmlExtensionPlugin
26 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
27 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
@@ -29,4 +30,4 @@ public:
29 void registerTypes(const char *uri) override;
30 void registerTypes(const char *uri) override;
32−#endif
33+#endif /* LIGHTDM_PLUGIN_H */
plugins/IntegratedLightDM/qmldir → plugins/LightDM/qmldirrenamed
The content is the same.
plugins/Lights/CMakeLists.txt+9−2
@@ -1,16 +1,23 @@
1pkg_check_modules(ANDROID_HEADERS REQUIRED android-headers)
1pkg_check_modules(ANDROID_HEADERS REQUIRED android-headers)
2pkg_check_modules(ANDROID_HARDWARE REQUIRED libhardware)
2pkg_check_modules(ANDROID_HARDWARE REQUIRED libhardware)
3+pkg_check_modules(ANDROID_PROPERTIES REQUIRED libandroid-properties)
4include_directories(
5include_directories(
5 ${ANDROID_HEADERS_INCLUDE_DIRS}
7 ${ANDROID_HEADERS_INCLUDE_DIRS}
8add_library(Lights-qml MODULE
10add_library(Lights-qml MODULE
9 plugin.cpp
11 plugin.cpp
10 Lights.cpp
12 Lights.cpp
13−qt5_use_modules(Lights-qml Qml Gui)
17+target_link_libraries(Lights-qml
18+ Qt5::Qml Qt5::Gui Qt5::DBus
14−target_link_libraries(Lights-qml ${ANDROID_HARDWARE_LIBRARIES})
19+ ${ANDROID_HARDWARE_LIBRARIES}
20+ ${ANDROID_PROPERTIES_LIBRARIES}
16add_unity8_plugin(Lights 0.1 Lights TARGETS Lights-qml)
23add_unity8_plugin(Lights 0.1 Lights TARGETS Lights-qml)
plugins/Lights/HfdLights.cppnew file+62
@@ -0,0 +1,62 @@
2+ * Copyright (C) 2021 UBports Foundation.
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.
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.
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/>.
16+ * Author: Florian Leeber <florian@ubports.com>
19+#include "HfdLights.h"
20+#include <QtCore/QDebug>
21+#include <QDBusArgument>
22+#include <QDBusConnection>
25+#define HFD_SERVICE_NAME "com.lomiri.hfd"
26+#define HFD_SERVICE_PATH "/com/lomiri/hfd"
27+#define HFD_SERVICE_INTERFACE "com.lomiri.hfd.Leds"
29+HfdLights::HfdLights(QObject* parent)
32+ m_hfdInterface = new QDBusInterface(
33+ QStringLiteral(HFD_SERVICE_NAME),
34+ QStringLiteral(HFD_SERVICE_PATH),
35+ QStringLiteral(HFD_SERVICE_INTERFACE),
36+ QDBusConnection::systemBus(),
41+bool HfdLights::init()
43+ // hfd does not need any initalization to be used
47+void HfdLights::turnOn()
49+ m_hfdInterface->call(QStringLiteral("setState"), 0);
50+ m_hfdInterface->call(QStringLiteral("setColor"), (quint32)m_color.rgba());
51+ m_hfdInterface->call(QStringLiteral("setOnMs"), m_onMs);
52+ m_hfdInterface->call(QStringLiteral("setOffMs"), m_offMs);
53+ m_hfdInterface->call(QStringLiteral("setState"), 1);
56+void HfdLights::turnOff()
58+ m_hfdInterface->call(QStringLiteral("setState"), 0);
59+ m_hfdInterface->call(QStringLiteral("setColor"), (quint32)0);
60+ m_hfdInterface->call(QStringLiteral("setOnMs"), 0);
61+ m_hfdInterface->call(QStringLiteral("setOffMs"), 0);
tests/mocks/Unity/fake_unity_plugin.h → plugins/Lights/HfdLights.hrenamed+17−9
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2021 UBports Foundation.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -13,22 +13,30 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16− * Author: Nick Dedekind <nick.dedekind@canonical.com>
16+ * Author: Florian Leeber <florian@ubports.com>
19−#ifndef FAKE_UNITY_PLUGIN_H
19+#ifndef UNITY_HFDLIGHTS_H
20−#define FAKE_UNITY_PLUGIN_H
20+#define UNITY_HFDLIGHTS_H
22−// Qt
22+#include <QtCore/QObject>
23−#include <QtQml/QQmlExtensionPlugin>
23+#include <QDBusInterface>
25−class FakeUnityPlugin : public QQmlExtensionPlugin
26+class HfdLights: public Lights
28− Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
31− void registerTypes(const char *uri) override;
31+ explicit HfdLights(QObject *parent = 0);
34+ bool init() override;
35+ void turnOff() override;
36+ void turnOn() override;
39+ QDBusInterface* m_hfdInterface;
plugins/Lights/LegacyLights.cppnew file+91
@@ -0,0 +1,91 @@
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ * Copyright (C) 2021 UBports Foundation.
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17+ * Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
20+#include "LegacyLights.h"
21+#include <QtCore/QDebug>
24+#include "android-hardware.h"
28+LegacyLights::~LegacyLights()
31+ hw_device_t* device = (hw_device_t*) m_lightDevice;
32+ device->close(device);
36+bool LegacyLights::init()
45+ err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
48+ err = module->methods->open(module, LIGHT_ID_NOTIFICATIONS, &device);
50+ m_lightDevice = (light_device_t*)device;
54+ qWarning() << "Failed to access notification lights";
57+ qWarning() << "Failed to initialize lights hardware.";
62+void LegacyLights::turnOn()
66+ memset(&state, 0, sizeof(light_state_t));
67+ state.color = m_color.rgba();
68+ state.flashMode = LIGHT_FLASH_TIMED;
69+ state.flashOnMS = m_onMs;
70+ state.flashOffMS = m_offMs;
71+ state.brightnessMode = BRIGHTNESS_MODE_USER;
73+ if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
74+ qWarning() << "Failed to turn the light off";
78+void LegacyLights::turnOff()
81+ memset(&state, 0, sizeof(light_state_t));
82+ state.color = 0x00000000;
83+ state.flashMode = LIGHT_FLASH_NONE;
85+ state.flashOffMS = 0;
86+ state.brightnessMode = 0;
88+ if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
89+ qWarning() << "Failed to turn the light off";
plugins/Unity/DashCommunicator/plugin.h → plugins/Lights/LegacyLights.hrenamed+19−8
@@ -1,5 +1,6 @@
2 * Copyright (C) 2014 Canonical, Ltd.
2 * Copyright (C) 2014 Canonical, Ltd.
3+ * Copyright (C) 2021 UBports Foundation.
4 * This program is free software; you can redistribute it and/or modify
5 * 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 * it under the terms of the GNU General Public License as published by
@@ -13,22 +14,32 @@
13 * You should have received a copy of the GNU General Public License
14 * 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 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16− * Authors: Michael Zanetti <michael.zanetti@canonical.com>
17+ * Author: Renato Araujo Oliveira Filho <renato.filho@canonical.com>
19−#ifndef DASHCOMMUNICATOR_PLUGIN_H
20+#ifndef UNITY_LEGACYLIGHTS_H
20−#define DASHCOMMUNICATOR_PLUGIN_H
21+#define UNITY_LEGACYLIGHTS_H
22−#include <QtQml/QQmlEngine>
23+#include <QtCore/QObject>
23−#include <QtQml/QQmlExtensionPlugin>
24+#include "Lights.h"
25−class DashCommunicatorPlugin : public QQmlExtensionPlugin
26+struct light_device_t;
28+class LegacyLights: public Lights
28− Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
31− void registerTypes(const char *uri) override;
33+ ~LegacyLights();
36+ bool init() override;
37+ void turnOff() override;
38+ void turnOn() override;
41+ light_device_t* m_lightDevice;
plugins/Lights/Lights.cpp−65
@@ -26,20 +26,12 @@ extern "C" {
27Lights::Lights(QObject* parent)
27Lights::Lights(QObject* parent)
28 : QObject(parent),
28 : QObject(parent),
30 m_color("blue"),
29 m_color("blue"),
31 m_state(Lights::Off),
30 m_state(Lights::Off),
32 m_onMs(1000),
31 m_onMs(1000),
33 m_offMs(3000)
32 m_offMs(3000)
40− hw_device_t* device = (hw_device_t*) m_lightDevice;
41− device->close(device);
45void Lights::setState(Lights::State newState)
37void Lights::setState(Lights::State newState)
@@ -107,60 +99,3 @@ void Lights::setOffMillisec(int offMs)
107 // FIXME: update the property if the light is already on
99 // FIXME: update the property if the light is already on
113− if (m_lightDevice) {
118− hw_module_t* module;
120− err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
122− hw_device_t* device;
123− err = module->methods->open(module, LIGHT_ID_NOTIFICATIONS, &device);
125− m_lightDevice = (light_device_t*)device;
129− qWarning() << "Failed to access notification lights";
132− qWarning() << "Failed to initialize lights hardware.";
137−void Lights::turnOn()
140− light_state_t state;
141− memset(&state, 0, sizeof(light_state_t));
142− state.color = m_color.rgba();
143− state.flashMode = LIGHT_FLASH_TIMED;
144− state.flashOnMS = m_onMs;
145− state.flashOffMS = m_offMs;
146− state.brightnessMode = BRIGHTNESS_MODE_USER;
148− if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
149− qWarning() << "Failed to turn the light off";
153−void Lights::turnOff()
155− light_state_t state;
156− memset(&state, 0, sizeof(light_state_t));
157− state.color = 0x00000000;
158− state.flashMode = LIGHT_FLASH_NONE;
159− state.flashOnMS = 0;
160− state.flashOffMS = 0;
161− state.brightnessMode = 0;
163− if (m_lightDevice->set_light(m_lightDevice, &state) != 0) {
164− qWarning() << "Failed to turn the light off";
plugins/Lights/Lights.h+5−9
@@ -22,12 +22,9 @@
22#include <QtCore/QObject>
22#include <QtCore/QObject>
23#include <QtGui/QColor>
23#include <QtGui/QColor>
25−struct light_device_t;
27class Lights: public QObject
25class Lights: public QObject
31 Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
28 Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
32 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
29 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
33 Q_PROPERTY(int onMillisec READ onMillisec WRITE setOnMillisec NOTIFY onMillisecChanged)
30 Q_PROPERTY(int onMillisec READ onMillisec WRITE setOnMillisec NOTIFY onMillisecChanged)
@@ -38,9 +35,9 @@ public:
42 explicit Lights(QObject *parent = 0);
40 explicit Lights(QObject *parent = 0);
45 void setState(State newState);
42 void setState(State newState);
46 State state() const;
43 State state() const;
@@ -60,16 +57,15 @@ Q_SIGNALS:
60 void onMillisecChanged(int onMs);
57 void onMillisecChanged(int onMs);
61 void offMillisecChanged(int offMs);
58 void offMillisecChanged(int offMs);
64− light_device_t* m_lightDevice;
65 QColor m_color;
61 QColor m_color;
66 State m_state;
62 State m_state;
67 int m_onMs;
63 int m_onMs;
68 int m_offMs;
64 int m_offMs;
70− bool init();
66+ virtual bool init() = 0;
71− void turnOff();
67+ virtual void turnOff() = 0;
72− void turnOn();
68+ virtual void turnOn() = 0;
plugins/Lights/Lights.qmltypesdeleted−45
@@ -1,45 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Lights 0.1 plugins'
13− exports: ["Lights/Lights 0.1"]
16− exportMetaObjectRevisions: [0]
24− Property { name: "state"; type: "State" }
25− Property { name: "color"; type: "QColor" }
26− Property { name: "onMillisec"; type: "int" }
27− Property { name: "offMillisec"; type: "int" }
30− Parameter { name: "newState"; type: "State" }
34− Parameter { name: "color"; type: "QColor" }
37− name: "onMillisecChanged"
38− Parameter { name: "onMs"; type: "int" }
41− name: "offMillisecChanged"
42− Parameter { name: "offMs"; type: "int" }
plugins/Lights/android-hardware.h−4
@@ -15,9 +15,5 @@
18−// The purpose of this header wrapper is just to avoid having warnings being reported on
19−// code from external header files, as we can't do anything about them.
20−#pragma GCC system_header
22#include <hardware/hardware.h>
18#include <hardware/hardware.h>
23#include <hardware/lights.h>
19#include <hardware/lights.h>
plugins/Lights/plugin.cpp+20−1
@@ -18,6 +18,11 @@
19#include "plugin.h"
19#include "plugin.h"
20#include "Lights.h"
20#include "Lights.h"
21+#include "HfdLights.h"
22+#include "LegacyLights.h"
24+// libandroid-properties
25+#include <hybris/properties/properties.h>
22#include <QtQml/qqml.h>
27#include <QtQml/qqml.h>
@@ -25,7 +30,21 @@ static QObject *lights_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
26 Q_UNUSED(engine)
31 Q_UNUSED(engine)
27 Q_UNUSED(scriptEngine)
32 Q_UNUSED(scriptEngine)
34+ bool use_hfd = false;
35+ char buffer[PROP_VALUE_MAX];
36+ auto result = property_get("ro.build.version.sdk", buffer, "0");
38+ auto sdkVersion = QString(buffer).toInt();
39+ if (sdkVersion >= 27 || sdkVersion == 0) {
28− return new Lights();
44+ return new HfdLights();
46+ return new LegacyLights();
31void LightsPlugin::registerTypes(const char *uri)
50void LightsPlugin::registerTypes(const char *uri)
plugins/Powerd/CMakeLists.txt+4−2
@@ -9,7 +9,9 @@ add_library(Powerd-qml MODULE
12−qt5_use_modules(Powerd-qml DBus Qml)
12+target_link_libraries(Powerd-qml
13−target_link_libraries(Powerd-qml ${GIO_LDFLAGS})
14+ ${GIO_LDFLAGS}
15add_unity8_plugin(Powerd 0.1 Powerd TARGETS Powerd-qml)
17add_unity8_plugin(Powerd 0.1 Powerd TARGETS Powerd-qml)
plugins/Powerd/Powerd.h+2−2
@@ -27,8 +27,6 @@
27class Powerd: public QObject
27class Powerd: public QObject
31− Q_ENUMS(DisplayStateChangeReason)
32 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
30 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
@@ -41,11 +39,13 @@ public:
41 SnapDecision = 5, // Display changed state due to snap decision prompt
39 SnapDecision = 5, // Display changed state due to snap decision prompt
42 CallDone = 6, // Display changed state due to voice call end
40 CallDone = 6, // Display changed state due to voice call end
42+ Q_ENUM(DisplayStateChangeReason)
45 enum Status {
44 enum Status {
50 explicit Powerd(QObject *parent = 0);
50 explicit Powerd(QObject *parent = 0);
51 ~Powerd();
51 ~Powerd();
plugins/Powerd/Powerd.qmltypesdeleted−39
@@ -1,39 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Powerd 0.1 plugins'
13− exports: ["Powerd/Powerd 0.1"]
16− exportMetaObjectRevisions: [0]
18− name: "DisplayStateChangeReason"
33− Property { name: "status"; type: "Status"; isReadonly: true }
35− name: "statusChanged"
36− Parameter { name: "reason"; type: "DisplayStateChangeReason" }
plugins/ScreenshotDirectory/CMakeLists.txt+1−1
@@ -4,6 +4,6 @@ set(PLUGIN_SOURCES
6add_library(ScreenshotDirectory-qml MODULE ${PLUGIN_SOURCES})
6add_library(ScreenshotDirectory-qml MODULE ${PLUGIN_SOURCES})
7−qt5_use_modules(ScreenshotDirectory-qml Qml Gui Quick)
7+target_link_libraries(ScreenshotDirectory-qml Qt5::Qml Qt5::Gui Qt5::Quick)
9add_unity8_plugin(ScreenshotDirectory 0.1 ScreenshotDirectory TARGETS ScreenshotDirectory-qml)
9add_unity8_plugin(ScreenshotDirectory 0.1 ScreenshotDirectory TARGETS ScreenshotDirectory-qml)
plugins/SessionBroadcast/CMakeLists.txt+1−2
@@ -6,9 +6,8 @@ add_library(SessionBroadcast-qml MODULE
9−qt5_use_modules(SessionBroadcast-qml DBus Qml)
11target_link_libraries(SessionBroadcast-qml
9target_link_libraries(SessionBroadcast-qml
12 ${GLIB_LIBRARIES}
11 ${GLIB_LIBRARIES}
plugins/SessionBroadcast/SessionBroadcast.cpp+35−9
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,12 +12,12 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16− * Author: Michael Terry <michael.terry@canonical.com>
19#include "SessionBroadcast.h"
17#include "SessionBroadcast.h"
20#include <QDBusConnection>
18#include <QDBusConnection>
19+#include <QDBusConnectionInterface>
20+#include <QDBusInterface>
22#include <glib.h>
22#include <glib.h>
@@ -27,13 +27,39 @@ SessionBroadcast::SessionBroadcast(QObject* parent)
27 m_username = QString::fromUtf8(g_get_user_name());
27 m_username = QString::fromUtf8(g_get_user_name());
29 auto connection = QDBusConnection::SM_BUSNAME();
29 auto connection = QDBusConnection::SM_BUSNAME();
30+ auto interface = connection.interface();
31+ interface->startService(QStringLiteral("com.canonical.Unity.Greeter.Broadcast"));
33+ m_broadcaster = new QDBusInterface(QStringLiteral("com.canonical.Unity.Greeter.Broadcast"),
34+ QStringLiteral("/com/canonical/Unity/Greeter/Broadcast"),
35+ QStringLiteral("com.canonical.Unity.Greeter.Broadcast"),
38+ connect(m_broadcaster, SIGNAL(StartUrl(const QString &, const QString &)),
39+ this, SLOT(onStartUrl(const QString &, const QString &)));
41+ connect(m_broadcaster, SIGNAL(ShowHome(const QString &)),
42+ this, SLOT(onShowHome(const QString &)));
45+void SessionBroadcast::requestUrlStart(const QString &username, const QString &url)
47+ m_broadcaster->asyncCall(QStringLiteral("RequestUrlStart"), username, url);
50+void SessionBroadcast::requestHomeShown(const QString &username)
52+ m_broadcaster->asyncCall(QStringLiteral("RequestHomeShown"), username);
31− connection.connect(QStringLiteral("com.canonical.Unity.Greeter.Broadcast"),
55+void SessionBroadcast::onStartUrl(const QString &username, const QString &url)
32− QStringLiteral("/com/canonical/Unity/Greeter/Broadcast"),
56+{
33− QStringLiteral("com.canonical.Unity.Greeter.Broadcast"),
57+ // Since this signal is just used for testing, we don't *really* care if
34− QStringLiteral("ShowHome"),
58+ // username matches, but just in case we do eventually use the signal, we
35− this,
59+ // should only listen to our own requests.
36− SLOT(onShowHome(const QString &)));
60+ if (username == m_username) {
61+ Q_EMIT startUrl(url);
39void SessionBroadcast::onShowHome(const QString &username)
65void SessionBroadcast::onShowHome(const QString &username)
plugins/SessionBroadcast/SessionBroadcast.h+10−3
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013,2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,8 +12,6 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16− * Authors: Michael Terry <michael.terry@canonical.com>
19#ifndef UNITY_SESSIONBROADCAST_H
17#ifndef UNITY_SESSIONBROADCAST_H
@@ -31,14 +29,23 @@ class SessionBroadcast: public QObject
32 explicit SessionBroadcast(QObject *parent = 0);
30 explicit SessionBroadcast(QObject *parent = 0);
32+ Q_INVOKABLE void requestUrlStart(const QString &username, const QString &url);
33+ Q_INVOKABLE void requestHomeShown(const QString &username);
36+ // This signal isn't actually used by the shell
37+ // (unity-greeter-session-broadcast handles launching an app for us), but
38+ // it's useful for testing the plugin.
39+ void startUrl(const QString &url);
35 void showHome();
40 void showHome();
37private Q_SLOTS:
42private Q_SLOTS:
43+ void onStartUrl(const QString &username, const QString &url);
38 void onShowHome(const QString &username);
44 void onShowHome(const QString &username);
41 QString m_username;
47 QString m_username;
48+ QDBusInterface *m_broadcaster;
plugins/SessionBroadcast/SessionBroadcast.qmltypesdeleted−19
@@ -1,19 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable SessionBroadcast 0.1 plugins'
11− name: "SessionBroadcast"
13− exports: ["SessionBroadcast/SessionBroadcast 0.1"]
16− exportMetaObjectRevisions: [0]
17− Signal { name: "showHome" }
plugins/UInput/CMakeLists.txt+1−1
@@ -3,5 +3,5 @@ add_library(UInput-qml MODULE
6−qt5_use_modules(UInput-qml Qml)
6+target_link_libraries(UInput-qml Qt5::Qml)
7add_unity8_plugin(UInput 0.1 UInput TARGETS UInput-qml)
7add_unity8_plugin(UInput 0.1 UInput TARGETS UInput-qml)
plugins/UInput/UInput.qmltypesdeleted−44
@@ -1,44 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable UInput 0.1 plugins'
13− exports: ["UInput/UInput 0.1"]
14− exportMetaObjectRevisions: [0]
23− Method { name: "createMouse" }
24− Method { name: "removeMouse" }
27− Parameter { name: "dx"; type: "int" }
28− Parameter { name: "dy"; type: "int" }
32− Parameter { name: "button"; type: "Button" }
36− Parameter { name: "button"; type: "Button" }
40− Parameter { name: "dh"; type: "int" }
41− Parameter { name: "dv"; type: "int" }
plugins/UInput/uinput.h+1−1
@@ -27,7 +27,6 @@
27class UInput : public QObject
27class UInput : public QObject
33 enum Button {
32 enum Button {
@@ -35,6 +34,7 @@ public:
35 ButtonRight,
34 ButtonRight,
36 ButtonMiddle
35 ButtonMiddle
39 explicit UInput(QObject *parent = nullptr);
39 explicit UInput(QObject *parent = nullptr);
40 ~UInput();
40 ~UInput();
plugins/Ubuntu/CMakeLists.txt−2
@@ -1,4 +1,2 @@
1add_subdirectory(Gestures)
1add_subdirectory(Gestures)
2add_subdirectory(DownloadDaemonListener)
2add_subdirectory(DownloadDaemonListener)
3−add_subdirectory(Payments)
4−add_subdirectory(SystemImage)
plugins/Ubuntu/DownloadDaemonListener/CMakeLists.txt+6−3
@@ -1,7 +1,6 @@
1include_directories(
1include_directories(
2 ${CMAKE_CURRENT_SOURCE_DIR}
2 ${CMAKE_CURRENT_SOURCE_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
4− ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
7set(DOWNLOADDAEMONLISTENER_SOURCES
6set(DOWNLOADDAEMONLISTENER_SOURCES
@@ -12,6 +11,10 @@ set(DOWNLOADDAEMONLISTENER_SOURCES
13add_library(DownloadDaemonListener MODULE ${DOWNLOADDAEMONLISTENER_SOURCES})
12add_library(DownloadDaemonListener MODULE ${DOWNLOADDAEMONLISTENER_SOURCES})
14+pkg_check_modules(DDLADAPTER REQUIRED udm-common)
15+add_definitions(${DDLADAPTER_CFLAGS} ${DDLADAPTER_CFLAGS_OTHER})
15−qt5_use_modules(DownloadDaemonListener Qml Quick DBus Core)
16+target_link_libraries(DownloadDaemonListener
16−
17+ Qt5::Qml Qt5::Quick Qt5::DBus Qt5::Core
18+ ${DDLADAPTER_LIBRARIES}
17add_unity8_plugin(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS DownloadDaemonListener)
20add_unity8_plugin(Ubuntu.DownloadDaemonListener 0.1 Ubuntu/DownloadDaemonListener TARGETS DownloadDaemonListener)
plugins/Ubuntu/DownloadDaemonListener/DownloadDaemonListener.qmltypesdeleted−60
@@ -1,60 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Ubuntu.DownloadDaemonListener 0.1 plugins'
11− name: "DownloadTracker"
13− exports: ["Ubuntu.DownloadDaemonListener/DownloadTracker 0.1"]
14− exportMetaObjectRevisions: [0]
15− Property { name: "service"; type: "string" }
16− Property { name: "dbusPath"; type: "string" }
17− Property { name: "serviceReady"; type: "bool"; isReadonly: true }
19− name: "serviceChanged"
20− Parameter { name: "service"; type: "string" }
23− name: "dbusPathChanged"
24− Parameter { name: "dbusPath"; type: "string" }
27− name: "serviceReadyChanged"
28− Parameter { name: "serviceReady"; type: "bool" }
32− Parameter { name: "success"; type: "bool" }
36− Parameter { name: "error"; type: "string" }
40− Parameter { name: "path"; type: "string" }
44− Parameter { name: "success"; type: "bool" }
48− Parameter { name: "received"; type: "qulonglong" }
49− Parameter { name: "total"; type: "qulonglong" }
53− Parameter { name: "success"; type: "bool" }
57− Parameter { name: "success"; type: "bool" }
plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.cpp+2−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 - Canonical Ltd.
2+ * Copyright (C) 2013-2016 Canonical Ltd.
4 * This program is free software: you can redistribute it and/or modify it
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, as
5 * under the terms of the GNU Lesser General Public License, as
@@ -78,6 +78,7 @@ void DownloadTracker::startService()
78 connect(m_adaptor, static_cast<void (DownloadTrackerAdaptor::*)(qulonglong, qulonglong)>(&DownloadTrackerAdaptor::progress), this, &DownloadTracker::progress);
78 connect(m_adaptor, static_cast<void (DownloadTrackerAdaptor::*)(qulonglong, qulonglong)>(&DownloadTrackerAdaptor::progress), this, &DownloadTracker::progress);
79 connect(m_adaptor, &DownloadTrackerAdaptor::resumed, this, &DownloadTracker::resumed);
79 connect(m_adaptor, &DownloadTrackerAdaptor::resumed, this, &DownloadTracker::resumed);
80 connect(m_adaptor, &DownloadTrackerAdaptor::started, this, &DownloadTracker::started);
80 connect(m_adaptor, &DownloadTrackerAdaptor::started, this, &DownloadTracker::started);
81+ connect(m_adaptor, &DownloadTrackerAdaptor::processing, this, &DownloadTracker::processing);
82 // FIXME find a better way of determining if the service is ready
83 // FIXME find a better way of determining if the service is ready
83 Q_EMIT serviceReadyChanged(m_adaptor && m_adaptor->isValid());
84 Q_EMIT serviceReadyChanged(m_adaptor && m_adaptor->isValid());
plugins/Ubuntu/DownloadDaemonListener/DownloadTracker.h+2−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2013 - Canonical Ltd.
2+ * Copyright (C) 2013-2016 Canonical Ltd.
4 * This program is free software: you can redistribute it and/or modify it
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, as
5 * under the terms of the GNU Lesser General Public License, as
@@ -54,6 +54,7 @@ Q_SIGNALS:
54 void error(const QString &error);
54 void error(const QString &error);
55 void finished(const QString &path);
55 void finished(const QString &path);
56 void paused(bool success);
56 void paused(bool success);
57+ void processing(const QString &path);
57 void progress(qulonglong received, qulonglong total);
58 void progress(qulonglong received, qulonglong total);
58 void resumed(bool success);
59 void resumed(bool success);
59 void started(bool success);
60 void started(bool success);
plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.cpp+2−2
@@ -1,8 +1,8 @@
2 * This file was generated by qdbusxml2cpp version 0.8
2 * This file was generated by qdbusxml2cpp version 0.8
3− * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h com.canonical.applications.download.xml
3+ * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h ../../../../../../ubuntu-download-manager/trunk/docs/dbus/com.canonical.applications.download.xml
5− * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
5+ * qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
7 * This is an auto-generated file.
7 * This is an auto-generated file.
8 * This file may have been hand-edited. Look for HAND-EDIT comments
8 * This file may have been hand-edited. Look for HAND-EDIT comments
plugins/Ubuntu/DownloadDaemonListener/interface/downloadtrackeradaptor.h+71−4
@@ -1,15 +1,15 @@
2 * This file was generated by qdbusxml2cpp version 0.8
2 * This file was generated by qdbusxml2cpp version 0.8
3− * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h com.canonical.applications.download.xml
3+ * Command line was: qdbusxml2cpp -v -c DownloadTrackerAdaptor -p downloadtrackeradaptor.h:downloadtrackeradaptor.cpp -i metatypes.h ../../../../../../ubuntu-download-manager/trunk/docs/dbus/com.canonical.applications.download.xml
5− * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
5+ * qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
7 * This is an auto-generated file.
7 * This is an auto-generated file.
8 * Do not edit! All changes made to it will be lost.
8 * Do not edit! All changes made to it will be lost.
11−#ifndef DOWNLOADTRACKERADAPTOR_H_1374434371
11+#ifndef DOWNLOADTRACKERADAPTOR_H
12−#define DOWNLOADTRACKERADAPTOR_H_1374434371
12+#define DOWNLOADTRACKERADAPTOR_H
14#include <QtCore/QObject>
14#include <QtCore/QObject>
15#include <QtCore/QByteArray>
15#include <QtCore/QByteArray>
@@ -36,6 +36,22 @@ public:
37 ~DownloadTrackerAdaptor();
37 ~DownloadTrackerAdaptor();
39+ Q_PROPERTY(QString ClickPackage READ clickPackage)
40+ inline QString clickPackage() const
41+ { return qvariant_cast< QString >(property("ClickPackage")); }
43+ Q_PROPERTY(QString DestinationApp READ destinationApp)
44+ inline QString destinationApp() const
45+ { return qvariant_cast< QString >(property("DestinationApp")); }
47+ Q_PROPERTY(bool ShowInIndicator READ showInIndicator)
48+ inline bool showInIndicator() const
49+ { return qvariant_cast< bool >(property("ShowInIndicator")); }
51+ Q_PROPERTY(QString Title READ title)
52+ inline QString title() const
53+ { return qvariant_cast< QString >(property("Title")); }
39public Q_SLOTS: // METHODS
55public Q_SLOTS: // METHODS
40 inline QDBusPendingReply<> allowGSMDownload(bool allowed)
56 inline QDBusPendingReply<> allowGSMDownload(bool allowed)
@@ -50,6 +66,24 @@ public Q_SLOTS: // METHODS
50 return asyncCallWithArgumentList(QStringLiteral("cancel"), argumentList);
66 return asyncCallWithArgumentList(QStringLiteral("cancel"), argumentList);
69+ inline QDBusPendingReply<> collected()
71+ QList<QVariant> argumentList;
72+ return asyncCallWithArgumentList(QStringLiteral("collected"), argumentList);
75+ inline QDBusPendingReply<QString> filePath()
77+ QList<QVariant> argumentList;
78+ return asyncCallWithArgumentList(QStringLiteral("filePath"), argumentList);
81+ inline QDBusPendingReply<StringMap> headers()
83+ QList<QVariant> argumentList;
84+ return asyncCallWithArgumentList(QStringLiteral("headers"), argumentList);
53 inline QDBusPendingReply<bool> isGSMDownloadAllowed()
87 inline QDBusPendingReply<bool> isGSMDownloadAllowed()
55 QList<QVariant> argumentList;
89 QList<QVariant> argumentList;
@@ -80,6 +114,27 @@ public Q_SLOTS: // METHODS
80 return asyncCallWithArgumentList(QStringLiteral("resume"), argumentList);
114 return asyncCallWithArgumentList(QStringLiteral("resume"), argumentList);
117+ inline QDBusPendingReply<> setDestinationDir(const QString &path)
119+ QList<QVariant> argumentList;
120+ argumentList << QVariant::fromValue(path);
121+ return asyncCallWithArgumentList(QStringLiteral("setDestinationDir"), argumentList);
124+ inline QDBusPendingReply<> setHeaders(StringMap headers)
126+ QList<QVariant> argumentList;
127+ argumentList << QVariant::fromValue(headers);
128+ return asyncCallWithArgumentList(QStringLiteral("setHeaders"), argumentList);
131+ inline QDBusPendingReply<> setMetadata(const QVariantMap &data)
133+ QList<QVariant> argumentList;
134+ argumentList << QVariant::fromValue(data);
135+ return asyncCallWithArgumentList(QStringLiteral("setMetadata"), argumentList);
83 inline QDBusPendingReply<> setThrottle(qulonglong speed)
138 inline QDBusPendingReply<> setThrottle(qulonglong speed)
85 QList<QVariant> argumentList;
140 QList<QVariant> argumentList;
@@ -93,6 +148,12 @@ public Q_SLOTS: // METHODS
93 return asyncCallWithArgumentList(QStringLiteral("start"), argumentList);
148 return asyncCallWithArgumentList(QStringLiteral("start"), argumentList);
151+ inline QDBusPendingReply<int> state()
153+ QList<QVariant> argumentList;
154+ return asyncCallWithArgumentList(QStringLiteral("state"), argumentList);
96 inline QDBusPendingReply<qulonglong> throttle()
157 inline QDBusPendingReply<qulonglong> throttle()
98 QList<QVariant> argumentList;
159 QList<QVariant> argumentList;
@@ -106,10 +167,16 @@ public Q_SLOTS: // METHODS
108Q_SIGNALS: // SIGNALS
169Q_SIGNALS: // SIGNALS
170+ void authError(AuthErrorStruct error);
109 void canceled(bool success);
171 void canceled(bool success);
110 void error(const QString &error);
172 void error(const QString &error);
111 void finished(const QString &path);
173 void finished(const QString &path);
174+ void hashError(HashErrorStruct error);
175+ void httpError(HttpErrorStruct error);
176+ void networkError(NetworkErrorStruct error);
112 void paused(bool success);
177 void paused(bool success);
178+ void processError(ProcessErrorStruct error);
179+ void processing(const QString &path);
113 void progress(qulonglong received, qulonglong total);
180 void progress(qulonglong received, qulonglong total);
114 void resumed(bool success);
181 void resumed(bool success);
115 void started(bool success);
182 void started(bool success);
plugins/Ubuntu/DownloadDaemonListener/interface/metatypes.h+3−6
@@ -1,5 +1,5 @@
2− * Copyright 2013 2013 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
4 * This library is free software; you can redistribute it and/or
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public
5 * modify it under the terms of version 3 of the GNU Lesser General Public
@@ -19,10 +19,7 @@
19#ifndef DOWNLOADER_LIB_APP_METATYPES_H
19#ifndef DOWNLOADER_LIB_APP_METATYPES_H
20#define DOWNLOADER_LIB_APP_METATYPES_H
20#define DOWNLOADER_LIB_APP_METATYPES_H
22−#include <QMap>
22+// Just include the system file so we're always up to date.
23−
23+#include <ubuntu/download_manager/metatypes.h>
24−typedef QMap<QString, QString> StringMap;
26−Q_DECLARE_METATYPE(StringMap)
28#endif // METATYPES_H
25#endif // METATYPES_H
plugins/Ubuntu/Gestures/AxisVelocityCalculator.cpp+1−1
@@ -21,7 +21,7 @@
21#include "AxisVelocityCalculator.h"
21#include "AxisVelocityCalculator.h"
22#include <QtCore/QElapsedTimer>
22#include <QtCore/QElapsedTimer>
24−using namespace UbuntuGestures;
24+UG_USE_NAMESPACE
26AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
26AxisVelocityCalculator::AxisVelocityCalculator(QObject *parent)
27 : AxisVelocityCalculator(SharedTimeSource(new RealTimeSource), parent)
27 : AxisVelocityCalculator(SharedTimeSource(new RealTimeSource), parent)
plugins/Ubuntu/Gestures/AxisVelocityCalculator.h+4−4
@@ -24,7 +24,7 @@
24#include "UbuntuGesturesQmlGlobal.h"
24#include "UbuntuGesturesQmlGlobal.h"
25#include <stdint.h>
25#include <stdint.h>
26#include <QtCore/QObject>
26#include <QtCore/QObject>
27−#include <TimeSource>
27+#include <UbuntuGestures/private/timesource_p.h>
30 Estimates the current velocity of a finger based on recent movement along an axis
30 Estimates the current velocity of a finger based on recent movement along an axis
@@ -68,7 +68,7 @@ public:
69 Constructor that takes a TimeSource
69 Constructor that takes a TimeSource
71− AxisVelocityCalculator(const UbuntuGestures::SharedTimeSource &timeSource, QObject *parent = 0);
71+ AxisVelocityCalculator(const UG_PREPEND_NAMESPACE(SharedTimeSource) &timeSource, QObject *parent = 0);
73 virtual ~AxisVelocityCalculator();
73 virtual ~AxisVelocityCalculator();
@@ -90,7 +90,7 @@ public:
91 Replaces the TimeSource with the given one. Useful for testing purposes.
91 Replaces the TimeSource with the given one. Useful for testing purposes.
93− void setTimeSource(const UbuntuGestures::SharedTimeSource &timeSource);
93+ void setTimeSource(const UG_PREPEND_NAMESPACE(SharedTimeSource) &timeSource);
96 The minimum amount of samples needed for a velocity calculation.
96 The minimum amount of samples needed for a velocity calculation.
@@ -138,7 +138,7 @@ private:
138 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
138 int m_samplesRead; /* index of the oldest sample available. -1 if buffer is empty */
139 int m_samplesWrite; /* index where the next sample will be written */
139 int m_samplesWrite; /* index where the next sample will be written */
141− UbuntuGestures::SharedTimeSource m_timeSource;
141+ UG_PREPEND_NAMESPACE(SharedTimeSource) m_timeSource;
143 qreal m_trackedPosition;
143 qreal m_trackedPosition;
plugins/Ubuntu/Gestures/CMakeLists.txt+7−4
@@ -17,14 +17,16 @@ pkg_check_modules(UBUNTUGESTURES REQUIRED UbuntuGestures)
17add_definitions(-DUBUNTUGESTURESQML_LIBRARY)
17add_definitions(-DUBUNTUGESTURESQML_LIBRARY)
19add_library(UbuntuGesturesQml SHARED ${UbuntuGesturesQml_SOURCES})
19add_library(UbuntuGesturesQml SHARED ${UbuntuGesturesQml_SOURCES})
20−target_link_libraries(UbuntuGesturesQml ${UBUNTUGESTURES_LIBRARIES})
20+target_link_libraries(UbuntuGesturesQml ${UBUNTUGESTURES_LIBRARIES} Qt5::Core Qt5::Quick)
22−qt5_use_modules(UbuntuGesturesQml Core Quick)
24# So that Foo.cpp can #include "Foo.moc"
22# So that Foo.cpp can #include "Foo.moc"
25include_directories(${CMAKE_CURRENT_BINARY_DIR})
23include_directories(${CMAKE_CURRENT_BINARY_DIR})
27−include_directories(${UBUNTUGESTURES_INCLUDE_DIRS})
27+ ${UBUNTUGESTURES_INCLUDE_DIRS}
28+ ${UBUNTUGESTURES_INCLUDEDIR}/UbuntuGestures/${UBUNTUGESTURES_VERSION}
29# There's no cmake var for v8 include path :-/ so create one
31# There's no cmake var for v8 include path :-/ so create one
30LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
32LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
@@ -32,6 +34,7 @@ SET(Qt5V8_PRIVATE_INCLUDE_DIR ${QtCoreDir0}/QtV8/${Qt5Core_VERSION_STRING}/QtV8)
33# DANGER! DANGER! Using Qt's private API!
35# DANGER! DANGER! Using Qt's private API!
34include_directories(
36include_directories(
35 ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
38 ${Qt5Qml_PRIVATE_INCLUDE_DIRS}
36 ${Qt5Quick_INCLUDE_DIRS}
39 ${Qt5Quick_INCLUDE_DIRS}
37 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
40 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
plugins/Ubuntu/Gestures/Direction.h+1−1
@@ -26,7 +26,6 @@
27class UBUNTUGESTURESQML_EXPORT Direction : public QObject {
27class UBUNTUGESTURESQML_EXPORT Direction : public QObject {
32 // Make sure it is kept synchronized with SDK UCSwipeArea::Direction
31 // Make sure it is kept synchronized with SDK UCSwipeArea::Direction
@@ -38,6 +37,7 @@ public:
38 Horizontal, // Along the X axis, in any direction
37 Horizontal, // Along the X axis, in any direction
39 Vertical // Along the Y axis, in any direction
38 Vertical // Along the Y axis, in any direction
42 Q_INVOKABLE static bool isHorizontal(Direction::Type type);
42 Q_INVOKABLE static bool isHorizontal(Direction::Type type);
43 Q_INVOKABLE static bool isVertical(Direction::Type type);
43 Q_INVOKABLE static bool isVertical(Direction::Type type);
plugins/Ubuntu/Gestures/Gestures.qmltypesdeleted−77
@@ -1,77 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Ubuntu.Gestures 0.1 plugins'
11− name: "AxisVelocityCalculator"
13− exports: ["Ubuntu.Gestures/AxisVelocityCalculator 0.1"]
14− exportMetaObjectRevisions: [0]
15− Property { name: "trackedPosition"; type: "double" }
17− name: "trackedPositionChanged"
18− Parameter { name: "value"; type: "double" }
20− Method { name: "calculate"; type: "double" }
21− Method { name: "reset" }
26− exports: ["Ubuntu.Gestures/Direction 0.1"]
29− exportMetaObjectRevisions: [0]
44− Parameter { name: "type"; type: "Direction::Type" }
49− Parameter { name: "type"; type: "Direction::Type" }
54− Parameter { name: "type"; type: "Direction::Type" }
58− name: "PressedOutsideNotifier"
59− defaultProperty: "data"
60− prototype: "QQuickItem"
61− exports: ["Ubuntu.Gestures/PressedOutsideNotifier 0.1"]
62− exportMetaObjectRevisions: [0]
63− Signal { name: "pressedOutside" }
67− defaultProperty: "data"
68− prototype: "QQuickItem"
69− exports: ["Ubuntu.Gestures/TouchGate 0.1"]
70− exportMetaObjectRevisions: [0]
71− Property { name: "targetItem"; type: "QQuickItem"; isPointer: true }
73− name: "targetItemChanged"
74− Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
plugins/Ubuntu/Gestures/TouchDispatcher.cpp+1−5
@@ -19,11 +19,7 @@
19#include <QGuiApplication>
19#include <QGuiApplication>
20#include <QScopedPointer>
20#include <QScopedPointer>
21#include <QStyleHints>
21#include <QStyleHints>
23−#pragma GCC diagnostic push
24−#pragma GCC diagnostic ignored "-pedantic"
25#include <private/qquickitem_p.h>
22#include <private/qquickitem_p.h>
26−#pragma GCC diagnostic pop
28#define TOUCHDISPATCHER_DEBUG 0
24#define TOUCHDISPATCHER_DEBUG 0
@@ -225,7 +221,7 @@ void TouchDispatcher::dispatchAsMouse(
225 QEvent::Type eventType;
221 QEvent::Type eventType;
226 if (touchMouse->state() == Qt::TouchPointPressed) {
222 if (touchMouse->state() == Qt::TouchPointPressed) {
227 eventType = QEvent::MouseButtonPress;
223 eventType = QEvent::MouseButtonPress;
228− } if (touchMouse->state() == Qt::TouchPointReleased) {
224+ } else if (touchMouse->state() == Qt::TouchPointReleased) {
229 eventType = QEvent::MouseButtonRelease;
225 eventType = QEvent::MouseButtonRelease;
230 m_touchMouseId = -1;
226 m_touchMouseId = -1;
plugins/Ubuntu/Gestures/TouchGate.cpp+10−5
@@ -20,16 +20,18 @@
20#include <QDebug>
20#include <QDebug>
21#include <QQuickWindow>
21#include <QQuickWindow>
23−#include <TouchOwnershipEvent>
23+#include <UbuntuGestures/private/touchownershipevent_p.h>
24−#include <TouchRegistry>
24+#include <UbuntuGestures/private/touchregistry_p.h>
26#if TOUCHGATE_DEBUG
26#if TOUCHGATE_DEBUG
27#define ugDebug(params) qDebug().nospace() << "[TouchGate(" << (void*)this << ")] " << params
27#define ugDebug(params) qDebug().nospace() << "[TouchGate(" << (void*)this << ")] " << params
28−#include <DebugHelpers.h>
28+#include <UbuntuGestures/private/debughelpers_p.h>
29#else // TOUCHGATE_DEBUG
29#else // TOUCHGATE_DEBUG
30#define ugDebug(params) ((void)0)
30#define ugDebug(params) ((void)0)
31#endif // TOUCHGATE_DEBUG
31#endif // TOUCHGATE_DEBUG
33TouchGate::TouchGate(QQuickItem *parent)
35TouchGate::TouchGate(QQuickItem *parent)
34 : QQuickItem(parent)
36 : QQuickItem(parent)
@@ -40,7 +42,7 @@ TouchGate::TouchGate(QQuickItem *parent)
40bool TouchGate::event(QEvent *e)
42bool TouchGate::event(QEvent *e)
42 if (e->type() == TouchOwnershipEvent::touchOwnershipEventType()) {
44 if (e->type() == TouchOwnershipEvent::touchOwnershipEventType()) {
43− touchOwnershipEvent(static_cast<TouchOwnershipEvent *>(e));
45+ touchOwnershipEvent(static_cast<TouchOwnershipEvent*>(e));
44 return true;
46 return true;
46 return QQuickItem::event(e);
48 return QQuickItem::event(e);
@@ -59,7 +61,10 @@ void TouchGate::touchEvent(QTouchEvent *event)
59 const QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
61 const QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
61 if (touchPoint.state() == Qt::TouchPointPressed) {
63 if (touchPoint.state() == Qt::TouchPointPressed) {
64+// FIXME: This assert triggers frequently in make trySomething. We have verified
65+// that it's a bug in the mouse to touch conversion of the test environment
66+// and not in the actual product. Still, it probably should be cleaned up eventually.
62− Q_ASSERT(!m_touchInfoMap.contains(touchPoint.id()));
67+// Q_ASSERT(!m_touchInfoMap.contains(touchPoint.id()));
63 m_touchInfoMap[touchPoint.id()].ownership = OwnershipRequested;
68 m_touchInfoMap[touchPoint.id()].ownership = OwnershipRequested;
64 m_touchInfoMap[touchPoint.id()].ended = false;
69 m_touchInfoMap[touchPoint.id()].ended = false;
65 TouchRegistry::instance()->requestTouchOwnership(touchPoint.id(), this);
70 TouchRegistry::instance()->requestTouchOwnership(touchPoint.id(), this);
plugins/Ubuntu/Gestures/TouchGate.h+3−2
@@ -19,6 +19,7 @@
20#include "UbuntuGesturesQmlGlobal.h"
20#include "UbuntuGesturesQmlGlobal.h"
21#include "TouchDispatcher.h"
21#include "TouchDispatcher.h"
22+#include <UbuntuGestures/ubuntugesturesglobal.h>
23#include <QQuickItem>
24#include <QQuickItem>
24#include <QList>
25#include <QList>
@@ -26,7 +27,7 @@
27#define TOUCHGATE_DEBUG 0
28#define TOUCHGATE_DEBUG 0
29−class TouchOwnershipEvent;
30+UG_FORWARD_DECLARE_CLASS(TouchOwnershipEvent)
32 Blocks the passage of events until ownership over the related touch points is granted.
33 Blocks the passage of events until ownership over the related touch points is granted.
@@ -82,7 +83,7 @@ private:
82 ulong timestamp;
83 ulong timestamp;
85− void touchOwnershipEvent(TouchOwnershipEvent *event);
86+ void touchOwnershipEvent(UG_PREPEND_NAMESPACE(TouchOwnershipEvent) *event);
86 bool isTouchPointOwned(int touchId) const;
87 bool isTouchPointOwned(int touchId) const;
87 void storeTouchEvent(QTouchDevice *device,
88 void storeTouchEvent(QTouchDevice *device,
88 Qt::KeyboardModifiers modifiers,
89 Qt::KeyboardModifiers modifiers,
plugins/Ubuntu/Gestures/TouchGestureArea.cpp+22−21
@@ -16,9 +16,9 @@
17#include "TouchGestureArea.h"
17#include "TouchGestureArea.h"
19−#include <UbuntuGestures/TouchOwnershipEvent>
19+#include <UbuntuGestures/private/touchownershipevent_p.h>
20−#include <UbuntuGestures/TouchRegistry>
20+#include <UbuntuGestures/private/touchregistry_p.h>
21−#include <UbuntuGestures/UnownedTouchEvent>
21+#include <UbuntuGestures/private/unownedtouchevent_p.h>
22// #include "TouchRegistry.h"
22// #include "TouchRegistry.h"
23// #include "UnownedTouchEvent.h"
23// #include "UnownedTouchEvent.h"
@@ -26,6 +26,8 @@
26#include <QStyleHints>
26#include <QStyleHints>
27#include <private/qquickwindow_p.h>
27#include <private/qquickwindow_p.h>
29#define TOUCHGESTUREAREA_DEBUG 0
31#define TOUCHGESTUREAREA_DEBUG 0
31// TODO - understand more about why we lose touch event releases.
33// TODO - understand more about why we lose touch event releases.
@@ -135,7 +137,7 @@ TouchGestureArea::TouchGestureArea(QQuickItem* parent)
135 , m_recognitionPeriod(50)
137 , m_recognitionPeriod(50)
136 , m_releaseRejectPeriod(100)
138 , m_releaseRejectPeriod(100)
138− setRecognitionTimer(new UbuntuGestures::Timer(this));
140+ setRecognitionTimer(new Timer(this));
139 m_recognitionTimer->setInterval(m_recognitionPeriod);
141 m_recognitionTimer->setInterval(m_recognitionPeriod);
140 m_recognitionTimer->setSingleShot(true);
142 m_recognitionTimer->setSingleShot(true);
@@ -153,10 +155,10 @@ bool TouchGestureArea::event(QEvent *event)
154 // Process unowned touch events (handles update/release for incomplete gestures)
156 // Process unowned touch events (handles update/release for incomplete gestures)
155 if (event->type() == TouchOwnershipEvent::touchOwnershipEventType()) {
157 if (event->type() == TouchOwnershipEvent::touchOwnershipEventType()) {
156− touchOwnershipEvent(static_cast<TouchOwnershipEvent *>(event));
158+ touchOwnershipEvent(static_cast<TouchOwnershipEvent*>(event));
157 return true;
159 return true;
158 } else if (event->type() == UnownedTouchEvent::unownedTouchEventType()) {
160 } else if (event->type() == UnownedTouchEvent::unownedTouchEventType()) {
159− unownedTouchEvent(static_cast<UnownedTouchEvent *>(event)->touchEvent());
161+ unownedTouchEvent(static_cast<UnownedTouchEvent*>(event)->touchEvent());
160 return true;
162 return true;
@@ -326,6 +328,12 @@ void TouchGestureArea::touchEvent_rejected(QTouchEvent *event)
332+ // If this event is a new touch, ignore it and let the item below have it.
333+ // We won't recognize any new touch until the whole current gesture is done
334+ // i.e. we're in WaitingForTouch state.
335+ // And even if it isn't, just ignore it anyway; we don't care about it.
331void TouchGestureArea::unownedTouchEvent(QTouchEvent *unownedTouchEvent)
339void TouchGestureArea::unownedTouchEvent(QTouchEvent *unownedTouchEvent)
@@ -375,7 +383,7 @@ void TouchGestureArea::unownedTouchEvent_waitingForMoreTouches(QTouchEvent *even
378− if (m_candidateTouches.count() == 0) {
386+ if (m_candidateTouches.isEmpty()) {
379 setInternalStatus(InternalStatus::WaitingForTouch);
387 setInternalStatus(InternalStatus::WaitingForTouch);
@@ -439,7 +447,7 @@ void TouchGestureArea::unownedTouchEvent_rejected(QTouchEvent *event)
442− if (m_watchedTouches.count() == 0) {
450+ if (m_watchedTouches.isEmpty()) {
443 setInternalStatus(InternalStatus::WaitingForTouch);
451 setInternalStatus(InternalStatus::WaitingForTouch);
@@ -527,7 +535,7 @@ void TouchGestureArea::updateTouchPoints(QTouchEvent *touchEvent)
527 if (updateable) {
535 if (updateable) {
528 if (!dragging() && m_status == InternalStatus::Recognized) {
536 if (!dragging() && m_status == InternalStatus::Recognized) {
529 bool allWantDrag = !m_liveTouchPoints.isEmpty();
537 bool allWantDrag = !m_liveTouchPoints.isEmpty();
530− Q_FOREACH(auto point, m_liveTouchPoints) {
538+ Q_FOREACH(const auto &point, m_liveTouchPoints) {
531 allWantDrag &= point->dragging();
539 allWantDrag &= point->dragging();
533 // only dragging if all points are dragging.
541 // only dragging if all points are dragging.
@@ -608,7 +616,7 @@ void TouchGestureArea::setInternalStatus(uint newStatus)
611−void TouchGestureArea::setRecognitionTimer(UbuntuGestures::AbstractTimer *timer)
619+void TouchGestureArea::setRecognitionTimer(AbstractTimer *timer)
613 int interval = 0;
621 int interval = 0;
614 bool timerWasRunning = false;
622 bool timerWasRunning = false;
@@ -646,11 +654,9 @@ bool TouchGestureArea::dragging() const
646QQmlListProperty<GestureTouchPoint> TouchGestureArea::touchPoints()
654QQmlListProperty<GestureTouchPoint> TouchGestureArea::touchPoints()
648 return QQmlListProperty<GestureTouchPoint>(this,
656 return QQmlListProperty<GestureTouchPoint>(this,
650− nullptr,
657+ nullptr,
651− TouchGestureArea::touchPoint_count,
658+ TouchGestureArea::touchPoint_count,
652− TouchGestureArea::touchPoint_at,
659+ TouchGestureArea::touchPoint_at);
656int TouchGestureArea::minimumTouchPoints() const
662int TouchGestureArea::minimumTouchPoints() const
@@ -721,7 +727,7 @@ void TouchGestureArea::rejectGesture()
722 m_candidateTouches.clear();
728 m_candidateTouches.clear();
724− if (m_watchedTouches.count() == 0) {
730+ if (m_watchedTouches.isEmpty()) {
725 setInternalStatus(InternalStatus::WaitingForTouch);
731 setInternalStatus(InternalStatus::WaitingForTouch);
727 setInternalStatus(InternalStatus::Rejected);
733 setInternalStatus(InternalStatus::Rejected);
@@ -735,7 +741,6 @@ void TouchGestureArea::resyncCachedTouchPoints()
735 bool added = false;
741 bool added = false;
736 bool ended = false;
742 bool ended = false;
737 bool moved = false;
743 bool moved = false;
738− bool wantsDrag = false;
740 // list of deletes
745 // list of deletes
741 QMutableHashIterator<int, GestureTouchPoint*> removeIter(m_cachedTouchPoints);
746 QMutableHashIterator<int, GestureTouchPoint*> removeIter(m_cachedTouchPoints);
@@ -765,10 +770,6 @@ void TouchGestureArea::resyncCachedTouchPoints()
768− if (wantsDrag && !dragging()) {
772 if (ended) {
773 if (ended) {
773 if (m_cachedTouchPoints.isEmpty()) {
774 if (m_cachedTouchPoints.isEmpty()) {
774 if (!dragging()) Q_EMIT clicked();
775 if (!dragging()) Q_EMIT clicked();
plugins/Ubuntu/Gestures/TouchGestureArea.h+17−16
@@ -21,10 +21,11 @@
22#include <QQuickItem>
22#include <QQuickItem>
24−#include <UbuntuGestures/Timer>
24+#include <UbuntuGestures/ubuntugesturesglobal.h>
25+#include <UbuntuGestures/private/timer_p.h>
26−class TouchOwnershipEvent;
27+UG_FORWARD_DECLARE_CLASS(TouchOwnershipEvent)
27−class UnownedTouchEvent;
28+UG_FORWARD_DECLARE_CLASS(UnownedTouchEvent)
29class GestureTouchPoint : public QObject
30class GestureTouchPoint : public QObject
@@ -75,7 +76,7 @@ public:
75 return *this;
76 return *this;
78− bool operator=(const GestureTouchPoint& rhs) const {
79+ bool operator==(const GestureTouchPoint& rhs) const {
79 if (&rhs == this) return true;
80 if (&rhs == this) return true;
80 return m_id == rhs.m_id &&
81 return m_id == rhs.m_id &&
81 m_pressed == rhs.m_pressed &&
82 m_pressed == rhs.m_pressed &&
@@ -83,7 +84,7 @@ public:
83 m_y == rhs.m_y &&
84 m_y == rhs.m_y &&
84 m_dragging == rhs.m_dragging;
85 m_dragging == rhs.m_dragging;
86− bool operator!=(const GestureTouchPoint& rhs) const { return !operator=(rhs); }
87+ bool operator!=(const GestureTouchPoint& rhs) const { return !operator==(rhs); }
88 void setPos(const QPointF &pos);
89 void setPos(const QPointF &pos);
@@ -105,15 +106,14 @@ private:
106 An area that detects multi-finger gestures.
107 An area that detects multi-finger gestures.
108− We can use this to detect gestures contstrained by a minimim and/or maximum number of touch points.
109+ We can use this to detect gestures constrained by a minimum and/or maximum number of touch points.
109− This components uses the touch registry to apply for ownership of touch points.
110+ This component uses the touch registry to apply for ownership of touch points.
110 This way we can use the component in conjuntion with the directional drag area to compete for ownwership
111 This way we can use the component in conjuntion with the directional drag area to compete for ownwership
111 or gestures; unlike the MultiPointTouchArea.
112 or gestures; unlike the MultiPointTouchArea.
113class UBUNTUGESTURESQML_EXPORT TouchGestureArea : public QQuickItem
114class UBUNTUGESTURESQML_EXPORT TouchGestureArea : public QQuickItem
118 Q_PROPERTY(int status READ status NOTIFY statusChanged)
118 Q_PROPERTY(int status READ status NOTIFY statusChanged)
119 Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
119 Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
@@ -136,12 +136,13 @@ public:
136 Recognized,
136 Recognized,
139− TouchGestureArea(QQuickItem* parent = NULL);
140+ TouchGestureArea(QQuickItem* parent = nullptr);
140 ~TouchGestureArea();
141 ~TouchGestureArea();
142 bool event(QEvent *e) override;
143 bool event(QEvent *e) override;
144− void setRecognitionTimer(UbuntuGestures::AbstractTimer *timer);
145+ void setRecognitionTimer(UG_PREPEND_NAMESPACE(AbstractTimer) *timer);
146 int status() const;
147 int status() const;
147 bool dragging() const;
148 bool dragging() const;
@@ -164,10 +165,10 @@ Q_SIGNALS:
165 void touchPointsUpdated();
166 void touchPointsUpdated();
166 void draggingChanged(bool dragging);
167 void draggingChanged(bool dragging);
167− void minimumTouchPointsChanged(bool value);
168+ void minimumTouchPointsChanged(int value);
168− void maximumTouchPointsChanged(bool value);
169+ void maximumTouchPointsChanged(int value);
169− void recognitionPeriodChanged(bool value);
170+ void recognitionPeriodChanged(int value);
170− void releaseRejectPeriodChanged(bool value);
171+ void releaseRejectPeriodChanged(int value);
172 void pressed(const QList<QObject*>& points);
173 void pressed(const QList<QObject*>& points);
173 void released(const QList<QObject*>& points);
174 void released(const QList<QObject*>& points);
@@ -194,7 +195,7 @@ private:
194 void unownedTouchEvent_recognised(QTouchEvent *unownedTouchEvent);
195 void unownedTouchEvent_recognised(QTouchEvent *unownedTouchEvent);
195 void unownedTouchEvent_rejected(QTouchEvent *unownedTouchEvent);
196 void unownedTouchEvent_rejected(QTouchEvent *unownedTouchEvent);
197− void touchOwnershipEvent(TouchOwnershipEvent *event);
198+ void touchOwnershipEvent(UG_PREPEND_NAMESPACE(TouchOwnershipEvent) *event);
198 void updateTouchPoints(QTouchEvent *event);
199 void updateTouchPoints(QTouchEvent *event);
200 GestureTouchPoint* addTouchPoint(const QTouchEvent::TouchPoint *tp);
201 GestureTouchPoint* addTouchPoint(const QTouchEvent::TouchPoint *tp);
@@ -209,7 +210,7 @@ private:
209 uint m_status;
210 uint m_status;
210 QSet<int> m_candidateTouches;
211 QSet<int> m_candidateTouches;
211 QSet<int> m_watchedTouches;
212 QSet<int> m_watchedTouches;
212− UbuntuGestures::AbstractTimer *m_recognitionTimer;
213+ UG_PREPEND_NAMESPACE(AbstractTimer) *m_recognitionTimer;
214 bool m_dragging;
215 bool m_dragging;
215 QHash<int, GestureTouchPoint*> m_liveTouchPoints;
216 QHash<int, GestureTouchPoint*> m_liveTouchPoints;
plugins/Ubuntu/Payments/CMakeLists.txtdeleted−20
@@ -1,20 +0,0 @@
2− ${CMAKE_CURRENT_SOURCE_DIR}
3− ${CMAKE_CURRENT_BINARY_DIR}
11−add_library(Payments MODULE ${PAYMENTS_SOURCES})
13−qt5_use_modules(Payments Qml Quick DBus Core)
15−add_unity8_plugin(Ubuntu.Payments 0.1 Ubuntu/Payments TARGETS Payments)
17−pkg_check_modules(LIBPAY REQUIRED pay-2)
18−add_definitions(${LIBPAY_CFLAGS} ${LIBPAY_CFLAGS_OTHER})
20−target_link_libraries(Payments ${LIBPAY_LDFLAGS})
plugins/Ubuntu/Payments/Payments.cppdeleted−136
@@ -1,136 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
21−#include <libpay/pay-package.h>
24−// The observer callback for the package we are watching.
25−static void observer(PayPackage* /* package */, const char* itemid, PayPackageItemStatus status, void* user_data) {
26− // This function is called in libpay's thread, so be careful what you call
27− // Emitting signals should be fine as long as they use Queued or Auto
28− // connections (the default)
29− // http://qt-project.org/doc/qt-5/threads-qobject.html#signals-and-slots-across-threads
31− Payments *self = static_cast<Payments*>(user_data);
33− // If the item ID is different, ignore it.
34− if (itemid != self->storeItemId()) {
38− // FIXME: No error reporting from libpay, but we need to show some
39− // types of errors to the user. https://launchpad.net/bugs/1333403
41− case PAY_PACKAGE_ITEM_STATUS_PURCHASED:
42− Q_EMIT self->purchaseCompleted();
44− case PAY_PACKAGE_ITEM_STATUS_PURCHASING:
45− self->setPurchasing(true);
47− case PAY_PACKAGE_ITEM_STATUS_NOT_PURCHASED:
48− if (self->purchasing()) {
49− self->setPurchasing(false);
50− Q_EMIT self->purchaseCancelled();
58−Payments::Payments(QObject *parent)
62− m_package = pay_package_new("click-scope");
63− pay_package_item_observer_install(m_package, observer, this);
68− pay_package_item_observer_uninstall(m_package, observer, this);
69− pay_package_delete(m_package);
72−QString Payments::currency() const
77−double Payments::price() const
82−QString Payments::storeItemId() const
84− return m_store_item_id;
87−QString Payments::formattedPrice() const
90− return locale.toCurrencyString(m_price, m_currency);
93−bool Payments::purchasing() const
98−void Payments::setCurrency(const QString ¤cy)
100− if(m_currency != currency) {
101− m_currency = currency;
102− Q_EMIT currencyChanged(currency);
103− Q_EMIT formattedPriceChanged(formattedPrice());
107−void Payments::setPrice(const double price)
109− if(m_price != price) {
111− Q_EMIT priceChanged(price);
112− Q_EMIT formattedPriceChanged(formattedPrice());
116−void Payments::setStoreItemId(const QString &store_item_id)
118− if (m_store_item_id != store_item_id) {
119− m_store_item_id = store_item_id;
120− Q_EMIT storeItemIdChanged(m_store_item_id);
123− if (m_store_item_id.isEmpty()) {
128−void Payments::setPurchasing(bool is_purchasing)
130− m_purchasing = is_purchasing;
133−void Payments::start()
135− pay_package_item_start_purchase(m_package, m_store_item_id.toLocal8Bit().data());
plugins/Ubuntu/Payments/Payments.hdeleted−69
@@ -1,69 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
22−#include <libpay/pay-package.h>
25−class Payments : public QObject
28− Q_DISABLE_COPY(Payments)
29− Q_PROPERTY(QString currency READ currency WRITE setCurrency NOTIFY currencyChanged)
30− Q_PROPERTY(double price READ price WRITE setPrice NOTIFY priceChanged)
31− Q_PROPERTY(QString storeItemId READ storeItemId WRITE setStoreItemId NOTIFY storeItemIdChanged)
32− Q_PROPERTY(QString formattedPrice READ formattedPrice NOTIFY formattedPriceChanged)
35− explicit Payments(QObject *parent = 0);
38− QString currency() const;
39− double price() const;
40− QString storeItemId() const;
41− QString formattedPrice() const;
42− bool purchasing() const;
44− void setCurrency(const QString& currency);
45− void setPrice(const double price);
46− void setStoreItemId(const QString& store_item_id);
47− void setPurchasing(bool is_purchasing);
48− Q_INVOKABLE void start();
51− void currencyChanged(const QString& currency);
52− void priceChanged(const double price);
53− void storeItemIdChanged(const QString &store_item_id);
54− void formattedPriceChanged(const QString &formatted_price);
56− void purchaseError(const QString &error);
57− void purchaseCompleted();
58− void purchaseCancelled();
63− QString m_store_item_id;
66− PayPackage *m_package;
plugins/Ubuntu/Payments/Payments.qmltypesdeleted−43
@@ -1,43 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Ubuntu.Payments 0.1 plugins'
13− exports: ["Ubuntu.Payments/Payments 0.1"]
14− exportMetaObjectRevisions: [0]
15− Property { name: "currency"; type: "string" }
16− Property { name: "price"; type: "double" }
17− Property { name: "storeItemId"; type: "string" }
18− Property { name: "formattedPrice"; type: "string"; isReadonly: true }
20− name: "currencyChanged"
21− Parameter { name: "currency"; type: "string" }
25− Parameter { name: "price"; type: "double" }
28− name: "storeItemIdChanged"
29− Parameter { name: "store_item_id"; type: "string" }
32− name: "formattedPriceChanged"
33− Parameter { name: "formatted_price"; type: "string" }
36− name: "purchaseError"
37− Parameter { name: "error"; type: "string" }
39− Signal { name: "purchaseCompleted" }
40− Signal { name: "purchaseCancelled" }
41− Method { name: "start" }
plugins/Ubuntu/Payments/qmldirdeleted−3
@@ -1,3 +0,0 @@
3−typeinfo Payments.qmltypes
plugins/Ubuntu/SystemImage/CMakeLists.txtdeleted−10
@@ -1,10 +0,0 @@
1−set(SYSTEMIMAGE_SOURCES
6−add_library(SystemImage MODULE ${SYSTEMIMAGE_SOURCES})
8−qt5_use_modules(SystemImage Qml DBus Core)
10−add_unity8_plugin(Ubuntu.SystemImage 0.1 Ubuntu/SystemImage TARGETS SystemImage)
plugins/Ubuntu/SystemImage/SystemImage.cppdeleted−33
@@ -1,33 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
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.
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.
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/>.
17−#include "SystemImage.h"
18−#include <QDBusConnection>
19−#include <QDBusPendingCall>
21−SystemImage::SystemImage(QObject *parent)
26−void SystemImage::factoryReset()
28− const QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("com.canonical.SystemImage"),
29− QStringLiteral("/Service"),
30− QStringLiteral("com.canonical.SystemImage"),
31− QStringLiteral("FactoryReset"));
32− QDBusConnection::systemBus().asyncCall(msg);
plugins/Ubuntu/SystemImage/SystemImage.qmltypesdeleted−19
@@ -1,19 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Ubuntu.SystemImage 0.1 plugins'
13− exports: ["Ubuntu.SystemImage/SystemImage 0.1"]
16− exportMetaObjectRevisions: [0]
17− Method { name: "factoryReset" }
plugins/Ubuntu/SystemImage/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Ubuntu.SystemImage
3−typeinfo SystemImage.qmltypes
plugins/Unity/ApplicationMenu/CMakeLists.txtnew file+19
@@ -0,0 +1,19 @@
1+find_package(Qt5DBus REQUIRED)
4+ ${CMAKE_CURRENT_SOURCE_DIR}
5+ ${CMAKE_CURRENT_BINARY_DIR}
8+set(applicationMenu_SRCS
9+ applicationmenuregistry.cpp
10+ dbusapplicationmenuregistry.cpp
13+qt5_add_dbus_adaptor(applicationMenu_SRCS com.ubuntu.MenuRegistrar.xml dbusapplicationmenuregistry.h DBusApplicationMenuRegistry)
15+add_library(ApplicationMenu-qml MODULE ${applicationMenu_SRCS})
17+target_link_libraries(ApplicationMenu-qml Qt5::DBus Qt5::Qml)
19+add_unity8_plugin(Unity.ApplicationMenu 0.1 Unity/ApplicationMenu TARGETS ApplicationMenu-qml)
plugins/Unity/ApplicationMenu/applicationmenuregistry.cppnew file+141
@@ -0,0 +1,141 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
17+#include "applicationmenuregistry.h"
22+Q_LOGGING_CATEGORY(UNITY_APPMENU, "unity.appmenu", QtDebugMsg)
24+#define DEBUG_MSG qCDebug(UNITY_APPMENU).nospace().noquote() << "ApplicationMenuRegistry::" << __func__
25+#define WARNING_MSG qCWarning(UNITY_APPMENU).nospace().noquote() << "ApplicationMenuRegistry::" << __func__
27+ApplicationMenuRegistry::ApplicationMenuRegistry(QObject *parent)
32+ApplicationMenuRegistry::~ApplicationMenuRegistry()
34+ qDeleteAll(m_appMenus);
37+ qDeleteAll(m_surfaceMenus);
38+ m_surfaceMenus.clear();
41+void ApplicationMenuRegistry::RegisterAppMenu(pid_t processId,
42+ const QDBusObjectPath &menuObjectPath,
43+ const QDBusObjectPath &actionObjectPath,
44+ const QString &service)
46+ DEBUG_MSG << "(pid=" << processId
47+ << ", menuPath=" << menuObjectPath.path()
48+ << ", actionPath=" << actionObjectPath.path()
49+ << ", service=" << service;
51+ auto i = m_appMenus.find(processId);
52+ while (i != m_appMenus.end() && i.key() == processId) {
53+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
54+ WARNING_MSG << "Already have a menu for application (pid= " << processId
55+ << ", service=" << service
56+ << ", menuPath=" << menuObjectPath.path() << ")";
62+ auto menu = new MenuServicePath(service, menuObjectPath, actionObjectPath);
63+ QQmlEngine::setObjectOwnership(menu, QQmlEngine::CppOwnership);
65+ m_appMenus.insert(processId, menu);
66+ Q_EMIT appMenuRegistered(processId);
69+void ApplicationMenuRegistry::UnregisterAppMenu(pid_t processId, const QDBusObjectPath &menuObjectPath)
71+ DEBUG_MSG << "(pid=" << processId
72+ << ", menuPath=" << menuObjectPath.path();
74+ auto i = m_appMenus.find(processId);
75+ while (i != m_appMenus.end() && i.key() == processId) {
76+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
77+ i.value()->deleteLater();
79+ Q_EMIT appMenuUnregistered(processId);
86+void ApplicationMenuRegistry::RegisterSurfaceMenu(const QString &surfaceId,
87+ const QDBusObjectPath &menuObjectPath,
88+ const QDBusObjectPath &actionObjectPath,
89+ const QString &service)
91+ DEBUG_MSG << "(surfaceId=" << surfaceId
92+ << ", menuPath=" << menuObjectPath.path()
93+ << ", actionPath=" << actionObjectPath.path()
94+ << ", service=" << service;
96+ auto i = m_surfaceMenus.find(surfaceId);
97+ while (i != m_surfaceMenus.end() && i.key() == surfaceId) {
98+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
99+ WARNING_MSG << "Already have a menu for surface (surfaceId= " << surfaceId
100+ << ", service=" << service
101+ << ", menuPath=" << menuObjectPath.path() << ")";
107+ auto menu = new MenuServicePath(service, menuObjectPath, actionObjectPath);
108+ QQmlEngine::setObjectOwnership(menu, QQmlEngine::CppOwnership);
110+ m_surfaceMenus.insert(surfaceId, menu);
111+ Q_EMIT surfaceMenuRegistered(surfaceId);
114+void ApplicationMenuRegistry::UnregisterSurfaceMenu(const QString &surfaceId, const QDBusObjectPath &menuObjectPath)
116+ DEBUG_MSG << "(surfaceId=" << surfaceId
117+ << ", menuPath=" << menuObjectPath.path();
119+ auto i = m_surfaceMenus.find(surfaceId);
120+ while (i != m_surfaceMenus.end() && i.key() == surfaceId) {
121+ if (i.value()->m_menuPath == menuObjectPath.path().toUtf8()) {
122+ i.value()->deleteLater();
123+ m_surfaceMenus.erase(i);
124+ Q_EMIT surfaceMenuUnregistered(surfaceId);
131+QList<QObject*> ApplicationMenuRegistry::getMenusForSurface(const QString &surfaceId) const
133+ QList<QObject*> list;
135+ auto i = m_surfaceMenus.find(surfaceId);
136+ while (i != m_surfaceMenus.constEnd() && i.key() == surfaceId) {
plugins/Unity/ApplicationMenu/applicationmenuregistry.hnew file+83
@@ -0,0 +1,83 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
17+#ifndef APPLICATIONMENUREGISTRY_H
18+#define APPLICATIONMENUREGISTRY_H
21+#include <QDBusContext>
22+#include <QDBusObjectPath>
25+Q_DECLARE_LOGGING_CATEGORY(UNITY_APPMENU)
27+class MenuServicePath : public QObject
30+ Q_PROPERTY(QByteArray service MEMBER m_service CONSTANT)
31+ Q_PROPERTY(QByteArray menuPath MEMBER m_menuPath CONSTANT)
32+ Q_PROPERTY(QByteArray actionPath MEMBER m_actionPath CONSTANT)
34+ explicit MenuServicePath(const QString &service,
35+ const QDBusObjectPath &menuPath,
36+ const QDBusObjectPath &actionPath)
37+ : m_service(service.toUtf8())
38+ , m_menuPath(menuPath.path().toUtf8())
39+ , m_actionPath(actionPath.path().toUtf8())
42+ const QByteArray m_service;
43+ const QByteArray m_menuPath;
44+ const QByteArray m_actionPath;
47+class ApplicationMenuRegistry : public QObject
51+ virtual ~ApplicationMenuRegistry();
54+ Q_INVOKABLE QList<QObject*> getMenusForSurface(const QString &surfaceId) const;
57+ void RegisterAppMenu(pid_t processId,
58+ const QDBusObjectPath &menuObjectPath,
59+ const QDBusObjectPath &actionObjectPath,
60+ const QString &service);
61+ void UnregisterAppMenu(pid_t processId, const QDBusObjectPath &menuObjectPath);
63+ void RegisterSurfaceMenu(const QString &surfaceId,
64+ const QDBusObjectPath &menuObjectPath,
65+ const QDBusObjectPath &actionObjectPath,
66+ const QString &service);
67+ void UnregisterSurfaceMenu(const QString &surfaceId, const QDBusObjectPath &menuObjectPath);
70+ void appMenuRegistered(uint processId);
71+ void appMenuUnregistered(uint processId);
73+ void surfaceMenuRegistered(const QString& surfaceId);
74+ void surfaceMenuUnregistered(const QString& surfaceId);
77+ explicit ApplicationMenuRegistry(QObject *parent = 0);
79+ QMultiMap<pid_t, MenuServicePath*> m_appMenus;
80+ QMultiMap<QString, MenuServicePath*> m_surfaceMenus;
83+#endif // APPLICATIONMENUREGISTRY_H
plugins/Unity/ApplicationMenu/com.ubuntu.MenuRegistrar.xmlnew file+83
@@ -0,0 +1,83 @@
1+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
2+<node xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
6+ An interface to register menus that are associated with a window in an application. The
7+ main interface is documented here: @ref com::ubuntu::MenuRegistrar.
9+ The actual menus are transported using the gmenumodel protocol
11+ <interface name="com.ubuntu.MenuRegistrar" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
13+ An interface to register a menu from an application to be displayed in another
14+ window. This manages that association between processes and/or Mir surface IDs and the dbus
15+ address and object that provides the menus using the org.gtk.Menus interface.
17+ <method name="RegisterAppMenu">
19+ Associates a gmenumodel with an application
21+ /note this method assumes that the connection from the caller is the DBus connection
22+ to use for the object. Applications that use multiple DBus connections will need to
23+ ensure this method is called with the same connection that implements the object.
25+ <arg name="pid" type="u" direction="in">
26+ <dox:d>The process ID of the application for which the menu is associated</dox:d>
28+ <arg name="menuObjectPath" type="o" direction="in">
29+ <dox:d>The dbus path where the gmenumodel interface for the application menu has been exported</dox:d>
31+ <arg name="actionObjectPath" type="o" direction="in">
32+ <dox:d>The dbus path where the gactionmenu interface for the application menu actions has been exported</dox:d>
34+ <arg name="service" type="s" direction="in">
35+ <dox:d>The dbus conection name of the client application to be registered (e.g. :1.23 or org.example.service)</dox:d>
38+ <method name="UnregisterAppMenu">
40+ A method to allow removing an application menu from the database.
42+ <arg name="pid" type="u" direction="in">
43+ <dox:d>The process id of the application</dox:d>
45+ <arg name="menuObjectPath" type="o" direction="in">
46+ <dox:d>The dbus path for the registered application menu to be unregistered</dox:d>
50+ <method name="RegisterSurfaceMenu">
52+ Associates a gmenumodel with a surface
54+ /note this method assumes that the connection from the caller is the DBus connection
55+ to use for the object. Applications that use multiple DBus connections will need to
56+ ensure this method is called with the same connection that implements the object.
58+ <arg name="surface" type="s" direction="in">
59+ <dox:d>The surface ID of the surface</dox:d>
61+ <arg name="menuObjectPath" type="o" direction="in">
62+ <dox:d>The dbus path where the gmenumodel interface for the surface menu has been exported</dox:d>
64+ <arg name="actionObjectPath" type="o" direction="in">
65+ <dox:d>The dbus path where the gactionmenu interface for the surface menu actions has been exported</dox:d>
67+ <arg name="service" type="s" direction="in">
68+ <dox:d>The dbus conection name of the client application to be registered (e.g. :1.23 or org.example.service)</dox:d>
71+ <method name="UnregisterSurfaceMenu">
73+ A method to allow removing a surface menu from the database.
75+ <arg name="surfaceId" type="s" direction="in">
76+ <dox:d>The surface id of the surface</dox:d>
78+ <arg name="menuObjectPath" type="o" direction="in">
79+ <dox:d>The dbus path for the registered surface menu to be unregistered</dox:d>
plugins/Unity/ApplicationMenu/dbusapplicationmenuregistry.cppnew file+44
@@ -0,0 +1,44 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
17+#include "dbusapplicationmenuregistry.h"
18+#include "menuregistraradaptor.h"
20+DBusApplicationMenuRegistry::DBusApplicationMenuRegistry(QObject *parent)
21+ : ApplicationMenuRegistry(parent)
23+ new MenuRegistrarAdaptor(this);
25+ QDBusConnection connection = QDBusConnection::sessionBus();
26+ if (!connection.registerObject("/com/ubuntu/MenuRegistrar", this)) {
27+ qCWarning(UNITY_APPMENU) << "Unable to register DBus object /com/ubuntu/MenuRegistrar";
29+ if (!connection.registerService("com.ubuntu.MenuRegistrar")) {
30+ qCWarning(UNITY_APPMENU) << "Unable to register DBus service com.ubuntu.MenuRegistrar";
34+DBusApplicationMenuRegistry::~DBusApplicationMenuRegistry()
36+ QDBusConnection connection = QDBusConnection::sessionBus();
37+ connection.unregisterObject("/com/ubuntu/MenuRegistrar");
40+ApplicationMenuRegistry *DBusApplicationMenuRegistry::instance()
42+ static ApplicationMenuRegistry* reg(new DBusApplicationMenuRegistry());
plugins/IntegratedLightDM/plugin.h → plugins/Unity/ApplicationMenu/dbusapplicationmenuregistry.hrenamed+12−11
@@ -1,5 +1,5 @@
2− * Copyright (C) 2012,2013, 2015 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -12,22 +12,23 @@
13 * You should have received a copy of the GNU General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18−#ifndef INTEGRATED_LIGHTDM_PLUGIN_H
17+#ifndef DBUSAPPLICATIONMENUREGISTRY_H
19−#define INTEGRATED_LIGHTDM_PLUGIN_H
18+#define DBUSAPPLICATIONMENUREGISTRY_H
21−#include <QtQml/QQmlEngine>
20+#include "applicationmenuregistry.h"
22−#include <QtQml/QQmlExtensionPlugin>
24−class IntegratedLightDMPlugin : public QQmlExtensionPlugin
22+class DBusApplicationMenuRegistry : public ApplicationMenuRegistry,
23+ protected QDBusContext
27− Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
30− void registerTypes(const char *uri) override;
27+ ~DBusApplicationMenuRegistry();
28+ static ApplicationMenuRegistry* instance();
31+ explicit DBusApplicationMenuRegistry(QObject *parent = 0);
33−#endif /* INTEGRATED_LIGHTDM_PLUGIN_H */
34+#endif // DBUSAPPLICATIONMENUREGISTRY_H
plugins/Unity/ApplicationMenu/plugin.cppnew file+42
@@ -0,0 +1,42 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
18+#include "dbusapplicationmenuregistry.h"
22+static QObject *menuRegistry(QQmlEngine *engine, QJSEngine *scriptEngine)
25+ Q_UNUSED(scriptEngine)
26+ return DBusApplicationMenuRegistry::instance();
29+void ApplicationMenuPlugin::registerTypes(const char *uri)
31+ Q_ASSERT(uri == QLatin1String("Unity.ApplicationMenu"));
33+ qmlRegisterUncreatableType<MenuServicePath>(uri, 0, 1, "MenuServicePath", "You cannot create a MenuServicePath");
34+ qmlRegisterSingletonType<DBusApplicationMenuRegistry>(uri, 0, 1, "ApplicationMenuRegistry", menuRegistry);
37+void ApplicationMenuPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
39+ QQmlExtensionPlugin::initializeEngine(engine, uri);
41+ menuRegistry(nullptr, nullptr);
tests/mocks/Ubuntu/SystemImage/plugin.h → plugins/Unity/ApplicationMenu/plugin.hrenamed+6−5
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -14,18 +14,19 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#ifndef MOCK_SYSTEMIMAGE_PLUGIN_H
17+#ifndef APPLICATIONMENU_PLUGIN_H
18−#define MOCK_SYSTEMIMAGE_PLUGIN_H
18+#define APPLICATIONMENU_PLUGIN_H
20#include <QQmlExtensionPlugin>
20#include <QQmlExtensionPlugin>
22−class BackendPlugin : public QQmlExtensionPlugin
22+class ApplicationMenuPlugin : public QQmlExtensionPlugin
25 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
25 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
28 void registerTypes(const char *uri) override;
28 void registerTypes(const char *uri) override;
29+ void initializeEngine(QQmlEngine *engine, const char *uri) override;
31−#endif // MOCK_SYSTEMIMAGE_PLUGIN_H
32+#endif // APPLICATIONMENU_PLUGIN_H
plugins/Unity/ApplicationMenu/qmldirnew file+3
@@ -0,0 +1,3 @@
1+module Unity.ApplicationMenu
2+plugin ApplicationMenu-qml
3+typeinfo ApplicationMenu.qmltypes
plugins/Unity/CMakeLists.txt+1−1
@@ -1,7 +1,7 @@
1+add_subdirectory(ApplicationMenu)
1add_subdirectory(Connectivity)
2add_subdirectory(Connectivity)
2add_subdirectory(Indicators)
3add_subdirectory(Indicators)
3add_subdirectory(Launcher)
4add_subdirectory(Launcher)
4add_subdirectory(Session)
5add_subdirectory(Session)
5−add_subdirectory(DashCommunicator)
6add_subdirectory(InputInfo)
6add_subdirectory(InputInfo)
7add_subdirectory(Platform)
7add_subdirectory(Platform)
plugins/Unity/Connectivity/CMakeLists.txt+1−1
@@ -5,6 +5,6 @@ set(CONNECTIVITY_SOURCES
6add_library(Connectivity MODULE ${CONNECTIVITY_SOURCES})
6add_library(Connectivity MODULE ${CONNECTIVITY_SOURCES})
8−qt5_use_modules(Connectivity Qml DBus Core)
8+target_link_libraries(Connectivity Qt5::Qml Qt5::DBus Qt5::Core)
10add_unity8_plugin(Unity.Connectivity 0.1 Unity/Connectivity TARGETS Connectivity)
10add_unity8_plugin(Unity.Connectivity 0.1 Unity/Connectivity TARGETS Connectivity)
plugins/Unity/Connectivity/Connectivity.qmltypesdeleted−19
@@ -1,19 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.Connectivity 0.1 plugins'
13− exports: ["Unity.Connectivity/Connectivity 0.1"]
16− exportMetaObjectRevisions: [0]
17− Method { name: "unlockAllModems" }
plugins/Unity/DashCommunicator/CMakeLists.txtdeleted−25
@@ -1,25 +0,0 @@
2− ${CMAKE_CURRENT_SOURCE_DIR}
3− ${libunity8-private_SOURCE_DIR}
6−set(QMLDASHCOMMUNICATORPLUGIN_SRC
8− dbusdashcommunicatorservice.cpp
9− dashcommunicatorservice.cpp
14−add_library(DashCommunicator-qml MODULE
15− ${QMLDASHCOMMUNICATORPLUGIN_SRC}
18−qt5_use_modules(DashCommunicator-qml DBus Qml)
20−target_link_libraries(DashCommunicator-qml
24−# export the qmldir and qmltypes files
25−add_unity8_plugin(Unity.DashCommunicator 0.1 Unity/DashCommunicator TARGETS DashCommunicator-qml)
plugins/Unity/DashCommunicator/DashCommunicator.qmltypesdeleted−47
@@ -1,47 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.DashCommunicator 0.1 plugins'
11− name: "DashCommunicator"
13− exports: ["Unity.DashCommunicator/DashCommunicator 0.1"]
14− exportMetaObjectRevisions: [0]
16− name: "setCurrentScope"
17− Parameter { name: "index"; type: "int" }
18− Parameter { name: "animate"; type: "bool" }
19− Parameter { name: "isSwipe"; type: "bool" }
23− name: "DashCommunicatorService"
25− exports: ["Unity.DashCommunicator/DashCommunicatorService 0.1"]
26− exportMetaObjectRevisions: [0]
28− name: "setCurrentScopeRequested"
29− Parameter { name: "index"; type: "int" }
30− Parameter { name: "animate"; type: "bool" }
31− Parameter { name: "isSwipe"; type: "bool" }
37− Signal { name: "started" }
38− Signal { name: "finished" }
41− Parameter { type: "Priority" }
43− Method { name: "start" }
44− Method { name: "terminate" }
45− Method { name: "quit" }
plugins/Unity/DashCommunicator/dashcommunicator.cppdeleted−58
@@ -1,58 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#include "dashcommunicator.h"
18−#include "dashconnection.h"
22−DashCommunicator::DashCommunicator(QObject *parent):
24− m_dashConnection(nullptr),
30−DashCommunicator::~DashCommunicator()
36−void DashCommunicator::setCurrentScope(int index, bool animate, bool isSwipe)
40− QMetaObject::invokeMethod(m_dashConnection, "setCurrentScope",
42− Q_ARG(bool, animate),
43− Q_ARG(bool, isSwipe));
48−void DashCommunicator::run()
50− m_dashConnection = new DashConnection(QStringLiteral("com.canonical.UnityDash"),
51− QStringLiteral("/com/canonical/UnityDash"),
52− QLatin1String(""), this);
plugins/Unity/DashCommunicator/dashcommunicatorservice.cppdeleted−30
@@ -1,30 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#include "dashcommunicatorservice.h"
19−DashCommunicatorService::DashCommunicatorService(QObject *parent):
21− m_dbusService(new DBusDashCommunicatorService(this))
23− connect(m_dbusService, &DBusDashCommunicatorService::setCurrentScopeRequested, this, &DashCommunicatorService::setCurrentScopeRequested);
27−DashCommunicatorService::~DashCommunicatorService()
plugins/Unity/DashCommunicator/dashcommunicatorservice.hdeleted−38
@@ -1,38 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#ifndef DASHCOMMUNICATORSERVICE_H
18−#define DASHCOMMUNICATORSERVICE_H
20−#include "dbusdashcommunicatorservice.h"
24−class DashCommunicatorService: public QObject
28− DashCommunicatorService(QObject *parent = 0);
29− ~DashCommunicatorService();
32− void setCurrentScopeRequested(int index, bool animate, bool isSwipe);
35− DBusDashCommunicatorService *m_dbusService;
38−#endif // DBUSUNITYSESSIONSERVICE_H
plugins/Unity/DashCommunicator/dashconnection.cppdeleted−63
@@ -1,63 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#include "dashconnection.h"
19−#include <QDBusInterface>
20−#include <QDBusPendingCall>
22−/* The default implementation of AbstractDBusServiceMonitor creates a QDBusInterface when the service
23− * appears on the bus.
25− * On construction QDBusInterface synchronously introspects the service, which will block the GUI
26− * thread of this process if the service is busy. QDBusAbstractInterface does not perform this
27− * introspection, so let's subclass that and avoid the blocking scenario.
29− * However we lose Qt's wrapping of the DBus service with a MetaObject, with the result that we
30− * cannot easily connect to DBus signals with the usual connect() calls. So this approach only
31− * suited to push communication with the DBus service.
33−class AsyncDBusInterface : public QDBusAbstractInterface
36− AsyncDBusInterface(const QString &service, const QString &path,
37− const QString &interface, const QDBusConnection &connection,
39− : QDBusAbstractInterface(service, path, interface.toLatin1().data(), connection, parent)
41− ~AsyncDBusInterface() = default;
45−DashConnection::DashConnection(const QString &service, const QString &path, const QString &interface, QObject *parent):
46− AbstractDBusServiceMonitor(service, path, interface, SessionBus, parent)
51−/* Override the default implementation to create a non-blocking DBus interface (see note above). */
52−QDBusAbstractInterface* DashConnection::createInterface(const QString &service, const QString &path,
53− const QString &interface, const QDBusConnection &connection)
55− return new AsyncDBusInterface(service, path, interface, connection);
58−void DashConnection::setCurrentScope(int index, bool animate, bool isSwipe)
60− if (dbusInterface()) {
61− dbusInterface()->asyncCall(QStringLiteral("SetCurrentScope"), index, animate, isSwipe);
plugins/Unity/DashCommunicator/dashconnection.hdeleted−37
@@ -1,37 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#ifndef THREADEDDASHCONNECTION_H
18−#define THREADEDDASHCONNECTION_H
21−#include "abstractdbusservicemonitor.h"
23−class DashConnection: public AbstractDBusServiceMonitor
27− DashConnection(const QString &service, const QString &path, const QString &interface, QObject *parent = 0);
30− void setCurrentScope(int index, bool animate, bool isSwipe);
33− QDBusAbstractInterface* createInterface(const QString &service, const QString &path,
34− const QString &interface, const QDBusConnection &connection) override;
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cppdeleted−35
@@ -1,35 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#include "dbusdashcommunicatorservice.h"
19−#include <QDBusConnection>
20−#include <QDBusInterface>
23−DBusDashCommunicatorService::DBusDashCommunicatorService(QObject *parent):
24− UnityDBusObject(QStringLiteral("/com/canonical/UnityDash"), QStringLiteral("com.canonical.UnityDash"), false, parent)
28−DBusDashCommunicatorService::~DBusDashCommunicatorService()
32−void DBusDashCommunicatorService::SetCurrentScope(int index, bool animate, bool isSwipe)
34− Q_EMIT setCurrentScopeRequested(index, animate, isSwipe);
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.hdeleted−39
@@ -1,39 +0,0 @@
2− * Copyright (C) 2014 Canonical, Ltd.
4− * This program is free software: you can redistribute it and/or modify it under
5− * the terms of the GNU Lesser General Public License version 3, as published by
6− * the Free Software Foundation.
8− * This program is distributed in the hope that it will be useful, but WITHOUT
9− * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10− * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11− * Lesser General Public License for more details.
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/>.
17−#ifndef DBUSDASHCOMMUNICATORSERVICE_H
18−#define DBUSDASHCOMMUNICATORSERVICE_H
20−#include "unitydbusobject.h"
22−class DBusDashCommunicatorService: public UnityDBusObject
25− Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.DashCommunicator")
28− DBusDashCommunicatorService(QObject *parent = 0);
29− ~DBusDashCommunicatorService();
32− void setCurrentScopeRequested(int index, bool animate, bool isSwipe);
35− Q_SCRIPTABLE void SetCurrentScope(int index, bool animate, bool isSwipe);
39−#endif // DBUSDASHCOMMUNICATORSERVICE_H
plugins/Unity/DashCommunicator/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Unity.DashCommunicator
2−plugin DashCommunicator-qml
3−typeinfo DashCommunicator.qmltypes
plugins/Unity/Indicators/CMakeLists.txt+8−2
@@ -6,7 +6,14 @@ find_package(Qt5Quick REQUIRED)
6include_directories(
6include_directories(
7 ${CMAKE_CURRENT_SOURCE_DIR}
7 ${CMAKE_CURRENT_SOURCE_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
8 ${CMAKE_CURRENT_BINARY_DIR}
9 ${GLIB_INCLUDE_DIRS}
13 ${GLIB_INCLUDE_DIRS}
10 ${GIO_INCLUDE_DIRS}
17 ${GIO_INCLUDE_DIRS}
11 ${QMENUMODEL_INCLUDE_DIRS}
18 ${QMENUMODEL_INCLUDE_DIRS}
@@ -37,8 +44,7 @@ target_link_libraries(IndicatorsQml
37 ${GLIB_LIBRARIES}
44 ${GLIB_LIBRARIES}
38 ${GIO_LIBRARIES}
45 ${GIO_LIBRARIES}
39 ${QMENUMODEL_LDFLAGS}
46 ${QMENUMODEL_LDFLAGS}
47+ Qt5::Core Qt5::Qml Qt5::Quick Qt5::DBus
42−qt5_use_modules(IndicatorsQml Core Qml Quick DBus)
44add_unity8_plugin(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsQml)
50add_unity8_plugin(Unity.Indicators 0.1 Unity/Indicators TARGETS IndicatorsQml)
plugins/Unity/Indicators/Indicators.qmltypesdeleted−264
@@ -1,264 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.Indicators 0.1 plugins'
11− name: "ActionRootState"
12− prototype: "RootStateObject"
13− exports: ["Unity.Indicators/ActionRootState 0.1"]
14− exportMetaObjectRevisions: [0]
15− Property { name: "actionGroup"; type: "QDBusActionGroup"; isPointer: true }
16− Property { name: "actionName"; type: "string" }
21− exports: ["Unity.Indicators/ActionState 0.1"]
23− exportMetaObjectRevisions: [0]
35− name: "FlatMenuProxyModelRole"
37− exports: ["Unity.Indicators/FlatMenuProxyModelRole 0.1"]
39− exportMetaObjectRevisions: [0]
53− name: "IndicatorsManager"
55− exports: ["Unity.Indicators/IndicatorsManager 0.1"]
56− exportMetaObjectRevisions: [0]
57− Property { name: "loaded"; type: "bool"; isReadonly: true }
58− Property { name: "profile"; type: "string" }
60− name: "loadedChanged"
61− Parameter { type: "bool" }
64− name: "profileChanged"
65− Parameter { type: "string" }
68− name: "indicatorLoaded"
69− Parameter { name: "indicator_name"; type: "string" }
72− name: "indicatorAboutToBeUnloaded"
73− Parameter { name: "indicator_name"; type: "string" }
75− Method { name: "load" }
76− Method { name: "unload" }
79− name: "IndicatorsModel"
80− prototype: "QAbstractListModel"
81− exports: ["Unity.Indicators/IndicatorsModel 0.1"]
82− exportMetaObjectRevisions: [0]
83− Property { name: "count"; type: "int"; isReadonly: true }
84− Property { name: "profile"; type: "string" }
86− name: "indicatorDataChanged"
87− Parameter { name: "data"; type: "QVariant" }
89− Method { name: "load" }
90− Method { name: "unload" }
94− Parameter { name: "row"; type: "int" }
95− Parameter { name: "role"; type: "int" }
99− name: "IndicatorsModelRole"
100− prototype: "QObject"
101− exports: ["Unity.Indicators/IndicatorsModelRole 0.1"]
103− exportMetaObjectRevisions: [0]
109− "IndicatorProperties": 2
114− name: "MenuContentActivator"
115− prototype: "QObject"
116− exports: ["Unity.Indicators/MenuContentActivator 0.1"]
117− exportMetaObjectRevisions: [0]
118− Property { name: "baseIndex"; type: "int" }
119− Property { name: "running"; type: "bool" }
120− Property { name: "count"; type: "int" }
121− Property { name: "content"; type: "MenuContentState"; isList: true; isReadonly: true }
123− name: "baseIndexChanged"
124− Parameter { name: "baseIndex"; type: "int" }
127− name: "deltaChanged"
128− Parameter { name: "delta"; type: "int" }
131− name: "runningChanged"
132− Parameter { name: "running"; type: "bool" }
135− name: "countChanged"
136− Parameter { name: "count"; type: "int" }
138− Method { name: "restart" }
139− Method { name: "stop" }
140− Method { name: "clear" }
142− name: "isMenuContentActive"
144− Parameter { name: "index"; type: "int" }
148− name: "MenuContentState"
149− prototype: "QObject"
150− exports: ["Unity.Indicators/MenuContentState 0.1"]
152− exportMetaObjectRevisions: [0]
153− Property { name: "active"; type: "bool"; isReadonly: true }
156− name: "ModelActionRootState"
157− prototype: "RootStateObject"
158− exports: ["Unity.Indicators/ModelActionRootState 0.1"]
159− exportMetaObjectRevisions: [0]
160− Property { name: "menu"; type: "UnityMenuModel"; isPointer: true }
161− Signal { name: "indexChanged" }
164− name: "ModelPrinter"
165− prototype: "QObject"
166− exports: ["Unity.Indicators/ModelPrinter 0.1"]
167− exportMetaObjectRevisions: [0]
168− Property { name: "model"; type: "UnityMenuModel"; isPointer: true }
169− Property { name: "text"; type: "string"; isReadonly: true }
170− Method { name: "text"; type: "string" }
173− name: "NetworkActionState"
174− prototype: "QObject"
175− exports: ["Unity.Indicators/NetworkActionState 0.1"]
177− exportMetaObjectRevisions: [0]
179− name: "NetworkActionStates"
187− name: "NetworkConnection"
188− prototype: "QObject"
189− exports: ["Unity.Indicators/NetworkConnection 0.1"]
191− exportMetaObjectRevisions: [0]
193− name: "NetworkConnectionStates"
203− name: "RootStateObject"
204− prototype: "QObject"
205− Property { name: "valid"; type: "bool"; isReadonly: true }
206− Property { name: "title"; type: "string"; isReadonly: true }
207− Property { name: "leftLabel"; type: "string"; isReadonly: true }
208− Property { name: "rightLabel"; type: "string"; isReadonly: true }
209− Property { name: "icons"; type: "QStringList"; isReadonly: true }
210− Property { name: "accessibleName"; type: "string"; isReadonly: true }
211− Property { name: "indicatorVisible"; type: "bool"; isReadonly: true }
212− Signal { name: "updated" }
215− name: "SharedUnityMenuModel"
216− prototype: "QObject"
217− exports: ["Unity.Indicators/SharedUnityMenuModel 0.1"]
218− exportMetaObjectRevisions: [0]
219− Property { name: "busName"; type: "QByteArray" }
220− Property { name: "menuObjectPath"; type: "QByteArray" }
221− Property { name: "actions"; type: "QVariantMap" }
222− Property { name: "model"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
225− name: "UnityMenuModelCache"
226− prototype: "QObject"
227− exports: ["Unity.Indicators/UnityMenuModelCache 0.1"]
230− exportMetaObjectRevisions: [0]
234− Parameter { name: "path"; type: "QByteArray" }
238− name: "UnityMenuModelStack"
239− prototype: "QObject"
240− exports: ["Unity.Indicators/UnityMenuModelStack 0.1"]
241− exportMetaObjectRevisions: [0]
242− Property { name: "head"; type: "UnityMenuModel"; isPointer: true }
243− Property { name: "tail"; type: "UnityMenuModel"; isReadonly: true; isPointer: true }
244− Property { name: "count"; type: "int"; isReadonly: true }
247− Parameter { name: "head"; type: "UnityMenuModel"; isPointer: true }
251− Parameter { name: "tail"; type: "UnityMenuModel"; isPointer: true }
254− name: "countChanged"
255− Parameter { name: "count"; type: "int" }
259− Parameter { name: "model"; type: "UnityMenuModel"; isPointer: true }
260− Parameter { name: "menuIndex"; type: "int" }
262− Method { name: "pop"; type: "UnityMenuModel*" }
plugins/Unity/Indicators/actionrootstate.cpp+1−1
@@ -44,7 +44,7 @@ void ActionRootState::setActionGroup(QDBusActionGroup *actionGroup)
44 connect(m_actionGroup, &QDBusActionGroup::statusChanged, this, [&](bool) { updateActionState(); });
44 connect(m_actionGroup, &QDBusActionGroup::statusChanged, this, [&](bool) { updateActionState(); });
45 connect(m_actionGroup, &QDBusActionGroup::actionAppear, this, [&](const QString&) { updateActionState(); });
45 connect(m_actionGroup, &QDBusActionGroup::actionAppear, this, [&](const QString&) { updateActionState(); });
46 connect(m_actionGroup, &QDBusActionGroup::actionVanish, this, [&](const QString&) { updateActionState(); });
46 connect(m_actionGroup, &QDBusActionGroup::actionVanish, this, [&](const QString&) { updateActionState(); });
47− connect(m_actionGroup, &QDBusActionGroup::actionStateChanged, this, [&](QVariant) { updateActionState(); });
47+ connect(m_actionGroup, &QDBusActionGroup::actionStateChanged, this, [&](const QVariant&) { updateActionState(); });
49 connect(m_actionGroup, &QObject::destroyed, this, [&](QObject*) { updateActionState(); });
49 connect(m_actionGroup, &QObject::destroyed, this, [&](QObject*) { updateActionState(); });
plugins/Unity/Indicators/indicators.h+5−5
@@ -27,13 +27,13 @@ class UNITYINDICATORS_EXPORT ActionState : public QObject
30− Q_ENUMS(ActionStates)
31 enum ActionStates {
30 enum ActionStates {
32 Label = 0x00,
31 Label = 0x00,
33 IconSource = 0x01,
32 IconSource = 0x01,
34 AccessableName = 0x02,
33 AccessableName = 0x02,
35 Visible = 0x03,
34 Visible = 0x03,
38 ActionState(QObject*parent=0):QObject(parent) {}
38 ActionState(QObject*parent=0):QObject(parent) {}
@@ -42,11 +42,11 @@ class UNITYINDICATORS_EXPORT NetworkActionState : public QObject
45− Q_ENUMS(NetworkActionStates)
46 enum NetworkActionStates {
45 enum NetworkActionStates {
47 Connection = 0x01,
46 Connection = 0x01,
48 SignalStrength = 0x02,
47 SignalStrength = 0x02,
49+ Q_ENUM(NetworkActionStates)
51 NetworkActionState(QObject*parent=0):QObject(parent) {}
51 NetworkActionState(QObject*parent=0):QObject(parent) {}
@@ -55,13 +55,13 @@ class UNITYINDICATORS_EXPORT NetworkConnection : public QObject
58− Q_ENUMS(NetworkConnectionStates)
59 enum NetworkConnectionStates {
58 enum NetworkConnectionStates {
60 Initial = 0x00,
59 Initial = 0x00,
61 Activating = 0x01,
60 Activating = 0x01,
62 Activated = 0x02,
61 Activated = 0x02,
63 Deactivating = 0x03,
62 Deactivating = 0x03,
64+ Q_ENUM(NetworkConnectionStates)
66 NetworkConnection(QObject*parent=0):QObject(parent) {}
66 NetworkConnection(QObject*parent=0):QObject(parent) {}
@@ -70,12 +70,12 @@ class UNITYINDICATORS_EXPORT IndicatorsModelRole : public QObject
74 enum Roles {
73 enum Roles {
75 Identifier = 0,
74 Identifier = 0,
77 IndicatorProperties
76 IndicatorProperties
80 IndicatorsModelRole(QObject*parent=0):QObject(parent) {}
80 IndicatorsModelRole(QObject*parent=0):QObject(parent) {}
@@ -84,7 +84,6 @@ class UNITYINDICATORS_EXPORT FlatMenuProxyModelRole : public QObject
88 enum Roles {
87 enum Roles {
89 Action = Qt::DisplayRole + 1,
88 Action = Qt::DisplayRole + 1,
@@ -93,6 +92,7 @@ public:
93 hasSection,
92 hasSection,
94 hasSubMenu
93 hasSubMenu
97 FlatMenuProxyModelRole(QObject*parent=0):QObject(parent) {}
97 FlatMenuProxyModelRole(QObject*parent=0):QObject(parent) {}
plugins/Unity/Indicators/indicatorsmanager.cpp+3−8
@@ -114,10 +114,6 @@ void IndicatorsManager::loadFile(const QFileInfo& file_info)
114 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
114 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
115 const QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString();
115 const QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString();
117− if (m_platform.isPC() && name == QLatin1String("indicator-keyboard")) {
118− return; // convergence: skip this indicator until it works in Mir
121 auto iter = m_indicatorsData.constFind(name);
117 auto iter = m_indicatorsData.constFind(name);
122 if (iter != m_indicatorsData.constEnd())
118 if (iter != m_indicatorsData.constEnd())
@@ -285,13 +281,12 @@ Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
286 // convergence:
282 // convergence:
287 // 1) enable session indicator
283 // 1) enable session indicator
288− // 2) on a PC, switch the battery/power indicator to desktop mode,
284+ // 2) enable keyboard indicator
289− // can't control brightness for now and phone-on-desktop broken (FIXME)
291 // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
286 // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
292 if ((new_indicator->identifier() == QStringLiteral("indicator-session"))
287 if ((new_indicator->identifier() == QStringLiteral("indicator-session"))
293− || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) {
288+ || new_indicator->identifier() == QStringLiteral("indicator-keyboard")) {
294− new_indicator->setProfile(QStringLiteral("desktop"));
289+ new_indicator->setProfile(QString(m_profile).replace(QStringLiteral("phone"), QStringLiteral("desktop")));
296 new_indicator->setProfile(m_profile);
291 new_indicator->setProfile(m_profile);
plugins/Unity/Indicators/indicatorsmanager.h−2
@@ -76,8 +76,6 @@ private:
76 QSharedPointer<QFileSystemWatcher> m_fsWatcher;
76 QSharedPointer<QFileSystemWatcher> m_fsWatcher;
77 bool m_loaded;
77 bool m_loaded;
78 QString m_profile;
78 QString m_profile;
83#endif // INDICATORS_MANAGER_H
81#endif // INDICATORS_MANAGER_H
plugins/Unity/Indicators/indicatorsmodel.cpp+13
@@ -103,6 +103,19 @@ void IndicatorsModel::setProfile(const QString &profile)
103 m_manager->setProfile(profile);
103 m_manager->setProfile(profile);
106+bool IndicatorsModel::light() const
111+void IndicatorsModel::setLight(const bool &light)
113+ if (m_light != light) {
115+ Q_EMIT lightChanged();
107 \qmlmethod IndicatorsModel::unload()
120 \qmlmethod IndicatorsModel::unload()
plugins/Unity/Indicators/indicatorsmodel.h+9−1
@@ -32,10 +32,12 @@ class IndicatorsManager;
32class UNITYINDICATORS_EXPORT IndicatorsModel : public QAbstractListModel
32class UNITYINDICATORS_EXPORT IndicatorsModel : public QAbstractListModel
36 Q_PROPERTY(int count READ count NOTIFY countChanged)
35 Q_PROPERTY(int count READ count NOTIFY countChanged)
37 Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
36 Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
39+ Q_PROPERTY(bool light READ light WRITE setLight NOTIFY lightChanged)
41 IndicatorsModel(QObject *parent=nullptr);
43 IndicatorsModel(QObject *parent=nullptr);
@@ -49,6 +51,9 @@ public:
49 QString profile() const;
51 QString profile() const;
50 void setProfile(const QString& profile);
52 void setProfile(const QString& profile);
55+ void setLight(const bool &light);
52 /* QAbstractItemModel */
57 /* QAbstractItemModel */
53 QHash<int, QByteArray> roleNames() const override;
58 QHash<int, QByteArray> roleNames() const override;
54 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
59 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
@@ -61,6 +66,7 @@ Q_SIGNALS:
61 void countChanged();
66 void countChanged();
62 void profileChanged();
67 void profileChanged();
63 void indicatorDataChanged(const QVariant& data);
68 void indicatorDataChanged(const QVariant& data);
65private Q_SLOTS:
71private Q_SLOTS:
66 void onIdentifierChanged();
72 void onIdentifierChanged();
@@ -75,6 +81,8 @@ private:
76 void notifyDataChanged(QObject *sender, int role);
82 void notifyDataChanged(QObject *sender, int role);
77 int count() const;
83 int count() const;
80#endif // INDICATORSMODEL_H
88#endif // INDICATORSMODEL_H
plugins/Unity/Indicators/modelprinter.cpp+19−4
@@ -105,12 +105,25 @@ QString ModelPrinter::getRowSring(UnityMenuModel* sourceModel, int row, int dept
106 Q_FOREACH(int role, roles) {
106 Q_FOREACH(int role, roles) {
107 const QByteArray& roleName = roleNames[role];
107 const QByteArray& roleName = roleNames[role];
108− stream << tabify(depth) << getVariantString(roleName, sourceModel->get(row, roleName));
108+ stream << getVariantString(roleName, sourceModel->get(row, roleName), depth);
110 return str;
110 return str;
113−QString ModelPrinter::getVariantString(const QString& roleName, const QVariant &vData) const
113+QString ModelPrinter::getVariantString(const QVariant& vData) const
115+ if (vData.type() == QVariant::List) {
116+ QStringList strList;
117+ for (const auto& v : vData.toList())
118+ strList.append(getVariantString(v));
120+ return '[' + strList.join(", ") + ']';
123+ return vData.toString();
126+QString ModelPrinter::getVariantString(const QString& roleName, const QVariant &vData, int depth) const
115 QString str;
128 QString str;
116 QTextStream stream(&str);
129 QTextStream stream(&str);
@@ -119,18 +132,20 @@ QString ModelPrinter::getVariantString(const QString& roleName, const QVariant &
119 QMapIterator<QString, QVariant> iter(vData.toMap());
132 QMapIterator<QString, QVariant> iter(vData.toMap());
120 while (iter.hasNext()) {
133 while (iter.hasNext()) {
121 iter.next();
134 iter.next();
135+ stream << tabify(depth);
122 stream << roleName
136 stream << roleName
124 << iter.key()
138 << iter.key()
126− << iter.value().toString()
140+ << getVariantString(iter.value())
145+ stream << tabify(depth);
131 stream << roleName
146 stream << roleName
133− << vData.toString()
148+ << getVariantString(vData)
136 return str;
151 return str;
plugins/Unity/Indicators/modelprinter.h+2−1
@@ -46,7 +46,8 @@ Q_SIGNALS:
47 QString getModelDataString(UnityMenuModel* sourceModel, int level);
47 QString getModelDataString(UnityMenuModel* sourceModel, int level);
48 QString getRowSring(UnityMenuModel* sourceModel, int index, int depth) const;
48 QString getRowSring(UnityMenuModel* sourceModel, int index, int depth) const;
49− QString getVariantString(const QString& roleName, const QVariant &vData) const;
49+ QString getVariantString(const QString& roleName, const QVariant &vData, int depth) const;
50+ QString getVariantString(const QVariant&) const;
51 UnityMenuModel* m_model;
52 UnityMenuModel* m_model;
52 QList<UnityMenuModel*> m_children;
53 QList<UnityMenuModel*> m_children;
plugins/Unity/Indicators/sharedunitymenumodel.cpp+4
@@ -81,12 +81,16 @@ void SharedUnityMenuModel::initialize()
83 QSharedPointer<UnityMenuModel> model = UnityMenuModelCache::singleton()->model(m_menuObjectPath);
83 QSharedPointer<UnityMenuModel> model = UnityMenuModelCache::singleton()->model(m_menuObjectPath);
84 if (model != m_model) {
85 if (model != m_model) {
85 if (model->busName() != m_busName) model->setBusName(m_busName);
86 if (model->busName() != m_busName) model->setBusName(m_busName);
86 if (model->actions() != m_actions) model->setActions(m_actions);
87 if (model->actions() != m_actions) model->setActions(m_actions);
88 m_model = model;
89 m_model = model;
89 Q_EMIT modelChanged();
90 Q_EMIT modelChanged();
91+ } else if (m_model) {
92+ if (m_model->busName() != m_busName) m_model->setBusName(m_busName);
93+ if (m_model->actions() != m_actions) m_model->setActions(m_actions);
plugins/Unity/InputInfo/CMakeLists.txt+1−2
@@ -32,8 +32,7 @@ add_library(InputInfo SHARED
32target_link_libraries(InputInfo
32target_link_libraries(InputInfo
33 ${LIBUDEV_LDFLAGS}
33 ${LIBUDEV_LDFLAGS}
34 ${LIBEVDEV_LDFLAGS}
34 ${LIBEVDEV_LDFLAGS}
35+ Qt5::Core Qt5::Qml Qt5::Quick
37−qt5_use_modules(InputInfo Core Qml Quick)
39add_unity8_plugin(Unity.InputInfo 0.1 Unity/InputInfo TARGETS InputInfo)
38add_unity8_plugin(Unity.InputInfo 0.1 Unity/InputInfo TARGETS InputInfo)
plugins/Unity/InputInfo/InputInfo.qmltypesdeleted−71
@@ -1,71 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.InputInfo 0.1 plugins'
11− name: "QDeclarativeInputDeviceModel"
12− prototype: "QAbstractListModel"
13− exports: ["Unity.InputInfo/InputDeviceModel 0.1"]
14− exportMetaObjectRevisions: [0]
15− Property { name: "deviceFilter"; type: "QInputDevice::InputType" }
16− Property { name: "count"; type: "int"; isReadonly: true }
19− Parameter { name: "devicePath"; type: "string" }
22− name: "deviceRemoved"
23− Parameter { name: "devicePath"; type: "string" }
26− name: "deviceFilterChanged"
27− Parameter { name: "filter"; type: "QInputDevice::InputType" }
29− Method { name: "updateDeviceList" }
33− Parameter { name: "devicePath"; type: "string" }
37− type: "QInputDevice*"
38− Parameter { name: "index"; type: "int" }
44− exports: ["Unity.InputInfo/InputInfo 0.1"]
45− exportMetaObjectRevisions: [0]
59− name: "InputTypeFlags"
plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux.cpp+7−2
@@ -44,6 +44,7 @@
44#include <libudev.h>
44#include <libudev.h>
45#include <libevdev/libevdev.h>
45#include <libevdev/libevdev.h>
46#include <fcntl.h>
46#include <fcntl.h>
47#include <QDebug>
48#include <QDebug>
48#include <QSocketNotifier>
49#include <QSocketNotifier>
49#include <QTimer>
50#include <QTimer>
@@ -52,6 +53,7 @@
52QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
53QInputDeviceManagerPrivate::QInputDeviceManagerPrivate(QObject *parent) :
53 QObject(parent),
54 QObject(parent),
54 currentFilter(QInputDevice::Unknown),
55 currentFilter(QInputDevice::Unknown),
55 udevice(0)
57 udevice(0)
57 QTimer::singleShot(250,this,SLOT(init()));
59 QTimer::singleShot(250,this,SLOT(init()));
@@ -83,9 +85,9 @@ void QInputDeviceManagerPrivate::init()
83 udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
85 udev_enumerate_add_match_subsystem(enumerate, subsystem.toLatin1());
85 udev_monitor_enable_receiving(udevMonitor);
87 udev_monitor_enable_receiving(udevMonitor);
86− notifierFd = udev_monitor_get_fd(udevMonitor);
88+ int notifierFd = udev_monitor_get_fd(udevMonitor);
88− notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
90+ QSocketNotifier *notifier = new QSocketNotifier(notifierFd, QSocketNotifier::Read, this);
89 connect(notifier, SIGNAL(activated(int)), this, SLOT(onUDevChanges()));
91 connect(notifier, SIGNAL(activated(int)), this, SLOT(onUDevChanges()));
91 udev_enumerate_scan_devices(enumerate);
93 udev_enumerate_scan_devices(enumerate);
@@ -168,6 +170,7 @@ QInputDevice *QInputDeviceManagerPrivate::addDevice(struct udev_device *udev)
168 rc = libevdev_new_from_fd(fd, &dev);
170 rc = libevdev_new_from_fd(fd, &dev);
169 if (rc < 0) {
171 if (rc < 0) {
170 qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
172 qWarning() << "Failed to init libevdev ("<< strerror(-rc) << ")";
171 return Q_NULLPTR;
174 return Q_NULLPTR;
@@ -195,6 +198,8 @@ QInputDevice *QInputDeviceManagerPrivate::addDevice(struct udev_device *udev)
198 return inputDevice;
203 return inputDevice;
plugins/Unity/InputInfo/linux/qinputdeviceinfo_linux_p.h−2
@@ -83,8 +83,6 @@ private:
84 QInputDevice *addDevice(const QString &path);
84 QInputDevice *addDevice(const QString &path);
85 void removeDevice(const QString &path);
85 void removeDevice(const QString &path);
86− QSocketNotifier *notifier;
88 struct udev_monitor *udevMonitor;
86 struct udev_monitor *udevMonitor;
89 QInputDevice::InputTypeFlags getInputTypeFlags(struct udev_device *);
87 QInputDevice::InputTypeFlags getInputTypeFlags(struct udev_device *);
90 struct udev *udevice;
88 struct udev *udevice;
plugins/Unity/InputInfo/qinputinfo.h+2−3
@@ -57,8 +57,6 @@ class QInputDeviceManager;
57class QInputDevice : public QObject
57class QInputDevice : public QObject
61− Q_FLAGS(InputType InputTypeFlags)
62 friend class QInputDeviceManagerPrivate;
60 friend class QInputDeviceManagerPrivate;
@@ -72,8 +70,9 @@ public:
72 Keyboard = 16,
70 Keyboard = 16,
73 Switch = 32
71 Switch = 32
75− Q_ENUMS(InputType)
73+ Q_FLAG(InputType)
76 Q_DECLARE_FLAGS(InputTypeFlags, InputType)
74 Q_DECLARE_FLAGS(InputTypeFlags, InputType)
75+ Q_FLAG(InputTypeFlags)
78 explicit QInputDevice(QObject *parent = 0);
77 explicit QInputDevice(QObject *parent = 0);
79 QString name() const;
78 QString name() const;
plugins/Unity/Launcher/CMakeLists.txt+17−6
@@ -1,4 +1,3 @@
1−pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
4add_definitions(-DSM_BUSNAME=systemBus)
3add_definitions(-DSM_BUSNAME=systemBus)
@@ -6,11 +5,16 @@ add_definitions(-DSM_BUSNAME=systemBus)
6include_directories(
5include_directories(
7 ${CMAKE_CURRENT_SOURCE_DIR}
6 ${CMAKE_CURRENT_SOURCE_DIR}
8 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
7 ${CMAKE_SOURCE_DIR}/plugins/AccountsService
9− ${GSETTINGS_QT_INCLUDE_DIRS}
11 ${libunity8-private_SOURCE_DIR}
8 ${libunity8-private_SOURCE_DIR}
13+ ${GSETTINGS_QT_INCLUDE_DIRS}
14set(QMLLAUNCHERPLUGIN_SRC
18set(QMLLAUNCHERPLUGIN_SRC
15 plugin.cpp
19 plugin.cpp
16 launchermodel.cpp
20 launchermodel.cpp
@@ -19,13 +23,20 @@ set(QMLLAUNCHERPLUGIN_SRC
19 quicklistentry.cpp
23 quicklistentry.cpp
20 dbusinterface.cpp
24 dbusinterface.cpp
21 gsettings.cpp
25 gsettings.cpp
22− desktopfilehandler.cpp
23 asadapter.cpp
26 asadapter.cpp
24 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
30 ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
25 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
31 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
32+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
33+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h
34+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
35+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
26 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
36 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
27 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
37 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
28 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
38 ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
39+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h
31add_library(UnityLauncher-qml MODULE
42add_library(UnityLauncher-qml MODULE
@@ -36,8 +47,8 @@ target_link_libraries(UnityLauncher-qml
36 unity8-private
47 unity8-private
37 ${GSETTINGS_QT_LDFLAGS}
48 ${GSETTINGS_QT_LDFLAGS}
38 ${GLIB_LIBRARIES}
49 ${GLIB_LIBRARIES}
51+ Qt5::DBus Qt5::Qml Qt5::Gui Qt5::Concurrent
41−qt5_use_modules(UnityLauncher-qml DBus Qml Gui)
43add_unity8_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
54add_unity8_plugin(Unity.Launcher 0.1 Unity/Launcher TARGETS UnityLauncher-qml)
plugins/Unity/Launcher/Launcher.qmltypesdeleted−182
@@ -1,182 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.Launcher 0.1 plugins'
12− prototype: "unity::shell::launcher::LauncherItemInterface"
13− exports: ["Unity.Launcher/LauncherItem 0.1"]
15− exportMetaObjectRevisions: [0]
18− name: "LauncherModel"
19− prototype: "unity::shell::launcher::LauncherModelInterface"
20− exports: ["Unity.Launcher/LauncherModel 0.1"]
23− exportMetaObjectRevisions: [0]
25− name: "requestRemove"
26− Parameter { name: "appId"; type: "string" }
28− Method { name: "refresh" }
31− type: "unity::shell::launcher::LauncherItemInterface*"
32− Parameter { name: "index"; type: "int" }
36− Parameter { name: "oldIndex"; type: "int" }
37− Parameter { name: "newIndex"; type: "int" }
41− Parameter { name: "appId"; type: "string" }
42− Parameter { name: "index"; type: "int" }
46− Parameter { name: "appId"; type: "string" }
49− name: "quickListActionInvoked"
50− Parameter { name: "appId"; type: "string" }
51− Parameter { name: "actionIndex"; type: "int" }
55− Parameter { name: "username"; type: "string" }
58− name: "getUrlForAppId"
60− Parameter { name: "appId"; type: "string" }
64− name: "QuickListModel"
65− prototype: "unity::shell::launcher::QuickListModelInterface"
66− exports: ["Unity.Launcher/QuickListModel 0.1"]
68− exportMetaObjectRevisions: [0]
71− name: "unity::shell::launcher::LauncherItemInterface"
73− exports: ["Unity.Launcher/LauncherItemInterface 0.1"]
75− exportMetaObjectRevisions: [0]
76− Property { name: "appId"; type: "string"; isReadonly: true }
77− Property { name: "name"; type: "string"; isReadonly: true }
78− Property { name: "icon"; type: "string"; isReadonly: true }
79− Property { name: "pinned"; type: "bool"; isReadonly: true }
80− Property { name: "running"; type: "bool"; isReadonly: true }
81− Property { name: "recent"; type: "bool"; isReadonly: true }
82− Property { name: "progress"; type: "int"; isReadonly: true }
83− Property { name: "count"; type: "int"; isReadonly: true }
84− Property { name: "countVisible"; type: "bool"; isReadonly: true }
85− Property { name: "focused"; type: "bool"; isReadonly: true }
88− type: "unity::shell::launcher::QuickListModelInterface"
94− Parameter { name: "name"; type: "string" }
98− Parameter { name: "icon"; type: "string" }
101− name: "pinnedChanged"
102− Parameter { name: "pinned"; type: "bool" }
105− name: "runningChanged"
106− Parameter { name: "running"; type: "bool" }
109− name: "recentChanged"
110− Parameter { name: "running"; type: "bool" }
113− name: "progressChanged"
114− Parameter { name: "progress"; type: "int" }
117− name: "countChanged"
118− Parameter { name: "count"; type: "int" }
121− name: "countVisibleChanged"
122− Parameter { name: "countVisible"; type: "bool" }
125− name: "focusedChanged"
126− Parameter { name: "focused"; type: "bool" }
130− name: "unity::shell::launcher::LauncherModelInterface"
131− prototype: "QAbstractListModel"
132− exports: ["Unity.Launcher/LauncherModelInterface 0.1"]
134− exportMetaObjectRevisions: [0]
136− name: "applicationManager"
137− type: "unity::shell::application::ApplicationManagerInterface"
140− Property { name: "onlyPinned"; type: "bool" }
141− Signal { name: "hint" }
144− Parameter { name: "oldIndex"; type: "int" }
145− Parameter { name: "newIndex"; type: "int" }
149− type: "unity::shell::launcher::LauncherItemInterface*"
150− Parameter { name: "index"; type: "int" }
154− Parameter { name: "appId"; type: "string" }
155− Parameter { name: "index"; type: "int" }
159− Parameter { name: "appId"; type: "string" }
162− name: "requestRemove"
163− Parameter { name: "appId"; type: "string" }
166− name: "quickListActionInvoked"
167− Parameter { name: "appId"; type: "string" }
168− Parameter { name: "actionIndex"; type: "int" }
172− Parameter { name: "username"; type: "string" }
176− name: "unity::shell::launcher::QuickListModelInterface"
177− prototype: "QAbstractListModel"
178− exports: ["Unity.Launcher/QuickListInterface 0.1"]
180− exportMetaObjectRevisions: [0]
plugins/Unity/Launcher/appdrawermodel.cppnew file+192
@@ -0,0 +1,192 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ * Copyright (C) 2020 UBports Foundation.
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#include "appdrawermodel.h"
19+#include "ualwrapper.h"
20+#include "xdgwatcher.h"
24+#include <QtConcurrentRun>
26+static std::shared_ptr<LauncherItem> makeSharedLauncherItem(
27+ const QString &appId, const QString &name, const QString &icon, QObject * parent)
29+ return std::shared_ptr<LauncherItem>(
30+ new LauncherItem(appId, name, icon, parent),
31+ [] (LauncherItem *item) { item->deleteLater(); });
34+AppDrawerModel::AppDrawerModel(QObject *parent):
35+ AppDrawerModelInterface(parent),
36+ m_ual(new UalWrapper(this)),
37+ m_xdgWatcher(new XdgWatcher(this)),
40+ connect(&m_refreshFutureWatcher, &QFutureWatcher<ItemList>::finished,
41+ this, &AppDrawerModel::onRefreshFinished);
43+ // keep this a queued connection as it's coming from another thread.
44+ connect(m_xdgWatcher, &XdgWatcher::appAdded, this, &AppDrawerModel::appAdded, Qt::QueuedConnection);
45+ connect(m_xdgWatcher, &XdgWatcher::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
46+ connect(m_xdgWatcher, &XdgWatcher::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
51+int AppDrawerModel::rowCount(const QModelIndex &parent) const
54+ return m_list.count();
57+QVariant AppDrawerModel::data(const QModelIndex &index, int role) const
61+ return m_list.at(index.row())->appId();
63+ return m_list.at(index.row())->name();
65+ return m_list.at(index.row())->icon();
67+ return m_list.at(index.row())->keywords();
69+ return m_list.at(index.row())->popularity();
75+void AppDrawerModel::appAdded(const QString &appId)
78+ // Will be replaced by the refresh result anyway.
81+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
83+ qWarning() << "App added signal received but failed to get app info for app" << appId;
87+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
88+ auto item = makeSharedLauncherItem(appId, info.name, info.icon, /* parent */ nullptr);
89+ item->setKeywords(info.keywords);
90+ item->setPopularity(info.popularity);
91+ m_list.append(std::move(item));
95+void AppDrawerModel::appRemoved(const QString &appId)
98+ // Will be replaced by the refresh result anyway.
102+ for (int i = 0; i < m_list.count(); i++) {
103+ if (m_list.at(i)->appId() == appId) {
109+ qWarning() << "App removed signal received but app doesn't seem to be in the drawer model";
112+ beginRemoveRows(QModelIndex(), idx, idx);
113+ m_list.removeAt(idx);
117+void AppDrawerModel::appInfoChanged(const QString &appId)
120+ // Will be replaced by the refresh result anyway.
123+ std::shared_ptr<LauncherItem> item;
126+ for(int i = 0; i < m_list.count(); i++) {
127+ if (m_list.at(i)->appId() == appId) {
128+ item = m_list.at(i);
138+ UalWrapper::AppInfo info = m_ual->getApplicationInfo(appId);
139+ item->setPopularity(info.popularity);
140+ Q_EMIT dataChanged(index(idx), index(idx), {AppDrawerModelInterface::RoleUsage});
143+bool AppDrawerModel::refreshing() {
144+ return m_refreshing;
147+void AppDrawerModel::refresh() {
151+ m_refreshFutureWatcher.setFuture(QtConcurrent::run([](QThread *thread) {
154+ Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
155+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
157+ qWarning() << "Failed to get app info for app" << appId;
160+ // We don't pass parent in because this may run after the model is destroyed.
161+ // (And, in fact, we can't, because the model is in a diferent thread.)
162+ auto item = makeSharedLauncherItem(appId, info.name, info.icon, /* parent */ nullptr);
163+ item->setKeywords(info.keywords);
164+ item->setPopularity(info.popularity);
165+ item->moveToThread(thread);
166+ list.append(std::move(item));
170+ }, this->thread()));
172+ m_refreshing = true;
173+ Q_EMIT refreshingChanged();
176+void AppDrawerModel::onRefreshFinished() {
177+ if (m_refreshFutureWatcher.isCanceled())
178+ // This is the result of setting canceled future below.
183+ m_list = m_refreshFutureWatcher.result();
184+ // Remove the future & its result, so that future modifications won't
186+ m_refreshFutureWatcher.setFuture(QFuture<ItemList>());
190+ m_refreshing = false;
191+ Q_EMIT refreshingChanged();
plugins/Unity/Launcher/appdrawermodel.hnew file+64
@@ -0,0 +1,64 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
3+ * Copyright (C) 2020 UBports Foundation.
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+#include <QFutureWatcher>
20+#include <unity/shell/launcher/AppDrawerModelInterface.h>
22+#include "launcheritem.h"
27+class AppDrawerModel: public AppDrawerModelInterface
30+ // TODO: Add this to AppDrawerModelInterface in unity-api.
31+ // Or, better yet, remove AppDrawerModelInterface from unity-api.
32+ Q_PROPERTY(bool refreshing READ refreshing NOTIFY refreshingChanged)
34+ AppDrawerModel(QObject* parent = nullptr);
36+ int rowCount(const QModelIndex &parent) const override;
37+ QVariant data(const QModelIndex &index, int role) const override;
39+ // TODO: add these to AppDrawerModelInterface too.
41+ Q_INVOKABLE void refresh();
44+ void refreshingChanged();
47+ void appAdded(const QString &appId);
48+ void appRemoved(const QString &appId);
49+ void appInfoChanged(const QString &appId);
51+ void onRefreshFinished();
54+ // Using shared_ptr is unavoidable in order to share the refresh result
55+ // from the worker thread safely without a memory leak, in case the model
56+ // is destructed before the worker finishes.
57+ typedef QList<std::shared_ptr<LauncherItem>> ItemList;
61+ XdgWatcher *m_xdgWatcher;
62+ QFutureWatcher<ItemList> m_refreshFutureWatcher;
plugins/Unity/Launcher/desktopfilehandler.cppdeleted−155
@@ -1,155 +0,0 @@
2− * Copyright 2014 Canonical Ltd.
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.
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.
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/>.
17− * Michael Zanetti <michael.zanetti@canonical.com>
20−#include "desktopfilehandler.h"
22−#include <QStringList>
23−#include <QStandardPaths>
30−DesktopFileHandler::DesktopFileHandler(const QString &appId, QObject *parent):
37−QString DesktopFileHandler::appId() const
42−void DesktopFileHandler::setAppId(const QString &appId)
44− if (m_appId != appId) {
50−QString DesktopFileHandler::filename() const
55−bool DesktopFileHandler::isValid() const
57− return !m_filename.isEmpty();
60−void DesktopFileHandler::load()
64− if (m_appId.isEmpty()) {
69− QString helper = m_appId;
71− QStringList searchDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
72−#ifdef LAUNCHER_TESTING
73− searchDirs << QStringLiteral(".");
79− helper.replace(dashPos, 1, '/');
82− if (helper.contains('/')) {
83− path += helper.split('/').at(0) + '/';
84− helper.remove(QRegExp("^" + path));
87− Q_FOREACH(const QString &searchDirName, searchDirs) {
88− QDir searchDir(searchDirName + "/" + path);
89− const QString desktop = QStringLiteral("*.desktop");
90− Q_FOREACH(const QString &desktopFile, searchDir.entryList(QStringList() << desktop)) {
91− if (desktopFile.startsWith(helper)) {
92− QFileInfo fileInfo(searchDir, desktopFile);
93− m_filename = fileInfo.absoluteFilePath();
99− dashPos = helper.indexOf('-');
100− } while (dashPos != -1);
103−QString DesktopFileHandler::displayName() const
109− QSettings settings(m_filename, QSettings::IniFormat);
110− settings.setIniCodec("UTF-8");
111− settings.beginGroup(QStringLiteral("Desktop Entry"));
113− // First try to find Name[xx_YY] and Name[xx] in .desktop file
114− const QString locale = QLocale().name();
115− const QStringList splitLocale = locale.split(QLatin1Char('_'));
116− const QString shortLocale = splitLocale.first();
118− if (locale != shortLocale && settings.contains(QStringLiteral("Name[%1]").arg(locale))) {
119− return settings.value(QStringLiteral("Name[%1]").arg(locale)).toString();
122− if (settings.contains(QStringLiteral("Name[%1]").arg(shortLocale))) {
123− return settings.value(QStringLiteral("Name[%1]").arg(shortLocale)).toString();
126− // No translation found in desktop file. Get the untranslated one and have a go with gettext.
127− QString displayName = settings.value(QStringLiteral("Name")).toString();
129− if (settings.contains(QStringLiteral("X-Ubuntu-Gettext-Domain"))) {
130− const QString domain = settings.value(QStringLiteral("X-Ubuntu-Gettext-Domain")).toString();
131− return dgettext(domain.toUtf8().constData(), displayName.toUtf8().constData());
137−QString DesktopFileHandler::icon() const
143− QSettings settings(m_filename, QSettings::IniFormat);
144− settings.setIniCodec("UTF-8");
145− settings.beginGroup(QStringLiteral("Desktop Entry"));
146− QString iconString = settings.value(QStringLiteral("Icon")).toString();
147− QString pathString = settings.value(QStringLiteral("Path")).toString();
149− if (QFileInfo::exists(iconString)) {
150− return QFileInfo(iconString).absoluteFilePath();
151− } else if (QFileInfo::exists(pathString + '/' + iconString)) {
152− return pathString + '/' + iconString;
154− return "image://theme/" + iconString;
plugins/Unity/Launcher/desktopfilehandler.hdeleted−56
@@ -1,56 +0,0 @@
2− * Copyright 2014 Canonical Ltd.
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.
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.
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/>.
17− * Michael Zanetti <michael.zanetti@canonical.com>
20−#ifndef DESKTOPFILEHANDLER_H
21−#define DESKTOPFILEHANDLER_H
26− * When an object of this class is created or whenever setAppId(appId) is called,
27− * this will search for a .desktop file matching the give appId. If a file is
28− * found, isValid() will return true and the other methods return the contents
29− * of the .desktop file.
31− * Note that this class will consider the user's locale and do a best effort
32− * to return localized values.
35−class DesktopFileHandler: public QObject
39− DesktopFileHandler(const QString &appId = QString(), QObject *parent = nullptr);
41− QString appId() const;
42− void setAppId(const QString &appId);
44− bool isValid() const;
45− QString filename() const;
46− QString displayName() const;
47− QString icon() const;
plugins/Unity/Launcher/launcheritem.cpp+65−10
@@ -37,20 +37,22 @@ LauncherItem::LauncherItem(const QString &appId, const QString &name, const QStr
37 m_alerting(false),
37 m_alerting(false),
38 m_quickList(new QuickListModel(this))
38 m_quickList(new QuickListModel(this))
40− Q_ASSERT(parent != nullptr);
41 QuickListEntry nameAction;
40 QuickListEntry nameAction;
42 nameAction.setActionId(QStringLiteral("launch_item"));
41 nameAction.setActionId(QStringLiteral("launch_item"));
43 nameAction.setText(m_name);
42 nameAction.setText(m_name);
43+ nameAction.setHasSeparator(true);
44 m_quickList->appendAction(nameAction);
44 m_quickList->appendAction(nameAction);
46 QuickListEntry pinningAction;
46 QuickListEntry pinningAction;
47 pinningAction.setActionId(QStringLiteral("pin_item"));
47 pinningAction.setActionId(QStringLiteral("pin_item"));
48 pinningAction.setText(gettext("Pin shortcut"));
48 pinningAction.setText(gettext("Pin shortcut"));
49+ pinningAction.setIsPrivate(true);
49 m_quickList->appendAction(pinningAction);
50 m_quickList->appendAction(pinningAction);
51 m_quitAction.setActionId(QStringLiteral("stop_item"));
52 m_quitAction.setActionId(QStringLiteral("stop_item"));
52 m_quitAction.setIcon(QStringLiteral("application-exit"));
53 m_quitAction.setIcon(QStringLiteral("application-exit"));
53 m_quitAction.setText(gettext("Quit"));
54 m_quitAction.setText(gettext("Quit"));
55+ m_quitAction.setIsPrivate(true);
56QString LauncherItem::appId() const
58QString LauncherItem::appId() const
@@ -88,6 +90,19 @@ void LauncherItem::setIcon(const QString &icon)
93+QStringList LauncherItem::keywords() const
98+void LauncherItem::setKeywords(const QStringList &keywords)
100+ if (m_keywords != keywords) {
101+ m_keywords = keywords;
102+ Q_EMIT keywordsChanged(keywords);
91bool LauncherItem::pinned() const
106bool LauncherItem::pinned() const
93 return m_pinned;
108 return m_pinned;
@@ -105,6 +120,7 @@ void LauncherItem::setPinned(bool pinned)
105 QuickListEntry entry;
120 QuickListEntry entry;
106 entry.setActionId(QStringLiteral("pin_item"));
121 entry.setActionId(QStringLiteral("pin_item"));
107 entry.setText(pinned ? gettext("Unpin shortcut") : gettext("Pin shortcut"));
122 entry.setText(pinned ? gettext("Unpin shortcut") : gettext("Pin shortcut"));
123+ entry.setIsPrivate(true);
108 m_quickList->updateAction(entry);
124 m_quickList->updateAction(entry);
@@ -162,9 +178,6 @@ void LauncherItem::setCount(int count)
162 if (m_count != count) {
178 if (m_count != count) {
163 m_count = count;
179 m_count = count;
164 Q_EMIT countChanged(count);
180 Q_EMIT countChanged(count);
165− if (m_countVisible) {
@@ -178,9 +191,6 @@ void LauncherItem::setCountVisible(bool countVisible)
178 if (m_countVisible != countVisible) {
191 if (m_countVisible != countVisible) {
179 m_countVisible = countVisible;
192 m_countVisible = countVisible;
180 Q_EMIT countVisibleChanged(countVisible);
193 Q_EMIT countVisibleChanged(countVisible);
@@ -193,9 +203,6 @@ void LauncherItem::setFocused(bool focused)
194 if (m_focused != focused) {
204 if (m_focused != focused) {
195 m_focused = focused;
205 m_focused = focused;
199 Q_EMIT focusedChanged(focused);
206 Q_EMIT focusedChanged(focused);
@@ -213,6 +220,54 @@ void LauncherItem::setAlerting(bool alerting)
223+int LauncherItem::surfaceCount() const
225+ return m_surfaces.count();
228+void LauncherItem::setSurfaces(const QList<QPair<QString, QString> > &surfaces)
230+ if (m_surfaces != surfaces) {
231+ m_surfaces = surfaces;
233+ QList<QuickListEntry> removedEntries;
234+ for (int i = 0; i < m_quickList->rowCount(); ++i) {
235+ QuickListEntry entry = m_quickList->get(i);
236+ if (entry.actionId().startsWith(QStringLiteral("surface_"))) {
237+ removedEntries.append(entry);
240+ Q_FOREACH (const QuickListEntry &entry, removedEntries) {
241+ m_quickList->removeAction(entry);
243+ for (int i = 0; i < surfaces.count(); ++i) {
244+ QuickListEntry entry;
245+ entry.setActionId(QStringLiteral("surface_") + surfaces.at(i).first);
246+ entry.setText(surfaces.at(i).second);
247+ entry.setIsPrivate(true);
248+ if (i == surfaces.count() - 1) {
249+ entry.setHasSeparator(true);
251+ m_quickList->insertAction(entry, i + 1);
254+ Q_EMIT surfaceCountChanged(m_surfaces.count());
258+uint LauncherItem::popularity() const
260+ return m_popularity;
263+void LauncherItem::setPopularity(uint popularity)
265+ if (m_popularity != popularity) {
266+ m_popularity = popularity;
267+ Q_EMIT popularityChanged(popularity);
216unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
271unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
218 return m_quickList;
273 return m_quickList;
plugins/Unity/Launcher/launcheritem.h+11
@@ -23,6 +23,7 @@
23#include "quicklistmodel.h"
23#include "quicklistmodel.h"
25#include <unity/shell/launcher/LauncherItemInterface.h>
25#include <unity/shell/launcher/LauncherItemInterface.h>
26+#include <unity/shell/application/MirSurfaceInterface.h>
27class QuickListModel;
28class QuickListModel;
@@ -37,6 +38,8 @@ public:
37 QString appId() const override;
38 QString appId() const override;
38 QString name() const override;
39 QString name() const override;
39 QString icon() const override;
40 QString icon() const override;
41+ QStringList keywords() const override;
42+ uint popularity() const override;
40 bool pinned() const override;
43 bool pinned() const override;
41 bool running() const override;
44 bool running() const override;
42 bool recent() const override;
45 bool recent() const override;
@@ -45,12 +48,15 @@ public:
45 bool countVisible() const override;
48 bool countVisible() const override;
46 bool focused() const override;
49 bool focused() const override;
47 bool alerting() const override;
50 bool alerting() const override;
51+ int surfaceCount() const override;
49 unity::shell::launcher::QuickListModelInterface *quickList() const override;
53 unity::shell::launcher::QuickListModelInterface *quickList() const override;
52 void setName(const QString &name);
56 void setName(const QString &name);
53 void setIcon(const QString &icon);
57 void setIcon(const QString &icon);
58+ void setKeywords(const QStringList &keywords);
59+ void setPopularity(uint popularity);
54 void setPinned(bool pinned);
60 void setPinned(bool pinned);
55 void setRunning(bool running);
61 void setRunning(bool running);
56 void setRecent(bool recent);
62 void setRecent(bool recent);
@@ -59,11 +65,14 @@ private:
59 void setCountVisible(bool countVisible);
65 void setCountVisible(bool countVisible);
60 void setFocused(bool focused);
66 void setFocused(bool focused);
61 void setAlerting(bool alerting);
67 void setAlerting(bool alerting);
68+ void setSurfaces(const QList<QPair<QString, QString >> &surfaces);
64 QString m_appId;
71 QString m_appId;
65 QString m_name;
72 QString m_name;
66 QString m_icon;
73 QString m_icon;
74+ QStringList m_keywords;
67 bool m_pinned;
76 bool m_pinned;
68 bool m_running;
77 bool m_running;
69 bool m_recent;
78 bool m_recent;
@@ -72,10 +81,12 @@ private:
72 bool m_countVisible;
81 bool m_countVisible;
73 bool m_focused;
82 bool m_focused;
74 bool m_alerting;
83 bool m_alerting;
84+ QList<QPair<QString, QString> > m_surfaces;
75 QuickListModel *m_quickList;
85 QuickListModel *m_quickList;
76 QuickListEntry m_quitAction;
86 QuickListEntry m_quitAction;
78 friend class LauncherModel;
88 friend class LauncherModel;
89+ friend class AppDrawerModel;
81#endif // LAUNCHERITEM_H
92#endif // LAUNCHERITEM_H
plugins/Unity/Launcher/launchermodel.cpp+118−59
@@ -1,5 +1,5 @@
2− * Copyright 2013-2014 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -12,19 +12,18 @@
13 * You should have received a copy of the GNU Lesser General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17− * Michael Zanetti <michael.zanetti@canonical.com>
20#include "launchermodel.h"
17#include "launchermodel.h"
21#include "launcheritem.h"
18#include "launcheritem.h"
22#include "gsettings.h"
19#include "gsettings.h"
23−#include "desktopfilehandler.h"
24#include "dbusinterface.h"
20#include "dbusinterface.h"
25#include "asadapter.h"
21#include "asadapter.h"
22+#include "ualwrapper.h"
27#include <unity/shell/application/ApplicationInfoInterface.h>
24#include <unity/shell/application/ApplicationInfoInterface.h>
25+#include <unity/shell/application/MirSurfaceListInterface.h>
26+#include <unity/shell/application/MirSurfaceInterface.h>
29#include <QDesktopServices>
28#include <QDesktopServices>
30#include <QDebug>
29#include <QDebug>
@@ -88,6 +87,8 @@ QVariant LauncherModel::data(const QModelIndex &index, int role) const
88 return item->alerting();
87 return item->alerting();
89 case RoleRunning:
88 case RoleRunning:
90 return item->running();
89 return item->running();
90+ case RoleSurfaceCount:
91+ return item->surfaceCount();
92 qWarning() << Q_FUNC_INFO << "missing role, implement me";
93 qWarning() << Q_FUNC_INFO << "missing role, implement me";
93 return QVariant();
94 return QVariant();
@@ -96,18 +97,6 @@ QVariant LauncherModel::data(const QModelIndex &index, int role) const
96 return QVariant();
97 return QVariant();
99−void LauncherModel::setAlerting(const QString &appId, bool alerting) {
100− int index = findApplication(appId);
102− QModelIndex modelIndex = this->index(index);
103− LauncherItem *item = m_list.at(index);
104− if (!item->focused()) {
105− item->setAlerting(alerting);
106− Q_EMIT dataChanged(modelIndex, modelIndex, {RoleAlerting});
111unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
100unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
113 if (index < 0 || index >= m_list.count()) {
102 if (index < 0 || index >= m_list.count()) {
@@ -166,18 +155,19 @@ void LauncherModel::pin(const QString &appId, int index)
166 index = m_list.count();
155 index = m_list.count();
169− DesktopFileHandler desktopFile(appId);
158+ UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(appId);
170− if (!desktopFile.isValid()) {
159+ if (!appInfo.valid) {
171− qWarning() << "Can't pin this application, there is no .desktop file available.";
160+ qWarning() << "Can't pin application, appId not found:" << appId;
175 beginInsertRows(QModelIndex(), index, index);
164 beginInsertRows(QModelIndex(), index, index);
176 LauncherItem *item = new LauncherItem(appId,
165 LauncherItem *item = new LauncherItem(appId,
177− desktopFile.displayName(),
166+ appInfo.name,
178− desktopFile.icon(),
167+ appInfo.icon,
180 item->setPinned(true);
169 item->setPinned(true);
170+ item->setPopularity(appInfo.popularity);
181 m_list.insert(index, item);
171 m_list.insert(index, item);
182 endInsertRows();
172 endInsertRows();
@@ -210,12 +200,26 @@ void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex
211 pin(appId);
201 pin(appId);
213− } else if (actionId == QLatin1String("launch_item")) {
203+ } else if (actionId == QStringLiteral("launch_item")) {
214 QDesktopServices::openUrl(getUrlForAppId(appId));
204 QDesktopServices::openUrl(getUrlForAppId(appId));
215− } else if (actionId == QLatin1String("stop_item")) { // Quit
205+ } else if (actionId == QStringLiteral("stop_item")) { // Quit
216 if (m_appManager) {
206 if (m_appManager) {
217 m_appManager->stopApplication(appId);
207 m_appManager->stopApplication(appId);
209+ } else if (actionId.startsWith(QStringLiteral("surface_"))){
210+ ApplicationInfoInterface *appInfo = m_appManager->findApplication(appId);
212+ for (int i = 0; i < appInfo->surfaceList()->count(); ++i) {
213+ MirSurfaceInterface *iface = appInfo->surfaceList()->get(i);
214+ QString id = actionId;
215+ id.remove(QRegExp("^surface_"));
216+ if (id == iface->persistentId()) {
221+ qWarning() << "App for" << appId << "not found in launcher. Cannot invoke quicklist action";
219 // Nope, we don't know this action, let the backend forward it to the application
223 // Nope, we don't know this action, let the backend forward it to the application
221 // TODO: forward quicklist action to app, possibly via m_dbusIface
225 // TODO: forward quicklist action to app, possibly via m_dbusIface
@@ -226,7 +230,6 @@ void LauncherModel::quickListActionInvoked(const QString &appId, int actionIndex
226void LauncherModel::setUser(const QString &username)
230void LauncherModel::setUser(const QString &username)
228 Q_UNUSED(username)
232 Q_UNUSED(username)
229− qWarning() << "This backend doesn't support multiple users";
232QString LauncherModel::getUrlForAppId(const QString &appId) const
235QString LauncherModel::getUrlForAppId(const QString &appId) const
@@ -358,11 +361,13 @@ void LauncherModel::countChanged(const QString &appId, int count)
358 if (idx >= 0) {
361 if (idx >= 0) {
359 LauncherItem *item = m_list.at(idx);
362 LauncherItem *item = m_list.at(idx);
360 item->setCount(count);
363 item->setCount(count);
364+ QVector<int> changedRoles = {RoleCount};
361− if (item->countVisible()) {
365+ if (item->countVisible() && !item->alerting() && !item->focused()) {
366+ changedRoles << RoleAlerting;
362− setAlerting(item->appId(), true);
367+ item->setAlerting(true);
364 m_asAdapter->syncItems(m_list);
369 m_asAdapter->syncItems(m_list);
365− Q_EMIT dataChanged(index(idx), index(idx), {RoleCount});
370+ Q_EMIT dataChanged(index(idx), index(idx), changedRoles);
@@ -372,10 +377,12 @@ void LauncherModel::countVisibleChanged(const QString &appId, bool countVisible)
372 if (idx >= 0) {
377 if (idx >= 0) {
373 LauncherItem *item = m_list.at(idx);
378 LauncherItem *item = m_list.at(idx);
374 item->setCountVisible(countVisible);
379 item->setCountVisible(countVisible);
380+ QVector<int> changedRoles = {RoleCountVisible};
375− if (countVisible) {
381+ if (countVisible && !item->alerting() && !item->focused()) {
382+ changedRoles << RoleAlerting;
376− setAlerting(item->appId(), true);
383+ item->setAlerting(true);
378− Q_EMIT dataChanged(index(idx), index(idx), {RoleCountVisible});
385+ Q_EMIT dataChanged(index(idx), index(idx), changedRoles);
380 // If countVisible goes to false, and the item is neither pinned nor recent we can drop it
387 // If countVisible goes to false, and the item is neither pinned nor recent we can drop it
381 if (!countVisible && !item->pinned() && !item->recent()) {
388 if (!countVisible && !item->pinned() && !item->recent()) {
@@ -385,11 +392,11 @@ void LauncherModel::countVisibleChanged(const QString &appId, bool countVisible)
387 // Need to create a new LauncherItem and show the highlight
394 // Need to create a new LauncherItem and show the highlight
388− DesktopFileHandler desktopFile(appId);
395+ UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(appId);
389− if (countVisible && desktopFile.isValid()) {
396+ if (countVisible && appInfo.valid) {
390 LauncherItem *item = new LauncherItem(appId,
397 LauncherItem *item = new LauncherItem(appId,
391− desktopFile.displayName(),
398+ appInfo.name,
392− desktopFile.icon(),
399+ appInfo.icon,
394 item->setCountVisible(true);
401 item->setCountVisible(true);
395 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
402 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
@@ -405,28 +412,28 @@ void LauncherModel::refresh()
405 // First walk through all the existing items and see if we need to remove something
412 // First walk through all the existing items and see if we need to remove something
406 QList<LauncherItem*> toBeRemoved;
413 QList<LauncherItem*> toBeRemoved;
407 Q_FOREACH (LauncherItem* item, m_list) {
414 Q_FOREACH (LauncherItem* item, m_list) {
408− DesktopFileHandler desktopFile(item->appId());
415+ UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(item->appId());
409− if (!desktopFile.isValid()) {
416+ if (!appInfo.valid) {
410− // Desktop file not available for this app => drop it!
417+ // Application no longer available => drop it!
411 toBeRemoved << item;
418 toBeRemoved << item;
412 } else if (!m_settings->storedApplications().contains(item->appId())) {
419 } else if (!m_settings->storedApplications().contains(item->appId())) {
413 // Item not in settings any more => drop it!
420 // Item not in settings any more => drop it!
414 toBeRemoved << item;
421 toBeRemoved << item;
416 int idx = m_list.indexOf(item);
423 int idx = m_list.indexOf(item);
417− item->setName(desktopFile.displayName());
424+ item->setName(appInfo.name);
418 item->setPinned(item->pinned()); // update pinned text if needed
425 item->setPinned(item->pinned()); // update pinned text if needed
419 item->setRunning(item->running());
426 item->setRunning(item->running());
420 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
427 Q_EMIT dataChanged(index(idx), index(idx), {RoleName, RoleRunning});
422 const QString oldIcon = item->icon();
429 const QString oldIcon = item->icon();
423− if (oldIcon == desktopFile.icon()) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
430+ if (oldIcon == appInfo.icon) { // same icon file, perhaps different contents, simulate changing the icon name to force reload
424 item->setIcon(QString());
431 item->setIcon(QString());
425 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
432 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
428 // now set the icon for real
435 // now set the icon for real
429− item->setIcon(desktopFile.icon());
436+ item->setIcon(appInfo.icon);
430 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
437 Q_EMIT dataChanged(index(idx), index(idx), {RoleIcon});
@@ -457,15 +464,14 @@ void LauncherModel::refresh()
457 if (itemIndex == -1) {
464 if (itemIndex == -1) {
458 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
465 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
459 // in the settings.
466 // in the settings.
460− DesktopFileHandler desktopFile(entry);
467+ UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(entry);
461− if (!desktopFile.isValid()) {
468+ if (!appInfo.valid) {
462− qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping...";
463 continue;
469 continue;
466 LauncherItem *item = new LauncherItem(entry,
472 LauncherItem *item = new LauncherItem(entry,
467− desktopFile.displayName(),
473+ appInfo.name,
468− desktopFile.icon(),
474+ appInfo.icon,
470 item->setPinned(true);
476 item->setPinned(true);
471 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
477 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
@@ -498,8 +504,10 @@ void LauncherModel::alert(const QString &appId)
498 int idx = findApplication(appId);
504 int idx = findApplication(appId);
499 if (idx >= 0) {
505 if (idx >= 0) {
500 LauncherItem *item = m_list.at(idx);
506 LauncherItem *item = m_list.at(idx);
507+ if (!item->focused() && !item->alerting()) {
501− setAlerting(item->appId(), true);
508+ item->setAlerting(true);
502− Q_EMIT dataChanged(index(idx), index(idx), {RoleAlerting});
509+ Q_EMIT dataChanged(index(idx), index(idx), {RoleAlerting});
@@ -513,11 +521,6 @@ void LauncherModel::applicationAdded(const QModelIndex &parent, int row)
516− if (app->appId() == QLatin1String("unity8-dash")) {
517− // Not adding the dash app
521 const int itemIndex = findApplication(app->appId());
524 const int itemIndex = findApplication(app->appId());
522 if (itemIndex != -1) {
525 if (itemIndex != -1) {
523 LauncherItem *item = m_list.at(itemIndex);
526 LauncherItem *item = m_list.at(itemIndex);
@@ -531,22 +534,65 @@ void LauncherModel::applicationAdded(const QModelIndex &parent, int row)
531 item->setRecent(true);
534 item->setRecent(true);
532 item->setRunning(true);
535 item->setRunning(true);
533 item->setFocused(app->focused());
536 item->setFocused(app->focused());
535 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
537 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
536 m_list.append(item);
538 m_list.append(item);
537 endInsertRows();
539 endInsertRows();
541+ connect(app, &ApplicationInfoInterface::surfaceCountChanged, this, &LauncherModel::updateSurfaceList);
539 m_asAdapter->syncItems(m_list);
542 m_asAdapter->syncItems(m_list);
540 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRunning});
543 Q_EMIT dataChanged(index(itemIndex), index(itemIndex), {RoleRunning});
546+void LauncherModel::updateSurfaceList()
548+ ApplicationInfoInterface *app = static_cast<ApplicationInfoInterface*>(sender());
549+ updateSurfaceListForApp(app);
552+void LauncherModel::updateSurfaceListForSurface()
554+ MirSurfaceInterface *iface = static_cast<MirSurfaceInterface*>(sender());
555+ ApplicationInfoInterface* app = m_appManager->findApplication(iface->appId());
559+ updateSurfaceListForApp(app);
562+void LauncherModel::updateSurfaceListForApp(ApplicationInfoInterface* app)
564+ int idx = findApplication(app->appId());
566+ qWarning() << "Received a surface count changed event from an app that's not in the Launcher model";
569+ LauncherItem *item = m_list.at(idx);
570+ QList<QPair<QString, QString> > surfaces;
571+ for (int i = 0; i < app->surfaceList()->count(); ++i) {
572+ MirSurfaceInterface* iface = app->surfaceList()->get(i);
573+ if (iface->type() == Mir::NormalType || iface->type() == Mir::DialogType) {
574+ // Avoid duplicate connections, so let's just disconnect first to be sure
575+ disconnect(iface, &MirSurfaceInterface::nameChanged, this, &LauncherModel::updateSurfaceListForSurface);
576+ connect(iface, &MirSurfaceInterface::nameChanged, this, &LauncherModel::updateSurfaceListForSurface);
577+ QString name = iface->name();
578+ if (name.isEmpty()) {
581+ surfaces.append({iface->persistentId(), name});
584+ item->setSurfaces(surfaces);
585+ Q_EMIT dataChanged(index(idx), index(idx), {RoleSurfaceCount});
543void LauncherModel::applicationRemoved(const QModelIndex &parent, int row)
588void LauncherModel::applicationRemoved(const QModelIndex &parent, int row)
545 Q_UNUSED(parent)
590 Q_UNUSED(parent)
592+ ApplicationInfoInterface *app = m_appManager->get(row);
547 int appIndex = -1;
593 int appIndex = -1;
548 for (int i = 0; i < m_list.count(); ++i) {
594 for (int i = 0; i < m_list.count(); ++i) {
549− if (m_list.at(i)->appId() == m_appManager->get(row)->appId()) {
595+ if (m_list.at(i)->appId() == app->appId()) {
550 appIndex = i;
596 appIndex = i;
@@ -557,17 +603,24 @@ void LauncherModel::applicationRemoved(const QModelIndex &parent, int row)
606+ disconnect(app, &ApplicationInfoInterface::surfaceCountChanged, this, &LauncherModel::updateSurfaceList);
560 LauncherItem * item = m_list.at(appIndex);
608 LauncherItem * item = m_list.at(appIndex);
561− item->setRunning(false);
563 if (!item->pinned()) {
610 if (!item->pinned()) {
564 beginRemoveRows(QModelIndex(), appIndex, appIndex);
611 beginRemoveRows(QModelIndex(), appIndex, appIndex);
565 m_list.takeAt(appIndex)->deleteLater();
612 m_list.takeAt(appIndex)->deleteLater();
566 endRemoveRows();
613 endRemoveRows();
567 m_asAdapter->syncItems(m_list);
614 m_asAdapter->syncItems(m_list);
616+ QVector<int> changedRoles = {RoleRunning};
617+ item->setRunning(false);
618+ if (item->focused()) {
619+ changedRoles << RoleFocused;
620+ item->setFocused(false);
568− Q_EMIT dataChanged(index(appIndex), index(appIndex), {RolePinned});
622+ Q_EMIT dataChanged(index(appIndex), index(appIndex), changedRoles);
570− Q_EMIT dataChanged(index(appIndex), index(appIndex), {RoleRunning});
573void LauncherModel::focusedAppIdChanged()
626void LauncherModel::focusedAppIdChanged()
@@ -576,8 +629,14 @@ void LauncherModel::focusedAppIdChanged()
576 for (int i = 0; i < m_list.count(); ++i) {
629 for (int i = 0; i < m_list.count(); ++i) {
577 LauncherItem *item = m_list.at(i);
630 LauncherItem *item = m_list.at(i);
578 if (!item->focused() && item->appId() == appId) {
631 if (!item->focused() && item->appId() == appId) {
632+ QVector<int> changedRoles;
633+ changedRoles << RoleFocused;
579 item->setFocused(true);
634 item->setFocused(true);
580− Q_EMIT dataChanged(index(i), index(i), {RoleFocused});
635+ if (item->alerting()) {
636+ changedRoles << RoleAlerting;
637+ item->setAlerting(false);
639+ Q_EMIT dataChanged(index(i), index(i), changedRoles);
581 } else if (item->focused() && item->appId() != appId) {
640 } else if (item->focused() && item->appId() != appId) {
582 item->setFocused(false);
641 item->setFocused(false);
583 Q_EMIT dataChanged(index(i), index(i), {RoleFocused});
642 Q_EMIT dataChanged(index(i), index(i), {RoleFocused});
plugins/Unity/Launcher/launchermodel.h+6−9
@@ -1,5 +1,5 @@
2− * Copyright 2013-2014 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -12,14 +12,11 @@
13 * You should have received a copy of the GNU Lesser General Public License
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/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17− * Michael Zanetti <michael.zanetti@canonical.com>
20−#ifndef LAUNCHERMODEL_H
17+#pragma once
21−#define LAUNCHERMODEL_H
23#include <unity/shell/launcher/LauncherModelInterface.h>
20#include <unity/shell/launcher/LauncherModelInterface.h>
24#include <unity/shell/application/ApplicationManagerInterface.h>
21#include <unity/shell/application/ApplicationManagerInterface.h>
@@ -45,7 +42,6 @@ public:
46 QVariant data(const QModelIndex &index, int role) const override;
43 QVariant data(const QModelIndex &index, int role) const override;
48− Q_INVOKABLE void setAlerting(const QString &appId, bool alerting) override;
49 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;
45 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const override;
50 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
46 Q_INVOKABLE void move(int oldIndex, int newIndex) override;
51 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
47 Q_INVOKABLE void pin(const QString &appId, int index = -1) override;
@@ -79,6 +75,9 @@ private Q_SLOTS:
79 void applicationAdded(const QModelIndex &parent, int row);
75 void applicationAdded(const QModelIndex &parent, int row);
80 void applicationRemoved(const QModelIndex &parent, int row);
76 void applicationRemoved(const QModelIndex &parent, int row);
81 void focusedAppIdChanged();
77 void focusedAppIdChanged();
78+ void updateSurfaceList();
79+ void updateSurfaceListForApp(ApplicationInfoInterface *app);
80+ void updateSurfaceListForSurface();
84 QList<LauncherItem*> m_list;
83 QList<LauncherItem*> m_list;
@@ -91,5 +90,3 @@ private:
92 friend class LauncherModelTest;
91 friend class LauncherModelTest;
95−#endif // LAUNCHERMODEL_H
plugins/Unity/Launcher/plugin.cpp+2−1
@@ -26,7 +26,7 @@
27#include "launchermodel.h"
27#include "launchermodel.h"
28#include "launcheritem.h"
28#include "launcheritem.h"
29−
29+#include "appdrawermodel.h"
31using namespace unity::shell::launcher;
31using namespace unity::shell::launcher;
@@ -46,4 +46,5 @@ void UnityLauncherPlugin::registerTypes(const char *uri)
46 qmlRegisterSingletonType<LauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
46 qmlRegisterSingletonType<LauncherModel>(uri, 0, 1, "LauncherModel", modelProvider);
47 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", QStringLiteral("Can't create new Launcher Items in QML. Get them from the LauncherModel."));
47 qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", QStringLiteral("Can't create new Launcher Items in QML. Get them from the LauncherModel."));
48 qmlRegisterUncreatableType<QuickListModel>(uri, 0, 1, "QuickListModel", QStringLiteral("Can't create a QuickListModel in QML. Get them from the LauncherItems."));
48 qmlRegisterUncreatableType<QuickListModel>(uri, 0, 1, "QuickListModel", QStringLiteral("Can't create a QuickListModel in QML. Get them from the LauncherItems."));
49+ qmlRegisterType<AppDrawerModel>(uri, 0, 1, "AppDrawerModel");
plugins/Unity/Launcher/quicklistentry.cpp+22
@@ -19,6 +19,8 @@
19#include "quicklistentry.h"
19#include "quicklistentry.h"
21QuickListEntry::QuickListEntry()
21QuickListEntry::QuickListEntry()
22+ : m_hasSeparator(false)
@@ -57,7 +59,27 @@ bool QuickListEntry::clickable() const
57 return !m_actionId.isEmpty();
59 return !m_actionId.isEmpty();
62+void QuickListEntry::setHasSeparator(bool hasSeparator)
64+ m_hasSeparator = hasSeparator;
67+bool QuickListEntry::hasSeparator() const
69+ return m_hasSeparator;
60bool QuickListEntry::operator==(const QuickListEntry &other)
72bool QuickListEntry::operator==(const QuickListEntry &other)
62 return !other.actionId().isEmpty() && other.actionId() == m_actionId;
74 return !other.actionId().isEmpty() && other.actionId() == m_actionId;
77+bool QuickListEntry::isPrivate() const
82+void QuickListEntry::setIsPrivate(bool isPrivate)
84+ m_isPrivate = isPrivate;
plugins/Unity/Launcher/quicklistentry.h+8
@@ -37,12 +37,20 @@ public:
38 bool clickable() const;
38 bool clickable() const;
40+ void setHasSeparator(bool hasSeparator);
41+ bool hasSeparator() const;
40 bool operator==(const QuickListEntry & other);
43 bool operator==(const QuickListEntry & other);
45+ bool isPrivate() const;
46+ void setIsPrivate(bool isPrivate);
43 QString m_actionId;
49 QString m_actionId;
44 QString m_text;
50 QString m_text;
45 QString m_icon;
51 QString m_icon;
48#endif // QUICKLISTENTRY
56#endif // QUICKLISTENTRY
plugins/Unity/Launcher/quicklistmodel.cpp+11
@@ -37,6 +37,13 @@ void QuickListModel::appendAction(const QuickListEntry &entry)
37 endInsertRows();
37 endInsertRows();
40+void QuickListModel::insertAction(const QuickListEntry &entry, int index)
42+ beginInsertRows(QModelIndex(), index, index);
43+ m_list.insert(index, entry);
40void QuickListModel::updateAction(const QuickListEntry &entry)
47void QuickListModel::updateAction(const QuickListEntry &entry)
42 for (int i = 0; i < m_list.count(); ++i) {
49 for (int i = 0; i < m_list.count(); ++i) {
@@ -79,6 +86,10 @@ QVariant QuickListModel::data(const QModelIndex &index, int role) const
79 return m_list.at(index.row()).icon();
86 return m_list.at(index.row()).icon();
80 case RoleClickable:
87 case RoleClickable:
81 return m_list.at(index.row()).clickable();
88 return m_list.at(index.row()).clickable();
89+ case RoleHasSeparator:
90+ return m_list.at(index.row()).hasSeparator();
92+ return m_list.at(index.row()).isPrivate();
83 return QVariant();
94 return QVariant();
plugins/Unity/Launcher/quicklistmodel.h+1
@@ -36,6 +36,7 @@ public:
36 ~QuickListModel();
36 ~QuickListModel();
38 void appendAction(const QuickListEntry &entry);
38 void appendAction(const QuickListEntry &entry);
39+ void insertAction(const QuickListEntry &entry, int index);
41 * @brief Update an existing action
42 * @brief Update an existing action
plugins/Unity/Launcher/ualwrapper.cppnew file+74
@@ -0,0 +1,74 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
19+#include "ualwrapper.h"
21+#include <ubuntu-app-launch/registry.h>
22+using namespace ubuntu::app_launch;
24+UalWrapper::UalWrapper(QObject *parent):
29+QStringList UalWrapper::installedApps()
33+ for (const std::shared_ptr<Application> &app : Registry::installedApps()) {
34+ if (!app->appId().package.value().empty()) {
35+ appIds << QString::fromStdString(app->appId().package.value() + "_" + app->appId().appname.value());
37+ appIds << QString::fromStdString(app->appId().appname);
40+ } catch (const std::runtime_error &e) {
41+ qWarning() << "ubuntu-app-launch threw an exception listing apps:" << e.what();
47+UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
52+ AppID ualAppId = AppID::find(appId.toStdString());
53+ if (ualAppId.empty()) {
54+ qWarning() << "Empty ualAppId result for" << appId;
58+ std::shared_ptr<Application> ualApp;
59+ ualApp = Application::create(ualAppId, Registry::getDefault());
62+ info.name = QString::fromStdString(ualApp->info()->name());
63+ info.icon = QString::fromStdString(ualApp->info()->iconPath());
64+ for (const std::string &keyword : ualApp->info()->keywords().value()) {
65+ info.keywords << QString::fromStdString(keyword);
67+ //info.popularity = ualApp->info()->popularity();
69+ } catch (const std::runtime_error &e) {
70+ qWarning() << "ubuntu-app-launch threw an exception getting app info for appId:" << appId << ":" << e.what();
plugins/Unity/Launcher/ualwrapper.hnew file+36
@@ -0,0 +1,36 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
19+class UalWrapper: public QObject
28+ QStringList keywords;
32+ UalWrapper(QObject* parent = nullptr);
34+ static QStringList installedApps();
35+ static AppInfo getApplicationInfo(const QString &appId);
plugins/Unity/Launcher/xdgwatcher.cppnew file+129
@@ -0,0 +1,129 @@
2+ * Copyright (C) 2019 UBports Foundation
3+ * Author(s): Marius Gripsgard <marius@ubports.com>
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#include "xdgwatcher.h"
23+#include <QStandardPaths>
24+#include <QTextStream>
26+XdgWatcher::XdgWatcher(QObject* parent)
28+ m_watcher(new QFileSystemWatcher(this))
30+ connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &XdgWatcher::onDirectoryChanged);
31+ connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &XdgWatcher::onFileChanged);
33+ const auto paths = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
34+ for (const auto &path: paths) {
35+ const auto qdir = QDir(path);
36+ if (!qdir.exists()) {
40+ // Add the path itself to watch for newly added apps
41+ m_watcher->addPath(path);
43+ // Add watcher for eatch app to watch for changes
44+ const auto files = qdir.entryInfoList(QDir::Files);
45+ for (const auto &file: files) {
46+ if (file.suffix() == "desktop") {
47+ const auto path = file.absoluteFilePath();
48+ m_watcher->addPath(path);
49+ m_registry.insert(path, getAppId(file));
55+// "Ubuntu style" appID is filename without versionNumber after last "_"
56+const QString XdgWatcher::stripAppIdVersion(const QString rawAppID) const {
57+ auto appIdComponents = rawAppID.split("_");
58+ appIdComponents.removeLast();
59+ return appIdComponents.join("_");
62+// Standard appID see:
63+// https://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id
64+const QString XdgWatcher::toStandardAppId(const QFileInfo fileInfo) const {
65+ const auto paths = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
66+ for (const auto &path: paths) {
67+ if (fileInfo.absolutePath() == path) {
70+ if (fileInfo.absolutePath().contains(path)) {
71+ auto fileStr = fileInfo.absoluteFilePath();
72+ fileStr.replace(path, "");
73+ fileStr.replace("/", "-");
74+ fileStr.replace(".desktop", "");
78+ return fileInfo.completeBaseName();
81+const QString XdgWatcher::getAppId(const QFileInfo fileInfo) const {
82+ // We need to open the file to check if its and Ual application
83+ // as we cant just rely on the app name as "normal" apps can also
84+ // contain 3 _ causing us to belive its an ubuntu app
85+ // Example kde_org_kate would become kde_org
86+ QFile qFile(fileInfo.absoluteFilePath());
87+ qFile.open(QIODevice::ReadOnly);
88+ QTextStream fileStream(&qFile);
90+ while (fileStream.readLineInto(&line)) {
91+ if (line.startsWith("X-Ubuntu-Application-ID=")) {
92+ auto rawAppID = line.replace("X-Ubuntu-Application-ID=", "");
94+ return stripAppIdVersion(rawAppID);
99+ // If it's not an "Ubuntu" appID, we follow freedesktop standard
100+ return toStandardAppId(fileInfo);
103+// Watch for newly added apps
104+void XdgWatcher::onDirectoryChanged(const QString &path) {
105+ const auto files = QDir(path).entryInfoList(QDir::Files);
106+ const auto watchedFiles = m_watcher->files();
107+ for (const auto &file: files) {
108+ const auto appPath = file.absoluteFilePath();
109+ if (file.suffix() == "desktop" && !watchedFiles.contains(appPath)) {
110+ m_watcher->addPath(appPath);
112+ const auto appId = getAppId(file);
113+ m_registry.insert(appPath, appId);
114+ Q_EMIT appAdded(appId);
119+void XdgWatcher::onFileChanged(const QString &path) {
120+ QFileInfo file(path);
121+ if (file.exists()) {
122+ // The file exists, this must be an modify event
123+ Q_EMIT appInfoChanged(m_registry.value(path));
125+ // File does not exist, assume this is an remove event.
126+ // onDirectoryChanged will handle rename event
127+ Q_EMIT appRemoved(m_registry.take(path));
plugins/Unity/Launcher/xdgwatcher.hnew file+46
@@ -0,0 +1,46 @@
2+ * Copyright (C) 2019 UBports Foundation
3+ * Author(s): Marius Gripsgard <marius@ubports.com>
5+ * This program is free software; you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation; version 3.
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#include <QFileSystemWatcher>
24+class XdgWatcher: public QObject
28+ XdgWatcher(QObject* parent = nullptr);
31+ void appAdded(const QString &appId);
32+ void appRemoved(const QString &appId);
33+ void appInfoChanged(const QString &appId);
36+ void onDirectoryChanged(const QString &path);
37+ void onFileChanged(const QString &path);
40+ const QString toStandardAppId(const QFileInfo fileInfo) const;
41+ const QString getAppId(const QFileInfo file) const;
42+ const QString stripAppIdVersion(const QString rawAppID) const;
44+ QFileSystemWatcher* m_watcher;
45+ QHash<const QString, QString> m_registry;
plugins/Unity/Platform/CMakeLists.txt+1−1
@@ -6,6 +6,6 @@ set(platformplugin_SRCS
7add_library(Platform-qml SHARED ${platformplugin_SRCS})
7add_library(Platform-qml SHARED ${platformplugin_SRCS})
9−qt5_use_modules(Platform-qml DBus Qml)
9+target_link_libraries(Platform-qml Qt5::DBus Qt5::Qml)
11add_unity8_plugin(Unity.Platform 1.0 Unity/Platform TARGETS Platform-qml)
11add_unity8_plugin(Unity.Platform 1.0 Unity/Platform TARGETS Platform-qml)
plugins/Unity/Platform/Platform.qmltypesdeleted−20
@@ -1,20 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.Platform 1.0 plugins'
13− exports: ["Unity.Platform/Platform 1.0"]
16− exportMetaObjectRevisions: [0]
17− Property { name: "chassis"; type: "string"; isReadonly: true }
18− Property { name: "isPC"; type: "bool"; isReadonly: true }
plugins/Unity/Platform/platform.cpp+16−2
@@ -17,9 +17,11 @@
17#include "platform.h"
17#include "platform.h"
19#include <QDBusConnection>
19#include <QDBusConnection>
21Platform::Platform(QObject *parent)
23Platform::Platform(QObject *parent)
22− : QObject(parent)
24+ : QObject(parent), m_isPC(true), m_isMultiSession(true)
24 QMetaObject::invokeMethod(this, "init");
26 QMetaObject::invokeMethod(this, "init");
@@ -31,8 +33,20 @@ void Platform::init()
31 QDBusInterface seatIface("org.freedesktop.login1", "/org/freedesktop/login1/seat/self", "org.freedesktop.login1.Seat",
33 QDBusInterface seatIface("org.freedesktop.login1", "/org/freedesktop/login1/seat/self", "org.freedesktop.login1.Seat",
32 QDBusConnection::systemBus(), this);
34 QDBusConnection::systemBus(), this);
36+ // From the source at https://cgit.freedesktop.org/systemd/systemd/tree/src/hostname/hostnamed.c#n130
34 m_chassis = iface.property("Chassis").toString();
46 m_chassis = iface.property("Chassis").toString();
35− m_isPC = (m_chassis == "desktop" || m_chassis == "laptop" || m_chassis == "server");
47+
48+ // A PC is not a handset, tablet or watch.
49+ m_isPC = !QSet<QString>{"handset", "tablet", "watch"}.contains(m_chassis);
36 m_isMultiSession = seatIface.property("CanMultiSession").toBool() && seatIface.property("CanGraphical").toBool();
50 m_isMultiSession = seatIface.property("CanMultiSession").toBool() && seatIface.property("CanGraphical").toBool();
plugins/Unity/Session/CMakeLists.txt+3−1
@@ -6,6 +6,8 @@ include_directories(
6 ${libunity8-private_SOURCE_DIR}
6 ${libunity8-private_SOURCE_DIR}
9+add_definitions(-DSM_BUSNAME=systemBus)
9set(QMLSESSIONPLUGIN_SRC
11set(QMLSESSIONPLUGIN_SRC
10 plugin.cpp
12 plugin.cpp
11 dbusunitysessionservice.cpp
13 dbusunitysessionservice.cpp
@@ -16,8 +18,8 @@ add_library(UnitySession-qml MODULE
16 ${QMLSESSIONPLUGIN_SRC}
18 ${QMLSESSIONPLUGIN_SRC}
19−qt5_use_modules(UnitySession-qml DBus Qml)
20target_link_libraries(UnitySession-qml
21target_link_libraries(UnitySession-qml
21 unity8-private
23 unity8-private
22 ${GIO_LDFLAGS}
24 ${GIO_LDFLAGS}
23 ${GLIB_LIBRARIES}
25 ${GLIB_LIBRARIES}
plugins/Unity/Session/Session.qmltypesdeleted−85
@@ -1,85 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Unity.Session 0.1 plugins'
11− name: "DBusUnitySessionService"
12− prototype: "UnityDBusObject"
13− exports: ["Unity.Session/DBusUnitySessionService 0.1"]
16− exportMetaObjectRevisions: [0]
18− name: "LogoutRequested"
19− Parameter { name: "have_inhibitors"; type: "bool" }
22− name: "logoutRequested"
23− Parameter { name: "have_inhibitors"; type: "bool" }
26− name: "RebootRequested"
27− Parameter { name: "have_inhibitors"; type: "bool" }
30− name: "rebootRequested"
31− Parameter { name: "have_inhibitors"; type: "bool" }
34− name: "ShutdownRequested"
35− Parameter { name: "have_inhibitors"; type: "bool" }
38− name: "shutdownRequested"
39− Parameter { name: "have_inhibitors"; type: "bool" }
41− Signal { name: "LogoutReady" }
42− Signal { name: "logoutReady" }
43− Signal { name: "LockRequested" }
44− Signal { name: "lockRequested" }
45− Signal { name: "Locked" }
46− Signal { name: "Unlocked" }
47− Method { name: "Logout" }
48− Method { name: "Reboot" }
49− Method { name: "Shutdown" }
50− Method { name: "Suspend" }
51− Method { name: "Hibernate" }
52− Method { name: "HybridSleep" }
53− Method { name: "RequestLogout" }
54− Method { name: "RequestReboot" }
55− Method { name: "RequestShutdown" }
56− Method { name: "EndSession" }
57− Method { name: "CanHibernate"; type: "bool" }
58− Method { name: "CanSuspend"; type: "bool" }
59− Method { name: "CanHybridSleep"; type: "bool" }
60− Method { name: "CanReboot"; type: "bool" }
61− Method { name: "CanShutdown"; type: "bool" }
62− Method { name: "CanLock"; type: "bool" }
63− Method { name: "UserName"; type: "string" }
64− Method { name: "RealName"; type: "string" }
65− Method { name: "HostName"; type: "string" }
66− Method { name: "PromptLock" }
67− Method { name: "Lock" }
68− Method { name: "IsLocked"; type: "bool" }
69− Method { name: "logout" }
70− Method { name: "reboot" }
71− Method { name: "shutdown" }
72− Method { name: "endSession" }
75− name: "OrientationLock"
77− exports: ["Unity.Session/OrientationLock 0.1"]
80− exportMetaObjectRevisions: [0]
81− Property { name: "enabled"; type: "bool"; isReadonly: true }
82− Property { name: "savedOrientation"; type: "Qt::ScreenOrientation" }
84− Component { name: "UnityDBusObject"; prototype: "QObject" }
plugins/Unity/Session/dbusunitysessionservice.cpp+125−22
@@ -18,6 +18,7 @@
18#include "dbusunitysessionservice.h"
18#include "dbusunitysessionservice.h"
21#include <sys/types.h>
22#include <sys/types.h>
22#include <unistd.h>
23#include <unistd.h>
23#include <pwd.h>
24#include <pwd.h>
@@ -64,19 +65,19 @@ public:
64 QStringLiteral("GetSessionByPID"));
65 QStringLiteral("GetSessionByPID"));
65 msg << (quint32) getpid();
66 msg << (quint32) getpid();
67− QDBusReply<QDBusObjectPath> reply = QDBusConnection::systemBus().call(msg);
68+ QDBusReply<QDBusObjectPath> reply = QDBusConnection::SM_BUSNAME().call(msg);
68 if (reply.isValid()) {
69 if (reply.isValid()) {
69 logindSessionPath = reply.value().path();
70 logindSessionPath = reply.value().path();
71 // start watching the Active property
72 // start watching the Active property
72− QDBusConnection::systemBus().connect(LOGIN1_SERVICE, logindSessionPath, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("PropertiesChanged"),
73+ QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, logindSessionPath, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("PropertiesChanged"),
73− this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
74+ this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
75 setupSystemdInhibition();
76 setupSystemdInhibition();
77 // re-enable the inhibition upon resume from sleep
78 // re-enable the inhibition upon resume from sleep
78− QDBusConnection::systemBus().connect(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, QStringLiteral("PrepareForSleep"),
79+ QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, QStringLiteral("PrepareForSleep"),
79− this, SLOT(onResuming(bool)));
80+ this, SLOT(onResuming(bool)));
81 qWarning() << "Failed to get logind session path" << reply.error().message();
82 qWarning() << "Failed to get logind session path" << reply.error().message();
@@ -96,7 +97,7 @@ public:
96 msg << "Unity8 handles power events"; // why
97 msg << "Unity8 handles power events"; // why
97 msg << "block"; // mode
98 msg << "block"; // mode
99− QDBusPendingCall pendingCall = QDBusConnection::systemBus().asyncCall(msg);
100+ QDBusPendingCall pendingCall = QDBusConnection::SM_BUSNAME().asyncCall(msg);
100 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
101 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
101 connect(watcher, &QDBusPendingCallWatcher::finished,
102 connect(watcher, &QDBusPendingCallWatcher::finished,
102 this, [this](QDBusPendingCallWatcher* watcher) {
103 this, [this](QDBusPendingCallWatcher* watcher) {
@@ -114,7 +115,7 @@ public:
114 bool checkLogin1Call(const QString &method) const
115 bool checkLogin1Call(const QString &method) const
116 QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
117 QDBusMessage msg = QDBusMessage::createMethodCall(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, method);
117− QDBusReply<QString> reply = QDBusConnection::systemBus().call(msg);
118+ QDBusReply<QString> reply = QDBusConnection::SM_BUSNAME().call(msg);
118 return reply.isValid() && (reply == QStringLiteral("yes") || reply == QStringLiteral("challenge"));
119 return reply.isValid() && (reply == QStringLiteral("yes") || reply == QStringLiteral("challenge"));
@@ -125,7 +126,7 @@ public:
125 LOGIN1_IFACE,
126 LOGIN1_IFACE,
127 msg.setArguments(args);
128 msg.setArguments(args);
128− QDBusConnection::systemBus().asyncCall(msg);
129+ QDBusConnection::SM_BUSNAME().asyncCall(msg);
131 void setActive(bool active)
132 void setActive(bool active)
@@ -157,7 +158,7 @@ public:
157 msg << LOGIN1_SESSION_IFACE;
158 msg << LOGIN1_SESSION_IFACE;
158 msg << ACTIVE_KEY;
159 msg << ACTIVE_KEY;
160− QDBusPendingCall pendingCall = QDBusConnection::systemBus().asyncCall(msg);
161+ QDBusPendingCall pendingCall = QDBusConnection::SM_BUSNAME().asyncCall(msg);
161 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
162 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
162 connect(watcher, &QDBusPendingCallWatcher::finished,
163 connect(watcher, &QDBusPendingCallWatcher::finished,
163 this, [this](QDBusPendingCallWatcher* watcher) {
164 this, [this](QDBusPendingCallWatcher* watcher) {
@@ -191,7 +192,7 @@ public:
191 msg << LOGIN1_SESSION_IFACE;
192 msg << LOGIN1_SESSION_IFACE;
192 msg << IDLE_SINCE_KEY;
193 msg << IDLE_SINCE_KEY;
194− QDBusReply<QVariant> reply = QDBusConnection::systemBus().call(msg);
195+ QDBusReply<QVariant> reply = QDBusConnection::SM_BUSNAME().call(msg);
195 if (reply.isValid()) {
196 if (reply.isValid()) {
196 return reply.value().value<quint64>();
197 return reply.value().value<quint64>();
@@ -208,7 +209,24 @@ public:
208 LOGIN1_SESSION_IFACE,
209 LOGIN1_SESSION_IFACE,
209 QStringLiteral("SetIdleHint"));
210 QStringLiteral("SetIdleHint"));
210 msg << idle;
211 msg << idle;
211− QDBusConnection::systemBus().asyncCall(msg);
212+ QDBusConnection::SM_BUSNAME().asyncCall(msg);
215+ bool isUserInGroup(const QString &user, const QString &groupName) const
217+ auto group = getgrnam(groupName.toUtf8().data());
219+ if (group && group->gr_mem)
221+ for (int i = 0; group->gr_mem[i]; ++i)
223+ if (g_strcmp0(group->gr_mem[i], user.toUtf8().data()) == 0) {
214private Q_SLOTS:
232private Q_SLOTS:
@@ -243,11 +261,11 @@ DBusUnitySessionService::DBusUnitySessionService()
243 : UnityDBusObject(QStringLiteral("/com/canonical/Unity/Session"), QStringLiteral("com.canonical.Unity"))
261 : UnityDBusObject(QStringLiteral("/com/canonical/Unity/Session"), QStringLiteral("com.canonical.Unity"))
245 if (!d->logindSessionPath.isEmpty()) {
263 if (!d->logindSessionPath.isEmpty()) {
246− // connect our Lock() slot to the logind's session Lock() signal
264+ // connect our PromptLock() slot to the logind's session Lock() signal
247− QDBusConnection::systemBus().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, QStringLiteral("Lock"), this, SLOT(Lock()));
265+ QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, QStringLiteral("Lock"), this, SLOT(PromptLock()));
248 // ... and our Unlocked() signal to the logind's session Unlock() signal
266 // ... and our Unlocked() signal to the logind's session Unlock() signal
249 // (lightdm handles the unlocking by calling logind's Unlock method which in turn emits this signal we connect to)
267 // (lightdm handles the unlocking by calling logind's Unlock method which in turn emits this signal we connect to)
250− QDBusConnection::systemBus().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, QStringLiteral("Unlock"), this, SIGNAL(Unlocked()));
268+ QDBusConnection::SM_BUSNAME().connect(LOGIN1_SERVICE, d->logindSessionPath, LOGIN1_SESSION_IFACE, QStringLiteral("Unlock"), this, SLOT(doUnlock()));
251 connect(d, &DBusUnitySessionServicePrivate::prepareForSleep, this, &DBusUnitySessionService::PromptLock);
269 connect(d, &DBusUnitySessionServicePrivate::prepareForSleep, this, &DBusUnitySessionService::PromptLock);
253 qWarning() << "Failed to connect to logind's session Lock/Unlock signals";
271 qWarning() << "Failed to connect to logind's session Lock/Unlock signals";
@@ -297,7 +315,13 @@ bool DBusUnitySessionService::CanShutdown() const
298bool DBusUnitySessionService::CanLock() const
316bool DBusUnitySessionService::CanLock() const
318+ auto user = UserName();
319+ if (user.startsWith(QStringLiteral("guest-")) ||
320+ d->isUserInGroup(user, QStringLiteral("nopasswdlogin"))) {
300− return true; // FIXME
323+ return true;
303QString DBusUnitySessionService::UserName() const
327QString DBusUnitySessionService::UserName() const
@@ -332,15 +356,43 @@ QString DBusUnitySessionService::HostName() const
333void DBusUnitySessionService::PromptLock()
357void DBusUnitySessionService::PromptLock()
359+ // Prompt as in quick. No locking animation needed. Usually used by
360+ // indicator-session in combination with a switch to greeter or other
335− Q_EMIT LockRequested();
363+ Q_EMIT LockRequested();
336− Q_EMIT lockRequested();
364+ Q_EMIT lockRequested();
339void DBusUnitySessionService::Lock()
368void DBusUnitySessionService::Lock()
341− // signal u8 to show the lockscreen/greeter
370+ // Normal lock (with animation, as compared to PromptLock above). Usually
371+ // used by indicator-session to lock the session in place.
373+ // FIXME: We also -- as a bit of a hack around indicator-session not fully
374+ // supporting a phone profile -- switch to greeter here. The unity7 flow is
375+ // that the user chooses "Lock/Switch" from the indicator, and then can go
376+ // to greeter by selecting "Switch" again from the indicator, which is now
377+ // exposed by the desktop_lockscreen profile. But since in unity8, we try
378+ // to expose most things all the time, we don't use the separate lockscreen
379+ // profile. Instead, we just go directly to the greeter the first time
380+ // a user presses "Lock/Switch". This isn't what this DBus call is
381+ // supposed to do, but we can live with it for now.
383+ // Here's a bug about indicator-session growing a converged Touch profile:
384+ // https://launchpad.net/bugs/1557716
386+ // We only do this here in the animated-lock call because that's the only
387+ // time the indicator locks without also asking the display manager to
388+ // switch sessions on us. And since we are switching screens, we also
389+ // don't bother respecting the animate request, simply doing a PromptLock.
342 PromptLock();
390 PromptLock();
394+void DBusUnitySessionService::switchToGreeter()
344 // lock the session using the org.freedesktop.DisplayManager system DBUS service
396 // lock the session using the org.freedesktop.DisplayManager system DBUS service
345 const QString sessionPath = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
397 const QString sessionPath = QString::fromLocal8Bit(qgetenv("XDG_SESSION_PATH"));
346 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DisplayManager"),
398 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DisplayManager"),
@@ -348,7 +400,7 @@ void DBusUnitySessionService::Lock()
348 QStringLiteral("org.freedesktop.DisplayManager.Session"),
400 QStringLiteral("org.freedesktop.DisplayManager.Session"),
349 QStringLiteral("Lock"));
401 QStringLiteral("Lock"));
351− QDBusPendingCall pendingCall = QDBusConnection::systemBus().asyncCall(msg);
403+ QDBusPendingCall pendingCall = QDBusConnection::SM_BUSNAME().asyncCall(msg);
352 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
404 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this);
353 connect(watcher, &QDBusPendingCallWatcher::finished,
405 connect(watcher, &QDBusPendingCallWatcher::finished,
354 this, [this](QDBusPendingCallWatcher* watcher) {
406 this, [this](QDBusPendingCallWatcher* watcher) {
@@ -365,6 +417,12 @@ void DBusUnitySessionService::Lock()
420+void DBusUnitySessionService::doUnlock()
368bool DBusUnitySessionService::IsLocked() const
426bool DBusUnitySessionService::IsLocked() const
370 return !d->isSessionActive;
428 return !d->isSessionActive;
@@ -436,11 +494,56 @@ void performAsyncUnityCall(const QString &method)
438DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
496DBusGnomeSessionManagerWrapper::DBusGnomeSessionManagerWrapper()
497+ : UnityDBusObject(QStringLiteral("/org/gnome/SessionManager"), QStringLiteral("org.gnome.SessionManager"))
501+void DBusGnomeSessionManagerWrapper::Logout(quint32 mode)
503+ auto call = QStringLiteral("RequestLogout");
505+ // These modes are documented as bitwise flags, not an enum, even though
506+ // they only ever seem to be used as enums.
508+ if (mode & 1) // without dialog
509+ call = QStringLiteral("Logout");
510+ if (mode & 2) // without dialog, ignoring inhibitors (which we don't have)
511+ call = QStringLiteral("Logout");
513+ performAsyncUnityCall(call);
516+void DBusGnomeSessionManagerWrapper::Reboot()
518+ // GNOME's Reboot means with dialog (they use Request differently than us).
519+ performAsyncUnityCall(QStringLiteral("RequestReboot"));
522+void DBusGnomeSessionManagerWrapper::RequestReboot()
524+ // GNOME's RequestReboot means no dialog (they use Request differently than us).
525+ performAsyncUnityCall(QStringLiteral("Reboot"));
528+void DBusGnomeSessionManagerWrapper::RequestShutdown()
530+ // GNOME's RequestShutdown means no dialog (they use Request differently than us).
531+ performAsyncUnityCall(QStringLiteral("Shutdown"));
534+void DBusGnomeSessionManagerWrapper::Shutdown()
536+ // GNOME's Shutdown means with dialog (they use Request differently than us).
537+ performAsyncUnityCall(QStringLiteral("RequestShutdown"));
541+DBusGnomeSessionManagerDialogWrapper::DBusGnomeSessionManagerDialogWrapper()
439 : UnityDBusObject(QStringLiteral("/org/gnome/SessionManager/EndSessionDialog"), QStringLiteral("com.canonical.Unity"))
542 : UnityDBusObject(QStringLiteral("/org/gnome/SessionManager/EndSessionDialog"), QStringLiteral("com.canonical.Unity"))
443−void DBusGnomeSessionManagerWrapper::Open(const unsigned type, const unsigned arg_1, const unsigned max_wait, const QList<QDBusObjectPath> &inhibitors)
546+void DBusGnomeSessionManagerDialogWrapper::Open(const unsigned type, const unsigned arg_1, const unsigned max_wait, const QList<QDBusObjectPath> &inhibitors)
445 Q_UNUSED(arg_1);
548 Q_UNUSED(arg_1);
446 Q_UNUSED(max_wait);
549 Q_UNUSED(max_wait);
@@ -486,7 +589,7 @@ void DBusGnomeScreensaverWrapper::SetActive(bool lock)
487void DBusGnomeScreensaverWrapper::Lock()
590void DBusGnomeScreensaverWrapper::Lock()
489− performAsyncUnityCall(QStringLiteral("Lock"));
592+ performAsyncUnityCall(QStringLiteral("PromptLock"));
492quint32 DBusGnomeScreensaverWrapper::GetActiveTime() const
595quint32 DBusGnomeScreensaverWrapper::GetActiveTime() const
@@ -523,7 +626,7 @@ bool DBusScreensaverWrapper::SetActive(bool lock)
524void DBusScreensaverWrapper::Lock()
627void DBusScreensaverWrapper::Lock()
526− performAsyncUnityCall(QStringLiteral("Lock"));
629+ performAsyncUnityCall(QStringLiteral("PromptLock"));
529quint32 DBusScreensaverWrapper::GetActiveTime() const
632quint32 DBusScreensaverWrapper::GetActiveTime() const
plugins/Unity/Session/dbusunitysessionservice.h+25−4
@@ -106,6 +106,7 @@ Q_SIGNALS:
106 * Emitted after the session has been unlocked.
106 * Emitted after the session has been unlocked.
108 Q_SCRIPTABLE void Unlocked();
108 Q_SCRIPTABLE void Unlocked();
110public Q_SLOTS:
111public Q_SLOTS:
@@ -258,22 +259,42 @@ public Q_SLOTS:
258 * @return whether the session is currently locked
259 * @return whether the session is currently locked
260 Q_SCRIPTABLE bool IsLocked() const;
261 Q_SCRIPTABLE bool IsLocked() const;
267+ void switchToGreeter();
263class DBusGnomeSessionManagerWrapper : public UnityDBusObject
270class DBusGnomeSessionManagerWrapper : public UnityDBusObject
266− Q_CLASSINFO("D-Bus Interface", "org.gnome.SessionManager.EndSessionDialog")
273+ Q_CLASSINFO("D-Bus Interface", "org.gnome.SessionManager")
269 DBusGnomeSessionManagerWrapper();
276 DBusGnomeSessionManagerWrapper();
270 ~DBusGnomeSessionManagerWrapper() = default;
277 ~DBusGnomeSessionManagerWrapper() = default;
272public Q_SLOTS:
279public Q_SLOTS:
273− Q_SCRIPTABLE void Open(const unsigned int type, const unsigned int arg_1, const unsigned int max_wait, const QList<QDBusObjectPath> &inhibitors);
280+ Q_SCRIPTABLE void Logout(quint32 mode);
281+ Q_SCRIPTABLE void Reboot();
282+ Q_SCRIPTABLE void RequestReboot();
283+ Q_SCRIPTABLE void RequestShutdown();
284+ Q_SCRIPTABLE void Shutdown();
275−private:
287+class DBusGnomeSessionManagerDialogWrapper : public UnityDBusObject
276− void performAsyncCall(const QString &method);
288+{
290+ Q_CLASSINFO("D-Bus Interface", "org.gnome.SessionManager.EndSessionDialog")
293+ DBusGnomeSessionManagerDialogWrapper();
294+ ~DBusGnomeSessionManagerDialogWrapper() = default;
297+ Q_SCRIPTABLE void Open(const unsigned int type, const unsigned int arg_1, const unsigned int max_wait, const QList<QDBusObjectPath> &inhibitors);
279class DBusGnomeScreensaverWrapper: public UnityDBusObject
300class DBusGnomeScreensaverWrapper: public UnityDBusObject
plugins/Unity/Session/plugin.cpp+1
@@ -26,6 +26,7 @@
27static QObject *dbusunitysessionservice_provider(QQmlEngine */*engine*/, QJSEngine */*jsEngine*/)
27static QObject *dbusunitysessionservice_provider(QQmlEngine */*engine*/, QJSEngine */*jsEngine*/)
29+ new DBusGnomeSessionManagerDialogWrapper();
29 new DBusGnomeSessionManagerWrapper();
30 new DBusGnomeSessionManagerWrapper();
30 new DBusGnomeScreensaverWrapper();
31 new DBusGnomeScreensaverWrapper();
31 new DBusScreensaverWrapper();
32 new DBusScreensaverWrapper();
plugins/Utils/CMakeLists.txt+16−4
@@ -1,15 +1,23 @@
1include_directories(
1include_directories(
2 ${CMAKE_CURRENT_SOURCE_DIR}
2 ${CMAKE_CURRENT_SOURCE_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
3 ${CMAKE_CURRENT_BINARY_DIR}
4 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
8 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
5 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
9 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
9set(QMLPLUGIN_SRC
12set(QMLPLUGIN_SRC
10 activefocuslogger.cpp
13 activefocuslogger.cpp
11 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
14 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
15+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
12 applicationsfiltermodel.cpp
16 applicationsfiltermodel.cpp
17+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h
18+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
19+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h
20+ appdrawerproxymodel.cpp
13 constants.cpp
21 constants.cpp
14 WindowInputMonitor.cpp
22 WindowInputMonitor.cpp
15 inputwatcher.cpp
23 inputwatcher.cpp
@@ -24,6 +32,10 @@ set(QMLPLUGIN_SRC
24 inputeventgenerator.cpp
32 inputeventgenerator.cpp
25 deviceconfigparser.cpp
33 deviceconfigparser.cpp
26 globalfunctions.cpp
34 globalfunctions.cpp
37+ expressionfiltermodel.cpp
38+ quicklistproxymodel.cpp
27 plugin.cpp
39 plugin.cpp
@@ -31,7 +43,9 @@ add_library(Utils-qml SHARED
31 ${QMLPLUGIN_SRC}
43 ${QMLPLUGIN_SRC}
34−target_link_libraries(Utils-qml ${GIO_LDFLAGS})
46+target_link_libraries(Utils-qml
47+ Qt5::Qml Qt5::Quick Qt5::DBus Qt5::Network Qt5::Gui Qt5::Sql Qt5::Concurrent
36# Because this is an internal support library, we want
50# Because this is an internal support library, we want
37# to expose all symbols in it. Consider changing this
51# to expose all symbols in it. Consider changing this
@@ -39,6 +53,4 @@ target_link_libraries(Utils-qml ${GIO_LDFLAGS})
39# files directly in targets.
53# files directly in targets.
40set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
54set_target_properties(Utils-qml PROPERTIES COMPILE_FLAGS -fvisibility=default)
42−qt5_use_modules(Utils-qml Qml Quick DBus Network Gui Sql Concurrent)
44add_unity8_plugin(Utils 0.1 Utils TARGETS Utils-qml)
56add_unity8_plugin(Utils 0.1 Utils TARGETS Utils-qml)
plugins/Utils/ElapsedTimer.h+1−1
@@ -41,7 +41,7 @@ class ElapsedTimer : public AbstractElapsedTimer {
42 void start() override { m_timer.start(); }
42 void start() override { m_timer.start(); }
43 qint64 msecsSinceReference() const override { return m_timer.msecsSinceReference(); }
43 qint64 msecsSinceReference() const override { return m_timer.msecsSinceReference(); }
44− qint64 elapsed() const override { return m_timer.elapsed(); }
44+ qint64 elapsed() const override { return m_timer.isValid() ? m_timer.elapsed() : 0; }
46 QElapsedTimer m_timer;
46 QElapsedTimer m_timer;
plugins/Utils/Timer.cpp+5−2
@@ -37,13 +37,16 @@ void Timer::setInterval(int msecs)
37void Timer::start()
37void Timer::start()
39 m_timer.start();
39 m_timer.start();
40− AbstractTimer::start();
43void Timer::stop()
42void Timer::stop()
45 m_timer.stop();
44 m_timer.stop();
46− AbstractTimer::stop();
45+}
47+bool Timer::isRunning() const
49+ return m_timer.isActive();
49bool Timer::isSingleShot() const
52bool Timer::isSingleShot() const
plugins/Utils/Timer.h+5−6
@@ -30,18 +30,16 @@ class AbstractTimer : public QObject
33− AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
33+ AbstractTimer(QObject *parent) : QObject(parent) {}
34 virtual int interval() const = 0;
34 virtual int interval() const = 0;
35 virtual void setInterval(int msecs) = 0;
35 virtual void setInterval(int msecs) = 0;
36− virtual void start() { m_isRunning = true; }
36+ virtual void start() = 0;
37− virtual void stop() { m_isRunning = false; }
37+ virtual void stop() = 0;
38− bool isRunning() const { return m_isRunning; }
38+ virtual bool isRunning() const = 0;
39 virtual bool isSingleShot() const = 0;
39 virtual bool isSingleShot() const = 0;
40 virtual void setSingleShot(bool value) = 0;
40 virtual void setSingleShot(bool value) = 0;
42 void timeout();
42 void timeout();
47/** A QTimer wrapper */
45/** A QTimer wrapper */
@@ -55,6 +53,7 @@ public:
55 void setInterval(int msecs) override;
53 void setInterval(int msecs) override;
56 void start() override;
54 void start() override;
57 void stop() override;
55 void stop() override;
56+ bool isRunning() const override;
58 bool isSingleShot() const override;
57 bool isSingleShot() const override;
59 void setSingleShot(bool value) override;
58 void setSingleShot(bool value) override;
plugins/Utils/URLDispatcher.cppnew file+80
@@ -0,0 +1,80 @@
2+ * Copyright (C) 2016-2017 Canonical, Ltd.
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.
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.
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/>.
17+#include "URLDispatcher.h"
19+#include <QDBusConnection>
22+class URLDispatcherInterface : public QObject
25+ Q_CLASSINFO("D-Bus Interface", "com.canonical.URLDispatcher")
28+ explicit URLDispatcherInterface(URLDispatcher *parent);
30+ Q_SCRIPTABLE void DispatchURL(const QString &url, const QString &package);
33+URLDispatcherInterface::URLDispatcherInterface(URLDispatcher *parent)
38+void URLDispatcherInterface::DispatchURL(const QString &url, const QString &package)
41+ Q_EMIT static_cast<URLDispatcher *>(parent())->urlRequested(url);
44+URLDispatcher::URLDispatcher(QObject *parent)
46+ , m_dispatcher(nullptr)
50+bool URLDispatcher::active() const
52+ return m_dispatcher != nullptr;
55+void URLDispatcher::setActive(bool value)
57+ if (value == active())
60+ QDBusConnection connection = QDBusConnection::sessionBus();
63+ URLDispatcherInterface *dispatcher = new URLDispatcherInterface(this);
64+ connection.registerObject(QStringLiteral("/com/canonical/URLDispatcher"),
66+ QDBusConnection::ExportScriptableContents);
67+ if (!connection.registerService(QStringLiteral("com.canonical.URLDispatcher"))) {
68+ qWarning() << "Unable to register DBus service com.canonical.URLDispatcher";
70+ m_dispatcher = dispatcher;
72+ connection.unregisterService(QStringLiteral("com.canonical.URLDispatcher"));
74+ m_dispatcher = nullptr;
77+ Q_EMIT activeChanged();
80+#include "URLDispatcher.moc"
plugins/Utils/URLDispatcher.hnew file+47
@@ -0,0 +1,47 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
17+#ifndef UNITY_URLDISPATCHER_H
18+#define UNITY_URLDISPATCHER_H
23+// This class manages our url-dispatcher interception. We intercept
24+// url-dispatcher because rather than spawning the handler for the URL
25+// in our own session, we want to notify the user session to do it for us
26+// (and start an unlock in the process).
28+class URLDispatcher : public QObject
31+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
34+ explicit URLDispatcher(QObject *parent=0);
37+ void setActive(bool active);
40+ void urlRequested(const QString &url);
41+ void activeChanged();
44+ QObject *m_dispatcher;
plugins/Utils/Utils.qmltypesdeleted−175
@@ -1,175 +0,0 @@
1−import QtQuick.tooling 1.1
3−// This file describes the plugin-supplied types contained in the library.
4−// It is used for QML tooling purposes only.
6−// This file was auto-generated by:
7−// 'qmlplugindump -notrelocatable Utils 0.1 plugins'
13− exports: ["Utils/EasingCurve 0.1"]
14− exportMetaObjectRevisions: [0]
15− Property { name: "type"; type: "QEasingCurve::Type" }
16− Property { name: "period"; type: "double" }
17− Property { name: "progress"; type: "double" }
18− Property { name: "value"; type: "double"; isReadonly: true }
21− name: "QAbstractProxyModel"
22− prototype: "QAbstractItemModel"
23− Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
25− Component { name: "QIdentityProxyModel"; prototype: "QAbstractProxyModel" }
27− name: "QLimitProxyModelQML"
28− prototype: "QIdentityProxyModel"
29− exports: ["Utils/LimitProxyModel 0.1"]
30− exportMetaObjectRevisions: [0]
31− Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
32− Property { name: "limit"; type: "int" }
33− Property { name: "count"; type: "int"; isReadonly: true }
34− Signal { name: "totalCountChanged" }
37− name: "QSortFilterProxyModel"
38− prototype: "QAbstractProxyModel"
39− Property { name: "filterRegExp"; type: "QRegExp" }
40− Property { name: "filterKeyColumn"; type: "int" }
41− Property { name: "dynamicSortFilter"; type: "bool" }
42− Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" }
43− Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" }
44− Property { name: "isSortLocaleAware"; type: "bool" }
45− Property { name: "sortRole"; type: "int" }
46− Property { name: "filterRole"; type: "int" }
48− name: "setFilterRegExp"
49− Parameter { name: "pattern"; type: "string" }
52− name: "setFilterWildcard"
53− Parameter { name: "pattern"; type: "string" }
56− name: "setFilterFixedString"
57− Parameter { name: "pattern"; type: "string" }
59− Method { name: "clear" }
60− Method { name: "invalidate" }
63− name: "RelativeTimeFormatter"
64− prototype: "TimeFormatter"
65− exports: ["Utils/RelativeTimeFormatter 0.1"]
66− exportMetaObjectRevisions: [0]
69− name: "TimeFormatter"
71− exports: ["Utils/GDateTimeFormatter 0.1", "Utils/TimeFormatter 0.1"]
72− exportMetaObjectRevisions: [0, 0]
73− Property { name: "format"; type: "string" }
74− Property { name: "timeString"; type: "string"; isReadonly: true }
75− Property { name: "time"; type: "qlonglong" }
77− name: "formatChanged"
78− Parameter { name: "format"; type: "string" }
81− name: "timeStringChanged"
82− Parameter { name: "timeString"; type: "string" }
86− Parameter { name: "time"; type: "qlonglong" }
90− name: "UnityMenuModelPaths"
92− exports: ["Utils/UnityMenuModelPaths 0.1"]
93− exportMetaObjectRevisions: [0]
94− Property { name: "source"; type: "QVariant" }
95− Property { name: "busName"; type: "QByteArray"; isReadonly: true }
96− Property { name: "actions"; type: "QVariantMap"; isReadonly: true }
97− Property { name: "menuObjectPath"; type: "QByteArray"; isReadonly: true }
98− Property { name: "busNameHint"; type: "QByteArray" }
99− Property { name: "actionsHint"; type: "QByteArray" }
100− Property { name: "menuObjectPathHint"; type: "QByteArray" }
103− name: "UnitySortFilterProxyModelQML"
104− prototype: "QSortFilterProxyModel"
105− exports: ["Utils/UnitySortFilterProxyModel 0.1"]
106− exportMetaObjectRevisions: [0]
107− Property { name: "model"; type: "QAbstractItemModel"; isPointer: true }
108− Property { name: "totalCount"; type: "int"; isReadonly: true }
109− Property { name: "count"; type: "int"; isReadonly: true }
110− Property { name: "invertMatch"; type: "bool" }
112− name: "invertMatchChanged"
113− Parameter { type: "bool" }
118− Parameter { name: "row"; type: "int" }
123− Parameter { name: "row"; type: "int" }
124− Parameter { name: "role"; type: "int" }
126− Method { name: "count"; type: "int" }
130− Parameter { name: "role"; type: "int" }
131− Parameter { name: "value"; type: "QVariant" }
134− name: "mapRowToSource"
136− Parameter { name: "row"; type: "int" }
139− name: "mapFromSource"
141− Parameter { name: "row"; type: "int" }
146− Parameter { name: "row"; type: "int" }
150− name: "WindowInputFilter"
151− defaultProperty: "data"
152− prototype: "QQuickItem"
153− exports: ["Utils/WindowInputFilter 0.1"]
154− exportMetaObjectRevisions: [0]
157− name: "WindowStateStorage"
158− prototype: "QObject"
159− exports: ["Utils/WindowStateStorage 0.1"]
162− exportMetaObjectRevisions: [0]
164− name: "saveGeometry"
165− Parameter { name: "windowId"; type: "string" }
166− Parameter { name: "rect"; type: "QRect" }
171− Parameter { name: "windowId"; type: "string" }
172− Parameter { name: "defaultValue"; type: "QRect" }
plugins/Utils/WindowInputMonitor.cpp+3
@@ -73,6 +73,9 @@ void WindowInputMonitor::update(QEvent *event)
73 && m_windowLastTouchedTimer->elapsed() >= msecsWithoutTouches) {
73 && m_windowLastTouchedTimer->elapsed() >= msecsWithoutTouches) {
74 m_pressedHomeKey = keyEvent->key();
74 m_pressedHomeKey = keyEvent->key();
75 m_activationTimer->start();
75 m_activationTimer->start();
76+ } else if (m_pressedHomeKey != 0 && !m_homeKeys.contains(keyEvent->key())) {
77+ // something else came in... cancel activation
78+ m_activationTimer->stop();
78 } else if (event->type() == QEvent::KeyRelease) {
81 } else if (event->type() == QEvent::KeyRelease) {
plugins/Utils/appdrawerproxymodel.cppnew file+189
@@ -0,0 +1,189 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
17+#include "appdrawerproxymodel.h"
19+#include <unity/shell/launcher/LauncherItemInterface.h>
23+AppDrawerProxyModel::AppDrawerProxyModel(QObject *parent):
24+ QSortFilterProxyModel(parent)
26+ setSortRole(AppDrawerModelInterface::RoleName);
27+ setSortLocaleAware(true);
30+ connect(this, &QAbstractListModel::rowsInserted, this, &AppDrawerProxyModel::countChanged);
31+ connect(this, &QAbstractListModel::rowsRemoved, this, &AppDrawerProxyModel::countChanged);
32+ connect(this, &QAbstractListModel::layoutChanged, this, &AppDrawerProxyModel::countChanged);
35+QAbstractItemModel *AppDrawerProxyModel::source() const
40+void AppDrawerProxyModel::setSource(QAbstractItemModel *source)
42+ if (m_source != source) {
44+ setSourceModel(m_source);
45+ setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage);
46+ connect(m_source, &QAbstractItemModel::rowsRemoved, this, &AppDrawerProxyModel::invalidate);
47+ connect(m_source, &QAbstractItemModel::rowsInserted, this, &AppDrawerProxyModel::invalidate);
48+ Q_EMIT sourceChanged();
52+AppDrawerProxyModel::GroupBy AppDrawerProxyModel::group() const
57+void AppDrawerProxyModel::setGroup(AppDrawerProxyModel::GroupBy group)
59+ if (m_group != group) {
61+ Q_EMIT groupChanged();
66+QString AppDrawerProxyModel::filterLetter() const
68+ return m_filterLetter;
71+void AppDrawerProxyModel::setFilterLetter(const QString &filterLetter)
73+ if (m_filterLetter != filterLetter) {
74+ m_filterLetter = filterLetter;
75+ Q_EMIT filterLetterChanged();
80+QString AppDrawerProxyModel::filterString() const
82+ return m_filterString;
85+void AppDrawerProxyModel::setFilterString(const QString &filterString)
87+ if (m_filterString != filterString) {
88+ m_filterString = filterString;
89+ Q_EMIT filterStringChanged();
94+AppDrawerProxyModel::SortBy AppDrawerProxyModel::sortBy() const
99+void AppDrawerProxyModel::setSortBy(AppDrawerProxyModel::SortBy sortBy)
101+ if (m_sortBy != sortBy) {
103+ Q_EMIT sortByChanged();
104+ setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage);
109+int AppDrawerProxyModel::count() const
114+QVariant AppDrawerProxyModel::data(const QModelIndex &index, int role) const
116+ QModelIndex idx = mapToSource(index);
117+ if (role == Qt::UserRole) {
118+ QString name = m_source->data(idx, AppDrawerModelInterface::RoleName).toString();
119+ return name.length() > 0 ? QString(name.at(0)).toUpper() : QChar();
121+ return m_source->data(idx, role);
124+QHash<int, QByteArray> AppDrawerProxyModel::roleNames() const
127+ QHash<int, QByteArray> roles = m_source->roleNames();
128+ roles.insert(Qt::UserRole, "letter");
131+ return QHash<int, QByteArray>();
134+bool AppDrawerProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
136+ Q_UNUSED(source_parent)
138+ if (m_group == GroupByAToZ && source_row > 0) {
139+ QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString();
140+ QChar currentLetter = currentName.length() > 0 ? currentName.at(0) : QChar();
141+ QString previousName = m_source->data(m_source->index(source_row - 1,0 ), AppDrawerModelInterface::RoleName).toString();
142+ QChar previousLetter = previousName.length() > 0 ? previousName.at(0) : QChar();
143+ if (currentLetter.toLower() == previousLetter.toLower()) {
146+ } else if(m_group == GroupByAll && source_row > 0) {
149+ if (!m_filterLetter.isEmpty()) {
150+ QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString();
151+ QString currentLetter = currentName.length() > 0 ? QString(currentName.at(0)) : QString();
152+ if (currentLetter.toLower() != m_filterLetter.toLower()) {
156+ if (!m_filterString.isEmpty()) {
157+ QStringList allWords = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleKeywords).toStringList();
158+ allWords.prepend(m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString());
160+ Q_FOREACH (const QString ¤tWord, allWords) {
161+ if (currentWord.contains(m_filterString, Qt::CaseInsensitive)) {
173+QString AppDrawerProxyModel::appId(int index) const
175+ if (index >= 0 && index < rowCount()) {
176+ QModelIndex sourceIndex = mapToSource(this->index(index, 0));
178+ AppDrawerModelInterface* adm = dynamic_cast<AppDrawerModelInterface*>(m_source);
180+ return adm->data(sourceIndex, AppDrawerModelInterface::RoleAppId).toString();
183+ AppDrawerProxyModel* adpm = qobject_cast<AppDrawerProxyModel*>(m_source);
185+ return adpm->appId(sourceIndex.row());
plugins/Utils/appdrawerproxymodel.hnew file+87
@@ -0,0 +1,87 @@
2+ * Copyright (C) 2016 Canonical, Ltd.
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.
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.
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/>.
17+#include <QSortFilterProxyModel>
19+#include <unity/shell/launcher/AppDrawerModelInterface.h>
21+using namespace unity::shell::launcher;
23+class AppDrawerProxyModel: public QSortFilterProxyModel
26+ Q_PROPERTY(QAbstractItemModel* source READ source WRITE setSource NOTIFY sourceChanged)
27+ Q_PROPERTY(GroupBy group READ group WRITE setGroup NOTIFY groupChanged)
28+ Q_PROPERTY(QString filterLetter READ filterLetter WRITE setFilterLetter NOTIFY filterLetterChanged)
29+ Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
30+ Q_PROPERTY(SortBy sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged)
31+ Q_PROPERTY(int count READ count NOTIFY countChanged)
46+ AppDrawerProxyModel(QObject* parent = nullptr);
48+ QAbstractItemModel* source() const;
49+ void setSource(QAbstractItemModel* source);
51+ GroupBy group() const;
52+ void setGroup(GroupBy group);
54+ QString filterLetter() const;
55+ void setFilterLetter(const QString &filterLetter);
57+ QString filterString() const;
58+ void setFilterString(const QString &filterString);
60+ SortBy sortBy() const;
61+ void setSortBy(SortBy sortBy);
65+ QVariant data(const QModelIndex &index, int role) const override;
66+ QHash<int, QByteArray> roleNames() const override;
68+ Q_INVOKABLE QString appId(int index) const;
71+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
74+ void sourceChanged();
76+ void filterLetterChanged();
77+ void filterStringChanged();
78+ void sortByChanged();
82+ QAbstractItemModel* m_source = nullptr;
83+ GroupBy m_group = GroupByNone;
84+ QString m_filterLetter;
85+ QString m_filterString;
86+ SortBy m_sortBy = SortByAToZ;
plugins/Utils/constants.cpp+6−1
@@ -1,5 +1,5 @@
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright 2015-2016 Canonical Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -16,6 +16,8 @@
17#include "constants.h"
17#include "constants.h"
19Constants::Constants(QObject *parent)
21Constants::Constants(QObject *parent)
20 : QObject(parent)
22 : QObject(parent)
@@ -24,4 +26,7 @@ Constants::Constants(QObject *parent)
25 m_indicatorValueTimeout = 5000;
27 m_indicatorValueTimeout = 5000;
30+ QString snapRoot = QFile::decodeName(qgetenv("SNAP"));
31+ m_defaultWallpaper = snapRoot + "/usr/share/backgrounds/warty-final-ubuntu.png";
plugins/Utils/constants.h+5−5
@@ -1,5 +1,5 @@
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright 2015-2016 Canonical Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU Lesser General Public License as published by
@@ -14,8 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#ifndef CONSTANTS_H
17+#pragma once
20#include <QObject>
19#include <QObject>
@@ -30,14 +29,15 @@ class Constants: public QObject
32 Q_PROPERTY(int indicatorValueTimeout READ indicatorValueTimeout CONSTANT)
31 Q_PROPERTY(int indicatorValueTimeout READ indicatorValueTimeout CONSTANT)
32+ Q_PROPERTY(QString defaultWallpaper READ defaultWallpaper CONSTANT)
35 Constants(QObject *parent = 0);
35 Constants(QObject *parent = 0);
37 int indicatorValueTimeout() const { return m_indicatorValueTimeout; }
37 int indicatorValueTimeout() const { return m_indicatorValueTimeout; }
38+ QString defaultWallpaper() const { return m_defaultWallpaper; }
40 int m_indicatorValueTimeout;
41 int m_indicatorValueTimeout;
42+ QString m_defaultWallpaper;
plugins/Utils/deviceconfigparser.cpp+19−1
@@ -26,7 +26,7 @@ DeviceConfigParser::DeviceConfigParser(QObject *parent): QObject(parent)
26 // Local files have highest priority
26 // Local files have highest priority
27 QString path;
27 QString path;
28 Q_FOREACH (const QString &standardPath, QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation)) {
28 Q_FOREACH (const QString &standardPath, QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation)) {
29− if (QFileInfo(standardPath + "/devices.conf").exists()) {
29+ if (QFileInfo::exists(standardPath + "/devices.conf")) {
30 path = standardPath + "/devices.conf";
30 path = standardPath + "/devices.conf";
@@ -116,6 +116,24 @@ QString DeviceConfigParser::category() const
116 return value;
116 return value;
119+bool DeviceConfigParser::supportsMultiColorLed() const
121+ return readBoolFromConfig("SupportsMultiColorLed", true);
124+bool DeviceConfigParser::readBoolFromConfig(const QString &key, bool defaultValue) const
126+ m_config->beginGroup(m_name);
128+ bool ret = defaultValue;
129+ if (m_config->contains(key)) {
130+ ret = m_config->value(key).toBool();
133+ m_config->endGroup();
119QStringList DeviceConfigParser::readOrientationsFromConfig(const QString &key) const
137QStringList DeviceConfigParser::readOrientationsFromConfig(const QString &key) const
121 m_config->beginGroup(m_name);
139 m_config->beginGroup(m_name);
plugins/Utils/deviceconfigparser.h+3
@@ -33,6 +33,7 @@ class DeviceConfigParser: public QObject
33 Q_PROPERTY(Qt::ScreenOrientation portraitOrientation READ portraitOrientation NOTIFY changed)
33 Q_PROPERTY(Qt::ScreenOrientation portraitOrientation READ portraitOrientation NOTIFY changed)
34 Q_PROPERTY(Qt::ScreenOrientation invertedPortraitOrientation READ invertedPortraitOrientation NOTIFY changed)
34 Q_PROPERTY(Qt::ScreenOrientation invertedPortraitOrientation READ invertedPortraitOrientation NOTIFY changed)
35 Q_PROPERTY(QString category READ category NOTIFY changed)
35 Q_PROPERTY(QString category READ category NOTIFY changed)
36+ Q_PROPERTY(bool supportsMultiColorLed READ supportsMultiColorLed NOTIFY changed)
38 DeviceConfigParser(QObject *parent = nullptr);
39 DeviceConfigParser(QObject *parent = nullptr);
@@ -47,6 +48,7 @@ public:
47 Qt::ScreenOrientation portraitOrientation() const;
48 Qt::ScreenOrientation portraitOrientation() const;
48 Qt::ScreenOrientation invertedPortraitOrientation() const;
49 Qt::ScreenOrientation invertedPortraitOrientation() const;
49 QString category() const;
50 QString category() const;
51+ bool supportsMultiColorLed() const;
52 void changed();
54 void changed();
@@ -58,6 +60,7 @@ private:
58 QStringList readOrientationsFromConfig(const QString &key) const;
60 QStringList readOrientationsFromConfig(const QString &key) const;
59 QString readOrientationFromConfig(const QString &key) const;
61 QString readOrientationFromConfig(const QString &key) const;
60 Qt::ScreenOrientation stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const;
62 Qt::ScreenOrientation stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const;
63+ bool readBoolFromConfig(const QString &key, bool defaultValue) const;
plugins/Utils/easingcurve.h−1
@@ -36,7 +36,6 @@
36class EasingCurve: public QObject
36class EasingCurve: public QObject
39− Q_ENUMS(QEasingCurve::Type)
40 Q_PROPERTY(QEasingCurve::Type type READ type WRITE setType NOTIFY typeChanged)
39 Q_PROPERTY(QEasingCurve::Type type READ type WRITE setType NOTIFY typeChanged)
41 Q_PROPERTY(qreal period READ period WRITE setPeriod NOTIFY periodChanged)
40 Q_PROPERTY(qreal period READ period WRITE setPeriod NOTIFY periodChanged)
42 Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
41 Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
plugins/Utils/expressionfiltermodel.cppnew file+49
@@ -0,0 +1,49 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
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.
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.
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/>.
17+#include "expressionfiltermodel.h"
19+ExpressionFilterModel::ExpressionFilterModel(QObject *parent)
20+ : UnitySortFilterProxyModelQML(parent)
24+QJSValue ExpressionFilterModel::matchExpression() const
26+ return m_matchExpression;
29+void ExpressionFilterModel::setMatchExpression(const QJSValue &value)
31+ m_matchExpression = value;
36+ExpressionFilterModel::filterAcceptsRow(int sourceRow,
37+ const QModelIndex &sourceParent) const
39+ if (m_matchExpression.isCallable()) {
42+ QJSValue ret = m_matchExpression.call(args);
48+ return UnitySortFilterProxyModelQML::filterAcceptsRow(sourceRow, sourceParent);
plugins/Utils/expressionfiltermodel.hnew file+42
@@ -0,0 +1,42 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
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.
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.
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/>.
17+#ifndef EXPRESSIONFILTERMODEL_H
18+#define EXPRESSIONFILTERMODEL_H
20+#include "unitysortfilterproxymodelqml.h"
23+class ExpressionFilterModel : public UnitySortFilterProxyModelQML
26+ Q_PROPERTY(QJSValue matchExpression READ matchExpression WRITE setMatchExpression NOTIFY matchExpressionChanged)
28+ explicit ExpressionFilterModel(QObject *parent = 0);
30+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
32+ QJSValue matchExpression() const;
33+ void setMatchExpression(const QJSValue& value);
36+ void matchExpressionChanged();
39+ mutable QJSValue m_matchExpression;
42+#endif // EXPRESSIONFILTERMODEL_H
plugins/Utils/globalfunctions.cpp+6−4
@@ -16,11 +16,8 @@
17#include "globalfunctions.h"
17#include "globalfunctions.h"
19−#pragma GCC diagnostic push
20−#pragma GCC diagnostic ignored "-pedantic"
21−#include <private/qquickitem_p.h>
22−#pragma GCC diagnostic pop
23#include <QQmlEngine>
19#include <QQmlEngine>
20+#include <private/qquickitem_p.h>
25GlobalFunctions::GlobalFunctions(QObject *parent)
22GlobalFunctions::GlobalFunctions(QObject *parent)
26 : QObject(parent)
23 : QObject(parent)
@@ -54,3 +51,8 @@ QQuickItem *GlobalFunctions::itemAt(QQuickItem* parent, int x, int y, QJSValue m
55 return nullptr;
52 return nullptr;
55+bool GlobalFunctions::itemUnderMouse(QQuickItem* item)
57+ return item && item->isUnderMouse();
plugins/Utils/globalfunctions.h+2
@@ -37,6 +37,8 @@ public:
39 QJSValue matcher);
39 QJSValue matcher);
41+ static Q_INVOKABLE bool itemUnderMouse(QQuickItem* item);
42#endif // GLOBALFUNCTIONS_H
44#endif // GLOBALFUNCTIONS_H
plugins/Utils/plugin.cpp+11−1
@@ -1,5 +1,5 @@
2− * Copyright (C) 2012-2015 Canonical, Ltd.
2+ * Copyright (C) 2012-2017 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
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
5 * it under the terms of the GNU General Public License as published by
@@ -38,6 +38,11 @@
38#include "inputeventgenerator.h"
38#include "inputeventgenerator.h"
39#include "deviceconfigparser.h"
39#include "deviceconfigparser.h"
40#include "globalfunctions.h"
40#include "globalfunctions.h"
41+#include "URLDispatcher.h"
42+#include "appdrawerproxymodel.h"
43+#include "tabfocusfence.h"
44+#include "expressionfiltermodel.h"
45+#include "quicklistproxymodel.h"
42static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
47static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -80,4 +85,9 @@ void UtilsPlugin::registerTypes(const char *uri)
80 qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
85 qmlRegisterType<InputEventGenerator>(uri, 0, 1, "InputEventGenerator");
81 qmlRegisterType<DeviceConfigParser>(uri, 0, 1, "DeviceConfigParser");
86 qmlRegisterType<DeviceConfigParser>(uri, 0, 1, "DeviceConfigParser");
82 qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions);
87 qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions);
88+ qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher");
89+ qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel");
90+ qmlRegisterType<TabFocusFenceItem>(uri, 0, 1, "TabFocusFence");
91+ qmlRegisterType<ExpressionFilterModel>(uri, 0, 1, "ExpressionFilterModel");
92+ qmlRegisterType<QuickListProxyModel>(uri, 0, 1, "QuickListProxyModel");
plugins/Utils/quicklistproxymodel.cppnew file+72
@@ -0,0 +1,72 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
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.
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.
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/>.
17+#include "quicklistproxymodel.h"
21+QuickListProxyModel::QuickListProxyModel(QObject *parent):
22+ QSortFilterProxyModel(parent)
24+ connect(this, &QAbstractListModel::rowsInserted, this, &QuickListProxyModel::countChanged);
25+ connect(this, &QAbstractListModel::rowsRemoved, this, &QuickListProxyModel::countChanged);
26+ connect(this, &QAbstractListModel::layoutChanged, this, &QuickListProxyModel::countChanged);
29+QAbstractItemModel *QuickListProxyModel::source() const
34+bool QuickListProxyModel::privateMode() const
36+ return m_privateMode;
39+void QuickListProxyModel::setPrivateMode(bool privateMode)
41+ if (m_privateMode != privateMode) {
42+ m_privateMode = privateMode;
44+ Q_EMIT privateModeChanged();
48+void QuickListProxyModel::setSource(QAbstractItemModel *source)
50+ if (m_source != source) {
52+ setSourceModel(m_source);
53+ connect(m_source, &QAbstractItemModel::rowsRemoved, this, &QuickListProxyModel::invalidate);
54+ connect(m_source, &QAbstractItemModel::rowsInserted, this, &QuickListProxyModel::invalidate);
55+ Q_EMIT sourceChanged();
59+int QuickListProxyModel::count() const
64+bool QuickListProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
66+ Q_UNUSED(source_parent)
69+ return !m_source->data(m_source->index(source_row, 0), QuickListModelInterface::RoleIsPrivate).toBool();
plugins/Utils/quicklistproxymodel.hnew file+52
@@ -0,0 +1,52 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
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.
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.
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/>.
17+#include <QSortFilterProxyModel>
19+#include <unity/shell/launcher/QuickListModelInterface.h>
21+using namespace unity::shell::launcher;
23+class QuickListProxyModel: public QSortFilterProxyModel
26+ Q_PROPERTY(QAbstractItemModel* source READ source WRITE setSource NOTIFY sourceChanged)
27+ Q_PROPERTY(bool privateMode READ privateMode WRITE setPrivateMode NOTIFY privateModeChanged)
28+ Q_PROPERTY(int count READ count NOTIFY countChanged)
31+ QuickListProxyModel(QObject* parent = nullptr);
33+ QAbstractItemModel* source() const;
34+ void setSource(QAbstractItemModel* source);
36+ bool privateMode() const;
37+ void setPrivateMode(bool privateMode);
42+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
45+ void sourceChanged();
46+ void privateModeChanged();
50+ QAbstractItemModel* m_source = nullptr;
51+ bool m_privateMode = false;
plugins/Utils/tabfocusfence.cppnew file+72
@@ -0,0 +1,72 @@
2+ * Copyright 2017 Canonical Ltd.
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.
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.
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/>.
17+#include "tabfocusfence.h"
19+#include <private/qquickitem_p.h>
21+TabFocusFenceItem::TabFocusFenceItem(QQuickItem *parent) : QQuickItem(parent)
23+ QQuickItemPrivate *d = QQuickItemPrivate::get(this);
24+ d->isTabFence = true;
25+ setFlag(ItemIsFocusScope);
28+bool TabFocusFenceItem::focusNext()
30+ QQuickItem * current = scopedFocusItem();
32+ QQuickItem * next = current->nextItemInFocusChain(true);
34+ next->setFocus(true, Qt::TabFocusReason);
41+bool TabFocusFenceItem::focusPrev()
43+ QQuickItem * current = scopedFocusItem();
45+ QQuickItem * prev = current->nextItemInFocusChain(false);
47+ prev->setFocus(true, Qt::BacktabFocusReason);
54+void TabFocusFenceItem::keyPressEvent(QKeyEvent *event)
56+ // Needed so we eat Tab keys when there's only one item inside the fence
57+ if (event->key() == Qt::Key_Tab) {
60+ QQuickItem::keyPressEvent(event);
64+void TabFocusFenceItem::keyReleaseEvent(QKeyEvent *event)
66+ // Needed so we eat Tab keys when there's only one item inside the fence
67+ if (event->key() == Qt::Key_Tab) {
70+ QQuickItem::keyReleaseEvent(event);
plugins/Utils/tabfocusfence.hnew file+38
@@ -0,0 +1,38 @@
2+ * Copyright 2017 Canonical Ltd.
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.
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.
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/>.
17+#ifndef TABFOCUSFENCE_H
18+#define TABFOCUSFENCE_H
22+// An item that restricts focus Tab travelling
24+class TabFocusFenceItem : public QQuickItem
29+ TabFocusFenceItem(QQuickItem *parent = nullptr);
31+ Q_INVOKABLE bool focusNext();
32+ Q_INVOKABLE bool focusPrev();
34+ void keyPressEvent(QKeyEvent *event) override;
35+ void keyReleaseEvent(QKeyEvent *event) override;
plugins/Utils/timezoneFormatter.cpp+1−1
@@ -39,7 +39,7 @@ QString TimezoneFormatter::currentTimeInTimezoneWithAbbrev(const QVariant &tzId)
39 QTimeZone tz(tzId.toByteArray());
39 QTimeZone tz(tzId.toByteArray());
40 if (tz.isValid()) {
40 if (tz.isValid()) {
41 const QDateTime now = QDateTime::currentDateTime().toTimeZone(tz);
41 const QDateTime now = QDateTime::currentDateTime().toTimeZone(tz);
42− return QStringLiteral("%1 %2").arg(now.time().toString(QStringLiteral("h:mm"))).arg(tz.abbreviation(now));
42+ return QStringLiteral("%1 %2").arg(now.time().toString(QStringLiteral("h:mm")), tz.abbreviation(now));
44 return QString();
44 return QString();
plugins/Utils/unitysortfilterproxymodelqml.h+5
@@ -38,6 +38,11 @@ public:
38 Q_INVOKABLE int mapRowToSource(int row);
38 Q_INVOKABLE int mapRowToSource(int row);
39 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
39 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
41+ // Make the QSortFilterProxyModel variants also accessible
42+ using QSortFilterProxyModel::data;
43+ using QSortFilterProxyModel::mapFromSource;
44+ using QSortFilterProxyModel::mapToSource;
41 /* getters */
46 /* getters */
42 int totalCount() const;
47 int totalCount() const;
43 bool invertMatch() const;
48 bool invertMatch() const;
plugins/Utils/windowstatestorage.cpp+316−121
@@ -1,5 +1,6 @@
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright 2015-2016 Canonical Ltd.
3+ * Copyright 2021 UBports Foundation
4 * This program is free software; you can redistribute it and/or modify
5 * 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 * it under the terms of the GNU Lesser General Public License as published by
@@ -16,173 +17,367 @@
17#include "windowstatestorage.h"
18#include "windowstatestorage.h"
19−#include <QtConcurrent>
20#include <QDebug>
20#include <QDebug>
21−#include <QFutureSynchronizer>
21+#include <QDir>
22+#include <QMetaObject>
22#include <QSqlQuery>
24#include <QSqlQuery>
23#include <QSqlError>
25#include <QSqlError>
24#include <QSqlResult>
26#include <QSqlResult>
27+#include <QStandardPaths>
25#include <QRect>
28#include <QRect>
26#include <unity/shell/application/ApplicationInfoInterface.h>
29#include <unity/shell/application/ApplicationInfoInterface.h>
28−QMutex WindowStateStorage::s_mutex;
30−inline QString sanitiseString(QString string) {
32+class AsyncQuery: public QObject
31− return string.remove("\"").remove("'").remove("\\");
34−WindowStateStorage::WindowStateStorage(QObject *parent):
37− QString dbPath = QDir::homePath() + "/.cache/unity8/";
34+ Q_OBJECT
38− m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"));
41− m_db.setDatabaseName(dbPath + "windowstatestorage.sqlite");
45−WindowStateStorage::~WindowStateStorage()
36+public:
46−{
37+ AsyncQuery(const QString &dbName):
47− QFutureSynchronizer<void> futureSync;
38+ m_dbName(dbName)
48− for (int i = 0; i < m_asyncQueries.count(); ++i) {
39+ {
49− futureSync.addFuture(m_asyncQueries[i]);
51− futureSync.waitForFinished();
55−void WindowStateStorage::saveState(const QString &windowId, WindowStateStorage::WindowState state)
42+ ~AsyncQuery()
57− const QString queryString = QStringLiteral("INSERT OR REPLACE INTO state (windowId, state) values ('%1', '%2');")
44+ QSqlDatabase::removeDatabase(m_connectionName);
58− .arg(sanitiseString(windowId))
45+ }
61− saveValue(queryString);
47+ Q_INVOKABLE const QString getDbName()
52+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
53+ return connection.databaseName();
64−WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
56+ Q_INVOKABLE bool initdb()
66− const QString queryString = QStringLiteral("SELECT * FROM state WHERE windowId = '%1';")
58+ if (m_ok) {
67− .arg(sanitiseString(windowId));
59+ return true;
61+ QSqlDatabase connection = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), m_connectionName);
62+ connection.setDatabaseName(m_dbName);
63+ connection.setConnectOptions(QStringLiteral("QSQLITE_BUSY_TIMEOUT=1000"));
64+ if (!connection.open()) {
65+ qWarning() << "AsyncQuery::initdb: Error opening state database. Window positions will not be saved or restored." << m_dbName << connection.lastError().driverText() << connection.lastError().databaseText();
68+ QSqlQuery query(connection);
70+ if (!connection.tables().contains(QStringLiteral("geometry"))) {
71+ QString geometryQuery = QStringLiteral("CREATE TABLE geometry(windowId TEXT UNIQUE, x INTEGER, y INTEGER, width INTEGER, height INTEGER);");
72+ if (!query.exec(geometryQuery)) {
78+ if (!connection.tables().contains(QStringLiteral("state"))) {
79+ QString stateQuery = QStringLiteral("CREATE TABLE state(windowId TEXT UNIQUE, state INTEGER);");
80+ if (!query.exec(stateQuery)) {
86+ if (!connection.tables().contains(QStringLiteral("stage"))) {
87+ QString stageQuery = QStringLiteral("CREATE TABLE stage(appId TEXT UNIQUE, stage INTEGER);");
88+ if (!query.exec(stageQuery)) {
97+ Q_INVOKABLE int getState(const QString &windowId) const
102+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
103+ QSqlQuery query(connection);
104+ query.prepare(m_getStateQuery);
105+ query.bindValue(":windowId", windowId);
107+ if (!query.isActive() || !query.isSelect()) {
111+ if (!query.first()) {
114+ bool converted = false;
115+ QVariant resultStr = query.value(0);
116+ int result = resultStr.toInt(&converted);
120+ qWarning() << "getState result expected integer, got " << resultStr;
125+ Q_INVOKABLE QRect getGeometry(const QString &windowId) const
130+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
69− QSqlQuery query = getValue(queryString);
131+ QSqlQuery query(connection);
132+ query.prepare(m_getGeometryQuery);
133+ query.bindValue(":windowId", windowId);
135+ if (!query.isActive() || !query.isSelect()) {
140+ if (!query.first()) {
144+ bool xConverted, yConverted, widthConverted, heightConverted = false;
145+ int x, y, width, height;
146+ QVariant xResultStr = query.value(QStringLiteral("x"));
147+ QVariant yResultStr = query.value(QStringLiteral("y"));
148+ QVariant widthResultStr = query.value(QStringLiteral("width"));
149+ QVariant heightResultStr = query.value(QStringLiteral("height"));
150+ x = xResultStr.toInt(&xConverted);
151+ y = yResultStr.toInt(&yConverted);
152+ width = widthResultStr.toInt(&widthConverted);
153+ height = heightResultStr.toInt(&heightConverted);
155+ if (xConverted && yConverted && widthConverted && heightConverted) {
156+ return QRect(x, y, width, height);
158+ qWarning() << "getGeometry result expected integers, got x:"
159+ << xResultStr << "y:" << yResultStr << "width" << widthResultStr
160+ << "height:" << heightResultStr;
71− if (!query.first()) {
74− return (WindowState)query.value(QStringLiteral("state")).toInt();
77−void WindowStateStorage::saveGeometry(const QString &windowId, const QRect rect)
166+ Q_INVOKABLE int getStage(const QString &appId) const
79− const QString queryString = QStringLiteral("INSERT OR REPLACE INTO geometry (windowId, x, y, width, height) values ('%1', '%2', '%3', '%4', '%5');")
168+ if (!m_ok) {
80− .arg(sanitiseString(windowId))
169+ return -1;
82− .arg(rect.y())
171+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
83− .arg(rect.width())
172+ QSqlQuery query(connection);
84− .arg(rect.height());
173+ query.prepare(m_getStageQuery);
85−
174+ query.bindValue(":appId", appId);
86− saveValue(queryString);
175+ query.exec();
176+ if (!query.isActive() || !query.isSelect()) {
180+ if (!query.first()) {
183+ bool converted = false;
184+ QVariant resultStr = query.value(0);
185+ int result = resultStr.toInt(&converted);
189+ qWarning() << "getStage result expected integer, got " << resultStr;
89−void WindowStateStorage::saveStage(const QString &appId, int stage)
194+public Q_SLOTS:
196+ void saveState(const QString &windowId, WindowStateStorage::WindowState state)
91− const QString queryString = QStringLiteral("INSERT OR REPLACE INTO stage (appId, stage) values ('%1', '%2');")
198+ if (!m_ok) {
92− .arg(sanitiseString(appId))
199+ return;
93− .arg((int)stage);
200+ }
201+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
202+ QSqlQuery query(connection);
203+ query.prepare(m_saveStateQuery);
204+ query.bindValue(":windowId", windowId);
205+ query.bindValue(":state", (int)state);
206+ if (!query.exec()) {
95− saveValue(queryString);
211+ void saveGeometry(const QString &windowId, const QRect &rect)
216+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
217+ QSqlQuery query(connection);
218+ query.prepare(m_saveGeometryQuery);
219+ query.bindValue(":windowId", windowId);
220+ query.bindValue(":x", rect.x());
221+ query.bindValue(":y", rect.y());
222+ query.bindValue(":width", rect.width());
223+ query.bindValue(":height", rect.height());
224+ if (!query.exec()) {
98−int WindowStateStorage::getStage(const QString &appId) const
229+ void saveStage(const QString &appId, int stage)
100− const QString queryString = QStringLiteral("SELECT * FROM stage WHERE appId = '%1';")
231+ if (!m_ok) {
101− .arg(sanitiseString(appId));
232+ return;
234+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
235+ QSqlQuery query(connection);
236+ query.prepare(m_saveStageQuery);
237+ query.bindValue(":appId", appId);
238+ query.bindValue(":stage", stage);
239+ if (!query.exec()) {
103− QSqlQuery query = getValue(queryString);
244+private:
245+ static const QString m_connectionName;
246+ static const QString m_getStateQuery;
247+ static const QString m_saveStateQuery;
248+ static const QString m_getGeometryQuery;
249+ static const QString m_saveGeometryQuery;
250+ static const QString m_getStageQuery;
251+ static const QString m_saveStageQuery;
253+ static void logSqlError(const QSqlQuery query)
255+ qWarning() << "Error executing query" << query.lastQuery()
256+ << "Driver error:" << query.lastError().driverText()
257+ << "Database error:" << query.lastError().databaseText();
105− if (!query.first()) {
260+ QString m_dbName;
106− return unity::shell::application::ApplicationInfoInterface::MainStage;
261+ bool m_ok = false;
264+const QString AsyncQuery::m_connectionName = QStringLiteral("WindowStateStorage");
265+const QString AsyncQuery::m_getStateQuery = QStringLiteral("SELECT state FROM state WHERE windowId = :windowId");
266+const QString AsyncQuery::m_saveStateQuery = QStringLiteral("INSERT OR REPLACE INTO state (windowId, state) values (:windowId, :state)");
267+const QString AsyncQuery::m_getGeometryQuery = QStringLiteral("SELECT * FROM geometry WHERE windowId = :windowId");
268+const QString AsyncQuery::m_saveGeometryQuery = QStringLiteral("INSERT OR REPLACE INTO geometry (windowId, x, y, width, height) values (:windowId, :x, :y, :width, :height)");
269+const QString AsyncQuery::m_getStageQuery = QStringLiteral("SELECT stage FROM stage WHERE appId = :appId");
270+const QString AsyncQuery::m_saveStageQuery = QStringLiteral("INSERT OR REPLACE INTO stage (appId, stage) values (:appId, :stage)");
272+WindowStateStorage::WindowStateStorage(const QString &dbName, QObject *parent):
276+ qRegisterMetaType<WindowStateStorage::WindowState>("WindowStateStorage::WindowState");
278+ if (dbName.isEmpty()) {
279+ const QString dbPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QStringLiteral("/unity8/");
282+ dbFile = QString(dbPath) + QStringLiteral("windowstatestorage.sqlite");
108− return query.value("stage").toInt();
286+ m_asyncQuery = new AsyncQuery(dbFile);
287+ m_asyncQuery->moveToThread(&m_thread);
288+ connect(&m_thread, &QThread::finished, m_asyncQuery, &QObject::deleteLater);
290+ // Note that we're relying on initdb being called before any other methods
291+ // on AsyncQuery. Given the current behavior of QueuedConnection (slots
292+ // invoked in the order they are received), this is fine.
293+ QMetaObject::invokeMethod(m_asyncQuery, "initdb",
294+ Qt::QueuedConnection);
295+ connect(this, &WindowStateStorage::saveState, m_asyncQuery, &AsyncQuery::saveState);
296+ connect(this, &WindowStateStorage::saveGeometry, m_asyncQuery, &AsyncQuery::saveGeometry);
297+ connect(this, &WindowStateStorage::saveStage, m_asyncQuery, &AsyncQuery::saveStage);
111−void WindowStateStorage::executeAsyncQuery(const QString &queryString)
300+WindowStateStorage::~WindowStateStorage()
113− QMutexLocker l(&s_mutex);
302+ m_thread.quit();
114− QSqlQuery query;
303+ m_thread.wait();
116− bool ok = query.exec(queryString);
118− qWarning() << "Error executing query" << queryString
119− << "Driver error:" << query.lastError().driverText()
120− << "Database error:" << query.lastError().databaseText();
124−QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect defaultValue) const
306+WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
126− QString queryString = QStringLiteral("SELECT * FROM geometry WHERE windowId = '%1';")
308+ int state;
127− .arg(sanitiseString(windowId));
129− QSqlQuery query = getValue(queryString);
310+ QMetaObject::invokeMethod(m_asyncQuery, "getState", Qt::BlockingQueuedConnection,
311+ Q_RETURN_ARG(int, state),
312+ Q_ARG(const QString&, windowId)
131− if (!query.first()) {
315+ if (state == -1) {
132 return defaultValue;
316 return defaultValue;
134− return QRect(query.value(QStringLiteral("x")).toInt(), query.value(QStringLiteral("y")).toInt(), query.value(QStringLiteral("width")).toInt(), query.value(QStringLiteral("height")).toInt());
318+
319+ return (WindowState)state;
137−void WindowStateStorage::initdb()
322+int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
139− m_db.open();
324+ int stage;
141− qWarning() << "Error opening state database:" << m_db.lastError().driverText() << m_db.lastError().databaseText();
145− if (!m_db.tables().contains(QStringLiteral("geometry"))) {
326+ QMetaObject::invokeMethod(m_asyncQuery, "getStage", Qt::BlockingQueuedConnection,
146− QSqlQuery query;
327+ Q_RETURN_ARG(int, stage),
147− query.exec(QStringLiteral("CREATE TABLE geometry(windowId TEXT UNIQUE, x INTEGER, y INTEGER, width INTEGER, height INTEGER);"));
328+ Q_ARG(const QString&, appId)
150− if (!m_db.tables().contains(QStringLiteral("state"))) {
331+ if (stage == -1) {
151− QSqlQuery query;
332+ return defaultValue;
152− query.exec(QStringLiteral("CREATE TABLE state(windowId TEXT UNIQUE, state INTEGER);"));
155− if (!m_db.tables().contains(QStringLiteral("stage"))) {
335+ return stage;
157− query.exec(QStringLiteral("CREATE TABLE stage(appId TEXT UNIQUE, stage INTEGER);"));
161−void WindowStateStorage::saveValue(const QString &queryString)
338+QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue) const
163− QMutexLocker mutexLocker(&s_mutex);
340+ QRect geometry;
164−
341+ QMetaObject::invokeMethod(m_asyncQuery, "getGeometry", Qt::BlockingQueuedConnection,
165− QFuture<void> future = QtConcurrent::run(executeAsyncQuery, queryString);
342+ Q_RETURN_ARG(QRect, geometry),
166− m_asyncQueries.append(future);
343+ Q_ARG(const QString&, windowId)
168− QFutureWatcher<void> *futureWatcher = new QFutureWatcher<void>();
345+ if (geometry.isNull() || !geometry.isValid()) {
169− futureWatcher->setFuture(future);
346+ return defaultValue;
170− connect(futureWatcher, &QFutureWatcher<void>::finished,
347+ }
171− this,
348+ return geometry;
172− [=](){ m_asyncQueries.removeAll(futureWatcher->future());
173− futureWatcher->deleteLater(); });
176−QSqlQuery WindowStateStorage::getValue(const QString &queryString) const
351+const QString WindowStateStorage::getDbName()
178− QMutexLocker l(&s_mutex);
353+ QString dbName;
179− QSqlQuery query;
354+ QMetaObject::invokeMethod(m_asyncQuery, "getDbName", Qt::BlockingQueuedConnection,
355+ Q_RETURN_ARG(QString, dbName)
357+ return QString(dbName);
181− bool ok = query.exec(queryString);
360+Mir::State WindowStateStorage::toMirState(WindowState state) const
183− qWarning() << "Error retrieving database query:" << queryString
362+ // assumes a single state (not an OR of several)
184− << "Driver error:" << query.lastError().driverText()
363+ switch (state) {
185− << "Database error:" << query.lastError().databaseText();
364+ case WindowStateMaximized: return Mir::MaximizedState;
365+ case WindowStateMinimized: return Mir::MinimizedState;
366+ case WindowStateFullscreen: return Mir::FullscreenState;
367+ case WindowStateMaximizedLeft: return Mir::MaximizedLeftState;
368+ case WindowStateMaximizedRight: return Mir::MaximizedRightState;
369+ case WindowStateMaximizedHorizontally: return Mir::HorizMaximizedState;
370+ case WindowStateMaximizedVertically: return Mir::VertMaximizedState;
371+ case WindowStateMaximizedTopLeft: return Mir::MaximizedTopLeftState;
372+ case WindowStateMaximizedTopRight: return Mir::MaximizedTopRightState;
373+ case WindowStateMaximizedBottomLeft: return Mir::MaximizedBottomLeftState;
374+ case WindowStateMaximizedBottomRight: return Mir::MaximizedBottomRightState;
376+ case WindowStateNormal:
377+ case WindowStateRestored:
379+ return Mir::RestoredState;
383+#include "windowstatestorage.moc"
plugins/Utils/windowstatestorage.h+27−20
@@ -1,5 +1,6 @@
2 * Copyright 2015-2016 Canonical Ltd.
2 * Copyright 2015-2016 Canonical Ltd.
3+ * Copyright 2021 UBports Foundation
4 * This program is free software; you can redistribute it and/or modify
5 * 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 * it under the terms of the GNU Lesser General Public License as published by
@@ -16,13 +17,19 @@
17#include <QObject>
18#include <QObject>
18#include <QSqlDatabase>
19#include <QSqlDatabase>
19#include <QMutex>
21#include <QMutex>
20#include <QFuture>
22#include <QFuture>
26+#include <unity/shell/application/Mir.h>
22class WindowStateStorage: public QObject
30class WindowStateStorage: public QObject
27 enum WindowState {
34 enum WindowState {
28 WindowStateNormal = 1 << 0,
35 WindowStateNormal = 1 << 0,
@@ -32,36 +39,36 @@ public:
32 WindowStateMaximizedLeft = 1 << 4,
39 WindowStateMaximizedLeft = 1 << 4,
33 WindowStateMaximizedRight = 1 << 5,
40 WindowStateMaximizedRight = 1 << 5,
34 WindowStateMaximizedHorizontally = 1 << 6,
41 WindowStateMaximizedHorizontally = 1 << 6,
35− WindowStateMaximizedVertically = 1 << 7
42+ WindowStateMaximizedVertically = 1 << 7,
43+ WindowStateMaximizedTopLeft = 1 << 8,
44+ WindowStateMaximizedTopRight = 1 << 9,
45+ WindowStateMaximizedBottomLeft = 1 << 10,
46+ WindowStateMaximizedBottomRight = 1 << 11,
47+ WindowStateRestored = 1 << 12
37 Q_DECLARE_FLAGS(WindowStates, WindowState)
50 Q_DECLARE_FLAGS(WindowStates, WindowState)
38−#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
39 Q_FLAG(WindowStates)
51 Q_FLAG(WindowStates)
42− WindowStateStorage(QObject *parent = 0);
53+ WindowStateStorage(const QString &dbName = QString(), QObject *parent = nullptr);
43 virtual ~WindowStateStorage();
54 virtual ~WindowStateStorage();
45− Q_INVOKABLE void saveState(const QString &windowId, WindowState state);
46 Q_INVOKABLE WindowState getState(const QString &windowId, WindowState defaultValue) const;
56 Q_INVOKABLE WindowState getState(const QString &windowId, WindowState defaultValue) const;
48− Q_INVOKABLE void saveGeometry(const QString &windowId, const QRect rect);
49− Q_INVOKABLE QRect getGeometry(const QString &windowId, const QRect defaultValue) const;
58+ Q_INVOKABLE QRect getGeometry(const QString &windowId, const QRect &defaultValue) const;
51− Q_INVOKABLE void saveStage(const QString &appId, int stage);
52− Q_INVOKABLE int getStage(const QString &appId) const;
60+ Q_INVOKABLE int getStage(const QString &appId, int defaultValue) const;
54−private:
62+ Q_INVOKABLE Mir::State toMirState(WindowState state) const;
57− void saveValue(const QString &queryString);
64+ const QString getDbName();
58− QSqlQuery getValue(const QString &queryString) const;
60− static void executeAsyncQuery(const QString &queryString);
66+Q_SIGNALS:
61− static QMutex s_mutex;
67+ void saveStage(const QString &appId, int stage);
68+ void saveGeometry(const QString &windowId, const QRect &rect);
69+ void saveState(const QString &windowId, WindowStateStorage::WindowState state);
63− // NB: This is accessed from threads. Make sure to mutex it.
71+private:
64− QSqlDatabase m_db;
72+ QThread m_thread;
65−
73+ AsyncQuery *m_asyncQuery;
66− QList< QFuture<void> > m_asyncQueries;
plugins/WindowManager/AvailableDesktopArea.cppnew file+50
@@ -0,0 +1,50 @@
2+ * Copyright (C) 2017 Canonical, Ltd.
4+ * This program is free software: you can redistribute it and/or modify it under
5+ * the terms of the GNU Lesser General Public License version 3, as published by
6+ * the Free Software Foundation.
8+ * This program is distributed in the hope that it will be useful, but WITHOUT
9+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11+ * Lesser General Public License for more details.
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/>.
17+#include "AvailableDesktopArea.h"
19+#include <QGuiApplication>
20+#include <QQuickWindow>
21+#include <qpa/qplatformnativeinterface.h>
23+AvailableDesktopArea::AvailableDesktopArea(QQuickItem *parent)
26+ connect(this, &QQuickItem::xChanged, this, &AvailableDesktopArea::updatePlatformWindowProperty);
27+ connect(this, &QQuickItem::yChanged, this, &AvailableDesktopArea::updatePlatformWindowProperty);
28+ connect(this, &QQuickItem::widthChanged, this, &AvailableDesktopArea::updatePlatformWindowProperty);
29+ connect(this, &QQuickItem::heightChanged, this, &AvailableDesktopArea::updatePlatformWindowProperty);
32+void AvailableDesktopArea::updatePlatformWindowProperty()
38+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
40+ QRect rect(x(), y(), width(), height());
42+ nativeInterface->setWindowProperty(window()->handle(), "availableDesktopArea", QVariant(rect));
45+void AvailableDesktopArea::itemChange(ItemChange change, const ItemChangeData &)
47+ if (change == ItemSceneChange) {
48+ updatePlatformWindowProperty();
plugins/Unity/DashCommunicator/dashcommunicator.h → plugins/WindowManager/AvailableDesktopArea.hrenamed+14−21
@@ -1,5 +1,5 @@
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2017 Canonical, Ltd.
4 * This program is free software: you can redistribute it and/or modify it under
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
5 * the terms of the GNU Lesser General Public License version 3, as published by
@@ -14,32 +14,25 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17−#ifndef DASHCOMMUNICATOR_H
17+#ifndef AVAILABLEDESKTOPAREA_H
18−#define DASHCOMMUNICATOR_H
18+#define AVAILABLEDESKTOPAREA_H
21−#include <QThread>
20+#include <QQuickItem>
24−class DashConnection;
22+/**
23+ @brief Used to inform qtmir/miral about the available desktop area of shell
26−class DashCommunicator: public QThread
25+ So that qtmir/miral can take correct window management decisions.
27+class AvailableDesktopArea : public QQuickItem
30− explicit DashCommunicator(QObject *parent = 0);
31+ AvailableDesktopArea(QQuickItem *parent = nullptr);
34− void setCurrentScope(int index, bool animate, bool isSwipe);
37− void run() override;
33+ void itemChange(ItemChange change, const ItemChangeData &value) override;
39−private:
34+private Q_SLOTS:
40− DashConnection *m_dashConnection;
35+ void updatePlatformWindowProperty();
45−#endif
38+#endif // AVAILABLEDESKTOPAREA_H
plugins/WindowManager/CMakeLists.txt+15−2
@@ -1,13 +1,26 @@
1set(WINDOWMANAGER_SRC
1set(WINDOWMANAGER_SRC
2− TopLevelSurfaceList.cpp
2+ AvailableDesktopArea.cpp
3+ TopLevelWindowModel.cpp
3 WindowManagerPlugin.cpp
5 WindowManagerPlugin.cpp
7+ InputMethodManager.cpp
4 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
8 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
5 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
9 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
6 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
10 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
11+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h
12+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/SurfaceManagerInterface.h
15+add_definitions(-DWINDOWMANAGERQML_LIBRARY)
19+ ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
9add_library(windowmanager-qml SHARED ${WINDOWMANAGER_SRC})
22add_library(windowmanager-qml SHARED ${WINDOWMANAGER_SRC})
11−qt5_use_modules(windowmanager-qml Qml Quick Gui)
24+target_link_libraries(windowmanager-qml Qt5::Qml Qt5::Quick Qt5::Gui)
13add_unity8_plugin(WindowManager 0.1 WindowManager TARGETS windowmanager-qml)
26add_unity8_plugin(WindowManager 0.1 WindowManager TARGETS windowmanager-qml)
plugins/WindowManager/InputMethodManager.cppnew file+56
@@ -0,0 +1,56 @@
2+ * Copyright (C) 2019 UBports Foundation.
3+ * Author(s) Marius Gripsgard <marius@ubports.com>
5+ * This program is free software: you can redistribute it and/or modify it under
6+ * the terms of the GNU Lesser General Public License version 3, as published by
7+ * the Free Software Foundation.
9+ * This program is distributed in the hope that it will be useful, but WITHOUT
10+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
11+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+ * Lesser General Public License for more details.
14+ * You should have received a copy of the GNU Lesser General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#include "InputMethodManager.h"
21+#include <unity/shell/application/MirSurfaceInterface.h>
26+Q_LOGGING_CATEGORY(INPUTMETHODMANAGER, "InputMethodManager", QtInfoMsg)
27+#define DEBUG_MSG qCDebug(INPUTMETHODMANAGER).nospace().noquote() << __func__
29+namespace unityapi = unity::shell::application;
31+InputMethodManager *InputMethodManager::instance()
33+ static InputMethodManager* inputMethod(new InputMethodManager());
37+InputMethodManager::InputMethodManager()
41+void InputMethodManager::setWindow(Window* window)
43+ if (window == m_inputMethodWindow) {
47+ DEBUG_MSG << "(" << window << ")";
49+ m_inputMethodWindow = window;
50+ Q_EMIT surfaceChanged(surface());
53+unityapi::MirSurfaceInterface* InputMethodManager::surface() const
55+ return m_inputMethodWindow ? m_inputMethodWindow->surface() : nullptr;
plugins/WindowManager/InputMethodManager.hnew file+55
@@ -0,0 +1,55 @@
2+ * Copyright (C) 2019 UBports Foundation.
3+ * Author(s) Marius Gripsgard <marius@ubports.com>
5+ * This program is free software: you can redistribute it and/or modify it under
6+ * the terms of the GNU Lesser General Public License version 3, as published by
7+ * the Free Software Foundation.
9+ * This program is distributed in the hope that it will be useful, but WITHOUT
10+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
11+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+ * Lesser General Public License for more details.
14+ * You should have received a copy of the GNU Lesser General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20+#include <QLoggingCategory>
23+#include "WindowManagerGlobal.h"
25+Q_DECLARE_LOGGING_CATEGORY(INPUTMETHODMANAGER)
31+ namespace application {
32+ class MirSurfaceInterface;
37+class WINDOWMANAGERQML_EXPORT InputMethodManager : public QObject
40+ Q_PROPERTY(unity::shell::application::MirSurfaceInterface* surface READ surface NOTIFY surfaceChanged)
43+ InputMethodManager();
44+ static InputMethodManager* instance();
46+ void setWindow(Window* window);
49+ void surfaceChanged(unity::shell::application::MirSurfaceInterface* inputMethodSurface);
52+ unity::shell::application::MirSurfaceInterface* surface() const;
54+ Window* m_inputMethodWindow{nullptr};
plugins/WindowManager/TopLevelSurfaceList.cppdeleted−486
This diff is too big to show here.
plugins/WindowManager/TopLevelSurfaceList.hdeleted−223
This diff is too big to show here.
plugins/WindowManager/TopLevelWindowModel.cppnew file+782
This diff is too big to show here.
plugins/WindowManager/TopLevelWindowModel.hnew file+308
This diff is too big to show here.
plugins/WindowManager/Window.cppnew file+277
This diff is too big to show here.
plugins/WindowManager/Window.hnew file+176
This diff is too big to show here.
plugins/WindowManager/WindowManagerGlobal.hnew file+23
This diff is too big to show here.
plugins/WindowManager/WindowManagerPlugin.cpp+19−3
This diff is too big to show here.
plugins/WindowManager/WindowMargins.cppnew file+74
This diff is too big to show here.
plugins/WindowManager/WindowMargins.hnew file+59
This diff is too big to show here.
plugins/Wizard/CMakeLists.txt+9−3
This diff is too big to show here.
plugins/Wizard/Changelog.cppnew file+58
This diff is too big to show here.
plugins/Wizard/Changelog.hnew file+52
This diff is too big to show here.
plugins/Wizard/PageList.cpp+17−4
This diff is too big to show here.
plugins/Wizard/System.cpp+79−8
This diff is too big to show here.
plugins/Wizard/System.h+22−1
This diff is too big to show here.
plugins/Wizard/Utils/CMakeLists.txt+1−1
This diff is too big to show here.
plugins/Wizard/Wizard.qmltypesdeleted−33
This diff is too big to show here.
plugins/Wizard/keyboardLayoutsModel.cppnew file+163
This diff is too big to show here.
plugins/Wizard/keyboardLayoutsModel.hnew file+66
This diff is too big to show here.
plugins/Wizard/plugin.cpp+4
This diff is too big to show here.
This diff is too big to show here.
plugins/Wizard/test.shdeleted−18
This diff is too big to show here.
plugins/Wizard/timezonemodel.cpp+5−5
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
po/ca@valencia.po+517−359
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.
qml/ApplicationMenus/ApplicationMenuItemFactory.qmlnew file+135
This diff is too big to show here.
qml/ApplicationMenus/ApplicationMenusLimits.qmlnew file+24
This diff is too big to show here.
qml/ApplicationMenus/MenuBar.qmlnew file+513
This diff is too big to show here.
qml/ApplicationMenus/MenuItem.qmlnew file+146
This diff is too big to show here.
qml/ApplicationMenus/MenuNavigator.qmlnew file+101
This diff is too big to show here.
qml/ApplicationMenus/MenuPopup.qmlnew file+510
This diff is too big to show here.
qml/ApplicationMenus/RegisteredApplicationMenuModel.qmlnew file+56
This diff is too big to show here.
qml/ApplicationMenus/qmldirnew file+1
This diff is too big to show here.
This diff is too big to show here.
qml/Components/Background.qml+1−1
This diff is too big to show here.
qml/Components/BlurLayer.qml+10−40
This diff is too big to show here.
qml/Components/BrightnessControl.qmlnew file+54
This diff is too big to show here.
qml/Components/Carousel.qmldeleted−336
This diff is too big to show here.
qml/Components/Dialogs.qml+101−30
This diff is too big to show here.
qml/Components/DragHandle.qml+1
This diff is too big to show here.
qml/Components/EdgeBarrier.qml+3
This diff is too big to show here.
qml/Components/EdgeBarrierController.qml+1
This diff is too big to show here.
qml/Components/FadingLabel.qmlnew file+42
This diff is too big to show here.
qml/Components/Flickable.qmlnew file+24
This diff is too big to show here.
qml/Components/FloatingFlickable.qml+4
This diff is too big to show here.
qml/Dash/Previews/PreviewActionButton.qml → qml/Components/GridView.qmlrenamed+7−10
This diff is too big to show here.
qml/Panel/Handle.qml → qml/Components/Handle.qmlrenamed+1
This diff is too big to show here.
qml/Components/InputMethod.qml+13−47
This diff is too big to show here.
qml/Components/ItemGrabber.qml+1−1
This diff is too big to show here.
qml/Components/KeyboardShortcutsOverlay.qmlnew file+336
This diff is too big to show here.
qml/Components/KeymapSwitcher.qml+40−3
This diff is too big to show here.
qml/Components/LazyImage.qml+5−1
This diff is too big to show here.
qml/Components/ListItems/Header.qmldeleted−64
This diff is too big to show here.
qml/Components/ListItems/graphics/ListItemDividerHorizontal@18.pngdeleted
Binary file not shown.
qml/Dash/DashApplication.qml → qml/Components/ListView.qmlrenamed+7−11
This diff is too big to show here.
qml/Components/Lockscreen.qml+6−21
This diff is too big to show here.
qml/Components/MediaServices/MediaServices.qmlnew file+386
This diff is too big to show here.
qml/Components/MediaServices/MediaServicesControls.qmlnew file+192
This diff is too big to show here.
qml/Components/MediaServices/MediaServicesHeader.qmlnew file+71
This diff is too big to show here.
qml/Components/MediaServices/VideoPlayer.qmlnew file+155
This diff is too big to show here.
qml/Components/MediaServices/VideoPlayerControls.qmlnew file+158
This diff is too big to show here.
qml/Components/ModeSwitchWarningDialog.qml+8−2
This diff is too big to show here.
qml/Components/NotificationAudio.qml+20−3
This diff is too big to show here.
qml/Components/PanelState/PanelState.qml+6−3
This diff is too big to show here.
qml/Components/PhysicalKeysMapper.qml+6−26
This diff is too big to show here.
qml/Components/ResponsiveGridView.qmldeleted−97
This diff is too big to show here.
qml/Components/ResponsiveVerticalJournal.qmldeleted−81
This diff is too big to show here.
qml/Components/ScrollCalculator.qml+21−2
This diff is too big to show here.
qml/Dash/Previews/PreviewSharing.qml → qml/Components/SharingPicker.qmlrenamed+2−14
This diff is too big to show here.
qml/Components/ShellDialog.qml+27−12
This diff is too big to show here.
qml/Components/Showable.qml+15−12
This diff is too big to show here.
qml/Components/UbuntuShapeForItem.qmldeleted−47
This diff is too big to show here.
qml/Components/VirtualTouchPad.qml+269−1
This diff is too big to show here.
qml/Components/VolumeControl.qml+3−3
This diff is too big to show here.
qml/Components/Wallpaper.qmlnew file+96
This diff is too big to show here.
qml/Components/WallpaperResolver.qml+34−37
This diff is too big to show here.
qml/Components/WindowControlButtons.qml+27−27
This diff is too big to show here.
qml/Components/ZoomableImage.qml+1−1
This diff is too big to show here.
qml/Components/flickableUtils.jsnew file+28
This diff is too big to show here.
qml/Components/graphics/close@20.png
Binary file not shown.
qml/Components/graphics/icon_star_empty@20.png
Binary file not shown.
qml/Components/graphics/icon_star_full@20.png
Binary file not shown.
qml/Components/graphics/icon_star_half@20.png
Binary file not shown.
qml/Components/graphics/icon_star_off@20.png
Binary file not shown.
qml/Components/graphics/icon_star_on@20.png
Binary file not shown.
qml/Components/graphics/non-selected@18.png
Binary file not shown.
qml/Components/graphics/window-close.svg+164−14
This diff is too big to show here.
qml/Components/graphics/window-maximize.svg+164−12
This diff is too big to show here.
qml/Components/graphics/window-minimize.svg+164−13
This diff is too big to show here.
qml/Components/graphics/window-window.svgnew file+41
This diff is too big to show here.
qml/Dash/CardCarousel.qmldeleted−73
This diff is too big to show here.
qml/Dash/CardGrid.qmldeleted−84
This diff is too big to show here.
qml/Dash/CardHorizontalList.qmldeleted−66
This diff is too big to show here.
qml/Dash/CardTool.qmldeleted−241
This diff is too big to show here.
qml/Dash/CardVerticalJournal.qmldeleted−85
This diff is too big to show here.
qml/Dash/Dash.qmldeleted−381
This diff is too big to show here.
qml/Dash/DashBackground.qmldeleted−30
This diff is too big to show here.
qml/Dash/DashCategoryBase.qmldeleted−54
This diff is too big to show here.
qml/Dash/DashContent.qmldeleted−213
This diff is too big to show here.
qml/Dash/DashContentTabBarStyle.qmldeleted−24
This diff is too big to show here.
qml/Dash/DashNavigation.qmldeleted−198
This diff is too big to show here.
qml/Dash/DashNavigationHeader.qmldeleted−73
This diff is too big to show here.
qml/Dash/DashNavigationList.qmldeleted−115
This diff is too big to show here.
qml/Dash/DashPageHeader.qmldeleted−452
This diff is too big to show here.
qml/Dash/DashRenderer.qmldeleted−66
This diff is too big to show here.
qml/Dash/Filters/FilterExpandableWidget.qmldeleted−96
This diff is too big to show here.
qml/Dash/Filters/FilterOptionSelector.qmldeleted−95
This diff is too big to show here.
qml/Dash/Filters/FilterRangeInput.qmldeleted−136
This diff is too big to show here.
qml/Dash/Filters/FilterValueSlider.qmldeleted−87
This diff is too big to show here.
qml/Dash/Filters/FilterWidgetFactory.qmldeleted−89
This diff is too big to show here.
qml/Dash/FiltersPopover.qmldeleted−105
This diff is too big to show here.
qml/Dash/GenericScopeView.qmldeleted−854
This diff is too big to show here.
qml/Dash/PageHeaderExtraPanel.qmldeleted−200
This diff is too big to show here.
qml/Dash/PreviewView.qmldeleted−76
This diff is too big to show here.
qml/Dash/Previews/Preview.qmldeleted−116
This diff is too big to show here.
qml/Dash/Previews/PreviewActionCombo.qmldeleted−68
This diff is too big to show here.
qml/Dash/Previews/PreviewActions.qmldeleted−72
This diff is too big to show here.
qml/Dash/Previews/PreviewAudioPlayback.qmldeleted−150
This diff is too big to show here.
qml/Dash/Previews/PreviewComment.qmldeleted−83
This diff is too big to show here.
qml/Dash/Previews/PreviewCommentInput.qmldeleted−73
This diff is too big to show here.
qml/Dash/Previews/PreviewExpandable.qmldeleted−104
This diff is too big to show here.
qml/Dash/Previews/PreviewHeader.qmldeleted−168
This diff is too big to show here.
qml/Dash/Previews/PreviewIconActions.qmldeleted−87
This diff is too big to show here.
qml/Dash/Previews/PreviewImageGallery.qmldeleted−147
This diff is too big to show here.
qml/Dash/Previews/PreviewOverlay.qmldeleted−166
This diff is too big to show here.
qml/Dash/Previews/PreviewPayments.qmldeleted−81
This diff is too big to show here.
qml/Dash/Previews/PreviewProgress.qmldeleted−71
This diff is too big to show here.
qml/Dash/Previews/PreviewRatingDisplay.qmldeleted−117
This diff is too big to show here.
qml/Dash/Previews/PreviewRatingEdit.qmldeleted−80
This diff is too big to show here.
qml/Dash/Previews/PreviewRatingInput.qmldeleted−180
This diff is too big to show here.
qml/Dash/Previews/PreviewRatingSingleDisplay.qmldeleted−70
This diff is too big to show here.
qml/Dash/Previews/PreviewTable.qmldeleted−85
This diff is too big to show here.
qml/Dash/Previews/PreviewTextSummary.qmldeleted−73
This diff is too big to show here.
qml/Dash/Previews/PreviewVideoPlayback.qmldeleted−87
This diff is too big to show here.
qml/Dash/Previews/PreviewWidget.qmldeleted−57
This diff is too big to show here.
qml/Dash/Previews/PreviewWidgetFactory.qmldeleted−92
This diff is too big to show here.
qml/Dash/Previews/PreviewZoomableImage.qmldeleted−102
This diff is too big to show here.
qml/Dash/ScopeListView.qmldeleted−26
This diff is too big to show here.
qml/Dash/ScopeSettings/ScopeSetting.qmldeleted−46
This diff is too big to show here.
qml/Dash/ScopeSettings/ScopeSettingBoolean.qmldeleted−63
This diff is too big to show here.
qml/Dash/ScopeSettings/ScopeSettingList.qmldeleted−50
This diff is too big to show here.
qml/Dash/ScopeSettings/ScopeSettingString.qmldeleted−89
This diff is too big to show here.
qml/Dash/ScopeSettings/ScopeSettingsWidgetFactory.qmldeleted−61
This diff is too big to show here.
qml/Dash/ScopeSettingsPage.qmldeleted−72
This diff is too big to show here.
qml/Dash/ScopesList.qmldeleted−122
This diff is too big to show here.
qml/Dash/ScopesListCategory.qmldeleted−180
This diff is too big to show here.
qml/Dash/ScopesListCategoryItem.qmldeleted−112
This diff is too big to show here.
qml/Dash/graphics/dark_background.jpgdeleted
Binary file not shown.
qml/Dash/graphics/dash_divider_top_darkgrad@27.pngdeleted
Binary file not shown.
qml/Dash/graphics/dash_divider_top_lightgrad@27.pngdeleted
Binary file not shown.
qml/Dash/graphics/header_handlearrow2@27.pngdeleted
Binary file not shown.
qml/Dash/graphics/header_handlearrow@27.pngdeleted
Binary file not shown.
qml/Dash/graphics/icon_clear@20.pngdeleted
Binary file not shown.
qml/Dash/graphics/icon_search_active@20.pngdeleted
Binary file not shown.
qml/Dash/graphics/icon_search_inactive@20.pngdeleted
Binary file not shown.
qml/Dash/graphics/navigation_shadow@18.pngdeleted
Binary file not shown.
qml/Dash/graphics/navigation_shadow_light@18.pngdeleted
Binary file not shown.
qml/Dash/graphics/overview_hint@27.pngdeleted
Binary file not shown.
qml/Dash/graphics/pagination_dot_off@30.pngdeleted
Binary file not shown.
qml/Dash/graphics/pagination_dot_on@30.pngdeleted
Binary file not shown.
qml/Dash/graphics/paper.pngdeleted
Binary file not shown.
qml/Dash/graphics/pixel.pngdeleted
Binary file not shown.
qml/Dash/graphics/play_button@18.pngdeleted
Binary file not shown.
qml/Dash/graphics/play_button_active@18.pngdeleted
Binary file not shown.
qml/Dash/graphics/play_button_active_big@20.pngdeleted
Binary file not shown.
qml/Dash/graphics/play_button_big@20.pngdeleted
Binary file not shown.
qml/Dash/graphics/tabbarchevron@27.pngdeleted
Binary file not shown.
qml/Dash/graphics/tablet/icon_close_preview@20.pngdeleted
Binary file not shown.
qml/Dash/graphics/tooltip_arrow@27.pngdeleted
Binary file not shown.
qml/DeviceConfiguration.qml+12
This diff is too big to show here.
qml/DisabledScreenNotice.qml+3−55
This diff is too big to show here.
qml/Greeter/ButtonPrompt.qmlnew file+51
This diff is too big to show here.
qml/Greeter/Circle.qmlnew file+57
This diff is too big to show here.
This diff is too big to show here.
qml/Greeter/CoverPage.qml+61−18
This diff is too big to show here.
qml/Components/DelayedLockscreen.qml → qml/Greeter/DelayedLockscreen.qmlrenamed+6−14
This diff is too big to show here.
qml/Dash/Filters/FilterWidget.qml → qml/Greeter/FullLightDMImpl.qmlrenamed+10−11
This diff is too big to show here.
qml/Greeter/Greeter.qml+273−114
This diff is too big to show here.
qml/Greeter/GreeterPrompt.qmlnew file+127
This diff is too big to show here.
qml/Greeter/GreeterView.qmlnew file+534
This diff is too big to show here.
qml/Greeter/Infographics.qml+44−23
This diff is too big to show here.
qml/Greeter/IntegratedLightDMImpl.qml+4−2
This diff is too big to show here.
qml/Greeter/LightDM.qml → qml/Greeter/LightDMService.qmlrenamed+16−3
This diff is too big to show here.
qml/Dash/Previews/PreviewMediaToolbar.qml → qml/Greeter/LoginAreaContainer.qmlrenamed+15−14
This diff is too big to show here.
qml/Greeter/LoginList.qml+147−157
This diff is too big to show here.
qml/Greeter/NarrowView.qmldeleted−184
This diff is too big to show here.
qml/Greeter/PinPrompt.qmlnew file+184
This diff is too big to show here.
qml/Greeter/PromptList.qmlnew file+151
This diff is too big to show here.
qml/Greeter/SessionIcon.qmlnew file+47
This diff is too big to show here.
qml/Greeter/SessionsList.qmlnew file+205
This diff is too big to show here.
qml/Greeter/ShimGreeter.qml+2
This diff is too big to show here.
qml/Greeter/TextPrompt.qmlnew file+198
This diff is too big to show here.
qml/Greeter/WideView.qmldeleted−135
This diff is too big to show here.
qml/Greeter/graphics/dot_empty.png
Binary file not shown.
qml/Greeter/graphics/dot_filled.png
Binary file not shown.
qml/Greeter/graphics/dot_pointer.png
Binary file not shown.
qml/Greeter/graphics/icon_arrow.png
Binary file not shown.
qml/Greeter/graphics/infographic_circle_back.pngdeleted
Binary file not shown.
qml/Greeter/graphics/session_icons/gnome_badge.pngnew file
Binary file not shown.
qml/Greeter/graphics/session_icons/kde_badge.pngnew file
Binary file not shown.
qml/Greeter/graphics/session_icons/recovery_console_badge.pngnew file
Binary file not shown.
qml/Greeter/graphics/session_icons/ubuntu_badge.pngnew file
Binary file not shown.
qml/Greeter/graphics/session_icons/unknown_badge.pngnew file
Binary file not shown.
qml/Greeter/qmldirnew file+1
This diff is too big to show here.
qml/Launcher/BackgroundBlur.qmlnew file+81
This diff is too big to show here.
qml/Launcher/Drawer.qmlnew file+413
This diff is too big to show here.
qml/Launcher/DrawerGridView.qmlnew file+85
This diff is too big to show here.
qml/Launcher/Launcher.qml+247−54
This diff is too big to show here.
qml/Launcher/LauncherDelegate.qml+14−20
This diff is too big to show here.
qml/Launcher/LauncherPanel.qml+183−46
This diff is too big to show here.
qml/Dash/PullToRefreshScopeStyle.qml → qml/Launcher/PullToRefreshScopeStyle.qmlrenamed+1
This diff is too big to show here.
qml/Launcher/Tooltip.qmlnew file+72
This diff is too big to show here.
qml/Launcher/graphics/divider-line.png
Binary file not shown.
qml/Launcher/graphics/focused_app_arrow@30.png
Binary file not shown.
qml/Launcher/graphics/home.svgnew file+243
This diff is too big to show here.
qml/Launcher/graphics/home@18.pngdeleted
Binary file not shown.
qml/Launcher/graphics/launcher-app-focus-ring.svgdeleted−12
This diff is too big to show here.
qml/Launcher/graphics/quicklist_tooltip@30.png
Binary file not shown.
qml/Notifications/Notification.qml+38−33
This diff is too big to show here.
qml/Notifications/NotificationButton.qml+2−1
This diff is too big to show here.
qml/Notifications/NotificationMenuItemFactory.qml−3
This diff is too big to show here.
qml/Notifications/Notifications.qml+14−24
This diff is too big to show here.
qml/Notifications/ShapedIcon.qml+1
This diff is too big to show here.
qml/Notifications/SwipeToAct.qml+4
This diff is too big to show here.
qml/OrientedShell.qml+36−10
This diff is too big to show here.
qml/Panel/ActiveCallHint.qml+3
This diff is too big to show here.
tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp → qml/Panel/FakePanelMenu.qmlrenamed+8−9
This diff is too big to show here.
qml/Panel/IndicatorPage.qmldeleted−187
This diff is too big to show here.
qml/Panel/IndicatorItem.qml → qml/Panel/Indicators/IndicatorItem.qmlrenamed+16−3
This diff is too big to show here.
qml/Panel/Indicators/MenuItemFactory.qml → qml/Panel/Indicators/IndicatorMenuItemFactory.qmlrenamed+183−92
This diff is too big to show here.
qml/Panel/Indicators/IndicatorsLight.qml+185−12
This diff is too big to show here.
qml/Panel/Indicators/client/IndicatorRepresentation.qml+45−28
This diff is too big to show here.
qml/Panel/Indicators/client/IndicatorsClient.qml+8−2
This diff is too big to show here.
qml/Panel/Indicators/client/IndicatorsList.qml+19−17
This diff is too big to show here.
qml/Panel/Indicators/client/IndicatorsTree.qml+6−8
This diff is too big to show here.
qml/Panel/MenuContent.qml+12−12
This diff is too big to show here.
qml/Panel/Panel.qml+379−103
This diff is too big to show here.
qml/Panel/IndicatorsBar.qml → qml/Panel/PanelBar.qmlrenamed+87−36
This diff is too big to show here.
qml/Panel/IndicatorItemRow.qml → qml/Panel/PanelItemRow.qmlrenamed+65−95
This diff is too big to show here.
qml/Panel/IndicatorsMenu.qml → qml/Panel/PanelMenu.qmlrenamed+81−35
This diff is too big to show here.
qml/Panel/PanelMenuPage.qmlnew file+226
This diff is too big to show here.
qml/Panel/graphics/rectangular_dropshadow@30.png
Binary file not shown.
qml/Rotation/HalfLoopRotationAnimation.qml+1−1
This diff is too big to show here.
qml/Rotation/ImmediateRotationAction.qml+1−1
This diff is too big to show here.
qml/Rotation/NinetyRotationAnimation.qml+1−1
This diff is too big to show here.
qml/Rotation/RotationStates.qml+2−11
This diff is too big to show here.
qml/Rotation/UpdateShellTransformations.qml+4−4
This diff is too big to show here.
qml/ScopeTool.qmldeleted−165
This diff is too big to show here.
This diff is too big to show here.
qml/Stages/ApplicationWindow.qml → qml/Stage/ApplicationWindow.qmlrenamed+61−50
This diff is too big to show here.
qml/Stage/ChildWindow.qmlnew file+203
This diff is too big to show here.
qml/Stage/ChildWindowRepeater.qmlnew file+39
This diff is too big to show here.
qml/Stage/ChildWindowTree.qmlnew file+138
This diff is too big to show here.
qml/Stage/DecoratedWindow.qmlnew file+319
This diff is too big to show here.
qml/Stage/FakeMaximizeDelegate.qmlnew file+233
This diff is too big to show here.
qml/Stages/MainViewStyle.qml → qml/Stage/MainViewStyle.qmlrenamed
The content is the same.
qml/Stage/MoveHandler.qmlnew file+201
This diff is too big to show here.
qml/Stages/OrientationChangeAnimation.qml → qml/Stage/OrientationChangeAnimation.qmlrenamed+30−6
This diff is too big to show here.
qml/Stages/PromptSurfaceAnimations.qml → qml/Stage/PromptSurfaceAnimations.qmlrenamed+2−3
This diff is too big to show here.
qml/Components/BaseCarouselDelegate.qml → qml/Stage/ResizeGrip.qmlrenamed+27−23
This diff is too big to show here.
qml/Stages/SideStage.qml → qml/Stage/SideStage.qmlrenamed+10−6
This diff is too big to show here.
qml/Stages/Splash.qml → qml/Stage/Splash.qmlrenamed+7−10
This diff is too big to show here.
qml/Stage/Spread/BezierCurve.qmlnew file+45
This diff is too big to show here.
qml/Stage/Spread/KeySpline.jsnew file+66
This diff is too big to show here.
qml/Stage/Spread/MathUtils.jsnew file+95
This diff is too big to show here.
qml/Stage/Spread/OpacityMask.qmlnew file+82
This diff is too big to show here.
qml/Stage/Spread/Spread.qmlnew file+173
This diff is too big to show here.
qml/Stage/Spread/SpreadDelegateInputArea.qmlnew file+189
This diff is too big to show here.
qml/Stage/Spread/SpreadMaths.qmlnew file+78
This diff is too big to show here.
qml/Stage/Spread/StagedRightEdgeMaths.qmlnew file+174
This diff is too big to show here.
qml/Stage/Spread/WindowedRightEdgeMaths.qmlnew file+96
This diff is too big to show here.
qml/Stage/Spread/cubic-bezier.jsnew file+39
This diff is too big to show here.
qml/Stage/Stage.qmlnew file+2241
This diff is too big to show here.
qml/Stage/StageMaths.qmlnew file+93
This diff is too big to show here.
qml/Stages/StagedFullscreenPolicy.qml → qml/Stage/StagedFullscreenPolicy.qmlrenamed+7−13
This diff is too big to show here.
qml/Stages/SurfaceContainer.qml → qml/Stage/SurfaceContainer.qmlrenamed+5−52
This diff is too big to show here.
qml/Stages/TabletSideStageTouchGesture.qml → qml/Stage/TabletSideStageTouchGesture.qmlrenamed+3
This diff is too big to show here.
qml/Stage/WindowControlsOverlay.qmlnew file+254
This diff is too big to show here.
qml/Stage/WindowDecoration.qmlnew file+163
This diff is too big to show here.
qml/Stage/WindowInfoItem.qmlnew file+69
This diff is too big to show here.
qml/Stages/WindowResizeArea.qml → qml/Stage/WindowResizeArea.qmlrenamed+45−110
This diff is too big to show here.
qml/Stage/WindowStateSaver.qmlnew file+64
This diff is too big to show here.
qml/Stages/WindowedFullscreenPolicy.qml → qml/Stage/WindowedFullscreenPolicy.qmlrenamed+4−12
This diff is too big to show here.
qml/Stage/graphics/PageHeaderBaseDividerBottom@18.pngnew file
Binary file not shown.
qml/Stage/graphics/PageHeaderBaseDividerLight@18.pngnew file
Binary file not shown.
qml/Stages/graphics/PageHeaderBaseDividerLight@18.sci → qml/Stage/graphics/PageHeaderBaseDividerLight@18.scirenamed
The content is the same.
qml/Stage/graphics/arrows-centre.pngnew file
Binary file not shown.
qml/Stage/graphics/arrows.pngnew file
Binary file not shown.
qml/Stages/graphics/sidestage_drag.svg → qml/Stage/graphics/sidestage_drag.svgrenamed
The content is the same.
qml/Stage/graphics/sidestage_handle@20.pngnew file
Binary file not shown.
qml/Stages/graphics/sidestage_handle@20.sci → qml/Stage/graphics/sidestage_handle@20.scirenamed
The content is the same.
qml/Stages/graphics/sidestage_open.svg → qml/Stage/graphics/sidestage_open.svgrenamed
The content is the same.
qml/Stages/graphics/window-close.svg → qml/Stage/graphics/window-close.svgrenamed
The content is the same.
qml/Stages/AbstractStage.qmldeleted−80
This diff is too big to show here.
qml/Stages/DecoratedWindow.qmldeleted−109
This diff is too big to show here.
qml/Stages/DesktopSpread.qmldeleted−574
This diff is too big to show here.
qml/Stages/DesktopSpreadDelegate.qmldeleted−126
This diff is too big to show here.
qml/Stages/DesktopStage.qmldeleted−684
This diff is too big to show here.
qml/Stages/PhoneStage.qmldeleted−800
This diff is too big to show here.
qml/Stages/SpreadDelegate.qmldeleted−437
This diff is too big to show here.
qml/Stages/SpreadMaths.qmldeleted−164
This diff is too big to show here.
qml/Stages/TabletStage.qmldeleted−1186
This diff is too big to show here.
qml/Stages/TopLevelSurfaceRepeater.qmldeleted−52
This diff is too big to show here.
qml/Stages/TransformedSpreadDelegate.qmldeleted−391
This diff is too big to show here.
qml/Stages/TransformedTabletSpreadDelegate.qmldeleted−437
This diff is too big to show here.
qml/Stages/WindowDecoration.qmldeleted−109
This diff is too big to show here.
qml/Stages/graphics/PageHeaderBaseDividerBottom@18.pngdeleted
Binary file not shown.
qml/Stages/graphics/PageHeaderBaseDividerLight@18.pngdeleted
Binary file not shown.
qml/Stages/graphics/dropshadow2gu@30.pngdeleted
Binary file not shown.
qml/Stages/graphics/sidestage_handle@20.pngdeleted
Binary file not shown.
qml/Tutorial/InactivityTimer.qml+26−10
This diff is too big to show here.
qml/Tutorial/Tutorial.qml+8−6
This diff is too big to show here.
qml/Tutorial/TutorialBottom.qmldeleted−124
This diff is too big to show here.
qml/Tutorial/TutorialContent.qml+85−150
This diff is too big to show here.
qml/Tutorial/TutorialLeft.qml+3−3
This diff is too big to show here.
qml/Tutorial/TutorialLeftLong.qml+5−3
This diff is too big to show here.
qml/Tutorial/TutorialPage.qml+2−2
This diff is too big to show here.
qml/Tutorial/TutorialRight.qml+4−5
This diff is too big to show here.
qml/Tutorial/TutorialTop.qml+4−5
This diff is too big to show here.
qml/Tutorial/graphics/background1.png
Binary file not shown.
qml/Tutorial/graphics/background2.png
Binary file not shown.
qml/Wizard/Components/InputMethod.qml+9−9
This diff is too big to show here.
This diff is too big to show here.
qml/Wizard/Pages.qml+90−16
This diff is too big to show here.
qml/Wizard/Pages/10-welcome-update.qmlnew file+137
This diff is too big to show here.
qml/Wizard/Pages/10-welcome.qml+23−5
This diff is too big to show here.
qml/Wizard/Pages/11-changelog.qmlnew file+95
This diff is too big to show here.
qml/Wizard/Pages/20-keyboard.qmlnew file+161
This diff is too big to show here.
qml/Wizard/Pages/30-wifi.qml+20−11
This diff is too big to show here.
qml/Wizard/Pages/40-location.qmldeleted−290
This diff is too big to show here.
qml/Wizard/Pages/50-timezone.qml+12−12
This diff is too big to show here.
qml/Wizard/Pages/60-account.qml+12−10
This diff is too big to show here.
qml/Wizard/Pages/70-passwd-type.qml+2
This diff is too big to show here.
qml/Wizard/Pages/75-report-check.qmldeleted−91
This diff is too big to show here.
qml/Wizard/Pages/78-firmware-update.qml.disablednew file+246
This diff is too big to show here.
qml/Wizard/Pages/79-system-update.qmlnew file+148
This diff is too big to show here.
qml/Wizard/Pages/80-finished.qml+4−2
This diff is too big to show here.
qml/Wizard/Pages/data/Desktop_header_bkg.png
Binary file not shown.
qml/Wizard/Pages/data/Desktop_splash_screen_bkg.png
Binary file not shown.
qml/Wizard/Pages/data/Phone_header_bkg.png
Binary file not shown.
qml/Wizard/Pages/data/Phone_splash_screen_bkg.png
Binary file not shown.
qml/Wizard/Pages/data/Tick@30.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/map.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/pin.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-1.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-10.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-11.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-2.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-3.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-3.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-4.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-4.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-6.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-7.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-8.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-9.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_-9.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_0.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_1.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_10.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_10.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_11.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_12.75.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_12.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_13.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_2.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_3.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_3.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_4.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_4.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_5.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_5.75.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_6.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_6.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_7.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_8.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_8.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_9.5.png
Binary file not shown.
qml/Wizard/Pages/data/timezonemap/timezone_9.png
Binary file not shown.
qml/Wizard/Pages/here-terms.qmldeleted−126
This diff is too big to show here.
qml/Wizard/Pages/passcode-confirm.qml+2−2
This diff is too big to show here.
qml/Wizard/Pages/passcode-desktop.qml+42−15
This diff is too big to show here.
qml/Wizard/Pages/passcode-set.qml+2−2
This diff is too big to show here.
qml/Wizard/Pages/password-set.qml+13−4
This diff is too big to show here.
qml/Wizard/PasswordMeter.qml+3−1
This diff is too big to show here.
qml/Wizard/Wizard.qml+11−4
This diff is too big to show here.
qml/Wizard/WizardItemSelector.qmlnew file+129
This diff is too big to show here.
qml/graphics/dropshadow2gu@30.pngnew file
Binary file not shown.
qml/Stages/graphics/dropshadow2gu@30.sci → qml/graphics/dropshadow2gu@30.scirenamed
The content is the same.
qml/graphics/dropshadow_left@20.png
Binary file not shown.
qml/graphics/dropshadow_right@20.png
Binary file not shown.
qml/graphics/phone_background.jpgdeleted
Binary file not shown.
qml/graphics/tablet_background.jpgdeleted
Binary file not shown.
This diff is too big to show here.
run_on_device.shdeleted−164
This diff is too big to show here.
src/ApplicationArguments.h+5
This diff is too big to show here.
This diff is too big to show here.
src/Dash/CMakeLists.txtdeleted−29
This diff is too big to show here.
src/Dash/main.cppdeleted−136
This diff is too big to show here.
src/DebuggingController.cppnew file+92
This diff is too big to show here.
src/DebuggingController.hnew file+57
This diff is too big to show here.
src/MouseTouchAdaptor.cpp+28−1
This diff is too big to show here.
src/MouseTouchAdaptor.h+1
This diff is too big to show here.
src/Panel/CMakeLists.txtdeleted−3
This diff is too big to show here.
src/Panel/Indicators/CMakeLists.txtdeleted−1
This diff is too big to show here.
src/SecondaryWindow.cpp+1−1
This diff is too big to show here.
src/ShellApplication.cpp+33−6
This diff is too big to show here.
src/ShellApplication.h+1−3
This diff is too big to show here.
This diff is too big to show here.
src/UnixSignalHandler.cpp+3−5
This diff is too big to show here.
src/libunity8-private/CMakeLists.txt+1−1
This diff is too big to show here.
src/libunity8-private/abstractdbusservicemonitor.h+1−1
This diff is too big to show here.
This diff is too big to show here.
tests/CMakeLists.txt+30−17
This diff is too big to show here.
tests/autopilot/unity8/dash.pydeleted−263
This diff is too big to show here.
tests/autopilot/unity8/fixture_setup.py+1−1
This diff is too big to show here.
tests/autopilot/unity8/greeter/__init__.py+1−1
This diff is too big to show here.
tests/autopilot/unity8/greeter/tests/test_args.py−5
This diff is too big to show here.
tests/autopilot/unity8/shell/__init__.py+2
This diff is too big to show here.
tests/autopilot/unity8/shell/fixture_setup.py+1−27
This diff is too big to show here.
tests/autopilot/unity8/shell/tests/__init__.py+5−2
This diff is too big to show here.
tests/autopilot/unity8/shell/tests/test_helpers.py−122
This diff is too big to show here.
tests/autopilot/unity8/shell/tests/test_notifications.py+9−9
This diff is too big to show here.
tests/autopilot/unity8/shell/tests/test_rotation.py+3−3
This diff is too big to show here.
tests/copyright/check_copyright.sh+35−4
This diff is too big to show here.
tests/data/unity/backgrounds/20x30.pngnew file
Binary file not shown.
tests/data/unity/backgrounds/black.pngnew file
Binary file not shown.
tests/data/unity/backgrounds/blue.png
Binary file not shown.
tests/data/unity/backgrounds/red.png
Binary file not shown.
tests/graphics/applicationIcons/browser@18.png
Binary file not shown.
tests/graphics/applicationIcons/calendar@18.png
Binary file not shown.
tests/graphics/applicationIcons/camera@18.png
Binary file not shown.
tests/graphics/applicationIcons/contacts-app@18.png
Binary file not shown.
tests/graphics/applicationIcons/dash.pngdeleted
Binary file not shown.
tests/graphics/applicationIcons/dash@18.pngnew file
Binary file not shown.
tests/graphics/applicationIcons/dialer-app@18.png
Binary file not shown.
tests/graphics/applicationIcons/evernote@18.png
Binary file not shown.
tests/graphics/applicationIcons/facebook@18.png
Binary file not shown.
tests/graphics/applicationIcons/gallery@18.png
Binary file not shown.
tests/graphics/applicationIcons/gmail@18.png
Binary file not shown.
tests/graphics/applicationIcons/libreoffice@18.png
Binary file not shown.
tests/graphics/applicationIcons/map@18.png
Binary file not shown.
tests/graphics/applicationIcons/messages-app@18.png
Binary file not shown.
tests/graphics/applicationIcons/notepad@18.png
Binary file not shown.
tests/graphics/applicationIcons/pinterest@18.png
Binary file not shown.
tests/graphics/applicationIcons/soundcloud@18.png
Binary file not shown.
tests/graphics/applicationIcons/system-settings@18.png
Binary file not shown.
tests/graphics/applicationIcons/twitter@18.png
Binary file not shown.
tests/graphics/applicationIcons/weather@18.png
Binary file not shown.
tests/graphics/applicationIcons/wikipedia@18.png
Binary file not shown.
tests/graphics/applicationIcons/youtube@18.png
Binary file not shown.
tests/graphics/avatars/amanda@12.png
Binary file not shown.
tests/graphics/avatars/anna_olsson@12.png
Binary file not shown.
tests/graphics/avatars/funky@12.png
Binary file not shown.
tests/graphics/clock@18.png
Binary file not shown.
tests/imports/CMakeLists.txt+1−1
This diff is too big to show here.
tests/imports/check_imports.py+58
This diff is too big to show here.
tests/mocks/AccountsService/AccountsService.cpp+35−32
This diff is too big to show here.
tests/mocks/AccountsService/AccountsService.h+22−26
This diff is too big to show here.
tests/mocks/AccountsService/AccountsService.qmltypesdeleted−41
This diff is too big to show here.
tests/mocks/AccountsService/CMakeLists.txt+15−1
This diff is too big to show here.
tests/mocks/Biometryd/CMakeLists.txtnew file+14
This diff is too big to show here.
tests/mocks/Biometryd/MockBiometryd.cppnew file+43
This diff is too big to show here.
tests/mocks/Biometryd/MockBiometryd.hnew file+50
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/plugin.cpp → tests/mocks/Biometryd/MockDevice.cpprenamed+10−9
This diff is too big to show here.
tests/mocks/IntegratedLightDM/MockUsersModel.h → tests/mocks/Biometryd/MockDevice.hrenamed+16−13
This diff is too big to show here.
plugins/Ubuntu/Payments/plugin.cpp → tests/mocks/Biometryd/MockIdentifier.cpprenamed+9−9
This diff is too big to show here.
plugins/Ubuntu/SystemImage/SystemImage.h → tests/mocks/Biometryd/MockIdentifier.hrenamed+11−9
This diff is too big to show here.
qml/Components/Circle.qml → tests/mocks/Biometryd/MockObserver.cpprenamed+6−6
This diff is too big to show here.
tests/mocks/Ubuntu/SystemImage/MockSystemImage.h → tests/mocks/Biometryd/MockObserver.hrenamed+11−10
This diff is too big to show here.
tests/mocks/Biometryd/MockOperation.cppnew file+56
This diff is too big to show here.
tests/mocks/Biometryd/MockOperation.hnew file+47
This diff is too big to show here.
plugins/Ubuntu/SystemImage/plugin.cpp → tests/mocks/Biometryd/plugin.cpprenamed+14−7
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/plugin.h → tests/mocks/Biometryd/plugin.hrenamed+4−4
This diff is too big to show here.
tests/mocks/Biometryd/qmldirnew file+3
This diff is too big to show here.
tests/mocks/CMakeLists.txt+5−2
This diff is too big to show here.
tests/mocks/Cursor/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Cursor/Cursor.qml+12−1
This diff is too big to show here.
tests/mocks/GSettings.1.0/CMakeLists.txt+1−2
This diff is too big to show here.
tests/mocks/GSettings.1.0/GSettings.qmltypesdeleted−42
This diff is too big to show here.
tests/mocks/GSettings.1.0/fake_gsettings.cpp+65−1
This diff is too big to show here.
tests/mocks/GSettings.1.0/fake_gsettings.h+18
This diff is too big to show here.
tests/mocks/IntegratedLightDM/CMakeLists.txtdeleted−48
This diff is too big to show here.
tests/mocks/IntegratedLightDM/IntegratedLightDM.qmltypesdeleted−269
This diff is too big to show here.
tests/mocks/IntegratedLightDM/MockUsersModel.cppdeleted−39
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/CMakeLists.txtdeleted−18
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/Greeter.cppdeleted−199
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/UsersModel.cppdeleted−120
This diff is too big to show here.
tests/mocks/IntegratedLightDM/plugin.cppdeleted−68
This diff is too big to show here.
tests/mocks/IntegratedLightDM/qmldirdeleted−3
This diff is too big to show here.
tests/mocks/LightDMController/CMakeLists.txtnew file+14
This diff is too big to show here.
plugins/Unity/DashCommunicator/plugin.cpp → tests/mocks/LightDMController/plugin.cpprenamed+14−11
This diff is too big to show here.
plugins/Ubuntu/Payments/plugin.h → tests/mocks/LightDMController/plugin.hrenamed+4−6
This diff is too big to show here.
tests/mocks/LightDMController/qmldirnew file+2
This diff is too big to show here.
tests/mocks/Lights/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Lights/Lights.h+1−1
This diff is too big to show here.
tests/mocks/Lights/Lights.qmltypesdeleted−45
This diff is too big to show here.
tests/mocks/MeeGo/QOfono/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/MeeGo/QOfono/QOfono.qmltypesdeleted−30
This diff is too big to show here.
tests/mocks/Powerd/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Powerd/Powerd.h+2−2
This diff is too big to show here.
tests/mocks/Powerd/Powerd.qmltypesdeleted−39
This diff is too big to show here.
tests/mocks/QMenuModel/CMakeLists.txt+1−2
This diff is too big to show here.
tests/mocks/QMenuModel/QMenuModel.qmltypesdeleted−111
This diff is too big to show here.
tests/mocks/QMenuModel/dbus-enums.h+2−3
This diff is too big to show here.
tests/mocks/QMenuModel/unitymenumodel.cpp+78−13
This diff is too big to show here.
tests/mocks/QMenuModel/unitymenumodel.h+12−1
This diff is too big to show here.
tests/mocks/QtMultimedia/CMakeLists.txt+8−2
This diff is too big to show here.
tests/mocks/QtMultimedia/QtMultimedia.qmltypesdeleted−62
This diff is too big to show here.
tests/mocks/QtMultimedia/VideoSurface.qmlnew file+111
This diff is too big to show here.
tests/mocks/QtMultimedia/audio.cppdeleted−132
This diff is too big to show here.
tests/mocks/QtMultimedia/audio.hdeleted−103
This diff is too big to show here.
tests/mocks/QtMultimedia/mediaplayer.cppnew file+319
This diff is too big to show here.
tests/mocks/QtMultimedia/mediaplayer.hnew file+224
This diff is too big to show here.
tests/mocks/QtMultimedia/plugin.cpp+7−3
This diff is too big to show here.
tests/mocks/QtMultimedia/videooutput.cppnew file+127
This diff is too big to show here.
tests/mocks/QtMultimedia/videooutput.hnew file+52
This diff is too big to show here.
tests/mocks/SessionBroadcast/CMakeLists.txtnew file+8
This diff is too big to show here.
tests/mocks/Ubuntu/SystemImage/plugin.cpp → tests/mocks/SessionBroadcast/SessionBroadcast.cpprenamed+12−12
This diff is too big to show here.
tests/mocks/SessionBroadcast/SessionBroadcast.hnew file+39
This diff is too big to show here.
tests/mocks/IntegratedLightDM/MockGreeter.cpp → tests/mocks/SessionBroadcast/plugin.cpprenamed+10−14
This diff is too big to show here.
plugins/Dash/plugin.h → tests/mocks/SessionBroadcast/plugin.hrenamed+4−5
This diff is too big to show here.
tests/mocks/SessionBroadcast/qmldirnew file+2
This diff is too big to show here.
tests/mocks/UInput/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/UInput/mockuinput.h+1−1
This diff is too big to show here.
tests/mocks/Ubuntu/CMakeLists.txt−2
This diff is too big to show here.
tests/mocks/Ubuntu/Connectivity/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Ubuntu/Connectivity/networking-status.cpp+7−1
This diff is too big to show here.
tests/mocks/Ubuntu/Connectivity/networking-status.h+7−6
This diff is too big to show here.
tests/mocks/Ubuntu/DownloadDaemonListener/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Ubuntu/DownloadDaemonListener/DownloadDaemonListener.qmltypesdeleted−60
This diff is too big to show here.
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.cpp+3−1
This diff is too big to show here.
tests/mocks/Ubuntu/DownloadDaemonListener/MockDownloadTracker.h+2−1
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/CMakeLists.txtdeleted−10
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/MockPayments.cppdeleted−95
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/MockPayments.hdeleted−62
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/Payments.qmltypesdeleted−44
This diff is too big to show here.
tests/mocks/Ubuntu/Payments/qmldirdeleted−3
This diff is too big to show here.
tests/mocks/Ubuntu/SystemImage/CMakeLists.txtdeleted−10
This diff is too big to show here.
tests/mocks/Ubuntu/SystemImage/SystemImage.qmltypesdeleted−20
This diff is too big to show here.
tests/mocks/Ubuntu/SystemImage/qmldirdeleted−3
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/CMakeLists.txt+1
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/LanguagePlugin.qmltypesdeleted−10
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/LanguagePlugin/MockLanguagePlugin.qml+3−2
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/MockSecurityPrivacy.h+1−1
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/SecurityPrivacy/SecurityPrivacy.qmltypesdeleted−39
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/Update/CMakeLists.txtnew file+1
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/Update/MockSystemImage.qmlnew file+30
This diff is too big to show here.
tests/mocks/Ubuntu/SystemSettings/Update/qmldirnew file+2
This diff is too big to show here.
tests/mocks/Ubuntu/Telephony/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Ubuntu/Telephony/MockTelepathyHelper.cpp+27
This diff is too big to show here.
tests/mocks/Ubuntu/Telephony/MockTelepathyHelper.h+22
This diff is too big to show here.
tests/mocks/Ubuntu/Telephony/Telephony.qmltypesdeleted−58
This diff is too big to show here.
tests/mocks/Ubuntu/Thumbnailer/Thumbnailer.qmltypesdeleted−17
This diff is too big to show here.
tests/mocks/Unity/Application/Application.qmltypesdeleted−517
This diff is too big to show here.
tests/mocks/Unity/Application/ApplicationInfo.cpp+83−54
This diff is too big to show here.
tests/mocks/Unity/Application/ApplicationInfo.h+13−17
This diff is too big to show here.
tests/mocks/Unity/Application/ApplicationManager.cpp+134−75
This diff is too big to show here.
tests/mocks/Unity/Application/ApplicationManager.h+32−10
This diff is too big to show here.
tests/mocks/Unity/Application/CMakeLists.txt+4−4
This diff is too big to show here.
tests/mocks/Unity/Application/MirMock.cppnew file+62
This diff is too big to show here.
tests/mocks/Unity/fake_valueslidervalues.h → tests/mocks/Unity/Application/MirMock.hrenamed+17−10
This diff is too big to show here.
tests/mocks/Unity/Application/MirSurface.cpp+146−80
This diff is too big to show here.
tests/mocks/Unity/Application/MirSurface.h+57−27
This diff is too big to show here.
tests/mocks/Unity/Application/MirSurfaceItem.cpp+72−17
This diff is too big to show here.
tests/mocks/Unity/Application/MirSurfaceItem.h+3−2
This diff is too big to show here.
tests/mocks/Unity/Application/MirSurfaceListModel.cpp+22−35
This diff is too big to show here.
tests/mocks/Unity/Application/MirSurfaceListModel.h+7−14
This diff is too big to show here.
tests/mocks/Unity/Application/SurfaceManager.cpp+186−31
This diff is too big to show here.
tests/mocks/Unity/Application/SurfaceManager.h+32−10
This diff is too big to show here.
tests/mocks/Unity/Application/UbuntuKeyboardInfo.cppdeleted−58
This diff is too big to show here.
tests/mocks/Unity/Application/UbuntuKeyboardInfo.hdeleted−57
This diff is too big to show here.
tests/mocks/Unity/Application/VirtualKeyboard.cpp+27−5
This diff is too big to show here.
tests/mocks/Unity/Application/VirtualKeyboard.h+4−1
This diff is too big to show here.
tests/mocks/Unity/Application/plugin.cpp+6−35
This diff is too big to show here.
tests/mocks/Unity/Application/resources/Kate.qmlnew file+49
This diff is too big to show here.
tests/mocks/Unity/Application/resources/KateDialog.qmlnew file+48
This diff is too big to show here.
qml/Stages/ShimStage.qml → tests/mocks/Unity/Application/resources/KateMenu.qmlrenamed+17−19
This diff is too big to show here.
tests/mocks/Unity/Application/resources/MirSurfaceItem.qml+2−5
This diff is too big to show here.
tests/mocks/Unity/Application/resources/VirtualKeyboard.qml+1−6
This diff is too big to show here.
tests/mocks/Unity/Application/resources/screenshots/browser@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/camera@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/dialer@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/facebook@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/gallery@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/libreoffice@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/map@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/music@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/twitter@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/unity8-dash@12.png
Binary file not shown.
tests/mocks/Unity/Application/resources/screenshots/vkb_portrait.png
Binary file not shown.
tests/mocks/Unity/Application/resources/surfaces.qrc+3
This diff is too big to show here.
tests/mocks/Unity/Application/resources/vkb_portrait.png
Binary file not shown.
tests/mocks/Unity/ApplicationMenu/CMakeLists.txtnew file+18
This diff is too big to show here.
tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.cppnew file+47
This diff is too big to show here.
tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.hnew file+41
This diff is too big to show here.
tests/mocks/Unity/ApplicationMenu/plugin.cppnew file+42
This diff is too big to show here.
plugins/Ubuntu/SystemImage/plugin.h → tests/mocks/Unity/ApplicationMenu/plugin.hrenamed+6−5
This diff is too big to show here.
tests/mocks/Unity/ApplicationMenu/qmldirnew file+3
This diff is too big to show here.
tests/mocks/Unity/CMakeLists.txt+2−66
This diff is too big to show here.
tests/mocks/Unity/Connectivity/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Unity/Connectivity/Connectivity.qmltypesdeleted−20
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/CMakeLists.txtdeleted−18
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/DashCommunicator.qmltypesdeleted−46
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/dashcommunicator.cppdeleted−42
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/dashcommunicator.hdeleted−39
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.cppdeleted−46
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.hdeleted−41
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/plugin.cppdeleted−31
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/plugin.hdeleted−34
This diff is too big to show here.
tests/mocks/Unity/DashCommunicator/qmldirdeleted−3
This diff is too big to show here.
tests/mocks/Unity/Indicators/CMakeLists.txt+2−2
This diff is too big to show here.
tests/mocks/Unity/Indicators/Indicators.qmltypesdeleted−232
This diff is too big to show here.
tests/mocks/Unity/Indicators/IndicatorsModel.qml+97−14
This diff is too big to show here.
tests/mocks/Unity/Indicators/fakeindicatorsmodel.h−1
This diff is too big to show here.
tests/mocks/Unity/Indicators/fakeindicatorsmodeldata.jsnew file+1328
This diff is too big to show here.
tests/mocks/Unity/Indicators/fakeplugin.cpp+2
This diff is too big to show here.
tests/mocks/Unity/InputInfo/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Unity/InputInfo/qinputdeviceinfo_mock.cpp+6−2
This diff is too big to show here.
tests/mocks/Unity/Launcher/CMakeLists.txt+5−3
This diff is too big to show here.
tests/mocks/Unity/Launcher/Launcher.qmltypesdeleted−187
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockAppDrawerModel.cppnew file+98
This diff is too big to show here.
tests/mocks/Unity/fake_optionselectoroptions.h → tests/mocks/Unity/Launcher/MockAppDrawerModel.hrenamed+14−18
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockLauncherItem.cpp+40
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockLauncherItem.h+12
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+12−1
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockLauncherModel.h+2−2
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockQuickListModel.cpp+5−1
This diff is too big to show here.
tests/mocks/Unity/Launcher/MockQuickListModel.h+2
This diff is too big to show here.
tests/mocks/Unity/Launcher/plugin.cpp+4
This diff is too big to show here.
tests/mocks/Unity/Notifications/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/Unity/Notifications/MockActionModel.h+1−1
This diff is too big to show here.
tests/mocks/Unity/Notifications/MockNotification.cpp+15
This diff is too big to show here.
tests/mocks/Unity/Notifications/MockNotification.h+7−1
This diff is too big to show here.
tests/mocks/Unity/Notifications/MockNotificationModel.cpp+4−6
This diff is too big to show here.
tests/mocks/Unity/Notifications/MockNotificationModel.h+2−4
This diff is too big to show here.
tests/mocks/Unity/Notifications/Notifications.qmltypesdeleted−149
This diff is too big to show here.
tests/mocks/Unity/Platform/CMakeLists.txtnew file+1
This diff is too big to show here.
qml/Components/ListItems/ThinDivider.qml → tests/mocks/Unity/Platform/MockPlatform.qmlrenamed+7−9
This diff is too big to show here.
tests/mocks/Unity/Platform/qmldirnew file+2
This diff is too big to show here.
tests/mocks/Unity/Screens/CMakeLists.txt+2−2
This diff is too big to show here.
tests/mocks/Unity/Screens/screens.cpp+1−1
This diff is too big to show here.
tests/mocks/Unity/Screens/screens.h+1−1
This diff is too big to show here.
tests/mocks/Unity/Unity.qmltypesdeleted−469
This diff is too big to show here.
tests/mocks/Unity/fake_categories.cppdeleted−161
This diff is too big to show here.
tests/mocks/Unity/fake_categories.hdeleted−54
This diff is too big to show here.
tests/mocks/Unity/fake_expandablefilterwidget.cppdeleted−53
This diff is too big to show here.
tests/mocks/Unity/fake_expandablefilterwidget.hdeleted−48
This diff is too big to show here.
tests/mocks/Unity/fake_filters.cppdeleted−136
This diff is too big to show here.
tests/mocks/Unity/fake_navigation.cppdeleted−123
This diff is too big to show here.
tests/mocks/Unity/fake_navigation.hdeleted−61
This diff is too big to show here.
tests/mocks/Unity/fake_optionselectorfilter.cppdeleted−65
This diff is too big to show here.
tests/mocks/Unity/fake_optionselectorfilter.hdeleted−52
This diff is too big to show here.
tests/mocks/Unity/fake_optionselectoroptions.cppdeleted−77
This diff is too big to show here.
tests/mocks/Unity/fake_previewmodel.cppdeleted−95
This diff is too big to show here.
tests/mocks/Unity/fake_previewmodel.hdeleted−58
This diff is too big to show here.
tests/mocks/Unity/fake_previewwidgetmodel.cppdeleted−89
This diff is too big to show here.
tests/mocks/Unity/fake_previewwidgetmodel.hdeleted−47
This diff is too big to show here.
tests/mocks/Unity/fake_rangeinputfilter.cppdeleted−167
This diff is too big to show here.
tests/mocks/Unity/fake_rangeinputfilter.hdeleted−79
This diff is too big to show here.
tests/mocks/Unity/fake_resultsmodel.cppdeleted−92
This diff is too big to show here.
tests/mocks/Unity/fake_resultsmodel.hdeleted−52
This diff is too big to show here.
tests/mocks/Unity/fake_scope.cppdeleted−363
This diff is too big to show here.
tests/mocks/Unity/fake_scope.hdeleted−127
This diff is too big to show here.
tests/mocks/Unity/fake_scopes.cppdeleted−279
This diff is too big to show here.
tests/mocks/Unity/fake_scopes.hdeleted−83
This diff is too big to show here.
tests/mocks/Unity/fake_scopesoverview.cppdeleted−340
This diff is too big to show here.
tests/mocks/Unity/fake_scopesoverview.hdeleted−117
This diff is too big to show here.
tests/mocks/Unity/fake_settingsmodel.cppdeleted−95
This diff is too big to show here.
tests/mocks/Unity/fake_settingsmodel.hdeleted−54
This diff is too big to show here.
tests/mocks/Unity/fake_unity_plugin.cppdeleted−62
This diff is too big to show here.
tests/mocks/Unity/fake_valuesliderfilter.cppdeleted−84
This diff is too big to show here.
tests/mocks/Unity/fake_valuesliderfilter.hdeleted−55
This diff is too big to show here.
tests/mocks/Unity/fake_valueslidervalues.cppdeleted−51
This diff is too big to show here.
tests/mocks/Unity/qmldirdeleted−3
This diff is too big to show here.
tests/mocks/Utils/CMakeLists.txt+18−4
This diff is too big to show here.
tests/mocks/Utils/URLDispatcher.cppnew file+38
This diff is too big to show here.
tests/mocks/Utils/URLDispatcher.hnew file+47
This diff is too big to show here.
tests/mocks/Utils/Utils.qmltypesdeleted−178
This diff is too big to show here.
tests/mocks/Utils/constants.cpp+2−1
This diff is too big to show here.
tests/mocks/Utils/constants.h+5−5
This diff is too big to show here.
tests/mocks/Utils/plugin.cpp+11−1
This diff is too big to show here.
tests/mocks/Utils/windowstatestorage.cpp+27−4
This diff is too big to show here.
tests/mocks/Utils/windowstatestorage.h+15−7
This diff is too big to show here.
tests/mocks/Wizard/CMakeLists.txt+6−3
This diff is too big to show here.
tests/mocks/Wizard/MockSystem.cpp+24−1
This diff is too big to show here.
tests/mocks/Wizard/MockSystem.h+15−1
This diff is too big to show here.
tests/mocks/Wizard/Wizard.qmltypesdeleted−37
This diff is too big to show here.
tests/mocks/Wizard/mockplugin.cpp+4
This diff is too big to show here.
tests/mocks/liblightdm/CMakeLists.txtnew file+18
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/GreeterPrivate.cpp → tests/mocks/liblightdm/GreeterPrivate.cpprenamed
The content is the same.
tests/mocks/IntegratedLightDM/liblightdm/GreeterPrivate.h → tests/mocks/liblightdm/GreeterPrivate.hrenamed+1
This diff is too big to show here.
tests/mocks/liblightdm/MockController.cppnew file+192
This diff is too big to show here.
tests/mocks/liblightdm/MockController.hnew file+106
This diff is too big to show here.
tests/mocks/liblightdm/MockGreeter.cppnew file+316
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/Greeter.h → tests/mocks/liblightdm/MockGreeter.hrenamed+10−24
This diff is too big to show here.
tests/mocks/liblightdm/MockSessionsModel.cppnew file+118
This diff is too big to show here.
tests/mocks/liblightdm/MockSessionsModel.hnew file+64
This diff is too big to show here.
tests/mocks/liblightdm/MockUsersModel.cppnew file+220
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/UsersModel.h → tests/mocks/liblightdm/MockUsersModel.hrenamed+11−19
This diff is too big to show here.
tests/mocks/liblightdm/SessionsModelPrivate.cppnew file+83
This diff is too big to show here.
tests/mocks/liblightdm/SessionsModelPrivate.hnew file+63
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp → tests/mocks/liblightdm/UsersModelPrivate.cpprenamed+43−23
This diff is too big to show here.
tests/mocks/IntegratedLightDM/liblightdm/UsersModelPrivate.h → tests/mocks/liblightdm/UsersModelPrivate.hrenamed+2−1
This diff is too big to show here.
tests/mocks/liblightdm/demo/CMakeLists.txt+1−1
This diff is too big to show here.
tests/mocks/libusermetrics/CMakeLists.txt+2−1
This diff is too big to show here.
tests/mocks/libusermetrics/ColorTheme.cpp+4
This diff is too big to show here.
tests/mocks/libusermetrics/UserMetrics.cpp+38−13
This diff is too big to show here.
tests/mocks/libusermetrics/UserMetrics.h+2
This diff is too big to show here.
tests/mocks/libusermetrics/libusermetricsoutput/ColorTheme.hdeleted−1
This diff is too big to show here.
tests/mocks/libusermetrics/libusermetricsoutput/UserMetrics.hdeleted−1
This diff is too big to show here.
tests/plugins/AccountsService/CMakeLists.txt+2−7
This diff is too big to show here.
tests/plugins/AccountsService/PropertiesServer.cpp+1−1
This diff is too big to show here.
tests/plugins/AccountsService/client.cpp+6−34
This diff is too big to show here.
tests/plugins/CMakeLists.txt+4−3
This diff is too big to show here.
tests/plugins/Cursor/tst_Cursor.qml+8−1
This diff is too big to show here.
tests/plugins/Dash/CMakeLists.txtdeleted−100
This diff is too big to show here.
tests/plugins/Dash/cardcreator/1.resdeleted−95
This diff is too big to show here.
tests/plugins/Dash/cardcreator/1.res.cardcreatordeleted−94
This diff is too big to show here.
tests/plugins/Dash/cardcreator/1.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/10.resdeleted−130
This diff is too big to show here.
tests/plugins/Dash/cardcreator/10.res.cardcreatordeleted−128
This diff is too big to show here.
tests/plugins/Dash/cardcreator/10.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/11.resdeleted−189
This diff is too big to show here.
tests/plugins/Dash/cardcreator/11.res.cardcreatordeleted−185
This diff is too big to show here.
tests/plugins/Dash/cardcreator/11.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/12.resdeleted−121
This diff is too big to show here.
tests/plugins/Dash/cardcreator/12.res.cardcreatordeleted−120
This diff is too big to show here.
tests/plugins/Dash/cardcreator/12.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/2.resdeleted−129
This diff is too big to show here.
tests/plugins/Dash/cardcreator/2.res.cardcreatordeleted−127
This diff is too big to show here.
tests/plugins/Dash/cardcreator/2.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/3.resdeleted−104
This diff is too big to show here.
tests/plugins/Dash/cardcreator/3.res.cardcreatordeleted−102
This diff is too big to show here.
tests/plugins/Dash/cardcreator/3.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/4.resdeleted−110
This diff is too big to show here.
tests/plugins/Dash/cardcreator/4.res.cardcreatordeleted−108
This diff is too big to show here.
tests/plugins/Dash/cardcreator/4.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/5.resdeleted−117
This diff is too big to show here.
tests/plugins/Dash/cardcreator/5.res.cardcreatordeleted−116
This diff is too big to show here.
tests/plugins/Dash/cardcreator/5.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/6.resdeleted−126
This diff is too big to show here.
tests/plugins/Dash/cardcreator/6.res.cardcreatordeleted−125
This diff is too big to show here.
tests/plugins/Dash/cardcreator/6.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/7.resdeleted−142
This diff is too big to show here.
tests/plugins/Dash/cardcreator/7.res.cardcreatordeleted−140
This diff is too big to show here.
tests/plugins/Dash/cardcreator/7.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/8.resdeleted−108
This diff is too big to show here.
tests/plugins/Dash/cardcreator/8.res.cardcreatordeleted−106
This diff is too big to show here.
tests/plugins/Dash/cardcreator/8.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreator/9.resdeleted−119
This diff is too big to show here.
tests/plugins/Dash/cardcreator/9.res.cardcreatordeleted−118
This diff is too big to show here.
tests/plugins/Dash/cardcreator/9.tstdeleted−4
This diff is too big to show here.
tests/plugins/Dash/cardcreatortest.cppdeleted−126
This diff is too big to show here.
tests/plugins/Dash/cardcreatortest.qmldeleted−29
This diff is too big to show here.
tests/plugins/Dash/horizontaljournaltest.cppdeleted−492
This diff is too big to show here.
tests/plugins/Dash/horizontaljournaltest.qmldeleted−44
This diff is too big to show here.
tests/plugins/Dash/horizontaljournaltry.cppdeleted−91
This diff is too big to show here.
tests/plugins/Dash/horizontaljournaltry.qmldeleted−120
This diff is too big to show here.
tests/plugins/Dash/listviewwithpageheadersectionexternalmodeltest.cppdeleted−248
This diff is too big to show here.
tests/plugins/Dash/listviewwithpageheadersectiontest.cppdeleted−2209
This diff is too big to show here.
tests/plugins/Dash/listviewwithpageheadertest.cppdeleted−2011
This diff is too big to show here.
tests/plugins/Dash/listviewwithpageheadertest.qmldeleted−96
This diff is too big to show here.
tests/plugins/Dash/listviewwithpageheadertestsection.qmldeleted−108
This diff is too big to show here.
tests/plugins/Dash/listviewwithpageheadertestsectionexternalmodel.qmldeleted−76
This diff is too big to show here.
tests/plugins/Dash/organicgridtest.cppdeleted−535
This diff is too big to show here.
tests/plugins/Dash/organicgridtest.qmldeleted−44
This diff is too big to show here.
tests/plugins/Dash/organicgridtry.cppdeleted−99
This diff is too big to show here.
tests/plugins/Dash/organicgridtry.qmldeleted−114
This diff is too big to show here.
tests/plugins/Dash/tst_CardAttributes.qmldeleted−57
This diff is too big to show here.
tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qmldeleted−56
This diff is too big to show here.
tests/plugins/Dash/tst_ListViewWithPageHeaderQML.qmldeleted−140
This diff is too big to show here.
tests/plugins/Dash/tst_ScopeStyle.qmldeleted−188
This diff is too big to show here.
tests/plugins/Dash/verticaljournaltest.cppdeleted−504
This diff is too big to show here.
tests/plugins/Dash/verticaljournaltest.qmldeleted−45
This diff is too big to show here.
tests/plugins/Dash/verticaljournaltry.cppdeleted−91
This diff is too big to show here.
tests/plugins/Dash/verticaljournaltry.qmldeleted−121
This diff is too big to show here.
tests/plugins/GlobalShortcut/CMakeLists.txt+1−2
This diff is too big to show here.
tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt+1−4
This diff is too big to show here.
tests/plugins/Greeter/Unity/Launcher/launchermodelastest.cpp−1
This diff is too big to show here.
tests/plugins/IntegratedLightDM/CMakeLists.txtdeleted−106
This diff is too big to show here.
tests/plugins/IntegratedLightDM/usersmodel.cppdeleted−84
This diff is too big to show here.
tests/plugins/LightDM/CMakeLists.txtnew file+1
This diff is too big to show here.
tests/plugins/LightDM/IntegratedLightDM/CMakeLists.txtnew file+157
This diff is too big to show here.
tests/plugins/IntegratedLightDM/dbus.cpp → tests/plugins/LightDM/IntegratedLightDM/dbus.cpprenamed+21−12
This diff is too big to show here.
tests/plugins/IntegratedLightDM/greeter.qml → tests/plugins/LightDM/IntegratedLightDM/greeter.qmlrenamed+2−7
This diff is too big to show here.
tests/plugins/IntegratedLightDM/integrated.cpp → tests/plugins/LightDM/IntegratedLightDM/integrated.cpprenamed
The content is the same.
tests/plugins/IntegratedLightDM/pam.cpp → tests/plugins/LightDM/IntegratedLightDM/pam.cpprenamed
The content is the same.
tests/plugins/LightDM/IntegratedLightDM/promptsmodel.cppnew file+175
This diff is too big to show here.
tests/plugins/LightDM/IntegratedLightDM/sessionsmodel.cppnew file+134
This diff is too big to show here.
tests/plugins/LightDM/IntegratedLightDM/usersmodel.cppnew file+168
This diff is too big to show here.
tests/plugins/SessionBroadcast/BroadcastServer.cppnew file+33
This diff is too big to show here.
tests/plugins/SessionBroadcast/BroadcastServer.hnew file+40
This diff is too big to show here.
tests/plugins/SessionBroadcast/CMakeLists.txtnew file+51
This diff is too big to show here.
tests/plugins/SessionBroadcast/interfaces.xmlnew file+18
This diff is too big to show here.
tests/plugins/SessionBroadcast/server.cppnew file+37
This diff is too big to show here.
tests/plugins/SessionBroadcast/sessionbroadcasttest.cppnew file+111
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/CMakeLists.txt+11−10
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/GestureTest.cpp+13−4
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/GestureTest.h+4−5
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/tst_AxisVelocityCalculator.cpp+1−1
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.cpp+1−1
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/tst_FloatingFlickable.qml+1−1
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/tst_TouchGate.cpp+14−3
This diff is too big to show here.
tests/plugins/Ubuntu/Gestures/tst_TouchGestureArea.cpp+30
This diff is too big to show here.
tests/plugins/Unity/CMakeLists.txt+1
This diff is too big to show here.
tests/plugins/Unity/Indicators/CMakeLists.txt+1−1
This diff is too big to show here.
tests/plugins/Unity/Launcher/CMakeLists.txt+51−24
This diff is too big to show here.
tests/plugins/Unity/Launcher/appdrawermodeltest.cppnew file+68
This diff is too big to show here.
tests/plugins/Unity/Launcher/abs-icon.desktop → tests/plugins/Unity/Launcher/applications/abs-icon.desktoprenamed+1
This diff is too big to show here.
tests/plugins/Unity/Launcher/click-icon.desktop → tests/plugins/Unity/Launcher/applications/click-icon.desktoprenamed+1
This diff is too big to show here.
tests/plugins/Unity/Launcher/click-icon.svg → tests/plugins/Unity/Launcher/applications/click-icon.svgrenamed
The content is the same.
tests/plugins/Unity/Launcher/no-name.desktop → tests/plugins/Unity/Launcher/applications/no-name.desktoprenamed+1
This diff is too big to show here.
tests/plugins/Unity/Launcher/rel-icon.desktop → tests/plugins/Unity/Launcher/applications/rel-icon.desktoprenamed+1
This diff is too big to show here.
tests/plugins/Unity/Launcher/rel-icon.svg → tests/plugins/Unity/Launcher/applications/rel-icon.svgrenamed
The content is the same.
tests/plugins/Unity/Launcher/launchermodeltest.cpp+163−25
This diff is too big to show here.
tests/plugins/Unity/Launcher/no-icon.desktopdeleted−2
This diff is too big to show here.
tests/plugins/Unity/Launcher/ualwrapper.cppnew file+58
This diff is too big to show here.
tests/plugins/Unity/Launcher/ualwrapper.hnew file+55
This diff is too big to show here.
tests/plugins/Unity/Launcher/xdgwatcher.cppnew file+45
This diff is too big to show here.
tests/mocks/IntegratedLightDM/MockGreeter.h → tests/plugins/Unity/Launcher/xdgwatcher.hrenamed+18−16
This diff is too big to show here.
tests/plugins/Unity/Platform/CMakeLists.txtnew file+30
This diff is too big to show here.
tests/plugins/Unity/Platform/platformtest.cppnew file+142
This diff is too big to show here.
tests/plugins/Unity/Session/CMakeLists.txt+45−2
This diff is too big to show here.
tests/plugins/Unity/Session/LightDMServer.cppnew file+29
This diff is too big to show here.
tests/plugins/Unity/Session/LightDMServer.hnew file+38
This diff is too big to show here.
tests/plugins/Unity/Session/LogindServer.cppnew file+43
This diff is too big to show here.
tests/plugins/Unity/Session/LogindServer.hnew file+48
This diff is too big to show here.
tests/plugins/Unity/Session/interfaces.xmlnew file+29
This diff is too big to show here.
tests/plugins/Unity/Session/preload.cnew file+43
This diff is too big to show here.
tests/plugins/Unity/Session/server.cppnew file+50
This diff is too big to show here.
tests/plugins/Unity/Session/sessionbackendtest.cpp+142−9
This diff is too big to show here.
tests/plugins/Utils/CMakeLists.txt+17−3
This diff is too big to show here.
tests/plugins/Utils/DeviceConfigParserTest.cpp+3
This diff is too big to show here.
tests/plugins/Utils/ModelTest.cpp+2−1
This diff is too big to show here.
tests/plugins/Utils/URLDispatcherTest.cppnew file+78
This diff is too big to show here.
tests/plugins/Utils/WindowInputMonitorTest.cpp+107−10
This diff is too big to show here.
tests/plugins/Utils/WindowStateStorageTest.cppnew file+121
This diff is too big to show here.
tests/plugins/WindowManager/CMakeLists.txtnew file+36
This diff is too big to show here.
tests/plugins/WindowManager/UnityApplicationMocks.hnew file+211
This diff is too big to show here.
tests/plugins/WindowManager/tst_TopLevelWindowModel.cppnew file+193
This diff is too big to show here.
tests/plugins/Wizard/CMakeLists.txt+2−2
This diff is too big to show here.
tests/plugins/Wizard/tst_pagelist.cpp+30−1
This diff is too big to show here.
tests/qmltests/ApplicationMenuDataLoader.qmlnew file+99
This diff is too big to show here.
tests/qmltests/ApplicationMenus/tst_MenuBar.qmlnew file+437
This diff is too big to show here.
tests/qmltests/ApplicationMenus/tst_MenuPopup.qmlnew file+361
This diff is too big to show here.
tests/qmltests/CMakeLists.txt+38−78
This diff is too big to show here.
tests/qmltests/Components/CMakeLists.txt+13−5
This diff is too big to show here.
tests/qmltests/Components/tst_Carousel.qmldeleted−293
This diff is too big to show here.
tests/qmltests/Components/tst_Dialogs.qml−1
This diff is too big to show here.
tests/qmltests/Components/tst_DragHandle.cpp+21−4
This diff is too big to show here.
tests/qmltests/Components/tst_DraggingArea.qml+6−6
This diff is too big to show here.
tests/qmltests/Components/tst_EdgeDragEvaluator.cpp+2−2
This diff is too big to show here.
tests/qmltests/Components/tst_LazyImage/portrait.png
Binary file not shown.
tests/qmltests/Components/tst_LazyImage/square.png
Binary file not shown.
tests/qmltests/Components/tst_LazyImage/wide.png
Binary file not shown.
tests/qmltests/Components/tst_Lockscreen.qml+14−32
This diff is too big to show here.
tests/qmltests/Components/tst_MediaServices.qmlnew file+231
This diff is too big to show here.
tests/qmltests/Components/tst_PhysicalKeysMapper.qml+19−27
This diff is too big to show here.
tests/qmltests/Components/tst_Rating.qml+1−1
This diff is too big to show here.
tests/qmltests/Components/tst_ResponsiveGridView.qmldeleted−157
This diff is too big to show here.
tests/qmltests/Components/tst_ResponsiveVerticalJournal.qmldeleted−183
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewSharing.qml → tests/qmltests/Components/tst_SharingPicker.qmlrenamed+11−11
This diff is too big to show here.
tests/qmltests/Components/tst_Showable.qml+13
This diff is too big to show here.
tests/qmltests/Components/tst_VirtualTouchPad.qml+55−1
This diff is too big to show here.
tests/qmltests/Components/tst_Wallpaper.qmlnew file+118
This diff is too big to show here.
tests/qmltests/Components/tst_WallpaperResolver.qml+115−43
This diff is too big to show here.
tests/qmltests/Components/tst_ZoomableImage.qml+1−1
This diff is too big to show here.
tests/qmltests/Dash/CardHelpers.jsdeleted−115
This diff is too big to show here.
tests/qmltests/Dash/Filters/tst_FilterExpandableWidget.qmldeleted−99
This diff is too big to show here.
tests/qmltests/Dash/Filters/tst_FilterOptionSelector.qmldeleted−96
This diff is too big to show here.
tests/qmltests/Dash/Filters/tst_FilterRangeInput.qmldeleted−247
This diff is too big to show here.
tests/qmltests/Dash/Filters/tst_FilterValueSlider.qmldeleted−101
This diff is too big to show here.
tests/qmltests/Dash/Filters/tst_FilterWidgetFactory.qmldeleted−59
This diff is too big to show here.
tests/qmltests/Dash/Previews/MockPreviewWidget.qmldeleted−27
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_Preview.qmldeleted−134
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewActions.qmldeleted−231
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qmldeleted−184
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewComment.qmldeleted−84
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewCommentInput.qmldeleted−85
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewExpandable.qmldeleted−339
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewHeader.qmldeleted−187
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewIconActions.qmldeleted−136
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qmldeleted−147
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewMediaToolbar.qmldeleted−69
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewPayments.qmldeleted−203
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewProgress.qmldeleted−87
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplay.qmldeleted−123
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewRatingDisplayCreationRanges.qmldeleted−94
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewRatingEdit.qmldeleted−84
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewRatingInput.qmldeleted−214
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewTable.qmldeleted−126
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewTextSummary.qmldeleted−87
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewVideoPlayback.qmldeleted−61
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewWidgetFactory.qmldeleted−103
This diff is too big to show here.
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qmldeleted−133
This diff is too big to show here.
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingBoolean.qmldeleted−62
This diff is too big to show here.
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingList.qmldeleted−84
This diff is too big to show here.
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingNumber.qmldeleted−98
This diff is too big to show here.
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingString.qmldeleted−88
This diff is too big to show here.
tests/qmltests/Dash/ScopeSettings/tst_ScopeSettingsWidgetFactory.qmldeleted−65
This diff is too big to show here.
tests/qmltests/Dash/artwork/avatar@12.pngdeleted
Binary file not shown.
tests/qmltests/Dash/artwork/background.pngdeleted
Binary file not shown.
tests/qmltests/Dash/artwork/checkers.pngdeleted
Binary file not shown.
tests/qmltests/Dash/artwork/emblem.pngdeleted
Binary file not shown.
tests/qmltests/Dash/artwork/music-player-design.pngdeleted
Binary file not shown.
tests/qmltests/Dash/tst_Card.qmldeleted−692
This diff is too big to show here.
tests/qmltests/Dash/tst_CardBenchmark.qmldeleted−95
This diff is too big to show here.
tests/qmltests/Dash/tst_CardCarousel.qmldeleted−87
This diff is too big to show here.
tests/qmltests/Dash/tst_CardTool.qmldeleted−379
This diff is too big to show here.
tests/qmltests/Dash/tst_Dash.qmldeleted−672
This diff is too big to show here.
tests/qmltests/Dash/tst_DashContent.qmldeleted−688
This diff is too big to show here.
tests/qmltests/Dash/tst_DashPageHeader.qmldeleted−316
This diff is too big to show here.
tests/qmltests/Dash/tst_DashShell.qmldeleted−139
This diff is too big to show here.
tests/qmltests/Dash/tst_GenericScopeView.qmldeleted−664
This diff is too big to show here.
tests/qmltests/Dash/tst_PageHeader/logo-ubuntu-orange.svgdeleted−60
This diff is too big to show here.
tests/qmltests/Dash/tst_PreviewView.qmldeleted−122
This diff is too big to show here.
tests/qmltests/Greeter/TestView.qml+24−22
This diff is too big to show here.
tests/qmltests/Greeter/tst_Greeter.qml+277−151
This diff is too big to show here.
tests/qmltests/Greeter/tst_GreeterView.qmlnew file+1366
This diff is too big to show here.
tests/qmltests/Greeter/tst_Infographics.qml+78−24
This diff is too big to show here.
tests/qmltests/Greeter/tst_NarrowView.qmldeleted−533
This diff is too big to show here.
tests/qmltests/Greeter/tst_WideView.qmldeleted−537
This diff is too big to show here.
tests/qmltests/Launcher/tst_Drawer.qmlnew file+520
This diff is too big to show here.
tests/qmltests/Launcher/tst_Launcher.qml+441−84
This diff is too big to show here.
tests/qmltests/Notifications/Notification.qml+1
This diff is too big to show here.
tests/qmltests/Notifications/tst_Notifications.qml+95−39
This diff is too big to show here.
tests/qmltests/Notifications/tst_OptionToggle.qml+13−22
This diff is too big to show here.
tests/qmltests/Notifications/tst_SwipeToAct.qml+14−21
This diff is too big to show here.
tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml+10−26
This diff is too big to show here.
tests/qmltests/Panel/tst_IndicatorItem.qml → tests/qmltests/Panel/Indicators/tst_IndicatorItem.qmlrenamed+5−4
This diff is too big to show here.
tests/qmltests/Panel/Indicators/tst_MenuItemFactory.qml → tests/qmltests/Panel/Indicators/tst_IndicatorMenuItemFactory.qmlrenamed+96−89
This diff is too big to show here.
tests/qmltests/Panel/Indicators/tst_IndicatorsLight.qml+168−8
This diff is too big to show here.
tests/qmltests/Panel/IndicatorTest.qml → tests/qmltests/Panel/PanelTest.qmlrenamed−5
This diff is too big to show here.
tests/qmltests/Panel/PanelUI.qmlnew file+286
This diff is too big to show here.
tests/qmltests/Panel/tst_ActiveCallHint.qml+29−10
This diff is too big to show here.
tests/qmltests/Panel/tst_MenuContent.qml+16−4
This diff is too big to show here.
tests/qmltests/Panel/tst_Panel.qml+434−233
This diff is too big to show here.
tests/qmltests/Panel/tst_PanelBar.qml+25−34
This diff is too big to show here.
tests/qmltests/Panel/tst_PanelItemRow.qml+41−12
This diff is too big to show here.
tests/qmltests/Panel/tst_PanelMenu.qml+137−34
This diff is too big to show here.
tests/qmltests/Panel/tst_PanelMenuPage.qml+53−49
This diff is too big to show here.
tests/qmltests/Panel/tst_PanelSmallScreen.qml+133
This diff is too big to show here.
tests/qmltests/Stage/ApplicationCheckBox.qml+9−9
This diff is too big to show here.
tests/qmltests/Stage/SizeHintField.qml
This diff is too big to show here.
tests/qmltests/Stage/SurfaceManagerControls.qml+1−1
This diff is too big to show here.
tests/qmltests/Stage/SurfaceManagerField.qml
This diff is too big to show here.
tests/qmltests/Stage/tst_ApplicationWindow.qml+52−41
This diff is too big to show here.
tests/qmltests/Stage/tst_DecoratedWindow.qml+267
This diff is too big to show here.
tests/qmltests/Stage/tst_DesktopStage.qml+1085
This diff is too big to show here.
tests/qmltests/Stage/tst_PhoneStage.qml+239−285
This diff is too big to show here.
tests/qmltests/Stage/tst_QMLTopLevelWindowModel.qml+191
This diff is too big to show here.
tests/qmltests/Stage/tst_Splash.qml+16−2
This diff is too big to show here.
tests/qmltests/Stage/tst_SurfaceContainer.qml+15−10
This diff is too big to show here.
tests/qmltests/Stage/tst_TabletStage.qml+315−309
This diff is too big to show here.
tests/qmltests/Stage/tst_WindowDecoration.qml+244
This diff is too big to show here.
tests/qmltests/Stage/tst_WindowResizeArea.qml+73−115
This diff is too big to show here.
tests/qmltests/Stages/tst_DesktopStage.qml−658
This diff is too big to show here.
tests/qmltests/Stages/tst_SpreadDelegate.qml−320
This diff is too big to show here.
tests/qmltests/Tutorial/tst_Tutorial.qml+319−332
This diff is too big to show here.
tests/qmltests/UnityLogo.png
This diff is too big to show here.
tests/qmltests/Wizard/tst_Wizard.qml+138−135
This diff is too big to show here.
tests/qmltests/tst_DisabledScreenNotice.qml+24−10
This diff is too big to show here.
tests/qmltests/tst_OrientedShell.qml+513−489
This diff is too big to show here.
tests/qmltests/tst_Shell.qml+1752−828
This diff is too big to show here.
tests/qmltests/tst_ShellWithPin.qml+167−231
This diff is too big to show here.
tests/qmltests/utils/Unity/Test/tst_UnityTest.qml+31
This diff is too big to show here.
tests/scripts/alert-launcher-icon.sh+16
This diff is too big to show here.
tests/scripts/get-progress.sh+16
This diff is too big to show here.
tests/scripts/list-launcher-icons.sh+16
This diff is too big to show here.
tests/scripts/set-count-visible.sh+16
This diff is too big to show here.
tests/scripts/set-count.sh+16
This diff is too big to show here.
tests/scripts/set-progress.sh+16
This diff is too big to show here.
tests/uqmlscene/CMakeLists.txt+10−2
This diff is too big to show here.
tests/uqmlscene/main.cpp+7−3
This diff is too big to show here.
tests/utils/modules/Unity/Test/CMakeLists.txt+8−5
This diff is too big to show here.
tests/utils/modules/Unity/Test/MouseTouchEmulationCheckbox.qml+5−1
This diff is too big to show here.
tests/utils/modules/Unity/Test/StageTestCase.qml+64
This diff is too big to show here.
tests/utils/modules/Unity/Test/Test.qmltypes−60
This diff is too big to show here.
tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.cpp+18−4
This diff is too big to show here.
tests/utils/modules/Unity/Test/TouchEventSequenceWrapper.h+4−2
This diff is too big to show here.
tests/utils/modules/Unity/Test/UnityTestCase.qml+12−22
This diff is too big to show here.
tests/utils/modules/Unity/Test/qmldir+2−1
This diff is too big to show here.
tests/utils/modules/Unity/Test/testutil.cpp+33−5
This diff is too big to show here.
tests/utils/modules/Unity/Test/testutil.h+1
This diff is too big to show here.
tools/CMakeLists.txt+2−12
This diff is too big to show here.
tools/indicatorsclient/CMakeLists.txt+1−1
This diff is too big to show here.
tools/indicatorsclient/indicatorsclient.cpp+10−8
This diff is too big to show here.
tools/indicatorsclient/indicatorsclient.h−2
This diff is too big to show here.
tools/indicatorsclient/main.cpp
This diff is too big to show here.
tools/menutool/CMakeLists.txt+5
This diff is too big to show here.
This diff is too big to show here.
tools/menutool/menutool.cpp+62
This diff is too big to show here.
tools/menutool/menutool.qml+118
This diff is too big to show here.
tools/registry-tracker.cpp−146
This diff is too big to show here.
tools/registry-tracker.h−49
This diff is too big to show here.
This diff is too big to show here.
This diff is too big to show here.