Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited 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 :
23 : #include "mainwindowbridge.h"
24 :
25 : #include <QWindow>
26 :
27 : #include "modularity/ioc.h"
28 : #include "async/notification.h"
29 :
30 : #include "log.h"
31 :
32 : using namespace muse;
33 : using namespace muse::ui;
34 : using namespace muse::modularity;
35 :
36 0 : MainWindowBridge::MainWindowBridge(QObject* parent)
37 0 : : QObject(parent), Contextable(muse::iocCtxForQmlObject(this)), m_window(nullptr)
38 : {
39 0 : }
40 :
41 0 : MainWindowBridge::~MainWindowBridge()
42 : {
43 0 : mainWindow()->deinit();
44 0 : }
45 :
46 0 : QWindow* MainWindowBridge::qWindow() const
47 : {
48 0 : return m_window;
49 : }
50 :
51 0 : void MainWindowBridge::setWindow(QWindow* window)
52 : {
53 0 : if (m_window != nullptr) {
54 0 : LOGW() << "Window for this MainWindowBridge is already set. Refusing to set it again.";
55 0 : return;
56 : }
57 :
58 0 : if (m_window) {
59 0 : windowsController()->unregWindow(m_window->winId());
60 : }
61 :
62 0 : m_window = window;
63 :
64 0 : emit windowChanged();
65 :
66 0 : init();
67 :
68 0 : if (m_window) {
69 0 : windowsController()->regWindow(m_window->winId());
70 : }
71 : }
72 :
73 0 : void MainWindowBridge::init()
74 : {
75 0 : mainWindow()->init(this);
76 :
77 0 : updateFullScreen();
78 0 : connect(m_window, &QWindow::windowStateChanged, this, [this]() {
79 0 : updateFullScreen();
80 0 : });
81 0 : }
82 :
83 0 : QString MainWindowBridge::filePath() const
84 : {
85 0 : return m_window ? m_window->filePath() : "";
86 : }
87 :
88 0 : void MainWindowBridge::setFilePath(const QString& filePath)
89 : {
90 0 : if (!m_window) {
91 0 : return;
92 : }
93 :
94 0 : if (filePath == m_window->filePath()) {
95 0 : return;
96 : }
97 :
98 0 : m_window->setFilePath(filePath);
99 0 : emit filePathChanged();
100 : }
101 :
102 0 : bool MainWindowBridge::fileModified() const
103 : {
104 0 : return false;
105 : }
106 :
107 0 : void MainWindowBridge::setFileModified(bool /*modified*/)
108 : {
109 0 : }
110 :
111 0 : void MainWindowBridge::showOnBack()
112 : {
113 0 : m_window->lower();
114 0 : }
115 :
116 0 : void MainWindowBridge::showOnFront()
117 : {
118 : #ifdef Q_OS_MAC
119 : // On macOS, this simple way of raising the window works just fine
120 : // (and the other way causes problems, since calling `show()` resizes the window if it was sized to fill the screen)
121 : m_window->setWindowStates(m_window->windowStates() & ~Qt::WindowMinimized);
122 : m_window->raise();
123 : #else
124 : struct Holder {
125 : QMetaObject::Connection conn;
126 : };
127 :
128 0 : Holder* h = new Holder();
129 0 : h->conn = QObject::connect(m_window, &QWindow::activeChanged, [this, h]() {
130 0 : if (m_window->isActive()) {
131 0 : m_window->raise();
132 : }
133 :
134 0 : QObject::disconnect(h->conn);
135 0 : delete h;
136 0 : });
137 0 : m_window->show();
138 0 : m_window->requestActivate();
139 : #endif
140 0 : }
141 :
142 0 : bool MainWindowBridge::isFullScreen() const
143 : {
144 0 : return m_isFullScreen;
145 : }
146 :
147 0 : async::Notification MainWindowBridge::isFullScreenChanged() const
148 : {
149 0 : return m_isFullScreenChanged;
150 : }
151 :
152 0 : void MainWindowBridge::toggleFullScreen()
153 : {
154 0 : if (!m_window) {
155 0 : return;
156 : }
157 :
158 0 : if (isFullScreen()) {
159 0 : m_window->setVisibility(m_windowVisibility);
160 : } else {
161 0 : m_windowVisibility = m_window->visibility();
162 0 : m_window->setVisibility(QWindow::FullScreen);
163 : }
164 : }
165 :
166 0 : void MainWindowBridge::updateFullScreen()
167 : {
168 0 : bool isFullScreen = m_window ? m_window->windowStates().testFlag(Qt::WindowFullScreen) : false;
169 0 : if (isFullScreen == m_isFullScreen) {
170 0 : return;
171 : }
172 :
173 0 : m_isFullScreen = isFullScreen;
174 0 : m_isFullScreenChanged.notify();
175 : }
176 :
177 0 : QScreen* MainWindowBridge::screen() const
178 : {
179 0 : return m_window ? m_window->screen() : nullptr;
180 : }
181 :
182 0 : void MainWindowBridge::showMinimizedWithSavePreviousState()
183 : {
184 : // On Windows, QWindow::showMinimized() doesn't store the previous state of the window.
185 : // Thus, it will always be restored to a windowed state once clicked on from the task bar, even
186 : // if it was maximized before.
187 : // Using setWindowStates, we can remember the previous state and restore it correctly
188 : // when the window is shown again.
189 0 : m_window->setWindowStates(Qt::WindowMinimized | m_window->windowStates());
190 0 : }
|