Skip to content

Add GSoC 2026 final report for LateNight QML - #451

Draft
xARSENICx wants to merge 9 commits into
mixxxdj:websitefrom
xARSENICx:fix-latenight-qml-blog-followups
Draft

xARSENICx wants to merge 9 commits into
mixxxdj:websitefrom
xARSENICx:fix-latenight-qml-blog-followups

Conversation

@xARSENICx

@xARSENICx xARSENICx commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Preview

  • This serves as the report for my GSoC project which needs to be turned in before 21/9/26 23:30 IST.
  • The article is intentionally marked as a draft.
  • Screenshots, the YouTube video, startup-performance section, and publication date still need to be completed before publishing.

@xARSENICx

xARSENICx commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

The blog doesn't touch upon --developer tag yet.
Benchmark results to be added.
Some PRs and features like Track Edit are still WIP, and I aim to get them in the blog before Sunday.

I aim to get PR in a mergeable state by 20/9/26.

@daschuer daschuer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Alread great, thank you.
I have added some comments where it can be improved if you like.


The result is a substantially complete LateNight QML interface with native QML decks, waveform integration and controls, toolbar, mixer, effects rack, samplers, microphone and auxiliary-input racks, menus, responsive deck layouts, and the theme infrastructure needed for Classic and PaleMoon styling.

The short version is that the original goal was not to make a new skin that merely looked like LateNight. It was to make the LateNight workflow available in QML, with the same controls, states, layouts, and visual language wherever the scope allowed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This read as ether an extra challenge or a reduced scope. If tried to improve that here:

Suggested change
The short version is that the original goal was not to make a new skin that merely looked like LateNight. It was to make the LateNight workflow available in QML, with the same controls, states, layouts, and visual language wherever the scope allowed.
The short version is that the original goal was not just to make a new skin that merely looked like LateNight. The aim was also to make the LateNight workflow available in QML, with the same controls, states, layouts, and visual language wherever the scope allowed.


The short version is that the original goal was not to make a new skin that merely looked like LateNight. It was to make the LateNight workflow available in QML, with the same controls, states, layouts, and visual language wherever the scope allowed.

You can also take a look at the video below to see LateNight QML in action.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"also" compared to what?

Suggested change
You can also take a look at the video below to see LateNight QML in action.
You can take a look at the video below to see LateNight QML in action.


## From a bridge to a working skin

The first milestone was deliberately modest. It introduced the QML skin shell and the `QmlLegacyLibraryItem`, a bridge that hosts the existing QWidget-based Library inside the QML scene.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If you have some time left a picture that visualises this archetecture would be nice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't quite understand what you mean by the architecture here. A function invocation mermaid diagram, for example?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe something like a skin mockup with widgets in on color and QML in another, that also shoes this new glue layer. Just an idea.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am unsure about this, as I am currently working on some PRs which are still very high priority. Maybe if I find some time before we merge this, I will see to this.


Larger surfaces also benefited from shared infrastructure. Application-menu and action proxies connect QML menus to Mixxx commands and dialogs. Effects infrastructure provides effect selectors, presets, parameter controls, routing, and tests. Reusable sampler, microphone, auxiliary-input, and ducking components keep rack implementations consistent while allowing the LateNight layout to control their presentation.

Finally, the project added QML-focused validation and CI smoke coverage so the interface can behave like a first-class Mixxx UI rather than a special demo mode.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This sentence to not fit logically. The test and the behaviour are not strictly depending.
Maybe you want to to too sentences?


Validation combined automated checks with manual testing. Theme colors and SVG assets have dedicated validation, the shared effects infrastructure includes tests, and the QML skin has a startup smoke-test path in CI. These checks catch malformed assets, missing QML registrations, and regressions that are easy to overlook when the main focus is visual work.

Manual testing focused on both color schemes, two- and four-deck layouts, different window sizes, high sampler counts, effects routing, library searches, track actions, and switching between the legacy skin and LateNight QML. The remaining issues in the triage list show where broader hardware, platform, display-scale, and accessibility testing is still needed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This paragraph has also a logic flaw. Did you use an actual triage list? Maybe explain this list and the process more closely. (just an idea). ... Or reduce this paragraph ... or ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I meant the LateNight QML triage label. I will reword this section better.


## Pull requests

The following list records the project work as of 17 September 2026. It includes 37 project contributions: 35 merged and 2 still open. An earlier closed bootstrap attempt is intentionally excluded because it was superseded by the merged Library-integration path listed below.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

An earlier closed bootstrap attempt is intentionally excluded because it was superseded by the merged Library-integration path listed below.

???????

Remove, or remove details.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, this leaked from the early draft. Will remove.


### AI-assisted work disclosure

The [scaling follow-up in PR #17020](https://github.com/mixxxdj/mixxx/pull/17020) is the only contribution in this GSoC effort where I used GPT Astra for code generation. It helped prepare a plan, generate small code snippets, and review branch changes; implementation decisions, testing, and validation remained my responsibility.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this can make use of an additional sentences why you device against AI otherwise and if you still consider the decision as good.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure.

The [scaling follow-up in PR #17020](https://github.com/mixxxdj/mixxx/pull/17020) is the only contribution in this GSoC effort where I used GPT Astra for code generation. It helped prepare a plan, generate small code snippets, and review branch changes; implementation decisions, testing, and validation remained my responsibility.

## Testing request

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you want the call for help here at the beginning of the paragraph. No one should miss reading it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right, good idea!

@Eve00000 Eve00000 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you for the write-up.
I made a 1st series of suggestions.
You know how to reach me for help with the video.


The first milestone was deliberately modest. It introduced the QML skin shell and the `QmlLegacyLibraryItem`, a bridge that hosts the existing QWidget-based Library inside the QML scene.

That bridge was important for two reasons. It made the experimental skin usable early in the project, and it let the rest of the interface be ported incrementally instead of waiting for a complete Library rewrite. It also exposed a number of details that are easy to miss when porting a skin: scrollbar and header behavior, sorting, search input, keyboard focus, drag-and-drop, splitters, preview controls, palette changes, and repaint scheduling.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As you want to motivate users to test the skin live, we should change 'experimental' to 'work in progres'.
experimental is a bit 'don't expect too much'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I understand this but I wanted to keep this verbose the skin name which carries (Experimental) as I am unsure if we would be dropping that word yet from the Skin list.

CC @JoergAtGithub

@JoergAtGithub JoergAtGithub Sep 18, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We use the term "Experimental" already for other features, which we exposed to the user in the stable release, where we have only limited feedback from practical usage. This term is e.g. used for options of the multi-soundcard clock syncronisation.
I think we should stay consistent with the wording here.


The first milestone was deliberately modest. It introduced the QML skin shell and the `QmlLegacyLibraryItem`, a bridge that hosts the existing QWidget-based Library inside the QML scene.

That bridge was important for two reasons. It made the experimental skin usable early in the project, and it let the rest of the interface be ported incrementally instead of waiting for a complete Library rewrite. It also exposed a number of details that are easy to miss when porting a skin: scrollbar and header behavior, sorting, search input, keyboard focus, drag-and-drop, splitters, preview controls, palette changes, and repaint scheduling.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

... instead of waiting for a complete Library rewrite.
-> while keeping the library in the QWidget versioin.


That bridge was important for two reasons. It made the experimental skin usable early in the project, and it let the rest of the interface be ported incrementally instead of waiting for a complete Library rewrite. It also exposed a number of details that are easy to miss when porting a skin: scrollbar and header behavior, sorting, search input, keyboard focus, drag-and-drop, splitters, preview controls, palette changes, and repaint scheduling.

The Library, its cover-art and Preview deck components, and the Preferences dialog remain deliberate QWidget transition boundaries in the current scope. The wider QML migration is already underway: native Library and Settings work is progressing, while QML replacements for the Preview deck and cover art remain follow-up work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The Library, its cover-art and Preview deck components, and the Preferences dialog
-> capitals or small letters

-> The library, its cover-art and preview deck components, and the preferences dialog
or
-> The 'library', its 'cover-art' and 'preview deck' components, and the 'preferences dialog'

underway
to?
-> being worked on / work making progression


The Library, its cover-art and Preview deck components, and the Preferences dialog remain deliberate QWidget transition boundaries in the current scope. The wider QML migration is already underway: native Library and Settings work is progressing, while QML replacements for the Preview deck and cover art remain follow-up work.

Once the bridge was stable, the work could proceed from the outside in. Shared controls and behaviors were added to `res/qml`, while the LateNight-specific composition lives in `res/skins/LateNightQML`. This separation makes the project more than a one-off skin port. It also provides a roadmap for future skin ports and independent skin implementations: enthusiasts can build on the shared QML controls, action proxies, effect infrastructure, and input behaviors instead of starting every skin from scratch.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This separation
-> Splitting these...

roadmap
-> building blocks


### Toolbar

The old Settings button was removed from the toolbar. It was a long-standing discoverability issue: a small button acted as the entry point for skin and layout settings, but its purpose was not obvious to new users and its behavior was often discovered only by accident. Users could also confuse it with the application Preferences entry, which was available from the menu bar. The relevant skin and layout settings are now exposed through dropdowns next to the toolbar sections. These dropdowns are implemented as overlays, so they can open above the skin without forcing the rest of the layout to move. This keeps the toolbar compact while making its controls easier to discover.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The old Settings button...
-> settings-button or 'Settings'-button

obvious
-> clear

Users could also confuse it
-> Users might also confuse it.

above
-> over


<!-- TODO: Add a toolbar GIF, video, or screenshot here. -->

On Windows and Linux desktop environments where a global application menu is not used, the traditional menu bar is replaced by a hamburger icon in the toolbar. It provides access to the same application actions through a hierarchical menu while saving vertical space. That gives DJs more room for the decks, mixer, and library without hiding essential application functions. On macOS, the actions continue to use the native system menu bar.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That gives DJs more room for the decks, mixer, and library without hiding essential application functions ...
room -> space
You already wrote that the menu is working as an overlay -> not interfering with place, why does it leave more space now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

why does it leave more space now?

Do you mean this as a suggesiton or a question to me?

For latter, by room/space I exactly mean the physical space we saved in the application window that can be utilised better for Decks, Mixer, Library, etc. (upto a DJ's use case)

@Eve00000 Eve00000 Sep 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No: as it's an overlay -> not interfearing with the layout -> it won't add extra space.
(in legacy uses could hide the menubar)


### Waveform stem and beatgrid control overlays

The waveform reskin places stem and beatgrid controls over the waveform instead of taking space away from it. This is difficult to express cleanly in the old widget layout, but is natural in QML: controls can sit above the waveform without changing the geometry underneath it. The split-stem display and its states are styled as part of the waveform surface rather than as a separate block below it. The implementation restores the backgrounds, markers, gutters, separators, splitters, and filter-menu sizing needed to make the waveform area feel like LateNight while keeping both control sets available without introducing another layout row.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The waveform reskin places stem and beatgrid controls over the waveform.
This was a problem in the legacy layout, while in QML controls can be positioned over other elements without changing their geometry.
The split-stem display and its states are styled as part of the waveform surface now.


### 64 samplers without a separate skin

The old widget-based LateNight workflow used a separate `LateNight (64 Samplers)` skin for a high sampler count. LateNight QML can expose 4, 8, 16, 32, 48, and 64 samplers directly from the same skin without constructing every expanded sampler at once. Rows are reused, expanded content is cached, and warming happens sequentially, keeping the larger rack manageable while preserving the rest of the layout. This is one of the places where QML’s dynamic composition makes a unified skin possible without giving up the practical performance considerations that made a separate skin useful before.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The legacy widget-based LateNight default skin had 16 samplers, a sibling had 64 samplers...

warming ??

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Clarified.


<!-- TODO: Add a 64-sampler GIF, video, or screenshot here. -->

The final result is intentionally recognisable. QML gives us a different implementation and more adaptable layout primitives, but the Classic scheme should still feel like LateNight, and PaleMoon should still feel like the alternate LateNight scheme that existing users know.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Although QML requires a different implementation, it offers more flexible layout building blocks. The classic color scheme is still reminiscent of the old LateNight, and the QML adaptation for PaleMoon ensures that users feel right at home.

@xARSENICx

Copy link
Copy Markdown
Contributor Author

User-Data safeguards section will require more content once a few more PRs get opened in next few days.


## New work in `res/qml`

Beyond the skin itself, the project contributed reusable QML infrastructure to `res/qml`, Mixxx’s common QML layer. Some of these generic pieces were not yet available as reusable components for the New UI, so they were implemented in the shared layer rather than duplicated inside LateNight QML. That gives LateNight QML and future custom skins a common foundation to build on.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Make more clear, that you implemented generic QML infrastructure to Mixxx for features that were not existing before. The term duplicate makes no sense for this first step. Maybe "preventing future duplication" would fit here.

@JoergAtGithub

Copy link
Copy Markdown
Member

Please use the terms "Menu bar", "Main menu" and "Menu" more precise.

  • Main menu can be a bar or a hamburger
  • The menu doesn't consume space, the menu bar does, and the hamburger button consumes a little


For the Library, the project kept the established QWidget implementation behind `QmlLegacyLibraryItem` instead of rewriting collection storage at the same time as the skin. QML menu and deck actions go through Mixxx’s existing Library, player, and `ControlProxy` backends rather than a skin-specific persistence layer. The File menu asks for confirmation before replacing a track on a playing deck, while shared drop handling ignores empty URLs and prevents a deck from being dropped onto itself.

Hotcue labels, colors, types, and clear actions can alter saved track metadata. The QML controls use the existing cue and control APIs, reject missing tracks, cues, or invalid cue positions, close the editor if the loaded track changes, and suppress keyboard mappings while label text is being edited. The clear action is a separate explicit control in the hotcue popup rather than part of ordinary cue triggering. Focused tests cover the new proxy and cue-direction behavior.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use the term "Mixxx Control Objects (CO)" here. You could even link the CO page in the Mixxx manual here.


Beyond the skin itself, the project contributed reusable QML infrastructure to `res/qml`, Mixxx’s common QML layer. Some of these generic pieces were not yet available as reusable components for the New UI, so they were implemented in the shared layer rather than duplicated inside LateNight QML. That gives LateNight QML and future custom skins a common foundation to build on.

Work on the New UI Settings window has extended this migration. Native pages now cover sound hardware, the Library, controllers, and interface settings. Antoine's open [waveform-settings work](https://github.com/mixxxdj/mixxx/pull/15381) fills in the remaining waveform controls. In the New UI, the legacy Interface page is hidden to avoid presenting duplicate or misleading settings that do not apply to the new skin, while the Preferences action remains available through the application menu.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would delete "Native pages now cover sound hardware, the Library, controllers, and interface settings. " as it sound like you changed it in this work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants