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