Refactor theme plugin loading.
In the old implementation, the QPlatformIntegration was asked for the theme first, so there was no way of overriding that by a custom plugin. Also, there was a memory leak in case the platform theme was actually created by a plugin. QGuiApplication now asks the QPlatformIntegration for a list of potential theme names first, tries to load them using the plugin loader and finally invokes a factory method of QPlatformIntegration in case that fails. The theme is now owned by QGuiApplication. In the XCB plugin, the environment variable DESKTOP_SESSION is queried and appended to the list of themes, making it possible to load plugins for other session types. Change-Id: I1a4b4e061815bca16c65b23e591bb7563a3e44e2 Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
parent
d295b9b9cf
commit
f7957f3993
@ -538,13 +538,22 @@ static void init_platform(const QString &pluginArgument, const QString &platform
|
||||
}
|
||||
|
||||
// Create the platform theme:
|
||||
// 1) Ask the platform integration to create a platform theme
|
||||
QGuiApplicationPrivate::platform_theme = QGuiApplicationPrivate::platform_integration->platformTheme();
|
||||
// 1) Ask the platform integration for a list of names.
|
||||
const QStringList themeNames = QGuiApplicationPrivate::platform_integration->themeNames();
|
||||
foreach (const QString &themeName, themeNames) {
|
||||
QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath);
|
||||
if (QGuiApplicationPrivate::platform_theme)
|
||||
break;
|
||||
}
|
||||
|
||||
// 2) If none found, look for a theme plugin. Theme plugins are located in the
|
||||
// same directory as platform plugins.
|
||||
if (!QGuiApplicationPrivate::platform_theme) {
|
||||
QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(name, platformPluginPath);
|
||||
foreach (const QString &themeName, themeNames) {
|
||||
QGuiApplicationPrivate::platform_theme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName);
|
||||
if (QGuiApplicationPrivate::platform_theme)
|
||||
break;
|
||||
}
|
||||
// No error message; not having a theme plugin is allowed.
|
||||
}
|
||||
|
||||
@ -748,6 +757,7 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
|
||||
|
||||
qt_cleanupFontDatabase();
|
||||
|
||||
delete platform_theme;
|
||||
delete platform_integration;
|
||||
platform_integration = 0;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <QtGui/QPlatformFontDatabase>
|
||||
#include <QtGui/QPlatformClipboard>
|
||||
#include <QtGui/QPlatformAccessibility>
|
||||
#include <QtGui/QPlatformTheme>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtGui/private/qpixmap_raster_p.h>
|
||||
#include <QtGui/private/qplatformscreen_qpa_p.h>
|
||||
@ -315,9 +316,15 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps)
|
||||
emit qGuiApp->screenAdded(screen);
|
||||
}
|
||||
|
||||
class QPlatformTheme *QPlatformIntegration::platformTheme() const
|
||||
QStringList QPlatformIntegration::themeNames() const
|
||||
{
|
||||
return 0;
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
class QPlatformTheme *QPlatformIntegration::createPlatformTheme(const QString &name) const
|
||||
{
|
||||
Q_UNUSED(name)
|
||||
return new QPlatformTheme;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -126,7 +126,8 @@ public:
|
||||
|
||||
virtual Qt::KeyboardModifiers queryKeyboardModifiers() const;
|
||||
|
||||
virtual QPlatformTheme *platformTheme() const;
|
||||
virtual QStringList themeNames() const;
|
||||
virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
||||
protected:
|
||||
void screenAdded(QPlatformScreen *screen);
|
||||
|
@ -77,6 +77,8 @@ void ResourceHelper::clear()
|
||||
\ingroup qpa
|
||||
*/
|
||||
|
||||
const char *QGenericUnixTheme::name = "generic";
|
||||
|
||||
// Helper to return the icon theme paths from XDG.
|
||||
QStringList QGenericUnixTheme::xdgIconThemePaths()
|
||||
{
|
||||
@ -159,6 +161,8 @@ static inline bool readKdeSystemPalette(const QSettings &kdeSettings, QPalette *
|
||||
\ingroup qpa
|
||||
*/
|
||||
|
||||
const char *QKdeTheme::name = "kde";
|
||||
|
||||
QKdeTheme::QKdeTheme(const QString &kdeHome, int kdeVersion) :
|
||||
m_kdeHome(kdeHome), m_kdeVersion(kdeVersion),
|
||||
m_toolButtonStyle(Qt::ToolButtonTextBesideIcon), m_toolBarIconSize(0)
|
||||
@ -329,6 +333,8 @@ QPlatformTheme *QKdeTheme::createKdeTheme()
|
||||
\ingroup qpa
|
||||
*/
|
||||
|
||||
const char *QGnomeTheme::name = "gnome";
|
||||
|
||||
QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
|
||||
{
|
||||
switch (hint) {
|
||||
@ -358,23 +364,38 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
|
||||
\brief Creates a UNIX theme according to the detected desktop environment.
|
||||
*/
|
||||
|
||||
QPlatformTheme *QGenericUnixTheme::createUnixTheme()
|
||||
QPlatformTheme *QGenericUnixTheme::createUnixTheme(const QString &name)
|
||||
{
|
||||
QPlatformTheme *result = 0;
|
||||
if (name == QLatin1String(QGenericUnixTheme::name))
|
||||
return new QGenericUnixTheme;
|
||||
if (name == QLatin1String(QKdeTheme::name))
|
||||
if (QPlatformTheme *kdeTheme = QKdeTheme::createKdeTheme())
|
||||
return kdeTheme;
|
||||
if (name == QLatin1String(QGnomeTheme::name))
|
||||
return new QGnomeTheme;
|
||||
return new QGenericUnixTheme;
|
||||
}
|
||||
|
||||
QStringList QGenericUnixTheme::themeNames()
|
||||
{
|
||||
QStringList result;
|
||||
if (QGuiApplication::desktopSettingsAware()) {
|
||||
switch (QGenericUnixServices::desktopEnvironment()) {
|
||||
case QGenericUnixServices::DE_UNKNOWN:
|
||||
break;
|
||||
case QGenericUnixServices::DE_KDE:
|
||||
result = QKdeTheme::createKdeTheme();
|
||||
result.push_back(QLatin1String(QKdeTheme::name));
|
||||
break;
|
||||
case QGenericUnixServices::DE_GNOME:
|
||||
result = new QGnomeTheme;
|
||||
result.push_back(QLatin1String(QGnomeTheme::name));
|
||||
break;
|
||||
case QGenericUnixServices::DE_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
result = new QGenericUnixTheme;
|
||||
const QByteArray session = qgetenv("DESKTOP_SESSION");
|
||||
if (!session.isEmpty() && session != "default")
|
||||
result.push_back(QString::fromLocal8Bit(session));
|
||||
} // desktopSettingsAware
|
||||
if (result.isEmpty())
|
||||
result.push_back(QLatin1String(QGenericUnixTheme::name));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -67,11 +67,14 @@ class QGenericUnixTheme : public QPlatformTheme
|
||||
public:
|
||||
QGenericUnixTheme() {}
|
||||
|
||||
static QPlatformTheme *createUnixTheme();
|
||||
static QPlatformTheme *createUnixTheme(const QString &name);
|
||||
static QStringList themeNames();
|
||||
|
||||
virtual QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
static QStringList xdgIconThemePaths();
|
||||
|
||||
static const char *name;
|
||||
};
|
||||
|
||||
class QKdeTheme : public QPlatformTheme
|
||||
@ -88,6 +91,8 @@ public:
|
||||
virtual const QFont *font(Font type) const
|
||||
{ return m_resources.fonts[type]; }
|
||||
|
||||
static const char *name;
|
||||
|
||||
private:
|
||||
QString globalSettingsFile() const;
|
||||
void refresh();
|
||||
@ -109,6 +114,8 @@ public:
|
||||
QGnomeTheme() {}
|
||||
virtual QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
static const char *name;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
@ -93,7 +93,9 @@ public:
|
||||
QPlatformAccessibility *accessibility() const;
|
||||
QPlatformDrag *drag() const;
|
||||
|
||||
QPlatformTheme *platformTheme() const;
|
||||
QStringList themeNames() const;
|
||||
QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
||||
private:
|
||||
|
||||
QScopedPointer<QPlatformFontDatabase> mFontDb;
|
||||
|
@ -93,7 +93,6 @@ QCocoaIntegration::QCocoaIntegration()
|
||||
, mEventDispatcher(new QCocoaEventDispatcher())
|
||||
, mInputContext(new QCocoaInputContext)
|
||||
, mAccessibility(new QPlatformAccessibility)
|
||||
, mPlatformTheme(new QCocoaTheme)
|
||||
, mCocoaDrag(new QCocoaDrag)
|
||||
{
|
||||
QCocoaAutoReleasePool pool;
|
||||
@ -212,9 +211,16 @@ QPlatformDrag *QCocoaIntegration::drag() const
|
||||
return mCocoaDrag.data();
|
||||
}
|
||||
|
||||
QPlatformTheme *QCocoaIntegration::platformTheme() const
|
||||
QStringList QCocoaIntegration::themeNames() const
|
||||
{
|
||||
return mPlatformTheme.data();
|
||||
return QStringList(QLatin1String(QCocoaTheme::name));
|
||||
}
|
||||
|
||||
QPlatformTheme *QCocoaIntegration::createPlatformTheme(const QString &name) const
|
||||
{
|
||||
if (name == QLatin1String(QCocoaTheme::name))
|
||||
return new QCocoaTheme;
|
||||
return QPlatformIntegration::createPlatformTheme(name);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -64,6 +64,9 @@ public:
|
||||
const QFont *font(Font type = SystemFont) const;
|
||||
|
||||
QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
static const char *name;
|
||||
|
||||
private:
|
||||
mutable QPalette *m_systemPalette;
|
||||
mutable QHash<QPlatformTheme::Palette, QPalette*> m_palettes;
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
const char *QCocoaTheme::name = "cocoa";
|
||||
|
||||
QCocoaTheme::QCocoaTheme()
|
||||
:m_systemPalette(0)
|
||||
{
|
||||
|
@ -788,7 +788,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
|
||||
QWindowSystemInterface::handleCloseEvent(platformWindow->window());
|
||||
return true;
|
||||
case QtWindows::ThemeChanged: // ### fixme: Compress these events?
|
||||
QWindowsTheme::instance()->windowsThemeChanged(platformWindow->window());
|
||||
if (QWindowsTheme *theme = QWindowsTheme::instance())
|
||||
theme->windowsThemeChanged(platformWindow->window());
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
@ -183,7 +183,6 @@ struct QWindowsIntegrationPrivate
|
||||
QOpenGLStaticContextPtr m_staticOpenGLContext;
|
||||
QWindowsInputContext m_inputContext;
|
||||
QWindowsAccessibility m_accessibility;
|
||||
QWindowsTheme m_theme;
|
||||
QWindowsServices m_services;
|
||||
};
|
||||
|
||||
@ -362,9 +361,16 @@ QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
|
||||
return d->m_eventDispatcher;
|
||||
}
|
||||
|
||||
QPlatformTheme *QWindowsIntegration::platformTheme() const
|
||||
QStringList QWindowsIntegration::themeNames() const
|
||||
{
|
||||
return &d->m_theme;
|
||||
return QStringList(QLatin1String(QWindowsTheme::name));
|
||||
}
|
||||
|
||||
QPlatformTheme *QWindowsIntegration::createPlatformTheme(const QString &name) const
|
||||
{
|
||||
if (name == QLatin1String(QWindowsTheme::name))
|
||||
return new QWindowsTheme;
|
||||
return QPlatformIntegration::createPlatformTheme(name);
|
||||
}
|
||||
|
||||
QPlatformServices *QWindowsIntegration::services() const
|
||||
|
@ -69,7 +69,8 @@ public:
|
||||
virtual QPlatformAccessibility *accessibility() const;
|
||||
virtual QPlatformNativeInterface *nativeInterface() const;
|
||||
virtual QPlatformFontDatabase *fontDatabase() const;
|
||||
virtual QPlatformTheme *platformTheme() const;
|
||||
virtual QStringList themeNames() const;
|
||||
virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
QPlatformServices *services() const;
|
||||
virtual QVariant styleHint(StyleHint hint) const;
|
||||
|
||||
|
@ -229,8 +229,12 @@ static inline QPalette *menuBarPalette(const QPalette &menuPalette)
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *QWindowsTheme::name = "windows";
|
||||
QWindowsTheme *QWindowsTheme::m_instance = 0;
|
||||
|
||||
QWindowsTheme::QWindowsTheme()
|
||||
{
|
||||
m_instance = this;
|
||||
qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
|
||||
qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
|
||||
refresh();
|
||||
@ -240,11 +244,7 @@ QWindowsTheme::~QWindowsTheme()
|
||||
{
|
||||
clearPalettes();
|
||||
clearFonts();
|
||||
}
|
||||
|
||||
QWindowsTheme *QWindowsTheme::instance()
|
||||
{
|
||||
return static_cast<QWindowsTheme *>(QWindowsIntegration::instance()->platformTheme());
|
||||
m_instance = 0;
|
||||
}
|
||||
|
||||
static inline QStringList iconThemeSearchPaths()
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
QWindowsTheme();
|
||||
~QWindowsTheme();
|
||||
|
||||
static QWindowsTheme *instance();
|
||||
static QWindowsTheme *instance() { return m_instance; }
|
||||
|
||||
virtual bool usePlatformNativeDialog(DialogType type) const;
|
||||
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
|
||||
@ -69,6 +69,8 @@ public:
|
||||
|
||||
void windowsThemeChanged(QWindow *window);
|
||||
|
||||
static const char *name;
|
||||
|
||||
private:
|
||||
void refresh() { refreshPalettes(); refreshFonts(); }
|
||||
void clearPalettes();
|
||||
@ -76,6 +78,7 @@ private:
|
||||
void clearFonts();
|
||||
void refreshFonts();
|
||||
|
||||
static QWindowsTheme *m_instance;
|
||||
QPalette *m_palettes[NPalettes];
|
||||
QFont *m_fonts[NFonts];
|
||||
};
|
||||
|
@ -88,8 +88,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QXcbIntegration::QXcbIntegration(const QStringList ¶meters)
|
||||
: m_eventDispatcher(createUnixEventDispatcher()),
|
||||
m_services(new QGenericUnixServices),
|
||||
m_theme(QGenericUnixTheme::createUnixTheme())
|
||||
m_services(new QGenericUnixServices)
|
||||
{
|
||||
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
|
||||
|
||||
@ -277,9 +276,14 @@ QPlatformServices *QXcbIntegration::services() const
|
||||
return m_services.data();
|
||||
}
|
||||
|
||||
QPlatformTheme *QXcbIntegration::platformTheme() const
|
||||
QStringList QXcbIntegration::themeNames() const
|
||||
{
|
||||
return m_theme.data();
|
||||
return QGenericUnixTheme::themeNames();
|
||||
}
|
||||
|
||||
QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const
|
||||
{
|
||||
return QGenericUnixTheme::createUnixTheme(name);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -85,7 +85,8 @@ public:
|
||||
|
||||
QPlatformServices *services() const;
|
||||
|
||||
QPlatformTheme *platformTheme() const;
|
||||
QStringList themeNames() const;
|
||||
QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
||||
private:
|
||||
QList<QXcbConnection *> m_connections;
|
||||
@ -103,7 +104,6 @@ private:
|
||||
#endif
|
||||
|
||||
QScopedPointer<QPlatformServices> m_services;
|
||||
QScopedPointer<QPlatformTheme> m_theme;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user