File indexing completed on 2024-11-10 04:57:38
0001 /* 0002 SPDX-FileCopyrightText: 2023 David Redondo <kde@david-redondo.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "xdgtopleveldrag_v1.h" 0008 #include "dataoffer.h" 0009 #include "datasource.h" 0010 #include "datasource_p.h" 0011 #include "display.h" 0012 #include "surface.h" 0013 #include "utils/resource.h" 0014 #include "xdgshell.h" 0015 0016 #include <qwayland-server-xdg-toplevel-drag-v1.h> 0017 0018 #include <QPointer> 0019 0020 #include <memory> 0021 0022 namespace KWin 0023 { 0024 constexpr int version = 1; 0025 0026 class XdgToplevelDragV1InterfacePrivate : public QtWaylandServer::xdg_toplevel_drag_v1 0027 { 0028 public: 0029 XdgToplevelDragV1InterfacePrivate(wl_resource *resource, XdgToplevelDragV1Interface *q) 0030 : xdg_toplevel_drag_v1(resource) 0031 , q(q) 0032 { 0033 } 0034 XdgToplevelDragV1Interface *q; 0035 QPointer<DataSourceInterface> dataSource; 0036 QPointer<XdgToplevelInterface> toplevel; 0037 QPoint pos; 0038 0039 private: 0040 void xdg_toplevel_drag_v1_attach(Resource *resource, wl_resource *toplevelResource, int32_t x_offset, int32_t y_offset) override 0041 { 0042 if (toplevel) { 0043 wl_resource_post_error(resource->handle, error_toplevel_attached, "Valid toplevel already attached"); 0044 return; 0045 } 0046 toplevel = XdgToplevelInterface::get(toplevelResource); 0047 QObject::connect(toplevel, &XdgToplevelInterface::resetOccurred, q, [this] { 0048 toplevel = nullptr; 0049 }); 0050 pos = QPoint(x_offset, y_offset); 0051 Q_EMIT q->toplevelChanged(); 0052 } 0053 0054 void xdg_toplevel_drag_v1_destroy_resource(Resource *resource) override 0055 { 0056 delete q; 0057 } 0058 void xdg_toplevel_drag_v1_destroy(Resource *resource) override 0059 { 0060 if (!dataSource || dataSource->isDndCancelled() || dataSource->isDropPerformed()) { 0061 wl_resource_destroy(resource->handle); 0062 return; 0063 } 0064 wl_resource_post_error(resource->handle, error_ongoing_drag, "Drag has not ended"); 0065 } 0066 }; 0067 0068 XdgToplevelDragV1Interface::XdgToplevelDragV1Interface(wl_resource *resource, DataSourceInterface *dataSource) 0069 : d(std::make_unique<XdgToplevelDragV1InterfacePrivate>(resource, this)) 0070 { 0071 d->dataSource = dataSource; 0072 DataSourceInterfacePrivate::get(dataSource)->xdgToplevelDrag = this; 0073 } 0074 0075 XdgToplevelDragV1Interface::~XdgToplevelDragV1Interface() 0076 { 0077 if (d->dataSource) { 0078 DataSourceInterfacePrivate::get(d->dataSource)->xdgToplevelDrag = nullptr; 0079 } 0080 } 0081 0082 XdgToplevelInterface *XdgToplevelDragV1Interface::toplevel() const 0083 { 0084 return d->toplevel; 0085 } 0086 0087 QPoint XdgToplevelDragV1Interface::offset() const 0088 { 0089 return d->pos; 0090 } 0091 0092 class XdgToplevelDragManagerV1InterfacePrivate : public QtWaylandServer::xdg_toplevel_drag_manager_v1 0093 { 0094 public: 0095 XdgToplevelDragManagerV1InterfacePrivate(XdgToplevelDragManagerV1Interface *q, Display *display) 0096 : xdg_toplevel_drag_manager_v1(*display, version) 0097 , q(q) 0098 { 0099 } 0100 0101 protected: 0102 void xdg_toplevel_drag_manager_v1_destroy(Resource *resource) override 0103 { 0104 wl_resource_destroy(resource->handle); 0105 } 0106 0107 void xdg_toplevel_drag_manager_v1_get_xdg_toplevel_drag(Resource *resource, uint32_t id, wl_resource *data_source) override 0108 { 0109 auto dataSource = DataSourceInterface::get(data_source); 0110 0111 wl_resource *xdg_toplevel_drag = wl_resource_create(resource->client(), &xdg_toplevel_drag_v1_interface, resource->version(), id); 0112 if (!xdg_toplevel_drag) { 0113 wl_resource_post_no_memory(resource->handle); 0114 return; 0115 } 0116 new XdgToplevelDragV1Interface(xdg_toplevel_drag, dataSource); 0117 } 0118 0119 XdgToplevelDragManagerV1Interface *q; 0120 }; 0121 0122 XdgToplevelDragManagerV1Interface::XdgToplevelDragManagerV1Interface(Display *display, QObject *parent) 0123 : QObject(parent) 0124 , d(std::make_unique<XdgToplevelDragManagerV1InterfacePrivate>(this, display)) 0125 { 0126 } 0127 0128 XdgToplevelDragManagerV1Interface::~XdgToplevelDragManagerV1Interface() = default; 0129 } 0130 0131 #include "moc_xdgtopleveldrag_v1.cpp"