diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e43e79e3..9d2e0bba2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,720 +1,717 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) project(KWIN) set(PROJECT_VERSION "5.15.80") set(PROJECT_VERSION_MAJOR 5) set(QT_MIN_VERSION "5.11.0") set(KF5_MIN_VERSION "5.54.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) # This is a workaround/compromise for a Kwin specific policy of not applying the relevant override fix. # See thread in D18167. if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-suggest-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(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.13.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 "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 output 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 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 outputscreens.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 abstract_output.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 touch_hide_cursor_spy.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) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) 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 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.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} ) add_subdirectory(qml) add_subdirectory(packageplugins) if (BUILD_TESTING) add_subdirectory(autotests) add_subdirectory(tests) endif() if (KF5DocTools_FOUND) add_subdirectory(doc) endif() add_subdirectory(kconf_update) 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/plugins/scenes/opengl/CMakeLists.txt b/plugins/scenes/opengl/CMakeLists.txt index a01a26533..1134f0644 100644 --- a/plugins/scenes/opengl/CMakeLists.txt +++ b/plugins/scenes/opengl/CMakeLists.txt @@ -1,27 +1,32 @@ -set(SCENE_OPENGL_SRCS scene_opengl.cpp) +set(SCENE_OPENGL_SRCS + scene_opengl.cpp + lanczosfilter.cpp +) include(ECMQtDeclareLoggingCategory) ecm_qt_declare_logging_category( SCENE_OPENGL_SRCS HEADER logging.h IDENTIFIER KWIN_OPENGL CATEGORY_NAME kwin_scene_opengl DEFAULT_SEVERITY Critical ) -add_library(KWinSceneOpenGL MODULE scene_opengl.cpp) +qt5_add_resources(SCENE_OPENGL_SRCS resources.qrc) + +add_library(KWinSceneOpenGL MODULE ${SCENE_OPENGL_SRCS}) set_target_properties(KWinSceneOpenGL PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/org.kde.kwin.scenes/") target_link_libraries(KWinSceneOpenGL kwin SceneOpenGLBackend ) install( TARGETS KWinSceneOpenGL DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kwin.scenes/ ) diff --git a/lanczosfilter.cpp b/plugins/scenes/opengl/lanczosfilter.cpp similarity index 97% rename from lanczosfilter.cpp rename to plugins/scenes/opengl/lanczosfilter.cpp index fbd4a393b..c02158dd6 100644 --- a/lanczosfilter.cpp +++ b/plugins/scenes/opengl/lanczosfilter.cpp @@ -1,426 +1,428 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2010 by Fredrik Höglund Copyright (C) 2010 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 . *********************************************************************/ #include "lanczosfilter.h" #include "client.h" #include "deleted.h" #include "effects.h" #include "screens.h" #include "unmanaged.h" #include "options.h" #include "workspace.h" +#include + #include #include #include #include #include #include namespace KWin { LanczosFilter::LanczosFilter(QObject* parent) : QObject(parent) , m_offscreenTex(0) , m_offscreenTarget(0) , m_inited(false) , m_shader(0) , m_uOffsets(0) , m_uKernel(0) { } LanczosFilter::~LanczosFilter() { delete m_offscreenTarget; delete m_offscreenTex; } void LanczosFilter::init() { if (m_inited) return; m_inited = true; const bool force = (qstrcmp(qgetenv("KWIN_FORCE_LANCZOS"), "1") == 0); if (force) { - qCWarning(KWIN_CORE) << "Lanczos Filter forced on by environment variable"; + qCWarning(KWIN_OPENGL) << "Lanczos Filter forced on by environment variable"; } if (!force && options->glSmoothScale() != 2) return; // disabled by config if (!GLRenderTarget::supported()) return; GLPlatform *gl = GLPlatform::instance(); if (!force) { // The lanczos filter is reported to be broken with the Intel driver prior SandyBridge if (gl->driver() == Driver_Intel && gl->chipClass() < SandyBridge) return; // also radeon before R600 has trouble if (gl->isRadeon() && gl->chipClass() < R600) return; // and also for software emulation (e.g. llvmpipe) if (gl->isSoftwareEmulation()) { return; } } QFile ff(gl->glslVersion() >= kVersionNumber(1, 40) ? - QStringLiteral(":/resources/shaders/1.40/lanczos-fragment.glsl") : - QStringLiteral(":/resources/shaders/1.10/lanczos-fragment.glsl")); + QStringLiteral(":/scenes/opengl/shaders/1.40/lanczos-fragment.glsl") : + QStringLiteral(":/scenes/opengl/shaders/1.10/lanczos-fragment.glsl")); if (!ff.open(QIODevice::ReadOnly)) { - qCDebug(KWIN_CORE) << "Failed to open lanczos shader"; + qCDebug(KWIN_OPENGL) << "Failed to open lanczos shader"; return; } m_shader.reset(ShaderManager::instance()->generateCustomShader(ShaderTrait::MapTexture, QByteArray(), ff.readAll())); if (m_shader->isValid()) { ShaderBinder binder(m_shader.data()); m_uKernel = m_shader->uniformLocation("kernel"); m_uOffsets = m_shader->uniformLocation("offsets"); } else { - qCDebug(KWIN_CORE) << "Shader is not valid"; + qCDebug(KWIN_OPENGL) << "Shader is not valid"; m_shader.reset(); } } void LanczosFilter::updateOffscreenSurfaces() { const QSize &s = screens()->size(); int w = s.width(); int h = s.height(); if (!m_offscreenTex || m_offscreenTex->width() != w || m_offscreenTex->height() != h) { if (m_offscreenTex) { delete m_offscreenTex; delete m_offscreenTarget; } m_offscreenTex = new GLTexture(GL_RGBA8, w, h); m_offscreenTex->setFilter(GL_LINEAR); m_offscreenTex->setWrapMode(GL_CLAMP_TO_EDGE); m_offscreenTarget = new GLRenderTarget(*m_offscreenTex); } } static float sinc(float x) { return std::sin(x * M_PI) / (x * M_PI); } static float lanczos(float x, float a) { if (qFuzzyCompare(x + 1.0, 1.0)) return 1.0; if (qAbs(x) >= a) return 0.0; return sinc(x) * sinc(x / a); } void LanczosFilter::createKernel(float delta, int *size) { const float a = 2.0; // The two outermost samples always fall at points where the lanczos // function returns 0, so we'll skip them. const int sampleCount = qBound(3, qCeil(delta * a) * 2 + 1 - 2, 29); const int center = sampleCount / 2; const int kernelSize = center + 1; const float factor = 1.0 / delta; QVector values(kernelSize); float sum = 0; for (int i = 0; i < kernelSize; i++) { const float val = lanczos(i * factor, a); sum += i > 0 ? val * 2 : val; values[i] = val; } memset(m_kernel, 0, 16 * sizeof(QVector4D)); // Normalize the kernel for (int i = 0; i < kernelSize; i++) { const float val = values[i] / sum; m_kernel[i] = QVector4D(val, val, val, val); } *size = kernelSize; } void LanczosFilter::createOffsets(int count, float width, Qt::Orientation direction) { memset(m_offsets, 0, 16 * sizeof(QVector2D)); for (int i = 0; i < count; i++) { m_offsets[i] = (direction == Qt::Horizontal) ? QVector2D(i / width, 0) : QVector2D(0, i / width); } } void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data) { if (data.xScale() < 0.9 || data.yScale() < 0.9) { if (!m_inited) init(); const QRect screenRect = Workspace::self()->clientArea(ScreenArea, w->screen(), w->desktop()); // window geometry may not be bigger than screen geometry to fit into the FBO QRect winGeo(w->expandedGeometry()); if (m_shader && winGeo.width() <= screenRect.width() && winGeo.height() <= screenRect.height()) { winGeo.translate(-w->geometry().topLeft()); double left = winGeo.left(); double top = winGeo.top(); double width = winGeo.right() - left; double height = winGeo.bottom() - top; int tx = data.xTranslation() + w->x() + left * data.xScale(); int ty = data.yTranslation() + w->y() + top * data.yScale(); int tw = width * data.xScale(); int th = height * data.yScale(); const QRect textureRect(tx, ty, tw, th); const bool hardwareClipping = !(QRegion(textureRect)-region).isEmpty(); int sw = width; int sh = height; GLTexture *cachedTexture = static_cast< GLTexture*>(w->data(LanczosCacheRole).value()); if (cachedTexture) { if (cachedTexture->width() == tw && cachedTexture->height() == th) { cachedTexture->bind(); if (hardwareClipping) { glEnable(GL_SCISSOR_TEST); } glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); const qreal rgb = data.brightness() * data.opacity(); const qreal a = data.opacity(); ShaderBinder binder(ShaderTrait::MapTexture | ShaderTrait::Modulate | ShaderTrait::AdjustSaturation); GLShader *shader = binder.shader(); QMatrix4x4 mvp = data.screenProjectionMatrix(); mvp.translate(textureRect.x(), textureRect.y()); shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp); shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a)); shader->setUniform(GLShader::Saturation, data.saturation()); cachedTexture->render(region, textureRect, hardwareClipping); glDisable(GL_BLEND); if (hardwareClipping) { glDisable(GL_SCISSOR_TEST); } cachedTexture->unbind(); m_timer.start(5000, this); return; } else { // offscreen texture not matching - delete delete cachedTexture; cachedTexture = 0; w->setData(LanczosCacheRole, QVariant()); } } WindowPaintData thumbData = data; thumbData.setXScale(1.0); thumbData.setYScale(1.0); thumbData.setXTranslation(-w->x() - left); thumbData.setYTranslation(-w->y() - top); thumbData.setBrightness(1.0); thumbData.setOpacity(1.0); thumbData.setSaturation(1.0); // Bind the offscreen FBO and draw the window on it unscaled updateOffscreenSurfaces(); GLRenderTarget::pushRenderTarget(m_offscreenTarget); QMatrix4x4 modelViewProjectionMatrix; modelViewProjectionMatrix.ortho(0, m_offscreenTex->width(), m_offscreenTex->height(), 0 , 0, 65535); thumbData.setProjectionMatrix(modelViewProjectionMatrix); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); w->sceneWindow()->performPaint(mask, infiniteRegion(), thumbData); // Create a scratch texture and copy the rendered window into it GLTexture tex(GL_RGBA8, sw, sh); tex.setFilter(GL_LINEAR); tex.setWrapMode(GL_CLAMP_TO_EDGE); tex.bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, sw, sh); // Set up the shader for horizontal scaling float dx = sw / float(tw); int kernelSize; createKernel(dx, &kernelSize); createOffsets(kernelSize, sw, Qt::Horizontal); ShaderManager::instance()->pushShader(m_shader.data()); m_shader->setUniform(GLShader::ModelViewProjectionMatrix, modelViewProjectionMatrix); setUniforms(); // Draw the window back into the FBO, this time scaled horizontally glClear(GL_COLOR_BUFFER_BIT); QVector verts; QVector texCoords; verts.reserve(12); texCoords.reserve(12); texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right texCoords << 0.0 << 0.0; verts << 0.0 << 0.0; // Top left texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left texCoords << 1.0 << 1.0; verts << tw << sh; // Bottom right texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); vbo->reset(); vbo->setData(6, 2, verts.constData(), texCoords.constData()); vbo->render(GL_TRIANGLES); // At this point we don't need the scratch texture anymore tex.unbind(); tex.discard(); // create scratch texture for second rendering pass GLTexture tex2(GL_RGBA8, tw, sh); tex2.setFilter(GL_LINEAR); tex2.setWrapMode(GL_CLAMP_TO_EDGE); tex2.bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, tw, sh); // Set up the shader for vertical scaling float dy = sh / float(th); createKernel(dy, &kernelSize); createOffsets(kernelSize, m_offscreenTex->height(), Qt::Vertical); setUniforms(); // Now draw the horizontally scaled window in the FBO at the right // coordinates on the screen, while scaling it vertically and blending it. glClear(GL_COLOR_BUFFER_BIT); verts.clear(); verts << tw << 0.0; // Top right verts << 0.0 << 0.0; // Top left verts << 0.0 << th; // Bottom left verts << 0.0 << th; // Bottom left verts << tw << th; // Bottom right verts << tw << 0.0; // Top right vbo->setData(6, 2, verts.constData(), texCoords.constData()); vbo->render(GL_TRIANGLES); tex2.unbind(); tex2.discard(); ShaderManager::instance()->popShader(); // create cache texture GLTexture *cache = new GLTexture(GL_RGBA8, tw, th); cache->setFilter(GL_LINEAR); cache->setWrapMode(GL_CLAMP_TO_EDGE); cache->bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th); GLRenderTarget::popRenderTarget(); if (hardwareClipping) { glEnable(GL_SCISSOR_TEST); } glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); const qreal rgb = data.brightness() * data.opacity(); const qreal a = data.opacity(); ShaderBinder binder(ShaderTrait::MapTexture | ShaderTrait::Modulate | ShaderTrait::AdjustSaturation); GLShader *shader = binder.shader(); QMatrix4x4 mvp = data.screenProjectionMatrix(); mvp.translate(textureRect.x(), textureRect.y()); shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp); shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a)); shader->setUniform(GLShader::Saturation, data.saturation()); cache->render(region, textureRect, hardwareClipping); glDisable(GL_BLEND); if (hardwareClipping) { glDisable(GL_SCISSOR_TEST); } cache->unbind(); w->setData(LanczosCacheRole, QVariant::fromValue(static_cast(cache))); // Delete the offscreen surface after 5 seconds m_timer.start(5000, this); return; } } // if ( effects->compositingType() == KWin::OpenGLCompositing ) w->sceneWindow()->performPaint(mask, region, data); } // End of function void LanczosFilter::timerEvent(QTimerEvent *event) { if (event->timerId() == m_timer.timerId()) { m_timer.stop(); delete m_offscreenTarget; delete m_offscreenTex; m_offscreenTarget = 0; m_offscreenTex = 0; foreach (Client *c, Workspace::self()->clientList()) { discardCacheTexture(c->effectWindow()); } foreach (Client *c, Workspace::self()->desktopList()) { discardCacheTexture(c->effectWindow()); } foreach (Unmanaged *u, Workspace::self()->unmanagedList()) { discardCacheTexture(u->effectWindow()); } foreach (Deleted *d, Workspace::self()->deletedList()) { discardCacheTexture(d->effectWindow()); } } } void LanczosFilter::discardCacheTexture(EffectWindow *w) { QVariant cachedTextureVariant = w->data(LanczosCacheRole); if (cachedTextureVariant.isValid()) { delete static_cast< GLTexture*>(cachedTextureVariant.value()); w->setData(LanczosCacheRole, QVariant()); } } void LanczosFilter::setUniforms() { glUniform2fv(m_uOffsets, 16, (const GLfloat*)m_offsets); glUniform4fv(m_uKernel, 16, (const GLfloat*)m_kernel); } } // namespace diff --git a/lanczosfilter.h b/plugins/scenes/opengl/lanczosfilter.h similarity index 95% rename from lanczosfilter.h rename to plugins/scenes/opengl/lanczosfilter.h index 90dff420c..66481a770 100644 --- a/lanczosfilter.h +++ b/plugins/scenes/opengl/lanczosfilter.h @@ -1,77 +1,73 @@ /******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2010 by Fredrik Höglund Copyright (C) 2010 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_LANCZOSFILTER_P_H #define KWIN_LANCZOSFILTER_P_H #include #include #include #include #include -#include -#include - namespace KWin { class EffectWindow; class EffectWindowImpl; class WindowPaintData; class GLTexture; class GLRenderTarget; class GLShader; -class KWIN_EXPORT LanczosFilter - : public QObject +class LanczosFilter : public QObject { Q_OBJECT public: explicit LanczosFilter(QObject* parent = 0); ~LanczosFilter(); void performPaint(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); protected: virtual void timerEvent(QTimerEvent*); private: void init(); void updateOffscreenSurfaces(); void setUniforms(); void discardCacheTexture(EffectWindow *w); void createKernel(float delta, int *kernelSize); void createOffsets(int count, float width, Qt::Orientation direction); GLTexture *m_offscreenTex; GLRenderTarget *m_offscreenTarget; QBasicTimer m_timer; bool m_inited; QScopedPointer m_shader; int m_uOffsets; int m_uKernel; QVector2D m_offsets[16]; QVector4D m_kernel[16]; }; } // namespace #endif // KWIN_LANCZOSFILTER_P_H diff --git a/resources.qrc b/plugins/scenes/opengl/resources.qrc similarity index 74% rename from resources.qrc rename to plugins/scenes/opengl/resources.qrc index 11616caf0..8fbd27d16 100644 --- a/resources.qrc +++ b/plugins/scenes/opengl/resources.qrc @@ -1,7 +1,6 @@ - + shaders/1.10/lanczos-fragment.glsl - shaders/1.40/lanczos-fragment.glsl - + diff --git a/shaders/1.10/lanczos-fragment.glsl b/plugins/scenes/opengl/shaders/1.10/lanczos-fragment.glsl similarity index 100% rename from shaders/1.10/lanczos-fragment.glsl rename to plugins/scenes/opengl/shaders/1.10/lanczos-fragment.glsl diff --git a/shaders/1.40/lanczos-fragment.glsl b/plugins/scenes/opengl/shaders/1.40/lanczos-fragment.glsl similarity index 100% rename from shaders/1.40/lanczos-fragment.glsl rename to plugins/scenes/opengl/shaders/1.40/lanczos-fragment.glsl