Merge lp:~gerboland/qtmir/desktopFileReader into lp:~dandrader/qtmir/parse_splash_from_desktop_file
- desktopFileReader
- Merge into parse_splash_from_desktop_...
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~gerboland/qtmir/desktopFileReader | ||||
Merge into: | lp:~dandrader/qtmir/parse_splash_from_desktop_file | ||||
Diff against target: |
3963 lines (+2079/-471) 58 files modified
README (+1/-1) debian/changelog (+25/-0) debian/control (+3/-0) src/common/debughelpers.cpp (+38/-6) src/common/debughelpers.h (+2/-1) src/lttng-compiler.pri (+25/-0) src/modules/Unity/Application/Application.pro (+11/-5) src/modules/Unity/Application/application.cpp (+6/-4) src/modules/Unity/Application/application.h (+7/-6) src/modules/Unity/Application/application_manager.cpp (+14/-6) src/modules/Unity/Application/desktopfilereader.cpp (+164/-114) src/modules/Unity/Application/desktopfilereader.h (+22/-40) src/modules/Unity/Application/gscopedpointer.h (+113/-0) src/modules/Unity/Application/mirsurfaceitem.cpp (+138/-31) src/modules/Unity/Application/mirsurfaceitem.h (+38/-7) src/modules/Unity/Application/mirsurfacemanager.cpp (+13/-7) src/modules/Unity/Application/plugin.cpp (+1/-0) src/modules/Unity/Application/session.cpp (+21/-19) src/modules/Unity/Application/session.h (+35/-63) src/modules/Unity/Application/session_interface.h (+106/-0) src/modules/Unity/Application/sessionmanager.cpp (+8/-8) src/modules/Unity/Application/sessionmanager.h (+4/-4) src/modules/Unity/Application/sessionmodel.h (+2/-2) src/modules/Unity/Application/tracepoints.tp (+9/-0) src/platforms/mirserver/logging.h (+1/-0) src/platforms/mirserver/mirplacementstrategy.cpp (+5/-0) src/platforms/mirserver/mirserver.pro (+8/-0) src/platforms/mirserver/mirserverconfiguration.cpp (+12/-1) src/platforms/mirserver/qteventfeeder.cpp (+175/-18) src/platforms/mirserver/qteventfeeder.h (+31/-1) src/platforms/mirserver/sessionauthorizer.cpp (+4/-0) src/platforms/mirserver/sessionlistener.cpp (+5/-0) src/platforms/mirserver/tracepoints.tp (+10/-0) tests/google-mock.pri (+24/-0) tests/mirserver/QtEventFeeder/QtEventFeeder.pro (+16/-0) tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h (+65/-0) tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp (+224/-0) tests/mirserver/mirserver.pro (+2/-0) tests/modules/ApplicationManager/application_manager_test.cpp (+3/-2) tests/modules/DesktopFileReader/DesktopFileReader.pro (+15/-0) tests/modules/DesktopFileReader/calculator.desktop (+227/-0) tests/modules/DesktopFileReader/desktopfilereader_test.cpp (+128/-0) tests/modules/MirSurfaceItem/MirSurfaceItem.pro (+13/-0) tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp (+113/-0) tests/modules/SessionManager/session_manager_test.cpp (+10/-9) tests/modules/SessionManager/session_test.cpp (+5/-6) tests/modules/common/common.pri (+5/-29) tests/modules/common/mock_focus_controller.h (+9/-6) tests/modules/common/mock_mir_session.h (+14/-13) tests/modules/common/mock_prompt_session.h (+7/-4) tests/modules/common/mock_prompt_session_manager.h (+21/-18) tests/modules/common/mock_renderable.h (+9/-6) tests/modules/common/mock_session.h (+65/-0) tests/modules/common/mock_surface.h (+24/-23) tests/modules/common/qtmir_test.h (+12/-9) tests/modules/modules.pro (+1/-1) tests/test-includes.pri (+9/-0) tests/tests.pro (+1/-1) |
||||
To merge this branch: | bzr merge lp:~gerboland/qtmir/desktopFileReader | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel d'Andrada | Pending | ||
Review via email: mp+235222@code.launchpad.net |
Commit message
Rewrite DesktopFileReader to use GDesktopAppInfo, enables reading localized keys
Description of the change
Rewrite DesktopFileReader to use GDesktopAppInfo, enables reading localized keys
* Are there any related MPs required for this MP to build/function as expected? Please list.
N
* Did you perform an exploratory manual test run of your code change and any related functionality?
Y
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A
- 259. By Gerry Boland
-
Oops, revert naughty change
- 260. By Gerry Boland
-
Typos
- 261. By Gerry Boland
-
Fix typos
- 262. By Gerry Boland
-
Sssh, not so noisy
- 263. By Gerry Boland
-
Use qCWarning
- 264. By Gerry Boland
-
Merge trunk
- 265. By Gerry Boland
-
Fix compiler unused warning
- 266. By Gerry Boland
-
GDesktopInfo actually checks that the binary specified by the Exec line is installed. So need to change calculator.desktop to definitely use an installed binary
- 267. By Gerry Boland
-
Add more verbose error message if desktop file not valid or missing
- 268. By Gerry Boland
-
Missing !, debug statement now makes sense
Unmerged revisions
- 268. By Gerry Boland
-
Missing !, debug statement now makes sense
- 267. By Gerry Boland
-
Add more verbose error message if desktop file not valid or missing
- 266. By Gerry Boland
-
GDesktopInfo actually checks that the binary specified by the Exec line is installed. So need to change calculator.desktop to definitely use an installed binary
- 265. By Gerry Boland
-
Fix compiler unused warning
- 264. By Gerry Boland
-
Merge trunk
- 263. By Gerry Boland
-
Use qCWarning
- 262. By Gerry Boland
-
Sssh, not so noisy
- 261. By Gerry Boland
-
Fix typos
- 260. By Gerry Boland
-
Typos
- 259. By Gerry Boland
-
Oops, revert naughty change
Preview Diff
1 | === modified file 'README' |
2 | --- README 2014-06-30 15:49:02 +0000 |
3 | +++ README 2014-09-18 22:57:30 +0000 |
4 | @@ -1,7 +1,7 @@ |
5 | This repo contains a QPA plugin to make Qt a Mir server. |
6 | |
7 | Handy way to grab dependencies is with: |
8 | -$ sudo mk-build-dep -ir debian/control |
9 | +$ sudo mk-build-deps -ir debian/control |
10 | |
11 | To use, compile and install with: |
12 | $ qmake |
13 | |
14 | === modified file 'debian/changelog' |
15 | --- debian/changelog 2014-09-03 08:03:52 +0000 |
16 | +++ debian/changelog 2014-09-18 22:57:30 +0000 |
17 | @@ -1,3 +1,28 @@ |
18 | +qtmir (0.4.3+14.10.20140915-0ubuntu1) utopic; urgency=low |
19 | + |
20 | + [ Daniel d'Andrada ] |
21 | + * MirSurfaceItem: Ensure all touch sequences sent to Mir surface are |
22 | + properly ended. |
23 | + |
24 | + -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 15 Sep 2014 14:50:16 +0000 |
25 | + |
26 | +qtmir (0.4.3+14.10.20140907-0ubuntu1) utopic; urgency=low |
27 | + |
28 | + [ Daniel d'Andrada ] |
29 | + * QtEventFeeder: validate touches before sending them to Qt |
30 | + |
31 | + [ josharenson ] |
32 | + * Fix a small typo in the README file |
33 | + |
34 | + [ Alan Griffiths ] |
35 | + * Provide Mir with a handler for any command-line arguments it fails |
36 | + to parse. For the moment, these are simply ignored. |
37 | + |
38 | + [ Gerry Boland ] |
39 | + * Add LTTng tracepoints |
40 | + |
41 | + -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Sun, 07 Sep 2014 19:42:56 +0000 |
42 | + |
43 | qtmir (0.4.3+14.10.20140903-0ubuntu1) utopic; urgency=medium |
44 | |
45 | [ Nick Dedekind ] |
46 | |
47 | === modified file 'debian/control' |
48 | --- debian/control 2014-09-08 21:05:38 +0000 |
49 | +++ debian/control 2014-09-18 22:57:30 +0000 |
50 | @@ -11,6 +11,7 @@ |
51 | libboost-system-dev, |
52 | libfontconfig1-dev, |
53 | libglib2.0-dev, |
54 | + liblttng-ust-dev, |
55 | libmirclient-dev (>= 0.6.0), |
56 | libmirserver-dev (>= 0.6.0), |
57 | libprocess-cpp-dev, |
58 | @@ -25,6 +26,8 @@ |
59 | libmircommon-dev, |
60 | pkg-config, |
61 | protobuf-compiler, |
62 | +# lttng-gen-ts needs python3, but doesn't depend on it itself: bug 1359147 |
63 | + python3:any, |
64 | qt5-default, |
65 | qtbase5-dev, |
66 | qtbase5-private-dev, |
67 | |
68 | === added directory 'src/common' |
69 | === renamed file 'src/modules/Unity/Application/debughelpers.cpp' => 'src/common/debughelpers.cpp' |
70 | --- src/modules/Unity/Application/debughelpers.cpp 2014-07-25 15:29:20 +0000 |
71 | +++ src/common/debughelpers.cpp 2014-09-18 22:57:30 +0000 |
72 | @@ -17,22 +17,24 @@ |
73 | #include "debughelpers.h" |
74 | #include <QTouchEvent> |
75 | |
76 | +#include <mir_toolkit/event.h> |
77 | + |
78 | // Unity API |
79 | #include <unity/shell/application/ApplicationInfoInterface.h> |
80 | |
81 | -QString touchPointStateToString(Qt::TouchPointState state) |
82 | +const char *touchPointStateToString(Qt::TouchPointState state) |
83 | { |
84 | switch (state) { |
85 | case Qt::TouchPointPressed: |
86 | - return QString("pressed"); |
87 | + return "pressed"; |
88 | case Qt::TouchPointMoved: |
89 | - return QString("moved"); |
90 | + return "moved"; |
91 | case Qt::TouchPointStationary: |
92 | - return QString("stationary"); |
93 | + return "stationary"; |
94 | case Qt::TouchPointReleased: |
95 | - return QString("released"); |
96 | + return "released"; |
97 | default: |
98 | - return QString("UNKNOWN!"); |
99 | + return "UNKNOWN!"; |
100 | } |
101 | } |
102 | |
103 | @@ -174,6 +176,36 @@ |
104 | } |
105 | } |
106 | |
107 | +const char *mirMotionActionToStr(int value) |
108 | +{ |
109 | + switch (value) { |
110 | + case mir_motion_action_move: |
111 | + return "move"; |
112 | + case mir_motion_action_down: |
113 | + return "down"; |
114 | + case mir_motion_action_up: |
115 | + return "up"; |
116 | + case mir_motion_action_pointer_down: |
117 | + return "pointer_down"; |
118 | + case mir_motion_action_cancel: |
119 | + return "cancel"; |
120 | + case mir_motion_action_pointer_up: |
121 | + return "pointer_up"; |
122 | + case mir_motion_action_outside: |
123 | + return "outside"; |
124 | + case mir_motion_action_hover_move: |
125 | + return "hover_move"; |
126 | + case mir_motion_action_scroll: |
127 | + return "scroll"; |
128 | + case mir_motion_action_hover_enter: |
129 | + return "hover_enter"; |
130 | + case mir_motion_action_hover_exit: |
131 | + return "hover_exit"; |
132 | + default: |
133 | + return "???"; |
134 | + } |
135 | +} |
136 | + |
137 | using namespace unity::shell::application; |
138 | |
139 | const char *applicationStateToStr(int state) |
140 | |
141 | === renamed file 'src/modules/Unity/Application/debughelpers.h' => 'src/common/debughelpers.h' |
142 | --- src/modules/Unity/Application/debughelpers.h 2014-07-25 15:29:20 +0000 |
143 | +++ src/common/debughelpers.h 2014-09-18 22:57:30 +0000 |
144 | @@ -23,7 +23,7 @@ |
145 | |
146 | class QTouchEvent; |
147 | |
148 | -QString touchPointStateToString(Qt::TouchPointState state); |
149 | +const char *touchPointStateToString(Qt::TouchPointState state); |
150 | QString touchEventToString(const QTouchEvent *ev); |
151 | |
152 | QString mirSurfaceAttribAndValueToString(MirSurfaceAttrib attrib, int value); |
153 | @@ -31,6 +31,7 @@ |
154 | const char *mirSurfaceStateToStr(int value); |
155 | const char *mirSurfaceFocusStateToStr(int value); |
156 | const char *mirSurfaceVisibilityToStr(int value); |
157 | +const char *mirMotionActionToStr(int value); |
158 | |
159 | const char *applicationStateToStr(int state); |
160 | |
161 | |
162 | === added file 'src/lttng-compiler.pri' |
163 | --- src/lttng-compiler.pri 1970-01-01 00:00:00 +0000 |
164 | +++ src/lttng-compiler.pri 2014-09-18 22:57:30 +0000 |
165 | @@ -0,0 +1,25 @@ |
166 | +# Add extra compiler to handle LTTng TP files |
167 | +# Append the files to the LTTNG_TP_FILES list |
168 | + |
169 | +# Note by Gerry (Aug 2014) - I tried to have lttng-gen-tp generate an object file but it failed to link with |
170 | +# the shared library we want. If there's a way to pass -fPIC to lttng-gen-tp, this workaround can be avoided |
171 | +QMAKE_EXTRA_COMPILERS += lttng_gen_tp_header |
172 | +lttng_gen_tp_header.name = "Generating headers .TP files and adding to HEADERS list" |
173 | +lttng_gen_tp_header.input = LTTNG_TP_FILES |
174 | +lttng_gen_tp_header.output = $${OUT_PWD}/${QMAKE_FILE_BASE}.h |
175 | +lttng_gen_tp_header.commands = lttng-gen-tp -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} |
176 | +lttng_gen_tp_header.dependency_type = TYPE_H |
177 | +lttng_gen_tp_header.variable_out = HEADERS #appends the generated file name to the HEADERS list |
178 | +lttng_gen_tp_header.CONFIG = no_link target_predeps |
179 | + |
180 | +QMAKE_EXTRA_COMPILERS += lttng_gen_tp_sources |
181 | +lttng_gen_tp_sources.name = "Generating sources from .TP files and adding to SOURCES list" |
182 | +lttng_gen_tp_sources.input = LTTNG_TP_FILES |
183 | +lttng_gen_tp_sources.output = $${OUT_PWD}/${QMAKE_FILE_BASE}.c |
184 | +lttng_gen_tp_sources.commands = lttng-gen-tp -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} |
185 | +lttng_gen_tp_sources.dependency_type = TYPE_C |
186 | +lttng_gen_tp_sources.variable_out = SOURCES #appends the generated file name to the SOURCES list |
187 | +lttng_gen_tp_sources.CONFIG = no_link target_predeps |
188 | + |
189 | +CONFIG += link_pkgconfig |
190 | +PKGCONFIG += lttng-ust |
191 | |
192 | === modified file 'src/modules/Unity/Application/Application.pro' |
193 | --- src/modules/Unity/Application/Application.pro 2014-08-29 11:15:51 +0000 |
194 | +++ src/modules/Unity/Application/Application.pro 2014-09-18 22:57:30 +0000 |
195 | @@ -1,3 +1,5 @@ |
196 | +include(../../../lttng-compiler.pri) |
197 | + |
198 | TARGET = unityapplicationplugin |
199 | TEMPLATE = lib |
200 | |
201 | @@ -10,9 +12,9 @@ |
202 | QMAKE_CXXFLAGS = -std=c++11 -Werror -Wall |
203 | QMAKE_LFLAGS = -std=c++11 -Wl,-no-undefined |
204 | |
205 | -PKGCONFIG += mirserver glib-2.0 process-cpp ubuntu-app-launch-2 |
206 | +PKGCONFIG += mirserver glib-2.0 gio-unix-2.0 process-cpp ubuntu-app-launch-2 |
207 | |
208 | -INCLUDEPATH += ../../../platforms/mirserver |
209 | +INCLUDEPATH += ../../../platforms/mirserver ../../../common |
210 | LIBS += -L../../../platforms/mirserver -lqpa-mirserver |
211 | QMAKE_RPATHDIR += $$[QT_INSTALL_PLUGINS]/platforms # where libqpa-mirserver.so is installed |
212 | |
213 | @@ -24,7 +26,7 @@ |
214 | |
215 | SOURCES += application_manager.cpp \ |
216 | application.cpp \ |
217 | - debughelpers.cpp \ |
218 | + ../../../common/debughelpers.cpp \ |
219 | desktopfilereader.cpp \ |
220 | plugin.cpp \ |
221 | applicationscreenshotprovider.cpp \ |
222 | @@ -44,7 +46,7 @@ |
223 | HEADERS += application_manager.h \ |
224 | applicationcontroller.h \ |
225 | application.h \ |
226 | - debughelpers.h \ |
227 | + ../../../common/debughelpers.h \ |
228 | desktopfilereader.h \ |
229 | applicationscreenshotprovider.h \ |
230 | dbuswindowstack.h \ |
231 | @@ -61,8 +63,12 @@ |
232 | processcontroller.h \ |
233 | proc_info.h \ |
234 | session.h \ |
235 | + session_interface.h \ |
236 | sessionmodel.h \ |
237 | - upstart/applicationcontroller.h |
238 | + upstart/applicationcontroller.h \ |
239 | + gscopedpointer.h |
240 | + |
241 | +LTTNG_TP_FILES += tracepoints.tp |
242 | |
243 | installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) |
244 | |
245 | |
246 | === modified file 'src/modules/Unity/Application/application.cpp' |
247 | --- src/modules/Unity/Application/application.cpp 2014-09-15 19:06:47 +0000 |
248 | +++ src/modules/Unity/Application/application.cpp 2014-09-18 22:57:30 +0000 |
249 | @@ -17,11 +17,13 @@ |
250 | // local |
251 | #include "application.h" |
252 | #include "application_manager.h" |
253 | -#include "debughelpers.h" |
254 | #include "desktopfilereader.h" |
255 | #include "session.h" |
256 | #include "taskcontroller.h" |
257 | |
258 | +// common |
259 | +#include <debughelpers.h> |
260 | + |
261 | // QPA mirserver |
262 | #include "logging.h" |
263 | |
264 | @@ -256,9 +258,9 @@ |
265 | m_session->setApplication(this); |
266 | m_session->setState(state()); |
267 | |
268 | - connect(m_session, &Session::suspended, this, &Application::onSessionSuspended); |
269 | - connect(m_session, &Session::resumed, this, &Application::onSessionResumed); |
270 | - connect(m_session, &Session::fullscreenChanged, this, &Application::fullscreenChanged); |
271 | + connect(m_session, &SessionInterface::suspended, this, &Application::onSessionSuspended); |
272 | + connect(m_session, &SessionInterface::resumed, this, &Application::onSessionResumed); |
273 | + connect(m_session, &SessionInterface::fullscreenChanged, this, &Application::fullscreenChanged); |
274 | |
275 | if (oldFullscreen != fullscreen()) |
276 | Q_EMIT fullscreenChanged(fullscreen()); |
277 | |
278 | === modified file 'src/modules/Unity/Application/application.h' |
279 | --- src/modules/Unity/Application/application.h 2014-09-08 21:42:56 +0000 |
280 | +++ src/modules/Unity/Application/application.h 2014-09-18 22:57:30 +0000 |
281 | @@ -21,6 +21,7 @@ |
282 | #include <memory> |
283 | |
284 | //Qt |
285 | +#include <QColor> |
286 | #include <QtCore/QtCore> |
287 | #include <QImage> |
288 | #include <QSharedPointer> |
289 | @@ -82,12 +83,12 @@ |
290 | Stage stage() const override; |
291 | State state() const override; |
292 | bool focused() const override; |
293 | - QString splashTitle() const override; |
294 | - QUrl splashImage() const override; |
295 | - bool splashShowHeader() const override; |
296 | - QColor splashColor() const override; |
297 | - QColor splashColorHeader() const override; |
298 | - QColor splashColorFooter() const override; |
299 | + QString splashTitle() const; |
300 | + QUrl splashImage() const; |
301 | + bool splashShowHeader() const; |
302 | + QColor splashColor() const; |
303 | + QColor splashColorHeader() const; |
304 | + QColor splashColorFooter() const; |
305 | |
306 | void setStage(Stage stage); |
307 | void setState(State state); |
308 | |
309 | === modified file 'src/modules/Unity/Application/application_manager.cpp' |
310 | --- src/modules/Unity/Application/application_manager.cpp 2014-09-08 21:05:15 +0000 |
311 | +++ src/modules/Unity/Application/application_manager.cpp 2014-09-18 22:57:30 +0000 |
312 | @@ -23,7 +23,7 @@ |
313 | #include "proc_info.h" |
314 | #include "taskcontroller.h" |
315 | #include "upstart/applicationcontroller.h" |
316 | - |
317 | +#include "tracepoints.h" // generated from tracepoints.tp |
318 | |
319 | // mirserver |
320 | #include "mirserverconfiguration.h" |
321 | @@ -424,6 +424,7 @@ |
322 | Application *ApplicationManager::startApplication(const QString &inputAppId, ExecFlags flags, |
323 | const QStringList &arguments) |
324 | { |
325 | + tracepoint(qtmir, startApplication); |
326 | QString appId = toShortAppIdIfPossible(inputAppId); |
327 | qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::startApplication - this=" << this << "appId" << qPrintable(appId); |
328 | |
329 | @@ -461,6 +462,7 @@ |
330 | |
331 | void ApplicationManager::onProcessStarting(const QString &appId) |
332 | { |
333 | + tracepoint(qtmir, onProcessStarting); |
334 | qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onProcessStarting - appId=" << appId; |
335 | |
336 | Application *application = findApplication(appId); |
337 | @@ -562,6 +564,7 @@ |
338 | |
339 | void ApplicationManager::onProcessStopped(const QString &appId) |
340 | { |
341 | + tracepoint(qtmir, onProcessStopped); |
342 | qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onProcessStopped - appId=" << appId; |
343 | Application *application = findApplication(appId); |
344 | |
345 | @@ -637,16 +640,21 @@ |
346 | |
347 | void ApplicationManager::authorizeSession(const quint64 pid, bool &authorized) |
348 | { |
349 | + tracepoint(qtmir, authorizeSession); |
350 | authorized = false; //to be proven wrong |
351 | |
352 | qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::authorizeSession - pid=" << pid; |
353 | |
354 | for (Application *app : m_applications) { |
355 | - if (app->state() == Application::Starting |
356 | - && m_taskController->appIdHasProcessId(app->appId(), pid)) { |
357 | - app->setPid(pid); |
358 | - authorized = true; |
359 | - return; |
360 | + if (app->state() == Application::Starting) { |
361 | + tracepoint(qtmir, appIdHasProcessId_start); |
362 | + if (m_taskController->appIdHasProcessId(app->appId(), pid)) { |
363 | + app->setPid(pid); |
364 | + authorized = true; |
365 | + tracepoint(qtmir, appIdHasProcessId_end, 1); //found |
366 | + return; |
367 | + } |
368 | + tracepoint(qtmir, appIdHasProcessId_end, 0); // not found |
369 | } |
370 | } |
371 | |
372 | |
373 | === modified file 'src/modules/Unity/Application/desktopfilereader.cpp' |
374 | --- src/modules/Unity/Application/desktopfilereader.cpp 2014-08-07 18:15:45 +0000 |
375 | +++ src/modules/Unity/Application/desktopfilereader.cpp 2014-09-18 22:57:30 +0000 |
376 | @@ -16,142 +16,192 @@ |
377 | |
378 | // local |
379 | #include "desktopfilereader.h" |
380 | +#include "gscopedpointer.h" |
381 | #include "logging.h" |
382 | |
383 | // Qt |
384 | #include <QFile> |
385 | +#include <QLocale> |
386 | + |
387 | +// GIO |
388 | +#include <gio/gdesktopappinfo.h> |
389 | |
390 | namespace qtmir |
391 | { |
392 | |
393 | -DesktopFileReader::Factory::Factory() |
394 | -{ |
395 | -} |
396 | - |
397 | -DesktopFileReader::Factory::~Factory() |
398 | -{ |
399 | -} |
400 | |
401 | DesktopFileReader* DesktopFileReader::Factory::createInstance(const QString &appId, const QFileInfo& fi) |
402 | { |
403 | return new DesktopFileReader(appId, fi); |
404 | } |
405 | |
406 | -// Retrieves the size of an array at compile time. |
407 | -#define ARRAY_SIZE(a) \ |
408 | - ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) |
409 | +typedef GObjectScopedPointer<GAppInfo> GAppInfoPointer; |
410 | + |
411 | +struct DesktopFileReaderPrivate |
412 | +{ |
413 | + DesktopFileReaderPrivate(DesktopFileReader *parent): |
414 | + q_ptr( parent ) |
415 | + {} |
416 | + |
417 | + QString getKey(const char *key) const |
418 | + { |
419 | + if (!loaded()) return QString(); |
420 | + |
421 | + return QString::fromUtf8(g_desktop_app_info_get_string((GDesktopAppInfo*)appInfo.data(), key)); |
422 | + } |
423 | + |
424 | + bool loaded() const |
425 | + { |
426 | + return !appInfo.isNull(); |
427 | + } |
428 | + |
429 | + DesktopFileReader * const q_ptr; |
430 | + Q_DECLARE_PUBLIC(DesktopFileReader) |
431 | + |
432 | + QString appId; |
433 | + QString file; |
434 | + GAppInfoPointer appInfo; // GAppInfo is actually implemented by GDesktopAppInfo |
435 | +}; |
436 | + |
437 | |
438 | DesktopFileReader::DesktopFileReader(const QString &appId, const QFileInfo &desktopFile) |
439 | - : appId_(appId) |
440 | - , entries_(DesktopFileReader::kNumberOfEntries, "") |
441 | + : d_ptr(new DesktopFileReaderPrivate(this)) |
442 | { |
443 | qCDebug(QTMIR_APPLICATIONS) << "DesktopFileReader::DesktopFileReader - this=" << this << "appId=" << appId; |
444 | - |
445 | - file_ = desktopFile.absoluteFilePath(); |
446 | - loaded_ = loadDesktopFile(file_); |
447 | + Q_D(DesktopFileReader); |
448 | + |
449 | + d->appId = appId; |
450 | + d->file = desktopFile.absoluteFilePath(); |
451 | + d->appInfo.reset((GAppInfo*) g_desktop_app_info_new_from_filename(d->file.toUtf8().constData())); |
452 | + |
453 | + if (!d->loaded()) { |
454 | + qWarning() << "Desktop file for appId:" << appId << "at:" << d->file << "does not exist, or is not valid"; |
455 | + } |
456 | } |
457 | |
458 | DesktopFileReader::~DesktopFileReader() |
459 | { |
460 | - qCDebug(QTMIR_APPLICATIONS) << "DesktopFileReader::~DesktopFileReader"; |
461 | - entries_.clear(); |
462 | -} |
463 | - |
464 | -bool DesktopFileReader::loadDesktopFile(QString desktopFile) |
465 | -{ |
466 | - qCDebug(QTMIR_APPLICATIONS) << "DesktopFileReader::loadDesktopFile - this=" << this << "desktopFile=" << desktopFile; |
467 | - |
468 | - if (this->file().isNull() || this->file().isEmpty()) { |
469 | - qCritical() << "No desktop file found for appId:" << appId_; |
470 | - return false; |
471 | - } |
472 | - |
473 | - Q_ASSERT(desktopFile != NULL); |
474 | - const struct { const char* const name; int size; unsigned int flag; } kEntryNames[] = { |
475 | - { "Name=", sizeof("Name=") - 1, 1 << DesktopFileReader::kNameIndex }, |
476 | - { "Comment=", sizeof("Comment=") - 1, 1 << DesktopFileReader::kCommentIndex }, |
477 | - { "Icon=", sizeof("Icon=") - 1, 1 << DesktopFileReader::kIconIndex }, |
478 | - { "Exec=", sizeof("Exec=") - 1, 1 << DesktopFileReader::kExecIndex }, |
479 | - { "Path=", sizeof("Path=") - 1, 1 << DesktopFileReader::kPathIndex }, |
480 | - { "X-Ubuntu-StageHint=", sizeof("X-Ubuntu-StageHint=") - 1, 1 << DesktopFileReader::kStageHintIndex }, |
481 | - { "X-Ubuntu-Splash-Title=", sizeof("X-Ubuntu-Splash-Title=") - 1, 1 << DesktopFileReader::kSplashTitleIndex }, |
482 | - { "X-Ubuntu-Splash-Image=", sizeof("X-Ubuntu-Splash-Image=") - 1, 1 << DesktopFileReader::kSplashImageIndex }, |
483 | - { "X-Ubuntu-Splash-Show-Header=", sizeof("X-Ubuntu-Splash-Show-Header=") - 1, 1 << DesktopFileReader::kSplashShowHeaderIndex }, |
484 | - { "X-Ubuntu-Splash-Color=", sizeof("X-Ubuntu-Splash-Color=") - 1, 1 << DesktopFileReader::kSplashColorIndex }, |
485 | - { "X-Ubuntu-Splash-Color-Header=", sizeof("X-Ubuntu-Splash-Color-Header=") - 1, 1 << DesktopFileReader::kSplashColorHeaderIndex }, |
486 | - { "X-Ubuntu-Splash-Color-Footer=", sizeof("X-Ubuntu-Splash-Color-Footer=") - 1, 1 << DesktopFileReader::kSplashColorFooterIndex } |
487 | - }; |
488 | - const unsigned int kAllEntriesMask = |
489 | - (1 << DesktopFileReader::kNameIndex) | (1 << DesktopFileReader::kCommentIndex) |
490 | - | (1 << DesktopFileReader::kIconIndex) | (1 << DesktopFileReader::kExecIndex) |
491 | - | (1 << DesktopFileReader::kPathIndex) | (1 << DesktopFileReader::kStageHintIndex) |
492 | - | (1 << DesktopFileReader::kSplashTitleIndex) | (1 << DesktopFileReader::kSplashImageIndex) |
493 | - | (1 << DesktopFileReader::kSplashShowHeaderIndex) | (1 << DesktopFileReader::kSplashColorIndex) |
494 | - | (1 << DesktopFileReader::kSplashColorHeaderIndex) | (1 << DesktopFileReader::kSplashColorFooterIndex); |
495 | - const unsigned int kMandatoryEntriesMask = |
496 | - (1 << DesktopFileReader::kNameIndex) | (1 << DesktopFileReader::kIconIndex) |
497 | - | (1 << DesktopFileReader::kExecIndex); |
498 | - const int kEntriesCount = ARRAY_SIZE(kEntryNames); |
499 | - const int kBufferSize = 256; |
500 | - static char buffer[kBufferSize]; |
501 | - QFile file(desktopFile); |
502 | - |
503 | - // Open file. |
504 | - if (!file.open(QFile::ReadOnly | QIODevice::Text)) { |
505 | - qWarning() << "Can't open file:" << file.errorString(); |
506 | - return false; |
507 | - } |
508 | - |
509 | - // Validate "magic key" (standard group header). |
510 | - if (file.readLine(buffer, kBufferSize) != -1) { |
511 | - if (strncmp(buffer, "[Desktop Entry]", sizeof("[Desktop Entry]") - 1)) { |
512 | - qWarning() << "not a desktop file, unable to read it"; |
513 | - return false; |
514 | - } |
515 | - } |
516 | - |
517 | - int length; |
518 | - unsigned int entryFlags = 0; |
519 | - while ((length = file.readLine(buffer, kBufferSize)) != -1) { |
520 | - // Skip empty lines. |
521 | - if (length > 1) { |
522 | - // Stop when reaching unsupported next group header. |
523 | - if (buffer[0] == '[') { |
524 | - qWarning() << "reached next group header, leaving loop"; |
525 | - break; |
526 | - } |
527 | - // Lookup entries ignoring duplicates if any. |
528 | - for (int i = 0; i < kEntriesCount; i++) { |
529 | - if (!strncmp(buffer, kEntryNames[i].name, kEntryNames[i].size)) { |
530 | - if (~entryFlags & kEntryNames[i].flag) { |
531 | - buffer[length-1] = '\0'; |
532 | - entries_[i] = QString::fromUtf8(&buffer[kEntryNames[i].size]); |
533 | - entryFlags |= kEntryNames[i].flag; |
534 | - break; |
535 | - } |
536 | - } |
537 | - } |
538 | - // Stop when matching the right number of entries. |
539 | - if (entryFlags == kAllEntriesMask) { |
540 | - break; |
541 | - } |
542 | - } |
543 | - } |
544 | - |
545 | - // Check that the mandatory entries are set. |
546 | - if ((entryFlags & kMandatoryEntriesMask) == kMandatoryEntriesMask) { |
547 | - qDebug("loaded desktop file with name='%s', comment='%s', icon='%s', exec='%s', path='%s', stagehint='%s'", |
548 | - qPrintable(entries_[DesktopFileReader::kNameIndex]), |
549 | - qPrintable(entries_[DesktopFileReader::kCommentIndex]), |
550 | - qPrintable(entries_[DesktopFileReader::kIconIndex]), |
551 | - qPrintable(entries_[DesktopFileReader::kExecIndex]), |
552 | - qPrintable(entries_[DesktopFileReader::kPathIndex]), |
553 | - qPrintable(entries_[DesktopFileReader::kStageHintIndex])); |
554 | - return true; |
555 | - } else { |
556 | - qWarning() << "not a valid desktop file, missing mandatory entries in the standard group header"; |
557 | - return false; |
558 | - } |
559 | + Q_D(const DesktopFileReader); |
560 | + qCDebug(QTMIR_APPLICATIONS) << "DesktopFileReader::~DesktopFileReader - this=" << this << "appId=" << d->appId; |
561 | + delete d_ptr; |
562 | +} |
563 | + |
564 | +QString DesktopFileReader::file() const |
565 | +{ |
566 | + Q_D(const DesktopFileReader); |
567 | + return d->file; |
568 | +} |
569 | + |
570 | +QString DesktopFileReader::appId() const |
571 | +{ |
572 | + Q_D(const DesktopFileReader); |
573 | + return d->appId; |
574 | +} |
575 | + |
576 | +QString DesktopFileReader::name() const |
577 | +{ |
578 | + Q_D(const DesktopFileReader); |
579 | + if (!d->loaded()) return QString(); |
580 | + |
581 | + return QString::fromUtf8(g_app_info_get_name(d->appInfo.data())); |
582 | +} |
583 | + |
584 | +QString DesktopFileReader::comment() const |
585 | +{ |
586 | + Q_D(const DesktopFileReader); |
587 | + if (!d->loaded()) return QString(); |
588 | + |
589 | + return QString::fromUtf8(g_app_info_get_description(d->appInfo.data())); |
590 | +} |
591 | + |
592 | +QString DesktopFileReader::icon() const |
593 | +{ |
594 | + Q_D(const DesktopFileReader); |
595 | + return d->getKey("Icon"); |
596 | +} |
597 | + |
598 | +QString DesktopFileReader::exec() const |
599 | +{ |
600 | + Q_D(const DesktopFileReader); |
601 | + if (!d->loaded()) return QString(); |
602 | + |
603 | + return QString::fromUtf8(g_app_info_get_commandline(d->appInfo.data())); |
604 | +} |
605 | + |
606 | +QString DesktopFileReader::path() const |
607 | +{ |
608 | + Q_D(const DesktopFileReader); |
609 | + return d->getKey("Path"); |
610 | +} |
611 | + |
612 | +QString DesktopFileReader::stageHint() const |
613 | +{ |
614 | + Q_D(const DesktopFileReader); |
615 | + return d->getKey("X-Ubuntu-StageHint"); |
616 | +} |
617 | + |
618 | +QString DesktopFileReader::splashTitle() const |
619 | +{ |
620 | + Q_D(const DesktopFileReader); |
621 | + if (!d->loaded()) return QString(); |
622 | + |
623 | + /* Sadly GDesktopAppInfo only considers Name, GenericName, Comments and Keywords to be keys |
624 | + * which can have locale-specific entries. So we need to work to make X-Ubuntu-Splash-Title |
625 | + * locale-aware, but generating a locale-correct key name and seeing if that exists. If yes, |
626 | + * get and return it. Else fallback to the non-localized key. |
627 | + */ |
628 | + GDesktopAppInfo *info = (GDesktopAppInfo*)d->appInfo.data(); |
629 | + QLocale defaultLocale; |
630 | + QStringList locales = defaultLocale.uiLanguages(); |
631 | + |
632 | + QString keyTemplate("X-Ubuntu-Splash-Title[%1]"); |
633 | + for (QString locale: locales) { |
634 | + // Desktop files use local specifiers with underscore separaters but Qt uses hyphens |
635 | + locale = locale.replace('-', '_'); |
636 | + const char* key = keyTemplate.arg(locale).toUtf8().constData(); |
637 | + if (g_desktop_app_info_has_key(info, key)) { |
638 | + return d->getKey(key); |
639 | + } |
640 | + } |
641 | + |
642 | + // Fallback to the non-localized string, if available |
643 | + return d->getKey("X-Ubuntu-Splash-Title"); |
644 | +} |
645 | + |
646 | +QString DesktopFileReader::splashImage() const |
647 | +{ |
648 | + Q_D(const DesktopFileReader); |
649 | + return d->getKey("X-Ubuntu-Splash-Image"); |
650 | +} |
651 | + |
652 | +QString DesktopFileReader::splashShowHeader() const |
653 | +{ |
654 | + Q_D(const DesktopFileReader); |
655 | + return d->getKey("X-Ubuntu-Splash-Show-Header"); |
656 | +} |
657 | + |
658 | +QString DesktopFileReader::splashColor() const |
659 | +{ |
660 | + Q_D(const DesktopFileReader); |
661 | + return d->getKey("X-Ubuntu-Splash-Color"); |
662 | +} |
663 | + |
664 | +QString DesktopFileReader::splashColorHeader() const |
665 | +{ |
666 | + Q_D(const DesktopFileReader); |
667 | + return d->getKey("X-Ubuntu-Splash-Color-Header"); |
668 | +} |
669 | + |
670 | +QString DesktopFileReader::splashColorFooter() const |
671 | +{ |
672 | + Q_D(const DesktopFileReader); |
673 | + return d->getKey("X-Ubuntu-Splash-Color-Footer"); |
674 | +} |
675 | + |
676 | +bool DesktopFileReader::loaded() const |
677 | +{ |
678 | + Q_D(const DesktopFileReader); |
679 | + return d->loaded(); |
680 | } |
681 | |
682 | } // namespace qtmir |
683 | |
684 | === modified file 'src/modules/Unity/Application/desktopfilereader.h' |
685 | --- src/modules/Unity/Application/desktopfilereader.h 2014-08-07 18:15:45 +0000 |
686 | +++ src/modules/Unity/Application/desktopfilereader.h 2014-09-18 22:57:30 +0000 |
687 | @@ -18,20 +18,19 @@ |
688 | #define DESKTOPFILEREADER_H |
689 | |
690 | #include <QString> |
691 | -#include <QVector> |
692 | #include <QFileInfo> |
693 | |
694 | namespace qtmir |
695 | { |
696 | |
697 | +class DesktopFileReaderPrivate; |
698 | class DesktopFileReader { |
699 | public: |
700 | class Factory |
701 | { |
702 | public: |
703 | - Factory(); |
704 | + Factory() = default; |
705 | Factory(const Factory&) = delete; |
706 | - virtual ~Factory(); |
707 | |
708 | Factory& operator=(const Factory&) = delete; |
709 | |
710 | @@ -40,48 +39,31 @@ |
711 | |
712 | virtual ~DesktopFileReader(); |
713 | |
714 | - virtual QString file() const { return file_; } |
715 | - virtual QString appId() const { return appId_; } |
716 | - virtual QString name() const { return entries_[kNameIndex]; } |
717 | - virtual QString comment() const { return entries_[kCommentIndex]; } |
718 | - virtual QString icon() const { return entries_[kIconIndex]; } |
719 | - virtual QString exec() const { return entries_[kExecIndex]; } |
720 | - virtual QString path() const { return entries_[kPathIndex]; } |
721 | - virtual QString stageHint() const { return entries_[kStageHintIndex]; } |
722 | - virtual QString splashTitle() const { return entries_[kSplashTitleIndex]; } |
723 | - virtual QString splashImage() const { return entries_[kSplashImageIndex]; } |
724 | - virtual QString splashShowHeader() const { return entries_[kSplashShowHeaderIndex]; } |
725 | - virtual QString splashColor() const { return entries_[kSplashColorIndex]; } |
726 | - virtual QString splashColorHeader() const { return entries_[kSplashColorHeaderIndex]; } |
727 | - virtual QString splashColorFooter() const { return entries_[kSplashColorFooterIndex]; } |
728 | - virtual bool loaded() const { return loaded_; } |
729 | + virtual QString file() const; |
730 | + virtual QString appId() const; |
731 | + virtual QString name() const; |
732 | + virtual QString comment() const; |
733 | + virtual QString icon() const; |
734 | + virtual QString exec() const; |
735 | + virtual QString path() const; |
736 | + virtual QString stageHint() const; |
737 | + virtual QString splashTitle() const; |
738 | + virtual QString splashImage() const; |
739 | + virtual QString splashShowHeader() const; |
740 | + virtual QString splashColor() const; |
741 | + virtual QString splashColorHeader() const; |
742 | + virtual QString splashColorFooter() const; |
743 | + virtual bool loaded() const; |
744 | |
745 | protected: |
746 | + DesktopFileReader(const QString &appId, const QFileInfo &desktopFile); |
747 | + |
748 | + DesktopFileReaderPrivate * const d_ptr; |
749 | + |
750 | friend class DesktopFileReaderFactory; |
751 | |
752 | - DesktopFileReader(const QString &appId, const QFileInfo &desktopFile); |
753 | - |
754 | private: |
755 | - static const int kNameIndex = 0, |
756 | - kCommentIndex = 1, |
757 | - kIconIndex = 2, |
758 | - kExecIndex = 3, |
759 | - kPathIndex = 4, |
760 | - kStageHintIndex = 5, |
761 | - kSplashTitleIndex = 6, |
762 | - kSplashImageIndex = 7, |
763 | - kSplashShowHeaderIndex = 8, |
764 | - kSplashColorIndex = 9, |
765 | - kSplashColorHeaderIndex = 10, |
766 | - kSplashColorFooterIndex = 11, |
767 | - kNumberOfEntries = 12; |
768 | - |
769 | - virtual bool loadDesktopFile(QString desktopFile); |
770 | - |
771 | - QString appId_; |
772 | - QString file_; |
773 | - QVector<QString> entries_; |
774 | - bool loaded_; |
775 | + Q_DECLARE_PRIVATE(DesktopFileReader) |
776 | }; |
777 | |
778 | } // namespace qtmir |
779 | |
780 | === added file 'src/modules/Unity/Application/gscopedpointer.h' |
781 | --- src/modules/Unity/Application/gscopedpointer.h 1970-01-01 00:00:00 +0000 |
782 | +++ src/modules/Unity/Application/gscopedpointer.h 2014-09-18 22:57:30 +0000 |
783 | @@ -0,0 +1,113 @@ |
784 | +/* |
785 | + * Copyright (C) 2011-2014 Canonical, Ltd. |
786 | + * |
787 | + * This program is free software: you can redistribute it and/or modify it under |
788 | + * the terms of the GNU Lesser General Public License version 3, as published by |
789 | + * the Free Software Foundation. |
790 | + * |
791 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
792 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
793 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
794 | + * Lesser General Public License for more details. |
795 | + * |
796 | + * You should have received a copy of the GNU Lesser General Public License |
797 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
798 | + * |
799 | + * Authors: |
800 | + * - Aurélien Gâteau <aurelien.gateau@canonical.com> |
801 | + */ |
802 | + |
803 | +#ifndef GSCOPEDPOINTER_H |
804 | +#define GSCOPEDPOINTER_H |
805 | + |
806 | +// Local |
807 | + |
808 | +// Qt |
809 | +#include <QScopedPointer> |
810 | + |
811 | +// GLib |
812 | +#include <glib-object.h> |
813 | + |
814 | +/** |
815 | + * Helper class for GScopedPointer |
816 | + */ |
817 | +template <class T, void (*cleanup_fcn)(T*)> |
818 | +class GScopedPointerDeleter |
819 | +{ |
820 | +public: |
821 | + static void cleanup(T* ptr) |
822 | + { |
823 | + if (ptr) { |
824 | + cleanup_fcn(ptr); |
825 | + } |
826 | + } |
827 | +}; |
828 | + |
829 | +/** |
830 | + * A GScopedPointer works like a QScopedPointer, except the cleanup static |
831 | + * method is replaced with a cleanup function, making it useful to handle C |
832 | + * structs whose cleanup function prototype is "void cleanup(T*)" |
833 | + * |
834 | + * Best way to use it is to define a typedef for your C struct, like this: |
835 | + * |
836 | + * typedef GScopedPointer<Foo, foo_free> GFooPointer; |
837 | + */ |
838 | +template <class T, void (*cleanup)(T*)> |
839 | +class GScopedPointer : public QScopedPointer<T, GScopedPointerDeleter<T, cleanup> > |
840 | +{ |
841 | +public: |
842 | + GScopedPointer(T* ptr = 0) |
843 | + : QScopedPointer<T, GScopedPointerDeleter<T, cleanup> >(ptr) |
844 | + {} |
845 | +}; |
846 | + |
847 | + |
848 | +/** |
849 | + * Helper class for GObjectScopedPointer |
850 | + */ |
851 | +template <class T, void (*cleanup_fcn)(gpointer)> |
852 | +class GObjectScopedPointerDeleter |
853 | +{ |
854 | +public: |
855 | + static void cleanup(T* ptr) |
856 | + { |
857 | + if (ptr) { |
858 | + cleanup_fcn(ptr); |
859 | + } |
860 | + } |
861 | +}; |
862 | + |
863 | +/** |
864 | + * A GObjectScopedPointer is similar to a GScopedPointer. The only difference |
865 | + * is its cleanup function signature is "void cleanup(gpointer)" and defaults to |
866 | + * g_object_unref(), making it useful for GObject-based classes. |
867 | + * |
868 | + * You can use it directly like this: |
869 | + * |
870 | + * GObjectScopedPointer<GFoo> foo; |
871 | + * |
872 | + * Or define a typedef for your class: |
873 | + * |
874 | + * typedef GObjectScopedPointer<GFoo> GFooPointer; |
875 | + * |
876 | + * Note: GObjectScopedPointer does *not* call gobject_ref() when assigned a |
877 | + * pointer. |
878 | + */ |
879 | +template <class T, void (*cleanup)(gpointer) = g_object_unref> |
880 | +class GObjectScopedPointer : public QScopedPointer<T, GObjectScopedPointerDeleter<T, cleanup> > |
881 | +{ |
882 | +public: |
883 | + GObjectScopedPointer(T* ptr = 0) |
884 | + : QScopedPointer<T, GObjectScopedPointerDeleter<T, cleanup> >(ptr) |
885 | + {} |
886 | +}; |
887 | + |
888 | +// A Generic GObject pointer |
889 | +typedef GObjectScopedPointer<GObject> GObjectPointer; |
890 | + |
891 | +// Take advantage of the cleanup signature of GObjectScopedPointer to define |
892 | +// a GCharPointer |
893 | +typedef GObjectScopedPointer<gchar, g_free> GCharPointer; |
894 | + |
895 | +#endif /* GSCOPEDPOINTER_H */ |
896 | + |
897 | |
898 | === modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp' |
899 | --- src/modules/Unity/Application/mirsurfaceitem.cpp 2014-08-29 14:58:07 +0000 |
900 | +++ src/modules/Unity/Application/mirsurfaceitem.cpp 2014-09-18 22:57:30 +0000 |
901 | @@ -20,12 +20,14 @@ |
902 | |
903 | // local |
904 | #include "application.h" |
905 | -#include "debughelpers.h" |
906 | #include "mirbuffersgtexture.h" |
907 | #include "session.h" |
908 | #include "mirsurfaceitem.h" |
909 | #include "logging.h" |
910 | |
911 | +// common |
912 | +#include <debughelpers.h> |
913 | + |
914 | // Qt |
915 | #include <QDebug> |
916 | #include <QQmlEngine> |
917 | @@ -85,7 +87,10 @@ |
918 | return true; |
919 | } |
920 | |
921 | -bool fillInMirEvent(MirEvent &mirEvent, QTouchEvent *qtEvent) |
922 | +bool fillInMirEvent(MirEvent &mirEvent, |
923 | + const QList<QTouchEvent::TouchPoint> &qtTouchPoints, |
924 | + Qt::TouchPointStates qtTouchPointStates, |
925 | + ulong qtTimestamp) |
926 | { |
927 | mirEvent.type = mir_event_type_motion; |
928 | |
929 | @@ -97,14 +102,14 @@ |
930 | // NB: it's assumed that touch points are pressed and released |
931 | // one at a time. |
932 | |
933 | - if (qtEvent->touchPointStates().testFlag(Qt::TouchPointPressed)) { |
934 | - if (qtEvent->touchPoints().count() > 1) { |
935 | + if (qtTouchPointStates.testFlag(Qt::TouchPointPressed)) { |
936 | + if (qtTouchPoints.count() > 1) { |
937 | mirEvent.motion.action = mir_motion_action_pointer_down; |
938 | } else { |
939 | mirEvent.motion.action = mir_motion_action_down; |
940 | } |
941 | - } else if (qtEvent->touchPointStates().testFlag(Qt::TouchPointReleased)) { |
942 | - if (qtEvent->touchPoints().count() > 1) { |
943 | + } else if (qtTouchPointStates.testFlag(Qt::TouchPointReleased)) { |
944 | + if (qtTouchPoints.count() > 1) { |
945 | mirEvent.motion.action = mir_motion_action_pointer_up; |
946 | } else { |
947 | mirEvent.motion.action = mir_motion_action_up; |
948 | @@ -136,18 +141,17 @@ |
949 | |
950 | // Note: QtEventFeeder scales the event time down, scale it back up - precision is |
951 | // lost but the time difference should still be accurate to milliseconds |
952 | - mirEvent.motion.event_time = static_cast<nsecs_t>(qtEvent->timestamp()) * 1000000; |
953 | - |
954 | - mirEvent.motion.pointer_count = qtEvent->touchPoints().count(); |
955 | - |
956 | - auto touchPoints = qtEvent->touchPoints(); |
957 | - for (int i = 0; i < touchPoints.count(); ++i) { |
958 | - auto touchPoint = touchPoints.at(i); |
959 | + mirEvent.motion.event_time = static_cast<nsecs_t>(qtTimestamp) * 1000000; |
960 | + |
961 | + mirEvent.motion.pointer_count = qtTouchPoints.count(); |
962 | + |
963 | + for (int i = 0; i < qtTouchPoints.count(); ++i) { |
964 | + auto touchPoint = qtTouchPoints.at(i); |
965 | auto &pointer = mirEvent.motion.pointer_coordinates[i]; |
966 | |
967 | // FIXME: https://bugs.launchpad.net/mir/+bug/1311699 |
968 | // When multiple touch points are transmitted with a MirEvent |
969 | - // and one of them (only one is allowed) indicates a pressed |
970 | + // and one of them (only one is allowed) indicates a presse |
971 | // state change the index is encoded in the second byte of the |
972 | // action value. |
973 | const int mir_motion_event_pointer_index_shift = 8; |
974 | @@ -232,7 +236,7 @@ |
975 | UbuntuKeyboardInfo *MirSurfaceItem::m_ubuntuKeyboardInfo = nullptr; |
976 | |
977 | MirSurfaceItem::MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface, |
978 | - QPointer<Session> session, |
979 | + SessionInterface* session, |
980 | QQuickItem *parent) |
981 | : QQuickItem(parent) |
982 | , m_surface(surface) |
983 | @@ -240,6 +244,7 @@ |
984 | , m_firstFrameDrawn(false) |
985 | , m_live(true) |
986 | , m_textureProvider(nullptr) |
987 | + , m_lastTouchEvent(nullptr) |
988 | { |
989 | qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::MirSurfaceItem"; |
990 | |
991 | @@ -314,6 +319,8 @@ |
992 | m_surface->remove_observer(m_surfaceObserver); |
993 | if (m_textureProvider) |
994 | m_textureProvider->deleteLater(); |
995 | + |
996 | + delete m_lastTouchEvent; |
997 | } |
998 | |
999 | // For QML to destroy this surface |
1000 | @@ -327,7 +334,7 @@ |
1001 | deleteLater(); |
1002 | } |
1003 | |
1004 | -Session* MirSurfaceItem::session() const |
1005 | +SessionInterface* MirSurfaceItem::session() const |
1006 | { |
1007 | return m_session.data(); |
1008 | } |
1009 | @@ -476,31 +483,115 @@ |
1010 | } |
1011 | } |
1012 | |
1013 | +QString MirSurfaceItem::appId() const |
1014 | +{ |
1015 | + QString appId; |
1016 | + if (session() && session()->application()) { |
1017 | + appId = session()->application()->appId(); |
1018 | + } else { |
1019 | + appId.append("-"); |
1020 | + } |
1021 | + return appId; |
1022 | +} |
1023 | + |
1024 | +void MirSurfaceItem::endCurrentTouchSequence(ulong timestamp) |
1025 | +{ |
1026 | + MirEvent mirEvent; |
1027 | + |
1028 | + Q_ASSERT(m_lastTouchEvent); |
1029 | + Q_ASSERT(m_lastTouchEvent->type != QEvent::TouchEnd); |
1030 | + Q_ASSERT(m_lastTouchEvent->touchPoints.count() > 0); |
1031 | + |
1032 | + TouchEvent touchEvent = *m_lastTouchEvent; |
1033 | + touchEvent.timestamp = timestamp; |
1034 | + |
1035 | + // Remove all already released touch points |
1036 | + int i = 0; |
1037 | + while (i < touchEvent.touchPoints.count()) { |
1038 | + if (touchEvent.touchPoints[i].state() == Qt::TouchPointReleased) { |
1039 | + touchEvent.touchPoints.removeAt(i); |
1040 | + } else { |
1041 | + ++i; |
1042 | + } |
1043 | + } |
1044 | + |
1045 | + // And release the others one by one as Mir expects one press/release per event |
1046 | + while (touchEvent.touchPoints.count() > 0) { |
1047 | + touchEvent.touchPoints[0].setState(Qt::TouchPointReleased); |
1048 | + |
1049 | + touchEvent.updateTouchPointStatesAndType(); |
1050 | + |
1051 | + if (fillInMirEvent(mirEvent, touchEvent.touchPoints, |
1052 | + touchEvent.touchPointStates, touchEvent.timestamp)) { |
1053 | + m_surface->consume(mirEvent); |
1054 | + } |
1055 | + *m_lastTouchEvent = touchEvent; |
1056 | + |
1057 | + touchEvent.touchPoints.removeAt(0); |
1058 | + } |
1059 | +} |
1060 | + |
1061 | +void MirSurfaceItem::validateAndDeliverTouchEvent(int eventType, |
1062 | + ulong timestamp, |
1063 | + const QList<QTouchEvent::TouchPoint> &touchPoints, |
1064 | + Qt::TouchPointStates touchPointStates) |
1065 | +{ |
1066 | + MirEvent mirEvent; |
1067 | + |
1068 | + if (eventType == QEvent::TouchBegin && m_lastTouchEvent && m_lastTouchEvent->type != QEvent::TouchEnd) { |
1069 | + qCWarning(QTMIR_SURFACES) << qPrintable(QString("MirSurfaceItem(%1) - Got a QEvent::TouchBegin while " |
1070 | + "there's still an active/unfinished touch sequence.").arg(appId())); |
1071 | + // Qt forgot to end the last touch sequence. Let's do it ourselves. |
1072 | + endCurrentTouchSequence(timestamp); |
1073 | + } |
1074 | + |
1075 | + if (fillInMirEvent(mirEvent, touchPoints, touchPointStates, timestamp)) { |
1076 | + m_surface->consume(mirEvent); |
1077 | + } |
1078 | + |
1079 | + if (!m_lastTouchEvent) { |
1080 | + m_lastTouchEvent = new TouchEvent; |
1081 | + } |
1082 | + m_lastTouchEvent->type = eventType; |
1083 | + m_lastTouchEvent->timestamp = timestamp; |
1084 | + m_lastTouchEvent->touchPoints = touchPoints; |
1085 | + m_lastTouchEvent->touchPointStates = touchPointStates; |
1086 | +} |
1087 | + |
1088 | void MirSurfaceItem::touchEvent(QTouchEvent *event) |
1089 | { |
1090 | - MirEvent mirEvent; |
1091 | - if (type() == InputMethod && event->type() == QEvent::TouchBegin) { |
1092 | + bool accepted = processTouchEvent(event->type(), |
1093 | + event->timestamp(), |
1094 | + event->touchPoints(), |
1095 | + event->touchPointStates()); |
1096 | + event->setAccepted(accepted); |
1097 | +} |
1098 | + |
1099 | +bool MirSurfaceItem::processTouchEvent( |
1100 | + int eventType, |
1101 | + ulong timestamp, |
1102 | + const QList<QTouchEvent::TouchPoint> &touchPoints, |
1103 | + Qt::TouchPointStates touchPointStates) |
1104 | +{ |
1105 | + bool accepted = true; |
1106 | + if (type() == InputMethod && eventType == QEvent::TouchBegin) { |
1107 | // FIXME: Hack to get the VKB use case working while we don't have the proper solution in place. |
1108 | - if (hasTouchInsideUbuntuKeyboard(event)) { |
1109 | - if (fillInMirEvent(mirEvent, event)) { |
1110 | - m_surface->consume(mirEvent); |
1111 | - } |
1112 | + if (hasTouchInsideUbuntuKeyboard(touchPoints)) { |
1113 | + validateAndDeliverTouchEvent(eventType, timestamp, touchPoints, touchPointStates); |
1114 | } else { |
1115 | - event->ignore(); |
1116 | + accepted = false; |
1117 | } |
1118 | |
1119 | } else { |
1120 | // NB: If we are getting QEvent::TouchUpdate or QEvent::TouchEnd it's because we've |
1121 | // previously accepted the corresponding QEvent::TouchBegin |
1122 | - if (fillInMirEvent(mirEvent, event)) { |
1123 | - m_surface->consume(mirEvent); |
1124 | - } |
1125 | + validateAndDeliverTouchEvent(eventType, timestamp, touchPoints, touchPointStates); |
1126 | } |
1127 | + return accepted; |
1128 | } |
1129 | |
1130 | -bool MirSurfaceItem::hasTouchInsideUbuntuKeyboard(QTouchEvent *event) |
1131 | +bool MirSurfaceItem::hasTouchInsideUbuntuKeyboard(const QList<QTouchEvent::TouchPoint> &touchPoints) |
1132 | { |
1133 | - const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
1134 | for (int i = 0; i < touchPoints.count(); ++i) { |
1135 | QPoint pos = touchPoints.at(i).pos().toPoint(); |
1136 | if (pos.x() >= m_ubuntuKeyboardInfo->x() |
1137 | @@ -637,15 +728,15 @@ |
1138 | m_frameDropperTimer.start(); |
1139 | } |
1140 | |
1141 | -void MirSurfaceItem::setSession(Session *session) |
1142 | +void MirSurfaceItem::setSession(SessionInterface *session) |
1143 | { |
1144 | m_session = session; |
1145 | } |
1146 | |
1147 | -void MirSurfaceItem::onSessionStateChanged(Session::State state) |
1148 | +void MirSurfaceItem::onSessionStateChanged(SessionInterface::State state) |
1149 | { |
1150 | switch (state) { |
1151 | - case Session::State::Running: |
1152 | + case SessionInterface::State::Running: |
1153 | syncSurfaceSizeWithItemSize(); |
1154 | break; |
1155 | default: |
1156 | @@ -674,6 +765,22 @@ |
1157 | || !m_session; |
1158 | } |
1159 | |
1160 | +void MirSurfaceItem::TouchEvent::updateTouchPointStatesAndType() |
1161 | +{ |
1162 | + touchPointStates = 0; |
1163 | + for (int i = 0; i < touchPoints.count(); ++i) { |
1164 | + touchPointStates |= touchPoints.at(i).state(); |
1165 | + } |
1166 | + |
1167 | + if (touchPointStates == Qt::TouchPointReleased) { |
1168 | + type = QEvent::TouchEnd; |
1169 | + } else if (touchPointStates == Qt::TouchPointPressed) { |
1170 | + type = QEvent::TouchBegin; |
1171 | + } else { |
1172 | + type = QEvent::TouchUpdate; |
1173 | + } |
1174 | +} |
1175 | + |
1176 | } // namespace qtmir |
1177 | |
1178 | #include "mirsurfaceitem.moc" |
1179 | |
1180 | === modified file 'src/modules/Unity/Application/mirsurfaceitem.h' |
1181 | --- src/modules/Unity/Application/mirsurfaceitem.h 2014-08-29 14:58:07 +0000 |
1182 | +++ src/modules/Unity/Application/mirsurfaceitem.h 2014-09-18 22:57:30 +0000 |
1183 | @@ -32,7 +32,7 @@ |
1184 | #include <mir/scene/surface_observer.h> |
1185 | #include <mir_toolkit/common.h> |
1186 | |
1187 | -#include "session.h" |
1188 | +#include "session_interface.h" |
1189 | #include "ubuntukeyboardinfo.h" |
1190 | |
1191 | namespace qtmir { |
1192 | @@ -78,7 +78,7 @@ |
1193 | |
1194 | public: |
1195 | explicit MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface, |
1196 | - QPointer<Session> session, |
1197 | + SessionInterface* session, |
1198 | QQuickItem *parent = 0); |
1199 | ~MirSurfaceItem(); |
1200 | |
1201 | @@ -107,7 +107,7 @@ |
1202 | State state() const; |
1203 | QString name() const; |
1204 | bool live() const; |
1205 | - Session *session() const; |
1206 | + SessionInterface *session() const; |
1207 | |
1208 | Q_INVOKABLE void release(); |
1209 | |
1210 | @@ -120,7 +120,13 @@ |
1211 | |
1212 | bool isFirstFrameDrawn() const { return m_firstFrameDrawn; } |
1213 | |
1214 | - void setSession(Session *app); |
1215 | + void setSession(SessionInterface *app); |
1216 | + |
1217 | + // to allow easy touch event injection from tests |
1218 | + bool processTouchEvent(int eventType, |
1219 | + ulong timestamp, |
1220 | + const QList<QTouchEvent::TouchPoint> &touchPoints, |
1221 | + Qt::TouchPointStates touchPointStates); |
1222 | |
1223 | Q_SIGNALS: |
1224 | void typeChanged(); |
1225 | @@ -130,7 +136,7 @@ |
1226 | void firstFrameDrawn(MirSurfaceItem *item); |
1227 | |
1228 | protected Q_SLOTS: |
1229 | - void onSessionStateChanged(Session::State state); |
1230 | + void onSessionStateChanged(SessionInterface::State state); |
1231 | |
1232 | protected: |
1233 | void mousePressEvent(QMouseEvent *event) override; |
1234 | @@ -167,15 +173,22 @@ |
1235 | void setAttribute(const MirSurfaceAttrib, const int); |
1236 | void setSurfaceValid(const bool); |
1237 | |
1238 | - bool hasTouchInsideUbuntuKeyboard(QTouchEvent *event); |
1239 | + bool hasTouchInsideUbuntuKeyboard(const QList<QTouchEvent::TouchPoint> &touchPoints); |
1240 | void syncSurfaceSizeWithItemSize(); |
1241 | |
1242 | bool clientIsRunning() const; |
1243 | |
1244 | + QString appId() const; |
1245 | + void endCurrentTouchSequence(ulong timestamp); |
1246 | + void validateAndDeliverTouchEvent(int eventType, |
1247 | + ulong timestamp, |
1248 | + const QList<QTouchEvent::TouchPoint> &touchPoints, |
1249 | + Qt::TouchPointStates touchPointStates); |
1250 | + |
1251 | QMutex m_mutex; |
1252 | |
1253 | std::shared_ptr<mir::scene::Surface> m_surface; |
1254 | - QPointer<Session> m_session; |
1255 | + QPointer<SessionInterface> m_session; |
1256 | bool m_firstFrameDrawn; |
1257 | bool m_live; |
1258 | |
1259 | @@ -189,6 +202,24 @@ |
1260 | |
1261 | QTimer m_updateMirSurfaceSizeTimer; |
1262 | |
1263 | + class TouchEvent { |
1264 | + public: |
1265 | + TouchEvent &operator= (const QTouchEvent &qtEvent) { |
1266 | + type = qtEvent.type(); |
1267 | + timestamp = qtEvent.timestamp(); |
1268 | + touchPoints = qtEvent.touchPoints(); |
1269 | + touchPointStates = qtEvent.touchPointStates(); |
1270 | + return *this; |
1271 | + } |
1272 | + |
1273 | + void updateTouchPointStatesAndType(); |
1274 | + |
1275 | + int type; |
1276 | + ulong timestamp; |
1277 | + QList<QTouchEvent::TouchPoint> touchPoints; |
1278 | + Qt::TouchPointStates touchPointStates; |
1279 | + } *m_lastTouchEvent; |
1280 | + |
1281 | friend class MirSurfaceManager; |
1282 | }; |
1283 | |
1284 | |
1285 | === modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp' |
1286 | --- src/modules/Unity/Application/mirsurfacemanager.cpp 2014-08-29 14:58:07 +0000 |
1287 | +++ src/modules/Unity/Application/mirsurfacemanager.cpp 2014-09-18 22:57:30 +0000 |
1288 | @@ -19,10 +19,13 @@ |
1289 | #include <QMutexLocker> |
1290 | |
1291 | // local |
1292 | -#include "debughelpers.h" |
1293 | #include "mirsurfacemanager.h" |
1294 | #include "sessionmanager.h" |
1295 | #include "application_manager.h" |
1296 | +#include "tracepoints.h" // generated from tracepoints.tp |
1297 | + |
1298 | +// common |
1299 | +#include <debughelpers.h> |
1300 | |
1301 | // QPA mirserver |
1302 | #include "nativeinterface.h" |
1303 | @@ -96,24 +99,25 @@ |
1304 | m_mirSurfaceToItemHash.clear(); |
1305 | } |
1306 | |
1307 | -void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *session, |
1308 | +void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession, |
1309 | const std::shared_ptr<mir::scene::Surface> &surface) |
1310 | { |
1311 | - qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - session=" << session |
1312 | + qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - mirSession=" << mirSession |
1313 | << "surface=" << surface.get() << "surface.name=" << surface->name().c_str(); |
1314 | |
1315 | - Session* sessionItem = m_sessionManager->findSession(session); |
1316 | - auto qmlSurface = new MirSurfaceItem(surface, sessionItem); |
1317 | + SessionInterface* session = m_sessionManager->findSession(mirSession); |
1318 | + auto qmlSurface = new MirSurfaceItem(surface, session); |
1319 | { |
1320 | QMutexLocker lock(&m_mutex); |
1321 | m_mirSurfaceToItemHash.insert(surface.get(), qmlSurface); |
1322 | } |
1323 | |
1324 | - if (sessionItem) |
1325 | - sessionItem->setSurface(qmlSurface); |
1326 | + if (session) |
1327 | + session->setSurface(qmlSurface); |
1328 | |
1329 | // Only notify QML of surface creation once it has drawn its first frame. |
1330 | connect(qmlSurface, &MirSurfaceItem::firstFrameDrawn, this, [&](MirSurfaceItem *item) { |
1331 | + tracepoint(qtmir, firstFrameDrawn); |
1332 | Q_EMIT surfaceCreated(item); |
1333 | |
1334 | insert(0, item); |
1335 | @@ -128,7 +132,9 @@ |
1336 | } |
1337 | |
1338 | remove(mirSurfaceItem); |
1339 | + tracepoint(qtmir, surfaceDestroyed); |
1340 | }); |
1341 | + tracepoint(qtmir, surfaceCreated); |
1342 | } |
1343 | |
1344 | void MirSurfaceManager::onSessionDestroyingSurface(const mir::scene::Session *session, |
1345 | |
1346 | === modified file 'src/modules/Unity/Application/plugin.cpp' |
1347 | --- src/modules/Unity/Application/plugin.cpp 2014-09-01 16:07:27 +0000 |
1348 | +++ src/modules/Unity/Application/plugin.cpp 2014-09-18 22:57:30 +0000 |
1349 | @@ -65,6 +65,7 @@ |
1350 | qRegisterMetaType<qtmir::MirSurfaceItem*>("MirSurfaceItem*"); |
1351 | qRegisterMetaType<qtmir::MirSurfaceItemModel*>("MirSurfaceItemModel*"); |
1352 | qRegisterMetaType<qtmir::Session*>("Session*"); |
1353 | + qRegisterMetaType<qtmir::SessionInterface*>("SessionInterface*"); |
1354 | qRegisterMetaType<qtmir::SessionModel*>("SessionModel*"); |
1355 | |
1356 | qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>( |
1357 | |
1358 | === modified file 'src/modules/Unity/Application/session.cpp' |
1359 | --- src/modules/Unity/Application/session.cpp 2014-09-01 16:07:27 +0000 |
1360 | +++ src/modules/Unity/Application/session.cpp 2014-09-18 22:57:30 +0000 |
1361 | @@ -34,13 +34,15 @@ |
1362 | |
1363 | namespace ms = mir::scene; |
1364 | |
1365 | +using unity::shell::application::ApplicationInfoInterface; |
1366 | + |
1367 | namespace qtmir |
1368 | { |
1369 | |
1370 | Session::Session(const std::shared_ptr<ms::Session>& session, |
1371 | const std::shared_ptr<ms::PromptSessionManager>& promptSessionManager, |
1372 | QObject *parent) |
1373 | - : QObject(parent) |
1374 | + : SessionInterface(parent) |
1375 | , m_session(session) |
1376 | , m_application(nullptr) |
1377 | , m_surface(nullptr) |
1378 | @@ -72,8 +74,8 @@ |
1379 | qCDebug(QTMIR_SESSIONS) << "Session::~Session() " << name(); |
1380 | stopPromptSessions(); |
1381 | |
1382 | - QList<Session*> children(m_children->list()); |
1383 | - for (Session* child : children) { |
1384 | + QList<SessionInterface*> children(m_children->list()); |
1385 | + for (SessionInterface* child : children) { |
1386 | delete child; |
1387 | } |
1388 | if (m_parentSession) { |
1389 | @@ -112,7 +114,7 @@ |
1390 | return m_session; |
1391 | } |
1392 | |
1393 | -Application* Session::application() const |
1394 | +ApplicationInfoInterface* Session::application() const |
1395 | { |
1396 | return m_application; |
1397 | } |
1398 | @@ -127,7 +129,7 @@ |
1399 | } |
1400 | } |
1401 | |
1402 | -Session* Session::parentSession() const |
1403 | +SessionInterface* Session::parentSession() const |
1404 | { |
1405 | return m_parentSession; |
1406 | } |
1407 | @@ -147,12 +149,12 @@ |
1408 | return m_live; |
1409 | } |
1410 | |
1411 | -void Session::setApplication(Application* application) |
1412 | +void Session::setApplication(ApplicationInfoInterface* application) |
1413 | { |
1414 | if (m_application == application) |
1415 | return; |
1416 | |
1417 | - m_application = application; |
1418 | + m_application = static_cast<Application*>(application); |
1419 | Q_EMIT applicationChanged(application); |
1420 | } |
1421 | |
1422 | @@ -251,7 +253,7 @@ |
1423 | m_state = state; |
1424 | Q_EMIT stateChanged(state); |
1425 | |
1426 | - foreachChildSession([state](Session* session) { |
1427 | + foreachChildSession([state](SessionInterface* session) { |
1428 | session->setState(state); |
1429 | }); |
1430 | } |
1431 | @@ -275,35 +277,35 @@ |
1432 | Q_EMIT parentSessionChanged(session); |
1433 | } |
1434 | |
1435 | -void Session::addChildSession(Session* session) |
1436 | +void Session::addChildSession(SessionInterface* session) |
1437 | { |
1438 | insertChildSession(m_children->rowCount(), session); |
1439 | } |
1440 | |
1441 | -void Session::insertChildSession(uint index, Session* session) |
1442 | +void Session::insertChildSession(uint index, SessionInterface* session) |
1443 | { |
1444 | qCDebug(QTMIR_SESSIONS) << "Session::insertChildSession - " << session->name() << " to " << name() << " @ " << index; |
1445 | |
1446 | - session->setParentSession(this); |
1447 | + static_cast<Session*>(session)->setParentSession(this); |
1448 | m_children->insert(index, session); |
1449 | |
1450 | session->setState(state()); |
1451 | } |
1452 | |
1453 | -void Session::removeChildSession(Session* session) |
1454 | +void Session::removeChildSession(SessionInterface* session) |
1455 | { |
1456 | qCDebug(QTMIR_SESSIONS) << "Session::removeChildSession - " << session->name() << " from " << name(); |
1457 | |
1458 | if (m_children->contains(session)) { |
1459 | m_children->remove(session); |
1460 | - session->setParentSession(nullptr); |
1461 | + static_cast<Session*>(session)->setParentSession(nullptr); |
1462 | } |
1463 | } |
1464 | |
1465 | -void Session::foreachChildSession(std::function<void(Session* session)> f) const |
1466 | +void Session::foreachChildSession(std::function<void(SessionInterface* session)> f) const |
1467 | { |
1468 | - QList<Session*> children(m_children->list()); |
1469 | - for (Session* child : children) { |
1470 | + QList<SessionInterface*> children(m_children->list()); |
1471 | + for (SessionInterface* child : children) { |
1472 | f(child); |
1473 | } |
1474 | } |
1475 | @@ -331,9 +333,9 @@ |
1476 | |
1477 | void Session::stopPromptSessions() |
1478 | { |
1479 | - QList<Session*> children(m_children->list()); |
1480 | - for (Session* child : children) { |
1481 | - child->stopPromptSessions(); |
1482 | + QList<SessionInterface*> children(m_children->list()); |
1483 | + for (SessionInterface* child : children) { |
1484 | + static_cast<Session*>(child)->stopPromptSessions(); |
1485 | } |
1486 | |
1487 | QList<std::shared_ptr<ms::PromptSession>> copy(m_promptSessions); |
1488 | |
1489 | === modified file 'src/modules/Unity/Application/session.h' |
1490 | --- src/modules/Unity/Application/session.h 2014-09-01 16:07:27 +0000 |
1491 | +++ src/modules/Unity/Application/session.h 2014-09-18 22:57:30 +0000 |
1492 | @@ -21,19 +21,15 @@ |
1493 | #include <memory> |
1494 | |
1495 | // local |
1496 | -#include "sessionmodel.h" |
1497 | +#include "session_interface.h" |
1498 | |
1499 | // Qt |
1500 | #include <QObject> |
1501 | #include <QTimer> |
1502 | |
1503 | -// Unity API |
1504 | -#include <unity/shell/application/ApplicationInfoInterface.h> |
1505 | |
1506 | namespace mir { |
1507 | namespace scene { |
1508 | - class Session; |
1509 | - class PromptSession; |
1510 | class PromptSessionManager; |
1511 | } |
1512 | } |
1513 | @@ -41,83 +37,61 @@ |
1514 | namespace qtmir { |
1515 | |
1516 | class Application; |
1517 | -class MirSurfaceItem; |
1518 | |
1519 | -class Session : public QObject |
1520 | +class Session : public SessionInterface |
1521 | { |
1522 | Q_OBJECT |
1523 | - Q_PROPERTY(MirSurfaceItem* surface READ surface NOTIFY surfaceChanged) |
1524 | - Q_PROPERTY(Application* application READ application NOTIFY applicationChanged DESIGNABLE false) |
1525 | - Q_PROPERTY(Session* parentSession READ parentSession NOTIFY parentSessionChanged DESIGNABLE false) |
1526 | - Q_PROPERTY(SessionModel* childSessions READ childSessions DESIGNABLE false CONSTANT) |
1527 | - Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged) |
1528 | - Q_PROPERTY(bool live READ live NOTIFY liveChanged) |
1529 | - |
1530 | public: |
1531 | explicit Session(const std::shared_ptr<mir::scene::Session>& session, |
1532 | const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager, |
1533 | QObject *parent = 0); |
1534 | - ~Session(); |
1535 | - |
1536 | - // Session State |
1537 | - typedef unity::shell::application::ApplicationInfoInterface::State State; |
1538 | - |
1539 | - Q_INVOKABLE void release(); |
1540 | + virtual ~Session(); |
1541 | + |
1542 | + Q_INVOKABLE void release() override; |
1543 | |
1544 | //getters |
1545 | - QString name() const; |
1546 | - Application* application() const; |
1547 | - MirSurfaceItem* surface() const; |
1548 | - Session* parentSession() const; |
1549 | - State state() const; |
1550 | - bool fullscreen() const; |
1551 | - bool live() const; |
1552 | - |
1553 | - void setSession(); |
1554 | - void setApplication(Application* item); |
1555 | - void setSurface(MirSurfaceItem* surface); |
1556 | - void setState(State state); |
1557 | - |
1558 | - void addChildSession(Session* session); |
1559 | - void insertChildSession(uint index, Session* session); |
1560 | - void removeChildSession(Session* session); |
1561 | - void foreachChildSession(std::function<void(Session* session)> f) const; |
1562 | - |
1563 | - std::shared_ptr<mir::scene::Session> session() const; |
1564 | - |
1565 | - std::shared_ptr<mir::scene::PromptSession> activePromptSession() const; |
1566 | - void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> f) const; |
1567 | - |
1568 | -Q_SIGNALS: |
1569 | - void surfaceChanged(MirSurfaceItem*); |
1570 | - void parentSessionChanged(Session*); |
1571 | - void applicationChanged(Application* application); |
1572 | - void aboutToBeDestroyed(); |
1573 | - void stateChanged(State state); |
1574 | - void fullscreenChanged(bool fullscreen); |
1575 | - void liveChanged(bool live); |
1576 | - |
1577 | - void suspended(); |
1578 | - void resumed(); |
1579 | + QString name() const override; |
1580 | + unity::shell::application::ApplicationInfoInterface* application() const override; |
1581 | + MirSurfaceItem* surface() const override; |
1582 | + SessionInterface* parentSession() const override; |
1583 | + State state() const override; |
1584 | + bool fullscreen() const override; |
1585 | + bool live() const override; |
1586 | + |
1587 | + void setApplication(unity::shell::application::ApplicationInfoInterface* item) override; |
1588 | + void setSurface(MirSurfaceItem* surface) override; |
1589 | + void setState(State state) override; |
1590 | + |
1591 | + void addChildSession(SessionInterface* session) override; |
1592 | + void insertChildSession(uint index, SessionInterface* session) override; |
1593 | + void removeChildSession(SessionInterface* session) override; |
1594 | + void foreachChildSession(std::function<void(SessionInterface* session)> f) const override; |
1595 | + |
1596 | + std::shared_ptr<mir::scene::Session> session() const override; |
1597 | + |
1598 | + std::shared_ptr<mir::scene::PromptSession> activePromptSession() const override; |
1599 | + void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> f) const override; |
1600 | + |
1601 | + SessionModel* childSessions() const override; |
1602 | + |
1603 | +protected: |
1604 | + void setFullscreen(bool fullscreen) override; |
1605 | + void setLive(const bool) override; |
1606 | + void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) override; |
1607 | + void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) override; |
1608 | |
1609 | private Q_SLOTS: |
1610 | void updateFullscreenProperty(); |
1611 | |
1612 | private: |
1613 | - SessionModel* childSessions() const; |
1614 | void setParentSession(Session* session); |
1615 | |
1616 | - void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>& session); |
1617 | - void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>& session); |
1618 | void stopPromptSessions(); |
1619 | |
1620 | - void setFullscreen(bool fullscreen); |
1621 | - void setLive(const bool); |
1622 | - |
1623 | std::shared_ptr<mir::scene::Session> m_session; |
1624 | Application* m_application; |
1625 | MirSurfaceItem* m_surface; |
1626 | - Session* m_parentSession; |
1627 | + SessionInterface* m_parentSession; |
1628 | SessionModel* m_children; |
1629 | bool m_fullscreen; |
1630 | State m_state; |
1631 | @@ -125,8 +99,6 @@ |
1632 | QTimer* m_suspendTimer; |
1633 | QList<std::shared_ptr<mir::scene::PromptSession>> m_promptSessions; |
1634 | std::shared_ptr<mir::scene::PromptSessionManager> const m_promptSessionManager; |
1635 | - |
1636 | - friend class SessionManager; |
1637 | }; |
1638 | |
1639 | } // namespace qtmir |
1640 | |
1641 | === added file 'src/modules/Unity/Application/session_interface.h' |
1642 | --- src/modules/Unity/Application/session_interface.h 1970-01-01 00:00:00 +0000 |
1643 | +++ src/modules/Unity/Application/session_interface.h 2014-09-18 22:57:30 +0000 |
1644 | @@ -0,0 +1,106 @@ |
1645 | +/* |
1646 | + * Copyright (C) 2014 Canonical, Ltd. |
1647 | + * |
1648 | + * This program is free software; you can redistribute it and/or modify |
1649 | + * it under the terms of the GNU General Public License as published by |
1650 | + * the Free Software Foundation; version 3. |
1651 | + * |
1652 | + * This program is distributed in the hope that it will be useful, |
1653 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1654 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1655 | + * GNU General Public License for more details. |
1656 | + * |
1657 | + * You should have received a copy of the GNU General Public License |
1658 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1659 | + */ |
1660 | + |
1661 | +#ifndef SESSION_INTERFACE_H |
1662 | +#define SESSION_INTERFACE_H |
1663 | + |
1664 | +#include <functional> |
1665 | +#include <memory> |
1666 | + |
1667 | +// Unity API |
1668 | +#include <unity/shell/application/ApplicationInfoInterface.h> |
1669 | + |
1670 | +// local |
1671 | +#include "sessionmodel.h" |
1672 | + |
1673 | +namespace mir { |
1674 | + namespace scene { |
1675 | + class Session; |
1676 | + class PromptSession; |
1677 | + } |
1678 | +} |
1679 | + |
1680 | +namespace qtmir { |
1681 | + |
1682 | +class MirSurfaceItem; |
1683 | + |
1684 | +class SessionInterface : public QObject { |
1685 | + Q_OBJECT |
1686 | + Q_PROPERTY(MirSurfaceItem* surface READ surface NOTIFY surfaceChanged) |
1687 | + Q_PROPERTY(unity::shell::application::ApplicationInfoInterface* application READ application NOTIFY applicationChanged DESIGNABLE false) |
1688 | + Q_PROPERTY(SessionInterface* parentSession READ parentSession NOTIFY parentSessionChanged DESIGNABLE false) |
1689 | + Q_PROPERTY(SessionModel* childSessions READ childSessions DESIGNABLE false CONSTANT) |
1690 | + Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged) |
1691 | + Q_PROPERTY(bool live READ live NOTIFY liveChanged) |
1692 | +public: |
1693 | + SessionInterface(QObject *parent = 0) : QObject(parent) {} |
1694 | + virtual ~SessionInterface() {} |
1695 | + |
1696 | + // Session State |
1697 | + typedef unity::shell::application::ApplicationInfoInterface::State State; |
1698 | + |
1699 | + Q_INVOKABLE virtual void release() = 0; |
1700 | + |
1701 | + //getters |
1702 | + virtual QString name() const = 0; |
1703 | + virtual unity::shell::application::ApplicationInfoInterface* application() const = 0; |
1704 | + virtual MirSurfaceItem* surface() const = 0; |
1705 | + virtual SessionInterface* parentSession() const = 0; |
1706 | + virtual State state() const = 0; |
1707 | + virtual bool fullscreen() const = 0; |
1708 | + virtual bool live() const = 0; |
1709 | + |
1710 | + virtual void setApplication(unity::shell::application::ApplicationInfoInterface* item) = 0; |
1711 | + virtual void setSurface(MirSurfaceItem* surface) = 0; |
1712 | + virtual void setState(State state) = 0; |
1713 | + |
1714 | + virtual void addChildSession(SessionInterface* session) = 0; |
1715 | + virtual void insertChildSession(uint index, SessionInterface* session) = 0; |
1716 | + virtual void removeChildSession(SessionInterface* session) = 0; |
1717 | + virtual void foreachChildSession(std::function<void(SessionInterface* session)> f) const = 0; |
1718 | + |
1719 | + virtual std::shared_ptr<mir::scene::Session> session() const = 0; |
1720 | + |
1721 | + virtual std::shared_ptr<mir::scene::PromptSession> activePromptSession() const = 0; |
1722 | + virtual void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> f) const = 0; |
1723 | + |
1724 | + virtual SessionModel* childSessions() const = 0; |
1725 | + |
1726 | +Q_SIGNALS: |
1727 | + void surfaceChanged(MirSurfaceItem*); |
1728 | + void parentSessionChanged(SessionInterface*); |
1729 | + void applicationChanged(unity::shell::application::ApplicationInfoInterface* application); |
1730 | + void aboutToBeDestroyed(); |
1731 | + void stateChanged(State state); |
1732 | + void fullscreenChanged(bool fullscreen); |
1733 | + void liveChanged(bool live); |
1734 | + |
1735 | + void suspended(); |
1736 | + void resumed(); |
1737 | + |
1738 | +protected: |
1739 | + virtual void setFullscreen(bool fullscreen) = 0; |
1740 | + virtual void setLive(const bool) = 0; |
1741 | + virtual void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) = 0; |
1742 | + virtual void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) = 0; |
1743 | + |
1744 | + friend class SessionManager; |
1745 | +}; |
1746 | + |
1747 | +} // namespace qtmir |
1748 | + |
1749 | + |
1750 | +#endif // SESSION_INTERFACE_H |
1751 | |
1752 | === modified file 'src/modules/Unity/Application/sessionmanager.cpp' |
1753 | --- src/modules/Unity/Application/sessionmanager.cpp 2014-08-29 14:58:07 +0000 |
1754 | +++ src/modules/Unity/Application/sessionmanager.cpp 2014-09-18 22:57:30 +0000 |
1755 | @@ -103,11 +103,11 @@ |
1756 | qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this; |
1757 | } |
1758 | |
1759 | -Session *SessionManager::findSession(const mir::scene::Session* session) const |
1760 | +SessionInterface *SessionManager::findSession(const mir::scene::Session* session) const |
1761 | { |
1762 | if (!session) return nullptr; |
1763 | |
1764 | - for (Session* child : list()) { |
1765 | + for (SessionInterface* child : list()) { |
1766 | if (child->session().get() == session) |
1767 | return child; |
1768 | } |
1769 | @@ -139,7 +139,7 @@ |
1770 | { |
1771 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStopping - sessionName=" << session->name().c_str(); |
1772 | |
1773 | - Session* qmlSession = findSession(session.get()); |
1774 | + SessionInterface* qmlSession = findSession(session.get()); |
1775 | if (!qmlSession) return; |
1776 | |
1777 | remove(qmlSession); |
1778 | @@ -153,7 +153,7 @@ |
1779 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStarting - promptSession=" << promptSession.get(); |
1780 | |
1781 | std::shared_ptr<mir::scene::Session> appSession = m_mirConfig->the_prompt_session_manager()->application_for(promptSession); |
1782 | - Session *qmlAppSession = findSession(appSession.get()); |
1783 | + SessionInterface *qmlAppSession = findSession(appSession.get()); |
1784 | if (qmlAppSession) { |
1785 | m_mirPromptToSessionHash[promptSession.get()] = qmlAppSession; |
1786 | qmlAppSession->appendPromptSession(promptSession); |
1787 | @@ -166,7 +166,7 @@ |
1788 | { |
1789 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStopping - promptSession=" << promptSession.get(); |
1790 | |
1791 | - for (Session *qmlSession : this->list()) { |
1792 | + for (SessionInterface *qmlSession : this->list()) { |
1793 | qmlSession->removePromptSession(promptSession); |
1794 | } |
1795 | m_mirPromptToSessionHash.remove(promptSession.get()); |
1796 | @@ -177,13 +177,13 @@ |
1797 | { |
1798 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - promptSession=" << promptSession << " promptProvider=" << promptProvider.get(); |
1799 | |
1800 | - Session* qmlAppSession = m_mirPromptToSessionHash.value(promptSession, nullptr); |
1801 | + SessionInterface* qmlAppSession = m_mirPromptToSessionHash.value(promptSession, nullptr); |
1802 | if (!qmlAppSession) { |
1803 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for app session"; |
1804 | return; |
1805 | } |
1806 | |
1807 | - Session* qmlPromptProvider = findSession(promptProvider.get()); |
1808 | + SessionInterface* qmlPromptProvider = findSession(promptProvider.get()); |
1809 | if (!qmlPromptProvider) { |
1810 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for provider session"; |
1811 | return; |
1812 | @@ -197,7 +197,7 @@ |
1813 | { |
1814 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderRemoved - promptSession=" << promptSession << " promptProvider=" << promptProvider.get(); |
1815 | |
1816 | - Session* qmlPromptProvider = findSession(promptProvider.get()); |
1817 | + SessionInterface* qmlPromptProvider = findSession(promptProvider.get()); |
1818 | if (!qmlPromptProvider) { |
1819 | qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for provider session"; |
1820 | return; |
1821 | |
1822 | === modified file 'src/modules/Unity/Application/sessionmanager.h' |
1823 | --- src/modules/Unity/Application/sessionmanager.h 2014-08-28 23:36:42 +0000 |
1824 | +++ src/modules/Unity/Application/sessionmanager.h 2014-09-18 22:57:30 +0000 |
1825 | @@ -59,11 +59,11 @@ |
1826 | |
1827 | static SessionManager* singleton(); |
1828 | |
1829 | - Session *findSession(const mir::scene::Session* session) const; |
1830 | + SessionInterface *findSession(const mir::scene::Session* session) const; |
1831 | |
1832 | Q_SIGNALS: |
1833 | - void sessionStarting(Session* session); |
1834 | - void sessionStopping(Session* session); |
1835 | + void sessionStarting(SessionInterface* session); |
1836 | + void sessionStopping(SessionInterface* session); |
1837 | |
1838 | public Q_SLOTS: |
1839 | void onSessionStarting(std::shared_ptr<mir::scene::Session> const& session); |
1840 | @@ -82,7 +82,7 @@ |
1841 | static SessionManager *the_session_manager; |
1842 | |
1843 | QList<Session*> m_sessions; |
1844 | - QHash<const mir::scene::PromptSession *, Session *> m_mirPromptToSessionHash; |
1845 | + QHash<const mir::scene::PromptSession *, SessionInterface *> m_mirPromptToSessionHash; |
1846 | }; |
1847 | |
1848 | } // namespace qtmir |
1849 | |
1850 | === modified file 'src/modules/Unity/Application/sessionmodel.h' |
1851 | --- src/modules/Unity/Application/sessionmodel.h 2014-08-29 11:15:51 +0000 |
1852 | +++ src/modules/Unity/Application/sessionmodel.h 2014-09-18 22:57:30 +0000 |
1853 | @@ -22,8 +22,8 @@ |
1854 | |
1855 | namespace qtmir { |
1856 | |
1857 | -class Session; |
1858 | -typedef ObjectListModel<Session> SessionModel; |
1859 | +class SessionInterface; |
1860 | +typedef ObjectListModel<SessionInterface> SessionModel; |
1861 | |
1862 | } // namespace qtmir |
1863 | |
1864 | |
1865 | === added file 'src/modules/Unity/Application/tracepoints.tp' |
1866 | --- src/modules/Unity/Application/tracepoints.tp 1970-01-01 00:00:00 +0000 |
1867 | +++ src/modules/Unity/Application/tracepoints.tp 2014-09-18 22:57:30 +0000 |
1868 | @@ -0,0 +1,9 @@ |
1869 | +TRACEPOINT_EVENT(qtmir, startApplication, TP_ARGS(0), TP_FIELDS()) |
1870 | +TRACEPOINT_EVENT(qtmir, onProcessStarting, TP_ARGS(0), TP_FIELDS()) |
1871 | +TRACEPOINT_EVENT(qtmir, authorizeSession, TP_ARGS(0), TP_FIELDS()) |
1872 | +TRACEPOINT_EVENT(qtmir, onProcessStopped, TP_ARGS(0), TP_FIELDS()) |
1873 | +TRACEPOINT_EVENT(qtmir, surfaceCreated, TP_ARGS(0), TP_FIELDS()) |
1874 | +TRACEPOINT_EVENT(qtmir, surfaceDestroyed, TP_ARGS(0), TP_FIELDS()) |
1875 | +TRACEPOINT_EVENT(qtmir, firstFrameDrawn, TP_ARGS(0), TP_FIELDS()) |
1876 | +TRACEPOINT_EVENT(qtmir, appIdHasProcessId_start, TP_ARGS(0), TP_FIELDS()) |
1877 | +TRACEPOINT_EVENT(qtmir, appIdHasProcessId_end, TP_ARGS(int, found), TP_FIELDS(ctf_integer(int, found, found))) |
1878 | |
1879 | === modified file 'src/platforms/mirserver/logging.h' |
1880 | --- src/platforms/mirserver/logging.h 2014-08-22 14:57:00 +0000 |
1881 | +++ src/platforms/mirserver/logging.h 2014-09-18 22:57:30 +0000 |
1882 | @@ -22,5 +22,6 @@ |
1883 | Q_DECLARE_LOGGING_CATEGORY(QTMIR_SESSIONS) |
1884 | Q_DECLARE_LOGGING_CATEGORY(QTMIR_SURFACES) |
1885 | Q_DECLARE_LOGGING_CATEGORY(QTMIR_MIR_MESSAGES) |
1886 | +Q_DECLARE_LOGGING_CATEGORY(QTMIR_MIR_INPUT) |
1887 | |
1888 | #endif // UBUNTU_APPLICATION_PLUGIN_LOGGING_H |
1889 | |
1890 | === modified file 'src/platforms/mirserver/mirplacementstrategy.cpp' |
1891 | --- src/platforms/mirserver/mirplacementstrategy.cpp 2014-07-01 13:38:06 +0000 |
1892 | +++ src/platforms/mirserver/mirplacementstrategy.cpp 2014-09-18 22:57:30 +0000 |
1893 | @@ -16,6 +16,7 @@ |
1894 | |
1895 | #include "mirplacementstrategy.h" |
1896 | #include "logging.h" |
1897 | +#include "tracepoints.h" // generated from tracepoints.tp |
1898 | |
1899 | #include <mir/geometry/rectangle.h> |
1900 | #include <mir/shell/display_layout.h> |
1901 | @@ -35,6 +36,8 @@ |
1902 | MirPlacementStrategy::place(ms::Session const& /*session*/, |
1903 | ms::SurfaceCreationParameters const& requestParameters) |
1904 | { |
1905 | + tracepoint(qtmirserver, surfacePlacementStart); |
1906 | + |
1907 | // TODO: Callback unity8 so that it can make a decision on that. |
1908 | // unity8 must bear in mind that the called function will be on a Mir thread though. |
1909 | // The QPA shouldn't be deciding for itself on such things. |
1910 | @@ -50,5 +53,7 @@ |
1911 | << requestParameters.size.width.as_int() << "," << requestParameters.size.height.as_int() << ") and returned (" |
1912 | << placedParameters.size.width.as_int() << "," << placedParameters.size.height.as_int() << ")"; |
1913 | |
1914 | + tracepoint(qtmirserver, surfacePlacementEnd); |
1915 | + |
1916 | return placedParameters; |
1917 | } |
1918 | |
1919 | === modified file 'src/platforms/mirserver/mirserver.pro' |
1920 | --- src/platforms/mirserver/mirserver.pro 2014-08-05 09:14:13 +0000 |
1921 | +++ src/platforms/mirserver/mirserver.pro 2014-09-18 22:57:30 +0000 |
1922 | @@ -1,3 +1,5 @@ |
1923 | +include(../../lttng-compiler.pri) |
1924 | + |
1925 | TARGET = qpa-mirserver |
1926 | TEMPLATE = lib |
1927 | |
1928 | @@ -14,6 +16,8 @@ |
1929 | QMAKE_CXXFLAGS = -std=c++11 -Werror -Wall |
1930 | QMAKE_LFLAGS = -std=c++11 -Wl,-no-undefined |
1931 | |
1932 | +INCLUDEPATH += ../../common |
1933 | + |
1934 | CONFIG += link_pkgconfig |
1935 | PKGCONFIG += mirserver protobuf egl xkbcommon url-dispatcher-1 |
1936 | |
1937 | @@ -21,6 +25,7 @@ |
1938 | |
1939 | SOURCES += \ |
1940 | connectioncreator.cpp \ |
1941 | + ../../common/debughelpers.cpp \ |
1942 | focussetter.cpp \ |
1943 | qteventfeeder.cpp \ |
1944 | plugin.cpp \ |
1945 | @@ -47,6 +52,7 @@ |
1946 | |
1947 | HEADERS += \ |
1948 | connectioncreator.h \ |
1949 | + ../../common/debughelpers.h \ |
1950 | focussetter.h \ |
1951 | qteventfeeder.h \ |
1952 | plugin.h \ |
1953 | @@ -73,6 +79,8 @@ |
1954 | unityprotobufservice.h \ |
1955 | unityrpc.h |
1956 | |
1957 | +LTTNG_TP_FILES += tracepoints.tp |
1958 | + |
1959 | # Installation path |
1960 | target.path += $$[QT_INSTALL_PLUGINS]/platforms |
1961 | |
1962 | |
1963 | === modified file 'src/platforms/mirserver/mirserverconfiguration.cpp' |
1964 | --- src/platforms/mirserver/mirserverconfiguration.cpp 2014-08-05 10:02:12 +0000 |
1965 | +++ src/platforms/mirserver/mirserverconfiguration.cpp 2014-09-18 22:57:30 +0000 |
1966 | @@ -31,20 +31,31 @@ |
1967 | #include "logging.h" |
1968 | #include "unityprotobufservice.h" |
1969 | |
1970 | +// mir |
1971 | +#include <mir/options/default_configuration.h> |
1972 | + |
1973 | // Qt |
1974 | #include <QDebug> |
1975 | |
1976 | // egl |
1977 | #include <EGL/egl.h> |
1978 | |
1979 | +namespace mo = mir::options; |
1980 | namespace msh = mir::shell; |
1981 | namespace ms = mir::scene; |
1982 | |
1983 | +namespace |
1984 | +{ |
1985 | +void ignore_unparsed_arguments(int /*argc*/, char const* const/*argv*/[]) |
1986 | +{ |
1987 | +} |
1988 | +} |
1989 | + |
1990 | Q_LOGGING_CATEGORY(QTMIR_MIR_MESSAGES, "qtmir.mir") |
1991 | |
1992 | MirServerConfiguration::MirServerConfiguration(int argc, char const* argv[], QObject* parent) |
1993 | : QObject(parent) |
1994 | - , DefaultServerConfiguration(argc, argv) |
1995 | + , DefaultServerConfiguration(std::make_shared<mo::DefaultConfiguration>(argc, argv, &ignore_unparsed_arguments)) |
1996 | , m_unityService(std::make_shared<UnityProtobufService>()) |
1997 | { |
1998 | qCDebug(QTMIR_MIR_MESSAGES) << "MirServerConfiguration created"; |
1999 | |
2000 | === modified file 'src/platforms/mirserver/qteventfeeder.cpp' |
2001 | --- src/platforms/mirserver/qteventfeeder.cpp 2014-07-29 15:01:34 +0000 |
2002 | +++ src/platforms/mirserver/qteventfeeder.cpp 2014-09-18 22:57:30 +0000 |
2003 | @@ -18,10 +18,10 @@ |
2004 | */ |
2005 | |
2006 | #include "qteventfeeder.h" |
2007 | +#include "logging.h" |
2008 | |
2009 | #include <qpa/qplatforminputcontext.h> |
2010 | #include <qpa/qplatformintegration.h> |
2011 | -#include <qpa/qwindowsysteminterface.h> |
2012 | #include <QGuiApplication> |
2013 | #include <private/qguiapplication_p.h> |
2014 | |
2015 | @@ -30,6 +30,8 @@ |
2016 | |
2017 | #include <QDebug> |
2018 | |
2019 | +Q_LOGGING_CATEGORY(QTMIR_MIR_INPUT, "qtmir.mir.input") |
2020 | + |
2021 | // from android-input AMOTION_EVENT_ACTION_*, hidden inside mir bowels |
2022 | // mir headers should define them |
2023 | const int QtEventFeeder::MirEventActionMask = 0xff; |
2024 | @@ -133,9 +135,61 @@ |
2025 | return toupper(sym); |
2026 | } |
2027 | |
2028 | - |
2029 | -QtEventFeeder::QtEventFeeder() |
2030 | +namespace { |
2031 | + |
2032 | +class QtWindowSystem : public QtEventFeeder::QtWindowSystemInterface { |
2033 | + |
2034 | + bool hasTargetWindow() override |
2035 | + { |
2036 | + if (mTopLevelWindow.isNull() && !QGuiApplication::topLevelWindows().isEmpty()) { |
2037 | + mTopLevelWindow = QGuiApplication::topLevelWindows().first(); |
2038 | + } |
2039 | + return !mTopLevelWindow.isNull(); |
2040 | + } |
2041 | + |
2042 | + QRect targetWindowGeometry() override |
2043 | + { |
2044 | + Q_ASSERT(!mTopLevelWindow.isNull()); |
2045 | + return mTopLevelWindow->geometry(); |
2046 | + } |
2047 | + |
2048 | + void registerTouchDevice(QTouchDevice *device) override |
2049 | + { |
2050 | + QWindowSystemInterface::registerTouchDevice(device); |
2051 | + } |
2052 | + |
2053 | + void handleExtendedKeyEvent(ulong timestamp, QEvent::Type type, int key, |
2054 | + Qt::KeyboardModifiers modifiers, |
2055 | + quint32 nativeScanCode, quint32 nativeVirtualKey, |
2056 | + quint32 nativeModifiers, |
2057 | + const QString& text, bool autorep, ushort count) override |
2058 | + { |
2059 | + Q_ASSERT(!mTopLevelWindow.isNull()); |
2060 | + QWindowSystemInterface::handleExtendedKeyEvent(mTopLevelWindow.data(), timestamp, type, key, modifiers, |
2061 | + nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); |
2062 | + } |
2063 | + |
2064 | + void handleTouchEvent(ulong timestamp, QTouchDevice *device, |
2065 | + const QList<struct QWindowSystemInterface::TouchPoint> &points, Qt::KeyboardModifiers mods) override |
2066 | + { |
2067 | + Q_ASSERT(!mTopLevelWindow.isNull()); |
2068 | + QWindowSystemInterface::handleTouchEvent(mTopLevelWindow.data(), timestamp, device, points, mods); |
2069 | + } |
2070 | +private: |
2071 | + QPointer<QWindow> mTopLevelWindow; |
2072 | +}; |
2073 | + |
2074 | +} // anonymous namespace |
2075 | + |
2076 | + |
2077 | +QtEventFeeder::QtEventFeeder(QtEventFeeder::QtWindowSystemInterface *windowSystem) |
2078 | { |
2079 | + if (windowSystem) { |
2080 | + mQtWindowSystem = windowSystem; |
2081 | + } else { |
2082 | + mQtWindowSystem = new QtWindowSystem; |
2083 | + } |
2084 | + |
2085 | // Initialize touch device. Hardcoded just like in qtubuntu |
2086 | // TODO: Create them from info gathered from Mir and store things like device id and source |
2087 | // in a QTouchDevice-derived class created by us. So that we can properly assemble back |
2088 | @@ -145,7 +199,12 @@ |
2089 | mTouchDevice->setCapabilities( |
2090 | QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | |
2091 | QTouchDevice::NormalizedPosition); |
2092 | - QWindowSystemInterface::registerTouchDevice(mTouchDevice); |
2093 | + mQtWindowSystem->registerTouchDevice(mTouchDevice); |
2094 | +} |
2095 | + |
2096 | +QtEventFeeder::~QtEventFeeder() |
2097 | +{ |
2098 | + delete mQtWindowSystem; |
2099 | } |
2100 | |
2101 | void QtEventFeeder::dispatch(MirEvent const& event) |
2102 | @@ -171,11 +230,9 @@ |
2103 | |
2104 | void QtEventFeeder::dispatchKey(MirKeyEvent const& event) |
2105 | { |
2106 | - if (QGuiApplication::topLevelWindows().isEmpty()) |
2107 | + if (!mQtWindowSystem->hasTargetWindow()) |
2108 | return; |
2109 | |
2110 | - QWindow *window = QGuiApplication::topLevelWindows().first(); |
2111 | - |
2112 | ulong timestamp = event.event_time / 1000000; |
2113 | xkb_keysym_t xk_sym = static_cast<xkb_keysym_t>(event.key_code); |
2114 | |
2115 | @@ -221,20 +278,33 @@ |
2116 | } |
2117 | } |
2118 | |
2119 | - QWindowSystemInterface::handleExtendedKeyEvent(window, timestamp, keyType, keyCode, modifiers, event.scan_code, event.key_code, event.modifiers, text); |
2120 | + mQtWindowSystem->handleExtendedKeyEvent(timestamp, keyType, keyCode, modifiers, |
2121 | + event.scan_code, event.key_code, event.modifiers, text); |
2122 | } |
2123 | |
2124 | void QtEventFeeder::dispatchMotion(MirMotionEvent const& event) |
2125 | { |
2126 | - if (QGuiApplication::topLevelWindows().isEmpty()) |
2127 | - return; |
2128 | - |
2129 | - QWindow *window = QGuiApplication::topLevelWindows().first(); |
2130 | + if (!mQtWindowSystem->hasTargetWindow()) |
2131 | + return; |
2132 | + |
2133 | + const int mirMotionAction = event.action & MirEventActionMask; |
2134 | + |
2135 | + // Ignore the events that do not interest us (or that we currently don't support or know |
2136 | + // how to translate into Qt events) |
2137 | + if (mirMotionAction != mir_motion_action_move |
2138 | + && mirMotionAction != mir_motion_action_down |
2139 | + && mirMotionAction != mir_motion_action_up |
2140 | + && mirMotionAction != mir_motion_action_pointer_down |
2141 | + && mirMotionAction != mir_motion_action_pointer_up |
2142 | + && mirMotionAction != mir_motion_action_cancel) { |
2143 | + return; |
2144 | + } |
2145 | + |
2146 | |
2147 | // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That |
2148 | // needs to be fixed as soon as the compat input lib adds query support. |
2149 | const float kMaxPressure = 1.28; |
2150 | - const QRect kWindowGeometry = window->geometry(); |
2151 | + const QRect kWindowGeometry = mQtWindowSystem->targetWindowGeometry(); |
2152 | QList<QWindowSystemInterface::TouchPoint> touchPoints; |
2153 | |
2154 | // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left |
2155 | @@ -257,7 +327,7 @@ |
2156 | touchPoints.append(touchPoint); |
2157 | } |
2158 | |
2159 | - switch (event.action & MirEventActionMask) { |
2160 | + switch (mirMotionAction) { |
2161 | case mir_motion_action_move: |
2162 | // No extra work needed. |
2163 | break; |
2164 | @@ -291,13 +361,17 @@ |
2165 | case mir_motion_action_scroll: |
2166 | case mir_motion_action_hover_enter: |
2167 | case mir_motion_action_hover_exit: |
2168 | - default: |
2169 | - qWarning() << "unhandled motion event action" << (int)(event.action & MirEventActionMask); |
2170 | + default: |
2171 | + // Should never reach this point. If so, it's a programming error. |
2172 | + qFatal("Trying to handle unsupported motion event action"); |
2173 | } |
2174 | |
2175 | + // Qt needs a happy, sane stream of touch events. So let's make sure we're not forwarding |
2176 | + // any insanity. |
2177 | + validateTouches(touchPoints); |
2178 | + |
2179 | // Touch event propagation. |
2180 | - QWindowSystemInterface::handleTouchEvent( |
2181 | - window, |
2182 | + mQtWindowSystem->handleTouchEvent( |
2183 | event.event_time / 1000000, //scales down the nsec_t (int64) to fit a ulong, precision lost but time difference suitable |
2184 | mTouchDevice, |
2185 | touchPoints); |
2186 | @@ -323,3 +397,86 @@ |
2187 | Q_UNUSED(device_id); |
2188 | Q_UNUSED(when); |
2189 | } |
2190 | + |
2191 | +void QtEventFeeder::validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints) |
2192 | +{ |
2193 | + QSet<int> updatedTouches; |
2194 | + |
2195 | + { |
2196 | + int i = 0; |
2197 | + while (i < touchPoints.count()) { |
2198 | + bool mustDiscardTouch = !validateTouch(touchPoints[i]); |
2199 | + if (mustDiscardTouch) { |
2200 | + touchPoints.removeAt(i); |
2201 | + } else { |
2202 | + updatedTouches.insert(touchPoints.at(i).id); |
2203 | + ++i; |
2204 | + } |
2205 | + } |
2206 | + } |
2207 | + |
2208 | + // Release all unmentioned touches. |
2209 | + { |
2210 | + QHash<int, QWindowSystemInterface::TouchPoint>::iterator it = mActiveTouches.begin(); |
2211 | + while (it != mActiveTouches.end()) { |
2212 | + if (!updatedTouches.contains(it.key())) { |
2213 | + qCWarning(QTMIR_MIR_INPUT) |
2214 | + << "There's a touch (id =" << it.key() << ") missing. Releasing it."; |
2215 | + it.value().state = Qt::TouchPointReleased; |
2216 | + touchPoints.append(it.value()); |
2217 | + it = mActiveTouches.erase(it); |
2218 | + } else { |
2219 | + ++it; |
2220 | + } |
2221 | + } |
2222 | + } |
2223 | +} |
2224 | + |
2225 | +bool QtEventFeeder::validateTouch(QWindowSystemInterface::TouchPoint &touchPoint) |
2226 | +{ |
2227 | + bool ok = true; |
2228 | + |
2229 | + switch (touchPoint.state) { |
2230 | + case Qt::TouchPointPressed: |
2231 | + if (mActiveTouches.contains(touchPoint.id)) { |
2232 | + qCWarning(QTMIR_MIR_INPUT) |
2233 | + << "Would press an already existing touch (id =" << touchPoint.id |
2234 | + << "). Making it move instead."; |
2235 | + touchPoint.state = Qt::TouchPointMoved; |
2236 | + } |
2237 | + mActiveTouches[touchPoint.id] = touchPoint; |
2238 | + break; |
2239 | + case Qt::TouchPointMoved: |
2240 | + if (!mActiveTouches.contains(touchPoint.id)) { |
2241 | + qCWarning(QTMIR_MIR_INPUT) |
2242 | + << "Would move a touch that wasn't pressed before (id =" << touchPoint.id |
2243 | + << "). Making it press instead."; |
2244 | + touchPoint.state = Qt::TouchPointPressed; |
2245 | + } |
2246 | + mActiveTouches[touchPoint.id] = touchPoint; |
2247 | + break; |
2248 | + case Qt::TouchPointStationary: |
2249 | + if (!mActiveTouches.contains(touchPoint.id)) { |
2250 | + qCWarning(QTMIR_MIR_INPUT) |
2251 | + << "There's an stationary touch that wasn't pressed before (id =" << touchPoint.id |
2252 | + << "). Making it press instead."; |
2253 | + touchPoint.state = Qt::TouchPointPressed; |
2254 | + } |
2255 | + mActiveTouches[touchPoint.id] = touchPoint; |
2256 | + break; |
2257 | + case Qt::TouchPointReleased: |
2258 | + if (!mActiveTouches.contains(touchPoint.id)) { |
2259 | + qCWarning(QTMIR_MIR_INPUT) |
2260 | + << "Would release a touch that wasn't pressed before (id =" << touchPoint.id |
2261 | + << "). Ignoring it."; |
2262 | + ok = false; |
2263 | + } else { |
2264 | + mActiveTouches.remove(touchPoint.id); |
2265 | + } |
2266 | + break; |
2267 | + default: |
2268 | + qFatal("QtEventFeeder: invalid touch state"); |
2269 | + } |
2270 | + |
2271 | + return ok; |
2272 | +} |
2273 | |
2274 | === modified file 'src/platforms/mirserver/qteventfeeder.h' |
2275 | --- src/platforms/mirserver/qteventfeeder.h 2014-07-18 20:23:35 +0000 |
2276 | +++ src/platforms/mirserver/qteventfeeder.h 2014-09-18 22:57:30 +0000 |
2277 | @@ -22,6 +22,8 @@ |
2278 | #include <mir/input/input_dispatcher.h> |
2279 | #include <mir/shell/input_targeter.h> |
2280 | |
2281 | +#include <qpa/qwindowsysteminterface.h> |
2282 | + |
2283 | class QTouchDevice; |
2284 | |
2285 | /* |
2286 | @@ -30,7 +32,29 @@ |
2287 | class QtEventFeeder : public mir::input::InputDispatcher |
2288 | { |
2289 | public: |
2290 | - QtEventFeeder(); |
2291 | + // Interface between QtEventFeeder and the actual QWindowSystemInterface functions |
2292 | + // and other related Qt methods and objects to enable replacing them with mocks in |
2293 | + // pure unit tests. |
2294 | + // TODO - Make it work with multimonitor scenarios |
2295 | + class QtWindowSystemInterface { |
2296 | + public: |
2297 | + virtual ~QtWindowSystemInterface() {} |
2298 | + virtual bool hasTargetWindow() = 0; |
2299 | + virtual QRect targetWindowGeometry() = 0; |
2300 | + virtual void registerTouchDevice(QTouchDevice *device) = 0; |
2301 | + virtual void handleExtendedKeyEvent(ulong timestamp, QEvent::Type type, int key, |
2302 | + Qt::KeyboardModifiers modifiers, |
2303 | + quint32 nativeScanCode, quint32 nativeVirtualKey, |
2304 | + quint32 nativeModifiers, |
2305 | + const QString& text = QString(), bool autorep = false, |
2306 | + ushort count = 1) = 0; |
2307 | + virtual void handleTouchEvent(ulong timestamp, QTouchDevice *device, |
2308 | + const QList<struct QWindowSystemInterface::TouchPoint> &points, |
2309 | + Qt::KeyboardModifiers mods = Qt::NoModifier) = 0; |
2310 | + }; |
2311 | + |
2312 | + QtEventFeeder(QtWindowSystemInterface *windowSystem = nullptr); |
2313 | + virtual ~QtEventFeeder(); |
2314 | |
2315 | static const int MirEventActionMask; |
2316 | static const int MirEventActionPointerIndexMask; |
2317 | @@ -45,8 +69,14 @@ |
2318 | private: |
2319 | void dispatchKey(MirKeyEvent const& event); |
2320 | void dispatchMotion(MirMotionEvent const& event); |
2321 | + void validateTouches(QList<QWindowSystemInterface::TouchPoint> &touchPoints); |
2322 | + bool validateTouch(QWindowSystemInterface::TouchPoint &touchPoint); |
2323 | |
2324 | QTouchDevice *mTouchDevice; |
2325 | + QtWindowSystemInterface *mQtWindowSystem; |
2326 | + |
2327 | + // Maps the id of an active touch to its last known state |
2328 | + QHash<int, QWindowSystemInterface::TouchPoint> mActiveTouches; |
2329 | }; |
2330 | |
2331 | #endif // MIR_QT_EVENT_FEEDER_H |
2332 | |
2333 | === modified file 'src/platforms/mirserver/sessionauthorizer.cpp' |
2334 | --- src/platforms/mirserver/sessionauthorizer.cpp 2014-07-18 08:53:13 +0000 |
2335 | +++ src/platforms/mirserver/sessionauthorizer.cpp 2014-09-18 22:57:30 +0000 |
2336 | @@ -16,6 +16,7 @@ |
2337 | |
2338 | #include "sessionauthorizer.h" |
2339 | #include "logging.h" |
2340 | +#include "tracepoints.h" // generated from tracepoints.tp |
2341 | |
2342 | // mir |
2343 | #include <mir/frontend/session_credentials.h> |
2344 | @@ -33,10 +34,13 @@ |
2345 | |
2346 | bool SessionAuthorizer::connection_is_allowed(SessionCredentials const& creds) |
2347 | { |
2348 | + tracepoint(qtmirserver, sessionAuthorizeStart); |
2349 | qCDebug(QTMIR_MIR_MESSAGES) << "SessionAuthorizer::connection_is_allowed - this=" << this << "pid=" << creds.pid(); |
2350 | bool authorized = true; |
2351 | |
2352 | Q_EMIT requestAuthorizationForSession(creds.pid(), authorized); // needs to block until authorized value returned |
2353 | + tracepoint(qtmirserver, sessionAuthorizeEnd); |
2354 | + |
2355 | return authorized; |
2356 | } |
2357 | |
2358 | |
2359 | === modified file 'src/platforms/mirserver/sessionlistener.cpp' |
2360 | --- src/platforms/mirserver/sessionlistener.cpp 2014-07-01 13:38:06 +0000 |
2361 | +++ src/platforms/mirserver/sessionlistener.cpp 2014-09-18 22:57:30 +0000 |
2362 | @@ -16,6 +16,7 @@ |
2363 | |
2364 | #include "sessionlistener.h" |
2365 | #include "logging.h" |
2366 | +#include "tracepoints.h" // generated from tracepoints.tp |
2367 | |
2368 | namespace ms = mir::scene; |
2369 | |
2370 | @@ -38,12 +39,14 @@ |
2371 | |
2372 | void SessionListener::starting(std::shared_ptr<ms::Session> const& session) |
2373 | { |
2374 | + tracepoint(qtmirserver, starting); |
2375 | qCDebug(QTMIR_MIR_MESSAGES) << "SessionListener::starting - this=" << this << "session=" << session.get(); |
2376 | Q_EMIT sessionStarting(session); |
2377 | } |
2378 | |
2379 | void SessionListener::stopping(std::shared_ptr<ms::Session> const& session) |
2380 | { |
2381 | + tracepoint(qtmirserver, stopping); |
2382 | qCDebug(QTMIR_MIR_MESSAGES) << "SessionListener::stopping - this=" << this << "session=" << session.get(); |
2383 | Q_EMIT sessionStopping(session); |
2384 | } |
2385 | @@ -62,6 +65,7 @@ |
2386 | |
2387 | void SessionListener::surface_created(ms::Session& session, std::shared_ptr<ms::Surface> const& surface) |
2388 | { |
2389 | + tracepoint(qtmirserver, surfaceCreated); |
2390 | qCDebug(QTMIR_MIR_MESSAGES) << "SessionListener::surface_created - this=" << this << "session=" << &session |
2391 | << "surface=" << surface.get(); |
2392 | Q_EMIT sessionCreatedSurface(&session, surface); |
2393 | @@ -69,6 +73,7 @@ |
2394 | |
2395 | void SessionListener::destroying_surface(ms::Session& session, std::shared_ptr<ms::Surface> const& surface) |
2396 | { |
2397 | + tracepoint(qtmirserver, surfaceDestroyed); |
2398 | qCDebug(QTMIR_MIR_MESSAGES) << "SessionListener::destroying_surface - this=" << this << "session=" << &session |
2399 | << "surface=" << surface.get(); |
2400 | Q_EMIT sessionDestroyingSurface(&session, surface); |
2401 | |
2402 | === added file 'src/platforms/mirserver/tracepoints.tp' |
2403 | --- src/platforms/mirserver/tracepoints.tp 1970-01-01 00:00:00 +0000 |
2404 | +++ src/platforms/mirserver/tracepoints.tp 2014-09-18 22:57:30 +0000 |
2405 | @@ -0,0 +1,10 @@ |
2406 | +TRACEPOINT_EVENT(qtmirserver, starting, TP_ARGS(0), TP_FIELDS()) |
2407 | +TRACEPOINT_EVENT(qtmirserver, stopping, TP_ARGS(0), TP_FIELDS()) |
2408 | +TRACEPOINT_EVENT(qtmirserver, surfaceCreated, TP_ARGS(0), TP_FIELDS()) |
2409 | +TRACEPOINT_EVENT(qtmirserver, surfaceDestroyed, TP_ARGS(0), TP_FIELDS()) |
2410 | + |
2411 | +TRACEPOINT_EVENT(qtmirserver, sessionAuthorizeStart, TP_ARGS(0), TP_FIELDS()) |
2412 | +TRACEPOINT_EVENT(qtmirserver, sessionAuthorizeEnd, TP_ARGS(0), TP_FIELDS()) |
2413 | + |
2414 | +TRACEPOINT_EVENT(qtmirserver, surfacePlacementStart, TP_ARGS(0), TP_FIELDS()) |
2415 | +TRACEPOINT_EVENT(qtmirserver, surfacePlacementEnd, TP_ARGS(0), TP_FIELDS()) |
2416 | |
2417 | === added file 'tests/google-mock.pri' |
2418 | --- tests/google-mock.pri 1970-01-01 00:00:00 +0000 |
2419 | +++ tests/google-mock.pri 2014-09-18 22:57:30 +0000 |
2420 | @@ -0,0 +1,24 @@ |
2421 | +GMOCK_SOURCES = /usr/src/gmock/src/gmock-all.cc \ |
2422 | + /usr/src/gmock/src/gmock_main.cc \ |
2423 | + /usr/src/gtest/src/gtest-all.cc |
2424 | + |
2425 | +QMAKE_EXTRA_COMPILERS += gmock_compiler |
2426 | +gmock_compiler.input = GMOCK_SOURCES |
2427 | +gmock_compiler.output = $${OUT_PWD}/${QMAKE_FILE_BASE}.o |
2428 | +gmock_compiler.commands = g++ \ |
2429 | + -I/usr/src/gtest \ |
2430 | + -I/usr/src/gmock \ |
2431 | + -c ${QMAKE_FILE_IN} \ |
2432 | + -o ${QMAKE_FILE_OUT} |
2433 | +gmock_compiler.CONFIG = no_link |
2434 | + |
2435 | +QMAKE_EXTRA_COMPILERS += gmock_linker |
2436 | +gmock_linker.depends = $${OUT_PWD}/gmock-all.o \ |
2437 | + $${OUT_PWD}/gmock_main.o \ |
2438 | + $${OUT_PWD}/gtest-all.o |
2439 | +gmock_linker.input = GMOCK_SOURCES |
2440 | +gmock_linker.output = $${OUT_PWD}/libgmock.a |
2441 | +gmock_linker.commands = ar -rv ${QMAKE_FILE_OUT} $${OUT_PWD}/gmock-all.o $${OUT_PWD}/gmock_main.o $${OUT_PWD}/gtest-all.o |
2442 | +gmock_linker.CONFIG = combine explicit_dependencies no_link target_predeps |
2443 | + |
2444 | +LIBS += $${OUT_PWD}/libgmock.a |
2445 | |
2446 | === added directory 'tests/mirserver' |
2447 | === added directory 'tests/mirserver/QtEventFeeder' |
2448 | === added file 'tests/mirserver/QtEventFeeder/QtEventFeeder.pro' |
2449 | --- tests/mirserver/QtEventFeeder/QtEventFeeder.pro 1970-01-01 00:00:00 +0000 |
2450 | +++ tests/mirserver/QtEventFeeder/QtEventFeeder.pro 2014-09-18 22:57:30 +0000 |
2451 | @@ -0,0 +1,16 @@ |
2452 | +include(../../test-includes.pri) |
2453 | + |
2454 | +TARGET = QtEventFeederTest |
2455 | + |
2456 | +QT += gui-private |
2457 | + |
2458 | +INCLUDEPATH += \ |
2459 | + ../../../src/platforms/mirserver \ |
2460 | + ../../../src/common |
2461 | + |
2462 | +SOURCES += \ |
2463 | + qteventfeeder_test.cpp \ |
2464 | + ../../../src/common/debughelpers.cpp |
2465 | + |
2466 | +LIBS += -Wl,-rpath,$${OUT_PWD}/../../../src/platforms/mirserver \ |
2467 | + -L../../../src/platforms/mirserver -lqpa-mirserver |
2468 | |
2469 | === added file 'tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h' |
2470 | --- tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 1970-01-01 00:00:00 +0000 |
2471 | +++ tests/mirserver/QtEventFeeder/mock_qtwindowsystem.h 2014-09-18 22:57:30 +0000 |
2472 | @@ -0,0 +1,65 @@ |
2473 | +/* |
2474 | + * Copyright (C) 2014 Canonical, Ltd. |
2475 | + * |
2476 | + * This program is free software: you can redistribute it and/or modify it under |
2477 | + * the terms of the GNU Lesser General Public License version 3, as published by |
2478 | + * the Free Software Foundation. |
2479 | + * |
2480 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
2481 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2482 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2483 | + * Lesser General Public License for more details. |
2484 | + * |
2485 | + * You should have received a copy of the GNU Lesser General Public License |
2486 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2487 | + * |
2488 | + */ |
2489 | + |
2490 | +#ifndef MOCK_QTWINDOWSYSTEM_H |
2491 | +#define MOCK_QTWINDOWSYSTEM_H |
2492 | + |
2493 | +#include <qteventfeeder.h> |
2494 | + |
2495 | +class MockQtWindowSystem : public QtEventFeeder::QtWindowSystemInterface { |
2496 | +public: |
2497 | + MOCK_METHOD0(hasTargetWindow, bool()); |
2498 | + MOCK_METHOD0(targetWindowGeometry, QRect()); |
2499 | + MOCK_METHOD1(registerTouchDevice, void(QTouchDevice* device)); |
2500 | + MOCK_METHOD10(handleExtendedKeyEvent, void(ulong timestamp, QEvent::Type type, int key, |
2501 | + Qt::KeyboardModifiers modifiers, |
2502 | + quint32 nativeScanCode, quint32 nativeVirtualKey, |
2503 | + quint32 nativeModifiers, |
2504 | + const QString& text, bool autorep, |
2505 | + ushort count)); |
2506 | + MOCK_METHOD4(handleTouchEvent, void(ulong timestamp, QTouchDevice *device, |
2507 | + const QList<struct QWindowSystemInterface::TouchPoint> &points, |
2508 | + Qt::KeyboardModifiers mods)); |
2509 | +}; |
2510 | + |
2511 | +namespace testing |
2512 | +{ |
2513 | + |
2514 | +MATCHER(IsPressed, std::string(negation ? "isn't" : "is") + " pressed") |
2515 | +{ |
2516 | + return arg.state == Qt::TouchPointPressed; |
2517 | +} |
2518 | + |
2519 | +MATCHER(IsReleased, std::string(negation ? "isn't" : "is") + " released") |
2520 | +{ |
2521 | + return arg.state == Qt::TouchPointReleased; |
2522 | +} |
2523 | + |
2524 | +MATCHER(StateIsMoved, "state " + std::string(negation ? "isn't" : "is") + " 'moved'") |
2525 | +{ |
2526 | + return arg.state == Qt::TouchPointMoved; |
2527 | +} |
2528 | + |
2529 | +MATCHER_P(HasId, expectedId, "id " + std::string(negation ? "isn't " : "is ") + PrintToString(expectedId)) |
2530 | +{ |
2531 | + return arg.id == expectedId; |
2532 | +} |
2533 | + |
2534 | +} // namespace testing |
2535 | + |
2536 | + |
2537 | +#endif // MOCK_QTWINDOWSYSTEM_H |
2538 | |
2539 | === added file 'tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp' |
2540 | --- tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 1970-01-01 00:00:00 +0000 |
2541 | +++ tests/mirserver/QtEventFeeder/qteventfeeder_test.cpp 2014-09-18 22:57:30 +0000 |
2542 | @@ -0,0 +1,224 @@ |
2543 | +/* |
2544 | + * Copyright (C) 2014 Canonical, Ltd. |
2545 | + * |
2546 | + * This program is free software: you can redistribute it and/or modify it under |
2547 | + * the terms of the GNU Lesser General Public License version 3, as published by |
2548 | + * the Free Software Foundation. |
2549 | + * |
2550 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
2551 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2552 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2553 | + * Lesser General Public License for more details. |
2554 | + * |
2555 | + * You should have received a copy of the GNU Lesser General Public License |
2556 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2557 | + * |
2558 | + */ |
2559 | + |
2560 | +#include <gmock/gmock.h> |
2561 | +#include <gtest/gtest.h> |
2562 | + |
2563 | +#include <qteventfeeder.h> |
2564 | +#include <debughelpers.h> |
2565 | + |
2566 | +#include <QGuiApplication> |
2567 | +#include <QWindow> |
2568 | + |
2569 | +#include "mock_qtwindowsystem.h" |
2570 | + |
2571 | +using ::testing::_; |
2572 | +using ::testing::AllOf; |
2573 | +using ::testing::AnyNumber; |
2574 | +using ::testing::Contains; |
2575 | +using ::testing::AtLeast; |
2576 | +using ::testing::InSequence; |
2577 | +using ::testing::Mock; |
2578 | +using ::testing::SizeIs; |
2579 | +using ::testing::Return; |
2580 | + |
2581 | +// own gmock extensions |
2582 | +using ::testing::IsPressed; |
2583 | +using ::testing::IsReleased; |
2584 | +using ::testing::HasId; |
2585 | +using ::testing::StateIsMoved; |
2586 | + |
2587 | +void PrintTo(const struct QWindowSystemInterface::TouchPoint& touchPoint, ::std::ostream* os) { |
2588 | + *os << "TouchPoint(" |
2589 | + << "id=" << touchPoint.id |
2590 | + << "," << touchPointStateToString(touchPoint.state) |
2591 | + << ")"; |
2592 | +} |
2593 | + |
2594 | +class QtEventFeederTest : public ::testing::Test { |
2595 | +protected: |
2596 | + void SetUp() override; |
2597 | + void TearDown() override; |
2598 | + |
2599 | + void setIrrelevantMockWindowSystemExpectations(); |
2600 | + |
2601 | + MockQtWindowSystem *mockWindowSystem; |
2602 | + QtEventFeeder *qtEventFeeder; |
2603 | +}; |
2604 | + |
2605 | +void QtEventFeederTest::SetUp() |
2606 | +{ |
2607 | + mockWindowSystem = new MockQtWindowSystem; |
2608 | + |
2609 | + EXPECT_CALL(*mockWindowSystem, registerTouchDevice(_)); |
2610 | + |
2611 | + qtEventFeeder = new QtEventFeeder(mockWindowSystem); |
2612 | + |
2613 | + ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem)); |
2614 | +} |
2615 | + |
2616 | +void QtEventFeederTest::TearDown() |
2617 | +{ |
2618 | + // mockWindowSystem will be deleted by QtEventFeeder |
2619 | + delete qtEventFeeder; |
2620 | +} |
2621 | + |
2622 | +void QtEventFeederTest::setIrrelevantMockWindowSystemExpectations() |
2623 | +{ |
2624 | + EXPECT_CALL(*mockWindowSystem, hasTargetWindow()) |
2625 | + .Times(AnyNumber()) |
2626 | + .WillRepeatedly(Return(true)); |
2627 | + EXPECT_CALL(*mockWindowSystem, targetWindowGeometry()) |
2628 | + .Times(AnyNumber()) |
2629 | + .WillRepeatedly(Return(QRect(0,0,100,100))); |
2630 | +} |
2631 | + |
2632 | + |
2633 | +/* |
2634 | + Mir sends a MirEvent([touch(id=0,state=pressed)]. QtEventFeeder happily forwards that to Qt. |
2635 | + |
2636 | + Then, Mir sends a MirEvent([touch(id=1,state=pressed)]). In MirEvents, every single active touch |
2637 | + point must be listed in the event even if it didn't change at all in the meantime. So that's a bug. |
2638 | + But instead of crashing or forwarding the bogus event stream down to Qt, QtEventFeeder should attempt |
2639 | + to fix the situation by synthesizing a touch[id=1,state=released] to be send along with the |
2640 | + touch(id=1,state=pressed) it got. So that Qt receives a correct touch event stream. |
2641 | + */ |
2642 | +TEST_F(QtEventFeederTest, GenerateMissingTouchEnd) |
2643 | +{ |
2644 | + |
2645 | + setIrrelevantMockWindowSystemExpectations(); |
2646 | + |
2647 | + EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(1), |
2648 | + Contains(AllOf(HasId(0), |
2649 | + IsPressed()))),_)).Times(1); |
2650 | + |
2651 | + MirEvent mirEvent; |
2652 | + mirEvent.type = mir_event_type_motion; |
2653 | + mirEvent.motion.pointer_count = 1; |
2654 | + mirEvent.motion.pointer_coordinates[0].id = 0; |
2655 | + mirEvent.motion.pointer_coordinates[0].x = 10; |
2656 | + mirEvent.motion.pointer_coordinates[0].y = 10; |
2657 | + mirEvent.motion.pointer_coordinates[0].touch_major = 1; |
2658 | + mirEvent.motion.pointer_coordinates[0].touch_minor = 1; |
2659 | + mirEvent.motion.pointer_coordinates[0].pressure = 10; |
2660 | + mirEvent.motion.action = mir_motion_action_down; |
2661 | + mirEvent.motion.event_time = 123 * 1000000; |
2662 | + |
2663 | + qtEventFeeder->dispatch(mirEvent); |
2664 | + |
2665 | + ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem)); |
2666 | + |
2667 | + setIrrelevantMockWindowSystemExpectations(); |
2668 | + |
2669 | + EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(2), |
2670 | + Contains(AllOf(HasId(0),IsReleased())), |
2671 | + Contains(AllOf(HasId(1),IsPressed())) |
2672 | + ),_)).Times(1); |
2673 | + |
2674 | + mirEvent.type = mir_event_type_motion; |
2675 | + mirEvent.motion.pointer_count = 1; |
2676 | + mirEvent.motion.pointer_coordinates[0].id = 1; |
2677 | + mirEvent.motion.pointer_coordinates[0].x = 20; |
2678 | + mirEvent.motion.pointer_coordinates[0].y = 20; |
2679 | + mirEvent.motion.pointer_coordinates[0].touch_major = 1; |
2680 | + mirEvent.motion.pointer_coordinates[0].touch_minor = 1; |
2681 | + mirEvent.motion.pointer_coordinates[0].pressure = 10; |
2682 | + mirEvent.motion.action = mir_motion_action_down; |
2683 | + mirEvent.motion.event_time = 125 * 1000000; |
2684 | + |
2685 | + qtEventFeeder->dispatch(mirEvent); |
2686 | + |
2687 | + ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem)); |
2688 | +} |
2689 | + |
2690 | +TEST_F(QtEventFeederTest, PressSameTouchTwice) |
2691 | +{ |
2692 | + setIrrelevantMockWindowSystemExpectations(); |
2693 | + |
2694 | + EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(1), |
2695 | + Contains(AllOf(HasId(0), |
2696 | + IsPressed()))),_)).Times(1); |
2697 | + |
2698 | + MirEvent mirEvent; |
2699 | + mirEvent.type = mir_event_type_motion; |
2700 | + mirEvent.motion.pointer_count = 1; |
2701 | + mirEvent.motion.pointer_coordinates[0].id = 0; |
2702 | + mirEvent.motion.pointer_coordinates[0].x = 10; |
2703 | + mirEvent.motion.pointer_coordinates[0].y = 10; |
2704 | + mirEvent.motion.pointer_coordinates[0].touch_major = 1; |
2705 | + mirEvent.motion.pointer_coordinates[0].touch_minor = 1; |
2706 | + mirEvent.motion.pointer_coordinates[0].pressure = 10; |
2707 | + mirEvent.motion.action = mir_motion_action_down; |
2708 | + mirEvent.motion.event_time = 123 * 1000000; |
2709 | + |
2710 | + qtEventFeeder->dispatch(mirEvent); |
2711 | + |
2712 | + ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem)); |
2713 | + |
2714 | + setIrrelevantMockWindowSystemExpectations(); |
2715 | + |
2716 | + EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,AllOf(SizeIs(1), |
2717 | + Contains(AllOf(HasId(0), StateIsMoved())) |
2718 | + ),_)).Times(1); |
2719 | + |
2720 | + mirEvent.type = mir_event_type_motion; |
2721 | + mirEvent.motion.pointer_count = 1; |
2722 | + mirEvent.motion.pointer_coordinates[0].id = 0; |
2723 | + mirEvent.motion.pointer_coordinates[0].x = 20; |
2724 | + mirEvent.motion.pointer_coordinates[0].y = 20; |
2725 | + mirEvent.motion.pointer_coordinates[0].touch_major = 1; |
2726 | + mirEvent.motion.pointer_coordinates[0].touch_minor = 1; |
2727 | + mirEvent.motion.pointer_coordinates[0].pressure = 10; |
2728 | + mirEvent.motion.action = mir_motion_action_down; |
2729 | + mirEvent.motion.event_time = 125 * 1000000; |
2730 | + |
2731 | + qtEventFeeder->dispatch(mirEvent); |
2732 | + |
2733 | + ASSERT_TRUE(Mock::VerifyAndClearExpectations(mockWindowSystem)); |
2734 | +} |
2735 | + |
2736 | +TEST_F(QtEventFeederTest, IgnoreHovering) |
2737 | +{ |
2738 | + setIrrelevantMockWindowSystemExpectations(); |
2739 | + EXPECT_CALL(*mockWindowSystem, handleTouchEvent(_,_,_,_)).Times(0); |
2740 | + |
2741 | + MirEvent mirEvent; |
2742 | + mirEvent.type = mir_event_type_motion; |
2743 | + mirEvent.motion.pointer_count = 1; |
2744 | + mirEvent.motion.pointer_coordinates[0].id = 0; |
2745 | + mirEvent.motion.pointer_coordinates[0].x = 10; |
2746 | + mirEvent.motion.pointer_coordinates[0].y = 10; |
2747 | + mirEvent.motion.pointer_coordinates[0].touch_major = 1; |
2748 | + mirEvent.motion.pointer_coordinates[0].touch_minor = 1; |
2749 | + mirEvent.motion.pointer_coordinates[0].pressure = 10; |
2750 | + mirEvent.motion.action = mir_motion_action_hover_enter; |
2751 | + mirEvent.motion.event_time = 123 * 1000000; |
2752 | + |
2753 | + qtEventFeeder->dispatch(mirEvent); |
2754 | + |
2755 | + mirEvent.motion.pointer_coordinates[0].x = 20; |
2756 | + mirEvent.motion.pointer_coordinates[0].y = 20; |
2757 | + mirEvent.motion.action = mir_motion_action_hover_move; |
2758 | + mirEvent.motion.event_time = 125 * 1000000; |
2759 | + |
2760 | + qtEventFeeder->dispatch(mirEvent); |
2761 | + |
2762 | + mirEvent.motion.action = mir_motion_action_hover_exit; |
2763 | + mirEvent.motion.event_time = 127 * 1000000; |
2764 | + |
2765 | + qtEventFeeder->dispatch(mirEvent); |
2766 | +} |
2767 | |
2768 | === added file 'tests/mirserver/mirserver.pro' |
2769 | --- tests/mirserver/mirserver.pro 1970-01-01 00:00:00 +0000 |
2770 | +++ tests/mirserver/mirserver.pro 2014-09-18 22:57:30 +0000 |
2771 | @@ -0,0 +1,2 @@ |
2772 | +TEMPLATE = subdirs |
2773 | +SUBDIRS = QtEventFeeder |
2774 | |
2775 | === modified file 'tests/modules/ApplicationManager/application_manager_test.cpp' |
2776 | --- tests/modules/ApplicationManager/application_manager_test.cpp 2014-08-29 10:18:57 +0000 |
2777 | +++ tests/modules/ApplicationManager/application_manager_test.cpp 2014-09-18 22:57:30 +0000 |
2778 | @@ -25,6 +25,7 @@ |
2779 | #include "qtmir_test.h" |
2780 | |
2781 | using namespace qtmir; |
2782 | +using mir::scene::MockSession; |
2783 | |
2784 | namespace ms = mir::scene; |
2785 | |
2786 | @@ -1774,7 +1775,7 @@ |
2787 | }).detach(); |
2788 | })); |
2789 | |
2790 | - auto mockSurface = std::make_shared<MockSurface>(); |
2791 | + auto mockSurface = std::make_shared<ms::MockSurface>(); |
2792 | EXPECT_CALL(*session, default_surface()).WillRepeatedly(Return(mockSurface)); |
2793 | |
2794 | { |
2795 | @@ -1826,7 +1827,7 @@ |
2796 | }).detach(); |
2797 | })); |
2798 | |
2799 | - auto mockSurface = std::make_shared<MockSurface>(); |
2800 | + auto mockSurface = std::make_shared<ms::MockSurface>(); |
2801 | EXPECT_CALL(*session, default_surface()).WillRepeatedly(Return(mockSurface)); |
2802 | |
2803 | { |
2804 | |
2805 | === added directory 'tests/modules/DesktopFileReader' |
2806 | === added file 'tests/modules/DesktopFileReader/DesktopFileReader.pro' |
2807 | --- tests/modules/DesktopFileReader/DesktopFileReader.pro 1970-01-01 00:00:00 +0000 |
2808 | +++ tests/modules/DesktopFileReader/DesktopFileReader.pro 2014-09-18 22:57:30 +0000 |
2809 | @@ -0,0 +1,15 @@ |
2810 | +include(../../test-includes.pri) |
2811 | +include(../common/common.pri) |
2812 | + |
2813 | +TARGET = desktopfilereader_test |
2814 | + |
2815 | +SOURCES += \ |
2816 | + desktopfilereader_test.cpp |
2817 | + |
2818 | +OTHER_FILES += \ |
2819 | + calculator.desktop |
2820 | + |
2821 | +# Copy to build directory |
2822 | +for(FILE, OTHER_FILES){ |
2823 | + QMAKE_POST_LINK += $$quote(cp $${PWD}/$${FILE} $${OUT_PWD}$$escape_expand(\\n\\t)) |
2824 | +} |
2825 | |
2826 | === added file 'tests/modules/DesktopFileReader/calculator.desktop' |
2827 | --- tests/modules/DesktopFileReader/calculator.desktop 1970-01-01 00:00:00 +0000 |
2828 | +++ tests/modules/DesktopFileReader/calculator.desktop 2014-09-18 22:57:30 +0000 |
2829 | @@ -0,0 +1,227 @@ |
2830 | +[Desktop Entry] |
2831 | +Name=Calculator |
2832 | +Name[am]=መደመሪያ |
2833 | +Name[ar]=الآلة الحاسبة |
2834 | +Name[ast]=Calculadora |
2835 | +Name[az]=Kalkulyator |
2836 | +Name[be]=Калькулятар |
2837 | +Name[bg]=Калкулатор |
2838 | +Name[br]=Jederez |
2839 | +Name[bs]=Kalkulator |
2840 | +Name[ca]=Calculadora |
2841 | +Name[cs]=Kalkulačka |
2842 | +Name[cy]=Cyfrifiannell |
2843 | +Name[da]=Lommeregner |
2844 | +Name[de]=Taschenrechner |
2845 | +Name[el]=Αριθμομηχανή |
2846 | +Name[en_AU]=Calculator |
2847 | +Name[en_CA]=Calculator |
2848 | +Name[en_GB]=Calculator |
2849 | +Name[es]=Calculadora |
2850 | +Name[eu]=Kalkulagailua |
2851 | +Name[fa]=ماشینحساب |
2852 | +Name[fi]=Laskin |
2853 | +Name[fr]=Calculatrice |
2854 | +Name[gd]=An t-àireamhair |
2855 | +Name[gl]=Calculadora |
2856 | +Name[gu]=કેલ્ક્યુલેટર |
2857 | +Name[he]=מחשבון |
2858 | +Name[hi]=कैलकुलेटर |
2859 | +Name[hu]=Számológép |
2860 | +Name[id]=Kalkulator |
2861 | +Name[is]=Reiknivél |
2862 | +Name[it]=Calcolatrice |
2863 | +Name[ja]=電卓 |
2864 | +Name[km]=ម៉ាស៊ីនគិតលេខ |
2865 | +Name[ko]=계산기 |
2866 | +Name[lv]=Kalkulators |
2867 | +Name[mr]=गणनयंत्र |
2868 | +Name[ms]=Kalkulator |
2869 | +Name[my]=ဂဏန်းတွက်စက် |
2870 | +Name[nb]=Kalkulator |
2871 | +Name[ne]=क्याल्कुलेटर |
2872 | +Name[nl]=Rekenmachine |
2873 | +Name[pa]=ਕੈਲਕੂਲੇਟਰ |
2874 | +Name[pl]=Kalkulator |
2875 | +Name[pt]=Calculadora |
2876 | +Name[pt_BR]=Calculadora |
2877 | +Name[ro]=Calculator |
2878 | +Name[ru]=Калькулятор |
2879 | +Name[sa]=सङ्कलकम् |
2880 | +Name[shn]=ၸၢၵ်ႈၼပ့်သွၼ် |
2881 | +Name[sl]=Računalo |
2882 | +Name[sr]=Калкулатор |
2883 | +Name[sv]=Kalkylator |
2884 | +Name[ta]=கணிப்பான் |
2885 | +Name[te]=గణన పరికరం |
2886 | +Name[tr]=Hesap Makinesi |
2887 | +Name[ug]=ھېسابلىغۇچ |
2888 | +Name[uk]=Калькулятор |
2889 | +Name[zh_CN]=计算器 |
2890 | +Name[zh_HK]=計數機 |
2891 | +Name[zh_TW]=計算機 |
2892 | +Comment=A simple calculator for Ubuntu. |
2893 | +Comment[am]=ለ ኡቡንቱ ቀላል መደመሪያ |
2894 | +Comment[ar]=آلة حاسبة بسيطة لأوبونتو. |
2895 | +Comment[ast]=Una calculadora cenciella pa Ubuntu. |
2896 | +Comment[az]=Ubuntu üçün sadә kalkulyator. |
2897 | +Comment[br]=Ur jederez eeun evit Ubuntu. |
2898 | +Comment[ca]=Una calculadora simple per a l'Ubuntu. |
2899 | +Comment[cy]=Cyfrifiannell hawdd ar gyfer Ubuntu. |
2900 | +Comment[da]=En simpel lommeregner til Ubuntu. |
2901 | +Comment[de]=Ein einfach Tachenrechner für Ubuntu. |
2902 | +Comment[el]=Μια απλή αριθμομηχανή για το Ubuntu |
2903 | +Comment[en_AU]=A simple calculator for Ubuntu. |
2904 | +Comment[en_GB]=A simple calculator for Ubuntu. |
2905 | +Comment[es]=Una calculadora sencilla para Ubuntu. |
2906 | +Comment[eu]=Ubunturako kalkulagailu sinplea. |
2907 | +Comment[fa]=یک ماشین حساب ساده برای اوبونتو. |
2908 | +Comment[fi]=Laskin Ubuntulle. |
2909 | +Comment[fr]=Une calculatrice simple pour Ubuntu. |
2910 | +Comment[gd]=Àireamhair simplidh airson Ubuntu. |
2911 | +Comment[gl]=Calculadora sinxela para Ubuntu. |
2912 | +Comment[he]=מחשבון פשוט לאובונטו. |
2913 | +Comment[hu]=Egyszerű számológép Ubuntuhoz. |
2914 | +Comment[is]=Einföld reiknivél |
2915 | +Comment[it]=Una semplice calcolatrice per Ubuntu. |
2916 | +Comment[ja]=Ubuntu用のシンプルな電卓です。 |
2917 | +Comment[km]=ម៉ាស៊ីនគិតលេខធម្មតាសម្រាប់ Ubuntu ។ |
2918 | +Comment[ko]=우분투를 위한 간단한 계산기 |
2919 | +Comment[lv]=Vienkāršs kalkulators priekš Ubuntu |
2920 | +Comment[nb]=En enkel kalkulator for Ubuntu. |
2921 | +Comment[ne]=Ubuntu को लागि एक सरल कैलकुलेटर। |
2922 | +Comment[nl]=Een eenvoudige rekenmachine voor Ubuntu. |
2923 | +Comment[pa]=ਉਬੰਤੂ ਲਈ ਇੱਕ ਸਧਾਰਨ ਕੈਲਕੂਲੇਟਰ |
2924 | +Comment[pl]=Prosty kalkulator dla Ubuntu |
2925 | +Comment[pt]=Uma calculadora simples para o Ubuntu. |
2926 | +Comment[pt_BR]=Uma simples calculadora para Ubuntu |
2927 | +Comment[ro]=Un calculator simplu pentru Ubuntu. |
2928 | +Comment[ru]=Простой калькулятор для Ubuntu |
2929 | +Comment[sa]=Ubuntu इत्यस्मा एकं सरलं सङ्कलकम्। |
2930 | +Comment[sl]=Preprost kalkulator za Ubuntu. |
2931 | +Comment[sr]=Једноставан калкулатор за Убунту |
2932 | +Comment[sv]=En enkel kalkylator för Ubuntu. |
2933 | +Comment[tr]=Ubuntu için sade bir hesap makinesi. |
2934 | +Comment[ug]=ئاددىي ھېسابلىغۇچى |
2935 | +Comment[uk]=Простий калькулятор для Ubuntu. |
2936 | +Comment[zh_CN]=Ubuntu 简易计算器 |
2937 | +Comment[zh_TW]=Ubuntu 簡易計算機。 |
2938 | +Keywords=math;addition;subtraction;multiplication;division; |
2939 | +Keywords[am]=ሂሳብ;መደመሪያ;መቀነሻ;ማባዣ;ማካፈያ; |
2940 | +Keywords[ar]=رياضة;ياضيات;حساب;حسابات;جمع;طرح;ضرب;قسمة; |
2941 | +Keywords[ast]=matemática;suma;resta;multiplicación;división; |
2942 | +Keywords[az]=riyaziyyat;әlavә etmә;çıxma;vurma;bölmә;toplama; |
2943 | +Keywords[br]=matematikoù;sammadenn;lamadenn;lieskementadenn;rannadenn; |
2944 | +Keywords[ca]=suma;resta;calculadora;multiplica;divideix |
2945 | +Keywords[da]=matematik;plus;minus;gange;dividere;beregning;lommeregner; |
2946 | +Keywords[de]=Mathe;Mathematik;Multiplikation;Subtraktion;Addition;Division; |
2947 | +Keywords[en_AU]=math;addition;subtraction;multiplication;division; |
2948 | +Keywords[en_GB]=maths;addition;subtraction;multiplication;division; |
2949 | +Keywords[es]=matemática;suma;resta;multiplicación;división; |
2950 | +Keywords[eu]=matematikak;gehitu;kendu;biderkatu;zatitu; |
2951 | +Keywords[fa]=حساب;جمع;تفریق;ضرب;تقسیم |
2952 | +Keywords[fi]=math;addition;subtraction;multiplication;division;matematiikka;lisäys;vähennys;kertaus;jakaminen; |
2953 | +Keywords[fr]=math;addition;soustraction;multiplication;division; |
2954 | +Keywords[gd]=math;addition;subtraction;multiplication;division;matamataig;roinneadh;toirt air falbh;cur ris;iomadadh |
2955 | +Keywords[gl]=matemáticas;suma;resta;multiplicación;división; |
2956 | +Keywords[he]=מתמטיקה;חשבון;חיבור;חיסור;כפל;חילוק; |
2957 | +Keywords[hu]=számolás;összeadás;kivonás;szorzás;osztás; |
2958 | +Keywords[is]=reikna;samlagning;frádráttur;margföldun;deiling |
2959 | +Keywords[it]=matematica;addizioni;sottrazioni;moltiplicazioni;divisioni; |
2960 | +Keywords[ja]=math;addition;subtraction;multiplication;division;計算;電卓;足し算;引き算;かけ算;わり算; |
2961 | +Keywords[km]=math;addition;subtraction;multiplication;division; |
2962 | +Keywords[ko]=수학;덧셈;뺄셈;곱셈;나눗셈; |
2963 | +Keywords[nb]=matte;addisjon;subtraksjon;multiplikasjon;divisjon; |
2964 | +Keywords[ne]=गणित; जोड्; घटाउ; गुणन; विभाजन; |
2965 | +Keywords[nl]=math;addition;subtraction;multiplication;division;optellen;aftrekken;vermenigvuldigen;delen; |
2966 | +Keywords[pa]=ਹਿਸਾਬ;ਜੋੜ;ਘਟਾਉ;ਗੁਣਾ;ਭਾਗ; |
2967 | +Keywords[pl]=liczenie;dodawanie;odejmowanie;mnożenie;dzielenie; |
2968 | +Keywords[pt]=matemática;soma;subtracção;multiplicação;divisão; |
2969 | +Keywords[pt_BR]=matemática;adição;subtração;multiplicação;divisão |
2970 | +Keywords[ro]=matematică;adunare;scădere;înmulțire;împărțire |
2971 | +Keywords[ru]=математика;сложение;умножение;деление; |
2972 | +Keywords[sa]=गणितम्;योजनम्;वियोजनम्;गुणनम्;विभाजनम्; |
2973 | +Keywords[sl]=matematika;seštevanje;odštevanje;množenje;deljenje; |
2974 | +Keywords[sr]=математика;сабирање;одузимање;множење;дељење;рачунање;дигитрон; |
2975 | +Keywords[sv]=matematik;addition;substraktion;multiplikation;division |
2976 | +Keywords[tr]=matematik;ekleme;çıkarma;çarpma;bölme;toplama |
2977 | +Keywords[ug]=ماتېماتىكا;قوشۇش;ئېلىش;كۆپەيتىش;بۆلۈش; |
2978 | +Keywords[uk]=math;addition;subtraction;multiplication;division;математика;додавання;віднімання;множення;ділення;калькулятор; |
2979 | +Keywords[zh_CN]=数学;加;减;乘;除; |
2980 | +Keywords[zh_TW]=math;addition;subtraction;multiplication;division;數學;加;減;乘;除; |
2981 | +Type=Application |
2982 | +Terminal=false |
2983 | +Exec=aa-exec-click -p com.ubuntu.calculator_calculator_1.3.329 -- qmlscene -qt5 ubuntu-calculator-app.qml |
2984 | +Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png |
2985 | +X-Ubuntu-Touch=true |
2986 | +X-Ubuntu-StageHint=SideStage |
2987 | +X-Ubuntu-Default-Department-ID=accessories |
2988 | +Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator |
2989 | +X-Ubuntu-Old-Icon=calculator-app@30.png |
2990 | +X-Ubuntu-Application-ID=com.ubuntu.calculator_calculator_1.3.329 |
2991 | +X-Ubuntu-Splash-Show-Header=True |
2992 | +X-Ubuntu-Splash-Color=#aabbcc |
2993 | +X-Ubuntu-Splash-Color-Header=purple |
2994 | +X-Ubuntu-Splash-Color-Footer=#deadbeefda |
2995 | +X-Ubuntu-Splash-Image=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png |
2996 | +X-Ubuntu-Splash-Title=Calculator 2.0 |
2997 | +X-Ubuntu-Splash-Title[am]=መደመሪያ 2.0 |
2998 | +X-Ubuntu-Splash-Title[ar]=الآلة 2.0الحاسبة |
2999 | +X-Ubuntu-Splash-Title[ast]=Calculadora 2.0 |
3000 | +X-Ubuntu-Splash-Title[az]=Kalkulyator 2.0 |
3001 | +X-Ubuntu-Splash-Title[be]=Калькулятар 2.0 |
3002 | +X-Ubuntu-Splash-Title[bg]=Калкулатор 2.0 |
3003 | +X-Ubuntu-Splash-Title[br]=Jederez 2.0 |
3004 | +X-Ubuntu-Splash-Title[bs]=Kalkulator 2.0 |
3005 | +X-Ubuntu-Splash-Title[ca]=Calculadora 2.0 |
3006 | +X-Ubuntu-Splash-Title[cs]=Kalkulačka 2.0 |
3007 | +X-Ubuntu-Splash-Title[cy]=Cyfrifiannell 2.0 |
3008 | +X-Ubuntu-Splash-Title[da]=Lommeregner 2.0 |
3009 | +X-Ubuntu-Splash-Title[de]=Taschenrechner 2.0 |
3010 | +X-Ubuntu-Splash-Title[el]=Αριθμομηχανή 2.0 |
3011 | +X-Ubuntu-Splash-Title[en_AU]=Calculator 2.0 |
3012 | +X-Ubuntu-Splash-Title[en_CA]=Calculator 2.0 |
3013 | +X-Ubuntu-Splash-Title[en_GB]=Calculator 2.0 |
3014 | +X-Ubuntu-Splash-Title[es]=Calculadora 2.0 |
3015 | +X-Ubuntu-Splash-Title[eu]=Kalkulagailua 2.0 |
3016 | +X-Ubuntu-Splash-Title[fa]= 2.0ماشینحساب |
3017 | +X-Ubuntu-Splash-Title[fi]=Laskin 2.0 |
3018 | +X-Ubuntu-Splash-Title[fr]=Calculatrice 2.0 |
3019 | +X-Ubuntu-Splash-Title[gd]=An t-àireamhair 2.0 |
3020 | +X-Ubuntu-Splash-Title[gl]=Calculadora 2.0 |
3021 | +X-Ubuntu-Splash-Title[gu]=કેલ્ક્યુલેટર 2.0 |
3022 | +X-Ubuntu-Splash-Title[he]= 2.0מחשבון |
3023 | +X-Ubuntu-Splash-Title[hi]=कैलकुलेटर 2.0 |
3024 | +X-Ubuntu-Splash-Title[hu]=Számológép 2.0 |
3025 | +X-Ubuntu-Splash-Title[id]=Kalkulator 2.0 |
3026 | +X-Ubuntu-Splash-Title[is]=Reiknivél 2.0 |
3027 | +X-Ubuntu-Splash-Title[it]=Calcolatrice 2.0 |
3028 | +X-Ubuntu-Splash-Title[ja]=電卓 2.0 |
3029 | +X-Ubuntu-Splash-Title[km]=ម៉ាស៊ីនគិតលេខ 2.0 |
3030 | +X-Ubuntu-Splash-Title[ko]=계산기 2.0 |
3031 | +X-Ubuntu-Splash-Title[lv]=Kalkulators 2.0 |
3032 | +X-Ubuntu-Splash-Title[mr]=गणनयंत्र 2.0 |
3033 | +X-Ubuntu-Splash-Title[ms]=Kalkulator 2.0 |
3034 | +X-Ubuntu-Splash-Title[my]=ဂဏန်းတွက်စက် 2.0 |
3035 | +X-Ubuntu-Splash-Title[nb]=Kalkulator 2.0 |
3036 | +X-Ubuntu-Splash-Title[ne]=क्याल्कुलेटर 2.0 |
3037 | +X-Ubuntu-Splash-Title[nl]=Rekenmachine 2.0 |
3038 | +X-Ubuntu-Splash-Title[pa]=ਕੈਲਕੂਲੇਟਰ 2.0 |
3039 | +X-Ubuntu-Splash-Title[pl]=Kalkulator 2.0 |
3040 | +X-Ubuntu-Splash-Title[pt]=Calculadora 2.0 |
3041 | +X-Ubuntu-Splash-Title[pt_BR]=Calculadora 2.0 |
3042 | +X-Ubuntu-Splash-Title[ro]=Calculator 2.0 |
3043 | +X-Ubuntu-Splash-Title[ru]=Калькулятор 2.0 |
3044 | +X-Ubuntu-Splash-Title[sa]=सङ्कलकम् 2.0 |
3045 | +X-Ubuntu-Splash-Title[shn]=ၸၢၵ်ႈၼပ့်သွၼ် 2.0 |
3046 | +X-Ubuntu-Splash-Title[sl]=Računalo 2.0 |
3047 | +X-Ubuntu-Splash-Title[sr]=Калкулатор 2.0 |
3048 | +X-Ubuntu-Splash-Title[sv]=Kalkylator 2.0 |
3049 | +X-Ubuntu-Splash-Title[ta]=கணிப்பான் 2.0 |
3050 | +X-Ubuntu-Splash-Title[te]=గణన పరికరం 2.0 |
3051 | +X-Ubuntu-Splash-Title[tr]=Hesap Makinesi 2.0 |
3052 | +X-Ubuntu-Splash-Title[ug]= 2.0ھېسابلىغۇچ |
3053 | +X-Ubuntu-Splash-Title[uk]=Калькулятор 2.0 |
3054 | +X-Ubuntu-Splash-Title[zh_CN]=计算器 2.0 |
3055 | +X-Ubuntu-Splash-Title[zh_HK]=計數機 2.0 |
3056 | +X-Ubuntu-Splash-Title[zh_TW]=計算機 2.0 |
3057 | |
3058 | === added file 'tests/modules/DesktopFileReader/desktopfilereader_test.cpp' |
3059 | --- tests/modules/DesktopFileReader/desktopfilereader_test.cpp 1970-01-01 00:00:00 +0000 |
3060 | +++ tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2014-09-18 22:57:30 +0000 |
3061 | @@ -0,0 +1,128 @@ |
3062 | +/* |
3063 | + * Copyright (C) 2014 Canonical, Ltd. |
3064 | + * |
3065 | + * This program is free software: you can redistribute it and/or modify it under |
3066 | + * the terms of the GNU Lesser General Public License version 3, as published by |
3067 | + * the Free Software Foundation. |
3068 | + * |
3069 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
3070 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
3071 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3072 | + * Lesser General Public License for more details. |
3073 | + * |
3074 | + * You should have received a copy of the GNU Lesser General Public License |
3075 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3076 | + * |
3077 | + */ |
3078 | + |
3079 | +#include <Unity/Application/desktopfilereader.h> |
3080 | + |
3081 | +#include <gtest/gtest.h> |
3082 | + |
3083 | +#include <QDir> |
3084 | +#include <QFileInfo> |
3085 | +#include <QLocale> |
3086 | +#include <QtGlobal> |
3087 | +#include <QString> |
3088 | + |
3089 | +using namespace qtmir; |
3090 | + |
3091 | +namespace { |
3092 | + static void setLocale(const char *locale) |
3093 | + { |
3094 | + qputenv("LANGUAGE", locale); |
3095 | + qputenv("LC_ALL", locale); // set these for GIO |
3096 | + QLocale::setDefault(QString(locale)); // set for Qt |
3097 | + } |
3098 | +} |
3099 | + |
3100 | +TEST(DesktopFileReader, testReadsDesktopFile) |
3101 | +{ |
3102 | + using namespace ::testing; |
3103 | + setLocale("C"); |
3104 | + |
3105 | + QFileInfo fileInfo(QDir::currentPath() + "/calculator.desktop"); |
3106 | + DesktopFileReader::Factory readerFactory; |
3107 | + DesktopFileReader *reader = readerFactory.createInstance("calculator", fileInfo); |
3108 | + |
3109 | + EXPECT_EQ(reader->loaded(), true); |
3110 | + EXPECT_EQ(reader->appId(), "calculator"); |
3111 | + EXPECT_EQ(reader->name(), "Calculator"); |
3112 | + EXPECT_EQ(reader->exec(), "aa-exec-click -p com.ubuntu.calculator_calculator_1.3.329 -- qmlscene -qt5 ubuntu-calculator-app.qml"); |
3113 | + EXPECT_EQ(reader->icon(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); |
3114 | + EXPECT_EQ(reader->path(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator"); |
3115 | + EXPECT_EQ(reader->comment(), "A simple calculator for Ubuntu."); |
3116 | + EXPECT_EQ(reader->stageHint(), "SideStage"); |
3117 | + EXPECT_EQ(reader->splashColor(), "#aabbcc"); |
3118 | + EXPECT_EQ(reader->splashColorFooter(), "#deadbeefda"); |
3119 | + EXPECT_EQ(reader->splashColorHeader(), "purple"); |
3120 | + EXPECT_EQ(reader->splashImage(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); |
3121 | + EXPECT_EQ(reader->splashShowHeader(), "True"); |
3122 | + EXPECT_EQ(reader->splashTitle(), "Calculator 2.0"); |
3123 | +} |
3124 | + |
3125 | +TEST(DesktopFileReader, testReadsLocalizedDesktopFile) |
3126 | +{ |
3127 | + using namespace ::testing; |
3128 | + setLocale("de"); |
3129 | + |
3130 | + QFileInfo fileInfo(QDir::currentPath() + "/calculator.desktop"); |
3131 | + DesktopFileReader::Factory readerFactory; |
3132 | + DesktopFileReader *reader = readerFactory.createInstance("calculator", fileInfo); |
3133 | + |
3134 | + EXPECT_EQ(reader->loaded(), true); |
3135 | + EXPECT_EQ(reader->appId(), "calculator"); |
3136 | + EXPECT_EQ(reader->name(), "Taschenrechner"); |
3137 | + EXPECT_EQ(reader->exec(), "aa-exec-click -p com.ubuntu.calculator_calculator_1.3.329 -- qmlscene -qt5 ubuntu-calculator-app.qml"); |
3138 | + EXPECT_EQ(reader->icon(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); |
3139 | + EXPECT_EQ(reader->path(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator"); |
3140 | + EXPECT_EQ(reader->comment(), "Ein einfach Tachenrechner für Ubuntu."); |
3141 | + EXPECT_EQ(reader->stageHint(), "SideStage"); |
3142 | + EXPECT_EQ(reader->splashColor(), "#aabbcc"); |
3143 | + EXPECT_EQ(reader->splashColorFooter(), "#deadbeefda"); |
3144 | + EXPECT_EQ(reader->splashColorHeader(), "purple"); |
3145 | + EXPECT_EQ(reader->splashImage(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); |
3146 | + EXPECT_EQ(reader->splashShowHeader(), "True"); |
3147 | + EXPECT_EQ(reader->splashTitle(), "Taschenrechner 2.0"); |
3148 | +} |
3149 | + |
3150 | +TEST(DesktopFileReader, testMissingDesktopFile) |
3151 | +{ |
3152 | + using namespace ::testing; |
3153 | + setLocale("C"); |
3154 | + |
3155 | + QFileInfo fileInfo(QDir::currentPath() + "/missing.desktop"); |
3156 | + DesktopFileReader::Factory readerFactory; |
3157 | + DesktopFileReader *reader = readerFactory.createInstance("calculator", fileInfo); |
3158 | + |
3159 | + EXPECT_EQ(reader->loaded(), false); |
3160 | + EXPECT_EQ(reader->appId(), "calculator"); |
3161 | + EXPECT_EQ(reader->name(), ""); |
3162 | + EXPECT_EQ(reader->exec(), ""); |
3163 | + EXPECT_EQ(reader->icon(), ""); |
3164 | + EXPECT_EQ(reader->path(), ""); |
3165 | + EXPECT_EQ(reader->comment(), ""); |
3166 | + EXPECT_EQ(reader->stageHint(), ""); |
3167 | + EXPECT_EQ(reader->splashColor(), ""); |
3168 | + EXPECT_EQ(reader->splashColorFooter(), ""); |
3169 | + EXPECT_EQ(reader->splashColorHeader(), ""); |
3170 | + EXPECT_EQ(reader->splashImage(), ""); |
3171 | + EXPECT_EQ(reader->splashShowHeader(), ""); |
3172 | + EXPECT_EQ(reader->splashTitle(), ""); |
3173 | +} |
3174 | + |
3175 | +TEST(DesktopFileReader, testUTF8Characters) |
3176 | +{ |
3177 | + using namespace ::testing; |
3178 | + setLocale("zh_CN"); |
3179 | + |
3180 | + QFileInfo fileInfo(QDir::currentPath() + "/calculator.desktop"); |
3181 | + DesktopFileReader::Factory readerFactory; |
3182 | + DesktopFileReader *reader = readerFactory.createInstance("calculator", fileInfo); |
3183 | + |
3184 | + EXPECT_EQ(reader->loaded(), true); |
3185 | + EXPECT_EQ(reader->appId(), "calculator"); |
3186 | + EXPECT_EQ(reader->name(), "计算器"); |
3187 | + EXPECT_EQ(reader->comment(), "Ubuntu 简易计算器"); |
3188 | + EXPECT_EQ(reader->splashTitle(), "计算器 2.0"); |
3189 | +} |
3190 | |
3191 | === added directory 'tests/modules/MirSurfaceItem' |
3192 | === added file 'tests/modules/MirSurfaceItem/MirSurfaceItem.pro' |
3193 | --- tests/modules/MirSurfaceItem/MirSurfaceItem.pro 1970-01-01 00:00:00 +0000 |
3194 | +++ tests/modules/MirSurfaceItem/MirSurfaceItem.pro 2014-09-18 22:57:30 +0000 |
3195 | @@ -0,0 +1,13 @@ |
3196 | +include(../../test-includes.pri) |
3197 | +include(../common/common.pri) |
3198 | + |
3199 | +TARGET = mirsurfaceitem_test |
3200 | + |
3201 | +QT += testlib |
3202 | + |
3203 | +INCLUDEPATH += \ |
3204 | + ../../../src/platforms/mirserver \ |
3205 | + ../../../src/modules/Unity/Application |
3206 | + |
3207 | +SOURCES += \ |
3208 | + mirsurfaceitem_test.cpp |
3209 | |
3210 | === added file 'tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp' |
3211 | --- tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp 1970-01-01 00:00:00 +0000 |
3212 | +++ tests/modules/MirSurfaceItem/mirsurfaceitem_test.cpp 2014-09-18 22:57:30 +0000 |
3213 | @@ -0,0 +1,113 @@ |
3214 | +/* |
3215 | + * Copyright (C) 2014 Canonical, Ltd. |
3216 | + * |
3217 | + * This program is free software: you can redistribute it and/or modify it under |
3218 | + * the terms of the GNU Lesser General Public License version 3, as published by |
3219 | + * the Free Software Foundation. |
3220 | + * |
3221 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
3222 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
3223 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3224 | + * Lesser General Public License for more details. |
3225 | + * |
3226 | + * You should have received a copy of the GNU Lesser General Public License |
3227 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3228 | + * |
3229 | + */ |
3230 | + |
3231 | +#include <gtest/gtest.h> |
3232 | + |
3233 | +#include <QLoggingCategory> |
3234 | +#include <QTest> |
3235 | + |
3236 | +// the test subject |
3237 | +#include <mirsurfaceitem.h> |
3238 | + |
3239 | +// mocks |
3240 | +#include <mock_surface.h> |
3241 | +#include <mock_session.h> |
3242 | + |
3243 | +using namespace qtmir; |
3244 | + |
3245 | +using mir::scene::MockSurface; |
3246 | +using qtmir::MockSession; |
3247 | + |
3248 | +// gtest stuff |
3249 | +using ::testing::_; |
3250 | +using ::testing::AnyNumber; |
3251 | +using ::testing::Invoke; |
3252 | +using ::testing::InSequence; |
3253 | +using ::testing::Return; |
3254 | + |
3255 | +/* |
3256 | + Tests that even if Qt fails to finish a touch sequence, MirSurfaceItem will |
3257 | + properly finish it when forwarding it to its mir::input::surface. So |
3258 | + mir::input::surface will still consume a proper sequence of touch events |
3259 | + (comprised of a begin, zero or more updates and an end). |
3260 | + */ |
3261 | +TEST(MirSurfaceItemTest, MissingTouchEnd) |
3262 | +{ |
3263 | + // We don't want the logging spam cluttering the test results |
3264 | + QLoggingCategory::setFilterRules(QStringLiteral("qtmir*=false")); |
3265 | + |
3266 | + std::shared_ptr<MockSurface> mockSurface = std::make_shared<MockSurface>(); |
3267 | + MockSession *mockSession = new MockSession; |
3268 | + |
3269 | + // Set some expectations and behavior for calls we are not interested in |
3270 | + EXPECT_CALL(*mockSurface, add_observer(_)).Times(AnyNumber()); |
3271 | + EXPECT_CALL(*mockSurface, remove_observer(_)).Times(AnyNumber()); |
3272 | + EXPECT_CALL(*mockSurface, size()).Times(AnyNumber()).WillRepeatedly(Return(mir::geometry::Size(100,100))); |
3273 | + EXPECT_CALL(*mockSurface, type()).Times(AnyNumber()).WillRepeatedly(Return(mir_surface_type_normal)); |
3274 | + EXPECT_CALL(*mockSession, setSurface(_)).Times(AnyNumber()); |
3275 | + |
3276 | + // The touch event sequence we expect mir::input::surface to receive from MirSurfaceItem. |
3277 | + // It should properly finish the sequence for touch 0 ('down', 'move' and 'up') before starting |
3278 | + // the sequence for touch 1. |
3279 | + EXPECT_CALL(*mockSurface, consume(_)) |
3280 | + .WillOnce(Invoke([] (MirEvent const& mirEvent) { |
3281 | + ASSERT_EQ(mir_motion_action_down, mirEvent.motion.action); |
3282 | + ASSERT_EQ(1, mirEvent.motion.pointer_count); |
3283 | + ASSERT_EQ(0, mirEvent.motion.pointer_coordinates[0].id); |
3284 | + })) |
3285 | + .WillOnce(Invoke([] (MirEvent const& mirEvent) { |
3286 | + ASSERT_EQ(mir_motion_action_move, mirEvent.motion.action); |
3287 | + ASSERT_EQ(1, mirEvent.motion.pointer_count); |
3288 | + ASSERT_EQ(0, mirEvent.motion.pointer_coordinates[0].id); |
3289 | + })) |
3290 | + .WillOnce(Invoke([] (MirEvent const& mirEvent) { |
3291 | + ASSERT_EQ(mir_motion_action_up, mirEvent.motion.action); |
3292 | + ASSERT_EQ(1, mirEvent.motion.pointer_count); |
3293 | + ASSERT_EQ(0, mirEvent.motion.pointer_coordinates[0].id); |
3294 | + })) |
3295 | + .WillOnce(Invoke([] (MirEvent const& mirEvent) { |
3296 | + ASSERT_EQ(mir_motion_action_down, mirEvent.motion.action); |
3297 | + ASSERT_EQ(1, mirEvent.motion.pointer_count); |
3298 | + ASSERT_EQ(1, mirEvent.motion.pointer_coordinates[0].id); |
3299 | + })); |
3300 | + |
3301 | + |
3302 | + MirSurfaceItem *surfaceItem = new MirSurfaceItem(mockSurface, mockSession); |
3303 | + |
3304 | + ulong timestamp = 1234; |
3305 | + QList<QTouchEvent::TouchPoint> touchPoints; |
3306 | + touchPoints.append(QTouchEvent::TouchPoint()); |
3307 | + |
3308 | + touchPoints[0].setId(0); |
3309 | + touchPoints[0].setState(Qt::TouchPointPressed); |
3310 | + surfaceItem->processTouchEvent(QEvent::TouchBegin, |
3311 | + timestamp, touchPoints, touchPoints[0].state()); |
3312 | + |
3313 | + touchPoints[0].setState(Qt::TouchPointMoved); |
3314 | + surfaceItem->processTouchEvent(QEvent::TouchUpdate, |
3315 | + timestamp + 10, touchPoints, touchPoints[0].state()); |
3316 | + |
3317 | + // Starting a new touch sequence (with touch 1) without ending the current one |
3318 | + // (wich has touch 0). |
3319 | + touchPoints[0].setId(1); |
3320 | + touchPoints[0].setState(Qt::TouchPointPressed); |
3321 | + surfaceItem->processTouchEvent(QEvent::TouchBegin, |
3322 | + timestamp + 20, touchPoints, touchPoints[0].state()); |
3323 | + |
3324 | + delete surfaceItem; |
3325 | + delete mockSession; |
3326 | +} |
3327 | |
3328 | === modified file 'tests/modules/SessionManager/session_manager_test.cpp' |
3329 | --- tests/modules/SessionManager/session_manager_test.cpp 2014-08-29 14:58:07 +0000 |
3330 | +++ tests/modules/SessionManager/session_manager_test.cpp 2014-09-18 22:57:30 +0000 |
3331 | @@ -24,6 +24,7 @@ |
3332 | #include "qtmir_test.h" |
3333 | |
3334 | using namespace qtmir; |
3335 | +using mir::scene::MockSession; |
3336 | |
3337 | namespace ms = mir::scene; |
3338 | |
3339 | @@ -33,7 +34,7 @@ |
3340 | SessionManagerTests() |
3341 | {} |
3342 | |
3343 | - QList<std::shared_ptr<ms::PromptSession>> listPromptSessions(Session* session) { |
3344 | + QList<std::shared_ptr<ms::PromptSession>> listPromptSessions(SessionInterface* session) { |
3345 | QList<std::shared_ptr<ms::PromptSession>> promptSessions; |
3346 | session->foreachPromptSession([&promptSessions](const std::shared_ptr<ms::PromptSession>& promptSession) { |
3347 | promptSessions << promptSession; |
3348 | @@ -41,9 +42,9 @@ |
3349 | return promptSessions; |
3350 | } |
3351 | |
3352 | - QList<Session*> listChildSessions(Session* session) { |
3353 | - QList<Session*> sessions; |
3354 | - session->foreachChildSession([&sessions](Session* session) { |
3355 | + QList<SessionInterface*> listChildSessions(SessionInterface* session) { |
3356 | + QList<SessionInterface*> sessions; |
3357 | + session->foreachChildSession([&sessions](SessionInterface* session) { |
3358 | sessions << session; |
3359 | }); |
3360 | return sessions; |
3361 | @@ -56,10 +57,10 @@ |
3362 | |
3363 | std::shared_ptr<ms::Session> mirAppSession = std::make_shared<MockSession>("mirAppSession", __LINE__); |
3364 | sessionManager.onSessionStarting(mirAppSession); |
3365 | - Session* qtmirAppSession = sessionManager.findSession(mirAppSession.get()); |
3366 | + SessionInterface* qtmirAppSession = sessionManager.findSession(mirAppSession.get()); |
3367 | EXPECT_TRUE(qtmirAppSession != nullptr); |
3368 | |
3369 | - auto promptSession = std::make_shared<MockPromptSession>(); |
3370 | + auto promptSession = std::make_shared<ms::MockPromptSession>(); |
3371 | ON_CALL(*mirConfig->the_mock_prompt_session_manager(), application_for(_)).WillByDefault(Return(mirAppSession)); |
3372 | |
3373 | sessionManager.onPromptSessionStarting(promptSession); |
3374 | @@ -80,18 +81,18 @@ |
3375 | |
3376 | std::shared_ptr<ms::Session> mirAppSession = std::make_shared<MockSession>("mirAppSession", __LINE__); |
3377 | sessionManager.onSessionStarting(mirAppSession); |
3378 | - Session* qtmirAppSession = sessionManager.findSession(mirAppSession.get()); |
3379 | + SessionInterface* qtmirAppSession = sessionManager.findSession(mirAppSession.get()); |
3380 | EXPECT_TRUE(qtmirAppSession != nullptr); |
3381 | |
3382 | EXPECT_CALL(*mirConfig->the_mock_prompt_session_manager(), application_for(_)).WillRepeatedly(Return(mirAppSession)); |
3383 | EXPECT_CALL(*mirConfig->the_mock_prompt_session_manager(), helper_for(_)).WillRepeatedly(Return(nullptr)); |
3384 | |
3385 | - std::shared_ptr<ms::PromptSession> mirPromptSession = std::make_shared<MockPromptSession>(); |
3386 | + std::shared_ptr<ms::PromptSession> mirPromptSession = std::make_shared<ms::MockPromptSession>(); |
3387 | |
3388 | // prompt provider session |
3389 | std::shared_ptr<ms::Session> mirProviderSession = std::make_shared<MockSession>("mirProviderSession", __LINE__); |
3390 | sessionManager.onSessionStarting(mirProviderSession); |
3391 | - Session* qtmirProviderSession = sessionManager.findSession(mirProviderSession.get()); |
3392 | + SessionInterface* qtmirProviderSession = sessionManager.findSession(mirProviderSession.get()); |
3393 | |
3394 | EXPECT_CALL(*mirConfig->the_mock_prompt_session_manager(), for_each_provider_in(mirPromptSession,_)).WillRepeatedly(WithArgs<1>(Invoke( |
3395 | [&](std::function<void(std::shared_ptr<ms::Session> const& prompt_provider)> const& f) { |
3396 | |
3397 | === modified file 'tests/modules/SessionManager/session_test.cpp' |
3398 | --- tests/modules/SessionManager/session_test.cpp 2014-08-28 23:36:42 +0000 |
3399 | +++ tests/modules/SessionManager/session_test.cpp 2014-09-18 22:57:30 +0000 |
3400 | @@ -22,6 +22,8 @@ |
3401 | #include "stub_scene_surface.h" |
3402 | |
3403 | using namespace qtmir; |
3404 | +using mir::scene::MockSession; |
3405 | + |
3406 | |
3407 | namespace ms = mir::scene; |
3408 | namespace mtd = mir::test::doubles; |
3409 | @@ -32,9 +34,9 @@ |
3410 | SessionTests() |
3411 | {} |
3412 | |
3413 | - QList<Session*> listChildSessions(Session* session) { |
3414 | - QList<Session*> sessions; |
3415 | - session->foreachChildSession([&sessions](Session* session) { |
3416 | + QList<SessionInterface*> listChildSessions(Session* session) { |
3417 | + QList<SessionInterface*> sessions; |
3418 | + session->foreachChildSession([&sessions](SessionInterface* session) { |
3419 | sessions << session; |
3420 | }); |
3421 | return sessions; |
3422 | @@ -151,17 +153,14 @@ |
3423 | |
3424 | // delete surfaces |
3425 | delete session2; |
3426 | - EXPECT_EQ(session2->parentSession(), nullptr); |
3427 | EXPECT_THAT(listChildSessions(&session), ElementsAre(session1, session3)); |
3428 | |
3429 | // delete surfaces |
3430 | delete session3; |
3431 | - EXPECT_EQ(session3->parentSession(), nullptr); |
3432 | EXPECT_THAT(listChildSessions(&session), ElementsAre(session1)); |
3433 | |
3434 | // delete surfaces |
3435 | delete session1; |
3436 | - EXPECT_EQ(session1->parentSession(), nullptr); |
3437 | EXPECT_THAT(listChildSessions(&session), IsEmpty()); |
3438 | } |
3439 | |
3440 | |
3441 | === modified file 'tests/modules/common/common.pri' |
3442 | --- tests/modules/common/common.pri 2014-08-26 14:55:03 +0000 |
3443 | +++ tests/modules/common/common.pri 2014-09-18 22:57:30 +0000 |
3444 | @@ -1,12 +1,12 @@ |
3445 | -CONFIG += link_pkgconfig no_keywords # keywords clash with ProcessC++ |
3446 | -PKGCONFIG += mirserver process-cpp ubuntu-app-launch-2 |
3447 | +CONFIG += no_keywords # keywords clash with ProcessC++ |
3448 | +PKGCONFIG += process-cpp ubuntu-app-launch-2 |
3449 | |
3450 | -QT += quick testlib |
3451 | -QMAKE_CXXFLAGS = -std=c++11 |
3452 | +QT += quick |
3453 | |
3454 | HEADERS += ../common/mock_application_controller.h \ |
3455 | ../common/mock_desktop_file_reader.h \ |
3456 | ../common/mock_focus_controller.h \ |
3457 | + ../common/mock_mir_session.h \ |
3458 | ../common/mock_oom_controller.h \ |
3459 | ../common/mock_process_controller.h \ |
3460 | ../common/mock_proc_info.h \ |
3461 | @@ -22,31 +22,7 @@ |
3462 | INCLUDEPATH += ../../../src/modules \ |
3463 | ../common |
3464 | |
3465 | - |
3466 | -GMOCK_SOURCES = /usr/src/gmock/src/gmock-all.cc \ |
3467 | - /usr/src/gmock/src/gmock_main.cc \ |
3468 | - /usr/src/gtest/src/gtest-all.cc |
3469 | - |
3470 | -QMAKE_EXTRA_COMPILERS += gmock_compiler |
3471 | -gmock_compiler.input = GMOCK_SOURCES |
3472 | -gmock_compiler.output = $${OUT_PWD}/${QMAKE_FILE_BASE}.o |
3473 | -gmock_compiler.commands = g++ \ |
3474 | - -I/usr/src/gtest \ |
3475 | - -I/usr/src/gmock \ |
3476 | - -c ${QMAKE_FILE_IN} \ |
3477 | - -o ${QMAKE_FILE_OUT} |
3478 | -gmock_compiler.CONFIG = no_link |
3479 | - |
3480 | -QMAKE_EXTRA_COMPILERS += gmock_linker |
3481 | -gmock_linker.depends = $${OUT_PWD}/gmock-all.o \ |
3482 | - $${OUT_PWD}/gmock_main.o \ |
3483 | - $${OUT_PWD}/gtest-all.o |
3484 | -gmock_linker.input = GMOCK_SOURCES |
3485 | -gmock_linker.output = $${OUT_PWD}/libgmock.a |
3486 | -gmock_linker.commands = ar -rv ${QMAKE_FILE_OUT} $${OUT_PWD}/gmock-all.o $${OUT_PWD}/gmock_main.o $${OUT_PWD}/gtest-all.o |
3487 | -gmock_linker.CONFIG = combine explicit_dependencies no_link target_predeps |
3488 | - |
3489 | -LIBS += $${OUT_PWD}/libgmock.a \ |
3490 | +LIBS += \ |
3491 | -Wl,-rpath,$${OUT_PWD}/../../../src/modules/Unity/Application \ |
3492 | -L$${OUT_PWD}/../../../src/modules/Unity/Application -lunityapplicationplugin \ |
3493 | -Wl,-rpath,$${OUT_PWD}/../../../src/platforms/mirserver \ |
3494 | |
3495 | === modified file 'tests/modules/common/mock_focus_controller.h' |
3496 | --- tests/modules/common/mock_focus_controller.h 2014-07-01 13:38:06 +0000 |
3497 | +++ tests/modules/common/mock_focus_controller.h 2014-09-18 22:57:30 +0000 |
3498 | @@ -23,15 +23,18 @@ |
3499 | |
3500 | #include <string> |
3501 | |
3502 | -namespace testing |
3503 | -{ |
3504 | -class MockFocusController : public mir::shell::FocusController |
3505 | +namespace mir { |
3506 | +namespace shell { |
3507 | + |
3508 | +class MockFocusController : public FocusController |
3509 | { |
3510 | public: |
3511 | MOCK_METHOD0(focus_next, void()); |
3512 | - MOCK_CONST_METHOD0(focussed_application, std::weak_ptr<mir::scene::Session>()); |
3513 | - MOCK_METHOD1(set_focus_to, void(std::shared_ptr<mir::scene::Session>const&)); |
3514 | + MOCK_CONST_METHOD0(focussed_application, std::weak_ptr<scene::Session>()); |
3515 | + MOCK_METHOD1(set_focus_to, void(std::shared_ptr<scene::Session>const&)); |
3516 | }; |
3517 | -} |
3518 | + |
3519 | +} // namespace shell |
3520 | +} // namespace mir |
3521 | |
3522 | #endif // MOCK_MIR_SHELL_FOCUS_CONTROLLER_H_ |
3523 | |
3524 | === renamed file 'tests/modules/common/mock_session.h' => 'tests/modules/common/mock_mir_session.h' |
3525 | --- tests/modules/common/mock_session.h 2014-07-01 13:38:06 +0000 |
3526 | +++ tests/modules/common/mock_mir_session.h 2014-09-18 22:57:30 +0000 |
3527 | @@ -25,9 +25,10 @@ |
3528 | |
3529 | #include <string> |
3530 | |
3531 | -namespace testing |
3532 | -{ |
3533 | -struct MockSession : public mir::scene::Session |
3534 | +namespace mir { |
3535 | +namespace scene { |
3536 | + |
3537 | +struct MockSession : public Session |
3538 | { |
3539 | MockSession() {} |
3540 | MockSession(std::string const& sessionName, pid_t processId) |
3541 | @@ -44,22 +45,20 @@ |
3542 | return m_sessionId; |
3543 | } |
3544 | |
3545 | - typedef mir::frontend::SurfaceId SurfaceId; |
3546 | - |
3547 | MOCK_METHOD0(force_requests_to_complete, void()); |
3548 | |
3549 | - MOCK_CONST_METHOD0(default_surface, std::shared_ptr<mir::scene::Surface>()); |
3550 | - MOCK_CONST_METHOD1(get_surface, std::shared_ptr<mir::frontend::Surface>(SurfaceId)); |
3551 | + MOCK_CONST_METHOD0(default_surface, std::shared_ptr<Surface>()); |
3552 | + MOCK_CONST_METHOD1(get_surface, std::shared_ptr<frontend::Surface>(frontend::SurfaceId)); |
3553 | |
3554 | - MOCK_METHOD1(take_snapshot, void(mir::scene::SnapshotCallback const&)); |
3555 | + MOCK_METHOD1(take_snapshot, void(SnapshotCallback const&)); |
3556 | MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState)); |
3557 | - MOCK_METHOD1(create_surface, SurfaceId(mir::scene::SurfaceCreationParameters const&)); |
3558 | - MOCK_METHOD1(destroy_surface, void (SurfaceId)); |
3559 | + MOCK_METHOD1(create_surface, frontend::SurfaceId(SurfaceCreationParameters const&)); |
3560 | + MOCK_METHOD1(destroy_surface, void (frontend::SurfaceId)); |
3561 | |
3562 | MOCK_METHOD0(hide, void()); |
3563 | MOCK_METHOD0(show, void()); |
3564 | - MOCK_METHOD1(send_display_config, void(mir::graphics::DisplayConfiguration const&)); |
3565 | - MOCK_METHOD3(configure_surface, int(SurfaceId, MirSurfaceAttrib, int)); |
3566 | + MOCK_METHOD1(send_display_config, void(graphics::DisplayConfiguration const&)); |
3567 | + MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int)); |
3568 | |
3569 | void start_prompt_session() override {}; |
3570 | void stop_prompt_session() override {}; |
3571 | @@ -68,6 +67,8 @@ |
3572 | std::string m_sessionName; |
3573 | pid_t m_sessionId; |
3574 | }; |
3575 | -} |
3576 | + |
3577 | +} // namespace scene |
3578 | +} // namespace mir |
3579 | |
3580 | #endif // MOCK_MIR_SCENE_SESSION_H |
3581 | |
3582 | === modified file 'tests/modules/common/mock_prompt_session.h' |
3583 | --- tests/modules/common/mock_prompt_session.h 2014-07-21 15:51:17 +0000 |
3584 | +++ tests/modules/common/mock_prompt_session.h 2014-09-18 22:57:30 +0000 |
3585 | @@ -21,11 +21,14 @@ |
3586 | #include <mir/scene/prompt_session.h> |
3587 | #include <gmock/gmock.h> |
3588 | |
3589 | -namespace testing |
3590 | -{ |
3591 | -struct MockPromptSession : public mir::scene::PromptSession |
3592 | +namespace mir { |
3593 | +namespace scene { |
3594 | + |
3595 | +struct MockPromptSession : public PromptSession |
3596 | { |
3597 | }; |
3598 | -} |
3599 | + |
3600 | +} // namespace scene |
3601 | +} // namespace mir |
3602 | |
3603 | #endif // MOCK_MIR_PROMPT_SESSION_H |
3604 | |
3605 | === modified file 'tests/modules/common/mock_prompt_session_manager.h' |
3606 | --- tests/modules/common/mock_prompt_session_manager.h 2014-07-21 15:51:17 +0000 |
3607 | +++ tests/modules/common/mock_prompt_session_manager.h 2014-09-18 22:57:30 +0000 |
3608 | @@ -23,33 +23,36 @@ |
3609 | |
3610 | #include <gmock/gmock.h> |
3611 | |
3612 | -namespace testing |
3613 | -{ |
3614 | -class MockPromptSessionManager: public mir::scene::PromptSessionManager |
3615 | +namespace mir { |
3616 | +namespace scene { |
3617 | + |
3618 | +class MockPromptSessionManager: public PromptSessionManager |
3619 | { |
3620 | public: |
3621 | - MOCK_CONST_METHOD2(start_prompt_session_for, std::shared_ptr<mir::scene::PromptSession>(std::shared_ptr<mir::scene::Session> const&, |
3622 | + MOCK_CONST_METHOD2(start_prompt_session_for, std::shared_ptr<PromptSession>(std::shared_ptr<mir::scene::Session> const&, |
3623 | mir::scene::PromptSessionCreationParameters const&)); |
3624 | |
3625 | - MOCK_CONST_METHOD1(stop_prompt_session, void(std::shared_ptr<mir::scene::PromptSession> const&)); |
3626 | + MOCK_CONST_METHOD1(stop_prompt_session, void(std::shared_ptr<PromptSession> const&)); |
3627 | |
3628 | - MOCK_CONST_METHOD2(add_prompt_provider, void(std::shared_ptr<mir::scene::PromptSession> const&, |
3629 | + MOCK_CONST_METHOD2(add_prompt_provider, void(std::shared_ptr<PromptSession> const&, |
3630 | std::shared_ptr<mir::scene::Session> const&)); |
3631 | |
3632 | - MOCK_CONST_METHOD2(add_prompt_provider_by_pid, void(std::shared_ptr<mir::scene::PromptSession> const&, |
3633 | + MOCK_CONST_METHOD2(add_prompt_provider_by_pid, void(std::shared_ptr<PromptSession> const&, |
3634 | pid_t)); |
3635 | |
3636 | - MOCK_CONST_METHOD1(add_expected_session, void(std::shared_ptr<mir::scene::Session> const&)); |
3637 | - |
3638 | - MOCK_CONST_METHOD1(remove_session, void(std::shared_ptr<mir::scene::Session> const&)); |
3639 | - |
3640 | - MOCK_CONST_METHOD1(application_for, std::shared_ptr<mir::scene::Session>(std::shared_ptr<mir::scene::PromptSession> const&)); |
3641 | - |
3642 | - MOCK_CONST_METHOD1(helper_for, std::shared_ptr<mir::scene::Session>(std::shared_ptr<mir::scene::PromptSession> const&)); |
3643 | - |
3644 | - MOCK_CONST_METHOD2(for_each_provider_in, void(std::shared_ptr<mir::scene::PromptSession> const&, |
3645 | - std::function<void(std::shared_ptr<mir::scene::Session> const&)> const&)); |
3646 | + MOCK_CONST_METHOD1(add_expected_session, void(std::shared_ptr<Session> const&)); |
3647 | + |
3648 | + MOCK_CONST_METHOD1(remove_session, void(std::shared_ptr<Session> const&)); |
3649 | + |
3650 | + MOCK_CONST_METHOD1(application_for, std::shared_ptr<Session>(std::shared_ptr<PromptSession> const&)); |
3651 | + |
3652 | + MOCK_CONST_METHOD1(helper_for, std::shared_ptr<Session>(std::shared_ptr<PromptSession> const&)); |
3653 | + |
3654 | + MOCK_CONST_METHOD2(for_each_provider_in, void(std::shared_ptr<PromptSession> const&, |
3655 | + std::function<void(std::shared_ptr<Session> const&)> const&)); |
3656 | }; |
3657 | -} // namespace testing |
3658 | + |
3659 | +} // namespace scene |
3660 | +} // namespace mir |
3661 | |
3662 | #endif // MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_ |
3663 | |
3664 | === modified file 'tests/modules/common/mock_renderable.h' |
3665 | --- tests/modules/common/mock_renderable.h 2014-08-14 15:38:15 +0000 |
3666 | +++ tests/modules/common/mock_renderable.h 2014-09-18 22:57:30 +0000 |
3667 | @@ -21,23 +21,26 @@ |
3668 | #include <mir/graphics/renderable.h> |
3669 | #include <gmock/gmock.h> |
3670 | |
3671 | -namespace testing |
3672 | -{ |
3673 | -struct MockRenderable : public mir::graphics::Renderable |
3674 | +namespace mir { |
3675 | +namespace graphics { |
3676 | + |
3677 | +struct MockRenderable : public Renderable |
3678 | { |
3679 | MockRenderable() {}; |
3680 | |
3681 | MOCK_CONST_METHOD0(id, ID()); |
3682 | - MOCK_CONST_METHOD0(buffer, std::shared_ptr<mir::graphics::Buffer>()); |
3683 | + MOCK_CONST_METHOD0(buffer, std::shared_ptr<Buffer>()); |
3684 | MOCK_CONST_METHOD0(alpha_enabled, bool()); |
3685 | - MOCK_CONST_METHOD0(screen_position, mir::geometry::Rectangle()); |
3686 | + MOCK_CONST_METHOD0(screen_position, geometry::Rectangle()); |
3687 | MOCK_CONST_METHOD0(alpha, float() ); |
3688 | MOCK_CONST_METHOD0(transformation, glm::mat4()); |
3689 | MOCK_CONST_METHOD0(visible, bool()); |
3690 | MOCK_CONST_METHOD0(shaped, bool()); |
3691 | MOCK_CONST_METHOD0(buffers_ready_for_compositor, int()); |
3692 | }; |
3693 | -} |
3694 | + |
3695 | +} // namespace graphics |
3696 | +} // namespace mir |
3697 | |
3698 | #endif // MOCK_MIR_GRAPHICS_RENDERABLE_H |
3699 | |
3700 | |
3701 | === added file 'tests/modules/common/mock_session.h' |
3702 | --- tests/modules/common/mock_session.h 1970-01-01 00:00:00 +0000 |
3703 | +++ tests/modules/common/mock_session.h 2014-09-18 22:57:30 +0000 |
3704 | @@ -0,0 +1,65 @@ |
3705 | +/* |
3706 | + * Copyright (C) 2014 Canonical, Ltd. |
3707 | + * |
3708 | + * This program is free software: you can redistribute it and/or modify it under |
3709 | + * the terms of the GNU Lesser General Public License version 3, as published by |
3710 | + * the Free Software Foundation. |
3711 | + * |
3712 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
3713 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
3714 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3715 | + * Lesser General Public License for more details. |
3716 | + * |
3717 | + * You should have received a copy of the GNU Lesser General Public License |
3718 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3719 | + * |
3720 | + */ |
3721 | + |
3722 | +#ifndef MOCK_QTMIR_SESSION_H |
3723 | +#define MOCK_QTMIR_SESSION_H |
3724 | + |
3725 | +#include <session_interface.h> |
3726 | +#include <gmock/gmock.h> |
3727 | + |
3728 | +namespace qtmir { |
3729 | + |
3730 | +class MockSession : public SessionInterface { |
3731 | +public: |
3732 | + MockSession() : SessionInterface(0) {} |
3733 | + |
3734 | + MOCK_METHOD0(release, void()); |
3735 | + |
3736 | + MOCK_CONST_METHOD0(name, QString()); |
3737 | + MOCK_CONST_METHOD0(application, unity::shell::application::ApplicationInfoInterface*()); |
3738 | + MOCK_CONST_METHOD0(surface, MirSurfaceItem*()); |
3739 | + MOCK_CONST_METHOD0(parentSession, SessionInterface*()); |
3740 | + MOCK_CONST_METHOD0(state, State()); |
3741 | + MOCK_CONST_METHOD0(fullscreen, bool()); |
3742 | + MOCK_CONST_METHOD0(live, bool()); |
3743 | + |
3744 | + MOCK_METHOD1(setApplication, void(unity::shell::application::ApplicationInfoInterface* item)); |
3745 | + MOCK_METHOD1(setSurface, void(MirSurfaceItem* surface)); |
3746 | + MOCK_METHOD1(setState, void(State state)); |
3747 | + |
3748 | + MOCK_METHOD1(addChildSession, void(SessionInterface* session)); |
3749 | + MOCK_METHOD2(insertChildSession, void(uint index, SessionInterface* session)); |
3750 | + MOCK_METHOD1(removeChildSession, void(SessionInterface* session)); |
3751 | + MOCK_CONST_METHOD1(foreachChildSession, void(std::function<void(SessionInterface* session)> f)); |
3752 | + |
3753 | + MOCK_CONST_METHOD0(session, std::shared_ptr<mir::scene::Session>()); |
3754 | + |
3755 | + MOCK_CONST_METHOD0(activePromptSession, std::shared_ptr<mir::scene::PromptSession>()); |
3756 | + MOCK_CONST_METHOD1(foreachPromptSession, void(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> f)); |
3757 | + |
3758 | + MOCK_CONST_METHOD0(childSessions, SessionModel*()); |
3759 | + |
3760 | +protected: |
3761 | + MOCK_METHOD1(setFullscreen, void(bool fullscreen)); |
3762 | + MOCK_METHOD1(setLive, void(const bool)); |
3763 | + MOCK_METHOD1(appendPromptSession, void(const std::shared_ptr<mir::scene::PromptSession>& session)); |
3764 | + MOCK_METHOD1(removePromptSession, void(const std::shared_ptr<mir::scene::PromptSession>& session)); |
3765 | +}; |
3766 | + |
3767 | +} // namespace qtmir |
3768 | + |
3769 | +#endif // MOCK_QTMIR_SESSION_H |
3770 | |
3771 | === modified file 'tests/modules/common/mock_surface.h' |
3772 | --- tests/modules/common/mock_surface.h 2014-08-18 19:40:31 +0000 |
3773 | +++ tests/modules/common/mock_surface.h 2014-09-18 22:57:30 +0000 |
3774 | @@ -24,22 +24,22 @@ |
3775 | #include <string> |
3776 | #include "mock_renderable.h" |
3777 | |
3778 | -namespace testing |
3779 | -{ |
3780 | +namespace mir { |
3781 | +namespace scene { |
3782 | |
3783 | struct MockSurface : public mir::scene::Surface |
3784 | { |
3785 | MockSurface() {} |
3786 | |
3787 | MOCK_CONST_METHOD0(name, std::string()); |
3788 | - MOCK_CONST_METHOD0(client_size, mir::geometry::Size()); |
3789 | - MOCK_CONST_METHOD0(input_bounds, mir::geometry::Rectangle()); |
3790 | - MOCK_CONST_METHOD0(top_left, mir::geometry::Point()); |
3791 | - MOCK_CONST_METHOD0(size, mir::geometry::Size()); |
3792 | + MOCK_CONST_METHOD0(client_size, geometry::Size()); |
3793 | + MOCK_CONST_METHOD0(input_bounds, geometry::Rectangle()); |
3794 | + MOCK_CONST_METHOD0(top_left, geometry::Point()); |
3795 | + MOCK_CONST_METHOD0(size, geometry::Size()); |
3796 | |
3797 | - std::unique_ptr<mir::graphics::Renderable> compositor_snapshot(void const* /*compositor_id*/) const |
3798 | + std::unique_ptr<graphics::Renderable> compositor_snapshot(void const* /*compositor_id*/) const |
3799 | { |
3800 | - return std::unique_ptr<mir::graphics::Renderable>(new MockRenderable); |
3801 | + return std::unique_ptr<graphics::Renderable>(new graphics::MockRenderable); |
3802 | } |
3803 | |
3804 | MOCK_CONST_METHOD0(alpha, float()); |
3805 | @@ -47,39 +47,40 @@ |
3806 | MOCK_CONST_METHOD0(state, MirSurfaceState()); |
3807 | MOCK_METHOD0(hide, void()); |
3808 | MOCK_METHOD0(show, void()); |
3809 | - MOCK_METHOD1(move_to, void(mir::geometry::Point const& top_left)); |
3810 | - MOCK_METHOD1(take_input_focus, void(std::shared_ptr<mir::shell::InputTargeter> const& targeter)); |
3811 | - MOCK_METHOD1(set_input_region, void(std::vector<mir::geometry::Rectangle> const& region)); |
3812 | + MOCK_METHOD1(move_to, void(geometry::Point const& top_left)); |
3813 | + MOCK_METHOD1(take_input_focus, void(std::shared_ptr<shell::InputTargeter> const& targeter)); |
3814 | + MOCK_METHOD1(set_input_region, void(std::vector<geometry::Rectangle> const& region)); |
3815 | MOCK_METHOD1(allow_framedropping, void(bool)); |
3816 | - MOCK_METHOD1(resize, void(mir::geometry::Size const& size)); |
3817 | + MOCK_METHOD1(resize, void(geometry::Size const& size)); |
3818 | MOCK_METHOD1(set_transformation, void(glm::mat4 const& t)); |
3819 | MOCK_METHOD1(set_alpha, void(float alpha)); |
3820 | MOCK_METHOD1(set_orientation, void(MirOrientation orientation)); |
3821 | MOCK_METHOD0(force_requests_to_complete, void()); |
3822 | - MOCK_METHOD1(set_cursor_image, void(std::shared_ptr<mir::graphics::CursorImage> const& image)); |
3823 | - MOCK_CONST_METHOD0(cursor_image, std::shared_ptr<mir::graphics::CursorImage>()); |
3824 | - MOCK_METHOD1(add_observer, void(std::shared_ptr<mir::scene::SurfaceObserver> const& observer)); |
3825 | - MOCK_METHOD1(remove_observer, void(std::weak_ptr<mir::scene::SurfaceObserver> const& observer)); |
3826 | - MOCK_CONST_METHOD0(input_channel, std::shared_ptr<mir::input::InputChannel>()); |
3827 | - MOCK_METHOD1(set_reception_mode, void(mir::input::InputReceptionMode mode)); |
3828 | + MOCK_METHOD1(set_cursor_image, void(std::shared_ptr<graphics::CursorImage> const& image)); |
3829 | + MOCK_CONST_METHOD0(cursor_image, std::shared_ptr<graphics::CursorImage>()); |
3830 | + MOCK_METHOD1(add_observer, void(std::shared_ptr<SurfaceObserver> const& observer)); |
3831 | + MOCK_METHOD1(remove_observer, void(std::weak_ptr<SurfaceObserver> const& observer)); |
3832 | + MOCK_CONST_METHOD0(input_channel, std::shared_ptr<input::InputChannel>()); |
3833 | + MOCK_METHOD1(set_reception_mode, void(input::InputReceptionMode mode)); |
3834 | |
3835 | // from mir::input::surface |
3836 | - MOCK_CONST_METHOD1(input_area_contains, bool(mir::geometry::Point const& point)); |
3837 | - MOCK_CONST_METHOD0(reception_mode, mir::input::InputReceptionMode()); |
3838 | + MOCK_CONST_METHOD1(input_area_contains, bool(geometry::Point const& point)); |
3839 | + MOCK_CONST_METHOD0(reception_mode, input::InputReceptionMode()); |
3840 | MOCK_METHOD1(consume, void(MirEvent const& event)); |
3841 | |
3842 | // from mir::frontend::surface |
3843 | MOCK_CONST_METHOD0(pixel_format, MirPixelFormat()); |
3844 | - MOCK_METHOD2(swap_buffers, void(mir::graphics::Buffer* old_buffer, std::function<void(mir::graphics::Buffer* new_buffer)> complete)); |
3845 | + MOCK_METHOD2(swap_buffers, void(graphics::Buffer* old_buffer, std::function<void(graphics::Buffer* new_buffer)> complete)); |
3846 | MOCK_CONST_METHOD0(supports_input, bool()); |
3847 | MOCK_CONST_METHOD0(client_input_fd, int()); |
3848 | MOCK_METHOD2(configure, int(MirSurfaceAttrib attrib, int value)); |
3849 | MOCK_METHOD1(query, int(MirSurfaceAttrib attrib)); |
3850 | |
3851 | // from mir::scene::SurfaceBufferAccess |
3852 | - MOCK_METHOD1(with_most_recent_buffer_do, void(std::function<void(mir::graphics::Buffer&)> const& exec)); |
3853 | + MOCK_METHOD1(with_most_recent_buffer_do, void(std::function<void(graphics::Buffer&)> const& exec)); |
3854 | }; |
3855 | |
3856 | -} |
3857 | +} // namespace scene |
3858 | +} // namespace mir |
3859 | |
3860 | #endif // MOCK_MIR_SCENE_SURFACE_H |
3861 | |
3862 | === modified file 'tests/modules/common/qtmir_test.h' |
3863 | --- tests/modules/common/qtmir_test.h 2014-08-28 23:36:42 +0000 |
3864 | +++ tests/modules/common/qtmir_test.h 2014-09-18 22:57:30 +0000 |
3865 | @@ -35,7 +35,7 @@ |
3866 | #include "mock_oom_controller.h" |
3867 | #include "mock_process_controller.h" |
3868 | #include "mock_proc_info.h" |
3869 | -#include "mock_session.h" |
3870 | +#include "mock_mir_session.h" |
3871 | #include "mock_focus_controller.h" |
3872 | #include "mock_prompt_session_manager.h" |
3873 | #include "mock_prompt_session.h" |
3874 | @@ -43,14 +43,13 @@ |
3875 | namespace ms = mir::scene; |
3876 | using namespace qtmir; |
3877 | |
3878 | -namespace testing |
3879 | -{ |
3880 | +namespace qtmir { |
3881 | |
3882 | -class QtMirTestConfiguration: public MirServerConfiguration |
3883 | +class FakeMirServerConfiguration: public MirServerConfiguration |
3884 | { |
3885 | - typedef NiceMock<testing::MockPromptSessionManager> StubPromptSessionManager; |
3886 | + typedef testing::NiceMock<mir::scene::MockPromptSessionManager> StubPromptSessionManager; |
3887 | public: |
3888 | - QtMirTestConfiguration() |
3889 | + FakeMirServerConfiguration() |
3890 | : MirServerConfiguration(0, nullptr) |
3891 | , mock_prompt_session_manager(std::make_shared<StubPromptSessionManager>()) |
3892 | { |
3893 | @@ -73,6 +72,10 @@ |
3894 | std::shared_ptr<StubPromptSessionManager> mock_prompt_session_manager; |
3895 | }; |
3896 | |
3897 | +} // namespace qtmir |
3898 | + |
3899 | +namespace testing { |
3900 | + |
3901 | class QtMirTest : public ::testing::Test |
3902 | { |
3903 | public: |
3904 | @@ -83,7 +86,7 @@ |
3905 | [](ProcessController::OomController*){}) |
3906 | } |
3907 | , mirConfig{ |
3908 | - QSharedPointer<QtMirTestConfiguration> (new QtMirTestConfiguration) |
3909 | + QSharedPointer<FakeMirServerConfiguration> (new FakeMirServerConfiguration) |
3910 | } |
3911 | , taskController{ |
3912 | QSharedPointer<TaskController> ( |
3913 | @@ -141,7 +144,7 @@ |
3914 | applicationManager.authorizeSession(procId, authed); |
3915 | EXPECT_EQ(authed, true); |
3916 | |
3917 | - auto appSession = std::make_shared<MockSession>(appId.toStdString(), procId); |
3918 | + auto appSession = std::make_shared<mir::scene::MockSession>(appId.toStdString(), procId); |
3919 | sessionManager.onSessionStarting(appSession); |
3920 | return application; |
3921 | return nullptr; |
3922 | @@ -152,7 +155,7 @@ |
3923 | testing::NiceMock<testing::MockApplicationController> appController; |
3924 | testing::NiceMock<testing::MockProcInfo> procInfo; |
3925 | testing::NiceMock<testing::MockDesktopFileReaderFactory> desktopFileReaderFactory; |
3926 | - QSharedPointer<QtMirTestConfiguration> mirConfig; |
3927 | + QSharedPointer<FakeMirServerConfiguration> mirConfig; |
3928 | QSharedPointer<TaskController> taskController; |
3929 | ApplicationManager applicationManager; |
3930 | SessionManager sessionManager; |
3931 | |
3932 | === modified file 'tests/modules/modules.pro' |
3933 | --- tests/modules/modules.pro 2014-08-28 23:36:42 +0000 |
3934 | +++ tests/modules/modules.pro 2014-09-18 22:57:30 +0000 |
3935 | @@ -1,2 +1,2 @@ |
3936 | TEMPLATE = subdirs |
3937 | -SUBDIRS = ApplicationManager General SessionManager TaskController |
3938 | +SUBDIRS = ApplicationManager General MirSurfaceItem SessionManager TaskController DesktopFileReader |
3939 | |
3940 | === modified file 'tests/test-includes.pri' |
3941 | --- tests/test-includes.pri 2014-07-07 19:33:56 +0000 |
3942 | +++ tests/test-includes.pri 2014-09-18 22:57:30 +0000 |
3943 | @@ -4,3 +4,12 @@ |
3944 | # adds a 'make install' that installs the test cases, which we do not want. |
3945 | # Can configure it not to do that with 'no_testcase_installs' |
3946 | CONFIG += testcase no_testcase_installs |
3947 | + |
3948 | +QMAKE_CXXFLAGS = -std=c++11 |
3949 | + |
3950 | +QT += testlib |
3951 | + |
3952 | +CONFIG += link_pkgconfig |
3953 | +PKGCONFIG += mirserver |
3954 | + |
3955 | +include(google-mock.pri) |
3956 | |
3957 | === modified file 'tests/tests.pro' |
3958 | --- tests/tests.pro 2014-08-28 23:36:42 +0000 |
3959 | +++ tests/tests.pro 2014-09-18 22:57:30 +0000 |
3960 | @@ -1,2 +1,2 @@ |
3961 | TEMPLATE = subdirs |
3962 | -SUBDIRS = modules |
3963 | +SUBDIRS = modules mirserver |