1 | // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
2 | // SPDX-FileCopyrightText: 2024 Harald Sitter <sitter@kde.org> |
3 | |
4 | #include "transientmagicianassistant.h" |
5 | |
6 | #include <QQuickItem> |
7 | #include <QQuickWindow> |
8 | |
9 | #include "knewstuffquickprivate_debug.h" |
10 | |
11 | void TransientMagicianAssistant::classBegin() |
12 | { |
13 | } |
14 | |
15 | void TransientMagicianAssistant::componentComplete() |
16 | { |
17 | auto optionalWindow = findWindowParent(); |
18 | if (!optionalWindow) { |
19 | qCWarning(KNEWSTUFFQUICKPRIVATE) << "Unexpectedly have not found a window as parent of TransientMagicianAssistant" ; |
20 | return; |
21 | } |
22 | auto window = optionalWindow.value(); |
23 | |
24 | if (window->transientParent()) { |
25 | return; |
26 | } |
27 | qCWarning(KNEWSTUFFQUICKPRIVATE) |
28 | << "You have not set a transientParent on KNewStuff.Dialog or .Action. This may cause severe problems with window and lifetime management. " |
29 | "We'll try to fix the situation automatically but you should really provide an explicit transientParent" ; |
30 | |
31 | qCDebug(KNEWSTUFFQUICKPRIVATE) << "Applying transient parent magic assistance to " << window << "🪄" ; |
32 | for (auto windowAncestor = qobject_cast<QObject *>(object: window)->parent(); windowAncestor; windowAncestor = windowAncestor->parent()) { |
33 | if (auto item = qobject_cast<QQuickItem *>(o: windowAncestor); item && item->window()) { |
34 | qCDebug(KNEWSTUFFQUICKPRIVATE) << window << "is now transient for" << item->window(); |
35 | connect(sender: item, signal: &QQuickItem::windowChanged, context: window, slot: [window](QQuickWindow *newParent) { |
36 | window->setTransientParent(newParent); |
37 | }); |
38 | window->setTransientParent(item->window()); |
39 | return; |
40 | } |
41 | } |
42 | qCWarning(KNEWSTUFFQUICKPRIVATE) << "Failed to do magic. Found no suitable window to become transient for." ; |
43 | } |
44 | |
45 | std::optional<QQuickWindow *> TransientMagicianAssistant::findWindowParent() |
46 | { |
47 | // Finds the KNewStuff.Dialog though practically it is always parent()->parent() it is a bit tidier to search |
48 | // for it instead. |
49 | for (auto ancestor = parent(); ancestor; ancestor = ancestor->parent()) { |
50 | if (auto window = qobject_cast<QQuickWindow *>(object: ancestor)) { |
51 | return window; |
52 | } |
53 | } |
54 | return {}; |
55 | } |
56 | |
57 | #include "moc_transientmagicianassistant.cpp" |
58 | |