File indexing completed on 2024-05-19 16:35:16
0001 /* 0002 SPDX-FileCopyrightText: 2017 David Edmundson <kde@davidedmundson.co.uk> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "appmenu_interface.h" 0007 #include "display.h" 0008 #include "surface_interface.h" 0009 0010 #include <QtGlobal> 0011 0012 #include "qwayland-server-appmenu.h" 0013 0014 namespace KWaylandServer 0015 { 0016 static const quint32 s_version = 1; 0017 0018 class AppMenuManagerInterfacePrivate : public QtWaylandServer::org_kde_kwin_appmenu_manager 0019 { 0020 public: 0021 AppMenuManagerInterfacePrivate(AppMenuManagerInterface *q, Display *d); 0022 0023 QVector<AppMenuInterface *> appmenus; 0024 AppMenuManagerInterface *q; 0025 0026 protected: 0027 void org_kde_kwin_appmenu_manager_create(Resource *resource, uint32_t id, wl_resource *surface) override; 0028 }; 0029 0030 void AppMenuManagerInterfacePrivate::org_kde_kwin_appmenu_manager_create(Resource *resource, uint32_t id, wl_resource *surface) 0031 { 0032 SurfaceInterface *s = SurfaceInterface::get(surface); 0033 if (!s) { 0034 wl_resource_post_error(resource->handle, 0, "Invalid surface"); 0035 return; 0036 } 0037 wl_resource *appmenu_resource = wl_resource_create(resource->client(), &org_kde_kwin_appmenu_interface, resource->version(), id); 0038 if (!appmenu_resource) { 0039 wl_client_post_no_memory(resource->client()); 0040 return; 0041 } 0042 auto appmenu = new AppMenuInterface(s, appmenu_resource); 0043 0044 appmenus.append(appmenu); 0045 QObject::connect(appmenu, &QObject::destroyed, q, [=, this]() { 0046 appmenus.removeOne(appmenu); 0047 }); 0048 Q_EMIT q->appMenuCreated(appmenu); 0049 } 0050 0051 AppMenuManagerInterfacePrivate::AppMenuManagerInterfacePrivate(AppMenuManagerInterface *_q, Display *d) 0052 : QtWaylandServer::org_kde_kwin_appmenu_manager(*d, s_version) 0053 , q(_q) 0054 { 0055 } 0056 0057 class AppMenuInterfacePrivate : public QtWaylandServer::org_kde_kwin_appmenu 0058 { 0059 public: 0060 AppMenuInterfacePrivate(AppMenuInterface *q, SurfaceInterface *surface, wl_resource *resource); 0061 0062 AppMenuInterface *q; 0063 QPointer<SurfaceInterface> surface; 0064 AppMenuInterface::InterfaceAddress address; 0065 0066 protected: 0067 void org_kde_kwin_appmenu_destroy_resource(Resource *resource) override; 0068 void org_kde_kwin_appmenu_set_address(Resource *resource, const QString &service_name, const QString &object_path) override; 0069 void org_kde_kwin_appmenu_release(Resource *resource) override; 0070 }; 0071 0072 AppMenuInterfacePrivate::AppMenuInterfacePrivate(AppMenuInterface *_q, SurfaceInterface *s, wl_resource *resource) 0073 : QtWaylandServer::org_kde_kwin_appmenu(resource) 0074 , q(_q) 0075 , surface(s) 0076 { 0077 } 0078 0079 void AppMenuInterfacePrivate::org_kde_kwin_appmenu_destroy_resource(QtWaylandServer::org_kde_kwin_appmenu::Resource *resource) 0080 { 0081 delete q; 0082 } 0083 0084 void AppMenuInterfacePrivate::org_kde_kwin_appmenu_set_address(Resource *resource, const QString &service_name, const QString &object_path) 0085 { 0086 if (address.serviceName == service_name && address.objectPath == object_path) { 0087 return; 0088 } 0089 0090 address.serviceName = service_name; 0091 address.objectPath = object_path; 0092 Q_EMIT q->addressChanged(address); 0093 } 0094 0095 void AppMenuInterfacePrivate::org_kde_kwin_appmenu_release(QtWaylandServer::org_kde_kwin_appmenu::Resource *resource) 0096 { 0097 wl_resource_destroy(resource->handle); 0098 } 0099 0100 AppMenuManagerInterface::AppMenuManagerInterface(Display *display, QObject *parent) 0101 : QObject(parent) 0102 , d(new AppMenuManagerInterfacePrivate(this, display)) 0103 { 0104 } 0105 0106 AppMenuManagerInterface::~AppMenuManagerInterface() 0107 { 0108 } 0109 0110 AppMenuInterface *AppMenuManagerInterface::appMenuForSurface(SurfaceInterface *surface) 0111 { 0112 for (AppMenuInterface *menu : d->appmenus) { 0113 if (menu->surface() == surface) { 0114 return menu; 0115 } 0116 } 0117 return nullptr; 0118 } 0119 0120 AppMenuInterface::AppMenuInterface(SurfaceInterface *surface, wl_resource *resource) 0121 : QObject() 0122 , d(new AppMenuInterfacePrivate(this, surface, resource)) 0123 { 0124 } 0125 0126 AppMenuInterface::~AppMenuInterface() 0127 { 0128 } 0129 0130 AppMenuInterface::InterfaceAddress AppMenuInterface::address() const 0131 { 0132 return d->address; 0133 } 0134 0135 SurfaceInterface *AppMenuInterface::surface() const 0136 { 0137 return d->surface.data(); 0138 } 0139 0140 } // namespace