File indexing completed on 2024-05-12 05:32:35

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include "datasource.h"
0012 #include "drag.h"
0013 
0014 #include "wayland/datadevicemanager.h"
0015 
0016 #include <QList>
0017 #include <QPoint>
0018 #include <QPointer>
0019 
0020 namespace KWin
0021 {
0022 class Window;
0023 
0024 namespace Xwl
0025 {
0026 class X11Source;
0027 enum class DragEventReply;
0028 class WlVisit;
0029 class Dnd;
0030 
0031 using Mimes = QList<QPair<QString, xcb_atom_t>>;
0032 
0033 class XToWlDrag : public Drag
0034 {
0035     Q_OBJECT
0036 
0037 public:
0038     explicit XToWlDrag(X11Source *source, Dnd *dnd);
0039     ~XToWlDrag() override;
0040 
0041     DragEventReply moveFilter(Window *target) override;
0042     bool handleClientMessage(xcb_client_message_event_t *event) override;
0043 
0044     void setDragAndDropAction(DataDeviceManagerInterface::DnDAction action);
0045     DataDeviceManagerInterface::DnDAction selectedDragAndDropAction();
0046 
0047     X11Source *x11Source() const
0048     {
0049         return m_source;
0050     }
0051 
0052 private:
0053     void setOffers(const Mimes &offers);
0054     void setDragTarget();
0055 
0056     bool checkForFinished();
0057 
0058     Dnd *const m_dnd;
0059     Mimes m_offers;
0060 
0061     XwlDataSource m_selectionSource;
0062 
0063     X11Source *m_source;
0064     QList<QPair<xcb_timestamp_t, bool>> m_dataRequests;
0065 
0066     WlVisit *m_visit = nullptr;
0067     QList<WlVisit *> m_oldVisits;
0068 
0069     bool m_performed = false;
0070     DataDeviceManagerInterface::DnDAction m_lastSelectedDragAndDropAction = DataDeviceManagerInterface::DnDAction::None;
0071 
0072     Q_DISABLE_COPY(XToWlDrag)
0073 };
0074 
0075 class WlVisit : public QObject
0076 {
0077     Q_OBJECT
0078 
0079 public:
0080     WlVisit(Window *target, XToWlDrag *drag, Dnd *dnd);
0081     ~WlVisit() override;
0082 
0083     bool handleClientMessage(xcb_client_message_event_t *event);
0084     bool leave();
0085 
0086     Window *target() const
0087     {
0088         return m_target;
0089     }
0090     xcb_window_t window() const
0091     {
0092         return m_window;
0093     }
0094     bool entered() const
0095     {
0096         return m_entered;
0097     }
0098     bool dropHandled() const
0099     {
0100         return m_dropHandled;
0101     }
0102     bool finished() const
0103     {
0104         return m_finished;
0105     }
0106     void sendFinished();
0107 
0108 Q_SIGNALS:
0109     void offersReceived(const Mimes &offers);
0110     void finish(WlVisit *self);
0111 
0112 private:
0113     bool handleEnter(xcb_client_message_event_t *event);
0114     bool handlePosition(xcb_client_message_event_t *event);
0115     bool handleDrop(xcb_client_message_event_t *event);
0116     bool handleLeave(xcb_client_message_event_t *event);
0117 
0118     void sendStatus();
0119 
0120     void getMimesFromWinProperty(Mimes &offers);
0121 
0122     bool targetAcceptsAction() const;
0123 
0124     void doFinish();
0125     void unmapProxyWindow();
0126 
0127     Dnd *const m_dnd;
0128     Window *m_target;
0129     xcb_window_t m_window;
0130 
0131     xcb_window_t m_srcWindow = XCB_WINDOW_NONE;
0132     XToWlDrag *m_drag;
0133 
0134     uint32_t m_version = 0;
0135 
0136     xcb_atom_t m_actionAtom;
0137     DataDeviceManagerInterface::DnDAction m_action = DataDeviceManagerInterface::DnDAction::None;
0138 
0139     bool m_mapped = false;
0140     bool m_entered = false;
0141     bool m_dropHandled = false;
0142     bool m_finished = false;
0143 
0144     Q_DISABLE_COPY(WlVisit)
0145 };
0146 
0147 } // namespace Xwl
0148 } // namespace KWin