18#include "core/Draggable_p.h"
19#include "core/Logging_p.h"
20#include "core/Utils_p.h"
21#include "core/layouting/Item_p.h"
22#include "core/layouting/LayoutingGuest_p.h"
23#include "core/layouting/LayoutingSeparator_p.h"
24#include "core/WindowBeingDragged_p.h"
25#include "core/DelayedCall_p.h"
28#include "core/DockWidget_p.h"
60class DropArea::Private
70 bool m_inDestructor =
false;
71 const bool m_isMDIWrapper;
73 ObjectGuard<DropIndicatorOverlay> m_dropIndicatorOverlay;
75 Core::ItemBoxContainer *m_rootItem =
nullptr;
84 , d(new Private(this, options, isMDIWrapper))
95 KDDW_TRACE(
"DropArea CTOR");
97 if (d->m_isMDIWrapper) {
98 d->m_visibleWidgetCountConnection =
Layout::d_ptr()->visibleWidgetCountChanged.connect([
this] {
101 KDDW_ERROR(
"Unexpected null wrapper dock widget");
108 dw->d->titleChanged.emit(dw->title());
116 if (d->m_centralFrame)
122 d->m_inDestructor =
true;
123 delete d->m_dropIndicatorOverlay;
125 KDDW_TRACE(
"~DropArea");
130 const Core::Item::List children = d->m_rootItem->items_recursive();
133 for (
const Core::Item *child : children) {
134 if (
auto guest = child->guest()) {
135 if (!guest->freed()) {
146Core::Group *DropArea::groupContainingPos(Point globalPos)
const
148 const Core::Item::List &
items = this->
items();
149 for (Core::Item *item :
items) {
151 if (!group || !group->isVisible()) {
155 if (group->containsMouse(globalPos))
161void DropArea::updateFloatingActions()
165 group->updateFloatingActions();
171 for (Core::Item *item :
items) {
173 if (group->isCentralFrame())
182 return d->m_dropIndicatorOverlay;
189 KDDW_ERROR(
"Invalid parameters {}, {} {}", (
void * )dw, (
void * )relativeTo, location);
195 KDDW_ERROR(
"Dock widget already exists in the layout");
199 if (!validateAffinity(dw))
202 Core::DockWidget::Private::UpdateActions actionsUpdater(dw);
205 Core::Group *relativeToFrame = relativeTo ? relativeTo->
d->group() :
nullptr;
207 dw->
d->saveLastFloatingGeometry();
237 updateFloatingActions();
249 return groups.
size() == 1 &&
groups.first()->isFloating();
260 return mw->affinities();
262 return fw->affinities();
272 KDDW_ERROR(
"Item not found for dw={}, group={}", (
void * )dw, (
void * )dw->
d->group());
281 if (
Config::self().dropIndicatorsInhibited() || !validateAffinity(draggedWindow))
284 if (!d->m_dropIndicatorOverlay) {
285 KDDW_ERROR(
"The frontend is missing a drop indicator overlay");
291 d->m_dropIndicatorOverlay->setWindowBeingDragged(
true);
292 d->m_dropIndicatorOverlay->setHoveredGroup(group);
293 draggedWindow->updateTransparency(
true);
295 return d->m_dropIndicatorOverlay->hover(globalPos);
314 Core::View *fv = droppedWindow->floatingWindowView();
317 KDDW_ERROR(
"Refusing to drop onto itself");
322 KDDW_DEBUG(
"DropArea::drop: bailing out, drop location = none");
326 KDDW_DEBUG(
"DropArea::drop: {}", (
void * )droppedWindow);
328 hover(droppedWindow, globalPos);
329 auto droploc = d->m_dropIndicatorOverlay->currentDropLocation();
330 Core::Group *acceptingGroup = d->m_dropIndicatorOverlay->hoveredGroup();
332 KDDW_ERROR(
"DropArea::drop: asserted with group={}, location={}", (
void * )acceptingGroup, droploc);
336 return drop(droppedWindow, acceptingGroup, droploc);
343 draggedWindow ? draggedWindow->floatingWindow() :
nullptr;
345 if (isWayland() && !droppedWindow) {
352 draggedWindow ? draggedWindow->draggable()->
makeWindow()->floatingWindow() :
nullptr;
353 if (!droppedWindow) {
355 KDDW_ERROR(
"Wayland: Expected window {}", (
void * )draggedWindow);
361 const bool needToFocusNewlyDroppedWidgets =
374 result =
drop(droppedWindow->
view(),
381 result =
drop(droppedWindow->
view(),
385 KDDW_DEBUG(
"Tabbing window={} into group={}", (
void * )droppedWindow, (
void * )acceptingGroup);
387 if (!validateAffinity(droppedWindow, acceptingGroup))
389 acceptingGroup->
addTab(droppedWindow);
393 KDDW_ERROR(
"DropArea::drop: Unexpected drop location = {}", d->m_dropIndicatorOverlay->currentDropLocation());
404 const bool isEGLFSRootWindow =
406 if (!isEGLFSRootWindow)
409 if (needToFocusNewlyDroppedWidgets) {
411 if (!droppedDockWidgets.
isEmpty()) {
417 KDDW_ERROR(
"Nothing was dropped?");
428 KDDW_DEBUG(
"DropArea::addFrame");
431 if (!validateAffinity(dock))
447 KDDW_ERROR(
"Unknown dropped widget {}", (
void * )droppedWindow);
456 d->m_dropIndicatorOverlay->removeHover();
460bool DropArea::validateAffinity(T *window,
Core::Group *acceptingGroup)
const
466 if (acceptingGroup) {
480 return d->m_isMDIWrapper;
485 if (d->m_isMDIWrapper) {
498 const bool hasPersistentCentralWidget =
500 if (hasPersistentCentralWidget) {
508 group->setObjectName(QStringLiteral(
"central group"));
515bool DropArea::validateInputs(
View *widget,
Location location,
519 KDDW_ERROR(
"Widget is null");
528 KDDW_ERROR(
"Unknown widget type {}", (
void * )widget);
532 if (isDockWidget != isStartHidden) {
533 KDDW_ERROR(
"Wrong parameters isDockWidget={}, isStartHidden={}", isDockWidget, isStartHidden);
537 if (relativeToFrame && relativeToFrame->
view()->
equals(widget)) {
538 KDDW_ERROR(
"widget can't be relative to itself");
545 KDDW_ERROR(
"DropArea::addWidget: Already contains w={}", (
void * )widget);
550 KDDW_ERROR(
"DropArea::addWidget: not adding to location None");
554 const bool relativeToThis = relativeToFrame ==
nullptr;
556 Core::Item *relativeToItem =
itemForFrame(relativeToFrame);
558 KDDW_ERROR(
"DropArea::addWidget: Doesn't contain relativeTo: relativeToGroup={}, relativeToItem{}, options={}", (
void * )relativeToFrame,
"; relativeToItem=", (
void * )relativeToItem, option);
575 group->setLayoutItem(
nullptr);
579 if (!validateInputs(w, location, relativeToWidget, option))
582 Core::Item *relativeTo =
itemForFrame(relativeToWidget);
584 relativeTo = d->m_rootItem;
586 Core::Item *newItem =
nullptr;
594 newItem->setGuest(group->asLayoutingGuest());
598 newItem->setGuest(group->asLayoutingGuest());
599 group->addTab(dw, option);
601 newItem = ms->d->m_rootItem;
604 if (
auto fw = ms->floatingWindow()) {
605 newItem->setSize_recursive(fw->size());
612 KDDW_ERROR(
"Unknown widget added", (
void * )w);
616 assert(!newItem->geometry().isEmpty());
617 Core::ItemBoxContainer::insertItemRelativeTo(newItem, relativeTo, location, option);
626 KDDW_DEBUG(
"DropArea::addMultiSplitter: {} {} {}", (
void * )sourceMultiSplitter, (
int )location, (
void * )relativeTo);
627 addWidget(sourceMultiSplitter->
view(), location, relativeTo, option);
630 updateFloatingActions();
635 return d->m_rootItem->separators_recursive();
638int DropArea::availableLengthForOrientation(
Qt::Orientation orientation)
const
641 return availableSize().height();
643 return availableSize().width();
646Size DropArea::availableSize()
const
648 return d->m_rootItem->availableSize();
664 container->layoutEqually_recursive();
666 KDDW_ERROR(
"null container");
670void DropArea::setRootItem(Core::ItemBoxContainer *root)
673 d->m_rootItem = root;
678 return d->m_rootItem;
682 const Core::Item *relativeTo)
const
684 Core::Item item(
nullptr);
688 item.setSize(wbd->size().boundedTo(wbd->maxSize()));
689 item.setMinSize(wbd->minSize());
690 item.setMaxSizeHint(wbd->maxSize());
692 Core::ItemBoxContainer *container =
693 relativeTo ? relativeTo->parentBoxContainer() : d->m_rootItem;
695 return container->suggestedDropRect(&item, relativeTo, location);
706 return d->m_rootItem->numSideBySide_recursive(o);
711 return d->m_dropIndicatorOverlay ? d->m_dropIndicatorOverlay->currentDropLocation() :
DropLocation_None;
716 return d->m_centralFrame;
Application-wide config to tune certain behaviours of the framework.
A ScopedConnection is a RAII-style way to make sure a Connection is disconnected.
static bool isOutterLocation(DropLocation location)
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.