diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bfd9f5ed..ec7aadc5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,775 +1,775 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) project(KWin) set(PROJECT_VERSION "5.18.80") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.14.0") -set(KF5_MIN_VERSION "5.68.0") +set(KF5_MIN_VERSION "5.70.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 Script Sensors 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(KDEClangFormat) include(ECMInstallIcons) include(ECMOptionalAddSubdirectory) add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0 -DQT_USE_QSTRINGBUILDER -DQT_NO_URL_CAST_FROM_STRING) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) 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 IconThemes IdleTime Notifications Package Plasma Wayland WidgetsAddons WindowSystem ) # required frameworks by config modules find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Completion Declarative KCMUtils KIO NewStuff Service TextWidgets 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(KF5Kirigami2 ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5Kirigami2 PROPERTIES DESCRIPTION "A QtQuick based components set" PURPOSE "Required at runtime for Virtual desktop KCM and the virtual keyboard" TYPE RUNTIME ) find_package(KDecoration2 5.18.0 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 "https://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 "https://www.freedesktop.org/wiki/Software/systemd/" 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 output of drm backend.") set(HAVE_GBM FALSE) if (HAVE_DRM AND gbm_FOUND) set(HAVE_GBM TRUE) endif() option(KWIN_BUILD_EGL_STREAM_BACKEND "Enable building of EGLStream based DRM backend" ON) if (HAVE_DRM AND KWIN_BUILD_EGL_STREAM_BACKEND) set(HAVE_EGL_STREAMS 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 "https://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 COMPOSITE CURSOR DAMAGE GLX ICCCM IMAGE KEYSYMS RANDR RENDER SHAPE SHM SYNC XCB XFIXES ) 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 "https://www.freetype.org" TYPE REQUIRED PURPOSE "Needed for KWin's QPA plugin." ) find_package(Fontconfig REQUIRED) set_package_properties(Fontconfig PROPERTIES TYPE REQUIRED PURPOSE "Needed for KWin's QPA plugin." ) find_package(Xwayland) set_package_properties(Xwayland PROPERTIES URL "https://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}) find_package(hwdata) set_package_properties(hwdata PROPERTIES TYPE RUNTIME PURPOSE "Runtime-only dependency needed for mapping monitor hardware vendor IDs to full names" URL "https://github.com/vcrhonek/hwdata" ) 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") # 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) 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") configure_file(config-kwin.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kwin.h) ########### global ############### set(kwin_effects_dbus_xml ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.kwin.Effects.xml) qt5_add_dbus_interface(effects_interface_SRCS ${kwin_effects_dbus_xml} kwineffects_interface) add_library(KWinEffectsInterface STATIC ${effects_interface_SRCS}) target_link_libraries(KWinEffectsInterface Qt5::DBus) 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_SRCS abstract_client.cpp abstract_opengl_context_attribute_builder.cpp abstract_output.cpp abstract_wayland_output.cpp activation.cpp appmenu.cpp atoms.cpp client_machine.cpp colorcorrection/clockskewnotifier.cpp colorcorrection/clockskewnotifierengine.cpp colorcorrection/colorcorrectdbusinterface.cpp colorcorrection/manager.cpp colorcorrection/suncalc.cpp composite.cpp cursor.cpp dbusinterface.cpp debug_console.cpp decorations/decoratedclient.cpp decorations/decorationbridge.cpp decorations/decorationpalette.cpp decorations/decorationrenderer.cpp decorations/decorations_logging.cpp decorations/settings.cpp deleted.cpp effectloader.cpp effects.cpp egl_context_attribute_builder.cpp events.cpp focuschain.cpp geometrytip.cpp gestures.cpp globalshortcuts.cpp group.cpp idle_inhibition.cpp input.cpp input_event.cpp input_event_spy.cpp internal_client.cpp keyboard_input.cpp keyboard_layout.cpp keyboard_layout_switching.cpp keyboard_repeat.cpp killwindow.cpp layers.cpp libinput/connection.cpp libinput/context.cpp libinput/device.cpp libinput/events.cpp libinput/libinput_logging.cpp linux_dmabuf.cpp logind.cpp main.cpp modifier_only_shortcuts.cpp moving_client_x11_filter.cpp netinfo.cpp onscreennotification.cpp options.cpp osd.cpp outline.cpp outputscreens.cpp overlaywindow.cpp placement.cpp platform.cpp pointer_input.cpp popup_input_filter.cpp rootinfo_filter.cpp rules.cpp rulebooksettings.cpp scene.cpp screenedge.cpp screenlockerwatcher.cpp screens.cpp scripting/dbuscall.cpp scripting/meta.cpp scripting/screenedgeitem.cpp scripting/scriptedeffect.cpp scripting/scripting.cpp scripting/scripting_logging.cpp scripting/scripting_model.cpp scripting/scriptingutils.cpp scripting/timer.cpp scripting/workspace_wrapper.cpp shadow.cpp sm.cpp thumbnailitem.cpp toplevel.cpp touch_hide_cursor_spy.cpp tablet_input.cpp touch_input.cpp udev.cpp unmanaged.cpp useractions.cpp utils.cpp virtualdesktops.cpp virtualdesktopsdbustypes.cpp virtualkeyboard.cpp virtualkeyboard_dbus.cpp was_user_interaction_x11_filter.cpp wayland_cursor_theme.cpp wayland_server.cpp window_property_notify_x11_filter.cpp workspace.cpp x11client.cpp x11eventfilter.cpp xcbutils.cpp xdgshellclient.cpp xkb.cpp xwl/xwayland_interface.cpp ) if (CMAKE_SYSTEM_NAME MATCHES "Linux") set(kwin_SRCS ${kwin_SRCS} colorcorrection/clockskewnotifierengine_linux.cpp ) endif() include(ECMQtDeclareLoggingCategory) ecm_qt_declare_logging_category(kwin_SRCS HEADER colorcorrect_logging.h IDENTIFIER KWIN_COLORCORRECTION CATEGORY_NAME kwin_colorcorrection DEFAULT_SEVERITY Critical ) if (KWIN_BUILD_TABBOX) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) set(kwin_SRCS ${kwin_SRCS} tabbox/clientmodel.cpp tabbox/desktopchain.cpp tabbox/desktopmodel.cpp tabbox/switcheritem.cpp tabbox/tabbox.cpp tabbox/tabbox_logging.cpp tabbox/tabboxconfig.cpp tabbox/tabboxhandler.cpp tabbox/x11_filter.cpp ) endif() if (KWIN_BUILD_ACTIVITIES) set(kwin_SRCS ${kwin_SRCS} activities.cpp ) endif() if (HAVE_LINUX_VT_H) set(kwin_SRCS ${kwin_SRCS} virtual_terminal.cpp ) endif() kconfig_add_kcfg_files(kwin_SRCS settings.kcfgc) kconfig_add_kcfg_files(kwin_SRCS colorcorrection/colorcorrect_settings.kcfgc) kconfig_add_kcfg_files(kwin_SRCS rulesettings.kcfgc) kconfig_add_kcfg_files(kwin_SRCS rulebooksettingsbase.kcfgc) qt5_add_dbus_adaptor(kwin_SRCS org.kde.KWin.xml dbusinterface.h KWin::DBusInterface) qt5_add_dbus_adaptor(kwin_SRCS org.kde.kwin.Compositing.xml dbusinterface.h KWin::CompositorDBusInterface) qt5_add_dbus_adaptor(kwin_SRCS org.kde.kwin.ColorCorrect.xml colorcorrection/colorcorrectdbusinterface.h KWin::ColorCorrect::ColorCorrectDBusInterface) qt5_add_dbus_adaptor(kwin_SRCS ${kwin_effects_dbus_xml} effects.h KWin::EffectsHandlerImpl) qt5_add_dbus_adaptor(kwin_SRCS org.kde.KWin.VirtualDesktopManager.xml dbusinterface.h KWin::VirtualDesktopManagerDBusInterface) qt5_add_dbus_adaptor(kwin_SRCS org.kde.KWin.Session.xml sm.h KWin::SessionManager) qt5_add_dbus_interface(kwin_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/kf5_org.freedesktop.ScreenSaver.xml screenlocker_interface) qt5_add_dbus_interface(kwin_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/org.kde.screensaver.xml kscreenlocker_interface) qt5_add_dbus_interface(kwin_SRCS org.kde.kappmenu.xml appmenu_interface) ki18n_wrap_ui(kwin_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::Script Qt5::Sensors ) set(kwin_KDE_LIBS KF5::ConfigCore KF5::ConfigWidgets KF5::CoreAddons KF5::GlobalAccel KF5::GlobalAccelPrivate KF5::I18n KF5::Notifications KF5::Package KF5::Plasma KF5::QuickAddons KF5::WindowSystem KDecoration2::KDecoration KDecoration2::KDecoration2Private PW::KScreenLocker ) set(kwin_XLIB_LIBS ${X11_ICE_LIB} ${X11_SM_LIB} ${X11_X11_LIB} ) set(kwin_XCB_LIBS XCB::COMPOSITE XCB::DAMAGE XCB::GLX XCB::ICCCM XCB::KEYSYMS XCB::RANDR XCB::RENDER XCB::SHAPE XCB::SHM XCB::SYNC XCB::XCB XCB::XFIXES ) set(kwin_WAYLAND_LIBS KF5::WaylandClient KF5::WaylandServer Wayland::Cursor XKB::XKB ${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_SRCS}) if (Libinput_VERSION_STRING VERSION_GREATER 1.14) target_compile_definitions(kwin PRIVATE -DLIBINPUT_HAS_TOTEM) endif () 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}) add_executable(kwin_x11 main_x11.cpp) target_link_libraries(kwin_x11 kwin KF5::Crash Qt5::X11Extras) install(TARGETS kwin ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) install(TARGETS kwin_x11 ${INSTALL_TARGETS_DEFAULT_ARGS}) set(kwin_XWAYLAND_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/xwl/clipboard.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/databridge.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/dnd.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/drag.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/drag_wl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/drag_x.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/selection.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/selection_source.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/transfer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/xwl/xwayland.cpp ) include(ECMQtDeclareLoggingCategory) ecm_qt_declare_logging_category(kwin_XWAYLAND_SRCS HEADER xwayland_logging.h IDENTIFIER KWIN_XWL CATEGORY_NAME kwin_xwl DEFAULT_SEVERITY Critical ) set(kwin_WAYLAND_SRCS main_wayland.cpp tabletmodemanager.cpp ) add_executable(kwin_wayland ${kwin_WAYLAND_SRCS} ${kwin_XWAYLAND_SRCS}) target_link_libraries(kwin_wayland kwin KF5::Crash) 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.VirtualDesktopManager.xml org.kde.KWin.xml org.kde.kwin.ColorCorrect.xml org.kde.kwin.Compositing.xml org.kde.kwin.Effects.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}) add_subdirectory(qml) if (BUILD_TESTING) add_subdirectory(autotests) add_subdirectory(tests) endif() if (KF5DocTools_FOUND) add_subdirectory(doc) endif() add_subdirectory(kconf_update) # add clang-format target for all our real source files file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h) kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) 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/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml b/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml index ed9765f8a..b86f5d5ed 100644 --- a/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml +++ b/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml @@ -1,270 +1,269 @@ /* * Copyright (c) 2020 Ismael Asensio * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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 . */ import QtQuick 2.14 import QtQuick.Layouts 1.14 import QtQuick.Controls 2.14 as QQC2 -import org.kde.kirigami 2.10 as Kirigami +import org.kde.kirigami 2.12 as Kirigami import org.kde.kcm 1.2 import org.kde.kitemmodels 1.0 import org.kde.kcms.kwinrules 1.0 ScrollViewKCM { id: rulesEditor property var rulesModel: kcm.rulesModel title: rulesModel.description view: ListView { id: rulesView clip: true model: enabledRulesModel delegate: RuleItemDelegate {} section { property: "section" delegate: Kirigami.ListSectionHeader { label: section } } - Item { + Kirigami.PlaceholderMessage { id: hintArea visible: rulesView.count <= 4 anchors { top: parent.contentItem.bottom left: parent.left right: parent.right bottom: parent.bottom } - QQC2.Button { - anchors.centerIn: parent + helpfulAction: QQC2.Action { text: i18n("Add Properties...") icon.name: "list-add-symbolic" - onClicked: { + onTriggered: { propertySheet.open(); } } } } // FIXME: InlineMessage.qml:241:13: QML Label: Binding loop detected for property "verticalAlignment" header: Kirigami.InlineMessage { Layout.fillWidth: true Layout.fillHeight: true text: rulesModel.warningMessage visible: text != "" } footer: RowLayout { QQC2.Button { text: checked ? i18n("Close") : i18n("Add Properties...") icon.name: checked ? "dialog-close" : "list-add-symbolic" checkable: true checked: propertySheet.sheetOpen visible: !hintArea.visible || checked onToggled: { propertySheet.sheetOpen = checked; } } Item { Layout.fillWidth: true } QQC2.Button { text: i18n("Detect Window Properties") icon.name: "edit-find" onClicked: { overlayModel.onlySuggestions = true; rulesModel.detectWindowProperties(delaySpin.value); } } QQC2.SpinBox { id: delaySpin Layout.preferredWidth: Kirigami.Units.gridUnit * 8 from: 0 to: 30 textFromValue: (value, locale) => { return (value == 0) ? i18n("Instantly") : i18np("After %1 second", "After %1 seconds", value) } } } Connections { target: rulesModel onSuggestionsChanged: { propertySheet.sheetOpen = true; } } Kirigami.OverlaySheet { id: propertySheet parent: view header: Kirigami.Heading { text: i18n("Select properties") } footer: Kirigami.SearchField { id: searchField horizontalAlignment: Text.AlignLeft } ListView { id: overlayView model: overlayModel Layout.preferredWidth: Kirigami.Units.gridUnit * 28 section { property: "section" delegate: Kirigami.ListSectionHeader { label: section } } delegate: Kirigami.AbstractListItem { id: propertyDelegate highlighted: false width: ListView.view.width RowLayout { anchors.fill: parent Kirigami.Icon { source: model.icon Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium Layout.leftMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing Layout.alignment: Qt.AlignVCenter } QQC2.Label { id: itemNameLabel text: model.name horizontalAlignment: Qt.AlignLeft Layout.preferredWidth: implicitWidth Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter QQC2.ToolTip { text: model.description visible: hovered && (model.description != "") } } QQC2.Label { id: suggestedLabel text: formatValue(model.suggested, model.type, model.options) horizontalAlignment: Text.AlignRight elide: Text.ElideRight opacity: 0.7 Layout.maximumWidth: propertyDelegate.width - itemNameLabel.implicitWidth - Kirigami.Units.gridUnit * 6 Layout.alignment: Qt.AlignVCenter QQC2.ToolTip { text: suggestedLabel.text visible: hovered && suggestedLabel.truncated } } QQC2.ToolButton { icon.name: (model.enabled) ? "dialog-ok-apply" : "list-add-symbolic" opacity: propertyDelegate.hovered ? 1 : 0 onClicked: propertyDelegate.clicked() Layout.preferredWidth: implicitWidth Layout.alignment: Qt.AlignVCenter } } onClicked: { model.enabled = true; if (model.suggested != null) { model.value = model.suggested; model.suggested = null; } } } } onSheetOpenChanged: { searchField.text = ""; if (sheetOpen) { searchField.forceActiveFocus(); } else { overlayModel.onlySuggestions = false; } } } function formatValue(value, type, options) { if (value == null) { return ""; } switch (type) { case RuleItem.Boolean: return value ? i18n("Yes") : i18n("No"); case RuleItem.Percentage: return i18n("%1 %", value); case RuleItem.Coordinate: var point = value.split(','); return i18nc("Coordinates (x, y)", "(%1, %2)", point[0], point[1]); case RuleItem.Option: return options.textOfValue(value); case RuleItem.FlagsOption: var selectedValue = value.toString(2).length - 1; return options.textOfValue(selectedValue); } return value; } KSortFilterProxyModel { id: enabledRulesModel sourceModel: rulesModel filterRowCallback: (source_row, source_parent) => { var index = sourceModel.index(source_row, 0, source_parent); return sourceModel.data(index, RulesModel.EnabledRole); } } KSortFilterProxyModel { id: overlayModel sourceModel: rulesModel property bool onlySuggestions: false onOnlySuggestionsChanged: { invalidateFilter(); } filterString: searchField.text.trim().toLowerCase() filterRowCallback: (source_row, source_parent) => { var index = sourceModel.index(source_row, 0, source_parent); var hasSuggestion = sourceModel.data(index, RulesModel.SuggestedValueRole) != null; var isOptional = sourceModel.data(index, RulesModel.SelectableRole); var isEnabled = sourceModel.data(index, RulesModel.EnabledRole); var showItem = hasSuggestion || (!onlySuggestions && isOptional && !isEnabled); if (!showItem) { return false; } if (filterString != "") { return sourceModel.data(index, RulesModel.NameRole).toLowerCase().includes(filterString) } return true; } } } diff --git a/kcmkwin/kwinrules/package/contents/ui/RulesList.qml b/kcmkwin/kwinrules/package/contents/ui/RulesList.qml index d2f3dd6bd..ca4709c4e 100644 --- a/kcmkwin/kwinrules/package/contents/ui/RulesList.qml +++ b/kcmkwin/kwinrules/package/contents/ui/RulesList.qml @@ -1,252 +1,247 @@ /* * Copyright (c) 2020 Ismael Asensio * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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 . */ import QtQuick 2.14 import QtQuick.Layouts 1.14 import QtQuick.Controls 2.14 as QQC2 import QtQml.Models 2.14 import org.kde.kcm 1.2 -import org.kde.kirigami 2.5 as Kirigami +import org.kde.kirigami 2.12 as Kirigami ScrollViewKCM { id: rulesListKCM // FIXME: ScrollViewKCM.qml:73:13: QML Control: Binding loop detected for property "implicitHeight" implicitWidth: Kirigami.Units.gridUnit * 35 implicitHeight: Kirigami.Units.gridUnit * 25 ConfigModule.columnWidth: Kirigami.Units.gridUnit * 23 ConfigModule.buttons: ConfigModule.Apply property var selectedIndexes: [] // Manage KCM pages Connections { target: kcm onEditIndexChanged: { if (kcm.editIndex < 0) { // If no rule is being edited, hide RulesEdidor page kcm.pop(); } else if (kcm.depth < 2) { // Add the RulesEditor page if it wasn't already kcm.push("RulesEditor.qml"); } } } view: ListView { id: ruleBookView clip: true model: kcm.ruleBookModel currentIndex: kcm.editIndex delegate: Kirigami.DelegateRecycler { width: ruleBookView.width sourceComponent: ruleBookDelegate } displaced: Transition { NumberAnimation { properties: "y"; duration: Kirigami.Units.longDuration } } - Kirigami.Heading { - level: 3 - enabled: false + Kirigami.PlaceholderMessage { visible: ruleBookView.count == 0 anchors.fill: parent - horizontalAlignment: Qt.AlignHCenter - verticalAlignment: Qt.AlignVCenter - wrapMode: Text.WordWrap text: i18n("No rules for specific windows are currently set"); } } header: Kirigami.InlineMessage { id: exportInfo icon.source: "document-export" showCloseButton: true text: i18n("Select the rules to export") actions: [ Kirigami.Action { iconName: "document-save" text: i18n("Save Rules") // FIXME: It does not update on selection changes // enabled: selectedIndexes.length > 0 onTriggered: { exportDialog.active = true; } } ] } footer: RowLayout { QQC2.Button { text: i18n("Add New...") icon.name: "list-add-symbolic" enabled: !exportInfo.visible onClicked: { kcm.createRule(); } } Item { Layout.fillWidth: true } QQC2.Button { text: i18n("Import...") icon.name: "document-import" enabled: !exportInfo.visible onClicked: { importDialog.active = true; } } QQC2.Button { text: i18n("Export...") icon.name: "document-export" enabled: ruleBookView.count > 0 checkable: true checked: exportInfo.visible onToggled: { selectedIndexes = [] exportInfo.visible = checked; } } } Component { id: ruleBookDelegate Kirigami.AbstractListItem { id: ruleBookItem RowLayout { //FIXME: If not used within DelegateRecycler, item goes on top of the first item when clicked Kirigami.ListItemDragHandle { visible: !exportInfo.visible listItem: ruleBookItem listView: ruleBookView onMoveRequested: { kcm.moveRule(oldIndex, newIndex); } } QQC2.TextField { id: descriptionField Layout.minimumWidth: Kirigami.Units.gridUnit * 2 Layout.fillWidth: true background: Item {} horizontalAlignment: Text.AlignLeft text: display onEditingFinished: { kcm.setRuleDescription(index, text); } Keys.onPressed: { switch (event.key) { case Qt.Key_Escape: // On key reset to model data before losing focus text = display; case Qt.Key_Enter: case Qt.Key_Return: case Qt.Key_Tab: ruleBookItem.forceActiveFocus(); event.accepted = true; break; } } MouseArea { anchors.fill: parent enabled: exportInfo.visible cursorShape: enabled ? Qt.PointingHandCursor : Qt.IBeamCursor onClicked: { itemSelectionCheck.toggle(); itemSelectionCheck.toggled(); } } } Kirigami.ActionToolBar { Layout.preferredWidth: maximumContentWidth + Kirigami.Units.smallSpacing alignment: Qt.AlignRight display: QQC2.Button.IconOnly visible: !exportInfo.visible opacity: ruleBookItem.hovered ? 1 : 0 focus: false actions: [ Kirigami.Action { text: i18n("Edit") iconName: "edit-entry" onTriggered: { kcm.editRule(index); } } , Kirigami.Action { text: i18n("Delete") iconName: "entry-delete" onTriggered: { kcm.removeRule(index); } } ] } QQC2.CheckBox { id: itemSelectionCheck visible: exportInfo.visible checked: selectedIndexes.includes(index) onToggled: { var position = selectedIndexes.indexOf(index); if (checked) { if (position < 0) { selectedIndexes.push(index); } } else { if (position >= 0) { selectedIndexes.splice(position, 1); } } } } } } } FileDialogLoader { id: importDialog title: i18n("Import Rules") isSaveDialog: false onLastFolderChanged: { exportDialog.lastFolder = lastFolder; } onFileSelected: { kcm.importFromFile(path); } } FileDialogLoader { id: exportDialog title: i18n("Export Rules") isSaveDialog: true onLastFolderChanged: { importDialog.lastFolder = lastFolder; } onFileSelected: { selectedIndexes.sort(); kcm.exportToFile(path, selectedIndexes); exportInfo.visible = false; } } }