@@ -49,14 +49,32 @@ ApplicationManager::ApplicationManager(QObject *parent)
50 buildListOfAvailableApplications();
50 buildListOfAvailableApplications();
52− startApplication("unity8-dash");
52+ // polling to find out when the toplevel window has been created as there's
53− focusApplication("unity8-dash");
53+ // no signal telling us that
54+ connect(&m_windowCreatedTimer, &QTimer::timeout,
55+ this, &ApplicationManager::onWindowCreatedTimerTimeout);
56+ m_windowCreatedTimer.setSingleShot(false);
57+ m_windowCreatedTimer.start(200);
56ApplicationManager::~ApplicationManager()
60ApplicationManager::~ApplicationManager()
64+void ApplicationManager::onWindowCreatedTimerTimeout()
66+ if (QGuiApplication::topLevelWindows().count() > 0) {
67+ m_windowCreatedTimer.stop();
72+void ApplicationManager::onWindowCreated()
74+ startApplication("unity8-dash");
75+ focusApplication("unity8-dash");
60int ApplicationManager::rowCount(const QModelIndex& parent) const {
78int ApplicationManager::rowCount(const QModelIndex& parent) const {
61 return !parent.isValid() ? m_runningApplications.size() : 0;
79 return !parent.isValid() ? m_runningApplications.size() : 0;
@@ -81,8 +99,6 @@ QVariant ApplicationManager::data(const QModelIndex& index, int role) const {
81 return app->state();
99 return app->state();
82 case RoleFocused:
100 case RoleFocused:
83 return app->focused();
101 return app->focused();
85− return app->screenshot();
86 case RoleSession:
102 case RoleSession:
87 return QVariant::fromValue(app->session());
103 return QVariant::fromValue(app->session());
88 case RoleFullscreen:
104 case RoleFullscreen:
@@ -135,6 +151,16 @@ void ApplicationManager::add(ApplicationInfo *application) {
135 if (!appIndex.isValid()) return;
151 if (!appIndex.isValid()) return;
136 Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << ApplicationManager::RoleSession);
152 Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << ApplicationManager::RoleSession);
154+ connect(application, &ApplicationInfo::focusedChanged, this, [application, this]() {
155+ QModelIndex appIndex = findIndex(application);
156+ if (!appIndex.isValid()) return;
157+ Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << ApplicationManager::RoleFocused);
159+ connect(application, &ApplicationInfo::stateChanged, this, [application, this]() {
160+ QModelIndex appIndex = findIndex(application);
161+ if (!appIndex.isValid()) return;
162+ Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << ApplicationManager::RoleState);
140void ApplicationManager::remove(ApplicationInfo *application) {
166void ApplicationManager::remove(ApplicationInfo *application) {
@@ -147,7 +173,7 @@ void ApplicationManager::remove(ApplicationInfo *application) {
147 Q_EMIT countChanged();
173 Q_EMIT countChanged();
148 if (isEmpty()) Q_EMIT emptyChanged(isEmpty());
174 if (isEmpty()) Q_EMIT emptyChanged(isEmpty());
150− disconnect(application, &ApplicationInfo::sessionChanged, this, 0);
176+ application->disconnect(this);
153void ApplicationManager::move(int from, int to) {
179void ApplicationManager::move(int from, int to) {
@@ -190,6 +216,21 @@ ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
190 const QStringList &arguments)
216 const QStringList &arguments)
192 Q_UNUSED(arguments)
218 Q_UNUSED(arguments)
219+ ApplicationInfo *application = add(appId);
223+ if (flags.testFlag(ApplicationManager::ForceMainStage)
224+ && application->stage() == ApplicationInfo::SideStage) {
225+ application->setStage(ApplicationInfo::MainStage);
227+ application->setState(ApplicationInfo::Running);
232+ApplicationInfo* ApplicationManager::add(QString appId)
193 ApplicationInfo *application = 0;
234 ApplicationInfo *application = 0;
195 for (ApplicationInfo *availableApp : m_availableApplications) {
236 for (ApplicationInfo *availableApp : m_availableApplications) {
@@ -199,15 +240,8 @@ ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
202− if (!application)
243+ if (application)
203− return 0;
244+ add(application);
205− if (flags.testFlag(ApplicationManager::ForceMainStage)
206− && application->stage() == ApplicationInfo::SideStage) {
207− application->setStage(ApplicationInfo::MainStage);
210− application->setState(ApplicationInfo::Running);
212 return application;
246 return application;
@@ -230,27 +264,6 @@ bool ApplicationManager::stopApplication(const QString &appId)
230 return true;
264 return true;
233−bool ApplicationManager::updateScreenshot(const QString &appId)
236− ApplicationInfo *application = nullptr;
237− for (int i = 0; i < m_availableApplications.count(); ++i) {
238− application = m_availableApplications.at(i);
239− if (application->appId() == appId) {
249− QModelIndex appIndex = index(idx);
250− Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << RoleScreenshot);
254QString ApplicationManager::focusedApplicationId() const {
267QString ApplicationManager::focusedApplicationId() const {
255 for (ApplicationInfo *app : m_runningApplications) {
268 for (ApplicationInfo *app : m_runningApplications) {
256 if (app->focused()) {
269 if (app->focused()) {
@@ -285,32 +298,18 @@ bool ApplicationManager::focusApplication(const QString &appId)
285 if (application == nullptr)
298 if (application == nullptr)
286 return false;
299 return false;
288− if (application->stage() == ApplicationInfo::MainStage) {
301+ // unfocus currently focused app
289− // unfocus currently focused mainstage app
302+ for (ApplicationInfo *app : m_runningApplications) {
290− for (ApplicationInfo *app : m_runningApplications) {
303+ if (app->focused()) {
291− if (app->focused() && app->stage() == ApplicationInfo::MainStage) {
304+ app->setFocused(false);
292− app->setFocused(false);
305+ app->setState(ApplicationInfo::Suspended);
293− app->setState(ApplicationInfo::Suspended);
298− application->setFocused(true);
299− application->setState(ApplicationInfo::Running);
300− } else if (application->stage() == ApplicationInfo::SideStage) {
301− // unfocus currently focused sidestage app
302− for (ApplicationInfo *app : m_runningApplications) {
303− if (app->focused() && app->stage() == ApplicationInfo::SideStage) {
304− app->setFocused(false);
305− app->setState(ApplicationInfo::Suspended);
310− application->setFocused(true);
311− application->setState(ApplicationInfo::Running);
310+ application->setFocused(true);
311+ application->setState(ApplicationInfo::Running);
314 // move app to top of stack
313 // move app to top of stack
315 move(m_runningApplications.indexOf(application), 0);
314 move(m_runningApplications.indexOf(application), 0);
316 Q_EMIT focusedApplicationIdChanged();
315 Q_EMIT focusedApplicationIdChanged();
@@ -333,126 +332,114 @@ void ApplicationManager::unfocusCurrentApplication()
333 Q_EMIT focusedApplicationIdChanged();
332 Q_EMIT focusedApplicationIdChanged();
336−void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
338− application->setScreenshot(QString("file://%1/Dash/graphics/phone/screenshots/%2@12.png").arg(qmlDirectory())
339− .arg(application->icon().toString()));
342void ApplicationManager::buildListOfAvailableApplications()
335void ApplicationManager::buildListOfAvailableApplications()
344 ApplicationInfo *application;
337 ApplicationInfo *application;
346− application = new ApplicationInfo("unity8-dash", this);
339+ application = new ApplicationInfo(("unity8-dash", this);
347 application->setName("Unity 8 Mock Dash");
340 application->setName("Unity 8 Mock Dash");
348− application->setIcon(QUrl("unity8-dash"));
341+ application->setScreenshotId("unity8-dash");
349 application->setStage(ApplicationInfo::MainStage);
342 application->setStage(ApplicationInfo::MainStage);
350− generateQmlStrings(application);
351 m_availableApplications.append(application);
343 m_availableApplications.append(application);
353 application = new ApplicationInfo("dialer-app", this);
345 application = new ApplicationInfo("dialer-app", this);
354 application->setName("Dialer");
346 application->setName("Dialer");
355− application->setIcon(QUrl("dialer"));
347+ application->setScreenshotId("dialer");
348+ application->setIconId("dialer-app");
356 application->setStage(ApplicationInfo::SideStage);
349 application->setStage(ApplicationInfo::SideStage);
357− generateQmlStrings(application);
358 m_availableApplications.append(application);
350 m_availableApplications.append(application);
360 application = new ApplicationInfo("camera-app", this);
352 application = new ApplicationInfo("camera-app", this);
361 application->setName("Camera");
353 application->setName("Camera");
362− application->setIcon(QUrl("camera"));
354+ application->setScreenshotId("camera");
355+ application->setIconId("camera");
363 application->setFullscreen(true);
356 application->setFullscreen(true);
364− generateQmlStrings(application);
365 m_availableApplications.append(application);
357 m_availableApplications.append(application);
367 application = new ApplicationInfo("gallery-app", this);
359 application = new ApplicationInfo("gallery-app", this);
368 application->setName("Gallery");
360 application->setName("Gallery");
369− application->setIcon(QUrl("gallery"));
361+ application->setScreenshotId("gallery");
370− generateQmlStrings(application);
362+ application->setIconId("gallery");
363+ application->setFullscreen(true);
371 m_availableApplications.append(application);
364 m_availableApplications.append(application);
373 application = new ApplicationInfo("facebook-webapp", this);
366 application = new ApplicationInfo("facebook-webapp", this);
374 application->setName("Facebook");
367 application->setName("Facebook");
375− application->setIcon(QUrl("facebook"));
368+ application->setScreenshotId("facebook");
369+ application->setIconId("facebook");
376 application->setStage(ApplicationInfo::SideStage);
370 application->setStage(ApplicationInfo::SideStage);
377− generateQmlStrings(application);
378 m_availableApplications.append(application);
371 m_availableApplications.append(application);
380 application = new ApplicationInfo("webbrowser-app", this);
373 application = new ApplicationInfo("webbrowser-app", this);
381 application->setFullscreen(true);
374 application->setFullscreen(true);
382 application->setName("Browser");
375 application->setName("Browser");
383− application->setIcon(QUrl("browser"));
376+ application->setScreenshotId("browser");
384− generateQmlStrings(application);
377+ application->setIconId("browser");
385 m_availableApplications.append(application);
378 m_availableApplications.append(application);
387 application = new ApplicationInfo("twitter-webapp", this);
380 application = new ApplicationInfo("twitter-webapp", this);
388 application->setName("Twitter");
381 application->setName("Twitter");
389− application->setIcon(QUrl("twitter"));
382+ application->setScreenshotId("twitter");
383+ application->setIconId("twitter");
390 application->setStage(ApplicationInfo::SideStage);
384 application->setStage(ApplicationInfo::SideStage);
391− generateQmlStrings(application);
385+ m_availableApplications.append(application);
387+ application = new ApplicationInfo("map", this);
388+ application->setName("Map");
389+ application->setIconId("map");
390+ application->setScreenshotId("map");
392 m_availableApplications.append(application);
391 m_availableApplications.append(application);
394 application = new ApplicationInfo("gmail-webapp", this);
393 application = new ApplicationInfo("gmail-webapp", this);
395 application->setName("GMail");
394 application->setName("GMail");
396− application->setIcon(QUrl("gmail"));
395+ application->setIconId("gmail");
397 m_availableApplications.append(application);
396 m_availableApplications.append(application);
399 application = new ApplicationInfo("ubuntu-weather-app", this);
398 application = new ApplicationInfo("ubuntu-weather-app", this);
400 application->setName("Weather");
399 application->setName("Weather");
401− application->setIcon(QUrl("weather"));
400+ application->setIconId("weather");
402 application->setStage(ApplicationInfo::SideStage);
401 application->setStage(ApplicationInfo::SideStage);
403− generateQmlStrings(application);
404 m_availableApplications.append(application);
402 m_availableApplications.append(application);
406 application = new ApplicationInfo("notes-app", this);
404 application = new ApplicationInfo("notes-app", this);
407 application->setName("Notepad");
405 application->setName("Notepad");
408− application->setIcon(QUrl("notepad"));
406+ application->setIconId("notepad");
409 application->setStage(ApplicationInfo::SideStage);
407 application->setStage(ApplicationInfo::SideStage);
410 m_availableApplications.append(application);
408 m_availableApplications.append(application);
412 application = new ApplicationInfo("calendar-app", this);
410 application = new ApplicationInfo("calendar-app", this);
413 application->setName("Calendar");
411 application->setName("Calendar");
414− application->setIcon(QUrl("calendar"));
412+ application->setIconId("calendar");
415 application->setStage(ApplicationInfo::SideStage);
413 application->setStage(ApplicationInfo::SideStage);
416 m_availableApplications.append(application);
414 m_availableApplications.append(application);
418− application = new ApplicationInfo("mediaplayer-app", this);
419− application->setName("Media Player");
420− application->setIcon(QUrl("mediaplayer-app"));
421− application->setFullscreen(true);
422− m_availableApplications.append(application);
424 application = new ApplicationInfo("evernote", this);
416 application = new ApplicationInfo("evernote", this);
425 application->setName("Evernote");
417 application->setName("Evernote");
426− application->setIcon(QUrl("evernote"));
418+ application->setIconId("evernote");
427− m_availableApplications.append(application);
429− application = new ApplicationInfo("map", this);
430− application->setName("Map");
431− application->setIcon(QUrl("map"));
432− generateQmlStrings(application);
433 m_availableApplications.append(application);
419 m_availableApplications.append(application);
435 application = new ApplicationInfo("pinterest", this);
421 application = new ApplicationInfo("pinterest", this);
436 application->setName("Pinterest");
422 application->setName("Pinterest");
437− application->setIcon(QUrl("pinterest"));
423+ application->setIconId("pinterest");
438 m_availableApplications.append(application);
424 m_availableApplications.append(application);
440 application = new ApplicationInfo("soundcloud", this);
426 application = new ApplicationInfo("soundcloud", this);
441 application->setName("SoundCloud");
427 application->setName("SoundCloud");
442− application->setIcon(QUrl("soundcloud"));
428+ application->setIconId("soundcloud");
443 m_availableApplications.append(application);
429 m_availableApplications.append(application);
445 application = new ApplicationInfo("wikipedia", this);
431 application = new ApplicationInfo("wikipedia", this);
446 application->setName("Wikipedia");
432 application->setName("Wikipedia");
447− application->setIcon(QUrl("wikipedia"));
433+ application->setIconId("wikipedia");
448 m_availableApplications.append(application);
434 m_availableApplications.append(application);
450 application = new ApplicationInfo("youtube", this);
436 application = new ApplicationInfo("youtube", this);
451 application->setName("YouTube");
437 application->setName("YouTube");
452− application->setIcon(QUrl("youtube"));
438+ application->setIconId("youtube");
453 m_availableApplications.append(application);
439 m_availableApplications.append(application);
456QStringList ApplicationManager::availableApplications()
443QStringList ApplicationManager::availableApplications()
458 QStringList appIds;
445 QStringList appIds;