Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linphone-desktop
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
linphone-desktop
Commits
4ba245d6
Commit
4ba245d6
authored
Mar 27, 2017
by
Ronan Abhamon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(src/app/App): calls/settings windows are now created in asynchronous calls
parent
d3a54121
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
248 additions
and
47 deletions
+248
-47
CMakeLists.txt
linphone-desktop/CMakeLists.txt
+2
-0
App.cpp
linphone-desktop/src/app/App.cpp
+45
-43
App.hpp
linphone-desktop/src/app/App.hpp
+7
-4
AsyncObjectBuilder.cpp
linphone-desktop/src/app/AsyncObjectBuilder.cpp
+123
-0
AsyncObjectBuilder.hpp
linphone-desktop/src/app/AsyncObjectBuilder.hpp
+71
-0
No files found.
linphone-desktop/CMakeLists.txt
View file @
4ba245d6
...
...
@@ -78,6 +78,7 @@ endif()
set
(
SOURCES
src/app/App.cpp
src/app/AsyncObjectBuilder.cpp
src/app/AvatarProvider.cpp
src/app/DefaultTranslator.cpp
src/app/Logger.cpp
...
...
@@ -111,6 +112,7 @@ set(SOURCES
set
(
HEADERS
src/app/App.hpp
src/app/AsyncObjectBuilder.hpp
src/app/AvatarProvider.hpp
src/app/DefaultTranslator.hpp
src/app/Logger.hpp
...
...
linphone-desktop/src/app/App.cpp
View file @
4ba245d6
...
...
@@ -157,27 +157,7 @@ void App::initContentApp () {
if
(
m_parser
.
isSet
(
"selftest"
))
QObject
::
connect
(
core
,
&
CoreManager
::
linphoneCoreCreated
,
this
,
&
App
::
quit
);
else
QObject
::
connect
(
core
,
&
CoreManager
::
linphoneCoreCreated
,
this
,
[
core
,
this
]()
{
tryToUsePreferredLocale
();
qInfo
()
<<
QStringLiteral
(
"Linphone core created."
);
core
->
enableHandlers
();
#ifndef __APPLE__
// Enable TrayIconSystem.
if
(
!
QSystemTrayIcon
::
isSystemTrayAvailable
())
qWarning
(
"System tray not found on this system."
);
else
setTrayIcon
();
if
(
!
m_parser
.
isSet
(
"iconified"
))
getMainWindow
()
->
showNormal
();
#else
getMainWindow
()
->
showNormal
();
#endif // ifndef __APPLE__
}
);
QObject
::
connect
(
core
,
&
CoreManager
::
linphoneCoreCreated
,
this
,
&
App
::
openAppAfterInit
);
QObject
::
connect
(
this
,
&
App
::
receivedMessage
,
this
,
[
this
](
int
,
QByteArray
message
)
{
...
...
@@ -238,11 +218,8 @@ void App::tryToUsePreferredLocale () {
// -----------------------------------------------------------------------------
QQuickWindow
*
App
::
getCallsWindow
()
{
if
(
!
m_calls_window
)
m_calls_window
=
createSubWindow
(
this
,
QML_VIEW_CALLS_WINDOW
);
return
m_calls_window
;
QQuickWindow
*
App
::
getCallsWindow
()
const
{
return
qobject_cast
<
QQuickWindow
*>
(
m_calls_window
.
getObject
());
}
QQuickWindow
*
App
::
getMainWindow
()
const
{
...
...
@@ -251,28 +228,14 @@ QQuickWindow *App::getMainWindow () const {
);
}
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
;
QQuickWindow
*
App
::
getSettingsWindow
()
const
{
return
qobject_cast
<
QQuickWindow
*>
(
m_settings_window
.
getObject
());
}
// -----------------------------------------------------------------------------
bool
App
::
hasFocus
()
const
{
return
getMainWindow
()
->
isActive
()
||
(
m_calls_window
&&
m_calls_window
->
isActive
());
return
getMainWindow
()
->
isActive
()
||
(
m_calls_window
.
isCreated
()
&&
getCallsWindow
()
->
isActive
());
}
// -----------------------------------------------------------------------------
...
...
@@ -398,6 +361,45 @@ QString App::getLocale () const {
// -----------------------------------------------------------------------------
void
App
::
openAppAfterInit
()
{
tryToUsePreferredLocale
();
qInfo
()
<<
QStringLiteral
(
"Linphone core created."
);
CoreManager
::
getInstance
()
->
enableHandlers
();
#ifndef __APPLE__
// Enable TrayIconSystem.
if
(
!
QSystemTrayIcon
::
isSystemTrayAvailable
())
qWarning
(
"System tray not found on this system."
);
else
setTrayIcon
();
if
(
!
m_parser
.
isSet
(
"iconified"
))
getMainWindow
()
->
showNormal
();
#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
());
}
}
);
}
);
}
// -----------------------------------------------------------------------------
void
App
::
quit
()
{
if
(
m_parser
.
isSet
(
"selftest"
))
cout
<<
tr
(
"selftestResult"
).
toStdString
()
<<
endl
;
...
...
linphone-desktop/src/app/App.hpp
View file @
4ba245d6
...
...
@@ -25,6 +25,7 @@
#include "../components/notifier/Notifier.hpp"
#include "../externals/single-application/SingleApplication.hpp"
#include "AsyncObjectBuilder.hpp"
#include <QCommandLineParser>
#include <QQmlApplicationEngine>
...
...
@@ -58,12 +59,12 @@ public:
return
m_notifier
;
}
QQuickWindow
*
getCallsWindow
();
QQuickWindow
*
getCallsWindow
()
const
;
QQuickWindow
*
getMainWindow
()
const
;
bool
hasFocus
()
const
;
Q_INVOKABLE
QQuickWindow
*
getSettingsWindow
();
Q_INVOKABLE
QQuickWindow
*
getSettingsWindow
()
const
;
static
App
*
getInstance
()
{
return
static_cast
<
App
*>
(
QApplication
::
instance
());
...
...
@@ -88,6 +89,8 @@ private:
return
m_available_locales
;
}
void
openAppAfterInit
();
QCommandLineParser
m_parser
;
QVariantList
m_available_locales
;
...
...
@@ -98,8 +101,8 @@ private:
DefaultTranslator
*
m_translator
=
nullptr
;
Notifier
*
m_notifier
=
nullptr
;
QQuickWindow
*
m_calls_window
=
nullptr
;
QQuickWindow
*
m_settings_window
=
nullptr
;
AsyncObjectBuilder
m_calls_window
;
AsyncObjectBuilder
m_settings_window
;
};
#endif // APP_H_
linphone-desktop/src/app/AsyncObjectBuilder.cpp
0 → 100644
View file @
4ba245d6
/*
* 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.
// Use `IncubationMode::Synchronous` 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
)
{
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
);
m_builder
->
m_is_created
=
true
;
// 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
);
// 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
)
{
Q_ASSERT
(
!
m_block_creation
);
#ifdef QT_DEBUG
m_block_creation
=
true
;
#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
);
}
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
();
}
}
linphone-desktop/src/app/AsyncObjectBuilder.hpp
0 → 100644
View file @
4ba245d6
/*
* 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 <QQmlEngine>
#include <QQmlComponent>
// =============================================================================
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_is_created
;
}
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
;
bool
m_is_created
=
false
;
#ifdef QT_DEBUG
bool
m_block_creation
=
false
;
#endif // ifdef QT_DEBUG
};
#endif // ASYNC_OBJECT_BUILDER_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment