diff --git a/src/platformtheme/config-platformtheme.h.cmake b/src/platformtheme/config-platformtheme.h.cmake index aee7975..f302837 100644 --- a/src/platformtheme/config-platformtheme.h.cmake +++ b/src/platformtheme/config-platformtheme.h.cmake @@ -1,4 +1,5 @@ #cmakedefine01 HAVE_X11 #define BREEZE_STYLE_NAME "${BREEZE_STYLE_NAME}" #define PLATFORM_PLUGIN_THEME_NAME "${PLATFORM_PLUGIN_THEME_NAME}" +#define PLATFORM_PLUGIN_FILE_NAME "${PLUGIN_FILENAME}" diff --git a/src/platformtheme/main_cocoa.cpp b/src/platformtheme/main_cocoa.cpp index 22a625a..ac1ff0e 100644 --- a/src/platformtheme/main_cocoa.cpp +++ b/src/platformtheme/main_cocoa.cpp @@ -1,85 +1,110 @@ /* This file is part of the KDE libraries * Copyright 2013 Kevin Ottens * Copyright 2015 RenĂ© J.V. Bertin * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License or ( at * your option ) version 3 or, at the discretion of KDE e.V. ( which shall * act as a proxy as in section 14 of the GPLv3 ), any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include +#include #include "kdemactheme.h" #include "platformtheme_logging.h" #include // We call ourselves the "cocoa" platform theme plugin. Doing that means we replace // the native platform theme. That is not a problem because the KdeMacTheme class proxies // the native theme. It just means that the native theme inherits a number of KDE // extensions, which are loaded automatically without user intervention like setting // an env. variable. // NB NB // This file should be kept in sync with main_kde.cpp !! // NB NB +static QPluginLoader unloadProtection; + class CocoaPlatformThemePlugin : public QPlatformThemePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformThemeFactoryInterface.5.1" FILE "cocoaplatformtheme.json") public: CocoaPlatformThemePlugin(QObject *parent = Q_NULLPTR) : QPlatformThemePlugin(parent) { if (qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_DISABLED")) { qCWarning(PLATFORMTHEME) << "The Cocoa platform theme plugin has been disabled because of QT_QPA_PLATFORMTHEME_DISABLED"; } if (qEnvironmentVariableIsSet("KDE_LAYOUT_USES_WIDGET_RECT")) { qApp->installEventFilter(this); } } + ~CocoaPlatformThemePlugin() + { + if (qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_VERBOSE")) { + qCWarning(PLATFORMTHEME) << Q_FUNC_INFO; + } + } QPlatformTheme *create(const QString &key, const QStringList ¶mList) override { Q_UNUSED(key) Q_UNUSED(paramList) if (!qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_DISABLED")) { + if (unloadProtection.fileName().isEmpty()) { + unloadProtection.setFileName(QStringLiteral("platformthemes/" PLATFORM_PLUGIN_FILE_NAME)); + if (unloadProtection.fileName().isEmpty()) { + // try with the non-standard extension - probably redundant but I won't + // count on Qt to try the .so extension on Mac forever. + unloadProtection.setFileName(QStringLiteral("platformthemes/" PLATFORM_PLUGIN_FILE_NAME ".so")); + } + // using a global static loader instance should already prevent us from being unloaded + // too early; add an additional layer of protection: + unloadProtection.setLoadHints(QLibrary::PreventUnloadHint); + bool success = unloadProtection.load(); + if (qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_VERBOSE")) { + qCWarning(PLATFORMTHEME) << "loaded from:" + << unloadProtection.fileName() << "unload protection:" << success; + } + } return new KdeMacTheme; } else { return nullptr; } } protected: bool eventFilter(QObject *object, QEvent *event) override { switch (event->type()) { case QEvent::ChildAdded: { QChildEvent *childEvent = static_cast(event); if (childEvent->child()->isWidgetType()) { QWidget* theChildWidget = qobject_cast(childEvent->child()); theChildWidget->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); } } } return qApp->eventFilter(object, event); } }; #include "main_cocoa.moc" diff --git a/src/platformtheme/main_kde.cpp b/src/platformtheme/main_kde.cpp index 9942049..4ff3dcc 100644 --- a/src/platformtheme/main_kde.cpp +++ b/src/platformtheme/main_kde.cpp @@ -1,84 +1,102 @@ /* This file is part of the KDE libraries * Copyright 2013 Kevin Ottens * Copyright 2015 RenĂ© J.V. Bertin * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License or ( at * your option ) version 3 or, at the discretion of KDE e.V. ( which shall * act as a proxy as in section 14 of the GPLv3 ), any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include +#include #include "kdemactheme.h" #include "platformtheme_logging.h" #include // We use a different internal class name for the Mac KDE platform theme plugin, but it will still // identify itself as "KDE" to Qt. This ensures that it will also be picked up when using // the XCB platform plugin (without patching it). // NB NB // This file should be kept in sync with main_kde.cpp !! // NB NB +static QPluginLoader unloadProtection; + class KdePlatformThemePlugin : public QPlatformThemePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformThemeFactoryInterface.5.1" FILE "kdeplatformtheme.json") public: KdePlatformThemePlugin(QObject *parent = Q_NULLPTR) : QPlatformThemePlugin(parent) { if (qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_DISABLED")) { qCWarning(PLATFORMTHEME) << "The KDE platform theme plugin has been disabled because of QT_QPA_PLATFORMTHEME_DISABLED"; return; } if (qEnvironmentVariableIsSet("KDE_LAYOUT_USES_WIDGET_RECT")) { qApp->installEventFilter(this); } } QPlatformTheme *create(const QString &key, const QStringList ¶mList) override { Q_UNUSED(key) Q_UNUSED(paramList) if (!qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_DISABLED")) { + if (unloadProtection.fileName().isEmpty()) { + unloadProtection.setFileName(QStringLiteral("platformthemes/" PLATFORM_PLUGIN_FILE_NAME)); + if (unloadProtection.fileName().isEmpty()) { + // try with the non-standard extension + unloadProtection.setFileName(QStringLiteral("platformthemes/" PLATFORM_PLUGIN_FILE_NAME ".so")); + } + // using a global static loader instance should already prevent us from being unloaded + // too early; add an additional layer of protection: + unloadProtection.setLoadHints(QLibrary::PreventUnloadHint); + bool success = unloadProtection.load(); + if (qEnvironmentVariableIsSet("QT_QPA_PLATFORMTHEME_VERBOSE")) { + qCWarning(PLATFORMTHEME) << "loaded from:" + << unloadProtection.fileName() << "unload protection:" << success; + } + } return new KdeMacTheme; } else { return nullptr; } } protected: bool eventFilter(QObject *object, QEvent *event) { switch (event->type()) { case QEvent::ChildAdded: { QChildEvent *childEvent = static_cast(event); if (childEvent->child()->isWidgetType()) { QWidget* theChildWidget = qobject_cast(childEvent->child()); theChildWidget->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); } } } return qApp->eventFilter(object, event); } }; #include "main_kde.moc"