on xenial help sign in
ShellApplication: use manual deletion for workaround hanging on shutdown
ffd336eDaniel d'Andrada
src/ShellApplication.cpp+16−6
@@ -74,7 +74,7 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
74 bindtextdomain("unity8", translationDirectory().toUtf8().data());
74 bindtextdomain("unity8", translationDirectory().toUtf8().data());
75 textdomain("unity8");
75 textdomain("unity8");
76
76
77− m_shellView.reset(new ShellView(m_qmlEngine, &m_qmlArgs));
77+ m_shellView = new ShellView(m_qmlEngine, &m_qmlArgs);
78
78
79 if (parser.windowGeometry().isValid()) {
79 if (parser.windowGeometry().isValid()) {
80 m_shellView->setWidth(parser.windowGeometry().width());
80 m_shellView->setWidth(parser.windowGeometry().width());
@@ -88,7 +88,7 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
88 // You will need this if you want to interact with touch-only components using a mouse
88 // You will need this if you want to interact with touch-only components using a mouse
89 // Needed only when manually testing on a desktop.
89 // Needed only when manually testing on a desktop.
90 if (parser.hasMouseToTouch()) {
90 if (parser.hasMouseToTouch()) {
91− m_mouseTouchAdaptor.reset(MouseTouchAdaptor::instance());
91+ m_mouseTouchAdaptor = MouseTouchAdaptor::instance();
92 }
92 }
93
93
94
94
@@ -101,7 +101,7 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
101 m_shellView->setScreen(screens().at(1));
101 m_shellView->setScreen(screens().at(1));
102 m_qmlArgs.setDeviceName("desktop");
102 m_qmlArgs.setDeviceName("desktop");
103
103
104− m_secondaryWindow.reset(new SecondaryWindow(m_qmlEngine));
104+ m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
105 m_secondaryWindow->setScreen(screens().at(0));
105 m_secondaryWindow->setScreen(screens().at(0));
106 // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
106 // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
107 m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
107 m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
@@ -115,6 +115,15 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
115 }
115 }
116}
116}
117
117
118+ShellApplication::~ShellApplication()
119+{
120+ // Deletion order is important. Don't use QScopedPointers and the like
121+ // Otherwise the process will hang on shutdown (bug somewhere I guess).
122+ delete m_shellView;
123+ delete m_secondaryWindow;
124+ delete m_mouseTouchAdaptor;
125+}
126+
118void ShellApplication::setupQmlEngine(bool isMirServer)
127void ShellApplication::setupQmlEngine(bool isMirServer)
119{
128{
120 m_qmlEngine = new QQmlEngine(this);
129 m_qmlEngine = new QQmlEngine(this);
@@ -143,7 +152,7 @@ void ShellApplication::onScreenAdded(QScreen * /*screen*/)
143 // its backing QPlatformWindow recreated). So lets refocus it.
152 // its backing QPlatformWindow recreated). So lets refocus it.
144 m_shellView->requestActivate();
153 m_shellView->requestActivate();
145
154
146− m_secondaryWindow.reset(new SecondaryWindow(m_qmlEngine));
155+ m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
147 m_secondaryWindow->setScreen(screens().at(0));
156 m_secondaryWindow->setScreen(screens().at(0));
148
157
149 // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
158 // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
@@ -159,8 +168,9 @@ void ShellApplication::onScreenAboutToBeRemoved(QScreen *screen)
159 if (screen == m_shellView->screen()) {
168 if (screen == m_shellView->screen()) {
160 Q_ASSERT(screens().count() > 1);
169 Q_ASSERT(screens().count() > 1);
161 Q_ASSERT(screens().at(0) != screen);
170 Q_ASSERT(screens().at(0) != screen);
162− Q_ASSERT(!m_secondaryWindow.isNull());
171+ Q_ASSERT(m_secondaryWindow);
163− m_secondaryWindow.reset();
172+ delete m_secondaryWindow;
173+ m_secondaryWindow = nullptr;
164 m_shellView->setScreen(screens().first());
174 m_shellView->setScreen(screens().first());
165 m_qmlArgs.setDeviceName(m_deviceName);
175 m_qmlArgs.setDeviceName(m_deviceName);
166 // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
176 // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
src/ShellApplication.h+4−3
@@ -32,6 +32,7 @@ class ShellApplication : public QGuiApplication
32 Q_OBJECT
32 Q_OBJECT
33public:
33public:
34 ShellApplication(int & argc, char ** argv, bool isMirServer);
34 ShellApplication(int & argc, char ** argv, bool isMirServer);
35+ virtual ~ShellApplication();
35
36
36public Q_SLOTS:
37public Q_SLOTS:
37 // called by qtmir
38 // called by qtmir
@@ -44,9 +45,9 @@ private:
44 void setupQmlEngine(bool isMirServer);
45 void setupQmlEngine(bool isMirServer);
45 QString m_deviceName;
46 QString m_deviceName;
46 ApplicationArguments m_qmlArgs;
47 ApplicationArguments m_qmlArgs;
47− QScopedPointer<ShellView> m_shellView;
48+ ShellView *m_shellView;
48− QScopedPointer<SecondaryWindow> m_secondaryWindow;
49+ SecondaryWindow *m_secondaryWindow;
49− QScopedPointer<MouseTouchAdaptor> m_mouseTouchAdaptor;
50+ MouseTouchAdaptor *m_mouseTouchAdaptor;
50 QQmlEngine *m_qmlEngine;
51 QQmlEngine *m_qmlEngine;
51};
52};
52
53