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
This commit is contained in:
parent
edb2654228
commit
ee28104c7a
7 changed files with 78 additions and 19 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue