tdf#126560 Qt5 fix D'n'D key-modifier handling

The patch has still one problem: the key-modifier state isn't
reflected by the cursor, unless the user moves the mouse. There is
an upstream Qt bug, reported in 2016-09 against Qt 5.6.1! It is
supposed to be fixed in Qt 5.12, according to the bug report at
https://bugreports.qt.io/browse/QTBUG-56218, which is still open.

I thought about adding a configure test, but I couldn't imagine
any realistic way to write it. And after Michael Weghorn found the
bug is actually not fixed, as claimed in one of the comments, I
decided to drop the warning.

Change-Id: Ice8ebc4ea149282b4c1551e755efe3d4856cf782
Reviewed-on: https://gerrit.libreoffice.org/77174
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
(cherry picked from commit 3355be0616c24c5e44b71e7623c4191ed9c69074)
Reviewed-on: https://gerrit.libreoffice.org/77956
diff --git a/vcl/inc/qt5/Qt5DragAndDrop.hxx b/vcl/inc/qt5/Qt5DragAndDrop.hxx
index dcd6cb5..0ec9ce5 100644
--- a/vcl/inc/qt5/Qt5DragAndDrop.hxx
+++ b/vcl/inc/qt5/Qt5DragAndDrop.hxx
@@ -25,7 +25,6 @@ class Qt5DragSource
    osl::Mutex m_aMutex;
    Qt5Frame* m_pFrame;
    css::uno::Reference<css::datatransfer::dnd::XDragSourceListener> m_xListener;
    css::uno::Reference<css::datatransfer::XTransferable> m_xTrans;

public:
    Qt5DragSource()
@@ -55,17 +54,7 @@ public:

    css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;

    void dragFailed();
    void fire_dragEnd(sal_Int8 nAction);

    static Qt5DragSource* m_ActiveDragSource;
    static bool m_bDropSuccessSet;
    static bool m_bDropSuccess;

    css::uno::Reference<css::datatransfer::XTransferable> const& GetTransferable() const
    {
        return m_xTrans;
    }
    void fire_dragEnd(sal_Int8 nAction, bool bSuccessful);
};

class Qt5DropTarget
@@ -76,11 +65,11 @@ class Qt5DropTarget
{
    osl::Mutex m_aMutex;
    Qt5Frame* m_pFrame;
    sal_Int8 mnDragAction;
    sal_Int8 mnDropAction;
    sal_Int8 m_nDropAction;
    bool m_bActive;
    sal_Int8 m_nDefaultActions;
    std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> m_aListeners;
    bool m_bDropSuccessful;

public:
    Qt5DropTarget();
@@ -115,10 +104,12 @@ public:
    css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;

    void fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde);
    void fire_dragExit(const css::datatransfer::dnd::DropTargetEvent& dte);
    void fire_dragOver(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde);
    void fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde);

    sal_Int8 proposedDragAction() const { return mnDragAction; }
    sal_Int8 proposedDropAction() const { return m_nDropAction; }
    bool dropSuccessful() const { return m_bDropSuccessful; }
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index 4c94b84..e296ce9 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -56,6 +56,8 @@ class Qt5MainWindow;
class Qt5Menu;
class Qt5SvpGraphics;

class QDragMoveEvent;
class QDropEvent;
class QImage;
class QMimeData;
class QPaintDevice;
@@ -159,10 +161,10 @@ public:
    virtual void deregisterDragSource(Qt5DragSource const* pDragSource);
    virtual void registerDropTarget(Qt5DropTarget* pDropTarget);
    virtual void deregisterDropTarget(Qt5DropTarget const* pDropTarget);
    void draggingStarted(const int x, const int y, Qt::DropActions eActions,
                         Qt::KeyboardModifiers eKeyMod, const QMimeData* pQMimeData);
    void dropping(const int x, const int y, Qt::KeyboardModifiers eKeyMod,
                  const QMimeData* pQMimeData);

    void handleDragLeave();
    void handleDragMove(QDragMoveEvent* pEvent);
    void handleDrop(QDropEvent* pEvent);

    virtual void SetExtendedFrameStyle(SalExtStyle nExtStyle) override;
    virtual void Show(bool bVisible, bool bNoActivate = false) override;
diff --git a/vcl/inc/qt5/Qt5Tools.hxx b/vcl/inc/qt5/Qt5Tools.hxx
index 6b1fb1ad..697b703 100644
--- a/vcl/inc/qt5/Qt5Tools.hxx
+++ b/vcl/inc/qt5/Qt5Tools.hxx
@@ -70,6 +70,7 @@ inline QColor toQColor(const Color& rColor)

Qt::DropActions toQtDropActions(sal_Int8 dragOperation);
sal_Int8 toVclDropActions(Qt::DropActions dragOperation);
sal_Int8 toVclDropAction(Qt::DropAction dragOperation);
Qt::DropAction getPreferredDropAction(sal_Int8 dragOperation);

inline QList<int> toQList(const css::uno::Sequence<sal_Int32>& aSequence)
@@ -126,8 +127,6 @@ inline sal_uInt16 getFormatBits(QImage::Format eFormat)
    }
}

static const QString sInternalMimeType = "application/x-libreoffice-dnditem";

typedef struct _cairo_surface cairo_surface_t;
struct CairoDeleter
{
diff --git a/vcl/inc/qt5/Qt5Transferable.hxx b/vcl/inc/qt5/Qt5Transferable.hxx
index f36216e..491ad81 100644
--- a/vcl/inc/qt5/Qt5Transferable.hxx
+++ b/vcl/inc/qt5/Qt5Transferable.hxx
@@ -117,6 +117,8 @@ public:
    QStringList formats() const override;

    bool deepCopy(QMimeData** const) const;

    css::datatransfer::XTransferable* xTransferable() const { return m_aContents.get(); }
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/Qt5Widget.hxx b/vcl/inc/qt5/Qt5Widget.hxx
index 8552395..a69c868 100644
--- a/vcl/inc/qt5/Qt5Widget.hxx
+++ b/vcl/inc/qt5/Qt5Widget.hxx
@@ -57,6 +57,7 @@ class Qt5Widget : public QWidget
    virtual void mousePressEvent(QMouseEvent*) override;
    virtual void mouseReleaseEvent(QMouseEvent*) override;
    virtual void dragEnterEvent(QDragEnterEvent*) override;
    virtual void dragLeaveEvent(QDragLeaveEvent*) override;
    virtual void dragMoveEvent(QDragMoveEvent*) override;
    virtual void dropEvent(QDropEvent*) override;
    virtual void moveEvent(QMoveEvent*) override;
@@ -74,7 +75,6 @@ public:
    Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f = Qt::WindowFlags());

    Qt5Frame& getFrame() const { return m_rFrame; }
    void startDrag(sal_Int8 nSourceActions);
    void endExtTextInput();

    static bool handleEvent(Qt5Frame&, const QWidget&, QEvent*);
diff --git a/vcl/qt5/Qt5DragAndDrop.cxx b/vcl/qt5/Qt5DragAndDrop.cxx
index 118939c..af163b2 100644
--- a/vcl/qt5/Qt5DragAndDrop.cxx
+++ b/vcl/qt5/Qt5DragAndDrop.cxx
@@ -16,13 +16,12 @@

#include <Qt5DragAndDrop.hxx>
#include <Qt5Frame.hxx>
#include <Qt5Transferable.hxx>
#include <Qt5Widget.hxx>

using namespace com::sun::star;
#include <QtGui/QDrag>

bool Qt5DragSource::m_bDropSuccessSet = false;
bool Qt5DragSource::m_bDropSuccess = false;
Qt5DragSource* Qt5DragSource::m_ActiveDragSource = nullptr;
using namespace com::sun::star;

Qt5DragSource::~Qt5DragSource() {}

@@ -60,52 +59,35 @@ void Qt5DragSource::startDrag(
    const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener)
{
    m_xListener = rListener;
    m_xTrans = rTrans;

    if (m_pFrame)
    {
        Qt5Widget* qw = static_cast<Qt5Widget*>(m_pFrame->GetQWidget());
        m_ActiveDragSource = this;
        m_bDropSuccessSet = false;
        m_bDropSuccess = false;
        qw->startDrag(sourceActions);
        QDrag* drag = new QDrag(m_pFrame->GetQWidget());
        drag->setMimeData(new Qt5MimeData(rTrans));
        // just a reminder that exec starts a nested event loop, so everything after
        // this call is just executed, after D'n'D has finished!
        drag->exec(toQtDropActions(sourceActions), getPreferredDropAction(sourceActions));
    }
    else
        dragFailed();

    // the drop will eventually call fire_dragEnd, which will clear the listener.
    // if D'n'D ends without success, we just get a leave event without any indicator,
    // but the event loop will be terminated, so we have to try to inform the source of
    // a failure in any way.
    fire_dragEnd(datatransfer::dnd::DNDConstants::ACTION_NONE, false);
}

void Qt5DragSource::dragFailed()
{
    if (m_xListener.is())
    {
        datatransfer::dnd::DragSourceDropEvent aEv;
        aEv.DropAction = datatransfer::dnd::DNDConstants::ACTION_NONE;
        aEv.DropSuccess = false;
        auto xListener = m_xListener;
        m_xListener.clear();
        xListener->dragDropEnd(aEv);
    }
}

void Qt5DragSource::fire_dragEnd(sal_Int8 nAction)
void Qt5DragSource::fire_dragEnd(sal_Int8 nAction, bool bDropSuccessful)
{
    if (m_xListener.is())
    {
        datatransfer::dnd::DragSourceDropEvent aEv;
        aEv.DropAction = nAction;

        // internal DnD can accept the drop
        // but still fail in Qt5DropTarget::dropComplete
        if (m_bDropSuccessSet)
            aEv.DropSuccess = m_bDropSuccess;
        else
            aEv.DropSuccess = true;
        aEv.DropSuccess = bDropSuccessful;

        auto xListener = m_xListener;
        m_xListener.clear();
        xListener->dragDropEnd(aEv);
    }
    m_ActiveDragSource = nullptr;
}

OUString SAL_CALL Qt5DragSource::getImplementationName()
@@ -177,8 +159,7 @@ void Qt5DropTarget::initialize(const uno::Sequence<uno::Any>& rArguments)
                                    static_cast<OWeakObject*>(this));
    }

    mnDragAction = datatransfer::dnd::DNDConstants::ACTION_NONE;
    mnDropAction = datatransfer::dnd::DNDConstants::ACTION_NONE;
    m_nDropAction = datatransfer::dnd::DNDConstants::ACTION_NONE;

    m_pFrame = reinterpret_cast<Qt5Frame*>(nFrame);
    m_pFrame->registerDropTarget(this);
@@ -241,6 +222,8 @@ void Qt5DropTarget::fire_dragOver(const css::datatransfer::dnd::DropTargetDragEn

void Qt5DropTarget::fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde)
{
    m_bDropSuccessful = true;

    osl::ClearableGuard<osl::Mutex> aGuard(m_aMutex);
    std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
        m_aListeners);
@@ -252,40 +235,28 @@ void Qt5DropTarget::fire_drop(const css::datatransfer::dnd::DropTargetDropEvent&
    }
}

void Qt5DropTarget::acceptDrag(sal_Int8 dragOperation)
void Qt5DropTarget::fire_dragExit(const css::datatransfer::dnd::DropTargetEvent& dte)
{
    mnDragAction = dragOperation;
    return;
    osl::ClearableGuard<::osl::Mutex> aGuard(m_aMutex);
    std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
        m_aListeners);
    aGuard.clear();

    for (auto const& listener : aListeners)
        listener->dragExit(dte);
}

void Qt5DropTarget::rejectDrag()
{
    mnDragAction = 0;
    return;
}
void Qt5DropTarget::acceptDrag(sal_Int8 dragOperation) { m_nDropAction = dragOperation; }

void Qt5DropTarget::acceptDrop(sal_Int8 dropOperation)
{
    mnDropAction = dropOperation;
    return;
}
void Qt5DropTarget::rejectDrag() { m_nDropAction = 0; }

void Qt5DropTarget::rejectDrop()
{
    mnDropAction = 0;
    return;
}
void Qt5DropTarget::acceptDrop(sal_Int8 dropOperation) { m_nDropAction = dropOperation; }

void Qt5DropTarget::rejectDrop() { m_nDropAction = 0; }

void Qt5DropTarget::dropComplete(sal_Bool success)
{
    // internal DnD
    if (Qt5DragSource::m_ActiveDragSource)
    {
        Qt5DragSource::m_bDropSuccessSet = true;
        Qt5DragSource::m_bDropSuccess = success;
    }

    return;
    m_bDropSuccessful = (m_bDropSuccessful && success);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index a02600b..9b86ee7 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -36,6 +36,8 @@
#include <QtCore/QPoint>
#include <QtCore/QSize>
#include <QtCore/QThread>
#include <QtGui/QDragMoveEvent>
#include <QtGui/QDropEvent>
#include <QtGui/QIcon>
#include <QtGui/QWindow>
#include <QtGui/QScreen>
@@ -1187,84 +1189,145 @@ void Qt5Frame::deregisterDropTarget(Qt5DropTarget const* pDropTarget)
    m_pDropTarget = nullptr;
}

void Qt5Frame::draggingStarted(const int x, const int y, Qt::DropActions eActions,
                               Qt::KeyboardModifiers eKeyMod, const QMimeData* pQMimeData)
static css::uno::Reference<css::datatransfer::XTransferable>
lcl_getXTransferable(const QMimeData* pMimeData)
{
    assert(m_pDropTarget);
    css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
    const Qt5MimeData* pQt5MimeData = dynamic_cast<const Qt5MimeData*>(pMimeData);
    if (!pQt5MimeData)
        xTransferable = new Qt5DnDTransferable(pMimeData);
    else
        xTransferable = pQt5MimeData->xTransferable();
    return xTransferable;
}

    sal_Int8 nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
static sal_Int8 lcl_getUserDropAction(const QDropEvent* pEvent, const sal_Int8 nSourceActions,
                                      const QMimeData* pMimeData)
{
    // we completely ignore all proposals by the Qt event, as they don't
    // match at all with the preferred LO DnD actions.
    const sal_Int8 nFilterActions
        = nSourceActions | css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;

    // check the key modifiers to detect a user-overridden DnD action
    const Qt::KeyboardModifiers eKeyMod = pEvent->keyboardModifiers();
    sal_Int8 nUserDropAction = 0;
    if ((eKeyMod & Qt::ShiftModifier) && !(eKeyMod & Qt::ControlModifier))
        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
    else if ((eKeyMod & Qt::ControlModifier) && !(eKeyMod & Qt::ShiftModifier))
        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_COPY;
    else if ((eKeyMod & Qt::ShiftModifier) && (eKeyMod & Qt::ControlModifier))
        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_LINK;
    nUserDropAction &= nFilterActions;

    // select the default DnD action, if there isn't a user preference
    if (0 == nUserDropAction)
    {
        // default LO internal action is move, but default external action is copy
        nUserDropAction = dynamic_cast<const Qt5MimeData*>(pMimeData)
                              ? css::datatransfer::dnd::DNDConstants::ACTION_MOVE
                              : css::datatransfer::dnd::DNDConstants::ACTION_COPY;
        nUserDropAction &= nFilterActions;

        // if the default doesn't match any allowed source action, fall back to the
        // preferred of all allowed source actions
        if (0 == nUserDropAction)
            nUserDropAction = toVclDropAction(getPreferredDropAction(nSourceActions));

        // this is "our" preference, but actually we would even prefer any default,
        // if there is any
        nUserDropAction |= css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
    }
    return nUserDropAction;
}

void Qt5Frame::handleDragMove(QDragMoveEvent* pEvent)
{
    assert(m_pDropTarget);

    // prepare our suggested drop action for the drop target
    const sal_Int8 nSourceActions = toVclDropActions(pEvent->possibleActions());
    const QMimeData* pMimeData = pEvent->mimeData();
    const sal_Int8 nUserDropAction = lcl_getUserDropAction(pEvent, nSourceActions, pMimeData);

    css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
    aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDragContext*>(m_pDropTarget);
    aEvent.LocationX = x;
    aEvent.LocationY = y;
    aEvent.LocationX = pEvent->pos().x();
    aEvent.LocationY = pEvent->pos().y();
    aEvent.DropAction = nUserDropAction;
    aEvent.SourceActions = nSourceActions;

    // system drop action if neither Shift nor Control is held
    if (!(eKeyMod & (Qt::ShiftModifier | Qt::ControlModifier)))
        aEvent.DropAction = getPreferredDropAction(eActions);
    // otherwise user-preferred action
    else
        aEvent.DropAction = nUserDropAction;
    aEvent.SourceActions = toVclDropActions(eActions);

    css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
    if (!pQMimeData->hasFormat(sInternalMimeType))
        xTransferable = new Qt5DnDTransferable(pQMimeData);
    else
        xTransferable = Qt5DragSource::m_ActiveDragSource->GetTransferable();

    if (!m_bInDrag && xTransferable.is())
    // ask the drop target to accept our drop action
    if (!m_bInDrag)
    {
        css::uno::Sequence<css::datatransfer::DataFlavor> aFormats
            = xTransferable->getTransferDataFlavors();
        aEvent.SupportedDataFlavors = aFormats;

        aEvent.SupportedDataFlavors = lcl_getXTransferable(pMimeData)->getTransferDataFlavors();
        m_pDropTarget->fire_dragEnter(aEvent);
        m_bInDrag = true;
    }
    else
        m_pDropTarget->fire_dragOver(aEvent);

    // the drop target accepted our drop action => inform Qt
    if (m_pDropTarget->proposedDropAction() != 0)
    {
        pEvent->setDropAction(getPreferredDropAction(m_pDropTarget->proposedDropAction()));
        pEvent->accept();
    }
    else // or maybe someone else likes it?
        pEvent->ignore();
}

void Qt5Frame::dropping(const int x, const int y, Qt::KeyboardModifiers eKeyMod,
                        const QMimeData* pQMimeData)
void Qt5Frame::handleDrop(QDropEvent* pEvent)
{
    assert(m_pDropTarget);

    // prepare our suggested drop action for the drop target
    const sal_Int8 nSourceActions = toVclDropActions(pEvent->possibleActions());
    const sal_Int8 nUserDropAction
        = lcl_getUserDropAction(pEvent, nSourceActions, pEvent->mimeData());

    css::datatransfer::dnd::DropTargetDropEvent aEvent;
    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
    aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDropContext*>(m_pDropTarget);
    aEvent.LocationX = x;
    aEvent.LocationY = y;
    aEvent.LocationX = pEvent->pos().x();
    aEvent.LocationY = pEvent->pos().y();
    aEvent.SourceActions = nSourceActions;
    aEvent.DropAction = nUserDropAction;
    aEvent.Transferable = lcl_getXTransferable(pEvent->mimeData());

    if (!(eKeyMod & (Qt::ShiftModifier | Qt::ControlModifier)))
        aEvent.DropAction = m_pDropTarget->proposedDragAction()
                            | css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
    else
        aEvent.DropAction = m_pDropTarget->proposedDragAction();
    aEvent.SourceActions = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;

    css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
    if (!pQMimeData->hasFormat(sInternalMimeType))
        xTransferable = new Qt5DnDTransferable(pQMimeData);
    else
        xTransferable = Qt5DragSource::m_ActiveDragSource->GetTransferable();
    aEvent.Transferable = xTransferable;

    // ask the drop target to accept our drop action
    m_pDropTarget->fire_drop(aEvent);
    m_bInDrag = false;

    if (m_pDragSource)
    const bool bDropSuccessful = m_pDropTarget->dropSuccessful();
    const sal_Int8 nDropAction = m_pDropTarget->proposedDropAction();

    // inform the drag source of the drag-origin frame of the drop result
    if (pEvent->source())
    {
        m_pDragSource->fire_dragEnd(m_pDropTarget->proposedDragAction());
        Qt5Widget* pWidget = dynamic_cast<Qt5Widget*>(pEvent->source());
        assert(pWidget); // AFAIK there shouldn't be any non-Qt5Widget as source in LO itself
        if (pWidget)
            pWidget->getFrame().m_pDragSource->fire_dragEnd(nDropAction, bDropSuccessful);
    }

    // the drop target accepted our drop action => inform Qt
    if (bDropSuccessful)
    {
        pEvent->setDropAction(getPreferredDropAction(nDropAction));
        pEvent->accept();
    }
    else // or maybe someone else likes it?
        pEvent->ignore();
}

void Qt5Frame::handleDragLeave()
{
    css::datatransfer::dnd::DropTargetEvent aEvent;
    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
    m_pDropTarget->fire_dragExit(aEvent);
    m_bInDrag = false;
}

cairo_t* Qt5Frame::getCairoContext() const
diff --git a/vcl/qt5/Qt5Tools.cxx b/vcl/qt5/Qt5Tools.cxx
index cff661b..24e60b9e 100644
--- a/vcl/qt5/Qt5Tools.cxx
+++ b/vcl/qt5/Qt5Tools.cxx
@@ -80,6 +80,18 @@ sal_Int8 toVclDropActions(Qt::DropActions dragOperation)
    return nRet;
}

sal_Int8 toVclDropAction(Qt::DropAction dragOperation)
{
    sal_Int8 nRet(0);
    if (dragOperation == Qt::CopyAction)
        nRet = css::datatransfer::dnd::DNDConstants::ACTION_COPY;
    else if (dragOperation == Qt::MoveAction)
        nRet = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
    else if (dragOperation == Qt::LinkAction)
        nRet = css::datatransfer::dnd::DNDConstants::ACTION_LINK;
    return nRet;
}

Qt::DropAction getPreferredDropAction(sal_Int8 dragOperation)
{
    Qt::DropAction eAct = Qt::IgnoreAction;
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index b8af22d..1d9f41e 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -24,6 +24,7 @@
#include <Qt5Graphics.hxx>
#include <Qt5Instance.hxx>
#include <Qt5SvpGraphics.hxx>
#include <Qt5Transferable.hxx>
#include <Qt5Tools.hxx>

#include <QtCore/QMimeData>
@@ -213,41 +214,20 @@ void Qt5Widget::wheelEvent(QWheelEvent* pEvent)
    pEvent->accept();
}

void Qt5Widget::startDrag(sal_Int8 nSourceActions)
{
    // internal drag source
    QMimeData* mimeData = new QMimeData;
    mimeData->setData(sInternalMimeType, nullptr);

    QDrag* drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->exec(toQtDropActions(nSourceActions), Qt::MoveAction);
}

void Qt5Widget::dragEnterEvent(QDragEnterEvent* event)
{
    if (event->mimeData()->hasFormat(sInternalMimeType))
    if (dynamic_cast<const Qt5MimeData*>(event->mimeData()))
        event->accept();
    else
        event->acceptProposedAction();
}

void Qt5Widget::dragMoveEvent(QDragMoveEvent* event)
{
    QPoint point = event->pos();
// also called when a drop is rejected
void Qt5Widget::dragLeaveEvent(QDragLeaveEvent*) { m_rFrame.handleDragLeave(); }

    m_rFrame.draggingStarted(point.x(), point.y(), event->possibleActions(),
                             event->keyboardModifiers(), event->mimeData());
    QWidget::dragMoveEvent(event);
}
void Qt5Widget::dragMoveEvent(QDragMoveEvent* pEvent) { m_rFrame.handleDragMove(pEvent); }

void Qt5Widget::dropEvent(QDropEvent* event)
{
    QPoint point = event->pos();

    m_rFrame.dropping(point.x(), point.y(), event->keyboardModifiers(), event->mimeData());
    QWidget::dropEvent(event);
}
void Qt5Widget::dropEvent(QDropEvent* pEvent) { m_rFrame.handleDrop(pEvent); }

void Qt5Widget::moveEvent(QMoveEvent* event)
{
diff --git a/vcl/unx/kde5/KDE5SalFrame.hxx b/vcl/unx/kde5/KDE5SalFrame.hxx
index cf3874a..e5f13b6 100644
--- a/vcl/unx/kde5/KDE5SalFrame.hxx
+++ b/vcl/unx/kde5/KDE5SalFrame.hxx
@@ -38,10 +38,6 @@ public:
    virtual SalGraphics* AcquireGraphics() override;
    virtual void ReleaseGraphics(SalGraphics* pGraphics) override;
    virtual void UpdateSettings(AllSettings& rSettings) override;

    virtual LanguageType GetInputLanguage() override { return LANGUAGE_SYSTEM; }
    virtual SalPointerState GetPointerState() override { return SalPointerState(); }
    virtual KeyIndicatorState GetIndicatorState() override { return KeyIndicatorState(); }
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */