Bug 334624

Summary: KCModule::save() unable to access combobox values on OK
Product: [Frameworks and Libraries] frameworks-kconfigwidgets Reporter: Sebastian Kügler <sebas>
Component: generalAssignee: kdelibs bugs <kdelibs-bugs>
Status: RESOLVED FIXED    
Severity: normal CC: agateau, cfeck, kdelibs-bugs
Priority: NOR    
Version: 4.99.0   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Sebastian Kügler 2014-05-11 22:09:28 UTC
I have a KCModule that uses a .ui file. When OK'ing the dialog, the ::save() function gets called, but values of a combobox in my .ui are gone by that time. When the module isn't deleted afterwards (Apply), everything works.

This is an issue showing with kcmshell5, but not with systemsettings, since systemsettings doesn't show an OK button.

Reproducible: Always

Steps to Reproduce:
1. Open "Formats" KCM
2. Change value of a combobox
3. Hit OK
Actual Results:  
When reopening the Formats KCM, values have not been applied.

Expected Results:  
Combobox values should have been saved correctly.

I've debugged this in the KCM as far as counting values of the combox, and in the problematic case, it's always zero. There seems to be a race condition that the comboboxes are emptied before we can save the config on deletion. My .ui file resulting widget is only deleted in the KCM dtor.

Code in plasma-desktop/kcms/formats/kcmformats.cpp show the problematic behavior. (Currently in branch sebas/locale, soon to be merged into master.)
Comment 1 Christoph Feck 2014-05-12 00:02:15 UTC
Hm, I am probably not understanding correctly, but do you think this bug is in kcombobox (which is in kcompletion) or in kcmodule (which is in kconfigwidgets)?
Comment 2 Sebastian Kügler 2014-05-12 01:01:49 UTC
I think it's a bug in KCModule, I'm using QComboBox.

That's basically the following going wrong:

void KCMFormats::save()
{
    // m_ui->comboBox ends up empty here when OK button is clicked from kcmshell5,
    // apparently the data in the combo is gone by the time save() is called.
    // This might be a problem in KCModule, but does not directly affect us
    // since within systemsettings, it works fine.
    // See https://bugs.kde.org/show_bug.cgi?id=334624
    if (m_ui->comboBox->count() == 0) {
        qWarning() << "Couldn't read data from UI, writing configuration failed.";
        return;
    }
   //[...]
}
Comment 3 Christoph Feck 2014-05-12 01:21:04 UTC
Thanks for the update, reassigning for further investigation.
Comment 4 Aurelien Gateau 2014-06-10 20:46:41 UTC
I have a fix for an issue with one of KWin KCM which looks very similar: https://git.reviewboard.kde.org/r/118639/
Comment 5 Sebastian Kügler 2014-06-12 15:55:40 UTC
This patch fixes the problem, indeed.
Comment 6 Aurelien Gateau 2014-06-13 07:41:44 UTC
Git commit cc99fac3af737619ea220ccb7059f0d8f0623efa by Aurélien Gâteau.
Committed on 10/06/2014 at 14:40.
Pushed by gateau into branch 'master'.

KCMultiDialog: Fix crash when clicking OK

When one closes KCMultiDialog with OK, QDialog::finished() can be emitted
before the clicked() signal of the OK button. This causes the following
sequence to happen:

- KCMultiDialogPrivate::_k_dialogClosed
  * deletes the KCModule
    - KCModuleProxyPrivate::_k_moduleDestroyed
      * sets kcm to 0

- KCMultiDialog::slotOkClicked
  - KCMultiDialogPrivate::apply
    - KCModuleProxy::save
      - KCModuleProxyPrivate::realModule
        * notices kcm is 0, so recreates it
        * calls kcm->save()
          - KWinDesktopConfig::save()
            * crashes because it expects kcm->load() to have been called

To avoid this, trigger the cleanup code in closeEvent() rather than when
finished() is emitted, as we can be sure closeEvent() is always called
*after* the methods connected to the button box signals has executed.

REVIEW: 118639

M  +15   -15   src/kcmultidialog.cpp
M  +2    -1    src/kcmultidialog.h

http://commits.kde.org/kcmutils/cc99fac3af737619ea220ccb7059f0d8f0623efa