|
17 | 17 | #include <qqmlengine.h>
|
18 | 18 | #include <qqmlerror.h>
|
19 | 19 | #include <qqmlincubator.h>
|
| 20 | +#include <qquickwindow.h> |
20 | 21 | #include <qtmetamacros.h>
|
21 | 22 |
|
22 | 23 | #include "iconimageprovider.hpp"
|
@@ -242,90 +243,6 @@ void EngineGeneration::onDirectoryChanged() {
|
242 | 243 | }
|
243 | 244 | }
|
244 | 245 |
|
245 |
| -void EngineGeneration::registerIncubationController(QQmlIncubationController* controller) { |
246 |
| - // We only want controllers that we can swap out if destroyed. |
247 |
| - // This happens if the window owning the active controller dies. |
248 |
| - auto* obj = dynamic_cast<QObject*>(controller); |
249 |
| - if (!obj) { |
250 |
| - qCWarning(logIncubator) << "Could not register incubation controller as it is not a QObject" |
251 |
| - << controller; |
252 |
| - |
253 |
| - return; |
254 |
| - } |
255 |
| - |
256 |
| - QObject::connect( |
257 |
| - obj, |
258 |
| - &QObject::destroyed, |
259 |
| - this, |
260 |
| - &EngineGeneration::incubationControllerDestroyed, |
261 |
| - Qt::UniqueConnection |
262 |
| - ); |
263 |
| - |
264 |
| - this->incubationControllers.push_back(obj); |
265 |
| - qCDebug(logIncubator) << "Registered incubation controller" << obj << "to generation" << this; |
266 |
| - |
267 |
| - // This function can run during destruction. |
268 |
| - if (this->engine == nullptr) return; |
269 |
| - |
270 |
| - if (this->engine->incubationController() == &this->delayedIncubationController) { |
271 |
| - this->assignIncubationController(); |
272 |
| - } |
273 |
| -} |
274 |
| - |
275 |
| -// Multiple controllers may be destroyed at once. Dynamic casts must be performed before working |
276 |
| -// with any controllers. The QQmlIncubationController destructor will already have run by the |
277 |
| -// point QObject::destroyed is called, so we can't cast to that. |
278 |
| -void EngineGeneration::deregisterIncubationController(QQmlIncubationController* controller) { |
279 |
| - auto* obj = dynamic_cast<QObject*>(controller); |
280 |
| - if (!obj) { |
281 |
| - qCCritical(logIncubator) << "Deregistering incubation controller which is not a QObject, " |
282 |
| - "however only QObject controllers should be registered."; |
283 |
| - } |
284 |
| - |
285 |
| - QObject::disconnect(obj, nullptr, this, nullptr); |
286 |
| - |
287 |
| - if (this->incubationControllers.removeOne(obj)) { |
288 |
| - qCDebug(logIncubator) << "Deregistered incubation controller" << obj << "from" << this; |
289 |
| - } else { |
290 |
| - qCCritical(logIncubator) << "Failed to deregister incubation controller" << obj << "from" |
291 |
| - << this << "as it was not registered to begin with"; |
292 |
| - qCCritical(logIncubator) << "Current registered incuabation controllers" |
293 |
| - << this->incubationControllers; |
294 |
| - } |
295 |
| - |
296 |
| - // This function can run during destruction. |
297 |
| - if (this->engine == nullptr) return; |
298 |
| - |
299 |
| - if (this->engine->incubationController() == controller) { |
300 |
| - qCDebug(logIncubator |
301 |
| - ) << "Destroyed incubation controller was currently active, reassigning from pool"; |
302 |
| - this->assignIncubationController(); |
303 |
| - } |
304 |
| -} |
305 |
| - |
306 |
| -void EngineGeneration::incubationControllerDestroyed() { |
307 |
| - auto* sender = this->sender(); |
308 |
| - |
309 |
| - if (this->incubationControllers.removeAll(sender) != 0) { |
310 |
| - qCDebug(logIncubator) << "Destroyed incubation controller" << sender << "deregistered from" |
311 |
| - << this; |
312 |
| - } else { |
313 |
| - qCCritical(logIncubator) << "Destroyed incubation controller" << sender |
314 |
| - << "was not registered, but its destruction was observed by" << this; |
315 |
| - |
316 |
| - return; |
317 |
| - } |
318 |
| - |
319 |
| - // This function can run during destruction. |
320 |
| - if (this->engine == nullptr) return; |
321 |
| - |
322 |
| - if (dynamic_cast<QObject*>(this->engine->incubationController()) == sender) { |
323 |
| - qCDebug(logIncubator |
324 |
| - ) << "Destroyed incubation controller was currently active, reassigning from pool"; |
325 |
| - this->assignIncubationController(); |
326 |
| - } |
327 |
| -} |
328 |
| - |
329 | 246 | void EngineGeneration::onEngineWarnings(const QList<QQmlError>& warnings) {
|
330 | 247 | for (const auto& error: warnings) {
|
331 | 248 | const auto& url = error.url();
|
@@ -367,13 +284,27 @@ void EngineGeneration::exit(int code) {
|
367 | 284 | this->destroy();
|
368 | 285 | }
|
369 | 286 |
|
| 287 | +void EngineGeneration::trackWindowIncubationController(QQuickWindow* window) { |
| 288 | + if (this->trackedWindows.contains(window)) return; |
| 289 | + |
| 290 | + QObject::connect(window, &QObject::destroyed, this, &EngineGeneration::onTrackedWindowDestroyed); |
| 291 | + this->trackedWindows.append(window); |
| 292 | + this->assignIncubationController(); |
| 293 | +} |
| 294 | + |
| 295 | +void EngineGeneration::onTrackedWindowDestroyed(QObject* object) { |
| 296 | + this->trackedWindows.removeAll(static_cast<QQuickWindow*>(object)); // NOLINT |
| 297 | + this->assignIncubationController(); |
| 298 | +} |
| 299 | + |
370 | 300 | void EngineGeneration::assignIncubationController() {
|
371 |
| - QQmlIncubationController* controller = nullptr; |
| 301 | + QQmlIncubationController* controller = &this->delayedIncubationController; |
372 | 302 |
|
373 |
| - if (this->incubationControllersLocked || this->incubationControllers.isEmpty()) { |
374 |
| - controller = &this->delayedIncubationController; |
375 |
| - } else { |
376 |
| - controller = dynamic_cast<QQmlIncubationController*>(this->incubationControllers.first()); |
| 303 | + for (auto* window: this->trackedWindows) { |
| 304 | + if (auto* wctl = window->incubationController()) { |
| 305 | + controller = wctl; |
| 306 | + break; |
| 307 | + } |
377 | 308 | }
|
378 | 309 |
|
379 | 310 | qCDebug(logIncubator) << "Assigning incubation controller" << controller << "to generation"
|
|
0 commit comments