[kstyle] Implement application unpolish to delete ShadowHelper
AbandonedPublic

Authored by graesslin on Nov 3 2016, 9:58 AM.

Details

Summary

Another change mostly for KWin (Wayland compositor). KWin destroys it's
internal Wayland connection prior to the QStyle getting destroyed. As
the ShadowHelper initialized Wayland objects those would be destroyed
after the connection is destroyed. With latest Wayland library this
would cause a crash.

Thus unpolish is implemented in the style and deletes the ShadowHelper.
KWin can on tear down invoke the unpolish and thus make sure it doesn't
crash.

CCBUG: 372001

Diff Detail

Repository
R31 Breeze
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
graesslin updated this revision to Diff 7849.Nov 3 2016, 9:58 AM
graesslin retitled this revision from to [kstyle] Implement application unpolish to delete ShadowHelper.
graesslin updated this object.
graesslin edited the test plan for this revision. (Show Details)
Restricted Application added a project: Plasma. · View Herald TranscriptNov 3 2016, 9:58 AM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript

Did you test whether unpolish is actually called ? Last time I tried, it was not, at least not always. (depending on whether you run a QApplication, KApplication, etc.)
This is what led to the mess of destroying the singleton style in the plugin helper, which in turn created other crashes, and which was removed aferwards.
This all story of QStyle dinitialization is a mess ...

Did you test whether unpolish is actually called ? Last time I tried, it was not, at least not always. (depending on whether you run a QApplication, KApplication, etc.)
This is what led to the mess of destroying the singleton style in the plugin helper, which in turn created other crashes, and which was removed aferwards.
This all story of QStyle dinitialization is a mess ...

Ah
sorry.
I misread the fact that you actually make sure that kwin calls the unpolish.

Did you test whether unpolish is actually called ? Last time I tried, it was not, at least not always. (depending on whether you run a QApplication, KApplication, etc.)
This is what led to the mess of destroying the singleton style in the plugin helper, which in turn created other crashes, and which was removed aferwards.
This all story of QStyle dinitialization is a mess ...

Ah
sorry.
I misread the fact that you actually make sure that kwin calls the unpolish.

For the general case you are right. Unpolish is only called from QApplication::setStyle when the old style gets destroyed. On Application tear-down it's not called.

For the general case you are right. Unpolish is only called from QApplication::setStyle when the old style gets destroyed. On Application tear-down it's not called.

To be honest, I am a bit uneasy about this change. Sounds somewhat like abusing the API (since you then call the method explicitly in kwin). What if people later on start adding other "destruction" stuff in unpolish, unaware that it is actually not called ?

Maybe something cleaner would be to move everything from the destructor to unpolish (with proper reassignment to nullptr), and then call unpolish explicitely in the destructor.
The whole thing with tons of comments/warning ?

For the general case you are right. Unpolish is only called from QApplication::setStyle when the old style gets destroyed. On Application tear-down it's not called.

To be honest, I am a bit uneasy about this change. Sounds somewhat like abusing the API (since you then call the method explicitly in kwin). What if people later on start adding other "destruction" stuff in unpolish, unaware that it is actually not called ?

Maybe something cleaner would be to move everything from the destructor to unpolish (with proper reassignment to nullptr), and then call unpolish explicitely in the destructor.
The whole thing with tons of comments/warning ?

I don't like calling virtual methods from a dtor, always a mess. But we can do a private cleanup method and call it from both dtor and unpolish. Would that be OK to you?

I don't like calling virtual methods from a dtor, always a mess.

agreed

But we can do a private cleanup method and call it from both dtor and unpolish. Would that be OK to you?

yes

graesslin updated this revision to Diff 7858.Nov 3 2016, 11:49 AM
graesslin edited edge metadata.

Implement a private cleanup method invoked by dtor and unpolish

hpereiradacosta accepted this revision.Nov 3 2016, 11:52 AM
hpereiradacosta edited edge metadata.

ship-it

This revision is now accepted and ready to land.Nov 3 2016, 11:52 AM
This revision was automatically updated to reflect the committed changes.
ivan reopened this revision.Nov 7 2016, 8:24 PM
ivan added a subscriber: ivan.

I've just had a crash in Cantata (on launch) with this patch. The cleanup() is called which deletes the _shadowHelper which is later used in polish().

This revision is now accepted and ready to land.Nov 7 2016, 8:24 PM
ivan requested changes to this revision.Nov 7 2016, 8:24 PM
ivan added a reviewer: ivan.
This revision now requires changes to proceed.Nov 7 2016, 8:24 PM
In D3240#61517, @ivan wrote:

I've just had a crash in Cantata (on launch) with this patch. The cleanup() is called which deletes the _shadowHelper which is later used in polish().

@ivan can you run cantata through gdb and break in the cleanup? I don't understand how it could have got there and to me it doesn't happen.

graesslin abandoned this revision.Nov 10 2016, 12:34 PM

Change is reverted. That just doesn't work with style sheets.