Skip to content

Commit 0bd5c09

Browse files
authored
Merge pull request #15826 from adazem009/master
Fix #15473: No platform menu bar support on Linux
2 parents e7071d0 + 47315f0 commit 0bd5c09

22 files changed

+343
-105
lines changed

build/cmake/FindQt5.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ if (WIN32)
4141
)
4242
endif(WIN32)
4343

44+
if (OS_IS_LIN)
45+
set(_components
46+
${_components}
47+
DBus
48+
)
49+
endif()
50+
4451
find_package(Qt5Core ${QT_MIN_VERSION} REQUIRED)
4552

4653
foreach(_component ${_components})

src/appshell/appshell.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<file>qml/platform/win/AppSystemButtons.qml</file>
104104
<file>qml/platform/AppMenuBar.qml</file>
105105
<file>qml/platform/AppButtonBackground.qml</file>
106+
<file>qml/platform/PlatformMenuBar.qml</file>
106107
<file>resources/LoadingScreen.svg</file>
107108
</qresource>
108109
</RCC>

src/appshell/appshellmodule.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,11 @@ void AppShellModule::registerUiTypes()
162162
qmlRegisterType<IOPreferencesModel>("MuseScore.Preferences", 1, 0, "IOPreferencesModel");
163163
qmlRegisterType<CommonAudioApiConfigurationModel>("MuseScore.Preferences", 1, 0, "CommonAudioApiConfigurationModel");
164164

165-
#ifdef Q_OS_MACOS
166-
qmlRegisterType<AppMenuModel>("MuseScore.AppShell", 1, 0, "AppMenuModel");
165+
#if defined(Q_OS_MACOS)
166+
qmlRegisterType<AppMenuModel>("MuseScore.AppShell", 1, 0, "PlatformAppMenuModel");
167+
#elif defined(Q_OS_LINUX)
168+
qmlRegisterType<AppMenuModel>("MuseScore.AppShell", 1, 0, "PlatformAppMenuModel");
169+
qmlRegisterType<NavigableAppMenuModel>("MuseScore.AppShell", 1, 0, "AppMenuModel");
167170
#else
168171
qmlRegisterType<NavigableAppMenuModel>("MuseScore.AppShell", 1, 0, "AppMenuModel");
169172
#endif
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* SPDX-License-Identifier: GPL-3.0-only
3+
* MuseScore-CLA-applies
4+
*
5+
* MuseScore
6+
* Music Composition & Notation
7+
*
8+
* Copyright (C) 2021 MuseScore BVBA 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+
import QtQuick 2.15
23+
import Qt.labs.platform 1.1 as PLATFORM
24+
25+
import MuseScore.AppShell 1.0
26+
27+
Item {
28+
// Loading subitems on Linux causes crashes when adding menus, but it works without it
29+
property bool loadSubitems: true
30+
readonly property bool available: menuModel.isGlobalMenuAvailable()
31+
32+
PLATFORM.MenuBar {
33+
id: menuBar
34+
}
35+
36+
PlatformAppMenuModel {
37+
id: menuModel
38+
}
39+
40+
function load() {
41+
menuModel.load()
42+
43+
var items = menuModel.items
44+
for (var i in items) {
45+
var item = items[i]
46+
var menu = makeMenu(item)
47+
48+
if (loadSubitems) {
49+
for (var j in item.subitems) {
50+
var menuItem = makeMenuItem(menu, item.subitems[j])
51+
menu.addItem(menuItem)
52+
}
53+
}
54+
55+
item.subitemsChanged.connect(function(subitems, menuId) {
56+
for (var l in menuBar.menus) {
57+
var menu = menuBar.menus[l]
58+
if (menu.id === menuId) {
59+
menuBar.menus[l].subitems = subitems
60+
}
61+
}
62+
})
63+
64+
menuBar.addMenu(menu)
65+
}
66+
67+
menuModel.itemsChanged.connect(function() {
68+
for (var i in menuModel.items) {
69+
menuBar.menus[i].subitems = menuModel.items[i].subitems
70+
}
71+
})
72+
}
73+
74+
function makeMenu(menuInfo) {
75+
var menu = menuComponent.createObject(menuBar)
76+
77+
menu.id = menuInfo.id
78+
menu.title = menuInfo.title
79+
menu.enabled = menuInfo.enabled
80+
menu.subitems = menuInfo.subitems
81+
82+
return menu
83+
}
84+
85+
function makeMenuItem(parentMenu, itemInfo) {
86+
var menuItem = menuItemComponent.createObject(parentMenu)
87+
88+
menuItem.id = itemInfo.id
89+
menuItem.text = itemInfo.title + "\t" + itemInfo.portableShortcuts
90+
menuItem.enabled = itemInfo.enabled
91+
menuItem.checked = itemInfo.checked
92+
menuItem.checkable = itemInfo.checkable
93+
menuItem.separator = !Boolean(itemInfo.title)
94+
menuItem.role = itemInfo.role
95+
96+
return menuItem
97+
}
98+
99+
Component {
100+
id: menuComponent
101+
102+
PLATFORM.Menu {
103+
property string id: ""
104+
property var subitems: []
105+
106+
onAboutToShow: {
107+
clear()
108+
109+
for (var i in subitems) {
110+
var item = subitems[i]
111+
var isMenu = Boolean(item.subitems) && item.subitems.length > 0
112+
113+
if (isMenu) {
114+
var subMenu = makeMenu(item)
115+
116+
addMenu(subMenu)
117+
} else {
118+
var menuItem = makeMenuItem(this, item)
119+
120+
addItem(menuItem)
121+
}
122+
}
123+
}
124+
}
125+
}
126+
127+
Component {
128+
id: menuItemComponent
129+
130+
PLATFORM.MenuItem {
131+
property string id: ""
132+
133+
onTriggered: {
134+
Qt.callLater(menuModel.handleMenuItem, id)
135+
}
136+
}
137+
}
138+
}

src/appshell/qml/platform/linux/Main.qml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,28 @@ import "../../"
3030
AppWindow {
3131
id: root
3232

33-
AppMenuBar {
33+
Loader {
3434
id: appMenuBar
3535

3636
anchors.top: parent.top
3737
anchors.left: parent.left
3838
anchors.right: parent.right
39+
}
3940

40-
appWindow: root
41+
Loader {
42+
id: platformMenuBar
4143
}
4244

4345
Component.onCompleted: {
46+
platformMenuBar.setSource("../PlatformMenuBar.qml", { "loadSubitems": false });
47+
if (platformMenuBar.item.available) {
48+
platformMenuBar.item.load();
49+
appMenuBar.active = 0;
50+
} else {
51+
appMenuBar.setSource("../AppMenuBar.qml", { "appWindow": root });
52+
platformMenuBar.active = 0;
53+
}
54+
4455
window.init()
4556
}
4657

src/appshell/qml/platform/mac/Main.qml

Lines changed: 3 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -20,122 +20,24 @@
2020
* along with this program. If not, see <https://www.gnu.org/licenses/>.
2121
*/
2222
import QtQuick 2.15
23-
import Qt.labs.platform 1.1 as PLATFORM
2423

2524
import MuseScore.AppShell 1.0
2625

26+
import "../"
2727
import "../../"
2828

2929
AppWindow {
3030
id: root
3131

32-
PLATFORM.MenuBar {
32+
PlatformMenuBar {
3333
id: menuBar
3434
}
3535

36-
AppMenuModel {
37-
id: menuModel
38-
}
39-
4036
Component.onCompleted: {
41-
menuModel.load()
42-
43-
var items = menuModel.items
44-
for (var i in items) {
45-
var item = items[i]
46-
var menu = makeMenu(item)
47-
48-
for (var j in item.subitems) {
49-
var menuItem = makeMenuItem(menu, item.subitems[j])
50-
menu.addItem(menuItem)
51-
}
52-
53-
item.subitemsChanged.connect(function(subitems, menuId) {
54-
for (var l in menuBar.menus) {
55-
var menu = menuBar.menus[l]
56-
if (menu.id === menuId) {
57-
menuBar.menus[l].subitems = subitems
58-
}
59-
}
60-
})
61-
62-
menuBar.addMenu(menu)
63-
}
64-
65-
menuModel.itemsChanged.connect(function() {
66-
for (var i in menuModel.items) {
67-
menuBar.menus[i].subitems = menuModel.items[i].subitems
68-
}
69-
})
70-
37+
menuBar.load();
7138
window.init()
7239
}
7340

74-
function makeMenu(menuInfo) {
75-
var menu = menuComponent.createObject(menuBar)
76-
77-
menu.id = menuInfo.id
78-
menu.title = menuInfo.title
79-
menu.enabled = menuInfo.enabled
80-
menu.subitems = menuInfo.subitems
81-
82-
return menu
83-
}
84-
85-
function makeMenuItem(parentMenu, itemInfo) {
86-
var menuItem = menuItemComponent.createObject(parentMenu)
87-
88-
menuItem.id = itemInfo.id
89-
menuItem.text = itemInfo.title + "\t" + itemInfo.portableShortcuts
90-
menuItem.enabled = itemInfo.enabled
91-
menuItem.checked = itemInfo.checked
92-
menuItem.checkable = itemInfo.checkable
93-
menuItem.separator = !Boolean(itemInfo.title)
94-
menuItem.role = itemInfo.role
95-
96-
return menuItem
97-
}
98-
99-
Component {
100-
id: menuComponent
101-
102-
PLATFORM.Menu {
103-
property string id: ""
104-
property var subitems: []
105-
106-
onAboutToShow: {
107-
clear()
108-
109-
for (var i in subitems) {
110-
var item = subitems[i]
111-
var isMenu = Boolean(item.subitems) && item.subitems.length > 0
112-
113-
if (isMenu) {
114-
var subMenu = makeMenu(item)
115-
116-
addMenu(subMenu)
117-
} else {
118-
var menuItem = makeMenuItem(this, item)
119-
120-
addItem(menuItem)
121-
}
122-
}
123-
}
124-
}
125-
}
126-
127-
Component {
128-
id: menuItemComponent
129-
130-
PLATFORM.MenuItem {
131-
property string id: ""
132-
133-
onTriggered: {
134-
Qt.callLater(menuModel.handleMenuItem, id)
135-
}
136-
}
137-
}
138-
13941
WindowContent {
14042
id: window
14143

src/appshell/view/appmenumodel.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ void AppMenuModel::load()
7171
appMenuModelHook()->onAppMenuInited();
7272
}
7373

74+
bool AppMenuModel::isGlobalMenuAvailable()
75+
{
76+
return uiConfiguration()->isGlobalMenuAvailable();
77+
}
78+
7479
void AppMenuModel::setupConnections()
7580
{
7681
recentProjectsProvider()->recentProjectListChanged().onNotify(this, [this]() {

src/appshell/view/appmenumodel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "ui/imainwindow.h"
3232
#include "ui/iuiactionsregister.h"
3333
#include "ui/inavigationcontroller.h"
34+
#include "ui/iuiconfiguration.h"
3435
#include "actions/iactionsdispatcher.h"
3536
#include "workspace/iworkspacemanager.h"
3637
#include "iappshellconfiguration.h"
@@ -48,6 +49,7 @@ class AppMenuModel : public uicomponents::AbstractMenuModel
4849
INJECT(appshell, ui::IMainWindow, mainWindow)
4950
INJECT(appshell, ui::IUiActionsRegister, uiActionsRegister)
5051
INJECT(appshell, ui::INavigationController, navigationController)
52+
INJECT(notation, ui::IUiConfiguration, uiConfiguration)
5153
INJECT(appshell, actions::IActionsDispatcher, actionsDispatcher)
5254
INJECT(appshell, workspace::IWorkspaceManager, workspacesManager)
5355
INJECT(appshell, IAppShellConfiguration, configuration)
@@ -61,6 +63,7 @@ class AppMenuModel : public uicomponents::AbstractMenuModel
6163
explicit AppMenuModel(QObject* parent = nullptr);
6264

6365
Q_INVOKABLE void load() override;
66+
Q_INVOKABLE bool isGlobalMenuAvailable();
6467

6568
private:
6669
void setupConnections();

src/framework/ui/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ elseif(OS_IS_WIN)
4444
${CMAKE_CURRENT_LIST_DIR}/internal/platform/windows/windowsplatformtheme.cpp
4545
${CMAKE_CURRENT_LIST_DIR}/internal/platform/windows/windowsplatformtheme.h
4646
)
47+
elseif(OS_IS_LIN)
48+
set(PLATFORM_THEME_SRC
49+
${CMAKE_CURRENT_LIST_DIR}/internal/platform/linux/linuxplatformtheme.cpp
50+
${CMAKE_CURRENT_LIST_DIR}/internal/platform/linux/linuxplatformtheme.h
51+
)
4752
else()
4853
set(PLATFORM_THEME_SRC
4954
${CMAKE_CURRENT_LIST_DIR}/internal/platform/stub/stubplatformtheme.cpp

src/framework/ui/internal/iplatformtheme.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class IPlatformTheme : MODULE_EXPORT_INTERFACE
4545
virtual bool isSystemThemeDark() const = 0;
4646
virtual async::Notification platformThemeChanged() const = 0;
4747

48+
virtual bool isGlobalMenuAvailable() const = 0;
49+
4850
virtual void applyPlatformStyleOnAppForTheme(const ThemeCode& themeCode) = 0;
4951
virtual void applyPlatformStyleOnWindowForTheme(QWindow* window, const ThemeCode& themeCode) = 0;
5052
};

0 commit comments

Comments
 (0)