Commit ee28104c authored by David Edmundson's avatar David Edmundson

Port to new AppMenu iface

Plus test

Test Plan:
Ran kwin with menus and patched QPT
Ran test

Reviewers: graesslin

Reviewed By: graesslin

Subscribers: graesslin, kwin, #kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D9262
parent edb26542
......@@ -29,6 +29,7 @@ namespace KWayland
{
namespace Client
{
class AppMenuManager;
class ConnectionThread;
class Compositor;
class IdleInhibitManager;
......@@ -83,7 +84,8 @@ enum class AdditionalWaylandInterface {
PlasmaShell = 1 << 2,
WindowManagement = 1 << 3,
PointerConstraints = 1 << 4,
IdleInhibition = 1 << 5
IdleInhibition = 1 << 5,
AppMenu = 1 << 6
};
Q_DECLARE_FLAGS(AdditionalWaylandInterfaces, AdditionalWaylandInterface)
/**
......@@ -112,6 +114,8 @@ KWayland::Client::PlasmaShell *waylandPlasmaShell();
KWayland::Client::PlasmaWindowManagement *waylandWindowManagement();
KWayland::Client::PointerConstraints *waylandPointerConstraints();
KWayland::Client::IdleInhibitManager *waylandIdleInhibitManager();
KWayland::Client::AppMenuManager *waylandAppMenuManager();
bool waitForWaylandPointer();
bool waitForWaylandTouch();
......
......@@ -33,11 +33,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/server_decoration.h>
#include <KWayland/Client/surface.h>
#include <KWayland/Client/xdgshell.h>
#include <KWayland/Client/appmenu.h>
#include <KWayland/Server/clientconnection.h>
#include <KWayland/Server/display.h>
#include <KWayland/Server/shell_interface.h>
// system
#include <sys/types.h>
#include <sys/socket.h>
......@@ -84,6 +86,7 @@ private Q_SLOTS:
void testUnresponsiveWindow();
void testX11WindowId_data();
void testX11WindowId();
void testAppMenu();
};
void TestShellClient::initTestCase()
......@@ -108,7 +111,8 @@ void TestShellClient::initTestCase()
void TestShellClient::init()
{
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration));
QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration |
Test::AdditionalWaylandInterface::AppMenu));
screens()->setCurrent(0);
KWin::Cursor::setPos(QPoint(1280, 512));
......@@ -955,5 +959,21 @@ void TestShellClient::testX11WindowId()
QCOMPARE(c->window(), 0u);
}
void TestShellClient::testAppMenu()
{
QScopedPointer<Surface> surface(Test::createSurface());
QScopedPointer<QObject> shellSurface(Test::createShellSurface(Test::ShellSurfaceType::XdgShellV6, surface.data()));
auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue);
QVERIFY(c);
QScopedPointer<AppMenu> menu(Test::waylandAppMenuManager()->create(surface.data()));
QSignalSpy spy(c, &ShellClient::hasApplicationMenuChanged);
menu->setAddress("service.name", "object/path");
spy.wait();
QCOMPARE(c->hasApplicationMenu(), true);
QCOMPARE(c->applicationMenuServiceName(), "service.name");
QCOMPARE(c->applicationMenuObjectPath(), "object/path");
}
WAYLANDTEST_MAIN(TestShellClient)
#include "shell_client_test.moc"
......@@ -36,6 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/shm_pool.h>
#include <KWayland/Client/output.h>
#include <KWayland/Client/surface.h>
#include <KWayland/Client/appmenu.h>
#include <KWayland/Client/xdgshell.h>
#include <KWayland/Server/display.h>
......@@ -73,6 +74,7 @@ static struct {
QThread *thread = nullptr;
QVector<Output*> outputs;
IdleInhibitManager *idleInhibit = nullptr;
AppMenuManager *appMenu = nullptr;
} s_waylandConnection;
bool setupWaylandConnection(AdditionalWaylandInterfaces flags)
......@@ -196,6 +198,12 @@ bool setupWaylandConnection(AdditionalWaylandInterfaces flags)
return false;
}
}
if (flags.testFlag(AdditionalWaylandInterface::AppMenu)) {
s_waylandConnection.appMenu = registry->createAppMenuManager(registry->interface(Registry::Interface::AppMenu).name, registry->interface(Registry::Interface::AppMenu).version);
if (!s_waylandConnection.appMenu->isValid()) {
return false;
}
}
return true;
}
......@@ -230,6 +238,8 @@ void destroyWaylandConnection()
s_waylandConnection.queue = nullptr;
delete s_waylandConnection.registry;
s_waylandConnection.registry = nullptr;
delete s_waylandConnection.appMenu;
s_waylandConnection.appMenu = nullptr;
if (s_waylandConnection.thread) {
QSignalSpy spy(s_waylandConnection.connection, &QObject::destroyed);
s_waylandConnection.connection->deleteLater();
......@@ -294,6 +304,11 @@ IdleInhibitManager *waylandIdleInhibitManager()
return s_waylandConnection.idleInhibit;
}
AppMenuManager* waylandAppMenuManager()
{
return s_waylandConnection.appMenu;
}
bool waitForWaylandPointer()
{
if (!s_waylandConnection.seat) {
......
......@@ -46,6 +46,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Server/server_decoration_interface.h>
#include <KWayland/Server/qtsurfaceextension_interface.h>
#include <KWayland/Server/plasmawindowmanagement_interface.h>
#include <KWayland/Server/appmenu_interface.h>
#include <KDesktopFile>
#include <QOpenGLFramebufferObject>
......@@ -58,8 +60,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using namespace KWayland::Server;
static const QByteArray s_schemePropertyName = QByteArrayLiteral("KDE_COLOR_SCHEME_PATH");
static const QByteArray s_appMenuServiceNamePropertyName = QByteArrayLiteral("KDE_APPMENU_SERVICE_NAME");
static const QByteArray s_appMenuObjectPathPropertyName = QByteArrayLiteral("KDE_APPMENU_OBJECT_PATH");
static const QByteArray s_skipClosePropertyName = QByteArrayLiteral("KWIN_SKIP_CLOSE_ANIMATION");
namespace KWin
......@@ -336,7 +336,6 @@ void ShellClient::init()
}
AbstractClient::updateColorScheme(QString());
updateApplicationMenu();
if (!m_internal) {
discardTemporaryRules();
......@@ -1374,16 +1373,26 @@ void ShellClient::installQtExtendedSurface(QtExtendedSurfaceInterface *surface)
m_qtExtendedSurface->installEventFilter(this);
}
void ShellClient::installAppMenu(AppMenuInterface *menu)
{
m_appMenuInterface = menu;
auto updateMenu = [this](AppMenuInterface::InterfaceAddress address) {
updateApplicationMenuServiceName(address.serviceName);
updateApplicationMenuObjectPath(address.objectPath);
};
connect(m_appMenuInterface, &AppMenuInterface::addressChanged, this, [=](AppMenuInterface::InterfaceAddress address) {
updateMenu(address);
});
updateMenu(menu->address());
}
bool ShellClient::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_qtExtendedSurface.data() && event->type() == QEvent::DynamicPropertyChange) {
QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent*>(event);
if (pe->propertyName() == s_schemePropertyName) {
AbstractClient::updateColorScheme(rules()->checkDecoColor(m_qtExtendedSurface->property(pe->propertyName().constData()).toString()));
} else if (pe->propertyName() == s_appMenuServiceNamePropertyName) {
updateApplicationMenuServiceName(m_qtExtendedSurface->property(pe->propertyName().constData()).toString());
} else if (pe->propertyName() == s_appMenuObjectPathPropertyName) {
updateApplicationMenuObjectPath(m_qtExtendedSurface->property(pe->propertyName().constData()).toString());
}
}
if (watched == m_internalWindow && event->type() == QEvent::DynamicPropertyChange) {
......@@ -1637,14 +1646,6 @@ void ShellClient::killWindow()
QTimer::singleShot(5000, c, &ClientConnection::destroy);
}
void ShellClient::updateApplicationMenu()
{
if (m_qtExtendedSurface) {
updateApplicationMenuServiceName(m_qtExtendedSurface->property(s_appMenuObjectPathPropertyName).toString());
updateApplicationMenuObjectPath(m_qtExtendedSurface->property(s_appMenuServiceNamePropertyName).toString());
}
}
bool ShellClient::hasPopupGrab() const
{
return m_hasPopupGrab;
......
......@@ -29,6 +29,7 @@ namespace Server
{
class ShellSurfaceInterface;
class ServerSideDecorationInterface;
class AppMenuInterface;
class PlasmaShellSurfaceInterface;
class QtExtendedSurfaceInterface;
}
......@@ -135,6 +136,7 @@ public:
void installPlasmaShellSurface(KWayland::Server::PlasmaShellSurfaceInterface *surface);
void installQtExtendedSurface(KWayland::Server::QtExtendedSurfaceInterface *surface);
void installServerSideDecoration(KWayland::Server::ServerSideDecorationInterface *decoration);
void installAppMenu(KWayland::Server::AppMenuInterface *appmenu);
bool isInitialPositionSet() const override;
......@@ -154,8 +156,6 @@ public:
// TODO: const-ref
void placeIn(QRect &area);
void updateApplicationMenu();
bool hasPopupGrab() const override;
void popupDone() override;
......@@ -219,6 +219,7 @@ private:
NET::WindowType m_windowType = NET::Normal;
QPointer<KWayland::Server::PlasmaShellSurfaceInterface> m_plasmaShellSurface;
QPointer<KWayland::Server::QtExtendedSurfaceInterface> m_qtExtendedSurface;
QPointer<KWayland::Server::AppMenuInterface> m_appMenuInterface;
KWayland::Server::ServerSideDecorationInterface *m_serverDecoration = nullptr;
bool m_userNoBorder = false;
bool m_fullScreen = false;
......
......@@ -33,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Client/shm_pool.h>
#include <KWayland/Client/surface.h>
// Server
#include <KWayland/Server/appmenu_interface.h>
#include <KWayland/Server/compositor_interface.h>
#include <KWayland/Server/datadevicemanager_interface.h>
#include <KWayland/Server/display.h>
......@@ -151,6 +152,9 @@ void WaylandServer::createSurface(T *surface)
client->installPlasmaShellSurface(*it);
m_plasmaShellSurfaces.erase(it);
}
if (auto menu = m_appMenuManager->appMenuForSurface(surface->surface())) {
client->installAppMenu(menu);
}
if (client->isInternal()) {
m_internalClients << client;
} else {
......@@ -261,6 +265,8 @@ bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
}
}
);
m_qtExtendedSurface = m_display->createQtSurfaceExtension(m_display);
m_qtExtendedSurface->create();
connect(m_qtExtendedSurface, &QtSurfaceExtensionInterface::surfaceCreated,
......@@ -270,6 +276,16 @@ bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
}
}
);
m_appMenuManager = m_display->createAppMenuManagerInterface(m_display);
m_appMenuManager->create();
connect(m_appMenuManager, &AppMenuManagerInterface::appMenuCreated,
[this] (AppMenuInterface *appMenu) {
if (ShellClient *client = findClient(appMenu->surface())) {
client->installAppMenu(appMenu);
}
}
);
m_windowManagement = m_display->createPlasmaWindowManagement(m_display);
m_windowManagement->create();
m_windowManagement->setShowingDesktopState(PlasmaWindowManagementInterface::ShowingDesktopState::Disabled);
......
......@@ -40,6 +40,7 @@ class Surface;
}
namespace Server
{
class AppMenuManagerInterface;
class ClientConnection;
class CompositorInterface;
class Display;
......@@ -219,6 +220,7 @@ private:
KWayland::Server::QtSurfaceExtensionInterface *m_qtExtendedSurface = nullptr;
KWayland::Server::ServerSideDecorationManagerInterface *m_decorationManager = nullptr;
KWayland::Server::OutputManagementInterface *m_outputManagement = nullptr;
KWayland::Server::AppMenuManagerInterface *m_appMenuManager = nullptr;
struct {
KWayland::Server::ClientConnection *client = nullptr;
QMetaObject::Connection destroyConnection;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment