Unity 8
main.cpp
1 /*
2  * Copyright (C) 2012-2015 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 // Qt
18 #include <QCommandLineParser>
19 #include <QtQuick/QQuickView>
20 #include <QtGui/QGuiApplication>
21 #include <QtQml/QQmlEngine>
22 #include <QtQml/QQmlContext>
23 #include <QLibrary>
24 #include <QDebug>
25 #include <csignal>
26 #include <libintl.h>
27 
28 // local
29 #include <paths.h>
30 #include "MouseTouchAdaptor.h"
31 #include "ApplicationArguments.h"
32 #include "CachingNetworkManagerFactory.h"
33 
34 // Ubuntu Gestures
35 #include <TouchRegistry.h>
36 
37 int main(int argc, const char *argv[])
38 {
39  bool isMirServer = false;
40  if (qgetenv("QT_QPA_PLATFORM") == "ubuntumirclient") {
41  setenv("QT_QPA_PLATFORM", "mirserver", 1 /* overwrite */);
42  isMirServer = true;
43  }
44 
45  QGuiApplication::setApplicationName("unity8");
46  QGuiApplication *application;
47 
48  QCommandLineParser parser;
49  parser.setApplicationDescription("Description: Unity 8 Shell");
50  parser.addHelpOption();
51 
52  QCommandLineOption fullscreenOption("fullscreen",
53  "Run in fullscreen");
54  parser.addOption(fullscreenOption);
55 
56  QCommandLineOption framelessOption("frameless",
57  "Run without window borders");
58  parser.addOption(framelessOption);
59 
60  QCommandLineOption mousetouchOption("mousetouch",
61  "Allow the mouse to provide touch input");
62  parser.addOption(mousetouchOption);
63 
64  QCommandLineOption windowGeometryOption(QStringList() << "windowgeometry",
65  "Specify the window geometry as [<width>x<height>]", "windowgeometry", "1");
66  parser.addOption(windowGeometryOption);
67 
68  QCommandLineOption testabilityOption("testability",
69  "DISCOURAGED: Please set QT_LOAD_TESTABILITY instead. \n \
70 Load the testability driver");
71  parser.addOption(testabilityOption);
72 
73  application = new QGuiApplication(argc, (char**)argv);
74 
75  // Treat args with single dashes the same as arguments with two dashes
76  // Ex: -fullscreen == --fullscreen
77  parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
78  parser.process(*application);
79 
80  QString indicatorProfile = qgetenv("UNITY_INDICATOR_PROFILE");
81  if (indicatorProfile.isEmpty()) {
82  indicatorProfile = "phone";
83  }
84 
85  ApplicationArguments qmlArgs;
86  if (parser.isSet(windowGeometryOption) &&
87  parser.value(windowGeometryOption).split('x').size() == 2)
88  {
89  QStringList geom = parser.value(windowGeometryOption).split('x');
90  qmlArgs.setSize(geom.at(0).toInt(), geom.at(1).toInt());
91  }
92 
93  // The testability driver is only loaded by QApplication but not by QGuiApplication.
94  // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
95  if (parser.isSet(testabilityOption) || getenv("QT_LOAD_TESTABILITY")) {
96  QLibrary testLib(QLatin1String("qttestability"));
97  if (testLib.load()) {
98  typedef void (*TasInitialize)(void);
99  TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
100  if (initFunction) {
101  initFunction();
102  } else {
103  qCritical("Library qttestability resolve failed!");
104  }
105  } else {
106  qCritical("Library qttestability load failed!");
107  }
108  }
109 
110  bindtextdomain("unity8", translationDirectory().toUtf8().data());
111  textdomain("unity8");
112 
113  QQuickView* view = new QQuickView();
114  view->setResizeMode(QQuickView::SizeRootObjectToView);
115  view->setColor("black");
116  view->setTitle("Unity8 Shell");
117  view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
118  view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
119  view->rootContext()->setContextProperty("indicatorProfile", indicatorProfile);
120  if (parser.isSet(framelessOption)) {
121  view->setFlags(Qt::FramelessWindowHint);
122  }
123  TouchRegistry touchRegistry;
124  view->installEventFilter(&touchRegistry);
125 
126  // You will need this if you want to interact with touch-only components using a mouse
127  // Needed only when manually testing on a desktop.
128  MouseTouchAdaptor *mouseTouchAdaptor = 0;
129  if (parser.isSet(mousetouchOption)) {
130  mouseTouchAdaptor = MouseTouchAdaptor::instance();
131  }
132 
133  QUrl source(::qmlDirectory()+"Shell.qml");
134  prependImportPaths(view->engine(), ::overrideImportPaths());
135  if (!isMirServer) {
136  prependImportPaths(view->engine(), ::nonMirImportPaths());
137  }
138  appendImportPaths(view->engine(), ::fallbackImportPaths());
139 
140  CachingNetworkManagerFactory *managerFactory = new CachingNetworkManagerFactory();
141  view->engine()->setNetworkAccessManagerFactory(managerFactory);
142 
143  view->setSource(source);
144  QObject::connect(view->engine(), SIGNAL(quit()), application, SLOT(quit()));
145 
146  if (isMirServer || parser.isSet(fullscreenOption)) {
147  view->showFullScreen();
148  } else {
149  view->show();
150  }
151 
152  int result = application->exec();
153 
154  delete view;
155  delete mouseTouchAdaptor;
156  delete application;
157 
158  return result;
159 }