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