diff --git a/linphone-desktop/CMakeLists.txt b/linphone-desktop/CMakeLists.txt index 4fb353262..50bc65dc3 100644 --- a/linphone-desktop/CMakeLists.txt +++ b/linphone-desktop/CMakeLists.txt @@ -83,7 +83,6 @@ endif() set(SOURCES src/app/App.cpp src/app/logger/Logger.cpp - src/app/object-builders/AsyncObjectBuilder.cpp src/app/paths/Paths.cpp src/app/providers/AvatarProvider.cpp src/app/providers/ThumbnailProvider.cpp @@ -121,7 +120,6 @@ set(SOURCES set(HEADERS src/app/App.hpp src/app/logger/Logger.hpp - src/app/object-builders/AsyncObjectBuilder.hpp src/app/paths/Paths.hpp src/app/providers/AvatarProvider.hpp src/app/providers/ThumbnailProvider.hpp diff --git a/linphone-desktop/src/app/App.cpp b/linphone-desktop/src/app/App.cpp index eff3bcc8b..b4b8ff2a1 100644 --- a/linphone-desktop/src/app/App.cpp +++ b/linphone-desktop/src/app/App.cpp @@ -215,8 +215,11 @@ void App::tryToUsePreferredLocale () { // ----------------------------------------------------------------------------- -QQuickWindow *App::getCallsWindow () const { - return qobject_cast(m_calls_window.getObject()); +QQuickWindow *App::getCallsWindow () { + if (!m_calls_window) + m_calls_window = createSubWindow(this, QML_VIEW_CALLS_WINDOW); + + return m_calls_window; } QQuickWindow *App::getMainWindow () const { @@ -225,14 +228,27 @@ QQuickWindow *App::getMainWindow () const { ); } -QQuickWindow *App::getSettingsWindow () const { - return qobject_cast(m_settings_window.getObject()); +QQuickWindow *App::getSettingsWindow () { + if (!m_settings_window) { + m_settings_window = createSubWindow(this, QML_VIEW_SETTINGS_WINDOW); + QObject::connect( + m_settings_window, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) { + if (visibility == QWindow::Hidden) { + qInfo() << "Update nat policy."; + shared_ptr core = CoreManager::getInstance()->getCore(); + core->setNatPolicy(core->getNatPolicy()); + } + } + ); + } + + return m_settings_window; } // ----------------------------------------------------------------------------- bool App::hasFocus () const { - return getMainWindow()->isActive() || (m_calls_window.isCreated() && getCallsWindow()->isActive()); + return getMainWindow()->isActive() || (m_calls_window && m_calls_window->isActive()); } // ----------------------------------------------------------------------------- @@ -379,23 +395,6 @@ void App::openAppAfterInit () { #else getMainWindow()->showNormal(); #endif // ifndef __APPLE__ - - m_calls_window.createObject(&m_engine, QML_VIEW_CALLS_WINDOW); - - m_settings_window.createObject( - &m_engine, QML_VIEW_SETTINGS_WINDOW, [this](QObject *object) { - QQuickWindow *window = qobject_cast(object); - QObject::connect( - window, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) { - if (visibility == QWindow::Hidden) { - qInfo() << "Update nat policy."; - shared_ptr core = CoreManager::getInstance()->getCore(); - core->setNatPolicy(core->getNatPolicy()); - } - } - ); - } - ); } // ----------------------------------------------------------------------------- diff --git a/linphone-desktop/src/app/App.hpp b/linphone-desktop/src/app/App.hpp index 960c2847e..55aa032b4 100644 --- a/linphone-desktop/src/app/App.hpp +++ b/linphone-desktop/src/app/App.hpp @@ -25,7 +25,6 @@ #include "../components/notifier/Notifier.hpp" #include "../externals/single-application/SingleApplication.hpp" -#include "object-builders/AsyncObjectBuilder.hpp" #include #include @@ -59,12 +58,12 @@ public: return m_notifier; } - QQuickWindow *getCallsWindow () const; + QQuickWindow *getCallsWindow (); QQuickWindow *getMainWindow () const; bool hasFocus () const; - Q_INVOKABLE QQuickWindow *getSettingsWindow () const; + Q_INVOKABLE QQuickWindow *getSettingsWindow (); static App *getInstance () { return static_cast(QApplication::instance()); @@ -101,8 +100,8 @@ private: DefaultTranslator *m_translator = nullptr; Notifier *m_notifier = nullptr; - AsyncObjectBuilder m_calls_window; - AsyncObjectBuilder m_settings_window; + QQuickWindow *m_calls_window = nullptr; + QQuickWindow *m_settings_window = nullptr; }; #endif // APP_H_ diff --git a/linphone-desktop/src/app/object-builders/AsyncObjectBuilder.cpp b/linphone-desktop/src/app/object-builders/AsyncObjectBuilder.cpp deleted file mode 100644 index a6364cdd3..000000000 --- a/linphone-desktop/src/app/object-builders/AsyncObjectBuilder.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * AsyncObjectBuilder.cpp - * Copyright (C) 2017 Belledonne Communications, Grenoble, France - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Created on: March 27, 2017 - * Author: Ronan Abhamon - */ - -#include -#include -#include - -#include "AsyncObjectBuilder.hpp" - -using namespace std; - -// ============================================================================= - -class AsyncObjectBuilder::ObjectIncubator : public QQmlIncubator { -public: - // FIXME: At this moment, asynchronous loading is unstable. - // In the future, use `IncubationMode::Asynchronous` instead in Qt 5.9. - // - // See: https://bugreports.qt.io/browse/QTBUG-49416 and - // https://bugreports.qt.io/browse/QTBUG-50992 - ObjectIncubator (AsyncObjectBuilder *builder) : QQmlIncubator(IncubationMode::Synchronous) { - Q_ASSERT(builder != nullptr); - m_builder = builder; - } - -protected: - void statusChanged (Status status) override { - if (status == Error) { - qWarning() << "ObjectIncubator failed to build component:" << errors(); - abort(); - } - - if (status == Ready) { - QObject *object = QQmlIncubator::object(); - - QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); - object->setParent(m_builder); - - // Call user decorator. - if (m_builder->m_decorator) - m_builder->m_decorator(object); - - qInfo() << QStringLiteral("Creation of component instance is successful:") << m_builder->m_component; - - m_builder->m_object = object; - emit m_builder->objectCreated(object); - - Q_ASSERT(m_builder->m_component != nullptr); - Q_ASSERT(m_builder->m_incubator != nullptr); - - // Optimization: Delete unused component now. - m_builder->m_component->deleteLater(); - - // Optimization: Delete unused incubator. - m_builder->m_incubator = nullptr; - delete this; // Very courageous but works. - } - } - -private: - AsyncObjectBuilder *m_builder; -}; - -// ----------------------------------------------------------------------------- - -AsyncObjectBuilder::AsyncObjectBuilder (QObject *parent) : QObject(parent) {} - -AsyncObjectBuilder::~AsyncObjectBuilder () { - delete m_incubator; -} - -void AsyncObjectBuilder::createObject (QQmlEngine *engine, const char *path, Decorator decorator) { - #ifdef QT_DEBUG - Q_ASSERT(!m_block_creation); - m_block_creation = true; - - Q_ASSERT(engine != nullptr); - Q_ASSERT(path != nullptr); - #endif // ifdef QT_DEBUG - - m_component = new QQmlComponent(engine, QUrl(path), QQmlComponent::Asynchronous, this); - m_decorator = decorator; - - qInfo() << QStringLiteral("Start async creation of: `%1`. Component:").arg(path) << m_component; - - QObject::connect( - m_component, &QQmlComponent::statusChanged, - this, &AsyncObjectBuilder::handleComponentCreation, - Qt::DirectConnection - ); -} - -QObject *AsyncObjectBuilder::getObject () const { - while (!m_object) - QCoreApplication::processEvents(QEventLoop::AllEvents, 50); - - return m_object; -} - -void AsyncObjectBuilder::handleComponentCreation (QQmlComponent::Status status) { - if (status == QQmlComponent::Ready) { - qInfo() << QStringLiteral("Component built:") << m_component; - - m_incubator = new ObjectIncubator(this); - - qInfo() << QStringLiteral("Start creation of component instance:") << m_component; - - m_component->create(*m_incubator); - } else if (status == QQmlComponent::Error) { - qWarning() << "AsyncObjectBuilder failed to build component:" << m_component->errors(); - abort(); - } -} diff --git a/linphone-desktop/src/app/object-builders/AsyncObjectBuilder.hpp b/linphone-desktop/src/app/object-builders/AsyncObjectBuilder.hpp deleted file mode 100644 index b53d76f95..000000000 --- a/linphone-desktop/src/app/object-builders/AsyncObjectBuilder.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * AsyncObjectBuilder.hpp - * Copyright (C) 2017 Belledonne Communications, Grenoble, France - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Created on: March 27, 2017 - * Author: Ronan Abhamon - */ - -#ifndef ASYNC_OBJECT_BUILDER_H_ -#define ASYNC_OBJECT_BUILDER_H_ - -#include - -#include -#include - -// ============================================================================= - -class AsyncObjectBuilder : public QObject { - Q_OBJECT; - - class ObjectIncubator; - - typedef std::function Decorator; - -public: - AsyncObjectBuilder (QObject *parent = Q_NULLPTR); - ~AsyncObjectBuilder (); - - void createObject (QQmlEngine *engine, const char *path, Decorator decorator = nullptr); - QObject *getObject () const; - - bool isCreated () const { - return !!m_object; - } - -signals: - void objectCreated (QObject *object); - -private: - void handleComponentCreation (QQmlComponent::Status status); - - ObjectIncubator *m_incubator = nullptr; - QQmlComponent *m_component = nullptr; - - Decorator m_decorator; - - QObject *m_object = nullptr; - - #ifdef QT_DEBUG - bool m_block_creation = false; - #endif // ifdef QT_DEBUG -}; - -#endif // ASYNC_OBJECT_BUILDER_H_