mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-02-07 06:59:45 +00:00
feat(src/app/App): remove usage of async creation of calls/settings window
This commit is contained in:
parent
a067245eca
commit
873f9df429
5 changed files with 25 additions and 230 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -215,8 +215,11 @@ void App::tryToUsePreferredLocale () {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QQuickWindow *App::getCallsWindow () const {
|
||||
return qobject_cast<QQuickWindow *>(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<QQuickWindow *>(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<linphone::Core> 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<QQuickWindow *>(object);
|
||||
QObject::connect(
|
||||
window, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) {
|
||||
if (visibility == QWindow::Hidden) {
|
||||
qInfo() << "Update nat policy.";
|
||||
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
core->setNatPolicy(core->getNatPolicy());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "../components/notifier/Notifier.hpp"
|
||||
#include "../externals/single-application/SingleApplication.hpp"
|
||||
#include "object-builders/AsyncObjectBuilder.hpp"
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
|
@ -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<App *>(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_
|
||||
|
|
|
|||
|
|
@ -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 <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QQmlIncubator>
|
||||
|
||||
#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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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 <functional>
|
||||
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlEngine>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class AsyncObjectBuilder : public QObject {
|
||||
Q_OBJECT;
|
||||
|
||||
class ObjectIncubator;
|
||||
|
||||
typedef std::function<void (QObject *)> 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_
|
||||
Loading…
Add table
Reference in a new issue