Skip to content

Commit

Permalink
Save previous floating layout when deleting FloatingWindow
Browse files Browse the repository at this point in the history
FloatingWindow's are deleted all the time but their layouts
are interesting to restore dockwidgets to floating position

For issue #513
  • Loading branch information
iamsergio committed Jul 20, 2024
1 parent 44b772d commit 7fba876
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 1 deletion.
1 change: 0 additions & 1 deletion src/core/DockWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "core/TabBar.h"
#include "core/TabBar_p.h"
#include "core/MainWindow.h"
#include "core/Utils_p.h"
#include "core/WindowBeingDragged_p.h"
#include "core/Position_p.h"
#include "core/Platform_p.h"
Expand Down
4 changes: 4 additions & 0 deletions src/core/DockWidget_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
#include "core/View_p.h"
#include "QtCompat_p.h"

#include <memory>

namespace KDDockWidgets {

namespace Core {
class SideBar;
class PreviousFloatingLayout;

class DOCKS_EXPORT_FOR_UNIT_TESTS DockWidget::Private
{
Expand Down Expand Up @@ -296,6 +299,7 @@ class DOCKS_EXPORT_FOR_UNIT_TESTS DockWidget::Private
KDBindings::ScopedConnection m_toggleActionConnection;
KDBindings::ScopedConnection m_floatActionConnection;
CloseReason m_lastCloseReason = CloseReason::Unspecified;
std::shared_ptr<Core::PreviousFloatingLayout> m_previousFloatingLayout;
};

}
Expand Down
10 changes: 10 additions & 0 deletions src/core/DropArea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,3 +726,13 @@ Core::Group *DropArea::centralGroup() const
{
return d->m_centralGroup;
}

PreviousFloatingLayout::PreviousFloatingLayout(Core::DropArea *l)
: layout(l)
{
}

PreviousFloatingLayout::~PreviousFloatingLayout()
{
delete layout;
}
22 changes: 22 additions & 0 deletions src/core/DropArea.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "kddockwidgets/KDDockWidgets.h"
#include "kddockwidgets/core/Layout.h"

#include <memory>

class TestQtWidgets;
class TestDocks;

Expand Down Expand Up @@ -184,7 +186,27 @@ class DOCKS_EXPORT DropArea : public Layout
class Private;
Private *const d;
};

/// Class to keep a Core::Layout * alive, so restore as floating window works
///
/// DockWidget::show() will try to put the dock widget in its previously known position. That
/// works well for MainWindow, as it keeps its layout Item alive as a placeholder. However,
/// FloatingWindow's are deleted all the time, so we need to store it's item Layout somewhere.
/// We store it inside PreviousFloatingLayout, which takes ownership and is refcounted so we don't leak
/// unneeded layouts.
class PreviousFloatingLayout
{
public:
typedef std::shared_ptr<PreviousFloatingLayout> Ptr;
explicit PreviousFloatingLayout(Core::DropArea *);
~PreviousFloatingLayout();

private:
Core::DropArea *const layout;
};

}

}

#endif
33 changes: 33 additions & 0 deletions src/core/FloatingWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ FloatingWindow::FloatingWindow(Core::Group *group, Rect suggestedGeometry,
FloatingWindow::~FloatingWindow()
{
m_inDtor = true;

/// Keep the Core::Layout around, so DockWidget::show() can still restore to floating
/// and go to the correct layout position
saveLastFloatingLayout();

view()->d->setAboutToBeDestroyed();

if (auto da = dropArea()) {
Expand Down Expand Up @@ -851,3 +856,31 @@ FloatingWindow::Private::Private(FloatingWindowFlags requestedFlags, FloatingWin
, m_dropArea(new DropArea(q->view(), MainWindowOption_None))
{
}

void FloatingWindow::saveLastFloatingLayout()
{
// ~FloatingWindow() is running, but let's keep the Core::Layout alive
// so any dock widget that later is promoted to a FloatingWindow can have the same layout.
if (!d->m_dropArea)
return;

if (!m_deleteScheduled) {
// This is a direct delete of FloatingWindow, not the regular case we're interested in
// where the FloatingWindow is deleted later because it's empty
return;
}

// relinquish ownership:
d->m_dropArea->setParentView(nullptr);

// Give it to all dock widgets so they use it the next time they become floating
auto layout = std::make_shared<PreviousFloatingLayout>(d->m_dropArea);

const auto docks = dockWidgets();
for (auto dock : docks) {
if (dock->inDtor())
continue;

dock->d->m_previousFloatingLayout = layout;
}
}
1 change: 1 addition & 0 deletions src/core/FloatingWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class DOCKS_EXPORT FloatingWindow : public Controller, public Draggable
void onVisibleFrameCountChanged(int count);
void onCloseEvent(CloseEvent *);
void updateSizeConstraints();
void saveLastFloatingLayout();

bool m_disableSetVisible = false;
bool m_deleteScheduled = false;
Expand Down

0 comments on commit 7fba876

Please sign in to comment.