Skip to content

Commit 4f5532d

Browse files
committed
fix(qml): fix platform menu handling and deck-dependent actions
1 parent c24b480 commit 4f5532d

11 files changed

Lines changed: 85 additions & 57 deletions

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4573,6 +4573,9 @@ elseif(UNIX AND NOT APPLE AND NOT EMSCRIPTEN AND NOT ANDROID)
45734573
endif()
45744574
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS DBus REQUIRED)
45754575
target_link_libraries(mixxx-lib PUBLIC Qt${QT_VERSION_MAJOR}::DBus)
4576+
if(QML)
4577+
target_link_libraries(mixxx-qml-lib PRIVATE Qt${QT_VERSION_MAJOR}::DBus)
4578+
endif()
45764579
elseif(WIN32)
45774580
if(Qt_IS_STATIC)
45784581
target_link_libraries(

res/qml/ApplicationMenuCommands.qml

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ Item {
3939
function showKeywheel() {
4040
keywheelDialog.open();
4141
}
42-
4342
FileDialog {
4443
id: trackFileDialog
4544

@@ -64,21 +63,10 @@ Item {
6463
text: qsTr("%1 %2").arg(Mixxx.Application.applicationName).arg(Mixxx.Application.version)
6564
title: qsTr("About %1").arg(Mixxx.Application.applicationName)
6665
}
67-
Dialog {
66+
KeywheelDialog {
6867
id: keywheelDialog
6968

70-
height: Math.min(620, root.applicationWindow.height - 80)
71-
modal: false
72-
standardButtons: Dialog.Close
73-
title: qsTr("Keywheel")
74-
width: height
75-
x: Math.round((root.applicationWindow.width - width) / 2)
76-
y: Math.round((root.applicationWindow.height - height) / 2)
77-
78-
contentItem: Image {
79-
fillMode: Image.PreserveAspectFit
80-
source: "../images/keywheel/keywheel.svg"
81-
}
69+
applicationWindow: root.applicationWindow
8270
}
8371
Mixxx.ControlProxy {
8472
id: deck1PlayControl

res/qml/KeywheelDialog.qml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import QtQuick
2+
import QtQuick.Controls
3+
4+
Dialog {
5+
id: root
6+
7+
required property ApplicationWindow applicationWindow
8+
9+
height: Math.min(620, applicationWindow.height - 80)
10+
modal: false
11+
standardButtons: Dialog.Close
12+
title: qsTr("Keywheel")
13+
width: height
14+
x: Math.round((applicationWindow.width - width) / 2)
15+
y: Math.round((applicationWindow.height - height) / 2)
16+
17+
contentItem: Image {
18+
fillMode: Image.PreserveAspectFit
19+
source: "../images/keywheel/keywheel.svg"
20+
}
21+
}

res/qml/MainMenuBar.qml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ MenuBar {
1515

1616
signal focusLibrarySearchRequested
1717

18-
visible: Qt.platform.os === "osx"
19-
2018
Component.onCompleted: {
2119
if (Mixxx.Application.developerMode) {
2220
developerMenu = developerMenuComponent.createObject(root);
@@ -204,6 +202,7 @@ MenuBar {
204202
Action {
205203
checkable: true
206204
checked: vinylDeck3Control.value > 0
205+
enabled: root.numberOfDecks >= 3
207206
shortcut: Mixxx.Application.menuShortcut("OptionsMenu_EnableVinyl3", "Ctrl+U")
208207
text: qsTr("Enable Vinyl Control 3")
209208

@@ -212,6 +211,7 @@ MenuBar {
212211
Action {
213212
checkable: true
214213
checked: vinylDeck4Control.value > 0
214+
enabled: root.numberOfDecks >= 4
215215
shortcut: Mixxx.Application.menuShortcut("OptionsMenu_EnableVinyl4", "Ctrl+I")
216216
text: qsTr("Enable Vinyl Control 4")
217217

res/qml/main.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ ApplicationWindow {
3434
Loader {
3535
id: nativeApplicationMenuLoader
3636

37-
active: Qt.platform.os === "osx"
37+
active: Qt.platform.os === "osx" || (Mixxx.Application.supportsGlobalMenuBar && root.visibility !== Window.FullScreen)
3838

3939
sourceComponent: Skin.MainMenuBar {
4040
applicationWindow: root

src/mixxxmainwindow.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "track/track.h"
5454
#include "util/debug.h"
5555
#include "util/desktophelper.h"
56+
#include "util/menubarhelper.h"
5657
#include "util/sandbox.h"
5758
#include "util/scopedoverridecursor.h"
5859
#include "util/timer.h"
@@ -69,25 +70,6 @@
6970
#endif
7071

7172
namespace {
72-
#ifdef __LINUX__
73-
// Detect if the desktop supports a global menu to decide whether we need to rebuild
74-
// and reconnect the menu bar when switching to/from fullscreen mode.
75-
// Compared to QMenuBar::isNativeMenuBar() (requires a set menu bar) and
76-
// Qt::AA_DontUseNativeMenuBar, which may both change, this is way more reliable
77-
// since it's rather unlikely that the Appmenu.Registrar service is unloaded/stopped
78-
// while Mixxx is running.
79-
// This is a reimplementation of QGenericUnixTheme > checkDBusGlobalMenuAvailable()
80-
inline bool supportsGlobalMenu() {
81-
#ifndef QT_NO_DBUS
82-
QDBusConnection conn = QDBusConnection::sessionBus();
83-
if (const auto* pIface = conn.interface()) {
84-
return pIface->isServiceRegistered("com.canonical.AppMenu.Registrar");
85-
}
86-
#endif
87-
return false;
88-
}
89-
#endif
90-
9173
const ConfigKey kHideMenuBarConfigKey = ConfigKey("[Config]", "hide_menubar");
9274
const ConfigKey kMenuBarHintConfigKey = ConfigKey("[Config]", "show_menubar_hint");
9375
} // namespace
@@ -105,7 +87,7 @@ MixxxMainWindow::MixxxMainWindow(std::shared_ptr<mixxx::CoreServices> pCoreServi
10587
m_noAuxInputDialog(nullptr),
10688
m_pGuiTick(nullptr),
10789
#ifdef __LINUX__
108-
m_supportsGlobalMenuBar(supportsGlobalMenu()),
90+
m_supportsGlobalMenuBar(mixxx::desktopSupportsGlobalMenuBar()),
10991
#endif
11092
m_inRebootMixxxView(false),
11193
m_pDeveloperToolsDlg(nullptr),

src/qml/qmlapplicationproxy.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "preferences/configobject.h"
66
#include "util/cmdlineargs.h"
77
#include "util/experiment.h"
8+
#include "util/menubarhelper.h"
89
#include "util/versionstore.h"
910

1011
namespace {
@@ -83,6 +84,10 @@ QString QmlApplicationProxy::platform() const {
8384
return VersionStore::platform();
8485
}
8586

87+
bool QmlApplicationProxy::supportsGlobalMenuBar() const {
88+
return desktopSupportsGlobalMenuBar();
89+
}
90+
8691
void QmlApplicationProxy::setExperimentStatsEnabled(bool enabled) {
8792
if (enabled) {
8893
Experiment::setExperiment();

src/qml/qmlapplicationproxy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class QmlApplicationProxy : public QObject {
2727
Q_PROPERTY(QString applicationName READ applicationName CONSTANT)
2828
Q_PROPERTY(QString version READ version CONSTANT)
2929
Q_PROPERTY(QString platform READ platform CONSTANT)
30+
Q_PROPERTY(bool supportsGlobalMenuBar READ supportsGlobalMenuBar CONSTANT)
3031
QML_NAMED_ELEMENT(Application)
3132
QML_SINGLETON
3233

@@ -44,6 +45,7 @@ class QmlApplicationProxy : public QObject {
4445
QString applicationName() const;
4546
QString version() const;
4647
QString platform() const;
48+
bool supportsGlobalMenuBar() const;
4749

4850
Q_INVOKABLE void setExperimentStatsEnabled(bool enabled);
4951
Q_INVOKABLE void setBaseStatsEnabled(bool enabled);

src/qml/qmllibraryproxy.cpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -147,20 +147,18 @@ QmlLibraryScannerProxy::QmlLibraryScannerProxy(LibraryScanner* libraryScanner, Q
147147
});
148148
}
149149

150-
QmlLibraryProxy::QmlLibraryProxy(
151-
std::shared_ptr<Library> pLibrary, QObject* parent)
150+
QmlLibraryProxy::QmlLibraryProxy(QObject* parent)
152151
: QObject(parent),
153-
m_pLibrary(pLibrary),
154152
m_pModelProperty(new QmlLibraryTrackListModel(
155-
QList<QmlLibraryTrackListColumn*>{}, m_pLibrary->trackTableModel(), this)),
153+
QList<QmlLibraryTrackListColumn*>{}, s_pLibrary->trackTableModel(), this)),
156154
m_pScanner(new QmlLibraryScannerProxy(
157-
m_pLibrary->trackCollectionManager()->scanner(), this)) {
155+
s_pLibrary->trackCollectionManager()->scanner(), this)) {
158156
connect(m_pScanner,
159157
&QmlLibraryScannerProxy::stateChanged,
160158
this,
161159
&QmlLibraryProxy::libraryScanActiveChanged);
162160
TrackCollectionManager* pTrackCollectionManager =
163-
m_pLibrary->trackCollectionManager();
161+
s_pLibrary->trackCollectionManager();
164162
VERIFY_OR_DEBUG_ASSERT(pTrackCollectionManager) {
165163
return;
166164
}
@@ -223,16 +221,16 @@ QmlLibraryProxy::QmlLibraryProxy(
223221
emit libraryScanSummaryAvailable(title, text, details.join(QLatin1Char('\n')));
224222
});
225223
#ifdef __ENGINEPRIME__
226-
m_pLibraryExporter = m_pLibrary->makeLibraryExporter(nullptr);
227-
connect(m_pLibrary.get(),
224+
m_pLibraryExporter = s_pLibrary->makeLibraryExporter(nullptr);
225+
connect(s_pLibrary.get(),
228226
&Library::exportLibrary,
229227
m_pLibraryExporter.get(),
230228
&mixxx::LibraryExporter::slotRequestExport);
231-
connect(m_pLibrary.get(),
229+
connect(s_pLibrary.get(),
232230
&Library::exportCrate,
233231
m_pLibraryExporter.get(),
234232
&mixxx::LibraryExporter::slotRequestExportWithInitialCrate);
235-
connect(m_pLibrary.get(),
233+
connect(s_pLibrary.get(),
236234
&Library::exportPlaylist,
237235
m_pLibraryExporter.get(),
238236
&mixxx::LibraryExporter::slotRequestExportWithInitialPlaylist);
@@ -468,7 +466,7 @@ QmlLibraryProxy* QmlLibraryProxy::create(QQmlEngine* pQmlEngine, QJSEngine* pJsE
468466
qWarning() << "Library hasn't been registered yet";
469467
return nullptr;
470468
}
471-
return new QmlLibraryProxy(s_pLibrary, pQmlEngine);
469+
return new QmlLibraryProxy(pQmlEngine);
472470
}
473471

474472
QmlLibraryProxy::AddResult QmlLibraryProxy::addSource(
@@ -529,11 +527,10 @@ QmlLibraryProxy::RelocateResult QmlLibraryProxy::relinkSource(
529527

530528
// Static
531529
qsizetype QmlLibraryProxy::sources_count(QQmlListProperty<QmlLibrarySource>* pList) {
532-
QmlLibraryProxy* pLibrary = static_cast<QmlLibraryProxy*>(pList->object);
533-
VERIFY_OR_DEBUG_ASSERT(pLibrary) {
530+
VERIFY_OR_DEBUG_ASSERT(pList && pList->object && s_pLibrary) {
534531
return 0;
535532
}
536-
return pLibrary->m_pLibrary->trackCollectionManager()
533+
return s_pLibrary->trackCollectionManager()
537534
->internalCollection()
538535
->getRootDirectories()
539536
.size();
@@ -545,12 +542,11 @@ QmlLibrarySource* QmlLibraryProxy::sources_at(
545542
VERIFY_OR_DEBUG_ASSERT(pList && pList->object) {
546543
return nullptr;
547544
}
548-
QmlLibraryProxy* pLibrary = static_cast<QmlLibraryProxy*>(pList->object);
549-
VERIFY_OR_DEBUG_ASSERT(pLibrary) {
545+
VERIFY_OR_DEBUG_ASSERT(s_pLibrary) {
550546
return nullptr;
551547
}
552548
return make_qml_owned<QmlLibrarySource>(
553-
pLibrary->m_pLibrary->trackCollectionManager()
549+
s_pLibrary->trackCollectionManager()
554550
->internalCollection()
555551
->getRootDirectories()
556552
.at(index));

src/qml/qmllibraryproxy.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class QmlLibraryProxy : public QObject {
124124
};
125125
Q_ENUM(SourceRemovalType);
126126

127-
explicit QmlLibraryProxy(std::shared_ptr<Library> pLibrary, QObject* parent = nullptr);
127+
explicit QmlLibraryProxy(QObject* parent = nullptr);
128128
~QmlLibraryProxy() override;
129129

130130
static QmlLibraryProxy* create(QQmlEngine* pQmlEngine, QJSEngine* pJsEngine);
@@ -200,8 +200,6 @@ class QmlLibraryProxy : public QObject {
200200
private:
201201
static inline std::shared_ptr<Library> s_pLibrary;
202202

203-
std::shared_ptr<Library> m_pLibrary;
204-
205203
/// This needs to be a plain pointer because it's used as a `Q_PROPERTY` member variable.
206204
QmlLibraryTrackListModel* m_pModelProperty;
207205
QmlLibraryScannerProxy* m_pScanner;

0 commit comments

Comments
 (0)