12#include "DropArea_p.h" 
   14#include "DockRegistry_p.h" 
   16#include "DockWidgetBase_p.h" 
   17#include "Draggable_p.h" 
   18#include "DropIndicatorOverlayInterface_p.h" 
   19#include "FloatingWindow_p.h" 
   25#include "multisplitter/Item_p.h" 
   26#include "WindowBeingDragged_p.h" 
   37    : MultiSplitter(parent)
 
   38    , m_isMDIWrapper(isMDIWrapper)
 
   39    , m_dropIndicatorOverlay(
Config::self().frameworkWidgetFactory()->createDropIndicatorOverlay(this))
 
   41    qCDebug(creation) << 
"DropArea";
 
   43#ifdef KDDOCKWIDGETS_QTWIDGETS 
   46        qWarning() << 
"Dropping not implement for QtQuick on Wayland yet!";
 
   51        connect(
this, &MultiSplitter::visibleWidgetCountChanged, 
this, [
this] {
 
   52            auto dw = mdiDockWidgetWrapper();
 
   54                qWarning() << Q_FUNC_INFO << 
"Unexpected null wrapper dock widget";
 
   58            if (visibleCount() > 0) {
 
   60                Q_EMIT dw->titleChanged(dw->title());
 
   71    m_inDestructor = 
true;
 
   72    qCDebug(creation) << 
"~DropArea";
 
   75Frame::List DropArea::frames()
 const 
   80Frame *DropArea::frameContainingPos(
QPoint globalPos)
 const 
   82    const Layouting::Item::List &items = this->items();
 
   83    for (Layouting::Item *item : items) {
 
   84        auto frame = 
static_cast<Frame *
>(item->guestAsQObject());
 
   85        if (!frame || !frame->QWidgetAdapter::isVisible()) {
 
   89        if (frame->containsMouse(globalPos))
 
   95void DropArea::updateFloatingActions()
 
   97    const Frame::List frames = this->frames();
 
   98    for (Frame *frame : frames)
 
   99        frame->updateFloatingActions();
 
  102Layouting::Item *DropArea::centralFrame()
 const 
  104    for (Layouting::Item *item : this->items()) {
 
  105        if (
auto f = 
static_cast<Frame *
>(item->guestAsQObject())) {
 
  106            if (f->isCentralFrame())
 
  117        qWarning() << Q_FUNC_INFO << 
"Invalid parameters" << dw << relativeTo << location;
 
  121    if ((option.
visibility == InitialVisibilityOption::StartHidden) && dw->d->frame() != 
nullptr) {
 
  123        qWarning() << Q_FUNC_INFO << 
"Dock widget already exists in the layout";
 
  127    if (!validateAffinity(dw))
 
  130    Frame *frame = 
nullptr;
 
  131    Frame *relativeToFrame = relativeTo ? relativeTo->d->frame() : 
nullptr;
 
  133    dw->d->saveLastFloatingGeometry();
 
  135    const bool hadSingleFloatingFrame = hasSingleFloatingFrame();
 
  138    if (containsDockWidget(dw)) {
 
  139        Frame *oldFrame = dw->d->frame();
 
  140        if (oldFrame->hasSingleDockWidget()) {
 
  141            Q_ASSERT(oldFrame->containsDockWidget(dw));
 
  146            frame->addWidget(dw);
 
  150        frame->addWidget(dw);
 
  154        addWidget(dw, location, relativeToFrame, option);
 
  156        addWidget(frame, location, relativeToFrame, option);
 
  159    if (hadSingleFloatingFrame && !hasSingleFloatingFrame()) {
 
  162        updateFloatingActions();
 
  168    return dw->d->frame() && LayoutWidget::containsFrame(dw->d->frame());
 
  171bool DropArea::hasSingleFloatingFrame()
 const 
  173    const Frame::List frames = this->frames();
 
  174    return frames.size() == 1 && frames.first()->isFloating();
 
  177bool DropArea::hasSingleFrame()
 const 
  179    return visibleCount() == 1;
 
  184    if (
auto mw = mainWindow()) {
 
  185        return mw->affinities();
 
  186    } 
else if (
auto fw = floatingWindow()) {
 
  187        return fw->affinities();
 
  195    Layouting::Item *item = itemForFrame(dw->d->frame());
 
  197        qWarning() << Q_FUNC_INFO << 
"Item not found for" << dw << dw->d->frame();
 
  201    layoutEqually(item->parentBoxContainer());
 
  206    if (
Config::self().dropIndicatorsInhibited() || !validateAffinity(draggedWindow))
 
  209    if (!m_dropIndicatorOverlay) {
 
  210        qWarning() << Q_FUNC_INFO << 
"The frontend is missing a drop indicator overlay";
 
  214    Frame *frame = frameContainingPos(globalPos); 
 
  215    m_dropIndicatorOverlay->setWindowBeingDragged(
true);
 
  216    m_dropIndicatorOverlay->setHoveredFrame(frame);
 
  217    return m_dropIndicatorOverlay->hover(globalPos);
 
  233bool DropArea::drop(WindowBeingDragged *droppedWindow, 
QPoint globalPos)
 
  235    FloatingWindow *floatingWindow = droppedWindow->floatingWindow();
 
  237    if (floatingWindow == window()) {
 
  238        qWarning() << 
"Refusing to drop onto itself"; 
 
  243        qCDebug(hovering) << 
"DropArea::drop: bailing out, drop location = none";
 
  247    qCDebug(dropping) << 
"DropArea::drop:" << droppedWindow;
 
  249    hover(droppedWindow, globalPos);
 
  250    auto droploc = m_dropIndicatorOverlay->currentDropLocation();
 
  251    Frame *acceptingFrame = m_dropIndicatorOverlay->hoveredFrame();
 
  253        qWarning() << 
"DropArea::drop: asserted with frame=" << acceptingFrame
 
  254                   << 
"; Location=" << droploc;
 
  258    return drop(droppedWindow, acceptingFrame, droploc);
 
  261bool DropArea::drop(WindowBeingDragged *draggedWindow, Frame *acceptingFrame,
 
  264    FloatingWindow *droppedWindow = draggedWindow ? draggedWindow->floatingWindow()
 
  267    if (isWayland() && !droppedWindow) {
 
  273        droppedWindow = draggedWindow ? draggedWindow->draggable()->makeWindow()->floatingWindow()
 
  275        if (!droppedWindow) {
 
  277            qWarning() << Q_FUNC_INFO << 
"Wayland: Expected window" << draggedWindow;
 
  285        ? droppedWindow->layoutWidget()->dockWidgets()
 
  294        result = drop(droppedWindow, DropIndicatorOverlayInterface::multisplitterLocationFor(droploc), acceptingFrame);
 
  300        result = drop(droppedWindow, DropIndicatorOverlayInterface::multisplitterLocationFor(droploc), 
nullptr);
 
  303        qCDebug(hovering) << 
"Tabbing" << droppedWindow << 
"into" << acceptingFrame;
 
  304        if (!validateAffinity(droppedWindow, acceptingFrame))
 
  306        acceptingFrame->addWidget(droppedWindow);
 
  310        qWarning() << 
"DropArea::drop: Unexpected drop location" << m_dropIndicatorOverlay->currentDropLocation();
 
  320        const bool isEGLFSRootWindow = isEGLFS() && (window()->isFullScreen() || window()->isMaximized());
 
  321        if (!isEGLFSRootWindow)
 
  324        if (needToFocusNewlyDroppedWidgets) {
 
  326            if (!droppedDockWidgets.
isEmpty()) {
 
  328                Frame *frame = droppedDockWidgets.
first()->d->frame();
 
  332                qWarning() << Q_FUNC_INFO << 
"Nothing was dropped?";
 
  342    qCDebug(docking) << 
"DropArea::addFrame";
 
  344    if (
auto dock = qobject_cast<DockWidgetBase *>(droppedWindow)) {
 
  345        if (!validateAffinity(dock))
 
  349        frame->addWidget(dock);
 
  350        addWidget(frame, location, relativeTo, DefaultSizeMode::FairButFloor);
 
  351    } 
else if (
auto floatingWindow = qobject_cast<FloatingWindow *>(droppedWindow)) {
 
  352        if (!validateAffinity(floatingWindow))
 
  355        const bool hadSingleFloatingFrame = hasSingleFloatingFrame();
 
  356        addMultiSplitter(floatingWindow->dropArea(), location, relativeTo,
 
  357                         DefaultSizeMode::FairButFloor);
 
  358        if (hadSingleFloatingFrame != hasSingleFloatingFrame())
 
  359            updateFloatingActions();
 
  361        floatingWindow->scheduleDeleteLater();
 
  364        qWarning() << 
"Unknown dropped widget" << droppedWindow;
 
  371void DropArea::removeHover()
 
  373    m_dropIndicatorOverlay->removeHover();
 
  377bool DropArea::validateAffinity(T *window, Frame *acceptingFrame)
 const 
  379    if (!DockRegistry::self()->affinitiesMatch(window->affinities(), affinities())) {
 
  383    if (acceptingFrame) {
 
  386        if (!DockRegistry::self()->affinitiesMatch(window->affinities(), acceptingFrame->affinities())) {
 
  394bool DropArea::isMDIWrapper()
 const 
  396    return m_isMDIWrapper;
 
  402        return qobject_cast<DockWidgetBase *>(QWidgetAdapter::parent());
 
Application-wide config to tune certain behaviours of the framework.
static bool isOutterLocation(DropLocation location)
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
bool isEmpty() const const