Skip to content

Commit

Permalink
WIP: Restore previous DropArea when creating a new FloatingWindow
Browse files Browse the repository at this point in the history
The idea works in theory, code is done, now just debugging is needed
as there's some weird results still

For issue #513
  • Loading branch information
iamsergio committed Jul 20, 2024
1 parent bafe1f8 commit f7b38e0
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/LayoutSaver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ bool LayoutSaver::restoreLayout(const QByteArray &data)
flags.setFlag(FloatingWindowFlag::StartsMinimized, int(fw.windowState) & int(WindowState::Minimized));

auto floatingWindow =
new Core::FloatingWindow({}, parent, flags);
new Core::FloatingWindow({}, nullptr, parent, flags);
fw.floatingWindowInstance = floatingWindow;
d->deserializeWindowGeometry(fw, floatingWindow->view()->window());
if (!floatingWindow->deserialize(fw)) {
Expand Down
3 changes: 2 additions & 1 deletion src/core/DockWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,8 @@ Core::FloatingWindow *DockWidget::Private::morphIntoFloatingWindow()
geo.setSize(geo.size().boundedTo(group->view()->maxSizeHint()));
geo.setSize(geo.size().expandedTo(group->view()->minSize()));
Core::FloatingWindow::ensureRectIsOnScreen(geo);
auto floatingWindow = new Core::FloatingWindow(group, geo);
auto floatingWindow = m_previousFloatingLayout ? FloatingWindow::fromExistingDropArea(group, geo, m_previousFloatingLayout->layout)
: new Core::FloatingWindow(group, geo, nullptr);

Core::AtomicSanityChecks checks(floatingWindow->dropArea()->rootItem());
floatingWindow->view()->show();
Expand Down
3 changes: 1 addition & 2 deletions src/core/DropArea.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ class PreviousFloatingLayout
explicit PreviousFloatingLayout(Core::DropArea *);
~PreviousFloatingLayout();

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

}
Expand Down
38 changes: 31 additions & 7 deletions src/core/FloatingWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ MainWindow *actualParent(MainWindow *candidate)
: candidate;
}

FloatingWindow::FloatingWindow(Rect suggestedGeometry, MainWindow *parent,
FloatingWindow::FloatingWindow(Rect suggestedGeometry, DropArea *dropAreaToReuse, MainWindow *parent,
FloatingWindowFlags requestedFlags)
: Controller(ViewType::FloatingWindow,
Config::self().viewFactory()->createFloatingWindow(
Expand All @@ -151,7 +151,7 @@ FloatingWindow::FloatingWindow(Rect suggestedGeometry, MainWindow *parent,
// Otherwise the
// KDDockWidgets::TitleBar is the
// draggable
, d(new Private(requestedFlags, this))
, d(new Private(requestedFlags, this, dropAreaToReuse))
, m_titleBar(new Core::TitleBar(this))
{
view()->init();
Expand Down Expand Up @@ -205,8 +205,8 @@ FloatingWindow::FloatingWindow(Rect suggestedGeometry, MainWindow *parent,
}

FloatingWindow::FloatingWindow(Core::Group *group, Rect suggestedGeometry,
MainWindow *parent)
: FloatingWindow({}, hackFindParentHarder(group, parent), floatingWindowFlagsForGroup(group))
DropArea *dropAreaToReuse, MainWindow *parent)
: FloatingWindow({}, dropAreaToReuse, hackFindParentHarder(group, parent), floatingWindowFlagsForGroup(group))
{
ScopedValueRollback guard(m_disableSetVisible, true);

Expand Down Expand Up @@ -264,6 +264,27 @@ FloatingWindow::FloatingWindow(Core::Group *group, Rect suggestedGeometry,
view()->setGeometry(suggestedGeometry);
}

/** static */
FloatingWindow *FloatingWindow::fromExistingDropArea(Core::Group *group, Rect suggestedGeometry,
DropArea *dropArea,
MainWindow *parent)
{
assert(dropArea);

// We're reusing a DropArea, transfer ownership to the new FloatingWindow.
// DockWidget's m_lastPositions has references to Core::Item* inside this DropArea, DockWidget
// no longer needs to keep the unused DropArea alive as it's now owned by FloatingWindow.
const auto allDockWidgets = DockRegistry::self()->dockwidgets();
for (Core::DockWidget *dw : allDockWidgets) {
if (dw->d->m_previousFloatingLayout && dw->d->m_previousFloatingLayout->layout == dropArea) {
dw->d->m_previousFloatingLayout->layout = nullptr;
dw->d->m_previousFloatingLayout = {};
}
}

return new FloatingWindow(group, suggestedGeometry, dropArea, parent);
}

FloatingWindow::~FloatingWindow()
{
m_inDtor = true;
Expand Down Expand Up @@ -394,6 +415,7 @@ void FloatingWindow::setSuggestedGeometry(Rect suggestedRect, SuggestedGeometryH
void FloatingWindow::scheduleDeleteLater()
{
m_deleteScheduled = true;

view()->d->setAboutToBeDestroyed();
DockRegistry::self()->unregisterFloatingWindow(this);
destroyLater();
Expand Down Expand Up @@ -851,10 +873,12 @@ inline FloatingWindowFlags flagsForFloatingWindow(FloatingWindowFlags requestedF
return flags;
}

FloatingWindow::Private::Private(FloatingWindowFlags requestedFlags, FloatingWindow *q)
FloatingWindow::Private::Private(FloatingWindowFlags requestedFlags, FloatingWindow *q, DropArea *dropAreaToReuse)
: m_flags(flagsForFloatingWindow(requestedFlags))
, m_dropArea(new DropArea(q->view(), MainWindowOption_None))
, m_dropArea(dropAreaToReuse ? dropAreaToReuse : new DropArea(q->view(), MainWindowOption_None))
{
if (dropAreaToReuse)
dropAreaToReuse->setParentView(q->view());
}

void FloatingWindow::saveLastFloatingLayout()
Expand All @@ -876,7 +900,7 @@ void FloatingWindow::saveLastFloatingLayout()
// 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();
const auto docks = DockRegistry::self()->dockwidgetsReferencedByDropArea(d->m_dropArea);
for (auto dock : docks) {
if (dock->inDtor())
continue;
Expand Down
9 changes: 8 additions & 1 deletion src/core/FloatingWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,17 @@ class DOCKS_EXPORT FloatingWindow : public Controller, public Draggable
Q_OBJECT
public:
explicit FloatingWindow(
Rect suggestedGeometry, MainWindow *parent = nullptr,
Rect suggestedGeometry, DropArea *dropAreaToReuse, MainWindow *parent = nullptr,
FloatingWindowFlags requestedFlags = FloatingWindowFlag::FromGlobalConfig);

explicit FloatingWindow(Core::Group *group, Rect suggestedGeometry,
DropArea *dropAreaToReuse = nullptr,
MainWindow *parent = nullptr);

static FloatingWindow *fromExistingDropArea(Core::Group *group, Rect suggestedGeometry,
DropArea *dropAreaToReuse,
MainWindow *parent = nullptr);

virtual ~FloatingWindow() override;

bool deserialize(const LayoutSaver::FloatingWindow &);
Expand Down
2 changes: 1 addition & 1 deletion src/core/FloatingWindow_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace Core {
class FloatingWindow::Private
{
public:
explicit Private(FloatingWindowFlags requestedFlags, FloatingWindow *q);
explicit Private(FloatingWindowFlags requestedFlags, FloatingWindow *q, DropArea *dropAreaToReuse);

KDBindings::Signal<> activatedChanged;
KDBindings::Signal<> numGroupsChanged;
Expand Down

0 comments on commit f7b38e0

Please sign in to comment.