Commit 9e519bea authored by David Edmundson's avatar David Edmundson
Browse files

Use QWaylandClientExtension for wayland code

This helps with our plans for Plasma 6. There should be no user facing
changes.
parent aeb3dfb3
Pipeline #153500 passed with stage
in 1 minute and 52 seconds
......@@ -19,17 +19,21 @@ include(GenerateExportHeader)
include(KDEClangFormat)
include(KDEGitCommitHooks)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} CONFIG REQUIRED Widgets DBus QuickControls2)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} CONFIG REQUIRED Widgets DBus QuickControls2 WaylandClient)
find_package(Qt${QT_MAJOR_VERSION}Gui ${QT_MIN_VERSION} CONFIG REQUIRED Private)
if (QT_MAJOR_VERSION EQUAL "5")
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED X11Extras)
endif()
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
Config ConfigWidgets I18n IconThemes KIO Notifications Wayland
Config ConfigWidgets I18n IconThemes KIO Notifications
WidgetsAddons WindowSystem ConfigWidgets
)
find_package(QtWaylandScanner REQUIRED)
find_package(Wayland 1.9 REQUIRED Client)
find_package(PlasmaWaylandProtocols 1.6.0 CONFIG REQUIRED)
find_package(XCB COMPONENTS XCB)
set_package_properties(XCB PROPERTIES
DESCRIPTION "X protocol C-language Binding"
......
......@@ -28,12 +28,23 @@ macro(FRAMEWORKINTEGRATION_TESTS _testname)
ecm_mark_as_test(${_testname})
ecm_mark_nongui_executable(${_testname})
target_include_directories(${_testname} PRIVATE ${CMAKE_BINARY_DIR}/src/platformtheme)
target_link_libraries(${_testname} Qt::GuiPrivate Qt::Test Qt::DBus Qt::X11Extras Qt::QuickControls2 ${QT5PLATFORMSUPPORT_LIBS} KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets KF5::I18n KF5::Notifications KF5::WindowSystem KF5::WaylandClient XCB::XCB)
target_link_libraries(${_testname} Qt::GuiPrivate Qt::Test Qt::DBus Qt::X11Extras Qt::QuickControls2 ${QT5PLATFORMSUPPORT_LIBS} KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets KF5::I18n KF5::Notifications KF5::WindowSystem Qt::WaylandClient XCB::XCB Wayland::Client)
endmacro()
set(dbus_interface)
qt_add_dbus_interface(dbus_interface ../src/platformtheme/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher_interface)
set(wayland_interfaces)
ecm_add_qtwayland_client_protocol(wayland_interfaces
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/appmenu.xml
BASENAME appmenu
)
ecm_add_qtwayland_client_protocol(wayland_interfaces
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/server-decoration-palette.xml
BASENAME server-decoration-palette
)
set(platformThemeSRCS
../src/platformtheme/qdbusmenubar.cpp # fork of Qt's qdbusmenubar with some added setters for our convenience
../src/platformtheme/kdeplatformtheme.cpp
......@@ -48,6 +59,7 @@ set(platformThemeSRCS
../src/platformtheme/x11integration.cpp
../src/platformtheme/qxdgdesktopportalfiledialog.cpp
${dbus_interface}
${wayland_interfaces}
)
frameworkintegration_tests(
......
......@@ -18,7 +18,6 @@ configure_file(config-platformtheme.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-p
# qdbusmenubar uses them
remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
set(platformtheme_SRCS
qdbusmenubar.cpp # fork of Qt's qdbusmenubar with some added setters for our convenience
kdeplatformtheme.cpp
......@@ -39,6 +38,16 @@ set(platformtheme_SRCS
qt_add_dbus_interface(platformtheme_SRCS org.kde.StatusNotifierWatcher.xml statusnotifierwatcher_interface)
kconfig_add_kcfg_files(platformtheme_SRCS renderersettings.kcfgc)
ecm_add_qtwayland_client_protocol(platformtheme_SRCS
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/appmenu.xml
BASENAME appmenu
)
ecm_add_qtwayland_client_protocol(platformtheme_SRCS
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/server-decoration-palette.xml
BASENAME server-decoration-palette
)
add_library(KDEPlasmaPlatformTheme MODULE ${platformtheme_SRCS})
target_link_libraries(KDEPlasmaPlatformTheme
......@@ -55,9 +64,11 @@ target_link_libraries(KDEPlasmaPlatformTheme
KF5::I18n
KF5::Notifications
KF5::WindowSystem
KF5::WaylandClient
XCB::XCB
${QT5PLATFORMSUPPORT_LIBS}
Qt::WaylandClient
Qt::GuiPrivate
Wayland::Client
)
if (QT_MAJOR_VERSION EQUAL "5")
target_link_libraries(KDEPlasmaPlatformTheme PRIVATE Qt5::X11Extras)
......
......@@ -63,7 +63,6 @@ KdePlatformTheme::KdePlatformTheme()
if (KWindowSystem::isPlatformWayland()) {
m_kwaylandIntegration.reset(new KWaylandIntegration());
m_kwaylandIntegration->init();
}
#if HAVE_X11
......
......@@ -7,47 +7,53 @@
#include <QExposeEvent>
#include <QGuiApplication>
#include <QWindow>
#include <qpa/qplatformnativeinterface.h>
#include <KWayland/Client/appmenu.h>
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h>
#include <KWayland/Client/server_decoration.h>
#include <KWayland/Client/server_decoration_palette.h>
#include <KWayland/Client/surface.h>
#include <KWindowEffects>
#include "qwayland-appmenu.h"
#include "qwayland-server-decoration-palette.h"
using namespace KWayland::Client;
#include <KWindowEffects>
static const QByteArray s_schemePropertyName = QByteArrayLiteral("KDE_COLOR_SCHEME_PATH");
static const QByteArray s_blurBehindPropertyName = QByteArrayLiteral("ENABLE_BLUR_BEHIND_HINT");
KWaylandIntegration::KWaylandIntegration()
: QObject()
class AppMenuManager : public QWaylandClientExtensionTemplate<AppMenuManager>, public QtWayland::org_kde_kwin_appmenu_manager
{
}
KWaylandIntegration::~KWaylandIntegration() = default;
Q_OBJECT
public:
AppMenuManager()
: QWaylandClientExtensionTemplate<AppMenuManager>(1)
{
}
};
void KWaylandIntegration::init()
class ServerSideDecorationPaletteManager : public QWaylandClientExtensionTemplate<ServerSideDecorationPaletteManager>,
public QtWayland::org_kde_kwin_server_decoration_palette_manager
{
auto connection = ConnectionThread::fromApplication(this);
if (!connection) {
return;
Q_OBJECT
public:
ServerSideDecorationPaletteManager()
: QWaylandClientExtensionTemplate<ServerSideDecorationPaletteManager>(1)
{
}
m_registry = new Registry(this);
m_registry->create(connection);
QObject::connect(m_registry, &Registry::interfacesAnnounced, this, [this] {
QCoreApplication::instance()->installEventFilter(this);
const auto menuInterface = m_registry->interface(Registry::Interface::AppMenu);
if (menuInterface.name != 0) {
m_appMenuManager = m_registry->createAppMenuManager(menuInterface.name, menuInterface.version, this);
}
});
};
using AppMenu = QtWayland::org_kde_kwin_appmenu;
using ServerSideDecorationPalette = QtWayland::org_kde_kwin_server_decoration_palette;
m_registry->setup();
Q_DECLARE_METATYPE(AppMenu *);
Q_DECLARE_METATYPE(ServerSideDecorationPalette *);
KWaylandIntegration::KWaylandIntegration()
: QObject()
, m_appMenuManager(new AppMenuManager)
, m_paletteManager(new ServerSideDecorationPaletteManager)
{
}
KWaylandIntegration::~KWaylandIntegration() = default;
bool KWaylandIntegration::isRelevantTopLevel(QWindow *w)
{
if (!w || w->parent()) {
......@@ -108,17 +114,17 @@ void KWaylandIntegration::shellSurfaceCreated(QWindow *w)
KWindowEffects::enableBlurBehind(w, blurBehindProperty.toBool());
}
// create deco
Surface *s = Surface::fromWindow(w);
wl_surface *s = surfaceFromWindow(w);
if (!s) {
return;
}
w->setProperty("org.kde.plasma.integration.shellSurfaceCreated", true);
if (m_appMenuManager) {
auto menu = m_appMenuManager->create(s, w);
if (m_appMenuManager->isActive()) {
auto menu = new AppMenu(m_appMenuManager->create(s));
w->setProperty("org.kde.plasma.integration.appmenu", QVariant::fromValue(menu));
menu->setAddress(m_windowInfo[w].appMenuServiceName, m_windowInfo[w].appMenuObjectPath);
menu->set_address(m_windowInfo[w].appMenuServiceName, m_windowInfo[w].appMenuObjectPath);
}
}
......@@ -126,34 +132,34 @@ void KWaylandIntegration::shellSurfaceDestroyed(QWindow *w)
{
w->setProperty("org.kde.plasma.integration.shellSurfaceCreated", QVariant());
delete w->property("org.kde.plasma.integration.appmenu").value<AppMenu *>();
auto appMenu = w->property("org.kde.plasma.integration.appmenu").value<AppMenu *>();
if (appMenu) {
appMenu->release();
delete appMenu;
}
w->setProperty("org.kde.plasma.integration.appmenu", QVariant());
delete w->property("org.kde.plasma.integration.palette").value<ServerSideDecorationPalette *>();
auto decoPallete = w->property("org.kde.plasma.integration.palette").value<ServerSideDecorationPalette *>();
if (decoPallete) {
decoPallete->release();
delete decoPallete;
}
w->setProperty("org.kde.plasma.integration.palette", QVariant());
}
void KWaylandIntegration::installColorScheme(QWindow *w)
{
if (!m_paletteManager) {
const auto paletteManagerInterface = m_registry->interface(Registry::Interface::ServerSideDecorationPalette);
if (paletteManagerInterface.name == 0) {
return;
} else {
m_paletteManager = m_registry->createServerSideDecorationPaletteManager(paletteManagerInterface.name, paletteManagerInterface.version, this);
}
}
auto palette = w->property("org.kde.plasma.integration.palette").value<ServerSideDecorationPalette *>();
if (!palette) {
Surface *s = Surface::fromWindow(w);
auto s = surfaceFromWindow(w);
if (!s) {
return;
}
palette = m_paletteManager->create(s, w);
auto palette = new ServerSideDecorationPalette(m_paletteManager->create(s));
w->setProperty("org.kde.plasma.integration.palette", QVariant::fromValue(palette));
}
if (palette) {
palette->setPalette(qApp->property(s_schemePropertyName.constData()).toString());
palette->set_palette(qApp->property(s_schemePropertyName.constData()).toString());
}
}
......@@ -168,6 +174,17 @@ void KWaylandIntegration::setAppMenu(QWindow *window, const QString &serviceName
m_windowInfo[window].appMenuObjectPath = objectPath;
auto menu = window->property("org.kde.plasma.integration.appmenu").value<AppMenu *>();
if (menu) {
menu->setAddress(serviceName, objectPath);
menu->set_address(serviceName, objectPath);
}
}
wl_surface *KWaylandIntegration::surfaceFromWindow(QWindow *window)
{
QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface();
if (!nativeInterface) {
return nullptr;
}
return static_cast<wl_surface *>(nativeInterface->nativeResourceForWindow("surface", window));
}
#include "kwaylandintegration.moc"
......@@ -8,18 +8,12 @@
#include <QHash>
#include <QObject>
#include <QtWaylandClient/QWaylandClientExtensionTemplate>
class QWindow;
namespace KWayland
{
namespace Client
{
class ServerSideDecorationPaletteManager;
class AppMenuManager;
class Registry;
}
}
class ServerSideDecorationPaletteManager;
class KWaylandIntegration : public QObject
{
......@@ -27,7 +21,6 @@ class KWaylandIntegration : public QObject
public:
explicit KWaylandIntegration();
~KWaylandIntegration() override;
void init();
void setAppMenu(QWindow *window, const QString &serviceName, const QString &objectPath);
void setPalette(QWindow *window, const QString &paletteName);
......@@ -36,13 +29,13 @@ public:
private:
static bool isRelevantTopLevel(QWindow *w);
static struct wl_surface *surfaceFromWindow(QWindow *w);
void shellSurfaceCreated(QWindow *w);
void shellSurfaceDestroyed(QWindow *w);
void installColorScheme(QWindow *w);
KWayland::Client::AppMenuManager *m_appMenuManager = nullptr;
KWayland::Client::ServerSideDecorationPaletteManager *m_paletteManager = nullptr;
KWayland::Client::Registry *m_registry = nullptr;
QScopedPointer<AppMenuManager> m_appMenuManager;
QScopedPointer<ServerSideDecorationPaletteManager> m_paletteManager;
struct WindowInfo {
QString appMenuServiceName;
......
  • This commit completely breaks both appmenu manager and palette manager functionality for me; reverting this commit fixes both.

  • Thanks for letting me know. Still works for me and another tester. Can you send me a WAYLAND_DEBUG=1 log.

  • this also seems to crash konsole for me:

    (gdb) bt
    #0  0x00007f554ec1a174 in wl_proxy_get_version () from /lib64/libwayland-client.so.0
    #1  0x00007f553d8bfef8 in org_kde_kwin_server_decoration_palette_manager_create (org_kde_kwin_server_decoration_palette_manager=0x0, surface=0x1e0a520)
        at /home/jblackquill/KDE/Build/plasma-integration/src/platformtheme/wayland-server-decoration-palette-client-protocol.h:109
    #2  0x00007f553d8c01c3 in QtWayland::org_kde_kwin_server_decoration_palette_manager::create (this=0x1c5bcd0, surface=0x1e0a520)
        at /home/jblackquill/KDE/Build/plasma-integration/src/platformtheme/qwayland-server-decoration-palette.cpp:70
    #3  0x00007f553d8b3c83 in KWaylandIntegration::installColorScheme (this=0x1c5bdd0, w=0x1cd6490)
        at /home/jblackquill/KDE/Source/plasma-integration/src/platformtheme/kwaylandintegration.cpp:159
    #4  0x00007f553d8b37c6 in KWaylandIntegration::eventFilter (this=0x1c5bdd0, watched=0x1c38d10, event=0x7ffee01dfbb0)
        at /home/jblackquill/KDE/Source/plasma-integration/src/platformtheme/kwaylandintegration.cpp:99
    #5  0x00007f55502f375e in QCoreApplicationPrivate::sendThroughApplicationEventFilters (event=<optimized out>, receiver=<optimized out>, this=<optimized out>)
        at /home/jblackquill/KDE/Source/Qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1172
    #6  QCoreApplicationPrivate::sendThroughApplicationEventFilters (this=this@entry=0x1c38f10, receiver=receiver@entry=0x1c38d10, event=event@entry=0x7ffee01dfbb0)
        at /home/jblackquill/KDE/Source/Qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1157
    #7  0x00007f5551055ac8 in QApplicationPrivate::notify_helper (this=0x1c38f10, receiver=0x1c38d10, e=0x7ffee01dfbb0)
        at /home/jblackquill/KDE/Source/Qt5/qtbase/src/widgets/kernel/qapplication.cpp:3603
    #8  0x00007f55502f3afa in QCoreApplication::notifyInternal2 (receiver=0x1c38d10, event=0x7ffee01dfbb0)
        at /home/jblackquill/KDE/Source/Qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1064
    #9  0x00007f5550818ba2 in QGuiApplicationPrivate::handlePaletteChanged (this=0x7ffee01dfbb0, className=0x0)
        at ../../include/QtCore/../../../../../Source/Qt5/qtbase/src/corelib/kernel/qcoreapplication.h:116
    #10 QGuiApplicationPrivate::handlePaletteChanged (this=this@entry=0x1c38f10, className=className@entry=0x0)
        at /home/jblackquill/KDE/Source/Qt5/qtbase/src/gui/kernel/qguiapplication.cpp:3444
    #11 0x00007f555105a4b9 in QApplicationPrivate::handlePaletteChanged (this=0x1c38f10, className=0x0) at /home/jblackquill/KDE/Source/Qt5/qtbase/src/widgets/kernel/qapplication.cpp:1368
    #12 0x00007f555222935c in activateScheme (colorSchemePath=..., overrideAutoSwitch=true) at /home/jblackquill/KDE/Source/kconfigwidgets/src/kcolorschememanager.cpp:41
    #13 0x00007f555222a818 in KColorSchemeManager::activateScheme (this=0x1c70f10, index=...) at /home/jblackquill/KDE/Source/kconfigwidgets/src/kcolorschememanager.cpp:223
    #14 0x00007f55522299b1 in KColorSchemeManager::KColorSchemeManager (this=0x1c70f10, parent=0x1cc4fc0) at /home/jblackquill/KDE/Source/kconfigwidgets/src/kcolorschememanager.cpp:109
    #15 0x00007f5552c593ad in AppColorSchemeChooser::AppColorSchemeChooser (this=0x1e72190, parent=0x1cc4fc0) at /home/jblackquill/KDE/Source/konsole/src/AppColorSchemeChooser.cpp:23
    #16 0x00007f5552e8b9dc in Konsole::MainWindow::setupActions (this=0x1d043e0) at /home/jblackquill/KDE/Source/konsole/src/MainWindow.cpp:346
    #17 0x00007f5552e89257 in Konsole::MainWindow::MainWindow (this=0x1d043e0, __in_chrg=<optimized out>, __vtt_parm=<optimized out>)
        at /home/jblackquill/KDE/Source/konsole/src/MainWindow.cpp:80
    #18 0x00007f5552e7f03d in Konsole::Application::newMainWindow (this=0x7ffee01e0730) at /home/jblackquill/KDE/Source/konsole/src/Application.cpp:122
    #19 0x00007f5552e80d3e in Konsole::Application::processWindowArgs (this=0x7ffee01e0730, createdNewMainWindow=@0x7ffee01e05ef: true)
        at /home/jblackquill/KDE/Source/konsole/src/Application.cpp:383
    #20 0x00007f5552e7f510 in Konsole::Application::newInstance (this=0x7ffee01e0730) at /home/jblackquill/KDE/Source/konsole/src/Application.cpp:171
    #21 0x000000000040571e in main (argc=1, argv=0x7ffee01e0ac8) at /home/jblackquill/KDE/Source/konsole/src/main.cpp:228
Supports Markdown
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