Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqc2qnativestyle.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtGui/qguiapplication.h>
8#include <QtGui/qstylehints.h>
9
10#include <QtCore/qapplicationstatic.h>
11#include <QtCore/qloggingcategory.h>
12#include <QtCore/qthread.h>
13
14#if defined(Q_OS_MACOS)
15# include "qquickmacstyle_mac_p.h"
16#elif defined(Q_OS_WINDOWS)
17# include "qquickwindowsxpstyle_p.h"
18#endif
19
20#include <memory>
21
23
24Q_STATIC_LOGGING_CATEGORY(lcNativeStylePlugin, "qt.quick.plugins.nativestyle");
25
26namespace QQC2 {
27
28namespace {
29
30// When we delete QStyle, it will free up its own internal resources. Especially
31// on macOS, this means releasing a lot of NSViews and NSCells from the QMacStyle
32// destructor. If we did this from ~QtQuickControls2NativeStylePlugin, it would
33// happen when the plugin was unloaded from a Q_DESTRUCTOR_FUNCTION in QLibrary,
34// which is very late in the tear-down process, and after qGuiApp has been set to
35// nullptr, NSApplication has stopped running, and perhaps also other static platform
36// variables (e.g in AppKit?) have been deleted. And to our best guess, this is also why
37// we see a crash in AppKit from the destructor in QMacStyle. So for this reason, we
38// delete QStyle from a post routine rather than from the destructor.
39//
40// Furthermore we need to ensure to recreate the QQuickFocusFrame when re-creating the qApplication
41
42struct StyleSingleton
43{
44 StyleSingleton();
45 ~StyleSingleton();
46 QStyle *style() { return m_style.get(); }
47
48private:
49 std::unique_ptr<QStyle> m_style;
50};
51
52Q_APPLICATION_STATIC(StyleSingleton, styleSingleton);
53
54StyleSingleton::StyleSingleton()
55{
56 qCDebug(lcNativeStylePlugin) << "Creating native style";
57
58 // Enable commonstyle as a reference style while
59 // the native styles are under development.
60 if (qEnvironmentVariable("QQC2_COMMONSTYLE") == u"true")
61 m_style = std::make_unique<QCommonStyle>();
62 else if (const QString envStyle = qEnvironmentVariable("QQC2_STYLE"); !envStyle.isNull()) {
63 if (envStyle == u"common")
64 m_style = std::make_unique<QCommonStyle>();
65#if defined(Q_OS_MACOS)
66 else if (envStyle == u"mac")
67 m_style.reset(QMacStyle::create());
68#endif
69#if defined(Q_OS_WINDOWS)
70 else if (envStyle == u"windows")
71 m_style = std::make_unique<QWindowsStyle>();
72 else if (envStyle == u"windowsxp")
73 m_style = std::make_unique<QWindowsXPStyle>();
74#endif
75 }
76
77 if (!m_style) {
78#if defined(Q_OS_MACOS)
79 m_style.reset(QMacStyle::create());
80#elif defined(Q_OS_WINDOWS)
81 m_style = std::make_unique<QWindowsXPStyle>();
82 if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
83 qobject_cast<QWindowsStyle *>(m_style.get())->refreshPalette();
84#endif
85 }
86
87 if (!m_style)
88 m_style = std::make_unique<QCommonStyle>();
89
90 // The native style plugin is neither the current style or fallback style
91 // during QQuickStylePlugin::registerTypes, so it's not given a chance to
92 // initialize or update the theme. But since it's used as an implementation
93 // detail of some of the other style plugins, it might need to know about
94 // theme changes.
95 Q_ASSERT(m_style->thread()->isMainThread());
96 QObject::connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, m_style.get(),
97 [this] {
98 m_style->handleThemeChange();
99 });
100}
101
102StyleSingleton::~StyleSingleton()
103{
104 qCDebug(lcNativeStylePlugin) << "Destroying native style";
105
106 m_style.reset();
107}
108
109}; // namespace
110
112{
113 return styleSingleton()->style();
114}
115
116} // namespace QQC2
117
118QT_END_NAMESPACE
QStyle * style()
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)