Git commit ef70ffffb0bdfe8f011e0f86bd475c54c55426f5 by Yichao Yu. Committed on 19/03/2016 at 18:34. Pushed by yuyichao into branch 'master'. workaround QStyle::~QStyle not called by at least klipper M +18 -18 qt5/style/qtcurve.cpp M +2 -1 qt5/style/qtcurve.h M +46 -0 qt5/style/qtcurve_plugin.cpp M +4 -0 qt5/style/qtcurve_plugin.h http://commits.kde.org/qtcurve/ef70ffffb0bdfe8f011e0f86bd475c54c55426f5 diff --git a/qt5/style/qtcurve.cpp b/qt5/style/qtcurve.cpp index ca24837..43d70d4 100644 --- a/qt5/style/qtcurve.cpp +++ b/qt5/style/qtcurve.cpp @@ -21,6 +21,7 @@ *************************************************************************= ****/ = #include "qtcurve_p.h" +#include "qtcurve_plugin.h" #include = #include @@ -346,7 +347,7 @@ Style::Style() : m_windowManager(new WindowManager(this)), m_blurHelper(new BlurHelper(this)), m_shortcutHandler(new ShortcutHandler(this)), - m_dbusConnected(false) + m_dbusConnected(nullptr) { const char *env =3D getenv(QTCURVE_PREVIEW_CONFIG); if (env && strcmp(env, QTCURVE_PREVIEW_CONFIG) =3D=3D 0) { @@ -658,7 +659,10 @@ void Style::connectDBus() { if (m_dbusConnected) return; - m_dbusConnected =3D true; + m_dbusConnected =3D registerCleanup([] (void *data) { + reinterpret_cast(data)->disconnectDBus(); + }, this); + return; auto bus =3D QDBusConnection::sessionBus(); bus.connect(QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange", this, SLOT(kdeGlobalSettingsChange(int, in= t))); @@ -685,28 +689,24 @@ void Style::disconnectDBus() { if (!m_dbusConnected) return; - m_dbusConnected =3D false; + void *cb =3D m_dbusConnected; + m_dbusConnected =3D nullptr; + unregisterCleanup(cb); + return; auto bus =3D QDBusConnection::sessionBus(); bus.disconnect(QString(), "/KGlobalSettings", "org.kde.KGlobalSettings= ", "notifyChange", this, SLOT(kdeGlobalSettingsChange(int, int))); bus.disconnect("org.kde.kwin", "/KWin", "org.kde.KWin", "compositingTo= ggled", this, SLOT(compositingToggled())); - - if (!qApp || qApp->arguments()[0] !=3D "kwin") { - bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", - "borderSizesChanged", this, SLOT(borderSizesChanged())= ); - if (opts.menubarHiding & HIDE_KWIN) - bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", - "toggleMenuBar", - this, SLOT(toggleMenuBar(unsigned int))); - - if (opts.statusbarHiding & HIDE_KWIN) { - bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", - "toggleStatusBar", - this, SLOT(toggleStatusBar(unsigned int))); - } - } + bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", + "borderSizesChanged", this, SLOT(borderSizesChanged())); + bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", + "toggleMenuBar", + this, SLOT(toggleMenuBar(unsigned int))); + bus.disconnect("org.kde.kwin", "/QtCurve", "org.kde.QtCurve", + "toggleStatusBar", + this, SLOT(toggleStatusBar(unsigned int))); } = Style::~Style() diff --git a/qt5/style/qtcurve.h b/qt5/style/qtcurve.h index 69cf3d7..6836b9d 100644 --- a/qt5/style/qtcurve.h +++ b/qt5/style/qtcurve.h @@ -509,6 +509,7 @@ private: const QStyleOption *option, QPainter *painter, const QWidget *widget) const; + static void dbusCleanupCallback(void*); = private: mutable Options opts; @@ -559,7 +560,7 @@ private: WindowManager *m_windowManager; BlurHelper *m_blurHelper; ShortcutHandler *m_shortcutHandler; - bool m_dbusConnected; + void *m_dbusConnected; }; } = diff --git a/qt5/style/qtcurve_plugin.cpp b/qt5/style/qtcurve_plugin.cpp index 500a3ff..b8c76ce 100644 --- a/qt5/style/qtcurve_plugin.cpp +++ b/qt5/style/qtcurve_plugin.cpp @@ -27,6 +27,7 @@ #include #include #include +#include = #include = @@ -43,6 +44,49 @@ = namespace QtCurve { = +// Using a `std::set` somehow result in a segfault in glibc (maybe realate= d to +// this function being called in the exit handler?) so use a home made sol= ution +// instead... +struct CleanupCallback { + void (*func)(void*); + void *data; + CleanupCallback *next; + CleanupCallback **prev; +}; + +static CleanupCallback *cleanup_callbacks =3D nullptr; + +void* +registerCleanup(void (*func)(void*), void *data) +{ + auto cb =3D new CleanupCallback{func, data, cleanup_callbacks, + &cleanup_callbacks}; + if (cleanup_callbacks) + cleanup_callbacks->prev =3D &cb->next; + cleanup_callbacks =3D cb; + return cb; +} + +void +unregisterCleanup(void *_cb) +{ + auto cb =3D (CleanupCallback*)_cb; + if (cb->next) + cb->next->prev =3D cb->prev; + *cb->prev =3D cb->next; + delete cb; +} + +static void +runAllCleanups() +{ + while (cleanup_callbacks) { + auto func =3D cleanup_callbacks->func; + auto data =3D cleanup_callbacks->data; + func(data); + } +} + __attribute__((hot)) static void polishQuickControl(QObject *obj) { @@ -120,6 +164,7 @@ StylePlugin::create(const QString &key) = StylePlugin::~StylePlugin() { + runAllCleanups(); QInternal::unregisterCallback(QInternal::EventNotifyCallback, qtcEventCallback); } @@ -140,4 +185,5 @@ StylePlugin::init() #endif }); } + } diff --git a/qt5/style/qtcurve_plugin.h b/qt5/style/qtcurve_plugin.h index 95bbfed..fc81107 100644 --- a/qt5/style/qtcurve_plugin.h +++ b/qt5/style/qtcurve_plugin.h @@ -36,6 +36,10 @@ private: void init(); std::once_flag m_ref_flag; }; + +void *registerCleanup(void (*func)(void*), void *data); +void unregisterCleanup(void *handle); + } = #endif