File indexing completed on 2024-05-19 16:35: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 "drag.h"
0012 
0013 #include "wayland/datadevicemanager_interface.h"
0014 
0015 #include <QPoint>
0016 #include <QPointer>
0017 #include <QVector>
0018 
0019 namespace KWaylandServer
0020 {
0021 class DataDeviceInterface;
0022 class DataSourceInterface;
0023 class SurfaceInterface;
0024 }
0025 
0026 namespace KWin
0027 {
0028 class Window;
0029 
0030 namespace Xwl
0031 {
0032 class X11Source;
0033 enum class DragEventReply;
0034 class Xvisit;
0035 class Dnd;
0036 
0037 class WlToXDrag : public Drag
0038 {
0039     Q_OBJECT
0040     using Drag::Drag;
0041 
0042 public:
0043     explicit WlToXDrag(Dnd *dnd);
0044     DragEventReply moveFilter(Window *target, const QPoint &pos) override;
0045     bool handleClientMessage(xcb_client_message_event_t *event) override;
0046 
0047 private:
0048     Dnd *const m_dnd;
0049     Q_DISABLE_COPY(WlToXDrag)
0050 };
0051 
0052 // visit to an X window
0053 class Xvisit : public QObject
0054 {
0055     Q_OBJECT
0056 
0057 public:
0058     // TODO: handle ask action
0059 
0060     Xvisit(Window *target, KWaylandServer::AbstractDataSource *dataSource, Dnd *dnd, QObject *parent);
0061 
0062     bool handleClientMessage(xcb_client_message_event_t *event);
0063     bool handleStatus(xcb_client_message_event_t *event);
0064     bool handleFinished(xcb_client_message_event_t *event);
0065 
0066     void sendPosition(const QPointF &globalPos);
0067     void leave();
0068 
0069     bool finished() const
0070     {
0071         return m_state.finished;
0072     }
0073     Window *target() const
0074     {
0075         return m_target;
0076     }
0077     void drop();
0078 Q_SIGNALS:
0079     void finish(Xvisit *self);
0080 
0081 private:
0082     void sendEnter();
0083     void sendDrop(uint32_t time);
0084     void sendLeave();
0085 
0086     void receiveOffer();
0087     void enter();
0088 
0089     void retrieveSupportedActions();
0090     void determineProposedAction();
0091     void requestDragAndDropAction();
0092     void setProposedAction();
0093 
0094     void doFinish();
0095     void stopConnections();
0096 
0097     Dnd *const m_dnd;
0098     Window *m_target;
0099     QPointer<KWaylandServer::AbstractDataSource> m_dataSource;
0100     uint32_t m_version = 0;
0101 
0102     QMetaObject::Connection m_motionConnection;
0103 
0104     struct
0105     {
0106         bool pending = false;
0107         bool cached = false;
0108         QPoint cache;
0109     } m_pos;
0110 
0111     // supported by the Wl source
0112     KWaylandServer::DataDeviceManagerInterface::DnDActions m_supportedActions = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
0113     // preferred by the X client
0114     KWaylandServer::DataDeviceManagerInterface::DnDAction m_preferredAction = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
0115     // decided upon by the compositor
0116     KWaylandServer::DataDeviceManagerInterface::DnDAction m_proposedAction = KWaylandServer::DataDeviceManagerInterface::DnDAction::None;
0117 
0118     struct
0119     {
0120         bool entered = false;
0121         bool dropped = false;
0122         bool finished = false;
0123     } m_state;
0124 
0125     bool m_accepts = false;
0126 
0127     Q_DISABLE_COPY(Xvisit)
0128 };
0129 
0130 } // namespace Xwl
0131 } // namespace KWin