Bug 395988

Summary: KMainWindow saves invalid window/widget state under Qt 5.11.1
Product: [Frameworks and Libraries] frameworks-kxmlgui Reporter: Mladen Milinkovic, Max <maxrd2>
Component: generalAssignee: kdelibs bugs <kdelibs-bugs>
Status: RESOLVED NOT A BUG    
Severity: major CC: asturm, bugs.kde.attila, bugseforuns, dbyy, gisk+kdebugs, jjm, kde, luca.forina, nate, nathan, oferty, pejakm, sigma343, wbauer1
Priority: HI    
Version: 5.47.0   
Target Milestone: ---   
Platform: Arch Linux   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Simple app to reproduce the problem
Simple app to reproduce the problem - Corrected

Description Mladen Milinkovic, Max 2018-06-29 06:34:12 UTC
Qt version 5.11.1
KDE Frameworks 5.47.0

Steps to Reproduce:
1. Start an application where mainwindow:
   - inherits KMainWindow (or KXmlGuiWindow) 
   - contains some widget that has WA_NativeWindow attribute set (or calls QWidget::winId()) - whether WA_DontCreateNativeAncestors is set is irrelevant
   - contains usual QStatusBar, QMenuBar (handled by KMainWindow), optionally QDockWidgets and a central widget :)
2. Close application
3. Reopen the application
4. Application starts with status/menu bar and dock widgets hidden, only central widget is visible

Additional information:
Cause of the problem is following commit: http://code.qt.io/cgit/qt/qtbase.git/commit/?id=e0b5ff4ad583befbecbcbe462998e3ed80899531 - and is related to following Qt bug: https://bugreports.qt.io/browse/QTBUG-43344

I've posted a bug report here rather than on Qt's bug tracker as I'm not sure whether it should be worked around somehow in KMainWindow, since I'm not 100% sure it's actually bug in Qt.

Above commit changed things so window close event gets handled by child widgets sooner... widgets get destroyed (and hidden) before QApplication::saveStateRequest triggers KMainWindow::saveState(). KMainWindow::saveMainWindowSettings() then calls QStatusBar/QMenuBar::isHidden() (which will return true) and updates rc file.

In usual use cases when close event is handled, QMainWindow's children are destroyed without QWidget::hide() being ever called on them, and this issue won't happen.

It seems that (in some cases) when one of the widgets has WA_NativeWindow flag set, all widgets get wrapped into QWindowWidget. In this case QMainWindow is destroyed with QWindowPrivate::destroy() and in turn child widgets (QMenuBar, QStatusBar, ...) are destroyed with QWindowPrivate::destroy() which also calls hide()/setVisible(false) on them and causes this issue.

The application where I've encountered this issue is subtitle composer here https://github.com/maxrd2/subtitlecomposer. I haven't noticed this issue on other applications I'm using so far, I suppose WA_NativeWindow flag usage is not that common in apps that rely on KMainWindow.
Comment 1 Mladen Milinkovic, Max 2018-06-29 13:31:31 UTC
Have managed to find workaround for time being (thanks frinring)

// fixes statusbar/menubar/toolbars
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
// fixes restoring root widget that contains Qt::WA_NativeWindow after
// calling KMainWindow->setupGUI()
rootDockWidget->show();

Using Qt::WA_DontCreateNativeAncestors on native window widget solved it not showing/restoring, but in combination with Qt::AA_DontCreateNativeWidgetSiblings has created painting issues.
Comment 2 Mladen Milinkovic, Max 2018-06-29 14:22:39 UTC
Created attachment 113648 [details]
Simple app to reproduce the problem

I'm not sure why in this example statusbar, menubar and toolbar continue showing. In other app case they go away too and just central widget remains.
Comment 3 Nate Graham 2018-06-29 17:15:41 UTC
Thanks for the detailed investigation! Would you be interested in producing a patch?

Our documentation for this can be found at https://community.kde.org/Infrastructure/Phabricator

It might also be worthwhile to file a bug against Qt and see what the Qt folks have to say about it.
Comment 4 Mladen Milinkovic, Max 2018-06-29 20:26:36 UTC
Yes, sure. Will have another good look at everything, to figure if there's some clean way to solve on kf5 side. If I don't come up with anything good, will create a ticket on bugreports.qt.io and try to solve it there.
Comment 5 Nate Graham 2018-06-29 21:35:01 UTC
Thanks so much, Max!
Comment 6 Mladen Milinkovic, Max 2018-06-30 09:42:31 UTC
The patch here https://phabricator.kde.org/D13808

Have tried reproducing this issue using just Qt and their recommendation of saving window state in closeEvent(), and it works fine like that.
Change introduced in Qt 5.11.1 can make the child widgets hide() during destruction, but it seems that they always hide after closeEvent() was called.

Patch just makes sure that window settings are not saved at any point after closeEvent() was accepted.
Comment 7 Wolfgang Bauer 2018-06-30 16:40:55 UTC
FTR, VirtualBox (a plain Qt application) has a similar problem since Qt 5.11.1:
the toolbar and statusbar disappear on next start if you close the window via the close button. (http://bugzilla.opensuse.org/show_bug.cgi?id=1099589)

Reverting the mentioned Qt commit fixes it, but the patch proposed here does not (of course, as it doesn't use KMainWindow').

So this is not really specific to KMailWindow...
Comment 8 Wolfgang Bauer 2018-06-30 16:41:39 UTC
(In reply to Wolfgang Bauer from comment #7)
> So this is not really specific to KMailWindow...
Oops, I mean KMainWindow of course.
Comment 9 Mladen Milinkovic, Max 2018-07-01 22:20:30 UTC
Created attachment 113693 [details]
Simple app to reproduce the problem - Corrected

Corrected the example app, statusbar, menubar and toolbar also break. SetupGUI() was supposed to be called after setting up all widgets, since that one restores settings from rc file.
Comment 10 Mladen Milinkovic, Max 2018-07-01 22:28:25 UTC
(In reply to Max from comment #0)
I apologize i wrote something wrong here:
> Above commit changed things so window close event gets handled by child
> widgets sooner... widgets get destroyed (and hidden) before
> QApplication::saveStateRequest triggers KMainWindow::saveState().
> KMainWindow::saveMainWindowSettings() then calls
> QStatusBar/QMenuBar::isHidden() (which will return true) and updates rc file.

Widgets get destroyed (and hidden) before KMainWindow::saveMainWindowSettings() gets triggered. Also it doesn't get trigerred by QApplication::saveStateRequest in this case.
Comment 11 Kai Uwe Broulik 2018-07-03 09:11:06 UTC
*** Bug 396116 has been marked as a duplicate of this bug. ***
Comment 12 Mladen Milinkovic, Max 2018-07-03 14:32:13 UTC
Have created a bug report upstream https://bugreports.qt.io/browse/QTBUG-69277
Comment 13 Mladen Milinkovic, Max 2018-07-04 16:25:52 UTC
There's an update from Qt report... They don't think it's a Qt's bug.
https://bugreports.qt.io/browse/QTBUG-69277?focusedCommentId=411008&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-411008
Comment 14 Kai Uwe Broulik 2018-07-05 07:29:52 UTC
For the record: I will advise distributions to revert the Qt patch until a proper solution is found (famous last words)
Comment 15 Wolfgang Bauer 2018-07-05 09:48:13 UTC
*** Bug 395752 has been marked as a duplicate of this bug. ***
Comment 16 Antonio Rojas 2018-07-09 14:47:36 UTC
*** Bug 396339 has been marked as a duplicate of this bug. ***
Comment 17 Nate Graham 2018-07-13 17:34:30 UTC
*** Bug 396203 has been marked as a duplicate of this bug. ***
Comment 18 Antonio Rojas 2018-07-15 14:39:22 UTC
*** Bug 396534 has been marked as a duplicate of this bug. ***
Comment 19 David Faure 2018-07-17 07:46:25 UTC
Git commit d35a88289513c0420863b80aa6c1cb7d2c6e978f by David Faure, on behalf of Mladen Milinkovic.
Committed on 17/07/2018 at 07:45.
Pushed by dfaure into branch 'master'.

Fix KMainWindow saving incorrect widget settings
In certain cases KMainWindow::saveMainWindowSettings() could have been
called after mainwindow started destroying itself. Window settings would
be saved with incorrect child widget states. e.g. some widgets would be
saved as hidden even if they were visible before destroying.

M  +4    -0    src/kmainwindow.cpp

https://commits.kde.org/kxmlgui/d35a88289513c0420863b80aa6c1cb7d2c6e978f
Comment 20 Daimonion 2018-07-17 10:27:16 UTC
396339 still not fixed after installing patched package in Arch: https://git.archlinux.org/svntogit/packages.git/commit/trunk?h=packages/kxmlgui&id=a974176c369056d599cc91343ac9373801bceec3
Comment 21 Mladen Milinkovic, Max 2018-07-17 15:00:40 UTC
(In reply to Daimonion from comment #20)
> 396339 still not fixed after installing patched package in Arch:
> https://git.archlinux.org/svntogit/packages.git/commit/trunk?h=packages/
> kxmlgui&id=a974176c369056d599cc91343ac9373801bceec3

KMail does saveMainWindowSettings() from mainwindow destructor:
https://cgit.kde.org/kmail.git/tree/src/kmmainwin.cpp#n99
That is broken in Qt 5.11.1 regardless of kf5 patches. It should be fixed in kmail.
Comment 22 Andreas Sturmlechner 2018-07-18 18:31:37 UTC
(In reply to Max from comment #21)
> KMail does saveMainWindowSettings() from mainwindow destructor:
> https://cgit.kde.org/kmail.git/tree/src/kmmainwin.cpp#n99
> That is broken in Qt 5.11.1 regardless of kf5 patches. It should be fixed in
> kmail.

Did you open a bug for kmail?
Comment 23 Mladen Milinkovic, Max 2018-07-19 08:51:13 UTC
(In reply to andreas.sturmlechner from comment #22)
> Did you open a bug for kmail?

yes... have reopened Bug 396339 and added explanation there
Comment 24 David Faure 2018-07-31 13:46:15 UTC
Git commit 814f0db2a1ae5b15bf91909ce80a5d6792f9aeed by David Faure.
Committed on 31/07/2018 at 13:46.
Pushed by dfaure into branch 'Applications/18.08'.

Port to setAutoSaveSettings so that saving happens before hiding.

Summary:
See d35a882895 in kxmlgui for more complete explanation.
Related: bug 396339

Test Plan: kmail ; Alt+F4 ; kmail -> now the statusbar and toolbar are visible again

Reviewers: ngraham, elvisangelaccio, broulik, cfeck, mlaurent

Reviewed By: mlaurent

Subscribers: kde-pim

Tags: #kde_pim

Differential Revision: https://phabricator.kde.org/D14454

M  +1    -5    src/kmmainwin.cpp

https://commits.kde.org/kmail/814f0db2a1ae5b15bf91909ce80a5d6792f9aeed
Comment 25 Christophe Marin 2018-09-26 09:00:35 UTC
*** Bug 398987 has been marked as a duplicate of this bug. ***
Comment 26 Damian Nowak 2020-10-09 21:22:08 UTC
I'm still affected by this. Latest KDE because using Arch Linux.

How do I get the File, Edit and other menus back?
Comment 27 Mladen Milinkovic, Max 2020-10-11 16:49:33 UTC
(In reply to Damian Nowak from comment #26)
> I'm still affected by this. Latest KDE because using Arch Linux.
> 
> How do I get the File, Edit and other menus back?

Which app did lose menus? You should probably edit (BACKUP FIRST) $HOME/.config/[YouAppName]rc and remove lines similar to 'xxxState=\x...bunch of binary values..\x....\x...'

Afterwards start the affected app again and it should restore your menu/window/widget visibility/layout to defaults.
Comment 28 Nate Graham 2023-04-10 17:50:50 UTC
*** Bug 468248 has been marked as a duplicate of this bug. ***
Comment 29 Fred 2023-04-12 15:03:15 UTC
(In reply to Mladen Milinkovic, Max from comment #27)
> (In reply to Damian Nowak from comment #26)
> > I'm still affected by this. Latest KDE because using Arch Linux.
> > 
> > How do I get the File, Edit and other menus back?
> 
> Which app did lose menus? You should probably edit (BACKUP FIRST)
> $HOME/.config/[YouAppName]rc and remove lines similar to
> 'xxxState=\x...bunch of binary values..\x....\x...'
> 
> Afterwards start the affected app again and it should restore your
> menu/window/widget visibility/layout to defaults.

As of April 2023, I proceed as suggested and removed the lines in questions but it didn't affect the menu options. Still some listed as 'no text'.
Btw. It's Okular where the corrupt menu happened.
Do I see it right, thus bug is known since 2018?
Comment 30 Mladen Milinkovic, Max 2023-04-12 15:07:26 UTC
(In reply to Fred from comment #29)
> (In reply to Mladen Milinkovic, Max from comment #27)
> > (In reply to Damian Nowak from comment #26)
> > > I'm still affected by this. Latest KDE because using Arch Linux.
> > > 
> > > How do I get the File, Edit and other menus back?
> > 
> > Which app did lose menus? You should probably edit (BACKUP FIRST)
> > $HOME/.config/[YouAppName]rc and remove lines similar to
> > 'xxxState=\x...bunch of binary values..\x....\x...'
> > 
> > Afterwards start the affected app again and it should restore your
> > menu/window/widget visibility/layout to defaults.
> 
> As of April 2023, I proceed as suggested and removed the lines in questions
> but it didn't affect the menu options. Still some listed as 'no text'.
> Btw. It's Okular where the corrupt menu happened.
> Do I see it right, thus bug is known since 2018?

You're seeing what is described in bug https://bugs.kde.org/show_bug.cgi?id=468248 .. correct?
I'm not 100% sure that menu entries showing as "No Text" is duplicate of this bug - this bug was about menu bar, toolbars, statusbar becoming hidden/invisible.
Comment 31 Fred 2023-04-22 14:10:54 UTC
I'm getting a little bit confused about this bug tracking.
I did not mark it as duplicate bug of this one.
I filed a new bug under # 468248, menu entries listed as 'no text'.
And beyond that I don't know how this bug tracking system is working. who reads it, who linked bugs and who looking into the reported bugs.
I'm just a humble user/reporter of a bug.
:-)