KWaylandServer

datasource_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3  SPDX-FileCopyrightText: 2020 David Edmundson <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #include "datasource_interface.h"
8 #include "clientconnection.h"
9 #include "datadevicemanager_interface.h"
10 #include "utils.h"
11 // Qt
12 #include <QStringList>
13 // Wayland
14 #include <qwayland-server-wayland.h>
15 // system
16 #include <unistd.h>
17 
18 namespace KWaylandServer
19 {
20 class DataSourceInterfacePrivate : public QtWaylandServer::wl_data_source
21 {
22 public:
23  DataSourceInterfacePrivate(DataSourceInterface *_q, ::wl_resource *resource);
24 
25  DataSourceInterface *q;
27  DataDeviceManagerInterface::DnDActions supportedDnDActions = DataDeviceManagerInterface::DnDAction::None;
28  bool isAccepted = false;
29 
30 protected:
31  void data_source_destroy_resource(Resource *resource) override;
32  void data_source_offer(Resource *resource, const QString &mime_type) override;
33  void data_source_destroy(Resource *resource) override;
34  void data_source_set_actions(Resource *resource, uint32_t dnd_actions) override;
35 
36 private:
37  void offer(const QString &mimeType);
38 };
39 
40 DataSourceInterfacePrivate::DataSourceInterfacePrivate(DataSourceInterface *_q, ::wl_resource *resource)
41  : QtWaylandServer::wl_data_source(resource)
42  , q(_q)
43 {
44 }
45 
46 void DataSourceInterfacePrivate::data_source_destroy_resource(Resource *resource)
47 {
48  Q_UNUSED(resource)
49  Q_EMIT q->aboutToBeDestroyed();
50  delete q;
51 }
52 
53 void DataSourceInterfacePrivate::data_source_offer(QtWaylandServer::wl_data_source::Resource *resource, const QString &mime_type)
54 {
55  Q_UNUSED(resource)
56  mimeTypes << mime_type;
57  Q_EMIT q->mimeTypeOffered(mime_type);
58 }
59 
60 void DataSourceInterfacePrivate::data_source_destroy(QtWaylandServer::wl_data_source::Resource *resource)
61 {
62  wl_resource_destroy(resource->handle);
63 }
64 
65 void DataSourceInterfacePrivate::offer(const QString &mimeType)
66 {
67  mimeTypes << mimeType;
68  Q_EMIT q->mimeTypeOffered(mimeType);
69 }
70 
71 void DataSourceInterfacePrivate::data_source_set_actions(Resource *resource, uint32_t dnd_actions)
72 {
73  // verify that the no other actions are sent
74  if (dnd_actions
75  & ~(QtWaylandServer::wl_data_device_manager::dnd_action_copy | QtWaylandServer::wl_data_device_manager::dnd_action_move
76  | QtWaylandServer::wl_data_device_manager::dnd_action_ask)) {
77  wl_resource_post_error(resource->handle, error_invalid_action_mask, "Invalid action mask");
78  return;
79  }
80  DataDeviceManagerInterface::DnDActions supportedActions;
81  if (dnd_actions & QtWaylandServer::wl_data_device_manager::dnd_action_copy) {
82  supportedActions |= DataDeviceManagerInterface::DnDAction::Copy;
83  }
84  if (dnd_actions & QtWaylandServer::wl_data_device_manager::dnd_action_move) {
85  supportedActions |= DataDeviceManagerInterface::DnDAction::Move;
86  }
87  if (dnd_actions & QtWaylandServer::wl_data_device_manager::dnd_action_ask) {
88  supportedActions |= DataDeviceManagerInterface::DnDAction::Ask;
89  }
90  if (supportedDnDActions != supportedActions) {
91  supportedDnDActions = supportedActions;
92  Q_EMIT q->supportedDragAndDropActionsChanged();
93  }
94 }
95 
96 DataSourceInterface::DataSourceInterface(DataDeviceManagerInterface *parent, wl_resource *resource)
97  : AbstractDataSource(parent)
98  , d(new DataSourceInterfacePrivate(this, resource))
99 {
100  if (d->resource()->version() < WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
101  d->supportedDnDActions = DataDeviceManagerInterface::DnDAction::Copy;
102  }
103 }
104 
105 DataSourceInterface::~DataSourceInterface() = default;
106 
107 void DataSourceInterface::accept(const QString &mimeType)
108 {
109  d->send_target(mimeType);
110  d->isAccepted = !mimeType.isNull();
111 }
112 
113 void DataSourceInterface::requestData(const QString &mimeType, qint32 fd)
114 {
115  d->send_send(mimeType, int32_t(fd));
116  close(fd);
117 }
118 
119 void DataSourceInterface::cancel()
120 {
121  d->send_cancelled();
122 }
123 
124 QStringList DataSourceInterface::mimeTypes() const
125 {
126  return d->mimeTypes;
127 }
128 
129 DataSourceInterface *DataSourceInterface::get(wl_resource *native)
130 {
131  if (auto sourcePrivate = resource_cast<DataSourceInterfacePrivate *>(native)) {
132  return sourcePrivate->q;
133  }
134  return nullptr;
135 }
136 
138 {
139  return d->supportedDnDActions;
140 }
141 
143 {
144  if (d->resource()->version() < WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) {
145  return;
146  }
147  d->send_dnd_drop_performed();
148 }
149 
151 {
152  if (d->resource()->version() < WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION) {
153  return;
154  }
155  d->send_dnd_finished();
156 }
157 
159 {
160  if (d->resource()->version() < WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
161  return;
162  }
163  uint32_t wlAction = QtWaylandServer::wl_data_device_manager::dnd_action_none;
164  if (action == DataDeviceManagerInterface::DnDAction::Copy) {
165  wlAction = QtWaylandServer::wl_data_device_manager::dnd_action_copy;
166  } else if (action == DataDeviceManagerInterface::DnDAction::Move) {
167  wlAction = QtWaylandServer::wl_data_device_manager::dnd_action_move;
168  } else if (action == DataDeviceManagerInterface::DnDAction::Ask) {
169  wlAction = QtWaylandServer::wl_data_device_manager::dnd_action_ask;
170  }
171  d->send_action(wlAction);
172 }
173 
175 {
176  // for v3 or less, cancel should not be called after a failed drag operation
177  if (wl_resource_get_version(resource()) < 3) {
178  return;
179  }
180  d->send_cancelled();
181 }
182 
183 wl_resource *DataSourceInterface::resource() const
184 {
185  return d->resource()->handle;
186 }
187 
188 wl_client *DataSourceInterface::client() const
189 {
190  return d->resource()->client();
191 }
192 
193 bool DataSourceInterface::isAccepted() const
194 {
195  return d->isAccepted;
196 }
197 
198 void DataSourceInterface::setAccepted(bool accepted)
199 {
200  d->isAccepted = accepted;
201 }
202 
203 }
DataDeviceManagerInterface::DnDActions supportedDragAndDropActions() const override
void dropPerformed() override
The user performed the drop action during a drag and drop operation.
const QList< QKeySequence > & close()
void dndCancelled() override
Called when a user stops clicking but it is not accepted by a client.
bool isNull() const const
DnDAction
Drag and Drop actions supported by the DataSourceInterface.
QStringList mimeTypes(Types)
void dndAction(DataDeviceManagerInterface::DnDAction action) override
This event indicates the action selected by the compositor after matching the source/destination side...
void dndFinished() override
The drop destination finished interoperating with this data source.
QObject * parent() const const
Q_EMITQ_EMIT
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 23:08:43 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.