summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <rgriebl@trolltech.com>2009-11-18 14:55:44 (GMT)
committerRobert Griebl <rgriebl@trolltech.com>2009-11-18 15:05:07 (GMT)
commitd173dabf3e441bf4a16237df1a90e256ae525596 (patch)
tree052d811b4cf33e118350586ccbd78777530f986e
parente2a6bf8d1c69d86c939aafcf357d60dcaa5f3d42 (diff)
downloadQt-d173dabf3e441bf4a16237df1a90e256ae525596.zip
Qt-d173dabf3e441bf4a16237df1a90e256ae525596.tar.gz
Qt-d173dabf3e441bf4a16237df1a90e256ae525596.tar.bz2
Fix QGtkStyle crash when switching themes.
This is a workaround for a bug that we introduced with the QGtkStyle refactoring to properly support Maemo5. RevBy: jbache
-rw-r--r--src/gui/styles/qgtkstyle_p.cpp58
-rw-r--r--src/gui/styles/qgtkstyle_p.h19
2 files changed, 46 insertions, 31 deletions
diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp
index 62d9197..5f4ebae 100644
--- a/src/gui/styles/qgtkstyle_p.cpp
+++ b/src/gui/styles/qgtkstyle_p.cpp
@@ -204,14 +204,14 @@ typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
Q_DECLARE_METATYPE(QGtkStylePrivate*);
-static void gtkStyleSetCallback(GtkWidget*, QGtkStylePrivate* stylePrivate)
+static void gtkStyleSetCallback(GtkWidget*)
{
qRegisterMetaType<QGtkStylePrivate *>();
// We have to let this function return and complete the event
// loop to ensure that all gtk widgets have been styled before
// updating
- QMetaObject::invokeMethod(styleScheduler(), "updateTheme", Qt::QueuedConnection, Q_ARG(QGtkStylePrivate*, stylePrivate));
+ QMetaObject::invokeMethod(styleScheduler(), "updateTheme", Qt::QueuedConnection);
}
static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer)
@@ -255,10 +255,18 @@ bool QGtkStyleFilter::eventFilter(QObject *obj, QEvent *e)
return QObject::eventFilter(obj, e);
}
+QList<QGtkStylePrivate *> QGtkStylePrivate::instances;
+
QGtkStylePrivate::QGtkStylePrivate()
: QCleanlooksStylePrivate()
, filter(this)
{
+ instances.append(this);
+}
+
+QGtkStylePrivate::~QGtkStylePrivate()
+{
+ instances.removeOne(this);
}
void QGtkStylePrivate::init()
@@ -289,7 +297,7 @@ GtkStyle* QGtkStylePrivate::gtkStyle(const QString &path)
/*! \internal
* Get references to gtk functions after we dynamically load the library.
*/
-void QGtkStylePrivate::resolveGtk()
+void QGtkStylePrivate::resolveGtk() const
{
// enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
@@ -417,7 +425,7 @@ void QGtkStylePrivate::resolveGtk()
* Initializes a number of gtk menu widgets.
* The widgets are cached.
*/
-void QGtkStylePrivate::initGtkMenu()
+void QGtkStylePrivate::initGtkMenu() const
{
// Create menubar
GtkWidget *gtkMenuBar = QGtkStylePrivate::gtk_menu_bar_new();
@@ -448,7 +456,7 @@ void QGtkStylePrivate::initGtkMenu()
}
-void QGtkStylePrivate::initGtkTreeview()
+void QGtkStylePrivate::initGtkTreeview() const
{
GtkWidget *gtkTreeView = gtk_tree_view_new();
gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
@@ -462,7 +470,7 @@ void QGtkStylePrivate::initGtkTreeview()
* Initializes a number of gtk widgets that we can later on use to determine some of our styles.
* The widgets are cached.
*/
-void QGtkStylePrivate::initGtkWidgets()
+void QGtkStylePrivate::initGtkWidgets() const
{
// From gtkmain.c
uid_t ruid = getuid ();
@@ -513,7 +521,7 @@ void QGtkStylePrivate::initGtkWidgets()
if (!gtkWidgetMap()->contains(QLS("GtkButton"))) {
GtkWidget *gtkButton = QGtkStylePrivate::gtk_button_new();
addWidget(gtkButton);
- g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), this);
+ g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0);
addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, NULL));
addWidget(QGtkStylePrivate::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
addWidget(QGtkStylePrivate::gtk_hbutton_box_new());
@@ -617,7 +625,7 @@ bool QGtkStylePrivate::getGConfBool(const QString &key, bool fallback)
return retVal;
}
-QString QGtkStylePrivate::getThemeName() const
+QString QGtkStylePrivate::getThemeName()
{
QString themeName;
// We try to parse the gtkrc file first
@@ -734,7 +742,7 @@ void QGtkStylePrivate::addAllSubWidgets(GtkWidget *widget, gpointer v)
}
// Updates window/windowtext palette based on the indicated gtk widget
-QPalette QGtkStylePrivate::gtkWidgetPalette(const QString &gtkWidgetName)
+QPalette QGtkStylePrivate::gtkWidgetPalette(const QString &gtkWidgetName) const
{
GtkWidget *gtkWidget = QGtkStylePrivate::gtkWidget(gtkWidgetName);
Q_ASSERT(gtkWidget);
@@ -755,7 +763,7 @@ QPalette QGtkStylePrivate::gtkWidgetPalette(const QString &gtkWidgetName)
}
-void QGtkStyleUpdateScheduler::updateTheme( QGtkStylePrivate* stylePrivate )
+void QGtkStyleUpdateScheduler::updateTheme()
{
static QString oldTheme(QLS("qt_not_set"));
QPixmapCache::clear();
@@ -764,20 +772,22 @@ void QGtkStyleUpdateScheduler::updateTheme( QGtkStylePrivate* stylePrivate )
if (QApplication::font() != font)
qApp->setFont(font);
- if (oldTheme != stylePrivate->getThemeName()) {
- oldTheme = stylePrivate->getThemeName();
- QPalette newPalette = qApp->style()->standardPalette();
- QApplicationPrivate::setSystemPalette(newPalette);
- QApplication::setPalette(newPalette);
- stylePrivate->initGtkWidgets();
- stylePrivate->applyCustomPaletteHash();
- QList<QWidget*> widgets = QApplication::allWidgets();
- // Notify all widgets that size metrics might have changed
- foreach (QWidget *widget, widgets) {
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(widget, &e);
- }
- }
+ if (oldTheme != QGtkStylePrivate::getThemeName()) {
+ oldTheme = QGtkStylePrivate::getThemeName();
+ QPalette newPalette = qApp->style()->standardPalette();
+ QApplicationPrivate::setSystemPalette(newPalette);
+ QApplication::setPalette(newPalette);
+ if (!QGtkStylePrivate::instances.isEmpty()) {
+ QGtkStylePrivate::instances.last()->initGtkWidgets();
+ QGtkStylePrivate::instances.last()->applyCustomPaletteHash();
+ }
+ QList<QWidget*> widgets = QApplication::allWidgets();
+ // Notify all widgets that size metrics might have changed
+ foreach (QWidget *widget, widgets) {
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &e);
+ }
+ }
QIconLoader::instance()->updateSystemTheme();
}
diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h
index fa16769..f6ab8a3 100644
--- a/src/gui/styles/qgtkstyle_p.h
+++ b/src/gui/styles/qgtkstyle_p.h
@@ -255,16 +255,17 @@ class QGtkStylePrivate : public QCleanlooksStylePrivate
Q_DECLARE_PUBLIC(QGtkStyle)
public:
QGtkStylePrivate();
+ ~QGtkStylePrivate();
QGtkStyleFilter filter;
static GtkWidget* gtkWidget(const QString &path);
static GtkStyle* gtkStyle(const QString &path = QLatin1String("GtkWindow"));
- virtual void resolveGtk();
- virtual void initGtkMenu();
- virtual void initGtkTreeview();
- virtual void initGtkWidgets();
+ virtual void resolveGtk() const;
+ virtual void initGtkMenu() const;
+ virtual void initGtkTreeview() const;
+ virtual void initGtkWidgets() const;
static void cleanupGtkWidgets();
@@ -276,7 +277,7 @@ public:
static bool getGConfBool(const QString &key, bool fallback = 0);
static QString getGConfString(const QString &key, const QString &fallback = QString());
- virtual QString getThemeName() const;
+ static QString getThemeName();
virtual int getSpinboxArrowSize() const;
static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
@@ -412,7 +413,7 @@ public:
static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
static Ptr_gnome_vfs_init gnome_vfs_init;
- virtual QPalette gtkWidgetPalette(const QString &gtkWidgetName);
+ virtual QPalette gtkWidgetPalette(const QString &gtkWidgetName) const;
protected:
typedef QHash<QString, GtkWidget*> WidgetMap;
@@ -434,6 +435,10 @@ protected:
static void addWidget(GtkWidget *widget);
virtual void init();
+
+private:
+ static QList<QGtkStylePrivate *> instances;
+ friend class QGtkStyleUpdateScheduler;
};
// Helper to ensure that we have polished all our gtk widgets
@@ -442,7 +447,7 @@ class QGtkStyleUpdateScheduler : public QObject
{
Q_OBJECT
public slots:
- void updateTheme( QGtkStylePrivate* stylePrivate );
+ void updateTheme();
};
QT_END_NAMESPACE