diff --git a/jami-qt.pro b/jami-qt.pro
index 7ff1ae464ca1ebdc377b2c0731eee391f9b6a3d2..30cf1f6ead952f15476d3b5e800e603c8cf8a384 100644
--- a/jami-qt.pro
+++ b/jami-qt.pro
@@ -17,7 +17,7 @@ win32-msvc {
     QMAKE_LFLAGS+= /ignore:4006,4049,4078,4098 /FORCE:MULTIPLE /INCREMENTAL:NO /Debug /LTCG /NODEFAULTLIB:LIBCMT
 
     # preprocessor defines
-    DEFINES += UNICODE PROCESS_DPI_AWARE=1 QT_NO_DEBUG NDEBUG
+    DEFINES += UNICODE QT_NO_DEBUG NDEBUG
 
     # dependencies
     LRC= ../lrc
@@ -179,7 +179,8 @@ HEADERS += ./src/aboutdialog.h \
         ./src/networkmanager.h \
         ./src/connectivitymonitor.h \
         ./src/userprofile.h \
-        ./src/qmlclipboardadapter.h
+        ./src/qmlclipboardadapter.h \
+        ./src/mainapplication.h
 SOURCES += ./src/aboutdialog.cpp \
         ./src/banneditemwidget.cpp \
         ./src/conversationsfilterwidget.cpp \
@@ -246,7 +247,8 @@ SOURCES += ./src/aboutdialog.cpp \
         ./src/recordwidget.cpp \
         ./src/networkmanager.cpp \
         ./src/connectivitymonitor.cpp \
-        ./src/userprofile.cpp
+        ./src/userprofile.cpp \
+        ./src/mainapplication.cpp
 FORMS += ./src/aboutdialog.ui \
         ./src/advancedsipsettingwidget.ui \
         ./src/callwidget.ui \
diff --git a/src/main.cpp b/src/main.cpp
index 7a614132f5a167c372926d6b1fca70bc4d57e49f..4ab402f7acc1b00a6b2aed0c0ffb54f4e327dede 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,8 @@
 /***************************************************************************
- * Copyright (C) 2015-2019 by Savoir-faire Linux                           *
+ * Copyright (C) 2015-2020 by Savoir-faire Linux                           *
  * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
  * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>          *
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>              *
  *                                                                         *
  * 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    *
@@ -17,286 +18,42 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
  **************************************************************************/
 
-#include "mainwindow.h"
-
-#include "accountmigrationdialog.h"
-#include "globalinstances.h"
-#include "networkmanager.h"
-#include "lrcinstance.h"
-#include "pixbufmanipulator.h"
+#include "mainapplication.h"
 #include "runguard.h"
-#include "utils.h"
-#include "splashscreen.h"
-#include "aboutdialog.h"
 #include "qmlclipboardadapter.h"
 
-#include <QApplication>
-#include <QFile>
-#include <QMessageBox>
-#include <QFontDatabase>
-#include <QLibraryInfo>
-#include <QTranslator>
-
-#include <thread>
-#include <ciso646>
-#include <locale.h>
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#endif
-
-#if defined _MSC_VER && !COMPILE_ONLY
-#include <gnutls/gnutls.h>
-#endif
-
-void
-consoleDebug()
-{
-#ifdef Q_OS_WIN
-    AllocConsole();
-    SetConsoleCP(CP_UTF8);
-
-    freopen("CONOUT$", "w", stdout);
-    freopen("CONOUT$", "w", stderr);
-
-    COORD coordInfo;
-    coordInfo.X = 130;
-    coordInfo.Y = 9000;
-
-    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
-    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
-#endif
-}
-
-#ifdef _MSC_VER
-void
-vsConsoleDebug()
-{
-    // Print debug to output window if using VS
-    QObject::connect(
-        &LRCInstance::behaviorController(),
-        &lrc::api::BehaviorController::debugMessageReceived,
-        [](const std::string& message) {
-            OutputDebugStringA((message + "\n").c_str());
-        });
-}
-#endif
-
-void
-fileDebug(QFile& debugFile)
-{
-    QObject::connect(
-        &LRCInstance::behaviorController(),
-        &lrc::api::BehaviorController::debugMessageReceived,
-        [&debugFile](const std::string& message) {
-            if (debugFile.open(QIODevice::WriteOnly | QIODevice::Append)) {
-                auto msg = (message + "\n").c_str();
-                debugFile.write(msg, qstrlen(msg));
-                debugFile.close();
-            }
-        });
-}
-
-void
-exitApp(RunGuard& guard)
-{
-    GlobalSystemTray::instance().hide();
-    guard.release();
-}
+#include <QCryptographicHash>
+#include <QQmlEngine>
+#include <QQmlApplicationEngine>
 
 int
 main(int argc, char* argv[])
 {
     setlocale(LC_ALL, "en_US.utf8");
 
-    char ARG_DISABLE_WEB_SECURITY[] = "--disable-web-security";
-    int newArgc = argc + 1 + 1;
-    char** newArgv = new char*[newArgc];
-    for (int i = 0; i < argc; i++) {
-        newArgv[i] = argv[i];
-    }
-    newArgv[argc] = ARG_DISABLE_WEB_SECURITY;
-    newArgv[argc + 1] = nullptr;
-
-#if defined(Q_OS_WIN) && (PROCESS_DPI_AWARE)
-    SetProcessDPIAware();
-#endif // Q_OS_WIN
-
-#ifdef Q_OS_LINUX
-    if (!getenv("QT_QPA_PLATFORMTHEME"))
-        setenv("QT_QPA_PLATFORMTHEME", "gtk3", true);
-#endif
-
-    QApplication a(newArgc, newArgv);
-
-    QCoreApplication::setApplicationName("Ring");
-    QCoreApplication::setOrganizationDomain("jami.net");
+    MainApplication::applicationInitialization();
 
+    // runguard to make sure that only one instance runs at a time
     QCryptographicHash appData(QCryptographicHash::Sha256);
     appData.addData(QApplication::applicationName().toUtf8());
     appData.addData(QApplication::organizationDomain().toUtf8());
     RunGuard guard(appData.result());
     if (!guard.tryToRun()) {
+        // no need to exitApp since app is not set up
+        guard.release();
         return 0;
     }
 
-    for (auto string : QCoreApplication::arguments()) {
-        if (string == "-d" || string == "--debug") {
-            consoleDebug();
-        }
-    }
-
-    Utils::removeOldVersions();
-
-    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);
-    QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-
-    auto startMinimized = false;
-    QString uri = "";
-
-    auto appDir = qApp->applicationDirPath() + "/";
-    const auto locale_name = QLocale::system().name();
-    const auto locale_lang = locale_name.split('_')[0];
-
-    QTranslator qtTranslator_lang;
-    QTranslator qtTranslator_name;
-    if (locale_name != locale_lang) {
-        if (qtTranslator_lang.load("qt_" + locale_lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
-            a.installTranslator(&qtTranslator_lang);
-    }
-    qtTranslator_name.load("qt_" + locale_name, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
-    a.installTranslator(&qtTranslator_name);
-
-    QTranslator lrcTranslator_lang;
-    QTranslator lrcTranslator_name;
-    if (locale_name != locale_lang) {
-        if (lrcTranslator_lang.load(appDir + "share/libringclient/translations/lrc_" + locale_lang))
-            a.installTranslator(&lrcTranslator_lang);
-    }
-    if (lrcTranslator_name.load(appDir + "share/libringclient/translations/lrc_" + locale_name))
-        a.installTranslator(&lrcTranslator_name);
-
-    QTranslator mainTranslator_lang;
-    QTranslator mainTranslator_name;
-    if (locale_name != locale_lang) {
-        if (mainTranslator_lang.load(appDir + "share/ring/translations/ring_client_windows_" + locale_lang))
-            a.installTranslator(&mainTranslator_lang);
-    }
-    if (mainTranslator_name.load(appDir + "share/ring/translations/ring_client_windows_" + locale_name))
-        a.installTranslator(&mainTranslator_name);
-
-    QFont font;
-    font.setFamily("Segoe UI");
-    a.setFont(font);
-
-#ifndef DEBUG_STYLESHEET
-#ifdef Q_OS_LINUX
-    QFile file(":/stylesheet.linux.css");
-#else
-    QFile file(":/stylesheet.css");
-#endif
-    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
-        a.setStyleSheet(file.readAll());
-        file.close();
-    }
-#endif
-
-#if defined _MSC_VER && !COMPILE_ONLY
-    gnutls_global_init();
-#endif
-
-    GlobalInstances::setPixmapManipulator(std::make_unique<PixbufManipulator>());
-
-    SplashScreen* splash = new SplashScreen();
-    std::atomic_bool isMigrating(false);
-    LRCInstance::init(
-        [&splash, &a, &isMigrating] {
-            splash->setupUI(
-                QPixmap(":/images/logo-jami-standard-coul.png"),
-                QString("Jami - ") + QObject::tr("Migration needed"),
-                QObject::tr("Migration in progress... This may take a while."),
-                QColor(232, 232, 232)
-            );
-            splash->show();
-            isMigrating = true;
-            while (isMigrating) {
-                a.processEvents();
-            }
-        },
-        [&splash, &isMigrating] {
-            while (!isMigrating) {
-                std::this_thread::sleep_for(std::chrono::milliseconds(10));
-            }
-            isMigrating = false;
-        });
-    splash->hide();
-    LRCInstance::subscribeToDebugReceived();
-    LRCInstance::getAPI().holdConferences = false;
-
-    QDir logPath(QStandardPaths::writableLocation(
-        QStandardPaths::AppLocalDataLocation));
-    // since logPath will be .../Ring, we use cdUp to remove it.
-    logPath.cdUp();
-    QFile debugFile(logPath.absolutePath() + "/jami/jami.log");
-
-    for (auto string : QCoreApplication::arguments()) {
-        if (string.startsWith("jami:")) {
-            uri = string;
-        } else {
-            if (string == "-m" || string == "--minimized") {
-                startMinimized = true;
-            }
-            auto dbgFile = string == "-f" || string == "--file";
-            auto dbgConsole = string == "-c" || string == "--vsconsole";
-            if (dbgFile || dbgConsole) {
-                if (dbgFile) {
-                    debugFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
-                    debugFile.close();
-                    fileDebug(debugFile);
-                }
-#ifdef _MSC_VER
-                if (dbgConsole) {
-                    vsConsoleDebug();
-                }
-#endif
-            }
-        }
-    }
-
-    auto accountList = LRCInstance::accountModel().getAccountList();
-
-    for (const std::string& i : accountList) {
-        auto accountStatus = LRCInstance::accountModel().getAccountInfo(i).status;
-        if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
-            std::unique_ptr<AccountMigrationDialog> dialog = std::make_unique<AccountMigrationDialog>(nullptr, i);
-            int status = dialog->exec();
-
-            //migration failed
-            if (!status) {
-#ifdef Q_OS_WIN
-                FreeConsole();
-#endif
-                exitApp(guard);
-                return status;
-            }
-        }
-    }
-
-    splash->finish(&MainWindow::instance());
-    splash->deleteLater();
-
-    QFontDatabase::addApplicationFont(":/images/FontAwesome.otf");
+    char ARG_DISABLE_WEB_SECURITY[] = "--disable-web-security";
+    auto newArgv = MainApplication::parseInputArgument(argc, argv, ARG_DISABLE_WEB_SECURITY);
 
-    QSettings settings("jami.net", "Jami");
-    if (not startMinimized) {
-        MainWindow::instance().showWindow();
-    } else {
-        MainWindow::instance().showMinimized();
-        MainWindow::instance().hide();
+    MainApplication a(argc, newArgv);
+    if (!a.applicationSetup()) {
+        guard.release();
+        a.exitApp();
+        return 0;
     }
 
-    QObject::connect(&a, &QApplication::aboutToQuit, [&guard] { exitApp(guard); });
-
     // for deployment and register types
     qmlRegisterType<QmlClipboardAdapter>("MyQClipboard", 1, 0, "QClipboard");
 
@@ -304,11 +61,9 @@ main(int argc, char* argv[])
     engine.load(QUrl(QStringLiteral("qrc:/src/KeyBoardShortcutTable.qml")));
     engine.load(QUrl(QStringLiteral("qrc:/src/UserProfileCard.qml")));
 
+    // exec the application
     auto ret = a.exec();
 
-#ifdef Q_OS_WIN
-    FreeConsole();
-#endif
-
+    guard.release();
     return ret;
 }
diff --git a/src/mainapplication.cpp b/src/mainapplication.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9a31ba22ec801c0fe0024b00aee10b5c23bdd62
--- /dev/null
+++ b/src/mainapplication.cpp
@@ -0,0 +1,339 @@
+/***************************************************************************
+ * Copyright (C) 2015-2020 by Savoir-faire Linux                           *
+ * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>          *
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>              *
+ *                                                                         *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.   *
+ **************************************************************************/
+
+#include "mainapplication.h"
+
+#include "mainwindow.h"
+#include "accountmigrationdialog.h"
+#include "globalinstances.h"
+#include "lrcinstance.h"
+#include "pixbufmanipulator.h"
+#include "utils.h"
+
+#include <locale.h>
+
+#ifdef Q_OS_WIN
+#include <windows.h>
+#endif
+
+#if defined _MSC_VER && !COMPILE_ONLY
+#include <gnutls/gnutls.h>
+#endif
+
+MainApplication::MainApplication(int &argc, char** argv) :
+    QApplication(argc, argv)
+{
+    QObject::connect(this, &QApplication::aboutToQuit, [this] { exitApp(); });
+}
+
+void
+MainApplication::applicationInitialization()
+{
+    // some attributes are needed to be set before the creation of the sapplication
+    QApplication::setApplicationName("Ring");
+    QApplication::setOrganizationDomain("jami.net");
+    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
+    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+}
+
+void
+MainApplication::consoleDebug()
+{
+#ifdef Q_OS_WIN
+    AllocConsole();
+    SetConsoleCP(CP_UTF8);
+
+    freopen("CONOUT$", "w", stdout);
+    freopen("CONOUT$", "w", stderr);
+
+    COORD coordInfo;
+    coordInfo.X = 130;
+    coordInfo.Y = 9000;
+
+    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
+    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
+#endif
+}
+
+void
+MainApplication::vsConsoleDebug()
+{
+#ifdef _MSC_VER
+    // Print debug to output window if using VS
+    QObject::connect(
+        &LRCInstance::behaviorController(),
+        &lrc::api::BehaviorController::debugMessageReceived,
+        [](const std::string& message) {
+            OutputDebugStringA((message + "\n").c_str());
+        });
+#endif
+}
+
+void
+MainApplication::fileDebug(QFile* debugFile)
+{
+    QObject::connect(
+        &LRCInstance::behaviorController(),
+        &lrc::api::BehaviorController::debugMessageReceived,
+        [debugFile](const std::string& message) {
+            if (debugFile->open(QIODevice::WriteOnly | QIODevice::Append)) {
+                auto msg = (message + "\n").c_str();
+                debugFile->write(msg, qstrlen(msg));
+                debugFile->close();
+            }
+        });
+}
+
+void
+MainApplication::exitApp()
+{
+    GlobalSystemTray::instance().hide();
+#ifdef Q_OS_WIN
+    FreeConsole();
+#endif
+}
+
+char**
+MainApplication::parseInputArgument(int& argc, char* argv[], char* argToParse)
+{
+    // forcefully append argToParse
+    int oldArgc = argc;
+    argc = argc + 1 + 1;
+    char** newArgv = new char* [argc];
+    for (int i = 0; i < oldArgc; i++) {
+        newArgv[i] = argv[i];
+    }
+    newArgv[oldArgc] = argToParse;
+    newArgv[oldArgc + 1] = nullptr;
+    return newArgv;
+}
+
+QString
+MainApplication::getDebugFilePath()
+{
+    QDir logPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
+    // since logPath will be .../Ring, we use cdUp to remove it.
+    logPath.cdUp();
+    return QString(logPath.absolutePath() + "/jami/jami.log");
+}
+
+void
+MainApplication::loadTranslations()
+{
+    auto appDir = qApp->applicationDirPath() + "/";
+    const auto locale_name = QLocale::system().name();
+    const auto locale_lang = locale_name.split('_')[0];
+
+    QTranslator qtTranslator_lang;
+    QTranslator qtTranslator_name;
+    if (locale_name != locale_lang) {
+        if (qtTranslator_lang.load("qt_" + locale_lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+            installTranslator(&qtTranslator_lang);
+    }
+    qtTranslator_name.load("qt_" + locale_name, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
+    installTranslator(&qtTranslator_name);
+
+    QTranslator lrcTranslator_lang;
+    QTranslator lrcTranslator_name;
+    if (locale_name != locale_lang) {
+        if (lrcTranslator_lang.load(appDir + "share/libringclient/translations/lrc_" + locale_lang))
+            installTranslator(&lrcTranslator_lang);
+    }
+    if (lrcTranslator_name.load(appDir + "share/libringclient/translations/lrc_" + locale_name))
+        installTranslator(&lrcTranslator_name);
+
+    QTranslator mainTranslator_lang;
+    QTranslator mainTranslator_name;
+    if (locale_name != locale_lang) {
+        if (mainTranslator_lang.load(appDir + "share/ring/translations/ring_client_windows_" + locale_lang))
+            installTranslator(&mainTranslator_lang);
+    }
+    if (mainTranslator_name.load(appDir + "share/ring/translations/ring_client_windows_" + locale_name))
+        installTranslator(&mainTranslator_name);
+}
+
+void
+MainApplication::initLrc()
+{
+    // init mainwindow and finish splash when mainwindow shows up
+    splash_ = std::make_unique<SplashScreen>();
+    std::atomic_bool isMigrating(false);
+    LRCInstance::init(
+        [this, &isMigrating] {
+            splash_->setupUI(
+                QPixmap(":/images/logo-jami-standard-coul.png"),
+                QString("Jami - ") + QObject::tr("Migration needed"),
+                QObject::tr("Migration in progress... This may take a while."),
+                QColor(232, 232, 232)
+            );
+            splash_->show();
+            isMigrating = true;
+            while (isMigrating) {
+                this->processEvents();
+            }
+        },
+        [this, &isMigrating] {
+            while (!isMigrating) {
+                std::this_thread::sleep_for(std::chrono::milliseconds(10));
+            }
+            isMigrating = false;
+        });
+    splash_->hide();
+    LRCInstance::subscribeToDebugReceived();
+    LRCInstance::getAPI().holdConferences = false;
+}
+
+void
+MainApplication::processInputArgument(bool& startMinimized)
+{
+    debugFile_ = std::make_unique<QFile>(getDebugFilePath());
+    QString uri = "";
+
+    for (auto string : QCoreApplication::arguments()) {
+        if (string.startsWith("jami:")) {
+            uri = string;
+        }
+        else {
+            if (string == "-m" || string == "--minimized") {
+                startMinimized = true;
+            }
+            auto dbgFile = string == "-f" || string == "--file";
+            auto dbgConsole = string == "-c" || string == "--vsconsole";
+            if (dbgFile || dbgConsole) {
+                if (dbgFile) {
+                    debugFile_->open(QIODevice::WriteOnly | QIODevice::Truncate);
+                    debugFile_->close();
+                    fileDebug(debugFile_.get());
+                }
+#ifdef _MSC_VER
+                if (dbgConsole) {
+                    vsConsoleDebug();
+                }
+#endif
+            }
+        }
+    }
+}
+
+void
+MainApplication::setApplicationStyleSheet()
+{
+#ifndef DEBUG_STYLESHEET
+#ifdef Q_OS_LINUX
+    QFile file(":/stylesheet.linux.css");
+#else
+    QFile file(":/stylesheet.css");
+#endif
+    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        setStyleSheet(file.readAll());
+        file.close();
+    }
+#endif
+}
+
+bool
+MainApplication::startAccountMigration()
+{
+    auto accountList = LRCInstance::accountModel().getAccountList();
+
+    for (const std::string& i : accountList) {
+        auto accountStatus = LRCInstance::accountModel().getAccountInfo(i).status;
+        if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
+            std::unique_ptr<AccountMigrationDialog> dialog = std::make_unique<AccountMigrationDialog>(nullptr, i);
+            int status = dialog->exec();
+
+            //migration failed
+            return status == 0 ? false : true;
+        }
+    }
+    return true;
+}
+
+void
+MainApplication::setApplicationFont()
+{
+    QFont font;
+    font.setFamily("Segoe UI");
+    setFont(font);
+    QFontDatabase::addApplicationFont(":/images/FontAwesome.otf");
+}
+
+bool
+MainApplication::applicationSetup()
+{
+#ifdef Q_OS_LINUX
+    if (!getenv("QT_QPA_PLATFORMTHEME"))
+        setenv("QT_QPA_PLATFORMTHEME", "gtk3", true);
+#endif
+
+    // start debug console
+    for (auto string : QCoreApplication::arguments()) {
+        if (string == "-d" || string == "--debug") {
+            consoleDebug();
+        }
+    }
+
+    // remove old version files
+    Utils::removeOldVersions();
+
+    // load translations
+    loadTranslations();
+
+    // set font
+    setApplicationFont();
+
+    // set style sheet
+    setApplicationStyleSheet();
+
+#if defined _MSC_VER && !COMPILE_ONLY
+    gnutls_global_init();
+#endif
+
+    // init pixmap manipulator
+    GlobalInstances::setPixmapManipulator(std::make_unique<PixbufManipulator>());
+
+    // init lrc and its possible migration ui
+    initLrc();
+    // init mainwindow and finish splash when mainwindow shows up
+    // release its source after
+    splash_->finish(&MainWindow::instance());
+
+    // process input argument
+    bool startMinimized{ false };
+    processInputArgument(startMinimized);
+
+    // start possible account migration
+    if (!startAccountMigration())
+        return false;
+
+    // create jami.net settings in Registry if it is not presented
+    QSettings settings("jami.net", "Jami");
+
+    // set mainwindow show size
+    if (not startMinimized) {
+        MainWindow::instance().showWindow();
+    }
+    else {
+        MainWindow::instance().showMinimized();
+        MainWindow::instance().hide();
+    }
+
+    return true;
+}
\ No newline at end of file
diff --git a/src/mainapplication.h b/src/mainapplication.h
new file mode 100644
index 0000000000000000000000000000000000000000..cac70d9a26ded1b5c60c408f2485bf64d6a79128
--- /dev/null
+++ b/src/mainapplication.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2015-2020 by Savoir-faire Linux                           *
+ * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
+ * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>          *
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>              *
+ *                                                                         *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.   *
+ **************************************************************************/
+
+#pragma once
+
+#include "splashscreen.h"
+
+#include <QApplication>
+#include <QFile>
+
+class MainApplication :public QApplication
+{
+    Q_OBJECT
+
+public:
+    explicit MainApplication(int &argc, char** argv);
+
+    bool applicationSetup();
+    void exitApp();
+
+    static void applicationInitialization();
+    static QString getDebugFilePath();
+    static char** parseInputArgument(int& argc, char* argv[], char* argToParse);
+
+protected:
+    void consoleDebug();
+    void vsConsoleDebug();
+    void fileDebug(QFile* debugFile);
+
+private:
+    void loadTranslations();
+    void initLrc();
+    void processInputArgument(bool& startMinimized);
+    void setApplicationStyleSheet();
+    bool startAccountMigration();
+    void setApplicationFont();
+
+    std::unique_ptr<SplashScreen> splash_;
+    std::unique_ptr<QFile> debugFile_;
+};
diff --git a/src/selectareadialog.cpp b/src/selectareadialog.cpp
index 6d0ec87f472579a7c6d133e38b98baba8f471b07..893e2c109998e54a05a48a8164aeb822782f9333 100644
--- a/src/selectareadialog.cpp
+++ b/src/selectareadialog.cpp
@@ -96,7 +96,7 @@ SelectAreaDialog::mouseReleaseEvent(QMouseEvent* event)
     QApplication::restoreOverrideCursor();
     releaseMouse();
     QRect rect = rubberBand_->geometry();
-#if defined(Q_OS_WIN) && !(PROCESS_DPI_AWARE)
+#if defined(Q_OS_WIN)
     if (screen && screen->devicePixelRatio() > 1.0) {
         auto scaledSize = screen->geometry();
         auto sourceHdc = GetDC(nullptr);
diff --git a/src/videoview.cpp b/src/videoview.cpp
index 010b3143b00933b4dc7f28155bbe830c687e01b1..7fc9aece6dbc16daf65999acefd79d399d838f52 100644
--- a/src/videoview.cpp
+++ b/src/videoview.cpp
@@ -225,9 +225,6 @@ VideoView::showContextMenu(const QPoint& position)
             auto screenNumber = qApp->desktop()->screenNumber(this);
             QScreen* screen = qApp->screens().at(screenNumber);
             QRect rect = screen ? screen->geometry() : qApp->primaryScreen()->geometry();
-#if defined(Q_OS_WIN) && (PROCESS_DPI_AWARE)
-            rect.setSize(Utils::getRealSize(screen));
-#endif
             LRCInstance::avModel().setDisplay(screenNumber,
                 rect.x(), rect.y(), rect.width(), rect.height()
             );