Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken restoration of nested MainWindow #508

Open
bbc131 opened this issue Jun 14, 2024 · 1 comment
Open

Broken restoration of nested MainWindow #508

bbc131 opened this issue Jun 14, 2024 · 1 comment
Assignees
Milestone

Comments

@bbc131
Copy link
Contributor

bbc131 commented Jun 14, 2024

I experienced some issues with the restoration of nested MainWindows.
The problem is, that during restoration, the properties of MainWindows are applied to the corresponding root views, which means, that an embedded MainWindows properties are forwarded to the embedding window, possibly overwriting the properties of the latter.

I have two specific cases where this causes problems, use the mwe below to reproduce them.

In the mwe I setup one MainWindow, which has two DockWidgets docked (SuperDock-1, SuperDock-2). Each of this "SuperDock" contains again a MainWindow. Both of those MainWindows has a docked DockWidget (SubDock-A (1), SubDock-B (2)).

Case 1 (visibility)

If you stack SuperDock-2 behind SuperDock-1 and then save and restore the layout (use the actions in the File menu), the application MainWindow disappears. You can run this actions by enabling the if (0) ... at the bottom of the mwe code.
This happens because the SuperDock-2 is restored at last and since it's hidden, its visibility property is false. As explained above, this is applied to the root view, which is the application MainWindow, which the is set invisible.

Case 2 (geometry)

Here you need at least two screens. Run the mwe, maximize the window on the right screen and then save and restore the layout. The window will appear on the left screen.
In this case the property normalGeometry of the Sub-Docks, which has something like x=9 in my case, instead of x=1920 for the application MainWindow, is applied to the application window. This moves the window to the left screen.
Just in case, I attach the saved layout .json (mylayout.json), where I got the numbers from. Note, that I have three screens.

MWE

#include <kddockwidgets/MainWindow.h>
#include <kddockwidgets/DockWidget.h>

#include "kddockwidgets/Config.h"
#include <kddockwidgets/LayoutSaver.h>

#include <QStyleFactory>
#include <QApplication>
#include <QLabel>
#include <QVBoxLayout>
#include <QMenu>
#include <QMenuBar>
#include <QMainWindow>

using namespace KDDockWidgets;

struct SuperDock
{
    QtWidgets::DockWidget *dockwidget;
    QtWidgets::MainWindow *mainwindow;
};

QtWidgets::DockWidget *create_sub_dockwidget(int number, QString label, QColor color)
{
    auto set_color = [](QLabel *label, QColor color) {
        auto pal = label->palette();
        pal.setColor(QPalette::ColorRole::Window, color);
        label->setPalette(pal);
        label->setAutoFillBackground(true);
    };

    auto subdock = new QtWidgets::DockWidget(QStringLiteral("SubDock-%2 (%1)").arg(number).arg(label));
    subdock->setAffinityName(QStringLiteral("MainWindow%1").arg(number));
    auto subwidget = new QLabel(QStringLiteral("subwidget-%1 (%2)").arg(number).arg(label));
    subwidget->setAlignment(Qt::AlignCenter);
    set_color(subwidget, color);
    subdock->setWidget(subwidget);
    return subdock;
}

SuperDock create_super_dock(int number)
{
    auto mw = new QtWidgets::MainWindow(QStringLiteral("MainWindow%1").arg(number));
    mw->setAffinities({ QStringLiteral("MainWindow%1").arg(number) });
    mw->setWindowTitle(QStringLiteral("Main Window %1").arg(number));

    auto container = new QWidget();
    auto layout = new QVBoxLayout(container);
    auto label = new QLabel(QStringLiteral("Main Window %1").arg(number));
    label->setAlignment(Qt::AlignBottom);
    layout->addWidget(label);
    layout->addWidget(mw);

    auto superdock = new KDDockWidgets::QtWidgets::DockWidget(QStringLiteral("SuperDock-%1").arg(number));
    superdock->setAttribute(Qt::WA_DeleteOnClose);
    superdock->setWidget(container);
    return { superdock, mw };
}

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtWidgets);

    auto &config = Config::self();

    // Create application main window
    QtWidgets::MainWindow appMainWindow(QStringLiteral("Application MainWindow"));
    appMainWindow.setWindowTitle("Application Main Window");
    appMainWindow.resize(600, 200);
    appMainWindow.show();

    auto menu = new QMenu(QStringLiteral("File"));
    auto menubar = appMainWindow.menuBar();
    menubar->addMenu(menu);

    auto saveLayoutAction = menu->addAction("Save layout");
    QObject::connect(saveLayoutAction, &QAction::triggered, [] {
        KDDockWidgets::LayoutSaver saver;
        const bool result = saver.saveToFile(QStringLiteral("mylayout.json"));
        qDebug() << "Saving layout to disk. Result=" << result;
    });
    auto restoreLayoutAction = menu->addAction("Restore layout");
    QObject::connect(restoreLayoutAction, &QAction::triggered, [] {
        KDDockWidgets::RestoreOptions options = KDDockWidgets::RestoreOption_None;
        KDDockWidgets::LayoutSaver saver(options);
        saver.restoreFromFile(QStringLiteral("mylayout.json"));
    });

    /* Setup the specific layout*/

    // Super-dock 1 with one red sub-dock
    auto super_dock_1 = create_super_dock(1);
    auto sub_dock_a_1 = create_sub_dockwidget(1, "A", Qt::red);
    appMainWindow.addDockWidget(super_dock_1.dockwidget, KDDockWidgets::Location_OnRight);
    super_dock_1.mainwindow->addDockWidget(sub_dock_a_1, KDDockWidgets::Location_OnRight);

    // Super-dock 2 with one blue sub-dock
    auto super_dock_2 = create_super_dock(2);
    auto sub_dock_b_2 = create_sub_dockwidget(2, "B", Qt::blue);
    appMainWindow.addDockWidget(super_dock_2.dockwidget, KDDockWidgets::Location_OnRight);
    super_dock_2.mainwindow->addDockWidget(sub_dock_b_2, KDDockWidgets::Location_OnRight);

    /* Do the problematic actions for case 1 (visibility) */
    if (0) {
        super_dock_1.dockwidget->addDockWidgetAsTab(super_dock_2.dockwidget);
        super_dock_1.dockwidget->setAsCurrentTab();
        saveLayoutAction->trigger();
        restoreLayoutAction->trigger();
    }

    return app.exec();
}
@iamsergio iamsergio self-assigned this Nov 29, 2024
@iamsergio iamsergio added this to the v2.2 milestone Nov 29, 2024
iamsergio added a commit that referenced this issue Nov 29, 2024
To be easy to build and test.
This will be deleted after the issue is fixed.
@iamsergio
Copy link
Contributor

Reproduced visibility problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants