MuseScore icon indicating copy to clipboard operation
MuseScore copied to clipboard

Update to Qt 6

Open cbjeukendrup opened this issue 3 years ago • 20 comments
trafficstars

It's one unnoticeably small step for a user, but technologically doubtlessly a huge leap forward.

Actually this is a strange experience: I've been working on it so long, and then it finally compiles and runs, and what you see is just MuseScore 4 but with some extra bugs. 😅 But eventually we will need it.

In the first instance, this PR is not meant to be merged soon. It is a bit like a "proof of concept", and to gather feedback on what I have been working over the past months. I'll rebase this PR occasionally to fix conflicts.

Some notes:

  • I tried to split the changes into commits in a way that makes sense. For some changes that are all about the same thing but involve many files, I also created multiple commits, to prevent mistakes. All commits could be reviewed separately.
  • Unfortunately, the differences are so big, that we cannot do this in small steps. At most, a few commits could be "backported" to the master branch.
  • We really need Qt 6.2.2, because anything older has bugs that cause crashes.
  • Merging this PR means saying farewell for good to 32-bit machines and macOS 10.13 and earlier (see https://doc-snapshots.qt.io/qt6-dev/supported-platforms.html)
  • I've only tested it on macOS (Intel and ARM) so far.
  • If you have a Universal binary of LibSndFile, you should be able to build a Universal version of MuseScore, that runs natively on both Intel and Apple Silicon Macs. I haven't been able to try it yet, but I added a CMake option that should do it.
  • We might want to create a arm64 or even better Universal version of the crashpad handler too, but I haven't done that yet.
  • For a long time, I tried to do it without the Qt 5 Compatibility module. But finally, I couldn't resist using this "power-up", because it just covers some things we critically depend on that were removed in Qt 6. Specifically, it is used just for QTextCodec in C++ and GraphicalEffects in QML.
  • I also had to add the State Machines module, which is no longer included by default. It is only used by the ExampleView class, which I expect to be removed at some time, so we can remove the State Machines module when that happens.
  • The biggest problem for which I don't see a solution, is that the XML Patterns module is removed. We depend on it for (Music)XML schema validation. I'm afraid that the only options are either removing the validation, or pulling in another third-party dependency.
  • In XML reading code, we often need to compare QStringViews with string literals. Now, I'm doing that by converting the QStringView to a QString using toString(), and then comparing the QString with the string literal, but I realized/found out later that other ways might be more efficient, such as comparing the QStringView from the Xml reader to another QStringView created from the string literal, or using the QStringLiteral macro. We might revise that later.
  • For the rest, at the C++ side, I believe everything is working without problems.
  • The unit tests are passing.
  • In QML, most things are working. There are a few problems:
    • Big problem: QtQuick.Controls 1 got removed, and Qt 5 Compatibility offers no alternative. We used it for tab bars in the Inspector and for TreeView in the Instruments panel and the Preferences dialog. Of course, for tab bars, QtQuick.Controls 2 has a replacement (albeit significantly different, but OK), but for TreeView, there is nothing. So I have temporarily replaced it with a ListView, which means that we can't expand items. There are various external solutions, such as the one at https://marketplace.qt.io/products/treeview, which is also available under a GPLv3 license, but I'm not sure whether and how we can make use of it.
    • Semi-big problem: QQuickWidget is not available because something changed to how QML is rendered. See https://doc.qt.io/qt-6/quick-changes-qt6.html#changes-to-qquickwidget. Using QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi) as they suggest produces such bad results that it is not a viable option, so we can't mix QtQuick and QWidget in one dialog anymore. So we'd better rewrite the EditStyle Dialog completely...
    • Semi-big problem: SortFilterProxyModel does not work correctly anymore in some cases; setting the source model seems not to trigger the proxy model to do its work. For the note input bar, I rushed in a temporary fix, because it made the app unusable. See the commit message for some details.
    • (I'm doubtlessly forgetting some things that I'll fill in here when I remember again)
    • Small problem: we now use DropShadow from Qt5Compat.GraphicalEffects, but it behaves a bit different. It is clipped at the bounds of its source item. Workaround is to wrap the source item into another Item with some padding, and setting that wrapper item as the source.
    • Small problems: some qml items behave slightly different in some cases. For example, I had to fix some strange binding loops I didn't recognize from Qt 5.
    • No problem: almost surprisingly, the Timeline, which is basically a QWidget inside QML, still works great.
  • I temporarily disabled the CI workflows, because I can't do everything that is needed to update them, and also to save resources and costs when force-pushing, which I expect to be doing often.

Statistics:

  • This is my 200th PR at MuseScore 🥳
  • The number of files changed (originally 573) is certainly the biggest in a PR of mine so far, the number of lines changed probably not.
  • I have apparently deleted more lines than I added, while I had the feeling that the changes mainly complicated the code.

Resolves: #9951 Resolves: https://musescore.org/en/node/323841

cbjeukendrup avatar Dec 15 '21 22:12 cbjeukendrup

This is my 200th PR at MuseScore

Congratulations!!

I think that many changes can be merged separately right now, which do not directly depend on Qt6. For example "Farewell QStringRef", "Replace QScopedPointer with std::unique_ptr" and so on It would be great to make most of these changes in advance, by separately PRs.

igorkorsukov avatar Dec 16 '21 08:12 igorkorsukov

This is my 200th PR at MuseScore

Congratulations!!

I think that many changes can be merged separately right now, which do not directly depend on Qt6. For example "Farewell QStringRef", "Replace QScopedPointer with std::unique_ptr" and so on It would be great to make most of these changes in advance, by separately PRs.

Thanks! With QStringRef specifically, that is a problem, because in Qt 5.15 the QXmlStreamReader just returns QStringRef and not QStringView. And for the rest, there were not that many uses of QStringRef, or they were indirectly related to the Xml Reading code. But indeed there are a few other cases, like the std::unique_ptr example, which can be done separately. I'll be doing that the coming time.

cbjeukendrup avatar Dec 16 '21 09:12 cbjeukendrup

Quite good news: Qt 6.3 alpha is released and contains a brand new TreeView component. That was one of the big missing things at the QML side! I will install this alpha version and try if the new TreeView component can help us.

cbjeukendrup avatar Jan 15 '22 21:01 cbjeukendrup

Ok, I experimented with it for a while. It definitely has much potential to be helpful, so that's a relief. But as soon as we start expanding and collapsing rows as in the Preferences dialog, it goes totally crazy. And dragging rows in the Instruments Panel is even worse. Fortunately, it's still alpha software, so there's hope that it will improve...

cbjeukendrup avatar Jan 15 '22 23:01 cbjeukendrup

Qt 6.3.0 just got released.

Jojo-Schmitz avatar Apr 12 '22 11:04 Jojo-Schmitz

Update: I have now also tried it out on Windows. I made most of the required additional changes, but got stuck at the installing part. The installed version of the application crashes because it says it can't load some QML-related DLLs, but those DLLs are just where they are expected to be. A curious thing is that the not-installed version (in the build folder) does not have this problem (but it has the usual other problems of not-installed builds, so is unusable too).

Does anyone know what you can do if a DLL at a certain path is "not found", while it is just present at that path?

It would be great if someone else could also install Qt 6.3 on Windows or Linux and try to build this PR.

cbjeukendrup avatar Apr 28 '22 14:04 cbjeukendrup

Now that the DLL problems are solved (it turned out that the DLL mentioned in the error message was indeed correctly present, but that some other DLLs were missing, in totally different places), this PR is ready for Windows too! Next step is Linux...

cbjeukendrup avatar Apr 28 '22 17:04 cbjeukendrup

Thought it would be nice to give a quick status update about this. The remaining problems are:

  • [ ] QML: drop shadows are now limited to their bounding box, so they are generally cut off. We'll have to work around that using negative margins and stuff; proof of concept is in DockFloatingWindow.qml.
  • [ ] QML: the new tree view component of Qt 6.3 is buggy:
    • [ ] in Preferences, clicking a row sometimes brings you to the wrong page (the index is not correct after the "General" item collapses/expands) (edit: hm, maybe I've fixed this now, and was it not entirely Qt's fault)
    • [ ] in the Instruments Panel, drag and drop is hopelessly broken, and expanding/collapsing feels not very solid either
  • [ ] QML/CPP: there are problems with updating the properties of SortFilterProxyModel
  • [ ] QML: there are some "binding loops" reported (but they don't seem to cause any visual of functional problems)
  • [ ] QML/QWidgets: still no working QQuickWidget, so a crash occurs when opening some pages in the EditStyle dialog
  • [ ] CPP: we still don't have any alternative to the XML Patterns module for validating MusicXML files against the Schema. I searched a bit on the internet, and it seems that the ideal XML library that supports xsd schema validation does not exist.
  • [ ] Which additional problems are we going to hit on Linux?
  • [ ] CI is still disabled

Meanwhile, dev snapshots of Qt 6.4 are already available, so I'm going to try that out and see if that brings anything new (I don't expect much).

cbjeukendrup avatar May 13 '22 11:05 cbjeukendrup

I just tried building this pr with unity builds disabled on a Linux machine. Fedora 34 with Wayland compositor, using qt 6.2.3. Having qt6 support in MuseScore is important for Wayland, since the current git master with qt5 behaves glitchy.

I had to apply this patch to get it to build (click me)

The patch to src/framework/accessibility/tests/accessibilitycontroller_tests.cpp is incorrect, but my goal here is to get MuseScore building, not the tests.

diff --git a/src/framework/accessibility/CMakeLists.txt b/src/framework/accessibility/CMakeLists.txt
index 1aeb308062..bfb7cab2d6 100644
--- a/src/framework/accessibility/CMakeLists.txt
+++ b/src/framework/accessibility/CMakeLists.txt
@@ -43,7 +43,7 @@ set(MODULE_SRC
 if (OS_IS_LIN)
 # it needed to send a spontaneous event by activating navigation
 set(MODULE_INCLUDE
-    ${Qt5Core_PRIVATE_INCLUDE_DIRS}
+    ${Qt6Core_PRIVATE_INCLUDE_DIRS}
     )
 endif()
 
diff --git a/src/framework/accessibility/tests/accessibilitycontroller_tests.cpp b/src/framework/accessibility/tests/accessibilitycontroller_tests.cpp
index 776ef85997..61865ffc46 100644
--- a/src/framework/accessibility/tests/accessibilitycontroller_tests.cpp
+++ b/src/framework/accessibility/tests/accessibilitycontroller_tests.cpp
@@ -114,14 +114,14 @@ public:
 #ifdef Q_OS_LINUX
     QEvent expectDispatchEventOnFocus()
     {
-        QEvent event(QEvent::None);
+        return QEvent(QEvent::None);
 
         //! For Linux it needs to send spontanous event for canceling reading the name of previous control on accessibility
-        QWindow* window = new QWindow();
-        EXPECT_CALL(*m_mainWindow, qWindow()).WillOnce(Return(window));
-        EXPECT_CALL(*m_application, notify(window, _)).WillOnce(DoAll(SaveArgPointee<1>(&event), Return(true)));
+//        QWindow* window = new QWindow();
+//        EXPECT_CALL(*m_mainWindow, qWindow()).WillOnce(Return(window));
+//        EXPECT_CALL(*m_application, notify(window, _)).WillOnce(DoAll(SaveArgPointee<1>(&event), Return(true)));
 
-        return event;
+//        return event;/
     }
 
     void notExpectDispatchEventOnFocus()
diff --git a/src/framework/uicomponents/view/internal/popupviewclosecontroller.cpp b/src/framework/uicomponents/view/internal/popupviewclosecontroller.cpp
index 4d6683caa3..624300a872 100644
--- a/src/framework/uicomponents/view/internal/popupviewclosecontroller.cpp
+++ b/src/framework/uicomponents/view/internal/popupviewclosecontroller.cpp
@@ -23,6 +23,7 @@
 #include "popupviewclosecontroller.h"
 
 #include <QApplication>
+#include <QWindow>
 
 using namespace mu::uicomponents;
 
diff --git a/src/framework/uicomponents/view/menuview.cpp b/src/framework/uicomponents/view/menuview.cpp
index 789f89390f..5b49b1c136 100644
--- a/src/framework/uicomponents/view/menuview.cpp
+++ b/src/framework/uicomponents/view/menuview.cpp
@@ -22,6 +22,8 @@
 
 #include "menuview.h"
 
+#include "log.h"
+
 using namespace mu::uicomponents;
 
 static const QString MENU_VIEW_CONTENT_OBJECT_NAME("_MenuViewContent");
diff --git a/src/notation/view/loopmarker.cpp b/src/notation/view/loopmarker.cpp
index ae14beb656..cdab436316 100644
--- a/src/notation/view/loopmarker.cpp
+++ b/src/notation/view/loopmarker.cpp
@@ -22,6 +22,7 @@
 
 #include "loopmarker.h"
 #include "draw/pen.h"
+#include "libmscore/scorefont.h"
 
 using namespace mu::notation;
 using namespace mu;
diff --git a/src/project/internal/notationproject.cpp b/src/project/internal/notationproject.cpp
index cfebea6360..f0cd00e240 100644
--- a/src/project/internal/notationproject.cpp
+++ b/src/project/internal/notationproject.cpp
@@ -34,6 +34,7 @@
 #include "engraving/engravingerrors.h"
 #include "engraving/style/defaultstyle.h"
 
+#include "iprojectautosaver.h"
 #include "notation/notationerrors.h"
 #include "projectaudiosettings.h"
 #include "projectfileinfoprovider.h"

The error in src/framework/accessibility/tests/accessibilitycontroller_tests.cpp was:

error: ‘constexpr QEvent::QEvent(const QEvent&)’ is protected within this context

Because I think this test needs more changes to fix this, I just botched the test.

Running mscore fails with the following log to stdout: muse-qt6.log

stacktrace, when the SIGABRT happens:
raise 0x00007ffff4e4f2a2
abort 0x00007ffff4e388a4
__gnu_cxx::__verbose_terminate_handler() [clone .cold] 0x00007ffff51e1a26
__cxxabiv1::__terminate(void (*)()) 0x00007ffff51ed24c
std::terminate() 0x00007ffff51ed2b7
__cxa_pure_virtual 0x00007ffff51edff5
deto::async::Asyncable::disconnectAll asyncable.h:46
deto::async::Asyncable::~Asyncable asyncable.h:20
mu::ipc::IpcSocket::~IpcSocket ipcsocket.cpp:37
mu::ipc::IpcSocket::~IpcSocket ipcsocket.cpp:37
mu::ipc::IpcChannel::~IpcChannel ipcchannel.cpp:44
mu::ipc::IpcChannel::~IpcChannel ipcchannel.cpp:46
mu::mi::MultiInstancesProvider::~MultiInstancesProvider multiinstancesprovider.cpp:55
__gnu_cxx::new_allocator::destroy<…> new_allocator.h:168
std::allocator_traits::destroy<…> alloc_traits.h:535
std::_Sp_counted_ptr_inplace::_M_dispose shared_ptr_base.h:528
std::_Sp_counted_base::_M_release shared_ptr_base.h:168
std::__shared_count::~__shared_count shared_ptr_base.h:705
std::__shared_ptr::~__shared_ptr shared_ptr_base.h:1154
std::shared_ptr::~shared_ptr shared_ptr.h:122
mu::shortcuts::ShortcutsRegister::~ShortcutsRegister shortcutsregister.h:38
__gnu_cxx::new_allocator::destroy<…> new_allocator.h:168
std::allocator_traits::destroy<…> alloc_traits.h:535
std::_Sp_counted_ptr_inplace::_M_dispose shared_ptr_base.h:528
std::_Sp_counted_base::_M_release shared_ptr_base.h:168
std::__shared_count::~__shared_count shared_ptr_base.h:705
std::__shared_ptr::~__shared_ptr shared_ptr_base.h:1154
std::shared_ptr::~shared_ptr shared_ptr.h:122
mu::ui::UiActionsRegister::~UiActionsRegister uiactionsregister.h:35
__gnu_cxx::new_allocator::destroy<…> new_allocator.h:168
std::allocator_traits::destroy<…> alloc_traits.h:535
std::_Sp_counted_ptr_inplace::_M_dispose shared_ptr_base.h:528
std::_Sp_counted_base::_M_release shared_ptr_base.h:168
std::__shared_count::~__shared_count shared_ptr_base.h:705
std::__shared_ptr::~__shared_ptr shared_ptr_base.h:1154
std::shared_ptr::~shared_ptr shared_ptr.h:122
__run_exit_handlers 0x00007ffff4e51af7
exit 0x00007ffff4e51ca0
__libc_start_main 0x00007ffff4e39b7c
_start 0x0000000000456f3e

madebr avatar May 30 '22 14:05 madebr

@madebr Thanks for testing! The fixes from your patch have been applied (some directly here, others via the master branch because they were also relevant there).

About the runtime crash: from the log you attached, it seems that you somehow don't have Qt 6.3 (which contains the TreeView component). Could you try again with the latest Qt version (6.3.1 by now)?

cbjeukendrup avatar Jun 17 '22 16:06 cbjeukendrup

You've done an amazing job to create this and keep it up to date!

What's the latest? Which of the problems you mentioned before are still active? Are there any new ones?

shoogle avatar Apr 03 '23 19:04 shoogle

Unfortunately, all those comments still apply indeed. And actually, with Qt 6.5.0, it got even worse: now there appear to be problems with DockPages where the central widget does not show up. See cf4a711 for the workaround. Also, Qt 6.5 bumps the minimum macOS version from 10.14 to 10.15. Ignoring this is no option, because the trouble starts already at compile time. So that means yet more disappointment... (although, okay, it still runs on almost 10 year old Macs).

cbjeukendrup avatar Apr 03 '23 19:04 cbjeukendrup

Ah, that's a shame!

shoogle avatar Apr 03 '23 22:04 shoogle

Update: after #17285, the Qt 6.5 problems are solved!

cbjeukendrup avatar Apr 19 '23 22:04 cbjeukendrup

Was you been able to compile Musescore with qt6 and MinGW?

zanaviska avatar Jun 03 '23 16:06 zanaviska

As that doesn't work with Qt 5 anymore, it is quite unlikely to work with Qt 6. Although I'd like it to work again... One major hurdle seems to be the new audio stuff

Jojo-Schmitz avatar Jun 03 '23 16:06 Jojo-Schmitz

@cbjeukendrup Hi Great work! Do you still actively work on this? Would you like some help? ( I did fix some quirks on FreeBSD not shared yet namely InstrumentTreeView had invisible text of instrument name (due to too far right alignment) and AppMenu invisible due to a missing height).. Anyways I did a small piece here https://gist.github.com/jsm222/eb1414b651e81a8ea20b20df8bb46556 that might help a lot with using libxml2 without the qt5 wrappers.. https://gist.github.com/jsm222/eb1414b651e81a8ea20b20df8bb46556#file-mscore-patch-L173 and https://gist.github.com/jsm222/eb1414b651e81a8ea20b20df8bb46556#file-mscore-patch-L178 should probably point to the app directory which should contain the schema folder from musicxml 4 https://github.com/w3c/musicxml/releases/tag/v4.0. I tested it briefly successfully. Thanks in advance.

jsm222 avatar Feb 05 '24 23:02 jsm222

@jsm222 Thanks for this! Here's an update about the status of this project:

  • I'm still rebasing this PR regularly, although at the moment some changes to the MusicXML module are going on so I'd rather rebase once after these changes are completed than again and again after every intermediate step
  • I'm not actively working on fixing the remaining few problems.
  • Within the MuseScore team, we are currently looking seriously into moving to Qt 6 for one of the next updates. Because of OS compatibility considerations, we will likely choose Qt 6.2.4 specifically. This means that some things of this PR are not entirely applicable because this PR targets Qt 6.6 at the moment, but most things are.
  • We have yet to decide whether this PR will be merged in its entirety, or that we will make the changes incrementally in smaller PRs. Since the code does not compile or run correctly after any of the individual commits in this PR, we may have no other choice than merging this huge PR all at once. However, things like the switch to libxml2 (or perhaps another library, I don't know this yet) can be done separately in advance, while we are still on Qt 5.15.

@igorkorsukov Please also take note of the previous comment :)

cbjeukendrup avatar Feb 05 '24 23:02 cbjeukendrup

FYI for Qt6 this is needed in the new braille module..

diff --git a/src/braille/braillemodule.cpp b/src/braille/braillemodule.cpp
index bc2e46e218..12738cdb63 100644
--- a/src/braille/braillemodule.cpp
+++ b/src/braille/braillemodule.cpp
@@ -40,6 +40,11 @@ using namespace mu::engraving;
 using namespace mu::notation;
 using namespace mu::project;
 
+static void braille_init_qrc()
+{
+    Q_INIT_RESOURCE(braille);
+}
+
 namespace mu::braille {
 std::string BrailleModule::moduleName() const
 {
@@ -54,6 +59,11 @@ void BrailleModule::resolveImports()
     }
 }
 
+void BrailleModule::registerResources()
+{
+     braille_init_qrc();
+}
+
 void BrailleModule::registerExports()
 {
     m_brailleConfiguration = std::make_shared<BrailleConfiguration>();

diff --git a/src/braille/braillemodule.h b/src/braille/braillemodule.h
index 5f4cd52f2e..3374ac2447 100644
--- a/src/braille/braillemodule.h
+++ b/src/braille/braillemodule.h
@@ -38,6 +38,7 @@ public:
     void resolveImports() override;
     void registerExports() override;
     void registerUiTypes() override;
+    void registerResources() override;
     void onInit(const framework::IApplication::RunMode& mode) override;
 
 private:

jsm222 avatar Feb 11 '24 16:02 jsm222

@jsm222 Thanks, that solves yet another mystery! That code should also be applied to the master branch, @igorkorsukov FYI :)

cbjeukendrup avatar Feb 12 '24 15:02 cbjeukendrup

It's time to say farewell to this PR; mainly because I want to free up the qt6 branch name prefix in my fork :) But also because this PR has served its purpose: the switch to Qt 6 has (almost) been completed, quite successfully! Most commits that are still left here only remove QT5_COMPAT checks, which I will do gradually and systematically in next PRs. Some other commits are small refactorings that can also be done in separate PRs. And then some more commits are about possibly going beyond Qt 6.2.4; those could be moved to a new branch and a perhaps new PR to get attention, hoping we can crowd-source some fixes for the mysteries that Qt 6.5 seems to introduce.

cbjeukendrup avatar May 13 '24 20:05 cbjeukendrup