Skip to content

Conversation

acolombier
Copy link
Member

@acolombier acolombier commented Mar 24, 2025

Depends of #14516

Alternative to #12897 and #4594

Demo

image
Track menu (basic)
image
Column sorting
image
Library feature (Playlist)
image
Library feature (Computer)
image
(Note: resizable column is only supported in Qt 6.5 - might need to implement our own to keep support to Ubuntu 24.04 )

Bonus: file drag visual

Screencast.From.2025-03-24.14-38-13.mp4

@JoergAtGithub
Copy link
Member

JoergAtGithub commented Mar 30, 2025

I tried this. The QML GUI opens, but the track list is empty. If I click on a sidebar element like Computer it crashs:

warning [Main] QQmlExpression: Expression file:///D:/mixxx-2.6-worktree/res/qml/Library.qml:211:13 depends on non-NOTIFYable properties:
warning [Main]     mixxx::qml::QmlLibrarySourceTree::defaultColumns
warning [Main] QQmlExpression: Expression file:///D:/mixxx-2.6-worktree/res/qml/Library.qml:204:13 depends on non-NOTIFYable properties:
warning [Main]     mixxx::qml::QmlLibrarySourceTree::defaultColumns
warning [Main] QQmlExpression: Expression file:///D:/mixxx-2.6-worktree/res/qml/Library.qml:197:13 depends on non-NOTIFYable properties:
warning [Main]     mixxx::qml::QmlLibrarySourceTree::defaultColumns
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:15: TypeError: Cannot read property 'valid' of undefined
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/Sampler.qml:86:9: Unable to assign [undefined] to QString
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/LibraryBrowser.qml:36:17: QML TreeView: modelIndex(row, column) is deprecated. Use index(row, column) instead. For more information, see https://doc.qt.io/qt-6/qml-qtquick-tableview-obsolete.html
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/LibraryBrowser.qml:116:37: QML QQuickImage: Cannot open: file:///D:/mixxx-2.6-worktree/res/qml/images/library_tracks.png
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/LibraryBrowser.qml:36:17: QML TreeView: modelIndex(row, column) is deprecated. Use index(row, column) instead. For more information, see https://doc.qt.io/qt-6/qml-qtquick-tableview-obsolete.html
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/LibraryBrowser.qml:36:17: QML TreeView: modelIndex(row, column) is deprecated. Use index(row, column) instead. For more information, see https://doc.qt.io/qt-6/qml-qtquick-tableview-obsolete.html
warning [Main] file:///D:/mixxx-2.6-worktree/res/qml/LibraryBrowser.qml:36:17: QML TreeView: modelIndex(row, column) is deprecated. Use index(row, column) instead. For more information, see https://doc.qt.io/qt-6/qml-qtquick-tableview-obsolete.html
DEBUG ASSERT: "index.isValid()" in function void __cdecl mixxx::qml::QmlSidebarModelProxy::activate(const class QModelIndex &) at D:\mixxx-2.6-worktree\src\qml\qmlsidebarmodelproxy.cpp:39

@acolombier
Copy link
Member Author

That's strange. Looking at modelIndex(row, column), I assume you are running >Qt 6.5. unfortunately, I believe there was a breaking change in that function according to the doc.

@acolombier
Copy link
Member Author

acolombier commented Apr 1, 2025

I can confirm that breaking change - see this change. Sadly, Ubuntu 24.04 is stuck at 6.4.2, which doesn't include the replacement method. Could you please run with the envvar QT_QUICK_TABLEVIEW_COMPAT_VERSION=6.4? If it doesn't work, this following patch should make it work with > Qt 6.4.2. could you please confirm that too?

diff --git a/res/qml/LibraryBrowser.qml b/res/qml/LibraryBrowser.qml
index a55206034d..7e994b2bce 100644
--- a/res/qml/LibraryBrowser.qml
+++ b/res/qml/LibraryBrowser.qml
@@ -59,7 +59,7 @@ Rectangle {
                         required property int row
                         required property int column
                         required property bool current
-                        readonly property var index: treeView.modelIndex(column, row) // FIXME this seems to become "row,column" in future version of Qt (after 6.4). Update to `index` when upgradeing
+                        readonly property var index: treeView.index(row, column) 
 
                         implicitWidth: treeView.width
                         implicitHeight: depth == 0 ? 42 : 35
@@ -89,13 +89,11 @@ Rectangle {
                                 hoverEnabled: true
                                 acceptedButtons: Qt.LeftButton | Qt.RightButton
                                 onClicked: {
-                                    treeView.selectionModel.select(treeView.selectionModel.model.index(row, 0), ItemSelectionModel.Rows | ItemSelectionModel.Select | ItemSelectionModel.Clear | ItemSelectionModel.Current);
+                                    treeView.selectionModel.setCurrentIndex(index, ItemSelectionModel.NoUpdate)
                                     treeView.model.activate(index)
-                                    console.log(treeView.modelIndex(column, row))
                                     if (isTreeNode && hasChildren) {
                                         treeView.toggleExpanded(row)
                                     }
-                                    event.accepted = true
                                 }
                             }
 

I tried with Qt 6.8 and QT_QUICK_TABLEVIEW_COMPAT_VERSION does the trick, though the selection won’t show on the sidebar (probably another breaking change somewhere that I need to handle)

Also, please note that if you have no playlist or crate, it is expected that the sidebar appears empty, as there is no feedback on this state yet

@acolombier
Copy link
Member Author

I consider this PR mature now. There is missing feature to be added later, such as context menu integration on the sidebar, list action such as playlist or crate creation, but this can be split and added later.

Regarding the breaking changes issue raised by @JoergAtGithub (to be confirmed), I suggest we dynamically set the QT_QUICK_TABLEVIEW_COMPAT_VERSION till we raise the minimal system requirement and drop support for Qt < 6.5

@acolombier acolombier marked this pull request as ready for review April 19, 2025 11:18
@Swiftb0y
Copy link
Member

This is quite a big PR. any chance of splitting it?

@acolombier
Copy link
Member Author

acolombier commented May 19, 2025

I could move out crate and playlist features in a follow up PR? This should reduce the diff by about 500 lines. Would that be sufficient?

@Swiftb0y
Copy link
Member

thats still 2,2k lines. Most of the C++ looks pretty boilerplate-y, so this might be feasible.

@Eve00000
Copy link
Contributor

Eve00000 commented Aug 1, 2025

Test Pt1 : Clean Win 10 x64 VM (4cpus 16Gb , build installed. (1920*1080)

1st impression : looks very nice
1st user experience:

  • sorting is delayed (red bullet is very nice how to see asc/desc?)
  • sidebar is empty
  • no horizontal scrolbar / scrolling?
  • cannot select columns (show/hide)
  • arrow keys not working
  • no resizing of columns (the whole table just moves to left/right)
afbeelding

performance same as in test audioHardware

@acolombier
Copy link
Member Author

Thanks for your feedback @Eve00000 !

sorting is delayed (red bullet is very nice how to see asc/desc?)

Yep, there are currently performance limitation with the model. I'm hoping this can be fixed later, as the model gets cleaned up a little bit more

sidebar is empty

Yes, this gets implemented later, in this PR

cannot select columns (show/hide)
no resizing of columns (the whole table just moves to left/right)

Yep, this will be implemented later. The reason for that is, more recent version of Qt support this built-in so I didn't want to implement it manually now

arrow keys not working

Yep, that also a know "limitation", which is likely due to me not understanding well yet how the focus works on QML! Probably can also be revisited next?

Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some thoughts on qml_owned_ptr since it was brought to my attention again in #14597

@acolombier acolombier requested a review from Swiftb0y September 16, 2025 07:37
@JoergAtGithub
Copy link
Member

I could run the latest commit on Windows 11:

  • Without Scroll-Bars it's barely usable
  • Scrolling through the library let the waveform jump heavily. This looks like the main event loop is blocked. Is the loading of track information done in a seperated thread?

Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't take a thorough look at the qml, but I did notice some stuff in the C++ that needs a little more polish. I'm sorry for dragging this out.

Comment on lines +65 to +69
// This is a workaround to support Qt 6.4.2, currently shipped on
// Ubuntu 24.04 See
// https://github.com/mixxxdj/mixxx/pull/14514#issuecomment-2770811094
// for further details
qputenv("QT_QUICK_TABLEVIEW_COMPAT_VERSION", "6.4");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. Can you raise an issue so we don't forget about this once Qt 6.5 is baseline?


class LibraryTableModel;
class TreeItemModel;
class AllTrackLibraryFeature final : public LibraryFeature {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk, didn't know qt imposed that directory structure limitation on us. no opinion.

@Swiftb0y
Copy link
Member

some of my concerns about ptr casts where bogus, I deleted them.

@acolombier
Copy link
Member Author

Thanks for the feedback @JoergAtGithub !

Without Scroll-Bars it's barely usable

Noted, I have added vertical scrollbar. I will add the horizontal later, once I have made the update to Qt 6.8 as there was quite some changes around TableView and I suspect I will need to refactor all the column sizing/horizontal sizing policy.

Scrolling through the library let the waveform jump heavily. This looks like the main event loop is blocked. Is the loading of track information done in a seperated thread?

No, it's all currently done on the UI thread!
This is part of the performance improvement I mentioned in our catchup that would be needed before considering this done! The reason for not introducing a side thread yet is that the current library model is quite messy and can probably be simplified (also likely to happen after the 6.8 upgrade!) so I didn't want to add complexity it just yet

Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, no complaints. Basically LGTM from my side

Comment on lines +28 to +35
tableView.selectionModel.selectRow(row);
tableView.loadSelectedTrackIntoNextAvailableDeck(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this works for now, though in the future it would be nice if this didn't have to go through the implicit state of the tableView.

Comment on lines +64 to +71
// FIXME: WaveformOverview is currently disabled due to performance limitation. Like for the legacy UI, a cache likely needs to be implemented to help
// Mixxx.TrackListColumn {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this FIXME still apply? Does the overview have perf issues?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does, it basically suffers for the same impacting covers, which @JoergAtGithub raised - the fact that the data model is fully operating in the QML thread is creating slow down, but due the fairly hacky state of the model, I don't feel comfortable adding thread yet, and would prefer starting up clean, as I do the 6.8 or 6.9 migration in the near future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, this is also an issue in the legacy GUI then, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the legacy library is already leveraging a worker thread - at least I have not noticed any significant performance issue!

@JoergAtGithub
Copy link
Member

In general this works on Windows. Im fine with merging this as it is, as first step.

@acolombier acolombier force-pushed the feat/qml-library branch 2 times, most recently from 1490e8b to 67f4125 Compare September 18, 2025 23:19
@acolombier
Copy link
Member Author

Squashed the fixups! Lets get this in for now, and iterate on the async waveform overview/cover, tracked into #15376

@Swiftb0y
Copy link
Member

Swiftb0y commented Sep 19, 2025

Just checked this out, works surprisingly well on the surface. Good job. Only surprising thing was that the text in the header doesn't seem to be clipped/stacked quite right. Idk if this is our bug or Qt.

Screencast.From.2025-09-19.13-48-41.mp4

Also got a bunch of qml warnings related to SourceTree.qml. It would be nice if you could look into some of those.

warning [Main] QQmlExpression: Expression file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/SourceTree.qml:186:9 depends on non-bindable properties:
warning [Main] SourceTree_QMLTYPE_151::defaultColumns

warning [Main] file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/Browser.qml:121:37: QML QQuickImage: Cannot open: file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/images/library_tracks.png

warning [Main] : Error: Cannot find the marker endIcon "/home/swiftb0y/Sourcerepositories/mixxx/res/qml/images/jump_%1.svg"

warning [Main] file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/SourceTree.qml:38:13: Unable to assign [undefined] to QString

Got this one spammed 30 times in a row.

warning [Main] Ignoring sourceSize request for image url that came from grabToImage. Use the targetSize parameter of the grabToImage() function instead.

warning [Main] file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/SourceTree.qml:132:23: QML DefaultDelegate (parent or ancestor of QQuickDragAttached): Don't know how to encode variant of type QMetaType(QUrl) as mime type "text/plain"
warning [Main] file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/SourceTree.qml:132:23: QML DefaultDelegate (parent or ancestor of QQuickDragAttached): Don't know how to encode variant of type QMetaType(QUrl) as mime type "text/uri-list"
warning [Main] file:///home/swiftb0y/Sourcerepositories/mixxx/res/qml/Library/SourceTree.qml:132:23: QML DefaultDelegate (parent or ancestor of QQuickDragAttached): Binding loop detected for property "active":

@acolombier
Copy link
Member Author

Thanks for your test! I should have fixed all those warning hopefully as well as the clipping issue. Only one remaining is:

warning [Main] : Error: Cannot find the marker endIcon "/home/swiftb0y/Sourcerepositories/mixxx/res/qml/images/jump_%1.svg"

This was introduced by the Saved Jump feature - this comes to the fact that we later on brought capability to have the jump icon to have a backward and forward version, but the QML interface has this now redundant early checks I need to remove

Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I can confirm the warnings I complained about are gone (there are still some, but they're unrelated to this PR)

@JoergAtGithub JoergAtGithub merged commit da6db1e into mixxxdj:main Sep 19, 2025
14 checks passed
@github-project-automation github-project-automation bot moved this from In progress to Done in QML GUI Sep 19, 2025
@github-project-automation github-project-automation bot moved this from In progress to Done in Releases Sep 19, 2025
@JoergAtGithub
Copy link
Member

This API might be interesting for the future: https://www.qt.io/blog/model-to-sort-and-filter-the-data-on-the-fly

@acolombier
Copy link
Member Author

Oh great ! I know there was improvement already on 6.5, but I could wait for 6.10 to add that, though this probably means we might struggle to support native Ubuntu 26.04 (not sure if they would stick to 6.8 LTS)
I don't think it's a deal breaker tho, we could discuss rolling out 3.0 on flatpak only (I know there were discussions on Zulip) and let distro maintainers have to deal with old deps.
Perhaps worth creating an issue to discuss that topic?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants