diff --git a/CMakeLists.txt b/CMakeLists.txt index 393b5c217..8cf6466f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,715 +1,716 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) project(KWIN) set(PROJECT_VERSION "5.13.80") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.9.0") set(KF5_MIN_VERSION "5.42.0") set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH} ) find_package(ECM 5.38 REQUIRED NO_MODULE) include(FeatureSummary) include(WriteBasicConfigVersionFile) include(GenerateExportHeader) # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Concurrent Core DBus Quick QuickWidgets Sensors Script UiTools Widgets X11Extras ) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG QUIET) set_package_properties(Qt5Test PROPERTIES PURPOSE "Required for tests" TYPE OPTIONAL ) add_feature_info("Qt5Test" Qt5Test_FOUND "Required for building tests") if (NOT Qt5Test_FOUND) set(BUILD_TESTING OFF CACHE BOOL "Build the testing tree.") endif() include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(ECMOptionalAddSubdirectory) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0 -DQT_USE_QSTRINGBUILDER) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") endif() find_package(Qt5Multimedia QUIET) set_package_properties(Qt5Multimedia PROPERTIES PURPOSE "Runtime-only dependency for effect video playback" TYPE RUNTIME ) # required frameworks by Core find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Config ConfigWidgets CoreAddons Crash GlobalAccel I18n Init Notifications Package Plasma WidgetsAddons WindowSystem IconThemes IdleTime Wayland ) # required frameworks by config modules find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Completion Declarative KCMUtils KIO TextWidgets NewStuff Service XmlGui ) find_package(Threads) set_package_properties(Threads PROPERTIES PURPOSE "Needed for VirtualTerminal support in KWin Wayland" TYPE REQUIRED ) # optional frameworks find_package(KF5Activities ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5Activities PROPERTIES PURPOSE "Enable building of KWin with kactivities support" TYPE OPTIONAL ) add_feature_info("KF5Activities" KF5Activities_FOUND "Enable building of KWin with kactivities support") find_package(KF5DocTools ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5DocTools PROPERTIES PURPOSE "Enable building documentation" TYPE OPTIONAL ) add_feature_info("KF5DocTools" KF5DocTools_FOUND "Enable building documentation") find_package(KDecoration2 CONFIG REQUIRED) find_package(KScreenLocker CONFIG REQUIRED) set_package_properties(KScreenLocker PROPERTIES TYPE REQUIRED PURPOSE "For screenlocker integration in kwin_wayland") find_package(Breeze 5.9.0 CONFIG) set_package_properties(Breeze PROPERTIES TYPE OPTIONAL PURPOSE "For setting the default window decoration plugin") if(${Breeze_FOUND}) if(${BREEZE_WITH_KDECORATION}) set(HAVE_BREEZE_DECO true) else() set(HAVE_BREEZE_DECO FALSE) endif() else() set(HAVE_BREEZE_DECO FALSE) endif() add_feature_info("Breeze-Decoration" HAVE_BREEZE_DECO "Default decoration plugin Breeze") find_package(EGL) set_package_properties(EGL PROPERTIES TYPE RUNTIME PURPOSE "Required to build KWin with EGL support" ) find_package(epoxy) set_package_properties(epoxy PROPERTIES DESCRIPTION "libepoxy" URL "http://github.com/anholt/libepoxy" TYPE REQUIRED PURPOSE "OpenGL dispatch library" ) set(HAVE_DL_LIBRARY FALSE) if(epoxy_HAS_GLX) find_library(DL_LIBRARY dl) if(DL_LIBRARY) set(HAVE_DL_LIBRARY TRUE) endif() endif() find_package(Wayland 1.2 REQUIRED COMPONENTS Cursor OPTIONAL_COMPONENTS Egl) set_package_properties(Wayland PROPERTIES TYPE REQUIRED PURPOSE "Required for building KWin with Wayland support" ) add_feature_info("Wayland::EGL" Wayland_Egl_FOUND "Enable building of Wayland backend and QPA with EGL support.") set(HAVE_WAYLAND_EGL FALSE) if(Wayland_Egl_FOUND) set(HAVE_WAYLAND_EGL TRUE) endif() find_package(XKB 0.7.0) set_package_properties(XKB PROPERTIES TYPE REQUIRED PURPOSE "Required for building KWin with Wayland support" ) find_package(Libinput 1.9) set_package_properties(Libinput PROPERTIES TYPE REQUIRED PURPOSE "Required for input handling on Wayland.") find_package(UDev) set_package_properties(UDev PROPERTIES URL "http://www.freedesktop.org/software/systemd/libudev/" DESCRIPTION "Linux device library." TYPE REQUIRED PURPOSE "Required for input handling on Wayland." ) find_package(Libdrm 2.4.62) set_package_properties(Libdrm PROPERTIES TYPE OPTIONAL PURPOSE "Required for drm output on Wayland.") set(HAVE_DRM FALSE) if(Libdrm_FOUND) set(HAVE_DRM TRUE) endif() find_package(gbm) set_package_properties(gbm PROPERTIES TYPE OPTIONAL PURPOSE "Required for egl ouput of drm backend.") set(HAVE_GBM FALSE) if(HAVE_DRM AND gbm_FOUND) set(HAVE_GBM TRUE) endif() find_package(libhybris) set_package_properties(libhybris PROPERTIES TYPE OPTIONAL PURPOSE "Required for libhybris backend") set(HAVE_LIBHYBRIS ${libhybris_FOUND}) find_package(X11) set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries" URL "http://www.x.org" TYPE REQUIRED ) add_feature_info("XInput" X11_Xinput_FOUND "Required for poll-free mouse cursor updates") set(HAVE_X11_XINPUT ${X11_Xinput_FOUND}) # All the required XCB components find_package(XCB 1.10 REQUIRED COMPONENTS XCB XFIXES DAMAGE COMPOSITE SHAPE SYNC RENDER RANDR KEYSYMS IMAGE SHM GLX CURSOR ICCCM ) set_package_properties(XCB PROPERTIES TYPE REQUIRED) # and the optional XCB dependencies if (XCB_ICCCM_VERSION VERSION_LESS "0.4") set(XCB_ICCCM_FOUND FALSE) endif() add_feature_info("XCB-ICCCM" XCB_ICCCM_FOUND "Required for building test applications for KWin") find_package(X11_XCB) set_package_properties(X11_XCB PROPERTIES PURPOSE "Required for building X11 windowed backend of kwin_wayland" TYPE OPTIONAL) # dependencies for QPA plugin find_package(Qt5FontDatabaseSupport REQUIRED) find_package(Qt5ThemeSupport REQUIRED) find_package(Qt5EventDispatcherSupport REQUIRED) find_package(Freetype REQUIRED) set_package_properties(Freetype PROPERTIES DESCRIPTION "A font rendering engine" URL "http://www.freetype.org" TYPE REQUIRED PURPOSE "Needed for KWin's QPA plugin." ) find_package(Fontconfig REQUIRED) set_package_properties(Fontconfig PROPERTIES DESCRIPTION "Font access configuration library" URL "http://www.freedesktop.org/wiki/Software/fontconfig" TYPE REQUIRED PURPOSE "Needed for KWin's QPA plugin." ) find_package(Xwayland) set_package_properties(Xwayland PROPERTIES URL "http://x.org" DESCRIPTION "Xwayland X server" TYPE RUNTIME PURPOSE "Needed for running kwin_wayland" ) find_package(Libcap) set_package_properties(Libcap PROPERTIES TYPE OPTIONAL PURPOSE "Needed for running kwin_wayland with real-time scheduling policy" ) set(HAVE_LIBCAP ${Libcap_FOUND}) include(ECMQMLModules) ecm_find_qmlmodule(QtQuick 2.3) ecm_find_qmlmodule(QtQuick.Controls 1.2) ecm_find_qmlmodule(QtQuick.Layouts 1.3) ecm_find_qmlmodule(QtQuick.VirtualKeyboard 2.1) ecm_find_qmlmodule(QtQuick.Window 2.1) ecm_find_qmlmodule(QtMultimedia 5.0) ecm_find_qmlmodule(org.kde.kquickcontrolsaddons 2.0) ecm_find_qmlmodule(org.kde.plasma.core 2.0) ecm_find_qmlmodule(org.kde.plasma.components 2.0) ########### configure tests ############### include(CMakeDependentOption) option(KWIN_BUILD_DECORATIONS "Enable building of KWin decorations." ON) option(KWIN_BUILD_KCMS "Enable building of KWin configuration modules." ON) option(KWIN_BUILD_TABBOX "Enable building of KWin Tabbox functionality" ON) option(KWIN_BUILD_XRENDER_COMPOSITING "Enable building of KWin with XRender Compositing support" ON) cmake_dependent_option(KWIN_BUILD_ACTIVITIES "Enable building of KWin with kactivities support" ON "KF5Activities_FOUND" OFF) # Binary name of KWin set(KWIN_NAME "kwin") set(KWIN_INTERNAL_NAME_X11 "kwin_x11") set(KWIN_INTERNAL_NAME_WAYLAND "kwin_wayland") set(KWIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # KWIN_HAVE_XRENDER_COMPOSITING - whether XRender-based compositing support is available: may be disabled if( KWIN_BUILD_XRENDER_COMPOSITING ) set( KWIN_HAVE_XRENDER_COMPOSITING 1 ) endif() include_directories(${XKB_INCLUDE_DIR}) include_directories(${epoxy_INCLUDE_DIR}) set(HAVE_EPOXY_GLX ${epoxy_HAS_GLX}) # for things that are also used by kwin libraries configure_file(libkwineffects/kwinconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/libkwineffects/kwinconfig.h ) # for kwin internal things set(HAVE_X11_XCB ${X11_XCB_FOUND}) include(CheckIncludeFile) include(CheckIncludeFiles) include(CheckSymbolExists) check_include_files(unistd.h HAVE_UNISTD_H) check_include_files(malloc.h HAVE_MALLOC_H) check_include_file("sys/prctl.h" HAVE_SYS_PRCTL_H) check_symbol_exists(PR_SET_DUMPABLE "sys/prctl.h" HAVE_PR_SET_DUMPABLE) check_symbol_exists(PR_SET_PDEATHSIG "sys/prctl.h" HAVE_PR_SET_PDEATHSIG) check_include_file("sys/procctl.h" HAVE_SYS_PROCCTL_H) check_symbol_exists(PROC_TRACE_CTL "sys/procctl.h" HAVE_PROC_TRACE_CTL) if (HAVE_PR_SET_DUMPABLE OR HAVE_PROC_TRACE_CTL) set(CAN_DISABLE_PTRACE TRUE) endif() add_feature_info("prctl/procctl tracing control" CAN_DISABLE_PTRACE "Required for disallowing ptrace on kwin_wayland process") check_include_file("sys/sysmacros.h" HAVE_SYS_SYSMACROS_H) configure_file(config-kwin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kwin.h ) check_include_file("linux/vt.h" HAVE_LINUX_VT_H) add_feature_info("linux/vt.h" HAVE_LINUX_VT_H "Required for virtual terminal support under wayland") check_include_file("linux/fb.h" HAVE_LINUX_FB_H) add_feature_info("linux/fb.h" HAVE_LINUX_FB_H "Required for the fbdev backend") check_symbol_exists(SCHED_RESET_ON_FORK "sched.h" HAVE_SCHED_RESET_ON_FORK) add_feature_info("SCHED_RESET_ON_FORK" HAVE_SCHED_RESET_ON_FORK "Required for running kwin_wayland with real-time scheduling") ########### global ############### set(kwin_effects_dbus_xml ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.kwin.Effects.xml) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/libkwineffects ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libkwineffects ${CMAKE_CURRENT_SOURCE_DIR}/effects ${CMAKE_CURRENT_SOURCE_DIR}/tabbox ${CMAKE_CURRENT_SOURCE_DIR}/platformsupport ) add_subdirectory( libkwineffects ) if(KWIN_BUILD_KCMS) add_subdirectory( kcmkwin ) endif() add_subdirectory( data ) add_subdirectory( effects ) add_subdirectory( scripts ) add_subdirectory( tabbox ) add_subdirectory(scripting) add_subdirectory(helpers) ########### next target ############### set(kwin_KDEINIT_SRCS workspace.cpp dbusinterface.cpp + virtualdesktopsdbustypes.cpp abstract_client.cpp client.cpp client_machine.cpp cursor.cpp debug_console.cpp tabgroup.cpp focuschain.cpp globalshortcuts.cpp input.cpp input_event.cpp input_event_spy.cpp keyboard_input.cpp keyboard_layout.cpp keyboard_layout_switching.cpp keyboard_repeat.cpp pointer_input.cpp touch_input.cpp netinfo.cpp placement.cpp atoms.cpp utils.cpp layers.cpp main.cpp options.cpp outline.cpp events.cpp killwindow.cpp geometrytip.cpp screens.cpp shadow.cpp sm.cpp group.cpp manage.cpp overlaywindow.cpp activation.cpp useractions.cpp geometry.cpp rules.cpp composite.cpp toplevel.cpp unmanaged.cpp scene.cpp screenlockerwatcher.cpp thumbnailitem.cpp lanczosfilter.cpp deleted.cpp effects.cpp effectloader.cpp virtualdesktops.cpp xcbutils.cpp x11eventfilter.cpp logind.cpp onscreennotification.cpp osd.cpp screenedge.cpp scripting/scripting.cpp scripting/workspace_wrapper.cpp scripting/meta.cpp scripting/scriptedeffect.cpp scripting/scriptingutils.cpp scripting/timer.cpp scripting/scripting_model.cpp scripting/dbuscall.cpp scripting/screenedgeitem.cpp scripting/scripting_logging.cpp decorations/decoratedclient.cpp decorations/decorationbridge.cpp decorations/decorationpalette.cpp decorations/settings.cpp decorations/decorationrenderer.cpp decorations/decorations_logging.cpp platform.cpp shell_client.cpp wayland_server.cpp wayland_cursor_theme.cpp virtualkeyboard.cpp virtualkeyboard_dbus.cpp appmenu.cpp modifier_only_shortcuts.cpp xkb.cpp gestures.cpp popup_input_filter.cpp colorcorrection/manager.cpp colorcorrection/colorcorrectdbusinterface.cpp colorcorrection/suncalc.cpp abstract_opengl_context_attribute_builder.cpp egl_context_attribute_builder.cpp was_user_interaction_x11_filter.cpp moving_client_x11_filter.cpp window_property_notify_x11_filter.cpp rootinfo_filter.cpp orientation_sensor.cpp idle_inhibition.cpp libinput/context.cpp libinput/connection.cpp libinput/device.cpp libinput/events.cpp libinput/libinput_logging.cpp udev.cpp ) include(ECMQtDeclareLoggingCategory) ecm_qt_declare_logging_category(kwin_KDEINIT_SRCS HEADER colorcorrect_logging.h IDENTIFIER KWIN_COLORCORRECTION CATEGORY_NAME kwin_colorcorrection DEFAULT_SEVERITY Critical ) if(KWIN_BUILD_TABBOX) set( kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} tabbox/tabbox.cpp tabbox/clientmodel.cpp tabbox/desktopchain.cpp tabbox/desktopmodel.cpp tabbox/switcheritem.cpp tabbox/tabboxconfig.cpp tabbox/tabboxhandler.cpp tabbox/tabbox_logging.cpp tabbox/x11_filter.cpp ) endif() if(KWIN_BUILD_ACTIVITIES) set( kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} activities.cpp ) endif() if (HAVE_LINUX_VT_H) set(kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} virtual_terminal.cpp ) endif() kconfig_add_kcfg_files(kwin_KDEINIT_SRCS settings.kcfgc) kconfig_add_kcfg_files(kwin_KDEINIT_SRCS colorcorrection/colorcorrect_settings.kcfgc) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml dbusinterface.h KWin::DBusInterface ) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.Compositing.xml dbusinterface.h KWin::CompositorDBusInterface ) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.ColorCorrect.xml colorcorrection/colorcorrectdbusinterface.h KWin::ColorCorrect::ColorCorrectDBusInterface ) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS ${kwin_effects_dbus_xml} effects.h KWin::EffectsHandlerImpl ) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.kwin.OrientationSensor.xml orientation_sensor.h KWin::OrientationSensor) qt5_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.VirtualDesktopManager.xml dbusinterface.h KWin::VirtualDesktopManagerDBusInterface ) qt5_add_dbus_interface( kwin_KDEINIT_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ScreenSaver.xml screenlocker_interface) qt5_add_dbus_interface( kwin_KDEINIT_SRCS org.kde.kappmenu.xml appmenu_interface ) qt5_add_resources( kwin_KDEINIT_SRCS resources.qrc ) ki18n_wrap_ui(kwin_KDEINIT_SRCS debug_console.ui shortcutdialog.ui ) ########### target link libraries ############### set(kwin_OWN_LIBS kwineffects kwin4_effect_builtins ) set(kwin_QT_LIBS Qt5::Concurrent Qt5::DBus Qt5::Quick Qt5::Sensors Qt5::Script ) set(kwin_KDE_LIBS KF5::ConfigCore KF5::CoreAddons KF5::ConfigWidgets KF5::GlobalAccel KF5::GlobalAccelPrivate KF5::I18n KF5::Notifications KF5::Package KF5::Plasma KF5::WindowSystem KF5::QuickAddons KDecoration2::KDecoration KDecoration2::KDecoration2Private PW::KScreenLocker ) set(kwin_XLIB_LIBS ${X11_X11_LIB} ${X11_ICE_LIB} ${X11_SM_LIB} ) set(kwin_XCB_LIBS XCB::XCB XCB::XFIXES XCB::DAMAGE XCB::COMPOSITE XCB::SHAPE XCB::SYNC XCB::RENDER XCB::RANDR XCB::KEYSYMS XCB::SHM XCB::GLX XCB::ICCCM ) set(kwin_WAYLAND_LIBS XKB::XKB KF5::WaylandClient KF5::WaylandServer Wayland::Cursor ${CMAKE_THREAD_LIBS_INIT} ) if(KWIN_BUILD_ACTIVITIES) set(kwin_KDE_LIBS ${kwin_KDE_LIBS} KF5::Activities) endif() set(kwinLibs ${kwin_OWN_LIBS} ${kwin_QT_LIBS} ${kwin_KDE_LIBS} ${kwin_XLIB_LIBS} ${kwin_XCB_LIBS} ${kwin_WAYLAND_LIBS} ${UDEV_LIBS} Libinput::Libinput ) add_library(kwin SHARED ${kwin_KDEINIT_SRCS}) set_target_properties(kwin PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) target_link_libraries(kwin ${kwinLibs}) generate_export_header(kwin EXPORT_FILE_NAME kwin_export.h) target_link_libraries(kwin kwinglutils ${epoxy_LIBRARY}) kf5_add_kdeinit_executable(kwin_x11 main_x11.cpp) target_link_libraries(kdeinit_kwin_x11 kwin KF5::Crash Qt5::X11Extras) install(TARGETS kwin ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP ) install(TARGETS kdeinit_kwin_x11 ${INSTALL_TARGETS_DEFAULT_ARGS} ) install(TARGETS kwin_x11 ${INSTALL_TARGETS_DEFAULT_ARGS} ) add_executable(kwin_wayland tabletmodemanager.cpp main_wayland.cpp) target_link_libraries(kwin_wayland kwin) if (HAVE_LIBCAP) target_link_libraries(kwin_wayland ${Libcap_LIBRARIES}) endif() install(TARGETS kwin_wayland ${INSTALL_TARGETS_DEFAULT_ARGS} ) if (HAVE_LIBCAP) install( CODE "execute_process( COMMAND ${SETCAP_EXECUTABLE} CAP_SYS_NICE=+ep \$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/kwin_wayland)" ) endif() add_subdirectory(platformsupport) add_subdirectory(plugins) ########### install files ############### install( FILES kwin.kcfg DESTINATION ${KCFG_INSTALL_DIR} RENAME ${KWIN_NAME}.kcfg ) install( FILES colorcorrection/colorcorrect_settings.kcfg DESTINATION ${KCFG_INSTALL_DIR} RENAME ${KWIN_NAME}_colorcorrect.kcfg ) install( FILES kwin.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR} RENAME ${KWIN_NAME}.notifyrc) install( FILES org.kde.KWin.xml org.kde.kwin.Compositing.xml org.kde.kwin.ColorCorrect.xml org.kde.kwin.Effects.xml org.kde.KWin.VirtualDesktopManager.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR} ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/kwin_export.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) # Install the KWin/Script service type install( FILES scripting/kwinscript.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) ecm_install_icons( ICONS 16-apps-kwin.png 32-apps-kwin.png 48-apps-kwin.png sc-apps-kwin.svgz DESTINATION ${ICON_INSTALL_DIR} THEME hicolor ) add_subdirectory(qml) add_subdirectory(packageplugins) if (BUILD_TESTING) add_subdirectory(autotests) add_subdirectory(tests) endif() if (KF5DocTools_FOUND) add_subdirectory(doc) endif() feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) include(CMakePackageConfigHelpers) set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KWinDBusInterface") configure_package_config_file(KWinDBusInterfaceConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/KWinDBusInterfaceConfig.cmake" PATH_VARS KDE_INSTALL_DBUSINTERFACEDIR INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/KWinDBusInterfaceConfig.cmake DESTINATION ${CMAKECONFIG_INSTALL_DIR}) diff --git a/dbusinterface.cpp b/dbusinterface.cpp index 7d0956ad0..1a4da99a6 100644 --- a/dbusinterface.cpp +++ b/dbusinterface.cpp @@ -1,544 +1,495 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2012 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ // own #include "dbusinterface.h" #include "compositingadaptor.h" #include "virtualdesktopmanageradaptor.h" // kwin #include "abstract_client.h" #include "atoms.h" #include "composite.h" #include "debug_console.h" #include "main.h" #include "placement.h" #include "platform.h" #include "kwinadaptor.h" #include "scene.h" #include "workspace.h" #include "virtualdesktops.h" #ifdef KWIN_BUILD_ACTIVITIES #include "activities.h" #endif // Qt #include #include - -// Marshall the DBusDesktopDataStruct data into a D-BUS argument -const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataStruct &desk) -{ - argument.beginStructure(); - argument << desk.position; - argument << desk.id; - argument << desk.name; - argument.endStructure(); - return argument; -} -// Retrieve -const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataStruct &desk) -{ - argument.beginStructure(); - argument >> desk.position; - argument >> desk.id; - argument >> desk.name; - argument.endStructure(); - return argument; -} - -const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataVector &deskVector) -{ - argument.beginArray(qMetaTypeId()); - for (int i = 0; i < deskVector.size(); ++i) { - argument << deskVector[i]; - } - argument.endArray(); - return argument; -} - -const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataVector &deskVector) -{ - argument.beginArray(); - deskVector.clear(); - - while (!argument.atEnd()) { - KWin::DBusDesktopDataStruct element; - argument >> element; - deskVector.append(element); - } - - argument.endArray(); - - return argument; -} - - namespace KWin { DBusInterface::DBusInterface(QObject *parent) : QObject(parent) , m_serviceName(QStringLiteral("org.kde.KWin")) { (void) new KWinAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject(QStringLiteral("/KWin"), this); const QByteArray dBusSuffix = qgetenv("KWIN_DBUS_SERVICE_SUFFIX"); if (!dBusSuffix.isNull()) { m_serviceName = m_serviceName + QLatin1Char('.') + dBusSuffix; } if (!dbus.registerService(m_serviceName)) { QDBusServiceWatcher *dog = new QDBusServiceWatcher(m_serviceName, dbus, QDBusServiceWatcher::WatchForUnregistration, this); connect (dog, SIGNAL(serviceUnregistered(QString)), SLOT(becomeKWinService(QString))); } else { announceService(); } dbus.connect(QString(), QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig"), Workspace::self(), SLOT(slotReloadConfig())); connect(kwinApp(), &Application::x11ConnectionChanged, this, &DBusInterface::announceService); } void DBusInterface::becomeKWinService(const QString &service) { // TODO: this watchdog exists to make really safe that we at some point get the service // but it's probably no longer needed since we explicitly unregister the service with the deconstructor if (service == m_serviceName && QDBusConnection::sessionBus().registerService(m_serviceName) && sender()) { sender()->deleteLater(); // bye doggy :'( announceService(); } } DBusInterface::~DBusInterface() { QDBusConnection::sessionBus().unregisterService(m_serviceName); // KApplication automatically also grabs org.kde.kwin, so it's often been used externally - ensure to free it as well QDBusConnection::sessionBus().unregisterService(QStringLiteral("org.kde.kwin")); if (kwinApp()->x11Connection()) { xcb_delete_property(kwinApp()->x11Connection(), kwinApp()->x11RootWindow(), atoms->kwin_dbus_service); } } void DBusInterface::announceService() { if (!kwinApp()->x11Connection()) { return; } const QByteArray service = m_serviceName.toUtf8(); xcb_change_property(kwinApp()->x11Connection(), XCB_PROP_MODE_REPLACE, kwinApp()->x11RootWindow(), atoms->kwin_dbus_service, atoms->utf8_string, 8, service.size(), service.constData()); } // wrap void methods with no arguments to Workspace #define WRAP(name) \ void DBusInterface::name() \ {\ Workspace::self()->name();\ } WRAP(reconfigure) #undef WRAP void DBusInterface::killWindow() { Workspace::self()->slotKillWindow(); } #define WRAP(name) \ void DBusInterface::name() \ {\ Placement::self()->name();\ } WRAP(cascadeDesktop) WRAP(unclutterDesktop) #undef WRAP // wrap returning methods with no arguments to Workspace #define WRAP( rettype, name ) \ rettype DBusInterface::name( ) \ {\ return Workspace::self()->name(); \ } WRAP(QString, supportInformation) #undef WRAP bool DBusInterface::startActivity(const QString &in0) { #ifdef KWIN_BUILD_ACTIVITIES if (!Activities::self()) { return false; } return Activities::self()->start(in0); #else Q_UNUSED(in0) return false; #endif } bool DBusInterface::stopActivity(const QString &in0) { #ifdef KWIN_BUILD_ACTIVITIES if (!Activities::self()) { return false; } return Activities::self()->stop(in0); #else Q_UNUSED(in0) return false; #endif } int DBusInterface::currentDesktop() { return VirtualDesktopManager::self()->current(); } bool DBusInterface::setCurrentDesktop(int desktop) { return VirtualDesktopManager::self()->setCurrent(desktop); } void DBusInterface::nextDesktop() { VirtualDesktopManager::self()->moveTo(); } void DBusInterface::previousDesktop() { VirtualDesktopManager::self()->moveTo(); } void DBusInterface::showDebugConsole() { DebugConsole *console = new DebugConsole; console->show(); } QVariantMap DBusInterface::queryWindowInfo() { m_replyQueryWindowInfo = message(); setDelayedReply(true); kwinApp()->platform()->startInteractiveWindowSelection( [this] (Toplevel *t) { if (auto c = qobject_cast(t)) { const QVariantMap ret{ {QStringLiteral("resourceClass"), c->resourceClass()}, {QStringLiteral("resourceName"), c->resourceName()}, {QStringLiteral("desktopFile"), c->desktopFileName()}, {QStringLiteral("role"), c->windowRole()}, {QStringLiteral("caption"), c->captionNormal()}, {QStringLiteral("clientMachine"), c->wmClientMachine(true)}, {QStringLiteral("type"), c->windowType()}, {QStringLiteral("x"), c->x()}, {QStringLiteral("y"), c->y()}, {QStringLiteral("width"), c->width()}, {QStringLiteral("height"), c->height()}, {QStringLiteral("x11DesktopNumber"), c->desktop()}, {QStringLiteral("minimized"), c->isMinimized()}, {QStringLiteral("shaded"), c->isShade()}, {QStringLiteral("fullscreen"), c->isFullScreen()}, {QStringLiteral("keepAbove"), c->keepAbove()}, {QStringLiteral("keepBelow"), c->keepBelow()}, {QStringLiteral("noBorder"), c->noBorder()}, {QStringLiteral("skipTaskbar"), c->skipTaskbar()}, {QStringLiteral("skipPager"), c->skipPager()}, {QStringLiteral("skipSwitcher"), c->skipSwitcher()}, {QStringLiteral("maximizeHorizontal"), c->maximizeMode() & MaximizeHorizontal}, {QStringLiteral("maximizeVertical"), c->maximizeMode() & MaximizeVertical} }; QDBusConnection::sessionBus().send(m_replyQueryWindowInfo.createReply(ret)); } else { QDBusConnection::sessionBus().send(m_replyQueryWindowInfo.createErrorReply(QString(), QString())); } } ); return QVariantMap{}; } CompositorDBusInterface::CompositorDBusInterface(Compositor *parent) : QObject(parent) , m_compositor(parent) { connect(m_compositor, &Compositor::compositingToggled, this, &CompositorDBusInterface::compositingToggled); new CompositingAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject(QStringLiteral("/Compositor"), this); dbus.connect(QString(), QStringLiteral("/Compositor"), QStringLiteral("org.kde.kwin.Compositing"), QStringLiteral("reinit"), m_compositor, SLOT(slotReinitialize())); } QString CompositorDBusInterface::compositingNotPossibleReason() const { return kwinApp()->platform()->compositingNotPossibleReason(); } QString CompositorDBusInterface::compositingType() const { if (!m_compositor->hasScene()) { return QStringLiteral("none"); } switch (m_compositor->scene()->compositingType()) { case XRenderCompositing: return QStringLiteral("xrender"); case OpenGL2Compositing: if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { return QStringLiteral("gles"); } else { return QStringLiteral("gl2"); } case QPainterCompositing: return QStringLiteral("qpainter"); case NoCompositing: default: return QStringLiteral("none"); } } bool CompositorDBusInterface::isActive() const { return m_compositor->isActive(); } bool CompositorDBusInterface::isCompositingPossible() const { return kwinApp()->platform()->compositingPossible(); } bool CompositorDBusInterface::isOpenGLBroken() const { return kwinApp()->platform()->openGLCompositingIsBroken(); } bool CompositorDBusInterface::platformRequiresCompositing() const { return kwinApp()->platform()->requiresCompositing(); } void CompositorDBusInterface::resume() { m_compositor->resume(Compositor::ScriptSuspend); } void CompositorDBusInterface::suspend() { m_compositor->suspend(Compositor::ScriptSuspend); } QStringList CompositorDBusInterface::supportedOpenGLPlatformInterfaces() const { QStringList interfaces; bool supportsGlx = false; #if HAVE_EPOXY_GLX supportsGlx = (kwinApp()->operationMode() == Application::OperationModeX11); #endif if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { supportsGlx = false; } if (supportsGlx) { interfaces << QStringLiteral("glx"); } interfaces << QStringLiteral("egl"); return interfaces; } VirtualDesktopManagerDBusInterface::VirtualDesktopManagerDBusInterface(VirtualDesktopManager *parent) : QObject(parent) , m_manager(parent) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); new VirtualDesktopManagerAdaptor(this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/VirtualDesktopManager"), QStringLiteral("org.kde.KWin.VirtualDesktopManager"), this ); connect(m_manager, &VirtualDesktopManager::currentChanged, this, [this](uint previousDesktop, uint newDesktop) { Q_UNUSED(previousDesktop); Q_UNUSED(newDesktop); emit currentChanged(m_manager->currentDesktop()->id()); } ); connect(m_manager, &VirtualDesktopManager::countChanged, this, [this](uint previousCount, uint newCount) { Q_UNUSED(previousCount); emit countChanged(newCount); emit desktopsChanged(desktops()); } ); connect(m_manager, &VirtualDesktopManager::navigationWrappingAroundChanged, this, [this]() { emit navigationWrappingAroundChanged(isNavigationWrappingAround()); } ); connect(m_manager, &VirtualDesktopManager::rowsChanged, this, &VirtualDesktopManagerDBusInterface::rowsChanged); for (auto *vd : m_manager->desktops()) { connect(vd, &VirtualDesktop::x11DesktopNumberChanged, this, [this, vd]() { DBusDesktopDataStruct data{.position = vd->x11DesktopNumber() - 1, .id = vd->id(), .name = vd->name()}; emit desktopDataChanged(vd->id(), data); emit desktopsChanged(desktops()); } ); connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() { DBusDesktopDataStruct data{.position = vd->x11DesktopNumber() - 1, .id = vd->id(), .name = vd->name()}; emit desktopDataChanged(vd->id(), data); emit desktopsChanged(desktops()); } ); } connect(m_manager, &VirtualDesktopManager::desktopCreated, this, [this](VirtualDesktop *vd) { connect(vd, &VirtualDesktop::x11DesktopNumberChanged, this, [this, vd]() { DBusDesktopDataStruct data{.position = vd->x11DesktopNumber() - 1, .id = vd->id(), .name = vd->name()}; emit desktopDataChanged(vd->id(), data); emit desktopsChanged(desktops()); } ); connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() { DBusDesktopDataStruct data{.position = vd->x11DesktopNumber() - 1, .id = vd->id(), .name = vd->name()}; emit desktopDataChanged(vd->id(), data); emit desktopsChanged(desktops()); } ); DBusDesktopDataStruct data{.position = vd->x11DesktopNumber() - 1, .id = vd->id(), .name = vd->name()}; emit desktopCreated(vd->id(), data); emit desktopsChanged(desktops()); } ); connect(m_manager, &VirtualDesktopManager::desktopRemoved, this, [this](VirtualDesktop *vd) { emit desktopRemoved(vd->id()); emit desktopsChanged(desktops()); } ); } uint VirtualDesktopManagerDBusInterface::count() const { return m_manager->count(); } void VirtualDesktopManagerDBusInterface::setRows(uint rows) { if (static_cast(m_manager->grid().height()) == rows) { return; } m_manager->setRows(rows); m_manager->save(); } uint VirtualDesktopManagerDBusInterface::rows() const { return m_manager->rows(); } void VirtualDesktopManagerDBusInterface::setCurrent(const QString &id) { if (m_manager->currentDesktop()->id() == id) { return; } auto *vd = m_manager->desktopForId(id.toUtf8()); if (vd) { m_manager->setCurrent(vd); } } QString VirtualDesktopManagerDBusInterface::current() const { return m_manager->currentDesktop()->id(); } void VirtualDesktopManagerDBusInterface::setNavigationWrappingAround(bool wraps) { if (m_manager->isNavigationWrappingAround() == wraps) { return; } m_manager->setNavigationWrappingAround(wraps); } bool VirtualDesktopManagerDBusInterface::isNavigationWrappingAround() const { return m_manager->isNavigationWrappingAround(); } DBusDesktopDataVector VirtualDesktopManagerDBusInterface::desktops() const { const auto desks = m_manager->desktops(); DBusDesktopDataVector desktopVect; desktopVect.reserve(m_manager->count()); std::transform(desks.constBegin(), desks.constEnd(), std::back_inserter(desktopVect), [] (const VirtualDesktop *vd) { return DBusDesktopDataStruct{.position = vd->x11DesktopNumber() - 1, .id = vd->id(), .name = vd->name()}; } ); return desktopVect; } void VirtualDesktopManagerDBusInterface::createDesktop(uint position, const QString &name) { m_manager->createVirtualDesktop(position + 1, name); } void VirtualDesktopManagerDBusInterface::setDesktopName(const QString &id, const QString &name) { VirtualDesktop *vd = m_manager->desktopForId(id.toUtf8()); if (!vd) { return; } if (vd->name() == name) { return; } vd->setName(name); m_manager->save(); } void VirtualDesktopManagerDBusInterface::removeDesktop(const QString &id) { m_manager->removeVirtualDesktop(id.toUtf8()); } } // namespace diff --git a/dbusinterface.h b/dbusinterface.h index 0e5ec39ed..e07019ba3 100644 --- a/dbusinterface.h +++ b/dbusinterface.h @@ -1,262 +1,247 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2012 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #ifndef KWIN_DBUS_INTERFACE_H #define KWIN_DBUS_INTERFACE_H #include #include +#include "virtualdesktopsdbustypes.h" + namespace KWin { class Compositor; class VirtualDesktopManager; /** * @brief This class is a wrapper for the org.kde.KWin D-Bus interface. * * The main purpose of this class is to be exported on the D-Bus as object /KWin. * It is a pure wrapper to provide the deprecated D-Bus methods which have been * removed from Workspace which used to implement the complete D-Bus interface. * * Nowadays the D-Bus interfaces are distributed, parts of it are exported on * /Compositor, parts on /Effects and parts on /KWin. The implementation in this * class just delegates the method calls to the actual implementation in one of the * three singletons. * * @author Martin Gräßlin **/ class DBusInterface: public QObject, protected QDBusContext { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.KWin") public: explicit DBusInterface(QObject *parent); virtual ~DBusInterface(); public: // PROPERTIES public Q_SLOTS: // METHODS Q_NOREPLY void cascadeDesktop(); int currentDesktop(); Q_NOREPLY void killWindow(); void nextDesktop(); void previousDesktop(); Q_NOREPLY void reconfigure(); bool setCurrentDesktop(int desktop); bool startActivity(const QString &in0); bool stopActivity(const QString &in0); QString supportInformation(); Q_NOREPLY void unclutterDesktop(); Q_NOREPLY void showDebugConsole(); QVariantMap queryWindowInfo(); private Q_SLOTS: void becomeKWinService(const QString &service); private: void announceService(); QString m_serviceName; QDBusMessage m_replyQueryWindowInfo; }; class CompositorDBusInterface : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Compositing") /** * @brief Whether the Compositor is active. That is a Scene is present and the Compositor is * not shutting down itself. **/ Q_PROPERTY(bool active READ isActive) /** * @brief Whether compositing is possible. Mostly means whether the required X extensions * are available. **/ Q_PROPERTY(bool compositingPossible READ isCompositingPossible) /** * @brief The reason why compositing is not possible. Empty String if compositing is possible. **/ Q_PROPERTY(QString compositingNotPossibleReason READ compositingNotPossibleReason) /** * @brief Whether OpenGL has failed badly in the past (crash) and is considered as broken. **/ Q_PROPERTY(bool openGLIsBroken READ isOpenGLBroken) /** * The type of the currently used Scene: * @li @c none No Compositing * @li @c xrender XRender * @li @c gl1 OpenGL 1 * @li @c gl2 OpenGL 2 * @li @c gles OpenGL ES 2 **/ Q_PROPERTY(QString compositingType READ compositingType) /** * @brief All currently supported OpenGLPlatformInterfaces. * * Possible values: * @li glx * @li egl * * Values depend on operation mode and compile time options. **/ Q_PROPERTY(QStringList supportedOpenGLPlatformInterfaces READ supportedOpenGLPlatformInterfaces) Q_PROPERTY(bool platformRequiresCompositing READ platformRequiresCompositing) public: explicit CompositorDBusInterface(Compositor *parent); virtual ~CompositorDBusInterface() = default; bool isActive() const; bool isCompositingPossible() const; QString compositingNotPossibleReason() const; bool isOpenGLBroken() const; QString compositingType() const; QStringList supportedOpenGLPlatformInterfaces() const; bool platformRequiresCompositing() const; public Q_SLOTS: /** * @brief Suspends the Compositor if it is currently active. * * Note: it is possible that the Compositor is not able to suspend. Use @link isActive to check * whether the Compositor has been suspended. * * @return void * @see resume * @see isActive **/ void suspend(); /** * @brief Resumes the Compositor if it is currently suspended. * * Note: it is possible that the Compositor cannot be resumed, that is there might be Clients * blocking the usage of Compositing or the Scene might be broken. Use @link isActive to check * whether the Compositor has been resumed. Also check @link isCompositingPossible and * @link isOpenGLBroken. * * Note: The starting of the Compositor can require some time and is partially done threaded. * After this method returns the setup may not have been completed. * * @return void * @see suspend * @see isActive * @see isCompositingPossible * @see isOpenGLBroken **/ void resume(); Q_SIGNALS: void compositingToggled(bool active); private: Compositor *m_compositor; }; //TODO: disable all of this in case of kiosk? -struct DBusDesktopDataStruct { - uint position; - QString id; - QString name; -}; -typedef QVector DBusDesktopDataVector; - class VirtualDesktopManagerDBusInterface : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.KWin.VirtualDesktopManager") /** * The number of virtual desktops currently available. * The ids of the virtual desktops are in the range [1, VirtualDesktopManager::maximum()]. **/ Q_PROPERTY(uint count READ count NOTIFY countChanged) /** * The number of rows the virtual desktops will be laid out in **/ Q_PROPERTY(uint rows READ rows WRITE setRows NOTIFY rowsChanged) /** * The id of the virtual desktop which is currently in use. **/ Q_PROPERTY(QString current READ current WRITE setCurrent NOTIFY currentChanged) /** * Whether navigation in the desktop layout wraps around at the borders. **/ Q_PROPERTY(bool navigationWrappingAround READ isNavigationWrappingAround WRITE setNavigationWrappingAround NOTIFY navigationWrappingAroundChanged) /** * list of key/value pairs which every one of them is representing a desktop */ Q_PROPERTY(KWin::DBusDesktopDataVector desktops READ desktops NOTIFY desktopsChanged); public: VirtualDesktopManagerDBusInterface(VirtualDesktopManager *parent); ~VirtualDesktopManagerDBusInterface() = default; uint count() const; void setRows(uint rows); uint rows() const; void setCurrent(const QString &id); QString current() const; void setNavigationWrappingAround(bool wraps); bool isNavigationWrappingAround() const; KWin::DBusDesktopDataVector desktops() const; Q_SIGNALS: void countChanged(uint count); void rowsChanged(uint rows); void currentChanged(const QString &id); void navigationWrappingAroundChanged(bool wraps); void desktopsChanged(KWin::DBusDesktopDataVector); void desktopDataChanged(const QString &id, KWin::DBusDesktopDataStruct); void desktopCreated(const QString &id, KWin::DBusDesktopDataStruct); void desktopRemoved(const QString &id); public Q_SLOTS: /** * Create a desktop with a new name at a given position * note: the position starts from 1 */ void createDesktop(uint position, const QString &name); void setDesktopName(const QString &id, const QString &name); void removeDesktop(const QString &id); private: VirtualDesktopManager *m_manager; }; } // namespace -const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataStruct &desk); -const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataStruct &desk); - -Q_DECLARE_METATYPE(KWin::DBusDesktopDataStruct) - -const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataVector &deskVector); -const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataVector &deskVector); - -Q_DECLARE_METATYPE(KWin::DBusDesktopDataVector) - #endif // KWIN_DBUS_INTERFACE_H diff --git a/virtualdesktopsdbustypes.cpp b/virtualdesktopsdbustypes.cpp new file mode 100644 index 000000000..aa9af454a --- /dev/null +++ b/virtualdesktopsdbustypes.cpp @@ -0,0 +1,70 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2018 Marco Martin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +// own +#include "virtualdesktopsdbustypes.h" + + +// Marshall the DBusDesktopDataStruct data into a D-BUS argument +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataStruct &desk) +{ + argument.beginStructure(); + argument << desk.position; + argument << desk.id; + argument << desk.name; + argument.endStructure(); + return argument; +} +// Retrieve +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataStruct &desk) +{ + argument.beginStructure(); + argument >> desk.position; + argument >> desk.id; + argument >> desk.name; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataVector &deskVector) +{ + argument.beginArray(qMetaTypeId()); + for (int i = 0; i < deskVector.size(); ++i) { + argument << deskVector[i]; + } + argument.endArray(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataVector &deskVector) +{ + argument.beginArray(); + deskVector.clear(); + + while (!argument.atEnd()) { + KWin::DBusDesktopDataStruct element; + argument >> element; + deskVector.append(element); + } + + argument.endArray(); + + return argument; +} diff --git a/virtualdesktopsdbustypes.h b/virtualdesktopsdbustypes.h new file mode 100644 index 000000000..071ad0d94 --- /dev/null +++ b/virtualdesktopsdbustypes.h @@ -0,0 +1,47 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2018 Marco Martin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#ifndef KWIN_VIRTUALDESKTOPS_DBUS_TYPES_H +#define KWIN_VIRTUALDESKTOPS_DBUS_TYPES_H + +#include + +namespace KWin +{ + +struct DBusDesktopDataStruct { + uint position; + QString id; + QString name; +}; +typedef QVector DBusDesktopDataVector; +} + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataStruct &desk); +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataStruct &desk); + +Q_DECLARE_METATYPE(KWin::DBusDesktopDataStruct) + +const QDBusArgument &operator<<(QDBusArgument &argument, const KWin::DBusDesktopDataVector &deskVector); +const QDBusArgument &operator>>(const QDBusArgument &argument, KWin::DBusDesktopDataVector &deskVector); + +Q_DECLARE_METATYPE(KWin::DBusDesktopDataVector) + +#endif // KWIN_VIRTUALDESKTOPS_DBUS_TYPES_H