diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e38860a3..fbbeaed8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -34,7 +34,7 @@ jobs:
- name: install monero dependencies
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
- name: install monero gui dependencies
- run: sudo apt -y install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtqml-models2 qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev libgcrypt20-dev xvfb
+ run: sudo apt -y install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtqml-models2 qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-platform qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev libgcrypt20-dev xvfb
- name: build
run: DEV_MODE=ON make release -j3
- name: test qml
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0281142b..2ca52fa1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -299,6 +299,7 @@ list(APPEND QT5_LIBRARIES
if(STATIC)
set(QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/Qt/labs/folderlistmodel)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/Qt/labs/settings)
+ list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/Qt/labs/platform)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtGraphicalEffects)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtGraphicalEffects/private)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtMultimedia)
@@ -324,6 +325,7 @@ if(STATIC)
dialogsprivateplugin
qmlfolderlistmodelplugin
qmlsettingsplugin
+ qtlabsplatformplugin
qmlxmllistmodelplugin
qquicklayoutsplugin
modelsplugin
diff --git a/README.md b/README.md
index adec7826..a772831c 100644
--- a/README.md
+++ b/README.md
@@ -208,7 +208,7 @@ The following instructions will fetch Qt from your distribution's repositories i
- For Ubuntu 17.10+
- `sudo apt install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtqml-models2 qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev`
+ `sudo apt install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtqml-models2 qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-platform qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev`
- For Gentoo
diff --git a/components/MenuBar.qml b/components/MenuBar.qml
new file mode 100644
index 00000000..cd8dcf8b
--- /dev/null
+++ b/components/MenuBar.qml
@@ -0,0 +1,56 @@
+// Copyright (c) 2014-2019, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import Qt.labs.platform 1.0 as PlatformLabs
+import "." as MoneroComponents
+
+PlatformLabs.MenuBar {
+ PlatformLabs.Menu {
+ title: qsTr("File")
+ PlatformLabs.MenuItem {
+ enabled: appWindow.viewState === "normal"
+ text: qsTr("Close Wallet")
+ onTriggered: appWindow.showWizard()
+ }
+ }
+ PlatformLabs.Menu {
+ title: qsTr("View")
+ PlatformLabs.MenuItem {
+ text: MoneroComponents.Style.blackTheme ? qsTr("Light Theme") : qsTr("Dark Theme")
+ onTriggered: {
+ MoneroComponents.Style.blackTheme = !MoneroComponents.Style.blackTheme;
+ persistentSettings.blackTheme = MoneroComponents.Style.blackTheme;
+ }
+ }
+ PlatformLabs.MenuItem {
+ text: qsTr("Change Language")
+ onTriggered: appWindow.toggleLanguageView();
+ }
+ }
+}
+
diff --git a/main.qml b/main.qml
index 8c0603e8..f7c3ae82 100644
--- a/main.qml
+++ b/main.qml
@@ -2360,6 +2360,8 @@ ApplicationWindow {
dragMargin: 0
}
+ MoneroComponents.MenuBar { }
+
Network {
id: network
proxyAddress: persistentSettings.getProxyAddress()
diff --git a/qml.qrc b/qml.qrc
index 4cc451cd..02b1cae2 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -45,6 +45,7 @@
images/prevMonth.png
images/prevMonth@2x.png
components/TitleBar.qml
+ components/MenuBar.qml
images/resize.png
images/resize@2x.png
images/resizeHovered.png
diff --git a/src/main/main.cpp b/src/main/main.cpp
index e3aca5e9..208ede89 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -72,6 +72,9 @@
#include "qt/KeysFiles.h"
#include "qt/MoneroSettings.h"
#include "qt/NetworkAccessBlockingFactory.h"
+#ifdef Q_OS_MAC
+#include "qt/macoshelper.h"
+#endif
// IOS exclusions
#ifndef Q_OS_IOS
@@ -133,6 +136,7 @@ Q_IMPORT_PLUGIN(QtQuickControls1Plugin)
Q_IMPORT_PLUGIN(QtQuick2DialogsPlugin)
Q_IMPORT_PLUGIN(QmlFolderListModelPlugin)
Q_IMPORT_PLUGIN(QmlSettingsPlugin)
+Q_IMPORT_PLUGIN(QtLabsPlatformPlugin)
Q_IMPORT_PLUGIN(QtQuick2DialogsPrivatePlugin)
Q_IMPORT_PLUGIN(QtQuick2PrivateWidgetsPlugin)
Q_IMPORT_PLUGIN(QtQuickControls2Plugin)
@@ -178,6 +182,10 @@ int main(int argc, char *argv[])
if(qgetenv("QMLSCENE_DEVICE") == "softwarecontext")
isOpenGL = false;
+#ifdef Q_OS_MAC
+ // macOS window tabbing is not supported
+ MacOSHelper::disableWindowTabbing();
+#endif
// disable "QApplication: invalid style override passed" warning
if (isDesktop) qputenv("QT_STYLE_OVERRIDE", "fusion");
#ifdef Q_OS_LINUX
diff --git a/src/qt/macoshelper.h b/src/qt/macoshelper.h
index c8e86b05..d3bd27b9 100644
--- a/src/qt/macoshelper.h
+++ b/src/qt/macoshelper.h
@@ -40,6 +40,7 @@ public:
static bool openFolderAndSelectItem(const QUrl &path);
static QPixmap screenshot();
static QString bundlePath();
+ static void disableWindowTabbing();
};
#endif //MACOSHELPER_H
diff --git a/src/qt/macoshelper.mm b/src/qt/macoshelper.mm
index 1d3b812a..35e42a32 100644
--- a/src/qt/macoshelper.mm
+++ b/src/qt/macoshelper.mm
@@ -41,6 +41,14 @@
#include "ScopeGuard.h"
+void MacOSHelper::disableWindowTabbing()
+{
+#ifdef __MAC_10_12
+ if ([NSWindow respondsToSelector:@selector(allowsAutomaticWindowTabbing)])
+ [NSWindow setAllowsAutomaticWindowTabbing: NO];
+#endif
+}
+
bool MacOSHelper::isCapsLock()
{
#ifdef __MAC_10_12