LCOV - code coverage report
Current view: top level - src/app - main.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 76 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include <csignal>
      24              : 
      25              : #include <QApplication>
      26              : #include <QStyleHints>
      27              : #include <QQuickWindow>
      28              : #include <QSslSocket>
      29              : 
      30              : #include "appfactory.h"
      31              : #include "internal/commandlineparser.h"
      32              : #include "global/iapplication.h"
      33              : 
      34              : #include "muse_framework_config.h"
      35              : #include "app_config.h"
      36              : 
      37              : #include "log.h"
      38              : 
      39              : // C++20 check
      40              : // #include <concepts>
      41              : // #include <type_traits>
      42              : // consteval int square(int n) { return n * n; }
      43              : // static_assert(square(5) == 25);
      44              : // ========================
      45              : 
      46              : #ifndef MUSE_MODULE_DIAGNOSTICS_CRASHPAD_CLIENT
      47            0 : static void crashCallback(int signum)
      48              : {
      49            0 :     const char* signame = "UNKNOWN SIGNAME";
      50            0 :     const char* sigdescript = "";
      51            0 :     switch (signum) {
      52            0 :     case SIGILL:
      53            0 :         signame = "SIGILL";
      54            0 :         sigdescript = "Illegal Instruction";
      55            0 :         break;
      56            0 :     case SIGSEGV:
      57            0 :         signame = "SIGSEGV";
      58            0 :         sigdescript =  "Invalid memory reference";
      59            0 :         break;
      60              :     }
      61            0 :     LOGE() << "Oops! Application crashed with signal: [" << signum << "] " << signame << "-" << sigdescript;
      62            0 :     exit(EXIT_FAILURE);
      63              : }
      64              : 
      65              : #endif
      66              : 
      67            0 : static void app_init_qrc()
      68              : {
      69            0 :     Q_INIT_RESOURCE(app);
      70              : 
      71              : #ifdef Q_OS_WIN
      72              :     Q_INIT_RESOURCE(app_win);
      73              : #endif
      74            0 : }
      75              : 
      76            0 : int main(int argc, char** argv)
      77              : {
      78              : #ifndef MUSE_MODULE_DIAGNOSTICS_CRASHPAD_CLIENT
      79            0 :     signal(SIGSEGV, crashCallback);
      80            0 :     signal(SIGILL, crashCallback);
      81            0 :     signal(SIGFPE, crashCallback);
      82              : #endif
      83              : 
      84              :     // ====================================================
      85              :     // Setup global Qt application variables
      86              :     // ====================================================
      87              : 
      88            0 :     app_init_qrc();
      89              : 
      90            0 :     qputenv("QT_STYLE_OVERRIDE", "Fusion");
      91            0 :     qputenv("QML_DISABLE_DISK_CACHE", "true");
      92              : 
      93              :     // HACK: Workaround for crash #28840. This disables the incremental GC
      94            0 :     if (!qEnvironmentVariableIsSet("MU_QV4_GC_TIMELIMIT")) {
      95            0 :         qputenv("QV4_GC_TIMELIMIT", "0");
      96              :     }
      97              : 
      98            0 :     if (!qEnvironmentVariableIsSet("QT_QUICK_FLICKABLE_WHEEL_DECELERATION")) {
      99            0 :         qputenv("QT_QUICK_FLICKABLE_WHEEL_DECELERATION", "5000");
     100              :     }
     101              : 
     102              : #ifdef Q_OS_LINUX
     103            0 :     if (qEnvironmentVariable("MU_QT_QPA_PLATFORM") != "offscreen") {
     104            0 :         qputenv("QT_QPA_PLATFORMTHEME", "gtk3");
     105              :     }
     106              : 
     107              :     //! NOTE Forced X11, with Wayland there are a number of problems now
     108            0 :     if (qEnvironmentVariable("MU_QT_QPA_PLATFORM") == "") {
     109            0 :         qputenv("QT_QPA_PLATFORM", "xcb");
     110              :     }
     111              : #endif
     112              : 
     113              : #ifdef Q_OS_WIN
     114              :     // NOTE: There are some problems with rendering the application window on some integrated graphics processors
     115              :     //       see https://github.com/musescore/MuseScore/issues/8270
     116              :     if (!qEnvironmentVariableIsSet("QT_OPENGL_BUGLIST")) {
     117              :         qputenv("QT_OPENGL_BUGLIST", ":/resources/win_opengl_buglist.json");
     118              :     }
     119              : #endif
     120              : 
     121            0 :     QGuiApplication::styleHints()->setMousePressAndHoldInterval(250);
     122              : 
     123              : #ifdef MUSE_APP_UNSTABLE
     124            0 :     QCoreApplication::setApplicationName(MUSE_APP_NAME_MACHINE_READABLE MUSE_APP_VERSION_MAJOR "Development");
     125              : #else
     126              :     QCoreApplication::setApplicationName(MUSE_APP_NAME_MACHINE_READABLE MUSE_APP_VERSION_MAJOR);
     127              : #endif
     128            0 :     QCoreApplication::setOrganizationName("MuseScore");
     129            0 :     QCoreApplication::setOrganizationDomain("musescore.org");
     130            0 :     QCoreApplication::setApplicationVersion(MUSE_APP_VERSION);
     131              : 
     132              : #if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) && !defined(Q_OS_WASM)
     133              :     // Any OS that uses Freedesktop.org Desktop Entry Specification (e.g. Linux, BSD)
     134              : #ifndef MUSE_APP_INSTALL_SUFFIX
     135              : #define MUSE_APP_INSTALL_SUFFIX ""
     136              : #endif
     137            0 :     QGuiApplication::setDesktopFileName("org.musescore.MuseScore" MUSE_APP_INSTALL_SUFFIX);
     138              : #endif
     139              : 
     140              :     using namespace muse;
     141              :     using namespace mu::app;
     142              : 
     143            0 :     auto fixSslBackend = []() {
     144              : #ifdef Q_OS_WIN
     145              :         // NOTE: Force schannel backend. Qt prefers OpenSSL when qopensslbackend.dll
     146              :         //       is present, which can crash on ABI mismatch with bundled OpenSSL.
     147              :         //       see https://github.com/musescore/MuseScore/issues/33401
     148              :         QSslSocket::setActiveBackend("schannel");
     149              : #endif
     150            0 :     };
     151              : 
     152              :     // ====================================================
     153              :     // Parse command line options
     154              :     // ====================================================
     155              : #ifdef MUE_ENABLE_CONSOLEAPP
     156            0 :     CommandLineParser commandLineParser;
     157            0 :     commandLineParser.init();
     158            0 :     commandLineParser.parse(argc, argv);
     159              : 
     160            0 :     IApplication::RunMode runMode = commandLineParser.runMode();
     161            0 :     QCoreApplication* qapp = nullptr;
     162              : 
     163            0 :     if (runMode == IApplication::RunMode::AudioPluginRegistration) {
     164            0 :         qapp = new QCoreApplication(argc, argv);
     165              :     } else {
     166            0 :         qapp = new QApplication(argc, argv);
     167              :     }
     168              : 
     169            0 :     fixSslBackend();
     170              : 
     171            0 :     commandLineParser.processBuiltinArgs(*qapp);
     172            0 :     std::shared_ptr<MuseScoreCmdOptions> opt = commandLineParser.options();
     173              : 
     174              : #else
     175              :     QCoreApplication* qapp = new QApplication(argc, argv);
     176              : 
     177              :     fixSslBackend();
     178              : 
     179              :     std::shared_ptr<MuseScoreCmdOptions> opt = std::make_shared<MuseScoreCmdOptions>();
     180              :     opt->runMode = IApplication::RunMode::GuiApp;
     181              : #endif
     182              : 
     183              :     // ====================================================
     184              :     // Setup application
     185              :     // ====================================================
     186              : 
     187              :     //! NOTE: We immediately launch the application's event loop
     188              :     // to be able to show a splash screen (on Linux, splash screen won't show without event loop).
     189              :     // All subsequent initialization steps will be executed as events in the event loop.
     190              : 
     191            0 :     std::shared_ptr<muse::IApplication> app;
     192            0 :     QMetaObject::invokeMethod(qapp, [qapp, &app, &opt]() {
     193              :         AppFactory f;
     194            0 :         app = f.newApp(opt);
     195            0 :         IF_ASSERT_FAILED(app) {
     196            0 :             return;
     197              :         }
     198            0 :         app->showSplash();
     199            0 :         QMetaObject::invokeMethod(qapp, [qapp, &app]() {
     200            0 :             app->setup();
     201            0 :             QMetaObject::invokeMethod(qapp, [&app]() {
     202            0 :                 app->setupNewContext();
     203              : 
     204            0 :                 LOGI() << QString("SSL Info: supported: %1, build: %2, runtime: %3, active backend: %4, available backends: %5")
     205            0 :                     .arg(QSslSocket::supportsSsl())
     206            0 :                     .arg(QSslSocket::sslLibraryBuildVersionString())
     207            0 :                     .arg(QSslSocket::sslLibraryVersionString())
     208            0 :                     .arg(QSslSocket::activeBackend())
     209            0 :                     .arg(QSslSocket::availableBackends().join(", "));
     210            0 :             }, Qt::QueuedConnection);
     211            0 :         }, Qt::QueuedConnection);
     212              :     }, Qt::QueuedConnection);
     213              : 
     214              :     // ====================================================
     215              :     // Run main loop
     216              :     // ====================================================
     217            0 :     int code = qapp->exec();
     218              : 
     219              :     // ====================================================
     220              :     // Quit
     221              :     // ====================================================
     222              : 
     223            0 :     if (app) {
     224            0 :         app->finish();
     225              :     }
     226              : 
     227            0 :     delete qapp;
     228              : 
     229            0 :     LOGI() << "Goodbye!! code: " << code;
     230            0 :     return code;
     231            0 : }
        

Generated by: LCOV version 2.0-1