diff --git a/CMakeLists.txt b/CMakeLists.txt
index 54d8387de..7bfd9f5ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,772 +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.12.0")
+set(QT_MIN_VERSION "5.14.0")
set(KF5_MIN_VERSION "5.68.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/autotests/integration/CMakeLists.txt b/autotests/integration/CMakeLists.txt
index 433785a14..39b626150 100644
--- a/autotests/integration/CMakeLists.txt
+++ b/autotests/integration/CMakeLists.txt
@@ -1,89 +1,89 @@
add_subdirectory(helper)
-add_library(KWinIntegrationTestFramework STATIC kwin_wayland_test.cpp test_helpers.cpp ${kwin_XWAYLAND_SRCS})
+add_library(KWinIntegrationTestFramework STATIC kwin_wayland_test.cpp test_helpers.cpp generic_scene_opengl_test.cpp ${kwin_XWAYLAND_SRCS})
target_link_libraries(KWinIntegrationTestFramework kwin Qt5::Test)
function(integrationTest)
set(optionArgs WAYLAND_ONLY)
set(oneValueArgs NAME)
set(multiValueArgs SRCS LIBS)
cmake_parse_arguments(ARGS "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
add_executable(${ARGS_NAME} ${ARGS_SRCS})
target_link_libraries(${ARGS_NAME} KWinIntegrationTestFramework kwin Qt5::Test ${ARGS_LIBS})
add_test(NAME kwin-${ARGS_NAME} COMMAND dbus-run-session ${CMAKE_BINARY_DIR}/bin/${ARGS_NAME})
if (${ARGS_WAYLAND_ONLY})
add_executable(${ARGS_NAME}_waylandonly ${ARGS_SRCS})
set_target_properties(${ARGS_NAME}_waylandonly PROPERTIES COMPILE_DEFINITIONS "NO_XWAYLAND")
target_link_libraries(${ARGS_NAME}_waylandonly KWinIntegrationTestFramework kwin Qt5::Test ${ARGS_LIBS})
add_test(NAME kwin-${ARGS_NAME}-waylandonly COMMAND dbus-run-session ${CMAKE_BINARY_DIR}/bin/${ARGS_NAME}_waylandonly)
endif()
endfunction()
integrationTest(NAME testDontCrashGlxgears SRCS dont_crash_glxgears.cpp)
integrationTest(NAME testLockScreen SRCS lockscreen.cpp)
integrationTest(WAYLAND_ONLY NAME testDecorationInput SRCS decoration_input_test.cpp)
integrationTest(WAYLAND_ONLY NAME testInternalWindow SRCS internal_window.cpp)
integrationTest(WAYLAND_ONLY NAME testTouchInput SRCS touch_input_test.cpp)
integrationTest(WAYLAND_ONLY NAME testInputStackingOrder SRCS input_stacking_order.cpp)
integrationTest(NAME testPointerInput SRCS pointer_input.cpp)
integrationTest(NAME testPlatformCursor SRCS platformcursor.cpp)
integrationTest(WAYLAND_ONLY NAME testDontCrashCancelAnimation SRCS dont_crash_cancel_animation.cpp)
integrationTest(WAYLAND_ONLY NAME testTransientPlacement SRCS transient_placement.cpp)
integrationTest(NAME testDebugConsole SRCS debug_console_test.cpp)
integrationTest(NAME testDontCrashEmptyDeco SRCS dont_crash_empty_deco.cpp)
integrationTest(WAYLAND_ONLY NAME testPlasmaSurface SRCS plasma_surface_test.cpp)
integrationTest(WAYLAND_ONLY NAME testMaximized SRCS maximize_test.cpp)
integrationTest(WAYLAND_ONLY NAME testXdgShellClient SRCS xdgshellclient_test.cpp)
integrationTest(WAYLAND_ONLY NAME testDontCrashNoBorder SRCS dont_crash_no_border.cpp)
integrationTest(NAME testXwaylandSelections SRCS xwayland_selections_test.cpp)
-integrationTest(WAYLAND_ONLY NAME testSceneOpenGL SRCS scene_opengl_test.cpp generic_scene_opengl_test.cpp)
+integrationTest(WAYLAND_ONLY NAME testSceneOpenGL SRCS scene_opengl_test.cpp )
integrationTest(WAYLAND_ONLY NAME testSceneOpenGLShadow SRCS scene_opengl_shadow_test.cpp)
-integrationTest(WAYLAND_ONLY NAME testSceneOpenGLES SRCS scene_opengl_es_test.cpp generic_scene_opengl_test.cpp)
+integrationTest(WAYLAND_ONLY NAME testSceneOpenGLES SRCS scene_opengl_es_test.cpp )
integrationTest(WAYLAND_ONLY NAME testNoXdgRuntimeDir SRCS no_xdg_runtime_dir_test.cpp)
integrationTest(WAYLAND_ONLY NAME testScreenChanges SRCS screen_changes_test.cpp)
integrationTest(NAME testModiferOnlyShortcut SRCS modifier_only_shortcut_test.cpp)
integrationTest(WAYLAND_ONLY NAME testTabBox SRCS tabbox_test.cpp)
integrationTest(WAYLAND_ONLY NAME testWindowSelection SRCS window_selection_test.cpp)
integrationTest(WAYLAND_ONLY NAME testPointerConstraints SRCS pointer_constraints_test.cpp)
integrationTest(WAYLAND_ONLY NAME testKeyboardLayout SRCS keyboard_layout_test.cpp)
integrationTest(WAYLAND_ONLY NAME testKeymapCreationFailure SRCS keymap_creation_failure_test.cpp)
integrationTest(WAYLAND_ONLY NAME testShowingDesktop SRCS showing_desktop_test.cpp)
integrationTest(WAYLAND_ONLY NAME testDontCrashUseractionsMenu SRCS dont_crash_useractions_menu.cpp)
integrationTest(WAYLAND_ONLY NAME testKWinBindings SRCS kwinbindings_test.cpp)
integrationTest(WAYLAND_ONLY NAME testVirtualDesktop SRCS virtual_desktop_test.cpp)
integrationTest(WAYLAND_ONLY NAME testXdgShellClientRules SRCS xdgshellclient_rules_test.cpp)
integrationTest(WAYLAND_ONLY NAME testIdleInhibition SRCS idle_inhibition_test.cpp)
integrationTest(WAYLAND_ONLY NAME testColorCorrectNightColor SRCS colorcorrect_nightcolor_test.cpp)
integrationTest(WAYLAND_ONLY NAME testDontCrashCursorPhysicalSizeEmpty SRCS dont_crash_cursor_physical_size_empty.cpp)
integrationTest(WAYLAND_ONLY NAME testDontCrashReinitializeCompositor SRCS dont_crash_reinitialize_compositor.cpp)
integrationTest(WAYLAND_ONLY NAME testNoGlobalShortcuts SRCS no_global_shortcuts_test.cpp)
-integrationTest(WAYLAND_ONLY NAME testBufferSizeChange SRCS buffer_size_change_test.cpp generic_scene_opengl_test.cpp)
+integrationTest(WAYLAND_ONLY NAME testBufferSizeChange SRCS buffer_size_change_test.cpp )
integrationTest(WAYLAND_ONLY NAME testPlacement SRCS placement_test.cpp)
integrationTest(WAYLAND_ONLY NAME testActivation SRCS activation_test.cpp)
if (XCB_ICCCM_FOUND)
integrationTest(NAME testMoveResize SRCS move_resize_window_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testStruts SRCS struts_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testShade SRCS shade_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testDontCrashAuroraeDestroyDeco SRCS dont_crash_aurorae_destroy_deco.cpp LIBS XCB::ICCCM)
integrationTest(NAME testPlasmaWindow SRCS plasmawindow_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testScreenEdgeClientShow SRCS screenedge_client_show_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testX11DesktopWindow SRCS desktop_window_x11_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testXwaylandInput SRCS xwayland_input_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testWindowRules SRCS window_rules_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testX11Client SRCS x11_client_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testQuickTiling SRCS quick_tiling_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testGlobalShortcuts SRCS globalshortcuts_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testSceneQPainter SRCS scene_qpainter_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testSceneQPainterShadow SRCS scene_qpainter_shadow_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testStackingOrder SRCS stacking_order_test.cpp LIBS XCB::ICCCM)
integrationTest(NAME testDbusInterface SRCS dbus_interface_test.cpp LIBS XCB::ICCCM)
if (KWIN_BUILD_ACTIVITIES)
integrationTest(NAME testActivities SRCS activities_test.cpp LIBS XCB::ICCCM)
endif()
endif()
add_subdirectory(scripting)
add_subdirectory(effects)
add_subdirectory(fakes)
diff --git a/autotests/libinput/CMakeLists.txt b/autotests/libinput/CMakeLists.txt
index 195ac2fdd..4ac4d2580 100644
--- a/autotests/libinput/CMakeLists.txt
+++ b/autotests/libinput/CMakeLists.txt
@@ -1,114 +1,85 @@
include_directories(${Libinput_INCLUDE_DIRS})
include_directories(${UDEV_INCLUDE_DIR})
+
+add_library(LibInputTestObjects STATIC ../../libinput/device.cpp ../../libinput/events.cpp mock_libinput.cpp)
+target_link_libraries(LibInputTestObjects Qt5::Test Qt5::Widgets Qt5::DBus Qt5::Gui KF5::ConfigCore)
+
########################################################
# Test Devices
########################################################
-set(testLibinputDevice_SRCS device_test.cpp mock_libinput.cpp ../../libinput/device.cpp )
-add_executable(testLibinputDevice ${testLibinputDevice_SRCS})
-target_link_libraries(testLibinputDevice Qt5::Test Qt5::DBus Qt5::Gui KF5::ConfigCore)
+add_executable(testLibinputDevice device_test.cpp)
+target_link_libraries(testLibinputDevice Qt5::Test Qt5::DBus Qt5::Gui KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testLibinputDevice COMMAND testLibinputDevice)
ecm_mark_as_test(testLibinputDevice)
########################################################
# Test Key Event
########################################################
-set(testLibinputKeyEvent_SRCS
- ../../libinput/device.cpp
- ../../libinput/events.cpp
- key_event_test.cpp
- mock_libinput.cpp
-)
-add_executable(testLibinputKeyEvent ${testLibinputKeyEvent_SRCS})
-target_link_libraries(testLibinputKeyEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore)
+add_executable(testLibinputKeyEvent key_event_test.cpp)
+target_link_libraries(testLibinputKeyEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testLibinputKeyEvent COMMAND testLibinputKeyEvent)
ecm_mark_as_test(testLibinputKeyEvent)
########################################################
# Test Pointer Event
########################################################
-set(testLibinputPointerEvent_SRCS
- ../../libinput/device.cpp
- ../../libinput/events.cpp
- mock_libinput.cpp
- pointer_event_test.cpp
-)
-add_executable(testLibinputPointerEvent ${testLibinputPointerEvent_SRCS})
-target_link_libraries(testLibinputPointerEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore)
+add_executable(testLibinputPointerEvent pointer_event_test.cpp)
+target_link_libraries(testLibinputPointerEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testLibinputPointerEvent COMMAND testLibinputPointerEvent)
ecm_mark_as_test(testLibinputPointerEvent)
########################################################
# Test Touch Event
########################################################
-set(testLibinputTouchEvent_SRCS
- ../../libinput/device.cpp
- ../../libinput/events.cpp
- mock_libinput.cpp
- touch_event_test.cpp
-)
-add_executable(testLibinputTouchEvent ${testLibinputTouchEvent_SRCS})
-target_link_libraries(testLibinputTouchEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore)
+add_executable(testLibinputTouchEvent touch_event_test.cpp)
+target_link_libraries(testLibinputTouchEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testLibinputTouchEvent COMMAND testLibinputTouchEvent)
ecm_mark_as_test(testLibinputTouchEvent)
########################################################
# Test Gesture Event
########################################################
-set(testLibinputGestureEvent_SRCS
- ../../libinput/device.cpp
- ../../libinput/events.cpp
- gesture_event_test.cpp
- mock_libinput.cpp
-)
-add_executable(testLibinputGestureEvent ${testLibinputGestureEvent_SRCS})
-target_link_libraries(testLibinputGestureEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore)
+add_executable(testLibinputGestureEvent gesture_event_test.cpp)
+target_link_libraries(testLibinputGestureEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testLibinputGestureEvent COMMAND testLibinputGestureEvent)
ecm_mark_as_test(testLibinputGestureEvent)
########################################################
# Test Switch Event
########################################################
-set(testLibinputSwitchEvent_SRCS
- ../../libinput/device.cpp
- ../../libinput/events.cpp
- mock_libinput.cpp
- switch_event_test.cpp
-)
-add_executable(testLibinputSwitchEvent ${testLibinputSwitchEvent_SRCS})
-target_link_libraries(testLibinputSwitchEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore)
+add_executable(testLibinputSwitchEvent switch_event_test.cpp)
+target_link_libraries(testLibinputSwitchEvent Qt5::Test Qt5::DBus Qt5::Widgets KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testLibinputSwitchEvent COMMAND testLibinputSwitchEvent)
ecm_mark_as_test(testLibinputSwitchEvent)
########################################################
# Test Context
########################################################
set(testLibinputContext_SRCS
../../libinput/context.cpp
- ../../libinput/device.cpp
- ../../libinput/events.cpp
../../libinput/libinput_logging.cpp
../../logind.cpp
context_test.cpp
- mock_libinput.cpp
mock_udev.cpp
)
add_executable(testLibinputContext ${testLibinputContext_SRCS})
target_link_libraries(testLibinputContext
+ LibInputTestObjects
+
Qt5::DBus
Qt5::Test
Qt5::Widgets
KF5::ConfigCore
KF5::WindowSystem
)
add_test(NAME kwin-testLibinputContext COMMAND testLibinputContext)
ecm_mark_as_test(testLibinputContext)
########################################################
# Test Input Events
########################################################
-set(testInputEvents_SRCS input_event_test.cpp mock_libinput.cpp ../../libinput/device.cpp ../../input_event.cpp)
-add_executable(testInputEvents ${testInputEvents_SRCS})
-target_link_libraries(testInputEvents Qt5::Test Qt5::DBus Qt5::Gui Qt5::Widgets KF5::ConfigCore)
+add_executable(testInputEvents input_event_test.cpp ../../input_event.cpp)
+target_link_libraries(testInputEvents Qt5::Test Qt5::DBus Qt5::Gui Qt5::Widgets KF5::ConfigCore LibInputTestObjects)
add_test(NAME kwin-testInputEvents COMMAND testInputEvents)
ecm_mark_as_test(testInputEvents)
diff --git a/effects/blur/CMakeLists.txt b/effects/blur/CMakeLists.txt
index c1d9bd9a4..35db55d5d 100644
--- a/effects/blur/CMakeLists.txt
+++ b/effects/blur/CMakeLists.txt
@@ -1,23 +1,23 @@
#######################################
# Config
set(kwin_blur_config_SRCS blur_config.cpp)
ki18n_wrap_ui(kwin_blur_config_SRCS blur_config.ui)
-qt5_add_dbus_interface(kwin_blur_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_blur_config_SRCS blurconfig.kcfgc)
add_library(kwin_blur_config MODULE ${kwin_blur_config_SRCS})
target_link_libraries(kwin_blur_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_blur_config blur_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_blur_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/coverswitch/CMakeLists.txt b/effects/coverswitch/CMakeLists.txt
index 56b7a8190..f344a0efb 100644
--- a/effects/coverswitch/CMakeLists.txt
+++ b/effects/coverswitch/CMakeLists.txt
@@ -1,26 +1,26 @@
#######################################
# Effect
#######################################
# Config
set(kwin_coverswitch_config_SRCS coverswitch_config.cpp)
ki18n_wrap_ui(kwin_coverswitch_config_SRCS coverswitch_config.ui)
-qt5_add_dbus_interface(kwin_coverswitch_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_coverswitch_config_SRCS coverswitchconfig.kcfgc)
add_library(kwin_coverswitch_config MODULE ${kwin_coverswitch_config_SRCS})
target_link_libraries(kwin_coverswitch_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_coverswitch_config coverswitch_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_coverswitch_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/cube/CMakeLists.txt b/effects/cube/CMakeLists.txt
index c80b3e50a..c9d94605f 100644
--- a/effects/cube/CMakeLists.txt
+++ b/effects/cube/CMakeLists.txt
@@ -1,32 +1,32 @@
#######################################
# Effect
# Data files
install(FILES data/cubecap.png DESTINATION ${DATA_INSTALL_DIR}/kwin)
#######################################
# Config
set(kwin_cube_config_SRCS cube_config.cpp)
ki18n_wrap_ui(kwin_cube_config_SRCS cube_config.ui)
-qt5_add_dbus_interface(kwin_cube_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_cube_config_SRCS cubeconfig.kcfgc)
add_library(kwin_cube_config MODULE ${kwin_cube_config_SRCS})
target_link_libraries(kwin_cube_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
KF5::KIOWidgets
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_cube_config cube_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_cube_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/cubeslide/CMakeLists.txt b/effects/cubeslide/CMakeLists.txt
index 2836614bc..042ae92c0 100644
--- a/effects/cubeslide/CMakeLists.txt
+++ b/effects/cubeslide/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_cubeslide_config_SRCS cubeslide_config.cpp)
ki18n_wrap_ui(kwin_cubeslide_config_SRCS cubeslide_config.ui)
-qt5_add_dbus_interface(kwin_cubeslide_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_cubeslide_config_SRCS cubeslideconfig.kcfgc)
add_library(kwin_cubeslide_config MODULE ${kwin_cubeslide_config_SRCS})
target_link_libraries(kwin_cubeslide_config
KF5::ConfigWidgets
KF5::I18n
kwineffects
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_cubeslide_config cubeslide_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_cubeslide_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/desktopgrid/CMakeLists.txt b/effects/desktopgrid/CMakeLists.txt
index 807ff0e69..7fa4b7ace 100644
--- a/effects/desktopgrid/CMakeLists.txt
+++ b/effects/desktopgrid/CMakeLists.txt
@@ -1,31 +1,31 @@
#######################################
# Effect
install(FILES main.qml DESTINATION ${DATA_INSTALL_DIR}/kwin/effects/desktopgrid/)
#######################################
# Config
set(kwin_desktopgrid_config_SRCS desktopgrid_config.cpp)
ki18n_wrap_ui(kwin_desktopgrid_config_SRCS desktopgrid_config.ui)
-qt5_add_dbus_interface(kwin_desktopgrid_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_desktopgrid_config_SRCS desktopgridconfig.kcfgc)
add_library(kwin_desktopgrid_config MODULE ${kwin_desktopgrid_config_SRCS})
target_link_libraries(kwin_desktopgrid_config
KF5::Completion
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
Qt5::Quick
kwineffects
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_desktopgrid_config desktopgrid_config.desktop SERVICE_TYPES kcmodule.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_desktopgrid_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/diminactive/CMakeLists.txt b/effects/diminactive/CMakeLists.txt
index 2aad1ea1b..5d6e7d3a1 100644
--- a/effects/diminactive/CMakeLists.txt
+++ b/effects/diminactive/CMakeLists.txt
@@ -1,23 +1,23 @@
#######################################
# Config
set(kwin_diminactive_config_SRCS diminactive_config.cpp)
ki18n_wrap_ui(kwin_diminactive_config_SRCS diminactive_config.ui)
-qt5_add_dbus_interface(kwin_diminactive_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_diminactive_config_SRCS diminactiveconfig.kcfgc)
add_library(kwin_diminactive_config MODULE ${kwin_diminactive_config_SRCS})
target_link_libraries(kwin_diminactive_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_diminactive_config diminactive_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_diminactive_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/eyeonscreen/package/metadata.desktop b/effects/eyeonscreen/package/metadata.desktop
index 7f11c282a..6bd5c54ae 100644
--- a/effects/eyeonscreen/package/metadata.desktop
+++ b/effects/eyeonscreen/package/metadata.desktop
@@ -1,56 +1,60 @@
[Desktop Entry]
Name=Eye on Screen
Name[ca]=Ull a la pantalla
Name[cs]=Oko na obrazovce
+Name[en_GB]=Eye on Screen
Name[es]=Ojo a la pantalla
Name[et]=Eye on Screen
Name[eu]=Begirada pantailan
Name[id]=Mata di Layar
Name[it]=Eye On Screen
Name[ko]=화면 위의 눈
Name[lt]=Akis ekrane
Name[nl]=Oog op scherm
Name[nn]=Auge på skjerm
Name[pt]=Olho no Ecrã
Name[pt_BR]=Olho na tela
Name[ru]=Втягивание окон в центр экрана
+Name[sl]=Oko na zaslonu
Name[sv]=Ögat på skärmen
Name[uk]=Око на екрані
Name[x-test]=xxEye on Screenxx
Name[zh_CN]=关注屏幕
Name[zh_TW]=螢幕之眼
Icon=preferences-system-windows-effect-eyeonscreen
Comment=Suck windows into the desktop
Comment[ca]=Enganxa les finestres a l'escriptori
+Comment[en_GB]=Suck windows into the desktop
Comment[es]=Aspirar las ventanas en el escritorio
Comment[et]=Akende imemine töölauale
Comment[eu]=Mahaigainak leihoak xurgatu
Comment[id]=Sedot window ke desktop
Comment[it]=Risucchia le finestre nel desktop
Comment[ko]=창을 바탕 화면으로 흡수
Comment[lt]=Įtraukti langus į darbalaukį
Comment[nl]=Zuig vensters in het bureaublad
Comment[nn]=Sug vindauge inn i skrivebordet
Comment[pt]=Aspira as janelas para o ecrã
Comment[pt_BR]=Suga as janelas para a área de trabalho
Comment[ru]=Втягивание окон в центр рабочего стола
+Comment[sl]=Prisesa okna na namizje
Comment[sv]=Sug in fönster i skrivbordet
Comment[uk]=Засмоктування вікон до стільниці
Comment[x-test]=xxSuck windows into the desktopxx
Comment[zh_CN]=将窗口吸收到桌面
Comment[zh_TW]=將視窗吸進桌面
Type=Service
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=Thomas Lübking
X-KDE-PluginInfo-Email=thomas.luebking@gmail.com
X-KDE-PluginInfo-Name=kwin4_effect_eyeonscreen
X-KDE-PluginInfo-Version=0.1.0
X-KDE-PluginInfo-Category=Show Desktop Animation
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=false
X-KDE-Ordering=50
X-KWin-Exclusive-Category=show-desktop
diff --git a/effects/fadingpopups/package/metadata.desktop b/effects/fadingpopups/package/metadata.desktop
index 05bbbe689..a42ae1df3 100644
--- a/effects/fadingpopups/package/metadata.desktop
+++ b/effects/fadingpopups/package/metadata.desktop
@@ -1,78 +1,80 @@
[Desktop Entry]
Name=Fading Popups
Name[ca]=Missatges emergents esvaïts
Name[ca@valencia]=Missatges emergents que es fonen
Name[cs]=Mizející vyskakovací okna
Name[da]=Pop-op'er udtoner
Name[de]=Überblendete Aufklappfenster
Name[en_GB]=Fading Popups
Name[es]=Desvanecer ventanas emergentes
Name[et]=Hääbuvad hüpikdialoogid
Name[eu]=Itzaleztatzen diren gainerakorrak
Name[fi]=Hiipuvat ponnahdusikkunat
Name[fr]=Fondu des boites de dialogue
Name[gl]=Xanelas emerxentes que esvaen
Name[hu]=Halványodó felugró ablakok
Name[ia]=Popups dissolvente
Name[id]=Sembulan Melesap
Name[it]=Finestre a comparsa che si dissolvono
Name[ko]=페이드 팝업
Name[lt]=Pamažu atsirandantys/išnykstantys iškylantieji langai
Name[nl]=Vervagende pop-ups
Name[nn]=Inn- og uttoning av sprettoppvindauge
Name[pl]=Zanikanie okien wysuwnych
Name[pt]=Mensagens Desvanecentes
Name[pt_BR]=Desvanecer mensagens
Name[ru]=Растворяющиеся всплывающие окна
Name[sk]=Miznúce vyskakovacie okná
+Name[sl]=Prehajajoča pojavna okna
Name[sv]=Borttonande meddelanderutor
Name[uk]=Інтерактивні контекстні панелі
Name[x-test]=xxFading Popupsxx
Name[zh_CN]=气泡通知渐隐渐现
Name[zh_TW]=淡化彈出視窗
Icon=preferences-system-windows-effect-fadingpopups
Comment=Make popups smoothly fade in and out when they are shown or hidden
Comment[ca]=Fa que els missatges emergents s'encenguin o s'apaguin de manera gradual quan es mostren o s'oculten
Comment[ca@valencia]=Fa que els missatges emergents s'encenguen o s'apaguen de manera gradual quan es mostren o s'oculten
Comment[cs]=Nechá vyskakovací okna plynule zmizet/objevit se, pokud jsou zobrazeny resp. skryty
Comment[da]=Få pop-op'er til at tone ud og ind når de vises eller skjules
Comment[de]=Blendet Aufklappfenster beim Öffnen/Schließen langsam ein bzw. aus
Comment[en_GB]=Make popups smoothly fade in and out when they are shown or hidden
Comment[es]=Hace que las ventanas emergentes aparezcan o se desvanezcan suavemente al mostrarlas u ocultarlas
Comment[et]=Paneb hüpikaknad sujuvalt hääbuma või tugevnema, kui need peidetakse või nähtavale tuuakse
Comment[eu]=Gainerakorrak emeki agertzen eta desagertzen ditu haiek erakustean edo ezkutatzean
Comment[fi]=Ponnahdusikkunat tulevat näkyviin tai poistuvat näkyvistä pehmeästi häivyttäen
Comment[fr]=Estompe ou fait apparaître en fondu les boites de dialogue lorsqu'elles sont affichées ou cachées
Comment[gl]=Esvae e fai opacas as xanelas emerxentes con suavidade ao mostralas ou agochadas
Comment[hu]=A felugró folyamatosan áttűnő módon lesznek elrejtve és megjelenítve
Comment[ia]=Face que fenestras pote dulcemente pallidir intra e foras quando illos es monstrate o celate
Comment[id]=Buat sembulan secara halus lesap-muncul dan lesap-hilang ketika ia ditampilkan atau disembunyikan
Comment[it]=Fai dissolvere e comparire gradualmente le finestre a comparsa quando vengono mostrate o nascoste
Comment[ko]=팝업이 보여지거나 감춰질 때 부드러운 페이드 인/아웃을 사용합니다
Comment[lt]=Sukuria efektą, kai iškylantieji langai, juos parodant ar paslepiant, glotniai pamažu atsiranda/išnyksta
Comment[nl]=Laat pop-ups vloeiend opkomen/vervagen als ze worden weergegeven of verborgen
Comment[nn]=Ton sprettoppvindauge gradvis inn og ut når dei vert viste eller gøymde
Comment[pl]=Okna wysuwne gładko wyłaniają się przy otwieraniu i zanikają przy zamykaniu
Comment[pt]=Fazer com que as janelas apareçam/desapareçam suavemente quando aparecem ou ficam escondidas
Comment[pt_BR]=Faz as mensagens aparecerem/desaparecerem suavemente quando são exibidas ou ocultadas
Comment[ru]=Всплывающие окна при закрытии будут становиться всё более прозрачными, а потом совсем исчезать
Comment[sk]=Okná sa plynule objavia/zmiznú pri ich zobrazení alebo skrytí
+Comment[sl]=Okna se pojavijo in izginejo postopoma, kadar se pokažejo ali skrijejo
Comment[sv]=Gör att meddelanderutor mjukt tonas in eller ut när de visas eller döljs
Comment[uk]=Поступова поява або зникнення контекстних вікон вікон при відкритті чи закритті
Comment[x-test]=xxMake popups smoothly fade in and out when they are shown or hiddenxx
Comment[zh_CN]=当弹窗被显示或者隐藏时,使窗口平滑地淡入淡出
Comment[zh_TW]=當彈出視窗出現或消失時,讓彈出視窗滑順的淡入和淡出
Type=Service
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=Vlad Zahorodnii
X-KDE-PluginInfo-Email=vlad.zahorodnii@kde.org
X-KDE-PluginInfo-Name=kwin4_effect_fadingpopups
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Category=Appearance
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Ordering=60
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
diff --git a/effects/flipswitch/CMakeLists.txt b/effects/flipswitch/CMakeLists.txt
index b1160a027..6829ea590 100644
--- a/effects/flipswitch/CMakeLists.txt
+++ b/effects/flipswitch/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_flipswitch_config_SRCS flipswitch_config.cpp)
ki18n_wrap_ui(kwin_flipswitch_config_SRCS flipswitch_config.ui)
-qt5_add_dbus_interface(kwin_flipswitch_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_flipswitch_config_SRCS flipswitchconfig.kcfgc)
add_library(kwin_flipswitch_config MODULE ${kwin_flipswitch_config_SRCS})
target_link_libraries(kwin_flipswitch_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_flipswitch_config flipswitch_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_flipswitch_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/glide/CMakeLists.txt b/effects/glide/CMakeLists.txt
index 7b7c3e17e..cd0a69cb4 100644
--- a/effects/glide/CMakeLists.txt
+++ b/effects/glide/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_glide_config_SRCS glide_config.cpp)
ki18n_wrap_ui(kwin_glide_config_SRCS glide_config.ui)
-qt5_add_dbus_interface(kwin_glide_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_glide_config_SRCS glideconfig.kcfgc)
add_library(kwin_glide_config MODULE ${kwin_glide_config_SRCS})
target_link_libraries(kwin_glide_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_glide_config glide_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_glide_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/invert/CMakeLists.txt b/effects/invert/CMakeLists.txt
index d20368f13..09dac3fcf 100644
--- a/effects/invert/CMakeLists.txt
+++ b/effects/invert/CMakeLists.txt
@@ -1,25 +1,25 @@
#######################################
# Effect
#######################################
# Config
set(kwin_invert_config_SRCS invert_config.cpp)
-qt5_add_dbus_interface(kwin_invert_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
add_library(kwin_invert_config MODULE ${kwin_invert_config_SRCS})
target_link_libraries(kwin_invert_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_invert_config invert_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_invert_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/logout/package/metadata.desktop b/effects/logout/package/metadata.desktop
index 9f171a339..d224e117b 100644
--- a/effects/logout/package/metadata.desktop
+++ b/effects/logout/package/metadata.desktop
@@ -1,81 +1,83 @@
[Desktop Entry]
Name=Logout
Name[ast]=Zarru de sesión
Name[ca]=Sortida
Name[ca@valencia]=Eixida
Name[cs]=Odhlášení
Name[da]=Log ud
Name[de]=Abmeldung
Name[el]=Αποσύνδεση
Name[en_GB]=Logout
Name[es]=Cerrar la sesión
Name[et]=Väljalogimine
Name[eu]=Saio-ixtea
Name[fi]=Kirjaudu ulos
Name[fr]=Déconnexion
Name[gl]=Saír
Name[hu]=Kijelentkezés
Name[ia]=Clausura de session
Name[id]=Logout
Name[it]=Uscita
Name[ko]=로그아웃
Name[lt]=Atsijungimas
Name[nl]=Afmelden
Name[nn]=Logg ut
Name[pl]=Wylogowywanie
Name[pt]=Encerrar
Name[pt_BR]=Encerrar sessão
Name[ru]=Завершение работы
Name[sk]=Odhlásiť sa
+Name[sl]=Odjava
Name[sv]=Logga ut
Name[uk]=Вихід
Name[x-test]=xxLogoutxx
Name[zh_CN]=注销
Name[zh_TW]=登出
Icon=preferences-system-windows-effect-logout
Comment=Smoothly fade to the logout screen
Comment[ca]=Transició suau a la pantalla de sortida
Comment[ca@valencia]=Transició suau a la pantalla d'eixida
Comment[cs]=Plynule přejít na odhlašovací obrazovku
Comment[da]=Toner blidt til log ud-skærmen
Comment[de]=Blendet den Abmeldungsdialog langsam ein.
Comment[el]=Ομαλή εμφάνιση της οθόνης αποσύνδεσης
Comment[en_GB]=Smoothly fade to the logout screen
Comment[es]=Desvanecer suavemente hasta la pantalla de cierre de sesión
Comment[et]=Sujuv hääbumine sisselogimisekraani ilmumiseni
Comment[eu]=Emeki desagertu saio-ixteko pantailarantz
Comment[fi]=Häivytä pehmeästi kirjautumisikkunaan
Comment[fr]=Effectue un dégradé progressif vers l'écran de déconnexion
Comment[gl]=Suaviza a aparición da pantalla de saída
Comment[hu]=Folyamatos átmenet a kijelentkező képernyőre
Comment[ia]=Dulcemente pallidi al schermo de abandono (logout)
Comment[id]=Melesap secara halus ke layar logout
Comment[it]=Dissolvenza graduale alla schermata di uscita
Comment[ko]=로그아웃 화면으로 부드럽게 전환합니다
Comment[lt]=Glotniai pamažu parodo atsijungimo ekraną
Comment[nl]=Langzaam naar het afmeldscherm vervagen
Comment[nn]=Ton ut til utloggingsbiletet
Comment[pl]=Płynne zanikanie do ekranu wylogowywania
Comment[pt]=Desvanecer suavemente para o ecrã de encerramento
Comment[pt_BR]=Suaviza o desaparecimento para a tela de encerramento da sessão
Comment[ru]=Плавное появление экрана завершения работы
Comment[sk]=Plynule zobrazí plochu pri odhlásení
+Comment[sl]=Postopoma okno zbledi v zaslon za odjavo
Comment[sv]=Tona mjukt till utloggningsskärmen
Comment[uk]=Плавний перехід до вікна виходу з системи
Comment[x-test]=xxSmoothly fade to the logout screenxx
Comment[zh_CN]=平滑地淡出到注销屏幕
Comment[zh_TW]=平順地淡入登出畫面
Type=Service
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=Lubos Lunak, Kai Uwe Broulik, Martin Gräßlin, Marco Martin
X-KDE-PluginInfo-Email=l.lunak@kde.org, kde@privat.broulik.de, mgraesslin@kde.org, mart@kde.org
X-KDE-PluginInfo-Name=kwin4_effect_logout
X-KDE-PluginInfo-Version=0.2.0
X-KDE-PluginInfo-Category=Appearance
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Ordering=40
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
diff --git a/effects/lookingglass/CMakeLists.txt b/effects/lookingglass/CMakeLists.txt
index 288d5f2c8..381a790b1 100644
--- a/effects/lookingglass/CMakeLists.txt
+++ b/effects/lookingglass/CMakeLists.txt
@@ -1,27 +1,27 @@
#######################################
# Effect
#######################################
# Config
set(kwin_lookingglass_config_SRCS lookingglass_config.cpp)
ki18n_wrap_ui(kwin_lookingglass_config_SRCS lookingglass_config.ui)
-qt5_add_dbus_interface(kwin_lookingglass_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_lookingglass_config_SRCS lookingglassconfig.kcfgc)
add_library(kwin_lookingglass_config MODULE ${kwin_lookingglass_config_SRCS})
target_link_libraries(kwin_lookingglass_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_lookingglass_config lookingglass_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_lookingglass_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/magiclamp/CMakeLists.txt b/effects/magiclamp/CMakeLists.txt
index ebeed364d..b1ea9c94a 100644
--- a/effects/magiclamp/CMakeLists.txt
+++ b/effects/magiclamp/CMakeLists.txt
@@ -1,23 +1,23 @@
#######################################
# Config
set(kwin_magiclamp_config_SRCS magiclamp_config.cpp)
ki18n_wrap_ui(kwin_magiclamp_config_SRCS magiclamp_config.ui)
-qt5_add_dbus_interface(kwin_magiclamp_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_magiclamp_config_SRCS magiclampconfig.kcfgc)
add_library(kwin_magiclamp_config MODULE ${kwin_magiclamp_config_SRCS})
target_link_libraries(kwin_magiclamp_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_magiclamp_config magiclamp_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_magiclamp_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/magnifier/CMakeLists.txt b/effects/magnifier/CMakeLists.txt
index 758a76463..cd3fe05be 100644
--- a/effects/magnifier/CMakeLists.txt
+++ b/effects/magnifier/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_magnifier_config_SRCS magnifier_config.cpp)
ki18n_wrap_ui(kwin_magnifier_config_SRCS magnifier_config.ui)
-qt5_add_dbus_interface(kwin_magnifier_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_magnifier_config_SRCS magnifierconfig.kcfgc)
add_library(kwin_magnifier_config MODULE ${kwin_magnifier_config_SRCS})
target_link_libraries(kwin_magnifier_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_magnifier_config magnifier_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_magnifier_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/magnifier/magnifier_config.desktop b/effects/magnifier/magnifier_config.desktop
index 30e48bed8..b09413f94 100644
--- a/effects/magnifier/magnifier_config.desktop
+++ b/effects/magnifier/magnifier_config.desktop
@@ -1,89 +1,89 @@
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-Library=kwin_magnifier_config
X-KDE-ParentComponents=magnifier
Name=Magnifier
Name[af]=Vergroter
Name[ar]=المكبّر
Name[be]=Павелічальная лупа
Name[be@latin]=Lupa
Name[bg]=Увеличител
Name[bn]=ম্যাগনিফায়ার
Name[bs]=Uveličavač
Name[ca]=Lupa
Name[ca@valencia]=Lupa
Name[cs]=Lupa
Name[csb]=Zwikszanié
Name[da]=Forstørrelsesglas
Name[de]=Lupe
Name[el]=Μεγεθυντής
Name[en_GB]=Magnifier
Name[eo]=Pligrandigilo
Name[es]=Lupa
Name[et]=Suurendaja
Name[eu]=Lupa
Name[fa]=ذرهبین
Name[fi]=Suurennuslasi
Name[fr]=Loupe
Name[fy]=Fergrutter
Name[ga]=Formhéadaitheoir
Name[gl]=Lupa
Name[gu]=મોટું કરનાર
Name[he]=זכוכית מגדלת
Name[hi]=आतिशी शीशा
Name[hne]=आतिसी सीसा
Name[hr]=Povećalo
Name[hu]=Nagyító
Name[ia]=Aggranditor
Name[id]=Suryakanta
Name[is]=Stækkunargler
Name[it]=Lente d'ingrandimento
Name[ja]=虫めがね
Name[kk]=Ұлғайтқыш
Name[km]=X Magnifier
Name[kn]=ವರ್ಧಕ (ಮಸೂರ)
Name[ko]=돋보기
Name[ku]=Mezinker
Name[lt]=Didinamasis stiklas
Name[lv]=Palielinātājs
Name[mai]=आवर्धक
Name[mk]=Лупа
Name[ml]=ഭൂതകണ്ണാടി
Name[mr]=वर्धक
Name[nb]=Lupe
Name[nds]=Kiekglas
Name[ne]=परिमार्जक
Name[nl]=Vergrootglas
Name[nn]=Forstørr skjermdel
Name[oc]=Lópia
Name[pa]=ਵੱਡਦਰਸ਼ੀ
Name[pl]=Powiększenie
Name[pt]=Lupa
Name[pt_BR]=Lente de aumento
Name[ro]=Lupă
Name[ru]=Лупа
Name[se]=Stuorideaddji
Name[si]=විශාලකය
Name[sk]=Lupa
-Name[sl]=Približevalnik
+Name[sl]=Povečevalnik
Name[sr]=Увеличавач
Name[sr@ijekavian]=Увеличавач
Name[sr@ijekavianlatin]=Uveličavač
Name[sr@latin]=Uveličavač
Name[sv]=Förstoringsglas
Name[ta]=பெரிதாக்கி
Name[te]=మాగ్నిఫైర్
Name[th]=แว่นขยาย
Name[tr]=Büyüteç
Name[ug]=چوڭايتقۇچ
Name[uk]=Лупа
Name[uz]=Kattalashtiruvchi
Name[uz@cyrillic]=Катталаштирувчи
Name[vi]=Kính lúp
Name[wa]=Magnifieu
Name[x-test]=xxMagnifierxx
Name[zh_CN]=放大镜
Name[zh_TW]=放大鏡
diff --git a/effects/mouseclick/CMakeLists.txt b/effects/mouseclick/CMakeLists.txt
index 92b0ae6b8..1b1834d62 100644
--- a/effects/mouseclick/CMakeLists.txt
+++ b/effects/mouseclick/CMakeLists.txt
@@ -1,25 +1,25 @@
##########################
## configurtion dialog
##########################
set(kwin_mouseclick_config_SRCS mouseclick_config.cpp)
ki18n_wrap_ui(kwin_mouseclick_config_SRCS mouseclick_config.ui)
-qt5_add_dbus_interface(kwin_mouseclick_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_mouseclick_config_SRCS mouseclickconfig.kcfgc)
add_library(kwin_mouseclick_config MODULE ${kwin_mouseclick_config_SRCS})
target_link_libraries(kwin_mouseclick_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_mouseclick_config mouseclick_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_mouseclick_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/mousemark/CMakeLists.txt b/effects/mousemark/CMakeLists.txt
index 1a8056e07..fd42575f1 100644
--- a/effects/mousemark/CMakeLists.txt
+++ b/effects/mousemark/CMakeLists.txt
@@ -1,25 +1,25 @@
#######################################
# Config
set(kwin_mousemark_config_SRCS mousemark_config.cpp)
ki18n_wrap_ui(kwin_mousemark_config_SRCS mousemark_config.ui)
-qt5_add_dbus_interface(kwin_mousemark_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_mousemark_config_SRCS mousemarkconfig.kcfgc)
add_library(kwin_mousemark_config MODULE ${kwin_mousemark_config_SRCS})
target_link_libraries(kwin_mousemark_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::TextWidgets
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_mousemark_config mousemark_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_mousemark_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/presentwindows/CMakeLists.txt b/effects/presentwindows/CMakeLists.txt
index fc550ae31..9f86c0413 100644
--- a/effects/presentwindows/CMakeLists.txt
+++ b/effects/presentwindows/CMakeLists.txt
@@ -1,29 +1,29 @@
#######################################
# Effect
install(FILES main.qml DESTINATION ${DATA_INSTALL_DIR}/kwin/effects/presentwindows/)
#######################################
# Config
set(kwin_presentwindows_config_SRCS presentwindows_config.cpp)
ki18n_wrap_ui(kwin_presentwindows_config_SRCS presentwindows_config.ui)
-qt5_add_dbus_interface(kwin_presentwindows_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_presentwindows_config_SRCS presentwindowsconfig.kcfgc)
add_library(kwin_presentwindows_config MODULE ${kwin_presentwindows_config_SRCS})
target_link_libraries(kwin_presentwindows_config
KF5::Completion
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_presentwindows_config presentwindows_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_presentwindows_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/resize/CMakeLists.txt b/effects/resize/CMakeLists.txt
index 9b6293b86..5b4393533 100644
--- a/effects/resize/CMakeLists.txt
+++ b/effects/resize/CMakeLists.txt
@@ -1,23 +1,23 @@
#######################################
# Config
set(kwin_resize_config_SRCS resize_config.cpp)
ki18n_wrap_ui(kwin_resize_config_SRCS resize_config.ui)
-qt5_add_dbus_interface(kwin_resize_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_resize_config_SRCS resizeconfig.kcfgc)
add_library(kwin_resize_config MODULE ${kwin_resize_config_SRCS})
target_link_libraries(kwin_resize_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_resize_config resize_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_resize_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/scale/package/metadata.desktop b/effects/scale/package/metadata.desktop
index 5d8823a03..359085e3f 100644
--- a/effects/scale/package/metadata.desktop
+++ b/effects/scale/package/metadata.desktop
@@ -1,83 +1,85 @@
[Desktop Entry]
Name=Scale
Name[ca]=Escala
Name[ca@valencia]=Escala
Name[cs]=Měřítko
Name[da]=Skalér
Name[de]=Skalieren
Name[el]=Κλιμάκωση
Name[en_GB]=Scale
Name[es]=Escalar
Name[et]=Skaleerimine
Name[eu]=Eskalatu
Name[fi]=Skaalaa
Name[fr]=Échelle
Name[gl]=Cambiar as dimensións
Name[hu]=Nagyítás
Name[ia]=Scala
Name[id]=Skala
Name[it]=Scala
Name[ko]=크기 조정
Name[lt]=Mastelio keitimas
Name[nl]=Schalen
Name[nn]=Skalering
Name[pl]=Skalowanie
Name[pt]=Escala
Name[pt_BR]=Escala
Name[ru]=Масштабирование
Name[sk]=Škálovať
+Name[sl]=Merilo
Name[sv]=Skala
Name[uk]=Масштабування
Name[x-test]=xxScalexx
Name[zh_CN]=比例
Name[zh_TW]=縮放
Icon=preferences-system-windows-effect-scale
Comment=Make windows smoothly scale in and out when they are shown or hidden
Comment[ca]=Fa que les finestres entrin o surtin volant quan es mostren o s'oculten
Comment[ca@valencia]=Fa que les finestres entrin o isquen volant quan es mostren o s'oculten
Comment[cs]=Nechá okna plynule zvětšit/zmenšit se, pokud jsou zobrazeny resp. skryty
Comment[da]=Få vinduer til at skalere blidt ud og ind når de vises eller skjules
Comment[de]=Ändert die Fenstergröße langsam beim Ein- oder Ausblenden
Comment[en_GB]=Make windows smoothly scale in and out when they are shown or hidden
Comment[es]=Hace que las ventanas se agranden o se encojan suavemente al mostrarlas u ocultarlas
Comment[et]=Skaleerib aknaid sujuvalt, kui need peidetakse või nähtavale tuuakse
Comment[eu]=Leihoak emeki eskalatu barrura eta kanpora haiek erakutsi edo ezkutatzean
Comment[fi]=Ikkunat ilmestyvät näkyviin tai poistuvat näkyvistä hiljalleen
Comment[fr]=Échelonne les fenêtres lorsqu'elles sont affichées ou cachées
Comment[gl]=Facer que as xanelas crezan ou decrezan suavemente cando se mostran ou agochan
Comment[ia]=Face que fenestras pote dulcemente scalar intra e foras quando illos es monstrate o celate
Comment[id]=Buat window menskala besar atau kecil secara mulus ketika ia ditampilkan atau disembunyikan
Comment[it]=Ridimensiona le finestre dolcemente quando sono mostrate o nascoste
Comment[ko]=창이 보여지거나 감춰질 때 부드러운 크기 조정을 사용합니다
Comment[lt]=Glotniai didinti ar mažinti langų mastelį, juos parodant ar paslepiant
Comment[nl]=Laat vensters vloeiend kleiner en groter schalen als ze worden getoond of verborgen
Comment[nn]=Skaler vindauge jamt inn og ut når dei vert viste eller gøymde
Comment[pl]=Okna gładko pomniejszają się przy otwieraniu i powiększają przy zamykaniu
Comment[pt]=Fazer com que as janelas apareçam/desapareçam suavemente quando aparecem ou ficam escondidas
Comment[pt_BR]=Faz com que as janelas aumentem ou reduzam o seu tamanho de forma suave ao serem exibidas ou ocultadas
Comment[ru]=Плавное увеличение или уменьшение окон при их появлении и скрытии
Comment[sk]=Okná sa plynule objavia/zmiznú pri ich zobrazení alebo skrytí
+Comment[sl]=Okna se pojavijo in izginejo postopoma kadar se prikažejo ali skrijejo
Comment[sv]=Gör att fönster mjukt skalas in eller ut när de visas eller döljs
Comment[uk]=Плавне масштабування вікон при появі або приховуванні
Comment[x-test]=xxMake windows smoothly scale in and out when they are shown or hiddenxx
Comment[zh_CN]=窗口显示或隐藏时平滑缩放
Comment[zh_TW]=顯示或隱藏視窗時以平順的比例縮放方式呈現。
Type=Service
X-KDE-ServiceTypes=KWin/Effect,KCModule
X-KDE-PluginInfo-Author=Vlad Zahorodnii
X-KDE-PluginInfo-Email=vlad.zahorodnii@kde.org
X-KDE-PluginInfo-Name=kwin4_effect_scale
X-KDE-PluginInfo-Version=1
X-KDE-PluginInfo-Category=Window Open/Close Animation
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=false
X-KDE-Ordering=60
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
X-KDE-PluginKeyword=kwin4_effect_scale
X-KDE-Library=kcm_kwin4_genericscripted
X-KDE-ParentComponents=kwin4_effect_scale
X-KWin-Config-TranslationDomain=kwin_effects
X-KWin-Exclusive-Category=toplevel-open-close-animation
diff --git a/effects/sessionquit/package/metadata.desktop b/effects/sessionquit/package/metadata.desktop
index 70a4eca6c..5dc800e84 100644
--- a/effects/sessionquit/package/metadata.desktop
+++ b/effects/sessionquit/package/metadata.desktop
@@ -1,69 +1,71 @@
[Desktop Entry]
Name=Session Quit
Name[ca]=Sortida de la sessió
Name[cs]=Sezení bylo ukončeno
Name[da]=Afslutning af session
Name[en_GB]=Session Quit
Name[es]=Cierre de sesión
Name[et]=Seansist väljumine
Name[eu]=Saiotik irtetea
Name[fi]=Istunnon lopetus
Name[gl]=Saída de sesión
Name[ia]=Abandona session
Name[id]=Sesi Berhenti
Name[it]=Chiusura sessione
Name[ko]=세션 종료
Name[lt]=Seanso baigimas
Name[nl]=Afsluiten van sessie
Name[nn]=Avslutt økt
Name[pl]=Opuszczenie sesji
Name[pt]=Saída da Sessão
Name[pt_BR]=Saída da sessão
Name[ru]=Завершение сеанса
Name[sk]=Ukončenie sedenia
+Name[sl]=Zapri sejo
Name[sv]=Avsluta session
Name[uk]=Вихід з сеансу
Name[x-test]=xxSession Quitxx
Name[zh_CN]=会话退出
Name[zh_TW]=離開工作階段
Icon=preferences-system-windows-effect-logout
Comment=Keep the desktop background alive during logout until the end
Comment[ca]=Manté viu el fons de l'escriptori durant la sortida de la sessió fins el final
Comment[da]=Hold skrivebordsbaggrunden i live under log ud helt til sidst
Comment[en_GB]=Keep the desktop background alive during logout until the end
Comment[es]=Mantener el fondo del escritorio activo durante el cierre de sesión hasta el final
Comment[et]=Töölaua taust hoitakse väljalogimisel alles kuni lõpuni
Comment[eu]=Eutsi mahaigaineko atzeko-planoa bizirik saio-ixtean bukaera arte
Comment[fi]=Pidä työpöydän tausta käynnissä aina uloskirjautumisen loppuun
Comment[gl]=Manter vivo o fondo de escritorio durante a saída ata o final
Comment[id]=Jaga latarbelakang desktop tetap nyala selama logout sampai akhir
Comment[it]=Mantieni attivo lo sfondo del desktop durante la chiusura della sessione fino alla fine
Comment[ko]=로그아웃이 끝날 때까지 데스크톱 배경 그림 유지
Comment[lt]=Atsijungiant, išlaikyti darbalaukio foną reaguojantį iki pat galo
Comment[nl]=De achtergrond van het bureaublad tot het einde levend houden gedurende afmelden
Comment[nn]=Hald skrivebordsbakgrunnen i live heilt til utlogginga er fullført
Comment[pl]=Utrzymuj tło pulpitu podczas wylogowania, aż do końca
Comment[pt]=Manter o fundo do ecrã activo durante a saída da sessão até ao fim
Comment[pt_BR]=Mantém ativo o fundo da área de trabalho até o fim do fechamento da sessão
Comment[ru]=Сохранение фона рабочего стола до окончания завершения сеанса
Comment[sk]=Ponechať pozadie plochy aktívne počas odhlásenia do skončenia
+Comment[sl]=Pusti ozadje namizja živo ob odjavi do konca
Comment[sv]=Behåll skrivbordets bakgrund levande under utloggning till slutet
Comment[uk]=Не вимикати тло стільниці до кінця процедури виходу із облікового запису
Comment[x-test]=xxKeep the desktop background alive during logout until the endxx
Comment[zh_CN]=注销时保持桌面背景,直到完全退出
Comment[zh_TW]=直到登出完成前皆保留桌面背景圖片
Type=Service
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=David Edmundson
X-KDE-PluginInfo-Email=davidedmundson@kde.org
X-KDE-PluginInfo-Name=kwin4_effect_sessionquit
X-KDE-PluginInfo-Version=0.2.0
X-KDE-PluginInfo-Category=Appearance
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Ordering=40
X-Plasma-API=javascript
X-KWin-Internal=true
X-Plasma-MainScript=code/main.js
diff --git a/effects/showfps/CMakeLists.txt b/effects/showfps/CMakeLists.txt
index a3418d9a3..e217e68fa 100644
--- a/effects/showfps/CMakeLists.txt
+++ b/effects/showfps/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_showfps_config_SRCS showfps_config.cpp)
ki18n_wrap_ui(kwin_showfps_config_SRCS showfps_config.ui)
-qt5_add_dbus_interface(kwin_showfps_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_showfps_config_SRCS showfpsconfig.kcfgc)
add_library(kwin_showfps_config MODULE ${kwin_showfps_config_SRCS})
target_link_libraries(kwin_showfps_config
KF5::Completion
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_showfps_config showfps_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_showfps_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/showfps/showfps_config.desktop b/effects/showfps/showfps_config.desktop
index eceea565f..765b1345d 100644
--- a/effects/showfps/showfps_config.desktop
+++ b/effects/showfps/showfps_config.desktop
@@ -1,85 +1,85 @@
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-Library=kwin_showfps_config
X-KDE-ParentComponents=showfps
Name=Show FPS
Name[af]=Wys FPS
Name[ar]=أظهر عدد الإطارات بالثانية
Name[be@latin]=Vyjaŭleńnie „FPS”
Name[bg]=Показване на кад/сек
Name[bn_IN]=FPS প্রদর্শন করা হবে
Name[bs]=Kadrovi/sekundi
Name[ca]=Mostra els FPS
Name[ca@valencia]=Mostra els FPS
Name[cs]=Zobrazit FPS
Name[csb]=Wëskrzëni FPS
Name[da]=Vis FPS
Name[de]=Bilder pro Sekunde anzeigen
Name[el]=Εμφάνιση καρέ ανά δευτερόλεπτο
Name[en_GB]=Show FPS
Name[eo]=Montri FPS
Name[es]=Muestra FPS
Name[et]=FPS-i näitamine
Name[eu]=Erakutsi FPS
Name[fa]=نمایش FPS
Name[fi]=FPS-näyttö
Name[fr]=Afficher le nombre de trames par seconde
Name[fy]=FPS sjen litte
Name[ga]=Taispeáin FSS
Name[gl]=Mostrar os FPS
Name[gu]=FPS બતાવો
Name[he]=הצג מספר תמונות לשנייה
Name[hi]=एफ़पीएस दिखायें
Name[hne]=एफपीएस देखाव
Name[hr]=Prikaz FPS-a (broj okvira po sekundi)
Name[hu]=Képkockaszámláló
Name[ia]=Monstra FPS
Name[id]=Tampilkan FPS
Name[is]=Sýna FPS (rammar á sekúndu)
Name[it]=Mostra fotogrammi al secondo
Name[ja]=フレームレート (FPS) 表示
Name[kk]=FPS-ты көрсету
Name[km]=បង្ហាញ FPS
Name[kn]=FPS ತೋರಿಸು
Name[ko]=FPS 표시
Name[ku]=FPS'ê nîşan bide
Name[lt]=Rodyti kadr./sek.
Name[lv]=Rādīt kadrus/sek.
Name[mai]=एफपीएस देखाबू
Name[mk]=Прикажи рамки/сек
Name[ml]=എഫ്പിഎസ് കാണിക്കുക
Name[mr]=एफपीएस दर्शवा
Name[nb]=Vis FPS
Name[nds]=Bps wiesen
Name[ne]=एफपीएस देखाउनुहोस्
Name[nl]=FPS tonen
Name[nn]=Vis talet på bilete per sekund
Name[pa]=FPS ਵੇਖੋ
Name[pl]=Pokaż ilość klatek na sekundę
Name[pt]=Mostrar as IPS
Name[pt_BR]=Mostrar FPS
Name[ro]=Afișează CPS
Name[ru]=График производительности
Name[se]=Čájet rámmaid sekunddas
Name[si]=FPS පෙන්වන්න
Name[sk]=Zobraziť FPS
-Name[sl]=Sličice na sekundo
+Name[sl]=Prikaži sličice na sekundo
Name[sr]=Кадрови/секунди
Name[sr@ijekavian]=Кадрови/секунди
Name[sr@ijekavianlatin]=Kadrovi/sekundi
Name[sr@latin]=Kadrovi/sekundi
Name[sv]=Visa ramar/s
Name[ta]=Show FPS
Name[te]=FPS ను చూపుము
Name[th]=แสดงอัตราเฟรมต่อวินาที
Name[tr]=FPS Göster
Name[ug]=FPS نى كۆرسەت
Name[uk]=Показ частоти кадрів
Name[vi]=Hiện FPS
Name[wa]=Mostrer FPS
Name[x-test]=xxShow FPSxx
Name[zh_CN]=显示 FPS
Name[zh_TW]=顯示 FPS 畫格數
diff --git a/effects/slide/CMakeLists.txt b/effects/slide/CMakeLists.txt
index 718b903fb..a579bb630 100644
--- a/effects/slide/CMakeLists.txt
+++ b/effects/slide/CMakeLists.txt
@@ -1,23 +1,23 @@
#######################################
# Config
set(kwin_slide_config_SRCS slide_config.cpp)
ki18n_wrap_ui(kwin_slide_config_SRCS slide_config.ui)
-qt5_add_dbus_interface(kwin_slide_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_slide_config_SRCS slideconfig.kcfgc)
add_library(kwin_slide_config MODULE ${kwin_slide_config_SRCS})
target_link_libraries(kwin_slide_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_slide_config slide_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_slide_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/squash/package/metadata.desktop b/effects/squash/package/metadata.desktop
index c9e7f2b17..36ad7062e 100644
--- a/effects/squash/package/metadata.desktop
+++ b/effects/squash/package/metadata.desktop
@@ -1,77 +1,79 @@
[Desktop Entry]
Comment=Squash windows when they are minimized
Comment[ca]=Amuntega les finestres quan estan minimitzades
Comment[ca@valencia]=Amuntega les finestres quan estan minimitzades
Comment[da]=Mas vinduer når de minimeres
Comment[de]=Quetscht Fenster beim Minimieren zusammen
Comment[en_GB]=Squash windows when they are minimised
Comment[es]=Aplastar las ventanas al minimizarlas
Comment[et]=Minimeeritud akende taas üleshüpitamine
Comment[eu]=Zanpatu leihoak haiek ikonotzean
Comment[fi]=Litistä ikkunat, kun ne pienennetään
Comment[fr]=Écrase les fenêtres lorsqu'elles sont minimisées
Comment[gl]=Xuntar as xanelas cando estean minimizadas
Comment[ia]=Deforma fenestras durante que illes es minimisate
Comment[id]=Sesakkan window ketika mereka diminimalkan
Comment[it]=Schiaccia le finestre quando vengono minimizzate
Comment[ko]=창을 최소화할 때 압축시킵니다
Comment[lt]=Sutraiškyti langus, juos suskleidžiant
Comment[nl]=Krimp vensters wanneer ze geminimaliseerd zijn
Comment[nn]=Skvis vindauge når dei vert minimerte
Comment[pl]=Ściąga okna przy ich minimalizacji
Comment[pt]=Esmagar as janelas quando são minimizadas
Comment[pt_BR]=Achatar as janelas quando são minimizadas
Comment[ru]=Сжатие окна при сворачивании
Comment[sk]=Deformuje okná pri ich minimalizovaní
+Comment[sl]=Zmečkaj okna, ko jih strneš
Comment[sv]=Kläm fönster när de minimeras
Comment[uk]=Складує вікна, якщо їх мінімізовано
Comment[x-test]=xxSquash windows when they are minimizedxx
Comment[zh_CN]=最小化时压扁窗口
Comment[zh_TW]=壓縮最小化的視窗
Icon=preferences-system-windows-effect-squash
Name=Squash
Name[ca]=Amuntega
Name[ca@valencia]=Amuntega
Name[da]=Mas
Name[de]=Quetschen
Name[en_GB]=Squash
Name[es]=Aplastar
Name[et]=Üleshüpe
Name[eu]=Zanpatu
Name[fi]=Litistä
Name[fr]=Écraser
Name[gl]=Xuntar
Name[ia]=Squash
Name[id]=Sesakkan
Name[it]=Schiaccia
Name[ko]=압축
Name[lt]=Sutraiškymas
Name[nl]=Krimpen
Name[nn]=Skvis
Name[pl]=Ściąganie
Name[pt]=Esmagar
Name[pt_BR]=Achatar
Name[ru]=Сжатие
Name[sk]=Rozpučiť
+Name[sl]=Zmečkaj
Name[sv]=Kläm
Name[uk]=Складування
Name[x-test]=xxSquashxx
Name[zh_CN]=压扁
Name[zh_TW]=壓縮
Type=Service
X-KDE-ParentApp=
X-KDE-PluginInfo-Author=Rivo Laks, Vlad Zahorodnii
X-KDE-PluginInfo-Category=Appearance
X-KDE-PluginInfo-Email=rivolaks@hot.ee, vlad.zahorodnii@kde.org
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Name=kwin4_effect_squash
X-KDE-PluginInfo-Version=1
X-KDE-PluginInfo-Website=
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Ordering=60
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
X-KWin-Exclusive-Category=minimize
X-KWin-Video-Url=https://files.kde.org/plasma/kwin/effect-videos/minimize.ogv
diff --git a/effects/thumbnailaside/CMakeLists.txt b/effects/thumbnailaside/CMakeLists.txt
index 6e5caf6c7..dacfb2a7e 100644
--- a/effects/thumbnailaside/CMakeLists.txt
+++ b/effects/thumbnailaside/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_thumbnailaside_config_SRCS thumbnailaside_config.cpp)
ki18n_wrap_ui(kwin_thumbnailaside_config_SRCS thumbnailaside_config.ui)
-qt5_add_dbus_interface(kwin_thumbnailaside_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_thumbnailaside_config_SRCS thumbnailasideconfig.kcfgc)
add_library(kwin_thumbnailaside_config MODULE ${kwin_thumbnailaside_config_SRCS})
target_link_libraries(kwin_thumbnailaside_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_thumbnailaside_config thumbnailaside_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_thumbnailaside_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/trackmouse/CMakeLists.txt b/effects/trackmouse/CMakeLists.txt
index f467998fc..c44223a00 100644
--- a/effects/trackmouse/CMakeLists.txt
+++ b/effects/trackmouse/CMakeLists.txt
@@ -1,29 +1,29 @@
#######################################
# Effect
# Data files
install(FILES data/tm_inner.png data/tm_outer.png DESTINATION ${DATA_INSTALL_DIR}/kwin)
#######################################
# Config
set(kwin_trackmouse_config_SRCS trackmouse_config.cpp)
ki18n_wrap_ui(kwin_trackmouse_config_SRCS trackmouse_config.ui)
-qt5_add_dbus_interface(kwin_trackmouse_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_trackmouse_config_SRCS trackmouseconfig.kcfgc)
add_library(kwin_trackmouse_config MODULE ${kwin_trackmouse_config_SRCS})
target_link_libraries(kwin_trackmouse_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_trackmouse_config trackmouse_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_trackmouse_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/windowaperture/package/metadata.desktop b/effects/windowaperture/package/metadata.desktop
index 6a3d09e6d..fc8d13731 100644
--- a/effects/windowaperture/package/metadata.desktop
+++ b/effects/windowaperture/package/metadata.desktop
@@ -1,78 +1,80 @@
[Desktop Entry]
Name=Window Aperture
Name[ast]=Apertura de ventanes
Name[ca]=Obertura de la finestra
Name[ca@valencia]=Obertura de la finestra
Name[cs]=Mřížka oken
Name[da]=Vinduesblænding
Name[de]=Fensteröffnung
Name[el]=Διάφραγμα παραθύρου
Name[en_GB]=Window Aperture
Name[es]=Apertura de ventanas
Name[et]=Aknaava
Name[eu]=Leihoa irekitzea
Name[fi]=Ikkunoiden siirto näytön kulmiin
Name[fr]=Ouverture de la fenêtre
Name[gl]=Apertura das xanelas
Name[hu]=Ablakrekeszek
Name[ia]=Aperturas de fenestra
Name[id]=Window Melubang
Name[it]=Apertura delle finestre
Name[ko]=조리개 모양 배치
Name[lt]=Lango anga
Name[nb]=Vindusåpning
Name[nl]=Vensteropening
Name[nn]=Vindaugsflukt
Name[pl]=Przesłona okna
Name[pt]=Aperto das Janelas
Name[pt_BR]=Aperto das janelas
Name[ro]=Diafragmă fereastră
Name[ru]=Разбрасывание окон в стороны
Name[sk]=Otvor okien
Name[sl]=Zaslonka okna
Name[sr]=Бленда прозора
Name[sr@ijekavian]=Бленда прозора
Name[sr@ijekavianlatin]=Blenda prozora
Name[sr@latin]=Blenda prozora
Name[sv]=Fönsteröppning
Name[tr]=Pencere Açıklığı
Name[uk]=Апертура вікна
Name[x-test]=xxWindow Aperturexx
Name[zh_CN]=窗口光圈
Name[zh_TW]=視窗光圈
Icon=preferences-system-windows-effect-windowaperture
Comment=Move windows into screen corners
Comment[ca]=Mou les finestres cap a les cantonades de la pantalla
Comment[cs]=Přesunout okna do rohů obrazovky
+Comment[en_GB]=Move windows into screen corners
Comment[es]=Mover las ventanas a las esquinas de la pantalla
Comment[et]=Akende liigutamine ekraani nurkadesse
Comment[eu]=Eraman leihoak pantailako bazterretara
Comment[id]=Pindahkan window ke sudut layar
Comment[it]=Sposta le finestre negli angoli dello schermo
Comment[ko]=창을 화면 꼭짓점으로 이동
Comment[lt]=Perkelti langus į kampus
Comment[nl]=Verplaats vensters in de hoeken van het scherm
Comment[nn]=Flytt vindauge til skjermhjørne
Comment[pt]=Mover as janelas para os cantos do ecrã
Comment[pt_BR]=Move as janelas para os cantos da tela
Comment[ru]=Перемещение окон в углы экрана
+Comment[sl]=Pomakne okna v kote zaslona
Comment[sv]=Flytta fönster till skärmhörn
Comment[uk]=Пересування вікон до кутів екрана
Comment[x-test]=xxMove windows into screen cornersxx
Comment[zh_CN]=将窗口移动到屏幕角
Comment[zh_TW]=將視窗移至螢幕角落
Type=Service
X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=Thomas Lübking
X-KDE-PluginInfo-Email=thomas.luebking@gmail.com
X-KDE-PluginInfo-Name=kwin4_effect_windowaperture
X-KDE-PluginInfo-Version=0.1.0
X-KDE-PluginInfo-Category=Show Desktop Animation
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Ordering=50
X-KWin-Exclusive-Category=show-desktop
diff --git a/effects/windowgeometry/CMakeLists.txt b/effects/windowgeometry/CMakeLists.txt
index 0d13c4fd6..4a460425d 100644
--- a/effects/windowgeometry/CMakeLists.txt
+++ b/effects/windowgeometry/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_windowgeometry_config_SRCS windowgeometry_config.cpp)
ki18n_wrap_ui(kwin_windowgeometry_config_SRCS windowgeometry_config.ui)
-qt5_add_dbus_interface(kwin_windowgeometry_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_windowgeometry_config_SRCS windowgeometryconfig.kcfgc)
add_library(kwin_windowgeometry_config MODULE ${kwin_windowgeometry_config_SRCS})
target_link_libraries(kwin_windowgeometry_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_windowgeometry_config windowgeometry_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_windowgeometry_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/wobblywindows/CMakeLists.txt b/effects/wobblywindows/CMakeLists.txt
index da4b21c1b..fb2e038e9 100644
--- a/effects/wobblywindows/CMakeLists.txt
+++ b/effects/wobblywindows/CMakeLists.txt
@@ -1,23 +1,23 @@
#######################################
# Config
set(kwin_wobblywindows_config_SRCS wobblywindows_config.cpp)
ki18n_wrap_ui(kwin_wobblywindows_config_SRCS wobblywindows_config.ui)
-qt5_add_dbus_interface(kwin_wobblywindows_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_wobblywindows_config_SRCS wobblywindowsconfig.kcfgc)
add_library(kwin_wobblywindows_config MODULE ${kwin_wobblywindows_config_SRCS})
target_link_libraries(kwin_wobblywindows_config
KF5::ConfigWidgets
KF5::I18n
Qt5::DBus
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_wobblywindows_config wobblywindows_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_wobblywindows_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/effects/zoom/CMakeLists.txt b/effects/zoom/CMakeLists.txt
index 81f50a400..b6b47f241 100644
--- a/effects/zoom/CMakeLists.txt
+++ b/effects/zoom/CMakeLists.txt
@@ -1,24 +1,24 @@
#######################################
# Config
set(kwin_zoom_config_SRCS zoom_config.cpp)
ki18n_wrap_ui(kwin_zoom_config_SRCS zoom_config.ui)
-qt5_add_dbus_interface(kwin_zoom_config_SRCS ${kwin_effects_dbus_xml} kwineffects_interface)
kconfig_add_kcfg_files(kwin_zoom_config_SRCS zoomconfig.kcfgc)
add_library(kwin_zoom_config MODULE ${kwin_zoom_config_SRCS})
target_link_libraries(kwin_zoom_config
KF5::ConfigWidgets
KF5::GlobalAccel
KF5::I18n
KF5::XmlGui
+ KWinEffectsInterface
)
kcoreaddons_desktop_to_json(kwin_zoom_config zoom_config.desktop SERVICE_TYPES kcmodule.desktop)
install(
TARGETS
kwin_zoom_config
DESTINATION
${PLUGIN_INSTALL_DIR}/kwin/effects/configs
)
diff --git a/input.cpp b/input.cpp
index e2c5f09c6..c0879252f 100644
--- a/input.cpp
+++ b/input.cpp
@@ -1,2697 +1,2712 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2013 Martin Gräßlin
Copyright (C) 2018 Roman Gilg
Copyright (C) 2019 Vlad Zahorodnii
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 "input.h"
#include "effects.h"
#include "gestures.h"
#include "globalshortcuts.h"
#include "input_event.h"
#include "input_event_spy.h"
#include "keyboard_input.h"
#include "logind.h"
#include "main.h"
#include "pointer_input.h"
#include "tablet_input.h"
#include "touch_hide_cursor_spy.h"
#include "touch_input.h"
#include "x11client.h"
#ifdef KWIN_BUILD_TABBOX
#include "tabbox/tabbox.h"
#endif
#include "internal_client.h"
#include "libinput/connection.h"
#include "libinput/device.h"
#include "platform.h"
#include "popup_input_filter.h"
#include "screenedge.h"
#include "screens.h"
#include "unmanaged.h"
#include "wayland_server.h"
#include "workspace.h"
#include "xdgshellclient.h"
#include "xwl/xwayland_interface.h"
#include "cursor.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
//screenlocker
#include
// Qt
#include
#include
namespace KWin
{
InputEventFilter::InputEventFilter() = default;
InputEventFilter::~InputEventFilter()
{
if (input()) {
input()->uninstallInputEventFilter(this);
}
}
bool InputEventFilter::pointerEvent(QMouseEvent *event, quint32 nativeButton)
{
Q_UNUSED(event)
Q_UNUSED(nativeButton)
return false;
}
bool InputEventFilter::wheelEvent(QWheelEvent *event)
{
Q_UNUSED(event)
return false;
}
bool InputEventFilter::keyEvent(QKeyEvent *event)
{
Q_UNUSED(event)
return false;
}
bool InputEventFilter::touchDown(qint32 id, const QPointF &point, quint32 time)
{
Q_UNUSED(id)
Q_UNUSED(point)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::touchMotion(qint32 id, const QPointF &point, quint32 time)
{
Q_UNUSED(id)
Q_UNUSED(point)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::touchUp(qint32 id, quint32 time)
{
Q_UNUSED(id)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::pinchGestureBegin(int fingerCount, quint32 time)
{
Q_UNUSED(fingerCount)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time)
{
Q_UNUSED(scale)
Q_UNUSED(angleDelta)
Q_UNUSED(delta)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::pinchGestureEnd(quint32 time)
{
Q_UNUSED(time)
return false;
}
bool InputEventFilter::pinchGestureCancelled(quint32 time)
{
Q_UNUSED(time)
return false;
}
bool InputEventFilter::swipeGestureBegin(int fingerCount, quint32 time)
{
Q_UNUSED(fingerCount)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::swipeGestureUpdate(const QSizeF &delta, quint32 time)
{
Q_UNUSED(delta)
Q_UNUSED(time)
return false;
}
bool InputEventFilter::swipeGestureEnd(quint32 time)
{
Q_UNUSED(time)
return false;
}
bool InputEventFilter::swipeGestureCancelled(quint32 time)
{
Q_UNUSED(time)
return false;
}
bool InputEventFilter::switchEvent(SwitchEvent *event)
{
Q_UNUSED(event)
return false;
}
bool InputEventFilter::tabletToolEvent(TabletEvent *event)
{
Q_UNUSED(event)
return false;
}
bool InputEventFilter::tabletToolButtonEvent(const QSet &pressedButtons)
{
Q_UNUSED(pressedButtons)
return false;
}
bool InputEventFilter::tabletPadButtonEvent(const QSet &pressedButtons)
{
Q_UNUSED(pressedButtons)
return false;
}
bool InputEventFilter::tabletPadStripEvent(int number, int position, bool isFinger)
{
Q_UNUSED(number)
Q_UNUSED(position)
Q_UNUSED(isFinger)
return false;
}
bool InputEventFilter::tabletPadRingEvent(int number, int position, bool isFinger)
{
Q_UNUSED(number)
Q_UNUSED(position)
Q_UNUSED(isFinger)
return false;
}
void InputEventFilter::passToWaylandServer(QKeyEvent *event)
{
Q_ASSERT(waylandServer());
if (event->isAutoRepeat()) {
return;
}
switch (event->type()) {
case QEvent::KeyPress:
waylandServer()->seat()->keyPressed(event->nativeScanCode());
break;
case QEvent::KeyRelease:
waylandServer()->seat()->keyReleased(event->nativeScanCode());
break;
default:
break;
}
}
class VirtualTerminalFilter : public InputEventFilter {
public:
bool keyEvent(QKeyEvent *event) override {
// really on press and not on release? X11 switches on press.
if (event->type() == QEvent::KeyPress && !event->isAutoRepeat()) {
const xkb_keysym_t keysym = event->nativeVirtualKey();
if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) {
LogindIntegration::self()->switchVirtualTerminal(keysym - XKB_KEY_XF86Switch_VT_1 + 1);
return true;
}
}
return false;
}
};
class TerminateServerFilter : public InputEventFilter {
public:
bool keyEvent(QKeyEvent *event) override {
if (event->type() == QEvent::KeyPress && !event->isAutoRepeat()) {
if (event->nativeVirtualKey() == XKB_KEY_Terminate_Server) {
qCWarning(KWIN_CORE) << "Request to terminate server";
QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
return true;
}
}
return false;
}
};
class LockScreenFilter : public InputEventFilter {
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
if (!waylandServer()->isScreenLocked()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(event->timestamp());
if (event->type() == QEvent::MouseMove) {
if (pointerSurfaceAllowed()) {
// TODO: should the pointer position always stay in sync, i.e. not do the check?
seat->setPointerPos(event->screenPos().toPoint());
}
} else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
if (pointerSurfaceAllowed()) {
// TODO: can we leak presses/releases here when we move the mouse in between from an allowed surface to
// disallowed one or vice versa?
event->type() == QEvent::MouseButtonPress ? seat->pointerButtonPressed(nativeButton) : seat->pointerButtonReleased(nativeButton);
}
}
return true;
}
bool wheelEvent(QWheelEvent *event) override {
if (!waylandServer()->isScreenLocked()) {
return false;
}
auto seat = waylandServer()->seat();
if (pointerSurfaceAllowed()) {
seat->setTimestamp(event->timestamp());
const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal;
seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y());
}
return true;
}
bool keyEvent(QKeyEvent * event) override {
if (!waylandServer()->isScreenLocked()) {
return false;
}
if (event->isAutoRepeat()) {
// wayland client takes care of it
return true;
}
// send event to KSldApp for global accel
// if event is set to accepted it means a whitelisted shortcut was triggered
// in that case we filter it out and don't process it further
event->setAccepted(false);
QCoreApplication::sendEvent(ScreenLocker::KSldApp::self(), event);
if (event->isAccepted()) {
return true;
}
// continue normal processing
input()->keyboard()->update();
auto seat = waylandServer()->seat();
seat->setTimestamp(event->timestamp());
if (!keyboardSurfaceAllowed()) {
// don't pass event to seat
return true;
}
switch (event->type()) {
case QEvent::KeyPress:
seat->keyPressed(event->nativeScanCode());
break;
case QEvent::KeyRelease:
seat->keyReleased(event->nativeScanCode());
break;
default:
break;
}
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
if (!waylandServer()->isScreenLocked()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
if (touchSurfaceAllowed()) {
input()->touch()->insertId(id, seat->touchDown(pos));
}
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
if (!waylandServer()->isScreenLocked()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
if (touchSurfaceAllowed()) {
const qint32 kwaylandId = input()->touch()->mappedId(id);
if (kwaylandId != -1) {
seat->touchMove(kwaylandId, pos);
}
}
return true;
}
bool touchUp(qint32 id, quint32 time) override {
if (!waylandServer()->isScreenLocked()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
if (touchSurfaceAllowed()) {
const qint32 kwaylandId = input()->touch()->mappedId(id);
if (kwaylandId != -1) {
seat->touchUp(kwaylandId);
input()->touch()->removeId(id);
}
}
return true;
}
bool pinchGestureBegin(int fingerCount, quint32 time) override {
Q_UNUSED(fingerCount)
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time) override {
Q_UNUSED(scale)
Q_UNUSED(angleDelta)
Q_UNUSED(delta)
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool pinchGestureEnd(quint32 time) override {
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool pinchGestureCancelled(quint32 time) override {
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool swipeGestureBegin(int fingerCount, quint32 time) override {
Q_UNUSED(fingerCount)
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool swipeGestureUpdate(const QSizeF &delta, quint32 time) override {
Q_UNUSED(delta)
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool swipeGestureEnd(quint32 time) override {
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
bool swipeGestureCancelled(quint32 time) override {
Q_UNUSED(time)
// no touchpad multi-finger gestures on lock screen
return waylandServer()->isScreenLocked();
}
private:
bool surfaceAllowed(KWayland::Server::SurfaceInterface *(KWayland::Server::SeatInterface::*method)() const) const {
if (KWayland::Server::SurfaceInterface *s = (waylandServer()->seat()->*method)()) {
if (Toplevel *t = waylandServer()->findClient(s)) {
return t->isLockScreen() || t->isInputMethod();
}
return false;
}
return true;
}
bool pointerSurfaceAllowed() const {
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedPointerSurface);
}
bool keyboardSurfaceAllowed() const {
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedKeyboardSurface);
}
bool touchSurfaceAllowed() const {
return surfaceAllowed(&KWayland::Server::SeatInterface::focusedTouchSurface);
}
};
class EffectsFilter : public InputEventFilter {
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
if (!effects) {
return false;
}
return static_cast(effects)->checkInputWindowEvent(event);
}
bool wheelEvent(QWheelEvent *event) override {
if (!effects) {
return false;
}
return static_cast(effects)->checkInputWindowEvent(event);
}
bool keyEvent(QKeyEvent *event) override {
if (!effects || !static_cast< EffectsHandlerImpl* >(effects)->hasKeyboardGrab()) {
return false;
}
waylandServer()->seat()->setFocusedKeyboardSurface(nullptr);
passToWaylandServer(event);
static_cast< EffectsHandlerImpl* >(effects)->grabbedKeyboardEvent(event);
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
if (!effects) {
return false;
}
return static_cast< EffectsHandlerImpl* >(effects)->touchDown(id, pos, time);
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
if (!effects) {
return false;
}
return static_cast< EffectsHandlerImpl* >(effects)->touchMotion(id, pos, time);
}
bool touchUp(qint32 id, quint32 time) override {
if (!effects) {
return false;
}
return static_cast< EffectsHandlerImpl* >(effects)->touchUp(id, time);
}
};
class MoveResizeFilter : public InputEventFilter {
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
AbstractClient *c = workspace()->moveResizeClient();
if (!c) {
return false;
}
switch (event->type()) {
case QEvent::MouseMove:
c->updateMoveResize(event->screenPos().toPoint());
break;
case QEvent::MouseButtonRelease:
if (event->buttons() == Qt::NoButton) {
c->endMoveResize();
}
break;
default:
break;
}
return true;
}
bool wheelEvent(QWheelEvent *event) override {
Q_UNUSED(event)
// filter out while moving a window
return workspace()->moveResizeClient() != nullptr;
}
bool keyEvent(QKeyEvent *event) override {
AbstractClient *c = workspace()->moveResizeClient();
if (!c) {
return false;
}
if (event->type() == QEvent::KeyPress) {
c->keyPressEvent(event->key() | event->modifiers());
if (c->isMove() || c->isResize()) {
// only update if mode didn't end
c->updateMoveResize(input()->globalPointer());
}
}
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(id)
Q_UNUSED(pos)
Q_UNUSED(time)
AbstractClient *c = workspace()->moveResizeClient();
if (!c) {
return false;
}
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(time)
AbstractClient *c = workspace()->moveResizeClient();
if (!c) {
return false;
}
if (!m_set) {
m_id = id;
m_set = true;
}
if (m_id == id) {
c->updateMoveResize(pos.toPoint());
}
return true;
}
bool touchUp(qint32 id, quint32 time) override {
Q_UNUSED(time)
AbstractClient *c = workspace()->moveResizeClient();
if (!c) {
return false;
}
if (m_id == id || !m_set) {
c->endMoveResize();
m_set = false;
// pass through to update decoration filter later on
return false;
}
m_set = false;
return true;
}
private:
qint32 m_id = 0;
bool m_set = false;
};
class WindowSelectorFilter : public InputEventFilter {
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
if (!m_active) {
return false;
}
switch (event->type()) {
case QEvent::MouseButtonRelease:
if (event->buttons() == Qt::NoButton) {
if (event->button() == Qt::RightButton) {
cancel();
} else {
accept(event->globalPos());
}
}
break;
default:
break;
}
return true;
}
bool wheelEvent(QWheelEvent *event) override {
Q_UNUSED(event)
// filter out while selecting a window
return m_active;
}
bool keyEvent(QKeyEvent *event) override {
Q_UNUSED(event)
if (!m_active) {
return false;
}
waylandServer()->seat()->setFocusedKeyboardSurface(nullptr);
passToWaylandServer(event);
if (event->type() == QEvent::KeyPress) {
// x11 variant does this on key press, so do the same
if (event->key() == Qt::Key_Escape) {
cancel();
} else if (event->key() == Qt::Key_Enter ||
event->key() == Qt::Key_Return ||
event->key() == Qt::Key_Space) {
accept(input()->globalPointer());
}
if (input()->supportsPointerWarping()) {
int mx = 0;
int my = 0;
if (event->key() == Qt::Key_Left) {
mx = -10;
}
if (event->key() == Qt::Key_Right) {
mx = 10;
}
if (event->key() == Qt::Key_Up) {
my = -10;
}
if (event->key() == Qt::Key_Down) {
my = 10;
}
if (event->modifiers() & Qt::ControlModifier) {
mx /= 10;
my /= 10;
}
input()->warpPointer(input()->globalPointer() + QPointF(mx, my));
}
}
// filter out while selecting a window
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(time)
if (!isActive()) {
return false;
}
m_touchPoints.insert(id, pos);
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(time)
if (!isActive()) {
return false;
}
auto it = m_touchPoints.find(id);
if (it != m_touchPoints.end()) {
*it = pos;
}
return true;
}
bool touchUp(qint32 id, quint32 time) override {
Q_UNUSED(time)
if (!isActive()) {
return false;
}
auto it = m_touchPoints.find(id);
if (it != m_touchPoints.end()) {
const auto pos = it.value();
m_touchPoints.erase(it);
if (m_touchPoints.isEmpty()) {
accept(pos);
}
}
return true;
}
bool isActive() const {
return m_active;
}
void start(std::function callback) {
Q_ASSERT(!m_active);
m_active = true;
m_callback = callback;
input()->keyboard()->update();
input()->cancelTouch();
}
void start(std::function callback) {
Q_ASSERT(!m_active);
m_active = true;
m_pointSelectionFallback = callback;
input()->keyboard()->update();
input()->cancelTouch();
}
private:
void deactivate() {
m_active = false;
m_callback = std::function();
m_pointSelectionFallback = std::function();
input()->pointer()->removeWindowSelectionCursor();
input()->keyboard()->update();
m_touchPoints.clear();
}
void cancel() {
if (m_callback) {
m_callback(nullptr);
}
if (m_pointSelectionFallback) {
m_pointSelectionFallback(QPoint(-1, -1));
}
deactivate();
}
void accept(const QPoint &pos) {
if (m_callback) {
// TODO: this ignores shaped windows
m_callback(input()->findToplevel(pos));
}
if (m_pointSelectionFallback) {
m_pointSelectionFallback(pos);
}
deactivate();
}
void accept(const QPointF &pos) {
accept(pos.toPoint());
}
bool m_active = false;
std::function m_callback;
std::function m_pointSelectionFallback;
QMap m_touchPoints;
};
class GlobalShortcutFilter : public InputEventFilter {
public:
+ GlobalShortcutFilter() {
+ m_powerDown = new QTimer;
+ m_powerDown->setSingleShot(true);
+ m_powerDown->setInterval(1000);
+ }
+ ~GlobalShortcutFilter() {
+ delete m_powerDown;
+ }
+
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton);
if (event->type() == QEvent::MouseButtonPress) {
if (input()->shortcuts()->processPointerPressed(event->modifiers(), event->buttons())) {
return true;
}
}
return false;
}
bool wheelEvent(QWheelEvent *event) override {
if (event->modifiers() == Qt::NoModifier) {
return false;
}
PointerAxisDirection direction = PointerAxisUp;
if (event->angleDelta().x() < 0) {
direction = PointerAxisRight;
} else if (event->angleDelta().x() > 0) {
direction = PointerAxisLeft;
} else if (event->angleDelta().y() < 0) {
direction = PointerAxisDown;
} else if (event->angleDelta().y() > 0) {
direction = PointerAxisUp;
}
return input()->shortcuts()->processAxis(event->modifiers(), direction);
}
bool keyEvent(QKeyEvent *event) override {
if (event->key() == Qt::Key_PowerOff) {
- if (event->type() == QEvent::KeyPress) {
- m_powerOffPress = event->timestamp();
+ const auto modifiers = static_cast(event)->modifiersRelevantForGlobalShortcuts();
+ if (event->type() == QEvent::KeyPress && !event->isAutoRepeat()) {
+ QObject::connect(m_powerDown, &QTimer::timeout, input()->shortcuts(), [this, modifiers] {
+ QObject::disconnect(m_powerDown, &QTimer::timeout, input()->shortcuts(), nullptr);
+ m_powerDown->stop();
+ input()->shortcuts()->processKey(modifiers, Qt::Key_PowerDown);
+ });
+ m_powerDown->start();
+ return true;
} else if (event->type() == QEvent::KeyRelease) {
- const uint duration = (event->timestamp() - m_powerOffPress);
- const Qt::Key key = duration > 1000 ? Qt::Key_PowerDown : Qt::Key_PowerOff;
- const auto shortcuts = static_cast(event)->modifiersRelevantForGlobalShortcuts();
- return input()->shortcuts()->processKey(shortcuts, key | (event->key() & ~Qt::KeyboardModifierMask));
+ const bool ret = !m_powerDown->isActive() || input()->shortcuts()->processKey(modifiers, event->key());
+ m_powerDown->stop();
+ return ret;
}
} else if (event->type() == QEvent::KeyPress) {
return input()->shortcuts()->processKey(static_cast(event)->modifiersRelevantForGlobalShortcuts(), event->key());
}
return false;
}
bool swipeGestureBegin(int fingerCount, quint32 time) override {
Q_UNUSED(time)
input()->shortcuts()->processSwipeStart(fingerCount);
return false;
}
bool swipeGestureUpdate(const QSizeF &delta, quint32 time) override {
Q_UNUSED(time)
input()->shortcuts()->processSwipeUpdate(delta);
return false;
}
bool swipeGestureCancelled(quint32 time) override {
Q_UNUSED(time)
input()->shortcuts()->processSwipeCancel();
return false;
}
bool swipeGestureEnd(quint32 time) override {
Q_UNUSED(time)
input()->shortcuts()->processSwipeEnd();
return false;
}
private:
- uint m_powerOffPress;
+ QTimer* m_powerDown = nullptr;
};
namespace {
enum class MouseAction {
ModifierOnly,
ModifierAndWindow
};
std::pair performClientMouseAction(QMouseEvent *event, AbstractClient *client, MouseAction action = MouseAction::ModifierOnly)
{
Options::MouseCommand command = Options::MouseNothing;
bool wasAction = false;
if (static_cast(event)->modifiersRelevantForGlobalShortcuts() == options->commandAllModifier()) {
if (!input()->pointer()->isConstrained() && !workspace()->globalShortcutsDisabled()) {
wasAction = true;
switch (event->button()) {
case Qt::LeftButton:
command = options->commandAll1();
break;
case Qt::MiddleButton:
command = options->commandAll2();
break;
case Qt::RightButton:
command = options->commandAll3();
break;
default:
// nothing
break;
}
}
} else {
if (action == MouseAction::ModifierAndWindow) {
command = client->getMouseCommand(event->button(), &wasAction);
}
}
if (wasAction) {
return std::make_pair(wasAction, !client->performMouseCommand(command, event->globalPos()));
}
return std::make_pair(wasAction, false);
}
std::pair performClientWheelAction(QWheelEvent *event, AbstractClient *c, MouseAction action = MouseAction::ModifierOnly)
{
bool wasAction = false;
Options::MouseCommand command = Options::MouseNothing;
if (static_cast(event)->modifiersRelevantForGlobalShortcuts() == options->commandAllModifier()) {
if (!input()->pointer()->isConstrained() && !workspace()->globalShortcutsDisabled()) {
wasAction = true;
command = options->operationWindowMouseWheel(-1 * event->angleDelta().y());
}
} else {
if (action == MouseAction::ModifierAndWindow) {
command = c->getWheelCommand(Qt::Vertical, &wasAction);
}
}
if (wasAction) {
return std::make_pair(wasAction, !c->performMouseCommand(command, event->globalPos()));
}
return std::make_pair(wasAction, false);
}
}
class InternalWindowEventFilter : public InputEventFilter {
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
auto internal = input()->pointer()->internalWindow();
if (!internal) {
return false;
}
// find client
switch (event->type())
{
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease: {
auto s = qobject_cast(workspace()->findInternal(internal));
if (s && s->isDecorated()) {
// only perform mouse commands on decorated internal windows
const auto actionResult = performClientMouseAction(event, s);
if (actionResult.first) {
return actionResult.second;
}
}
break;
}
default:
break;
}
QMouseEvent e(event->type(),
event->pos() - internal->position(),
event->globalPos(),
event->button(), event->buttons(), event->modifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(internal.data(), &e);
return e.isAccepted();
}
bool wheelEvent(QWheelEvent *event) override {
auto internal = input()->pointer()->internalWindow();
if (!internal) {
return false;
}
if (event->angleDelta().y() != 0) {
auto s = qobject_cast(workspace()->findInternal(internal));
if (s && s->isDecorated()) {
// client window action only on vertical scrolling
const auto actionResult = performClientWheelAction(event, s);
if (actionResult.first) {
return actionResult.second;
}
}
}
const QPointF localPos = event->globalPosF() - QPointF(internal->x(), internal->y());
const Qt::Orientation orientation = (event->angleDelta().x() != 0) ? Qt::Horizontal : Qt::Vertical;
const int delta = event->angleDelta().x() != 0 ? event->angleDelta().x() : event->angleDelta().y();
QWheelEvent e(localPos, event->globalPosF(), QPoint(),
event->angleDelta() * -1,
delta * -1,
orientation,
event->buttons(),
event->modifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(internal.data(), &e);
return e.isAccepted();
}
bool keyEvent(QKeyEvent *event) override {
const QList &internalClients = workspace()->internalClients();
if (internalClients.isEmpty()) {
return false;
}
QWindow *found = nullptr;
auto it = internalClients.end();
do {
it--;
if (QWindow *w = (*it)->internalWindow()) {
if (!w->isVisible()) {
continue;
}
if (!screens()->geometry().contains(w->geometry())) {
continue;
}
if (w->property("_q_showWithoutActivating").toBool()) {
continue;
}
if (w->property("outputOnly").toBool()) {
continue;
}
if (w->flags().testFlag(Qt::ToolTip)) {
continue;
}
found = w;
break;
}
} while (it != internalClients.begin());
if (!found) {
return false;
}
auto xkb = input()->keyboard()->xkb();
Qt::Key key = xkb->toQtKey(xkb->toKeysym(event->nativeScanCode()));
if (key == Qt::Key_Super_L || key == Qt::Key_Super_R) {
// workaround for QTBUG-62102
key = Qt::Key_Meta;
}
QKeyEvent internalEvent(event->type(), key,
event->modifiers(), event->nativeScanCode(), event->nativeVirtualKey(),
event->nativeModifiers(), event->text());
internalEvent.setAccepted(false);
if (QCoreApplication::sendEvent(found, &internalEvent)) {
waylandServer()->seat()->setFocusedKeyboardSurface(nullptr);
passToWaylandServer(event);
return true;
}
return false;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
auto seat = waylandServer()->seat();
if (seat->isTouchSequence()) {
// something else is getting the events
return false;
}
auto touch = input()->touch();
if (touch->internalPressId() != -1) {
// already on internal window, ignore further touch points, but filter out
return true;
}
// a new touch point
seat->setTimestamp(time);
auto internal = touch->internalWindow();
if (!internal) {
return false;
}
touch->setInternalPressId(id);
// Qt's touch event API is rather complex, let's do fake mouse events instead
m_lastGlobalTouchPos = pos;
m_lastLocalTouchPos = pos - QPointF(internal->x(), internal->y());
QEnterEvent enterEvent(m_lastLocalTouchPos, m_lastLocalTouchPos, pos);
QCoreApplication::sendEvent(internal.data(), &enterEvent);
QMouseEvent e(QEvent::MouseButtonPress, m_lastLocalTouchPos, pos, Qt::LeftButton, Qt::LeftButton, input()->keyboardModifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(internal.data(), &e);
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
auto touch = input()->touch();
auto internal = touch->internalWindow();
if (!internal) {
return false;
}
if (touch->internalPressId() == -1) {
return false;
}
waylandServer()->seat()->setTimestamp(time);
if (touch->internalPressId() != qint32(id)) {
// ignore, but filter out
return true;
}
m_lastGlobalTouchPos = pos;
m_lastLocalTouchPos = pos - QPointF(internal->x(), internal->y());
QMouseEvent e(QEvent::MouseMove, m_lastLocalTouchPos, m_lastGlobalTouchPos, Qt::LeftButton, Qt::LeftButton, input()->keyboardModifiers());
QCoreApplication::instance()->sendEvent(internal.data(), &e);
return true;
}
bool touchUp(qint32 id, quint32 time) override {
auto touch = input()->touch();
auto internal = touch->internalWindow();
if (!internal) {
return false;
}
if (touch->internalPressId() == -1) {
return false;
}
waylandServer()->seat()->setTimestamp(time);
if (touch->internalPressId() != qint32(id)) {
// ignore, but filter out
return true;
}
// send mouse up
QMouseEvent e(QEvent::MouseButtonRelease, m_lastLocalTouchPos, m_lastGlobalTouchPos, Qt::LeftButton, Qt::MouseButtons(), input()->keyboardModifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(internal.data(), &e);
QEvent leaveEvent(QEvent::Leave);
QCoreApplication::sendEvent(internal.data(), &leaveEvent);
m_lastGlobalTouchPos = QPointF();
m_lastLocalTouchPos = QPointF();
input()->touch()->setInternalPressId(-1);
return true;
}
private:
QPointF m_lastGlobalTouchPos;
QPointF m_lastLocalTouchPos;
};
class DecorationEventFilter : public InputEventFilter {
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
auto decoration = input()->pointer()->decoration();
if (!decoration) {
return false;
}
const QPointF p = event->globalPos() - decoration->client()->pos();
switch (event->type()) {
case QEvent::MouseMove: {
QHoverEvent e(QEvent::HoverMove, p, p);
QCoreApplication::instance()->sendEvent(decoration->decoration(), &e);
decoration->client()->processDecorationMove(p.toPoint(), event->globalPos());
return true;
}
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease: {
const auto actionResult = performClientMouseAction(event, decoration->client());
if (actionResult.first) {
return actionResult.second;
}
QMouseEvent e(event->type(), p, event->globalPos(), event->button(), event->buttons(), event->modifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(decoration->decoration(), &e);
if (!e.isAccepted() && event->type() == QEvent::MouseButtonPress) {
decoration->client()->processDecorationButtonPress(&e);
}
if (event->type() == QEvent::MouseButtonRelease) {
decoration->client()->processDecorationButtonRelease(&e);
}
return true;
}
default:
break;
}
return false;
}
bool wheelEvent(QWheelEvent *event) override {
auto decoration = input()->pointer()->decoration();
if (!decoration) {
return false;
}
if (event->angleDelta().y() != 0) {
// client window action only on vertical scrolling
const auto actionResult = performClientWheelAction(event, decoration->client());
if (actionResult.first) {
return actionResult.second;
}
}
const QPointF localPos = event->globalPosF() - decoration->client()->pos();
const Qt::Orientation orientation = (event->angleDelta().x() != 0) ? Qt::Horizontal : Qt::Vertical;
const int delta = event->angleDelta().x() != 0 ? event->angleDelta().x() : event->angleDelta().y();
QWheelEvent e(localPos, event->globalPosF(), QPoint(),
event->angleDelta(),
delta,
orientation,
event->buttons(),
event->modifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(decoration.data(), &e);
if (e.isAccepted()) {
return true;
}
if ((orientation == Qt::Vertical) && decoration->client()->titlebarPositionUnderMouse()) {
decoration->client()->performMouseCommand(options->operationTitlebarMouseWheel(delta * -1),
event->globalPosF().toPoint());
}
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
auto seat = waylandServer()->seat();
if (seat->isTouchSequence()) {
return false;
}
if (input()->touch()->decorationPressId() != -1) {
// already on a decoration, ignore further touch points, but filter out
return true;
}
seat->setTimestamp(time);
auto decoration = input()->touch()->decoration();
if (!decoration) {
return false;
}
input()->touch()->setDecorationPressId(id);
m_lastGlobalTouchPos = pos;
m_lastLocalTouchPos = pos - decoration->client()->pos();
QHoverEvent hoverEvent(QEvent::HoverMove, m_lastLocalTouchPos, m_lastLocalTouchPos);
QCoreApplication::sendEvent(decoration->decoration(), &hoverEvent);
QMouseEvent e(QEvent::MouseButtonPress, m_lastLocalTouchPos, pos, Qt::LeftButton, Qt::LeftButton, input()->keyboardModifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(decoration->decoration(), &e);
if (!e.isAccepted()) {
decoration->client()->processDecorationButtonPress(&e);
}
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(time)
auto decoration = input()->touch()->decoration();
if (!decoration) {
return false;
}
if (input()->touch()->decorationPressId() == -1) {
return false;
}
if (input()->touch()->decorationPressId() != qint32(id)) {
// ignore, but filter out
return true;
}
m_lastGlobalTouchPos = pos;
m_lastLocalTouchPos = pos - decoration->client()->pos();
QHoverEvent e(QEvent::HoverMove, m_lastLocalTouchPos, m_lastLocalTouchPos);
QCoreApplication::instance()->sendEvent(decoration->decoration(), &e);
decoration->client()->processDecorationMove(m_lastLocalTouchPos.toPoint(), pos.toPoint());
return true;
}
bool touchUp(qint32 id, quint32 time) override {
Q_UNUSED(time);
auto decoration = input()->touch()->decoration();
if (!decoration) {
return false;
}
if (input()->touch()->decorationPressId() == -1) {
return false;
}
if (input()->touch()->decorationPressId() != qint32(id)) {
// ignore, but filter out
return true;
}
// send mouse up
QMouseEvent e(QEvent::MouseButtonRelease, m_lastLocalTouchPos, m_lastGlobalTouchPos, Qt::LeftButton, Qt::MouseButtons(), input()->keyboardModifiers());
e.setAccepted(false);
QCoreApplication::sendEvent(decoration->decoration(), &e);
decoration->client()->processDecorationButtonRelease(&e);
QHoverEvent leaveEvent(QEvent::HoverLeave, QPointF(), QPointF());
QCoreApplication::sendEvent(decoration->decoration(), &leaveEvent);
m_lastGlobalTouchPos = QPointF();
m_lastLocalTouchPos = QPointF();
input()->touch()->setDecorationPressId(-1);
return true;
}
private:
QPointF m_lastGlobalTouchPos;
QPointF m_lastLocalTouchPos;
};
#ifdef KWIN_BUILD_TABBOX
class TabBoxInputFilter : public InputEventFilter
{
public:
bool pointerEvent(QMouseEvent *event, quint32 button) override {
Q_UNUSED(button)
if (!TabBox::TabBox::self() || !TabBox::TabBox::self()->isGrabbed()) {
return false;
}
return TabBox::TabBox::self()->handleMouseEvent(event);
}
bool keyEvent(QKeyEvent *event) override {
if (!TabBox::TabBox::self() || !TabBox::TabBox::self()->isGrabbed()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setFocusedKeyboardSurface(nullptr);
input()->pointer()->setEnableConstraints(false);
// pass the key event to the seat, so that it has a proper model of the currently hold keys
// this is important for combinations like alt+shift to ensure that shift is not considered pressed
passToWaylandServer(event);
if (event->type() == QEvent::KeyPress) {
TabBox::TabBox::self()->keyPress(event->modifiers() | event->key());
} else if (static_cast(event)->modifiersRelevantForGlobalShortcuts() == Qt::NoModifier) {
TabBox::TabBox::self()->modifiersReleased();
}
return true;
}
bool wheelEvent(QWheelEvent *event) override {
if (!TabBox::TabBox::self() || !TabBox::TabBox::self()->isGrabbed()) {
return false;
}
return TabBox::TabBox::self()->handleWheelEvent(event);
}
};
#endif
class ScreenEdgeInputFilter : public InputEventFilter
{
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
ScreenEdges::self()->isEntered(event);
// always forward
return false;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(time)
// TODO: better check whether a touch sequence is in progress
if (m_touchInProgress || waylandServer()->seat()->isTouchSequence()) {
// cancel existing touch
ScreenEdges::self()->gestureRecognizer()->cancelSwipeGesture();
m_touchInProgress = false;
m_id = 0;
return false;
}
if (ScreenEdges::self()->gestureRecognizer()->startSwipeGesture(pos) > 0) {
m_touchInProgress = true;
m_id = id;
m_lastPos = pos;
return true;
}
return false;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(time)
if (m_touchInProgress && m_id == id) {
ScreenEdges::self()->gestureRecognizer()->updateSwipeGesture(QSizeF(pos.x() - m_lastPos.x(), pos.y() - m_lastPos.y()));
m_lastPos = pos;
return true;
}
return false;
}
bool touchUp(qint32 id, quint32 time) override {
Q_UNUSED(time)
if (m_touchInProgress && m_id == id) {
ScreenEdges::self()->gestureRecognizer()->endSwipeGesture();
m_touchInProgress = false;
return true;
}
return false;
}
private:
bool m_touchInProgress = false;
qint32 m_id = 0;
QPointF m_lastPos;
};
/**
* This filter implements window actions. If the event should not be passed to the
* current pointer window it will filter out the event
*/
class WindowActionInputFilter : public InputEventFilter
{
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
Q_UNUSED(nativeButton)
if (event->type() != QEvent::MouseButtonPress) {
return false;
}
AbstractClient *c = dynamic_cast(input()->pointer()->focus().data());
if (!c) {
return false;
}
const auto actionResult = performClientMouseAction(event, c, MouseAction::ModifierAndWindow);
if (actionResult.first) {
return actionResult.second;
}
return false;
}
bool wheelEvent(QWheelEvent *event) override {
if (event->angleDelta().y() == 0) {
// only actions on vertical scroll
return false;
}
AbstractClient *c = dynamic_cast(input()->pointer()->focus().data());
if (!c) {
return false;
}
const auto actionResult = performClientWheelAction(event, c, MouseAction::ModifierAndWindow);
if (actionResult.first) {
return actionResult.second;
}
return false;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
Q_UNUSED(id)
Q_UNUSED(time)
auto seat = waylandServer()->seat();
if (seat->isTouchSequence()) {
return false;
}
AbstractClient *c = dynamic_cast(input()->touch()->focus().data());
if (!c) {
return false;
}
bool wasAction = false;
const Options::MouseCommand command = c->getMouseCommand(Qt::LeftButton, &wasAction);
if (wasAction) {
return !c->performMouseCommand(command, pos.toPoint());
}
return false;
}
};
/**
* The remaining default input filter which forwards events to other windows
*/
class ForwardInputFilter : public InputEventFilter
{
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
auto seat = waylandServer()->seat();
seat->setTimestamp(event->timestamp());
switch (event->type()) {
case QEvent::MouseMove: {
seat->setPointerPos(event->globalPos());
MouseEvent *e = static_cast(event);
if (e->delta() != QSizeF()) {
seat->relativePointerMotion(e->delta(), e->deltaUnaccelerated(), e->timestampMicroseconds());
}
break;
}
case QEvent::MouseButtonPress:
seat->pointerButtonPressed(nativeButton);
break;
case QEvent::MouseButtonRelease:
seat->pointerButtonReleased(nativeButton);
break;
default:
break;
}
return true;
}
bool wheelEvent(QWheelEvent *event) override {
auto seat = waylandServer()->seat();
seat->setTimestamp(event->timestamp());
auto _event = static_cast(event);
KWayland::Server::PointerAxisSource source;
switch (_event->axisSource()) {
case KWin::InputRedirection::PointerAxisSourceWheel:
source = KWayland::Server::PointerAxisSource::Wheel;
break;
case KWin::InputRedirection::PointerAxisSourceFinger:
source = KWayland::Server::PointerAxisSource::Finger;
break;
case KWin::InputRedirection::PointerAxisSourceContinuous:
source = KWayland::Server::PointerAxisSource::Continuous;
break;
case KWin::InputRedirection::PointerAxisSourceWheelTilt:
source = KWayland::Server::PointerAxisSource::WheelTilt;
break;
case KWin::InputRedirection::PointerAxisSourceUnknown:
default:
source = KWayland::Server::PointerAxisSource::Unknown;
break;
}
seat->pointerAxisV5(_event->orientation(), _event->delta(), _event->discreteDelta(), source);
return true;
}
bool keyEvent(QKeyEvent *event) override {
if (!workspace()) {
return false;
}
if (event->isAutoRepeat()) {
// handled by Wayland client
return false;
}
auto seat = waylandServer()->seat();
input()->keyboard()->update();
seat->setTimestamp(event->timestamp());
passToWaylandServer(event);
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
input()->touch()->insertId(id, seat->touchDown(pos));
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
const qint32 kwaylandId = input()->touch()->mappedId(id);
if (kwaylandId != -1) {
seat->touchMove(kwaylandId, pos);
}
return true;
}
bool touchUp(qint32 id, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
const qint32 kwaylandId = input()->touch()->mappedId(id);
if (kwaylandId != -1) {
seat->touchUp(kwaylandId);
input()->touch()->removeId(id);
}
return true;
}
bool pinchGestureBegin(int fingerCount, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->startPointerPinchGesture(fingerCount);
return true;
}
bool pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->updatePointerPinchGesture(delta, scale, angleDelta);
return true;
}
bool pinchGestureEnd(quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->endPointerPinchGesture();
return true;
}
bool pinchGestureCancelled(quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->cancelPointerPinchGesture();
return true;
}
bool swipeGestureBegin(int fingerCount, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->startPointerSwipeGesture(fingerCount);
return true;
}
bool swipeGestureUpdate(const QSizeF &delta, quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->updatePointerSwipeGesture(delta);
return true;
}
bool swipeGestureEnd(quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->endPointerSwipeGesture();
return true;
}
bool swipeGestureCancelled(quint32 time) override {
if (!workspace()) {
return false;
}
auto seat = waylandServer()->seat();
seat->setTimestamp(time);
seat->cancelPointerSwipeGesture();
return true;
}
};
static KWayland::Server::SeatInterface *findSeat()
{
auto server = waylandServer();
if (!server) {
return nullptr;
}
return server->seat();
}
/**
* Useful when there's no proper tablet support on the clients
*/
class TabletInputFilter : public QObject, public InputEventFilter
{
public:
TabletInputFilter()
{
}
static KWayland::Server::TabletSeatInterface *findTabletSeat()
{
auto server = waylandServer();
if (!server) {
return nullptr;
}
KWayland::Server::TabletManagerInterface *manager = server->tabletManager();
return manager->seat(findSeat());
}
void integrateDevice(LibInput::Device *device)
{
if (device->isTabletTool()) {
KWayland::Server::TabletSeatInterface *tabletSeat = findTabletSeat();
struct udev_device *const udev_device = libinput_device_get_udev_device(device->device());
const char *devnode = udev_device_get_devnode(udev_device);
tabletSeat->addTablet(device->vendor(), device->product(), device->sysName(), device->name(), {QString::fromUtf8(devnode)});
}
}
void removeDevice(const QString &sysname)
{
KWayland::Server::TabletSeatInterface *tabletSeat = findTabletSeat();
tabletSeat->removeTablet(sysname);
}
bool tabletToolEvent(TabletEvent *event) override
{
if (!workspace()) {
return false;
}
KWayland::Server::TabletSeatInterface *tabletSeat = findTabletSeat();
auto tool = tabletSeat->toolByHardwareSerial(event->serialId());
if (!tool) {
using namespace KWayland::Server;
const QVector capabilities = event->capabilities();
const auto f = [](InputRedirection::Capability cap) {
switch (cap) {
case InputRedirection::Tilt:
return TabletToolInterface::Tilt;
case InputRedirection::Pressure:
return TabletToolInterface::Pressure;
case InputRedirection::Distance:
return TabletToolInterface::Distance;
case InputRedirection::Rotation:
return TabletToolInterface::Rotation;
case InputRedirection::Slider:
return TabletToolInterface::Slider;
case InputRedirection::Wheel:
return TabletToolInterface::Wheel;
}
return TabletToolInterface::Wheel;
};
QVector ifaceCapabilities;
ifaceCapabilities.resize(capabilities.size());
std::transform(capabilities.constBegin(), capabilities.constEnd(), ifaceCapabilities.begin(), f);
TabletToolInterface::Type toolType = TabletToolInterface::Type::Pen;
switch (event->toolType()) {
case InputRedirection::Pen:
toolType = TabletToolInterface::Type::Pen;
break;
case InputRedirection::Eraser:
toolType = TabletToolInterface::Type::Eraser;
break;
case InputRedirection::Brush:
toolType = TabletToolInterface::Type::Brush;
break;
case InputRedirection::Pencil:
toolType = TabletToolInterface::Type::Pencil;
break;
case InputRedirection::Airbrush:
toolType = TabletToolInterface::Type::Airbrush;
break;
case InputRedirection::Finger:
toolType = TabletToolInterface::Type::Finger;
break;
case InputRedirection::Mouse:
toolType = TabletToolInterface::Type::Mouse;
break;
case InputRedirection::Lens:
toolType = TabletToolInterface::Type::Lens;
break;
case InputRedirection::Totem:
toolType = TabletToolInterface::Type::Totem;
break;
}
tool = tabletSeat->addTool(toolType, event->serialId(), event->uniqueId(), ifaceCapabilities);
}
KWayland::Server::TabletInterface *tablet = tabletSeat->tabletByName(event->tabletSysName());
Toplevel *toplevel = input()->findToplevel(event->globalPos());
if (!toplevel || !toplevel->surface()) {
return false;
}
KWayland::Server::SurfaceInterface *surface = toplevel->surface();
tool->setCurrentSurface(surface);
if (!tool->isClientSupported() || !tablet->isSurfaceSupported(surface)) {
return emulateTabletEvent(event);
}
switch (event->type()) {
case QEvent::TabletMove: {
const auto pos = event->globalPosF() - toplevel->pos();
tool->sendMotion(pos);
break;
} case QEvent::TabletEnterProximity: {
tool->sendProximityIn(tablet);
break;
} case QEvent::TabletLeaveProximity:
tool->sendProximityOut();
break;
case QEvent::TabletPress:
tool->sendDown();
break;
case QEvent::TabletRelease:
tool->sendUp();
break;
default:
qCWarning(KWIN_CORE) << "Unexpected tablet event type" << event;
break;
}
const quint32 MAX_VAL = 65535;
tool->sendPressure(MAX_VAL * event->pressure());
tool->sendFrame(event->timestamp());
waylandServer()->simulateUserActivity();
return true;
}
bool emulateTabletEvent(TabletEvent *event)
{
if (!workspace()) {
return false;
}
switch (event->type()) {
case QEvent::TabletMove:
case QEvent::TabletEnterProximity:
input()->pointer()->processMotion(event->globalPosF(), event->timestamp());
break;
case QEvent::TabletPress:
input()->pointer()->processButton(KWin::qtMouseButtonToButton(Qt::LeftButton),
InputRedirection::PointerButtonPressed, event->timestamp());
break;
case QEvent::TabletRelease:
input()->pointer()->processButton(KWin::qtMouseButtonToButton(Qt::LeftButton),
InputRedirection::PointerButtonReleased, event->timestamp());
break;
case QEvent::TabletLeaveProximity:
break;
default:
qCWarning(KWIN_CORE) << "Unexpected tablet event type" << event;
break;
}
waylandServer()->simulateUserActivity();
return true;
}
};
class DragAndDropInputFilter : public InputEventFilter
{
public:
bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override {
auto seat = waylandServer()->seat();
if (!seat->isDragPointer()) {
return false;
}
if (seat->isDragTouch()) {
return true;
}
seat->setTimestamp(event->timestamp());
switch (event->type()) {
case QEvent::MouseMove: {
const auto pos = input()->globalPointer();
seat->setPointerPos(pos);
const auto eventPos = event->globalPos();
// TODO: use InputDeviceHandler::at() here and check isClient()?
Toplevel *t = input()->findManagedToplevel(eventPos);
if (auto *xwl = xwayland()) {
const auto ret = xwl->dragMoveFilter(t, eventPos);
if (ret == Xwl::DragEventReply::Ignore) {
return false;
} else if (ret == Xwl::DragEventReply::Take) {
break;
}
}
if (t) {
// TODO: consider decorations
if (t->surface() != seat->dragSurface()) {
if (AbstractClient *c = qobject_cast(t)) {
workspace()->activateClient(c);
}
seat->setDragTarget(t->surface(), t->inputTransformation());
}
} else {
// no window at that place, if we have a surface we need to reset
seat->setDragTarget(nullptr);
}
break;
}
case QEvent::MouseButtonPress:
seat->pointerButtonPressed(nativeButton);
break;
case QEvent::MouseButtonRelease:
seat->pointerButtonReleased(nativeButton);
break;
default:
break;
}
// TODO: should we pass through effects?
return true;
}
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override {
auto seat = waylandServer()->seat();
if (seat->isDragPointer()) {
return true;
}
if (!seat->isDragTouch()) {
return false;
}
if (m_touchId != id) {
return true;
}
seat->setTimestamp(time);
input()->touch()->insertId(id, seat->touchDown(pos));
return true;
}
bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override {
auto seat = waylandServer()->seat();
if (seat->isDragPointer()) {
return true;
}
if (!seat->isDragTouch()) {
return false;
}
if (m_touchId < 0) {
// We take for now the first id appearing as a move after a drag
// started. We can optimize by specifying the id the drag is
// associated with by implementing a key-value getter in KWayland.
m_touchId = id;
}
if (m_touchId != id) {
return true;
}
seat->setTimestamp(time);
const qint32 kwaylandId = input()->touch()->mappedId(id);
if (kwaylandId == -1) {
return true;
}
seat->touchMove(kwaylandId, pos);
if (Toplevel *t = input()->findToplevel(pos.toPoint())) {
// TODO: consider decorations
if (t->surface() != seat->dragSurface()) {
if (AbstractClient *c = qobject_cast(t)) {
workspace()->activateClient(c);
}
seat->setDragTarget(t->surface(), pos, t->inputTransformation());
}
} else {
// no window at that place, if we have a surface we need to reset
seat->setDragTarget(nullptr);
}
return true;
}
bool touchUp(qint32 id, quint32 time) override {
auto seat = waylandServer()->seat();
if (!seat->isDragTouch()) {
return false;
}
seat->setTimestamp(time);
const qint32 kwaylandId = input()->touch()->mappedId(id);
if (kwaylandId != -1) {
seat->touchUp(kwaylandId);
input()->touch()->removeId(id);
}
if (m_touchId == id) {
m_touchId = -1;
}
return true;
}
private:
qint32 m_touchId = -1;
};
KWIN_SINGLETON_FACTORY(InputRedirection)
static const QString s_touchpadComponent = QStringLiteral("kcm_touchpad");
InputRedirection::InputRedirection(QObject *parent)
: QObject(parent)
, m_keyboard(new KeyboardInputRedirection(this))
, m_pointer(new PointerInputRedirection(this))
, m_tablet(new TabletInputRedirection(this))
, m_touch(new TouchInputRedirection(this))
, m_shortcuts(new GlobalShortcutsManager(this))
{
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
if (Application::usesLibinput()) {
if (LogindIntegration::self()->hasSessionControl()) {
setupLibInput();
} else {
LibInput::Connection::createThread();
if (LogindIntegration::self()->isConnected()) {
LogindIntegration::self()->takeControl();
} else {
connect(LogindIntegration::self(), &LogindIntegration::connectedChanged, LogindIntegration::self(), &LogindIntegration::takeControl);
}
connect(LogindIntegration::self(), &LogindIntegration::hasSessionControlChanged, this,
[this] (bool sessionControl) {
if (sessionControl) {
setupLibInput();
}
}
);
}
}
connect(kwinApp(), &Application::workspaceCreated, this, &InputRedirection::setupWorkspace);
reconfigure();
}
InputRedirection::~InputRedirection()
{
s_self = nullptr;
qDeleteAll(m_filters);
qDeleteAll(m_spies);
}
void InputRedirection::installInputEventFilter(InputEventFilter *filter)
{
Q_ASSERT(!m_filters.contains(filter));
m_filters << filter;
}
void InputRedirection::prependInputEventFilter(InputEventFilter *filter)
{
Q_ASSERT(!m_filters.contains(filter));
m_filters.prepend(filter);
}
void InputRedirection::uninstallInputEventFilter(InputEventFilter *filter)
{
m_filters.removeOne(filter);
}
void InputRedirection::installInputEventSpy(InputEventSpy *spy)
{
m_spies << spy;
}
void InputRedirection::uninstallInputEventSpy(InputEventSpy *spy)
{
m_spies.removeOne(spy);
}
void InputRedirection::init()
{
m_shortcuts->init();
}
void InputRedirection::setupWorkspace()
{
if (waylandServer()) {
using namespace KWayland::Server;
FakeInputInterface *fakeInput = waylandServer()->display()->createFakeInput(this);
fakeInput->create();
connect(fakeInput, &FakeInputInterface::deviceCreated, this,
[this] (FakeInputDevice *device) {
connect(device, &FakeInputDevice::authenticationRequested, this,
[device] (const QString &application, const QString &reason) {
Q_UNUSED(application)
Q_UNUSED(reason)
// TODO: make secure
device->setAuthentication(true);
}
);
connect(device, &FakeInputDevice::pointerMotionRequested, this,
[this] (const QSizeF &delta) {
// TODO: Fix time
m_pointer->processMotion(globalPointer() + QPointF(delta.width(), delta.height()), 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::pointerMotionAbsoluteRequested, this,
[this] (const QPointF &pos) {
// TODO: Fix time
m_pointer->processMotion(pos, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::pointerButtonPressRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_pointer->processButton(button, InputRedirection::PointerButtonPressed, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::pointerButtonReleaseRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_pointer->processButton(button, InputRedirection::PointerButtonReleased, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::pointerAxisRequested, this,
[this] (Qt::Orientation orientation, qreal delta) {
// TODO: Fix time
InputRedirection::PointerAxis axis;
switch (orientation) {
case Qt::Horizontal:
axis = InputRedirection::PointerAxisHorizontal;
break;
case Qt::Vertical:
axis = InputRedirection::PointerAxisVertical;
break;
default:
Q_UNREACHABLE();
break;
}
// TODO: Fix time
m_pointer->processAxis(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::touchDownRequested, this,
[this] (qint32 id, const QPointF &pos) {
// TODO: Fix time
m_touch->processDown(id, pos, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::touchMotionRequested, this,
[this] (qint32 id, const QPointF &pos) {
// TODO: Fix time
m_touch->processMotion(id, pos, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::touchUpRequested, this,
[this] (qint32 id) {
// TODO: Fix time
m_touch->processUp(id, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::touchCancelRequested, this,
[this] () {
m_touch->cancel();
}
);
connect(device, &FakeInputDevice::touchFrameRequested, this,
[this] () {
m_touch->frame();
}
);
connect(device, &FakeInputDevice::keyboardKeyPressRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_keyboard->processKey(button, InputRedirection::KeyboardKeyPressed, 0);
waylandServer()->simulateUserActivity();
}
);
connect(device, &FakeInputDevice::keyboardKeyReleaseRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_keyboard->processKey(button, InputRedirection::KeyboardKeyReleased, 0);
waylandServer()->simulateUserActivity();
}
);
}
);
connect(workspace(), &Workspace::configChanged, this, &InputRedirection::reconfigure);
m_keyboard->init();
m_pointer->init();
m_touch->init();
m_tablet->init();
}
setupInputFilters();
}
void InputRedirection::setupInputFilters()
{
const bool hasGlobalShortcutSupport = !waylandServer() || waylandServer()->hasGlobalShortcutSupport();
if (LogindIntegration::self()->hasSessionControl() && hasGlobalShortcutSupport) {
installInputEventFilter(new VirtualTerminalFilter);
}
if (waylandServer()) {
installInputEventSpy(new TouchHideCursorSpy);
if (hasGlobalShortcutSupport) {
installInputEventFilter(new TerminateServerFilter);
}
installInputEventFilter(new DragAndDropInputFilter);
installInputEventFilter(new LockScreenFilter);
installInputEventFilter(new PopupInputFilter);
m_windowSelector = new WindowSelectorFilter;
installInputEventFilter(m_windowSelector);
}
if (hasGlobalShortcutSupport) {
installInputEventFilter(new ScreenEdgeInputFilter);
}
installInputEventFilter(new EffectsFilter);
installInputEventFilter(new MoveResizeFilter);
#ifdef KWIN_BUILD_TABBOX
installInputEventFilter(new TabBoxInputFilter);
#endif
if (hasGlobalShortcutSupport) {
installInputEventFilter(new GlobalShortcutFilter);
}
installInputEventFilter(new DecorationEventFilter);
installInputEventFilter(new InternalWindowEventFilter);
if (waylandServer()) {
installInputEventFilter(new WindowActionInputFilter);
installInputEventFilter(new ForwardInputFilter);
if (m_libInput) {
m_tabletSupport = new TabletInputFilter;
for (LibInput::Device *dev : m_libInput->devices()) {
m_tabletSupport->integrateDevice(dev);
}
connect(m_libInput, &LibInput::Connection::deviceAdded, m_tabletSupport, &TabletInputFilter::integrateDevice);
connect(m_libInput, &LibInput::Connection::deviceRemovedSysName, m_tabletSupport, &TabletInputFilter::removeDevice);
installInputEventFilter(m_tabletSupport);
}
}
}
void InputRedirection::reconfigure()
{
if (Application::usesLibinput()) {
auto inputConfig = kwinApp()->inputConfig();
inputConfig->reparseConfiguration();
const auto config = inputConfig->group(QStringLiteral("Keyboard"));
const int delay = config.readEntry("RepeatDelay", 660);
const int rate = config.readEntry("RepeatRate", 25);
const bool enabled = config.readEntry("KeyboardRepeating", 0) == 0;
waylandServer()->seat()->setKeyRepeatInfo(enabled ? rate : 0, delay);
}
}
void InputRedirection::setupLibInput()
{
if (!Application::usesLibinput()) {
return;
}
if (m_libInput) {
return;
}
LibInput::Connection *conn = LibInput::Connection::create(this);
m_libInput = conn;
if (conn) {
if (waylandServer()) {
// create relative pointer manager
waylandServer()->display()->createRelativePointerManager(KWayland::Server::RelativePointerInterfaceVersion::UnstableV1, waylandServer()->display())->create();
}
conn->setInputConfig(kwinApp()->inputConfig());
conn->updateLEDs(m_keyboard->xkb()->leds());
waylandServer()->updateKeyState(m_keyboard->xkb()->leds());
connect(m_keyboard, &KeyboardInputRedirection::ledsChanged, waylandServer(), &WaylandServer::updateKeyState);
connect(m_keyboard, &KeyboardInputRedirection::ledsChanged, conn, &LibInput::Connection::updateLEDs);
connect(conn, &LibInput::Connection::eventsRead, this,
[this] {
m_libInput->processEvents();
}, Qt::QueuedConnection
);
conn->setup();
connect(conn, &LibInput::Connection::pointerButtonChanged, m_pointer, &PointerInputRedirection::processButton);
connect(conn, &LibInput::Connection::pointerAxisChanged, m_pointer, &PointerInputRedirection::processAxis);
connect(conn, &LibInput::Connection::pinchGestureBegin, m_pointer, &PointerInputRedirection::processPinchGestureBegin);
connect(conn, &LibInput::Connection::pinchGestureUpdate, m_pointer, &PointerInputRedirection::processPinchGestureUpdate);
connect(conn, &LibInput::Connection::pinchGestureEnd, m_pointer, &PointerInputRedirection::processPinchGestureEnd);
connect(conn, &LibInput::Connection::pinchGestureCancelled, m_pointer, &PointerInputRedirection::processPinchGestureCancelled);
connect(conn, &LibInput::Connection::swipeGestureBegin, m_pointer, &PointerInputRedirection::processSwipeGestureBegin);
connect(conn, &LibInput::Connection::swipeGestureUpdate, m_pointer, &PointerInputRedirection::processSwipeGestureUpdate);
connect(conn, &LibInput::Connection::swipeGestureEnd, m_pointer, &PointerInputRedirection::processSwipeGestureEnd);
connect(conn, &LibInput::Connection::swipeGestureCancelled, m_pointer, &PointerInputRedirection::processSwipeGestureCancelled);
connect(conn, &LibInput::Connection::keyChanged, m_keyboard, &KeyboardInputRedirection::processKey);
connect(conn, &LibInput::Connection::pointerMotion, this,
[this] (const QSizeF &delta, const QSizeF &deltaNonAccel, uint32_t time, quint64 timeMicroseconds, LibInput::Device *device) {
m_pointer->processMotion(m_pointer->pos() + QPointF(delta.width(), delta.height()), delta, deltaNonAccel, time, timeMicroseconds, device);
}
);
connect(conn, &LibInput::Connection::pointerMotionAbsolute, this,
[this] (QPointF orig, QPointF screen, uint32_t time, LibInput::Device *device) {
Q_UNUSED(orig)
m_pointer->processMotion(screen, time, device);
}
);
connect(conn, &LibInput::Connection::touchDown, m_touch, &TouchInputRedirection::processDown);
connect(conn, &LibInput::Connection::touchUp, m_touch, &TouchInputRedirection::processUp);
connect(conn, &LibInput::Connection::touchMotion, m_touch, &TouchInputRedirection::processMotion);
connect(conn, &LibInput::Connection::touchCanceled, m_touch, &TouchInputRedirection::cancel);
connect(conn, &LibInput::Connection::touchFrame, m_touch, &TouchInputRedirection::frame);
auto handleSwitchEvent = [this] (SwitchEvent::State state, quint32 time, quint64 timeMicroseconds, LibInput::Device *device) {
SwitchEvent event(state, time, timeMicroseconds, device);
processSpies(std::bind(&InputEventSpy::switchEvent, std::placeholders::_1, &event));
processFilters(std::bind(&InputEventFilter::switchEvent, std::placeholders::_1, &event));
};
connect(conn, &LibInput::Connection::switchToggledOn, this,
std::bind(handleSwitchEvent, SwitchEvent::State::On, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
connect(conn, &LibInput::Connection::switchToggledOff, this,
std::bind(handleSwitchEvent, SwitchEvent::State::Off, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
connect(conn, &LibInput::Connection::tabletToolEvent,
m_tablet, &TabletInputRedirection::tabletToolEvent);
connect(conn, &LibInput::Connection::tabletToolButtonEvent,
m_tablet, &TabletInputRedirection::tabletToolButtonEvent);
connect(conn, &LibInput::Connection::tabletPadButtonEvent,
m_tablet, &TabletInputRedirection::tabletPadButtonEvent);
connect(conn, &LibInput::Connection::tabletPadRingEvent,
m_tablet, &TabletInputRedirection::tabletPadRingEvent);
connect(conn, &LibInput::Connection::tabletPadStripEvent,
m_tablet, &TabletInputRedirection::tabletPadStripEvent);
if (screens()) {
setupLibInputWithScreens();
} else {
connect(kwinApp(), &Application::screensCreated, this, &InputRedirection::setupLibInputWithScreens);
}
if (auto s = findSeat()) {
// Workaround for QTBUG-54371: if there is no real keyboard Qt doesn't request virtual keyboard
s->setHasKeyboard(true);
s->setHasPointer(conn->hasPointer());
s->setHasTouch(conn->hasTouch());
connect(conn, &LibInput::Connection::hasAlphaNumericKeyboardChanged, this,
[this] (bool set) {
if (m_libInput->isSuspended()) {
return;
}
// TODO: this should update the seat, only workaround for QTBUG-54371
emit hasAlphaNumericKeyboardChanged(set);
}
);
connect(conn, &LibInput::Connection::hasTabletModeSwitchChanged, this,
[this] (bool set) {
if (m_libInput->isSuspended()) {
return;
}
emit hasTabletModeSwitchChanged(set);
}
);
connect(conn, &LibInput::Connection::hasPointerChanged, this,
[this, s] (bool set) {
if (m_libInput->isSuspended()) {
return;
}
s->setHasPointer(set);
}
);
connect(conn, &LibInput::Connection::hasTouchChanged, this,
[this, s] (bool set) {
if (m_libInput->isSuspended()) {
return;
}
s->setHasTouch(set);
}
);
}
connect(LogindIntegration::self(), &LogindIntegration::sessionActiveChanged, m_libInput,
[this] (bool active) {
if (!active) {
m_libInput->deactivate();
}
}
);
}
setupTouchpadShortcuts();
}
void InputRedirection::setupTouchpadShortcuts()
{
if (!m_libInput) {
return;
}
QAction *touchpadToggleAction = new QAction(this);
QAction *touchpadOnAction = new QAction(this);
QAction *touchpadOffAction = new QAction(this);
touchpadToggleAction->setObjectName(QStringLiteral("Toggle Touchpad"));
touchpadToggleAction->setProperty("componentName", s_touchpadComponent);
touchpadOnAction->setObjectName(QStringLiteral("Enable Touchpad"));
touchpadOnAction->setProperty("componentName", s_touchpadComponent);
touchpadOffAction->setObjectName(QStringLiteral("Disable Touchpad"));
touchpadOffAction->setProperty("componentName", s_touchpadComponent);
KGlobalAccel::self()->setDefaultShortcut(touchpadToggleAction, QList{Qt::Key_TouchpadToggle});
KGlobalAccel::self()->setShortcut(touchpadToggleAction, QList{Qt::Key_TouchpadToggle});
KGlobalAccel::self()->setDefaultShortcut(touchpadOnAction, QList{Qt::Key_TouchpadOn});
KGlobalAccel::self()->setShortcut(touchpadOnAction, QList{Qt::Key_TouchpadOn});
KGlobalAccel::self()->setDefaultShortcut(touchpadOffAction, QList{Qt::Key_TouchpadOff});
KGlobalAccel::self()->setShortcut(touchpadOffAction, QList{Qt::Key_TouchpadOff});
#ifndef KWIN_BUILD_TESTING
registerShortcut(Qt::Key_TouchpadToggle, touchpadToggleAction);
registerShortcut(Qt::Key_TouchpadOn, touchpadOnAction);
registerShortcut(Qt::Key_TouchpadOff, touchpadOffAction);
#endif
connect(touchpadToggleAction, &QAction::triggered, m_libInput, &LibInput::Connection::toggleTouchpads);
connect(touchpadOnAction, &QAction::triggered, m_libInput, &LibInput::Connection::enableTouchpads);
connect(touchpadOffAction, &QAction::triggered, m_libInput, &LibInput::Connection::disableTouchpads);
}
bool InputRedirection::hasAlphaNumericKeyboard()
{
if (m_libInput) {
return m_libInput->hasAlphaNumericKeyboard();
}
return true;
}
bool InputRedirection::hasTabletModeSwitch()
{
if (m_libInput) {
return m_libInput->hasTabletModeSwitch();
}
return false;
}
void InputRedirection::setupLibInputWithScreens()
{
if (!screens() || !m_libInput) {
return;
}
m_libInput->setScreenSize(screens()->size());
m_libInput->updateScreens();
connect(screens(), &Screens::sizeChanged, this,
[this] {
m_libInput->setScreenSize(screens()->size());
}
);
connect(screens(), &Screens::changed, m_libInput, &LibInput::Connection::updateScreens);
}
void InputRedirection::processPointerMotion(const QPointF &pos, uint32_t time)
{
m_pointer->processMotion(pos, time);
}
void InputRedirection::processPointerButton(uint32_t button, InputRedirection::PointerButtonState state, uint32_t time)
{
m_pointer->processButton(button, state, time);
}
void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, PointerAxisSource source, uint32_t time)
{
m_pointer->processAxis(axis, delta, discreteDelta, source, time);
}
void InputRedirection::processKeyboardKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time)
{
m_keyboard->processKey(key, state, time);
}
void InputRedirection::processKeyboardModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
{
m_keyboard->processModifiers(modsDepressed, modsLatched, modsLocked, group);
}
void InputRedirection::processKeymapChange(int fd, uint32_t size)
{
m_keyboard->processKeymapChange(fd, size);
}
void InputRedirection::processTouchDown(qint32 id, const QPointF &pos, quint32 time)
{
m_touch->processDown(id, pos, time);
}
void InputRedirection::processTouchUp(qint32 id, quint32 time)
{
m_touch->processUp(id, time);
}
void InputRedirection::processTouchMotion(qint32 id, const QPointF &pos, quint32 time)
{
m_touch->processMotion(id, pos, time);
}
void InputRedirection::cancelTouch()
{
m_touch->cancel();
}
void InputRedirection::touchFrame()
{
m_touch->frame();
}
Qt::MouseButtons InputRedirection::qtButtonStates() const
{
return m_pointer->buttons();
}
static bool acceptsInput(Toplevel *t, const QPoint &pos)
{
const QRegion input = t->inputShape();
if (input.isEmpty()) {
return true;
}
// TODO: What about sub-surfaces sticking outside the main surface?
const QPoint localPoint = pos - t->bufferGeometry().topLeft();
return input.contains(localPoint);
}
Toplevel *InputRedirection::findToplevel(const QPoint &pos)
{
if (!Workspace::self()) {
return nullptr;
}
const bool isScreenLocked = waylandServer() && waylandServer()->isScreenLocked();
// TODO: check whether the unmanaged wants input events at all
if (!isScreenLocked) {
// if an effect overrides the cursor we don't have a window to focus
if (effects && static_cast(effects)->isMouseInterception()) {
return nullptr;
}
const QList &unmanaged = Workspace::self()->unmanagedList();
foreach (Unmanaged *u, unmanaged) {
if (u->inputGeometry().contains(pos) && acceptsInput(u, pos)) {
return u;
}
}
}
return findManagedToplevel(pos);
}
Toplevel *InputRedirection::findManagedToplevel(const QPoint &pos)
{
if (!Workspace::self()) {
return nullptr;
}
const bool isScreenLocked = waylandServer() && waylandServer()->isScreenLocked();
const QList &stacking = Workspace::self()->stackingOrder();
if (stacking.isEmpty()) {
return nullptr;
}
auto it = stacking.end();
do {
--it;
Toplevel *t = (*it);
if (t->isDeleted()) {
// a deleted window doesn't get mouse events
continue;
}
if (AbstractClient *c = dynamic_cast(t)) {
if (!c->isOnCurrentActivity() || !c->isOnCurrentDesktop() || c->isMinimized() || c->isHiddenInternal()) {
continue;
}
}
if (!t->readyForPainting()) {
continue;
}
if (isScreenLocked) {
if (!t->isLockScreen() && !t->isInputMethod()) {
continue;
}
}
if (t->inputGeometry().contains(pos) && acceptsInput(t, pos)) {
return t;
}
} while (it != stacking.begin());
return nullptr;
}
Qt::KeyboardModifiers InputRedirection::keyboardModifiers() const
{
return m_keyboard->modifiers();
}
Qt::KeyboardModifiers InputRedirection::modifiersRelevantForGlobalShortcuts() const
{
return m_keyboard->modifiersRelevantForGlobalShortcuts();
}
void InputRedirection::registerShortcut(const QKeySequence &shortcut, QAction *action)
{
Q_UNUSED(shortcut)
kwinApp()->platform()->setupActionForGlobalAccel(action);
}
void InputRedirection::registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action)
{
m_shortcuts->registerPointerShortcut(action, modifiers, pointerButtons);
}
void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action)
{
m_shortcuts->registerAxisShortcut(action, modifiers, axis);
}
void InputRedirection::registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action)
{
m_shortcuts->registerTouchpadSwipe(action, direction);
}
void InputRedirection::registerGlobalAccel(KGlobalAccelInterface *interface)
{
m_shortcuts->setKGlobalAccelInterface(interface);
}
void InputRedirection::warpPointer(const QPointF &pos)
{
m_pointer->warp(pos);
}
bool InputRedirection::supportsPointerWarping() const
{
return m_pointer->supportsWarping();
}
QPointF InputRedirection::globalPointer() const
{
return m_pointer->pos();
}
void InputRedirection::startInteractiveWindowSelection(std::function callback, const QByteArray &cursorName)
{
if (!m_windowSelector || m_windowSelector->isActive()) {
callback(nullptr);
return;
}
m_windowSelector->start(callback);
m_pointer->setWindowSelectionCursor(cursorName);
}
void InputRedirection::startInteractivePositionSelection(std::function callback)
{
if (!m_windowSelector || m_windowSelector->isActive()) {
callback(QPoint(-1, -1));
return;
}
m_windowSelector->start(callback);
m_pointer->setWindowSelectionCursor(QByteArray());
}
bool InputRedirection::isSelectingWindow() const
{
return m_windowSelector ? m_windowSelector->isActive() : false;
}
InputDeviceHandler::InputDeviceHandler(InputRedirection *input)
: QObject(input)
{
}
InputDeviceHandler::~InputDeviceHandler() = default;
void InputDeviceHandler::init()
{
connect(workspace(), &Workspace::stackingOrderChanged, this, &InputDeviceHandler::update);
connect(workspace(), &Workspace::clientMinimizedChanged, this, &InputDeviceHandler::update);
connect(VirtualDesktopManager::self(), &VirtualDesktopManager::currentChanged, this, &InputDeviceHandler::update);
}
bool InputDeviceHandler::setAt(Toplevel *toplevel)
{
if (m_at.at == toplevel) {
return false;
}
auto old = m_at.at;
disconnect(m_at.surfaceCreatedConnection);
m_at.surfaceCreatedConnection = QMetaObject::Connection();
m_at.at = toplevel;
emit atChanged(old, toplevel);
return true;
}
void InputDeviceHandler::setFocus(Toplevel *toplevel)
{
m_focus.focus = toplevel;
//TODO: call focusUpdate?
}
void InputDeviceHandler::setDecoration(QPointer decoration)
{
auto oldDeco = m_focus.decoration;
m_focus.decoration = decoration;
cleanupDecoration(oldDeco.data(), m_focus.decoration.data());
emit decorationChanged();
}
void InputDeviceHandler::setInternalWindow(QWindow *window)
{
m_focus.internalWindow = window;
//TODO: call internalWindowUpdate?
}
void InputDeviceHandler::updateFocus()
{
auto oldFocus = m_focus.focus;
if (m_at.at && !m_at.at->surface()) {
// The surface has not yet been created (special XWayland case).
// Therefore listen for its creation.
if (!m_at.surfaceCreatedConnection) {
m_at.surfaceCreatedConnection = connect(m_at.at, &Toplevel::surfaceChanged,
this, &InputDeviceHandler::update);
}
m_focus.focus = nullptr;
} else {
m_focus.focus = m_at.at;
}
focusUpdate(oldFocus, m_focus.focus);
}
bool InputDeviceHandler::updateDecoration()
{
const auto oldDeco = m_focus.decoration;
m_focus.decoration = nullptr;
auto *ac = qobject_cast(m_at.at);
if (ac && ac->decoratedClient()) {
const QRect clientRect = QRect(ac->clientPos(), ac->clientSize()).translated(ac->pos());
if (!clientRect.contains(position().toPoint())) {
// input device above decoration
m_focus.decoration = ac->decoratedClient();
}
}
if (m_focus.decoration == oldDeco) {
// no change to decoration
return false;
}
cleanupDecoration(oldDeco.data(), m_focus.decoration.data());
emit decorationChanged();
return true;
}
void InputDeviceHandler::updateInternalWindow(QWindow *window)
{
if (m_focus.internalWindow == window) {
// no change
return;
}
const auto oldInternal = m_focus.internalWindow;
m_focus.internalWindow = window;
cleanupInternalWindow(oldInternal, window);
}
void InputDeviceHandler::update()
{
if (!m_inited) {
return;
}
Toplevel *toplevel = nullptr;
QWindow *internalWindow = nullptr;
if (!positionValid()) {
const auto pos = position().toPoint();
internalWindow = findInternalWindow(pos);
if (internalWindow) {
toplevel = workspace()->findInternal(internalWindow);
} else {
toplevel = input()->findToplevel(pos);
}
}
// Always set the toplevel at the position of the input device.
setAt(toplevel);
if (focusUpdatesBlocked()) {
return;
}
if (internalWindow) {
if (m_focus.internalWindow != internalWindow) {
// changed internal window
updateDecoration();
updateInternalWindow(internalWindow);
updateFocus();
} else if (updateDecoration()) {
// went onto or off from decoration, update focus
updateFocus();
}
return;
}
updateInternalWindow(nullptr);
if (m_focus.focus != m_at.at) {
// focus change
updateDecoration();
updateFocus();
return;
}
// check if switched to/from decoration while staying on the same Toplevel
if (updateDecoration()) {
// went onto or off from decoration, update focus
updateFocus();
}
}
QWindow* InputDeviceHandler::findInternalWindow(const QPoint &pos) const
{
if (waylandServer()->isScreenLocked()) {
return nullptr;
}
const QList &internalClients = workspace()->internalClients();
if (internalClients.isEmpty()) {
return nullptr;
}
auto it = internalClients.end();
do {
--it;
QWindow *w = (*it)->internalWindow();
if (!w || !w->isVisible()) {
continue;
}
if (!(*it)->frameGeometry().contains(pos)) {
continue;
}
// check input mask
const QRegion mask = w->mask().translated(w->geometry().topLeft());
if (!mask.isEmpty() && !mask.contains(pos)) {
continue;
}
if (w->property("outputOnly").toBool()) {
continue;
}
return w;
} while (it != internalClients.begin());
return nullptr;
}
} // namespace
diff --git a/kcmkwin/common/effectsmodel.cpp b/kcmkwin/common/effectsmodel.cpp
index 9584c05b4..60e733b5e 100644
--- a/kcmkwin/common/effectsmodel.cpp
+++ b/kcmkwin/common/effectsmodel.cpp
@@ -1,682 +1,682 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2013 Antonis Tsiapaliokas
Copyright (C) 2018 Vlad Zahorodnii
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 "effectsmodel.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace KWin
{
static QString translatedCategory(const QString &category)
{
static const QVector knownCategories = {
QStringLiteral("Accessibility"),
QStringLiteral("Appearance"),
QStringLiteral("Focus"),
QStringLiteral("Show Desktop Animation"),
QStringLiteral("Tools"),
QStringLiteral("Virtual Desktop Switching Animation"),
QStringLiteral("Window Management"),
QStringLiteral("Window Open/Close Animation")
};
static const QVector translatedCategories = {
i18nc("Category of Desktop Effects, used as section header", "Accessibility"),
i18nc("Category of Desktop Effects, used as section header", "Appearance"),
i18nc("Category of Desktop Effects, used as section header", "Focus"),
i18nc("Category of Desktop Effects, used as section header", "Show Desktop Animation"),
i18nc("Category of Desktop Effects, used as section header", "Tools"),
i18nc("Category of Desktop Effects, used as section header", "Virtual Desktop Switching Animation"),
i18nc("Category of Desktop Effects, used as section header", "Window Management"),
i18nc("Category of Desktop Effects, used as section header", "Window Open/Close Animation")
};
const int index = knownCategories.indexOf(category);
if (index == -1) {
qDebug() << "Unknown category '" << category << "' and thus not translated";
return category;
}
return translatedCategories[index];
}
static EffectsModel::Status effectStatus(bool enabled)
{
return enabled ? EffectsModel::Status::Enabled : EffectsModel::Status::Disabled;
}
EffectsModel::EffectsModel(QObject *parent)
: QAbstractItemModel(parent)
{
}
QHash EffectsModel::roleNames() const
{
QHash roleNames;
roleNames[NameRole] = "NameRole";
roleNames[DescriptionRole] = "DescriptionRole";
roleNames[AuthorNameRole] = "AuthorNameRole";
roleNames[AuthorEmailRole] = "AuthorEmailRole";
roleNames[LicenseRole] = "LicenseRole";
roleNames[VersionRole] = "VersionRole";
roleNames[CategoryRole] = "CategoryRole";
roleNames[ServiceNameRole] = "ServiceNameRole";
roleNames[IconNameRole] = "IconNameRole";
roleNames[StatusRole] = "StatusRole";
roleNames[VideoRole] = "VideoRole";
roleNames[WebsiteRole] = "WebsiteRole";
roleNames[SupportedRole] = "SupportedRole";
roleNames[ExclusiveRole] = "ExclusiveRole";
roleNames[ConfigurableRole] = "ConfigurableRole";
roleNames[ScriptedRole] = QByteArrayLiteral("ScriptedRole");
roleNames[EnabledByDefaultRole] = "EnabledByDefaultRole";
return roleNames;
}
QModelIndex EffectsModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() || column > 0 || column < 0 || row < 0 || row >= m_effects.count()) {
return {};
}
return createIndex(row, column);
}
QModelIndex EffectsModel::parent(const QModelIndex &child) const
{
Q_UNUSED(child)
return {};
}
int EffectsModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 1;
}
int EffectsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_effects.count();
}
QVariant EffectsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return {};
}
const EffectData effect = m_effects.at(index.row());
switch (role) {
case Qt::DisplayRole:
case NameRole:
return effect.name;
case DescriptionRole:
return effect.description;
case AuthorNameRole:
return effect.authorName;
case AuthorEmailRole:
return effect.authorEmail;
case LicenseRole:
return effect.license;
case VersionRole:
return effect.version;
case CategoryRole:
return effect.category;
case ServiceNameRole:
return effect.serviceName;
case IconNameRole:
return effect.iconName;
case StatusRole:
return static_cast(effect.status);
case VideoRole:
return effect.video;
case WebsiteRole:
return effect.website;
case SupportedRole:
return effect.supported;
case ExclusiveRole:
return effect.exclusiveGroup;
case InternalRole:
return effect.internal;
case ConfigurableRole:
return effect.configurable;
case ScriptedRole:
return effect.kind == Kind::Scripted;
case EnabledByDefaultRole:
return effect.enabledByDefault;
default:
return {};
}
}
bool EffectsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid()) {
return QAbstractItemModel::setData(index, value, role);
}
if (role == StatusRole) {
// note: whenever the StatusRole is modified (even to the same value) the entry
// gets marked as changed and will get saved to the config file. This means the
// config file could get polluted
EffectData &data = m_effects[index.row()];
data.status = Status(value.toInt());
data.changed = data.status != data.originalStatus;
emit dataChanged(index, index);
if (data.status == Status::Enabled && !data.exclusiveGroup.isEmpty()) {
// need to disable all other exclusive effects in the same category
for (int i = 0; i < m_effects.size(); ++i) {
if (i == index.row()) {
continue;
}
EffectData &otherData = m_effects[i];
if (otherData.exclusiveGroup == data.exclusiveGroup) {
otherData.status = Status::Disabled;
otherData.changed = otherData.status != otherData.originalStatus;
emit dataChanged(this->index(i, 0), this->index(i, 0));
}
}
}
return true;
}
return QAbstractItemModel::setData(index, value, role);
}
void EffectsModel::loadBuiltInEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs)
{
const auto builtins = BuiltInEffects::availableEffects();
for (auto builtin : builtins) {
const BuiltInEffects::EffectData &data = BuiltInEffects::effectData(builtin);
EffectData effect;
effect.name = data.displayName;
effect.description = data.comment;
effect.authorName = i18n("KWin development team");
effect.authorEmail = QString(); // not used at all
effect.license = QStringLiteral("GPL");
effect.version = QStringLiteral(KWIN_VERSION_STRING);
effect.untranslatedCategory = data.category;
effect.category = translatedCategory(data.category);
effect.serviceName = data.name;
effect.iconName = QStringLiteral("preferences-system-windows");
effect.enabledByDefault = data.enabled;
effect.enabledByDefaultFunction = (data.enabledFunction != nullptr);
const QString enabledKey = QStringLiteral("%1Enabled").arg(effect.serviceName);
if (kwinConfig.hasKey(enabledKey)) {
effect.status = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", effect.enabledByDefault));
} else if (data.enabledFunction != nullptr) {
effect.status = Status::EnabledUndeterminded;
} else {
effect.status = effectStatus(effect.enabledByDefault);
}
effect.originalStatus = effect.status;
effect.video = data.video;
effect.website = QUrl();
effect.supported = true;
effect.exclusiveGroup = data.exclusiveCategory;
effect.internal = data.internal;
effect.kind = Kind::BuiltIn;
effect.configurable = std::any_of(configs.constBegin(), configs.constEnd(),
[data](const KPluginInfo &info) {
return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == data.name;
}
);
if (shouldStore(effect)) {
m_pendingEffects << effect;
}
}
}
void EffectsModel::loadJavascriptEffects(const KConfigGroup &kwinConfig)
{
const auto plugins = KPackage::PackageLoader::self()->listPackages(
QStringLiteral("KWin/Effect"),
QStringLiteral("kwin/effects")
);
for (const KPluginMetaData &metaData : plugins) {
KPluginInfo plugin(metaData);
EffectData effect;
effect.name = plugin.name();
effect.description = plugin.comment();
effect.authorName = plugin.author();
effect.authorEmail = plugin.email();
effect.license = plugin.license();
effect.version = plugin.version();
effect.untranslatedCategory = plugin.category();
effect.category = translatedCategory(plugin.category());
effect.serviceName = plugin.pluginName();
effect.iconName = plugin.icon();
effect.status = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", plugin.isPluginEnabledByDefault()));
effect.originalStatus = effect.status;
effect.enabledByDefault = plugin.isPluginEnabledByDefault();
effect.enabledByDefaultFunction = false;
effect.video = plugin.property(QStringLiteral("X-KWin-Video-Url")).toUrl();
effect.website = QUrl(plugin.website());
effect.supported = true;
effect.exclusiveGroup = plugin.property(QStringLiteral("X-KWin-Exclusive-Category")).toString();
effect.internal = plugin.property(QStringLiteral("X-KWin-Internal")).toBool();
effect.kind = Kind::Scripted;
const QString pluginKeyword = plugin.property(QStringLiteral("X-KDE-PluginKeyword")).toString();
if (!pluginKeyword.isEmpty()) {
// scripted effects have their pluginName() as the keyword
effect.configurable = plugin.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginKeyword;
} else {
effect.configurable = false;
}
if (shouldStore(effect)) {
m_pendingEffects << effect;
}
}
}
void EffectsModel::loadPluginEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs)
{
const auto pluginEffects = KPluginLoader::findPlugins(
QStringLiteral("kwin/effects/plugins/"),
[](const KPluginMetaData &data) {
return data.serviceTypes().contains(QStringLiteral("KWin/Effect"));
}
);
for (const KPluginMetaData &pluginEffect : pluginEffects) {
if (!pluginEffect.isValid()) {
continue;
}
EffectData effect;
effect.name = pluginEffect.name();
effect.description = pluginEffect.description();
effect.license = pluginEffect.license();
effect.version = pluginEffect.version();
effect.untranslatedCategory = pluginEffect.category();
effect.category = translatedCategory(pluginEffect.category());
effect.serviceName = pluginEffect.pluginId();
effect.iconName = pluginEffect.iconName();
effect.enabledByDefault = pluginEffect.isEnabledByDefault();
effect.supported = true;
effect.enabledByDefaultFunction = false;
effect.internal = false;
effect.kind = Kind::Binary;
for (int i = 0; i < pluginEffect.authors().count(); ++i) {
effect.authorName.append(pluginEffect.authors().at(i).name());
effect.authorEmail.append(pluginEffect.authors().at(i).emailAddress());
if (i+1 < pluginEffect.authors().count()) {
effect.authorName.append(", ");
effect.authorEmail.append(", ");
}
}
if (pluginEffect.rawData().contains("org.kde.kwin.effect")) {
const QJsonObject d(pluginEffect.rawData().value("org.kde.kwin.effect").toObject());
effect.exclusiveGroup = d.value("exclusiveGroup").toString();
effect.video = QUrl::fromUserInput(d.value("video").toString());
effect.enabledByDefaultFunction = d.value("enabledByDefaultMethod").toBool();
}
effect.website = QUrl(pluginEffect.website());
const QString enabledKey = QStringLiteral("%1Enabled").arg(effect.serviceName);
if (kwinConfig.hasKey(enabledKey)) {
effect.status = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", effect.enabledByDefault));
} else if (effect.enabledByDefaultFunction) {
effect.status = Status::EnabledUndeterminded;
} else {
effect.status = effectStatus(effect.enabledByDefault);
}
effect.originalStatus = effect.status;
effect.configurable = std::any_of(configs.constBegin(), configs.constEnd(),
[pluginEffect](const KPluginInfo &info) {
return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginEffect.pluginId();
}
);
if (shouldStore(effect)) {
m_pendingEffects << effect;
}
}
}
void EffectsModel::load(LoadOptions options)
{
KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins");
m_pendingEffects.clear();
const KPluginInfo::List configs = KPluginTrader::self()->query(QStringLiteral("kwin/effects/configs/"));
loadBuiltInEffects(kwinConfig, configs);
loadJavascriptEffects(kwinConfig);
loadPluginEffects(kwinConfig, configs);
std::sort(m_pendingEffects.begin(), m_pendingEffects.end(),
[](const EffectData &a, const EffectData &b) {
if (a.category == b.category) {
if (a.exclusiveGroup == b.exclusiveGroup) {
return a.name < b.name;
}
return a.exclusiveGroup < b.exclusiveGroup;
}
return a.category < b.category;
}
);
auto commit = [this, options] {
if (options == LoadOptions::KeepDirty) {
for (const EffectData &oldEffect : m_effects) {
if (!oldEffect.changed) {
continue;
}
auto effectIt = std::find_if(m_pendingEffects.begin(), m_pendingEffects.end(),
[oldEffect](const EffectData &data) {
return data.serviceName == oldEffect.serviceName;
}
);
if (effectIt == m_pendingEffects.end()) {
continue;
}
effectIt->status = oldEffect.status;
effectIt->changed = effectIt->status != effectIt->originalStatus;
}
}
beginResetModel();
m_effects = m_pendingEffects;
m_pendingEffects.clear();
endResetModel();
emit loaded();
};
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/Effects"),
QDBusConnection::sessionBus());
if (interface.isValid()) {
QStringList effectNames;
effectNames.reserve(m_pendingEffects.count());
for (const EffectData &data : m_pendingEffects) {
effectNames.append(data.serviceName);
}
const int serial = ++m_lastSerial;
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(interface.areEffectsSupported(effectNames), this);
connect(watcher, &QDBusPendingCallWatcher::finished, this,
[=](QDBusPendingCallWatcher *self) {
self->deleteLater();
if (m_lastSerial != serial) {
return;
}
const QDBusPendingReply > reply = *self;
if (reply.isError()) {
commit();
return;
}
const QList supportedValues = reply.value();
if (supportedValues.count() != effectNames.count()) {
return;
}
for (int i = 0; i < effectNames.size(); ++i) {
const bool supported = supportedValues.at(i);
const QString effectName = effectNames.at(i);
auto it = std::find_if(m_pendingEffects.begin(), m_pendingEffects.end(),
[effectName](const EffectData &data) {
return data.serviceName == effectName;
}
);
if (it == m_pendingEffects.end()) {
continue;
}
if ((*it).supported != supported) {
(*it).supported = supported;
}
}
commit();
}
);
} else {
commit();
}
}
void EffectsModel::updateEffectStatus(const QModelIndex &rowIndex, Status effectState)
{
setData(rowIndex, static_cast(effectState), StatusRole);
}
void EffectsModel::save()
{
KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins");
QVector dirtyEffects;
for (EffectData &effect : m_effects) {
if (!effect.changed) {
continue;
}
effect.changed = false;
effect.originalStatus = effect.status;
const QString key = effect.serviceName + QStringLiteral("Enabled");
const bool shouldEnable = (effect.status != Status::Disabled);
const bool restoreToDefault = effect.enabledByDefaultFunction
? effect.status == Status::EnabledUndeterminded
: shouldEnable == effect.enabledByDefault;
if (restoreToDefault) {
kwinConfig.deleteEntry(key);
} else {
kwinConfig.writeEntry(key, shouldEnable);
}
dirtyEffects.append(effect);
}
if (dirtyEffects.isEmpty()) {
return;
}
kwinConfig.sync();
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/Effects"),
QDBusConnection::sessionBus());
if (!interface.isValid()) {
return;
}
for (const EffectData &effect : dirtyEffects) {
if (effect.status != Status::Disabled) {
interface.loadEffect(effect.serviceName);
} else {
interface.unloadEffect(effect.serviceName);
}
}
}
void EffectsModel::defaults()
{
for (int i = 0; i < m_effects.count(); ++i) {
const auto &effect = m_effects.at(i);
if (effect.enabledByDefaultFunction && effect.status != Status::EnabledUndeterminded) {
updateEffectStatus(index(i, 0), Status::EnabledUndeterminded);
} else if (static_cast(effect.status) != effect.enabledByDefault) {
updateEffectStatus(index(i, 0), effect.enabledByDefault ? Status::Enabled : Status::Disabled);
}
}
}
bool EffectsModel::isDefaults() const
{
return std::all_of(m_effects.constBegin(), m_effects.constEnd(), [](const EffectData &effect) {
if (effect.enabledByDefaultFunction && effect.status != Status::EnabledUndeterminded) {
return false;
}
if (static_cast(effect.status) != effect.enabledByDefault) {
return false;
}
return true;
});
}
bool EffectsModel::needsSave() const
{
return std::any_of(m_effects.constBegin(), m_effects.constEnd(),
[](const EffectData &data) {
return data.changed;
}
);
}
QModelIndex EffectsModel::findByPluginId(const QString &pluginId) const
{
auto it = std::find_if(m_effects.constBegin(), m_effects.constEnd(),
[pluginId](const EffectData &data) {
return data.serviceName == pluginId;
}
);
if (it == m_effects.constEnd()) {
return {};
}
return index(std::distance(m_effects.constBegin(), it), 0);
}
static KCModule *findBinaryConfig(const QString &pluginId, QObject *parent)
{
return KPluginTrader::createInstanceFromQuery(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(pluginId),
parent
);
}
static KCModule *findScriptedConfig(const QString &pluginId, QObject *parent)
{
const auto offers = KPluginTrader::self()->query(
QStringLiteral("kwin/effects/configs/"),
QString(),
QStringLiteral("[X-KDE-Library] == 'kcm_kwin4_genericscripted'")
);
if (offers.isEmpty()) {
return nullptr;
}
const KPluginInfo &generic = offers.first();
KPluginLoader loader(generic.libraryPath());
KPluginFactory *factory = loader.factory();
if (!factory) {
return nullptr;
}
return factory->create(pluginId, parent);
}
void EffectsModel::requestConfigure(const QModelIndex &index, QWindow *transientParent)
{
if (!index.isValid()) {
return;
}
- QPointer dialog = new QDialog();
+ auto dialog = new QDialog();
KCModule *module = index.data(ScriptedRole).toBool()
? findScriptedConfig(index.data(ServiceNameRole).toString(), dialog)
: findBinaryConfig(index.data(ServiceNameRole).toString(), dialog);
if (!module) {
delete dialog;
return;
}
dialog->setWindowTitle(index.data(NameRole).toString());
dialog->winId();
dialog->windowHandle()->setTransientParent(transientParent);
auto buttons = new QDialogButtonBox(
QDialogButtonBox::Ok |
QDialogButtonBox::Cancel |
QDialogButtonBox::RestoreDefaults,
dialog
);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
connect(buttons->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
module, &KCModule::defaults);
connect(module, &KCModule::defaulted, this, [=](bool defaulted) {
buttons->button(QDialogButtonBox::RestoreDefaults)->setEnabled(!defaulted);
});
auto layout = new QVBoxLayout(dialog);
layout->addWidget(module);
layout->addWidget(buttons);
- if (dialog->exec() == QDialog::Accepted) {
- module->save();
- }
+ connect(dialog, &QDialog::accepted, module, &KCModule::save);
- delete dialog;
+ dialog->setModal(true);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->show();
}
bool EffectsModel::shouldStore(const EffectData &data) const
{
Q_UNUSED(data)
return true;
}
}
diff --git a/kcmkwin/kwincompositing/CMakeLists.txt b/kcmkwin/kwincompositing/CMakeLists.txt
index d759e202b..eb8c47d5a 100644
--- a/kcmkwin/kwincompositing/CMakeLists.txt
+++ b/kcmkwin/kwincompositing/CMakeLists.txt
@@ -1,35 +1,37 @@
#########################################################################
# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcmkwincompositing\")
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
remove_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_STRICT_ITERATORS -DQT_NO_CAST_FROM_BYTEARRAY)
################# configure checks and create the configured files #################
-set(kwincomposing_SRC
+set(kwincompositing_SRC
main.cpp
compositing.cpp
)
-qt5_add_dbus_interface(kwincomposing_SRC
+kconfig_add_kcfg_files(kwincompositing_SRC kwincompositing_setting.kcfgc GENERATE_MOC)
+
+qt5_add_dbus_interface(kwincompositing_SRC
${KWin_SOURCE_DIR}/org.kde.kwin.Compositing.xml kwin_compositing_interface
)
-ki18n_wrap_ui(kwincomposing_SRC compositing.ui)
+ki18n_wrap_ui(kwincompositing_SRC compositing.ui)
-add_library(kwincompositing MODULE ${kwincomposing_SRC})
+add_library(kwincompositing MODULE ${kwincompositing_SRC})
target_link_libraries(kwincompositing
Qt5::DBus
Qt5::Widgets
KF5::ConfigCore
KF5::CoreAddons
KF5::I18n
KF5::KCMUtils
)
install(TARGETS kwincompositing DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES kwincompositing.desktop DESTINATION ${SERVICES_INSTALL_DIR})
diff --git a/kcmkwin/kwincompositing/compositing.cpp b/kcmkwin/kwincompositing/compositing.cpp
index b43f7cea2..e7042984d 100644
--- a/kcmkwin/kwincompositing/compositing.cpp
+++ b/kcmkwin/kwincompositing/compositing.cpp
@@ -1,546 +1,514 @@
/**************************************************************************
* KWin - the KDE window manager *
* This file is part of the KDE project. *
* *
* Copyright (C) 2013 Antonis Tsiapaliokas *
* Copyright (C) 2013 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 "compositing.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#include "kwincompositing_setting.h"
+
namespace KWin {
namespace Compositing {
Compositing::Compositing(QObject *parent)
: QObject(parent)
, m_animationSpeed(1.0)
, m_windowThumbnail(0)
, m_glScaleFilter(0)
, m_xrScaleFilter(false)
, m_glSwapStrategy(0)
, m_compositingType(0)
, m_compositingEnabled(true)
- , m_changed(false)
, m_openGLPlatformInterfaceModel(new OpenGLPlatformInterfaceModel(this))
, m_openGLPlatformInterface(0)
, m_windowsBlockCompositing(true)
, m_compositingInterface(new OrgKdeKwinCompositingInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Compositor"), QDBusConnection::sessionBus(), this))
- , m_config(KSharedConfig::openConfig("kwinrc"))
-{
- reset();
- connect(this, &Compositing::animationSpeedChanged, this, &Compositing::changed);
- connect(this, &Compositing::windowThumbnailChanged, this, &Compositing::changed);
- connect(this, &Compositing::glScaleFilterChanged, this, &Compositing::changed);
- connect(this, &Compositing::xrScaleFilterChanged, this, &Compositing::changed);
- connect(this, &Compositing::glSwapStrategyChanged, this, &Compositing::changed);
- connect(this, &Compositing::compositingTypeChanged, this, &Compositing::changed);
- connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::changed);
- connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::changed);
- connect(this, &Compositing::windowsBlockCompositingChanged, this, &Compositing::changed);
-
- connect(this, &Compositing::changed, [this]{
- m_changed = true;
- });
+ , m_settings(new KWinCompositingSetting(this))
+{
+ load();
+ connect(this, &Compositing::animationSpeedChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::windowThumbnailChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::glScaleFilterChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::xrScaleFilterChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::glSwapStrategyChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::compositingTypeChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::updateSettings);
+ connect(this, &Compositing::windowsBlockCompositingChanged, this, &Compositing::updateSettings);
}
-void Compositing::reset()
+void Compositing::load()
{
- KConfigGroup globalConfig(m_config, QStringLiteral("KDE"));
- setAnimationSpeed(globalConfig.readEntry("AnimationDurationFactor", 1.0));
+ m_settings->load();
- KConfigGroup kwinConfig(m_config, QStringLiteral("Compositing"));
- setWindowThumbnail(kwinConfig.readEntry("HiddenPreviews", 5) - 4);
- setGlScaleFilter(kwinConfig.readEntry("GLTextureFilter", 2));
- setXrScaleFilter(kwinConfig.readEntry("XRenderSmoothScale", false));
- setCompositingEnabled(kwinConfig.readEntry("Enabled", true));
+ applyValues();
- auto swapStrategy = [&kwinConfig]() {
- const QString glSwapStrategyValue = kwinConfig.readEntry("GLPreferBufferSwap", "a");
+ emit changed(false);
+ emit defaulted(m_settings->isDefaults());
+}
- if (glSwapStrategyValue == "n") {
- return 0;
- } else if (glSwapStrategyValue == "a") {
- return 1;
- } else if (glSwapStrategyValue == "e") {
- return 2;
- } else if (glSwapStrategyValue == "p") {
- return 3;
- } else if (glSwapStrategyValue == "c") {
- return 4;
- }
- return 0;
- };
- setGlSwapStrategy(swapStrategy());
+void Compositing::applyValues()
+{
+ setAnimationSpeed(m_settings->animationDurationFactor());
+ // from options.cpp Options::reloadCompositingSettings
+ // 4 - off, 5 - shown, 6 - always, other are old values
+ setWindowThumbnail(m_settings->hiddenPreviews() - 4);
+ setGlScaleFilter(m_settings->glTextureFilter());
+ setXrScaleFilter(m_settings->xRenderSmoothScale());
+ setCompositingEnabled(m_settings->enabled());
+ setGlSwapStrategy(m_settings->glPreferBufferSwap());
- auto type = [&kwinConfig]{
- const QString backend = kwinConfig.readEntry("Backend", "OpenGL");
- const bool glCore = kwinConfig.readEntry("GLCore", false);
+ const auto type = [this]{
+ const int backend = m_settings->backend();
+ const bool glCore = m_settings->glCore();
- if (backend == QStringLiteral("OpenGL")) {
+ if (backend == KWinCompositingSetting::EnumBackend::OpenGL) {
if (glCore) {
return CompositingType::OPENGL31_INDEX;
} else {
return CompositingType::OPENGL20_INDEX;
}
} else {
return CompositingType::XRENDER_INDEX;
}
};
setCompositingType(type());
- const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(kwinConfig.readEntry("GLPlatformInterface", "glx"));
+ const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(m_settings->glPlatformInterface());
setOpenGLPlatformInterface(index.isValid() ? index.row() : 0);
- setWindowsBlockCompositing(kwinConfig.readEntry("WindowsBlockCompositing", true));
-
- m_changed = false;
+ setWindowsBlockCompositing(m_settings->windowsBlockCompositing());
}
void Compositing::defaults()
{
- setAnimationSpeed(1.0);
- setWindowThumbnail(1);
- setGlScaleFilter(2);
- setXrScaleFilter(false);
- setGlSwapStrategy(1);
- setCompositingType(CompositingType::OPENGL20_INDEX);
- const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(QStringLiteral("glx"));
- setOpenGLPlatformInterface(index.isValid() ? index.row() : 0);
- setWindowsBlockCompositing(true);
- m_changed = true;
+ m_settings->setDefaults();
+
+ applyValues();
+
+ emit changed(m_settings->isSaveNeeded());
+ emit defaulted(m_settings->isDefaults());
}
bool Compositing::OpenGLIsUnsafe() const
{
- KConfigGroup kwinConfig(m_config, "Compositing");
- return kwinConfig.readEntry("OpenGLIsUnsafe", true);
+ return m_settings->openGLIsUnsafe();
}
bool Compositing::OpenGLIsBroken()
{
- KConfigGroup kwinConfig(m_config, "Compositing");
-
- QString oldBackend = kwinConfig.readEntry("Backend", "OpenGL");
- kwinConfig.writeEntry("Backend", "OpenGL");
- kwinConfig.sync();
+ const int oldBackend = m_settings->backend();
+ m_settings->setBackend(KWinCompositingSetting::EnumBackend::OpenGL);
+ m_settings->save();
if (m_compositingInterface->openGLIsBroken()) {
- kwinConfig.writeEntry("Backend", oldBackend);
- kwinConfig.sync();
+ m_settings->setBackend(oldBackend);
+ m_settings->save();
return true;
}
- kwinConfig.writeEntry("OpenGLIsUnsafe", false);
- kwinConfig.sync();
+ m_settings->setOpenGLIsUnsafe(false);
+ m_settings->save();
return false;
}
void Compositing::reenableOpenGLDetection()
{
- KConfigGroup kwinConfig(m_config, "Compositing");
- kwinConfig.writeEntry("OpenGLIsUnsafe", false);
- kwinConfig.sync();
+ m_settings->setOpenGLIsUnsafe(false);
+ m_settings->save();
}
qreal Compositing::animationSpeed() const
{
return m_animationSpeed;
}
int Compositing::windowThumbnail() const
{
return m_windowThumbnail;
}
int Compositing::glScaleFilter() const
{
return m_glScaleFilter;
}
bool Compositing::xrScaleFilter() const
{
return m_xrScaleFilter;
}
int Compositing::glSwapStrategy() const
{
return m_glSwapStrategy;
}
int Compositing::compositingType() const
{
return m_compositingType;
}
bool Compositing::compositingEnabled() const
{
return m_compositingEnabled;
}
void Compositing::setAnimationSpeed(qreal speed)
{
if (speed == m_animationSpeed) {
return;
}
m_animationSpeed = speed;
emit animationSpeedChanged(speed);
}
void Compositing::setGlScaleFilter(int index)
{
if (index == m_glScaleFilter) {
return;
}
m_glScaleFilter = index;
emit glScaleFilterChanged(index);
}
void Compositing::setGlSwapStrategy(int strategy)
{
if (strategy == m_glSwapStrategy) {
return;
}
m_glSwapStrategy = strategy;
emit glSwapStrategyChanged(strategy);
}
void Compositing::setWindowThumbnail(int index)
{
if (index == m_windowThumbnail) {
return;
}
m_windowThumbnail = index;
emit windowThumbnailChanged(index);
}
void Compositing::setXrScaleFilter(bool filter)
{
if (filter == m_xrScaleFilter) {
return;
}
m_xrScaleFilter = filter;
emit xrScaleFilterChanged(filter);
}
void Compositing::setCompositingType(int index)
{
if (index == m_compositingType) {
return;
}
m_compositingType = index;
emit compositingTypeChanged(index);
}
void Compositing::setCompositingEnabled(bool enabled)
{
if (compositingRequired()) {
return;
}
if (enabled == m_compositingEnabled) {
return;
}
m_compositingEnabled = enabled;
emit compositingEnabledChanged(enabled);
}
-void Compositing::save()
+void Compositing::updateSettings()
{
// this writes to the KDE group of the kwinrc, when loading we rely on kconfig cascading to
// load a global value, or allow a kwin override
- KConfigGroup generalConfig(m_config, "KDE");
if (!isRunningPlasma()) {
- generalConfig.writeEntry("AnimationDurationFactor", animationSpeed());
+ m_settings->setAnimationDurationFactor(animationSpeed());
}
- KConfigGroup kwinConfig(m_config, "Compositing");
- kwinConfig.writeEntry("HiddenPreviews", windowThumbnail() + 4);
- kwinConfig.writeEntry("GLTextureFilter", glScaleFilter());
- kwinConfig.writeEntry("XRenderSmoothScale", xrScaleFilter());
+ m_settings->setHiddenPreviews(windowThumbnail() + 4);
+ m_settings->setGlTextureFilter(glScaleFilter());
+ m_settings->setXRenderSmoothScale(xrScaleFilter());
if (!compositingRequired()) {
- kwinConfig.writeEntry("Enabled", compositingEnabled());
+ m_settings->setEnabled(compositingEnabled());
}
- auto swapStrategy = [this] {
- switch (glSwapStrategy()) {
- case 0:
- return QStringLiteral("n");
- case 2:
- return QStringLiteral("e");
- case 3:
- return QStringLiteral("p");
- case 4:
- return QStringLiteral("c");
- case 1:
- default:
- return QStringLiteral("a");
- }
- };
- kwinConfig.writeEntry("GLPreferBufferSwap", swapStrategy());
- QString backend;
+ m_settings->setGlPreferBufferSwap(glSwapStrategy());
+ int backend = KWinCompositingSetting::EnumBackend::OpenGL;
bool glCore = false;
switch (compositingType()) {
case CompositingType::OPENGL31_INDEX:
- backend = "OpenGL";
+ backend = KWinCompositingSetting::EnumBackend::OpenGL;
glCore = true;
break;
case CompositingType::OPENGL20_INDEX:
- backend = "OpenGL";
+ backend = KWinCompositingSetting::EnumBackend::OpenGL;
glCore = false;
break;
case CompositingType::XRENDER_INDEX:
- backend = "XRender";
+ backend = KWinCompositingSetting::EnumBackend::XRender;
glCore = false;
break;
}
- kwinConfig.writeEntry("Backend", backend);
- kwinConfig.writeEntry("GLCore", glCore);
+ m_settings->setBackend(backend);
+ m_settings->setGlCore(glCore);
if (!compositingRequired()) {
- kwinConfig.writeEntry("WindowsBlockCompositing", windowsBlockCompositing());
+ m_settings->setWindowsBlockCompositing(windowsBlockCompositing());
}
- kwinConfig.sync();
- if (m_changed) {
+ emit changed(m_settings->isSaveNeeded());
+ emit defaulted(m_settings->isDefaults());
+}
+
+void Compositing::save()
+{
+ if (m_settings->isSaveNeeded()) {
+
+ m_settings->save();
+
// Send signal to all kwin instances
QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/Compositor"),
QStringLiteral("org.kde.kwin.Compositing"),
QStringLiteral("reinit"));
QDBusConnection::sessionBus().send(message);
- m_changed = false;
}
}
OpenGLPlatformInterfaceModel *Compositing::openGLPlatformInterfaceModel() const
{
return m_openGLPlatformInterfaceModel;
}
int Compositing::openGLPlatformInterface() const
{
return m_openGLPlatformInterface;
}
void Compositing::setOpenGLPlatformInterface(int interface)
{
if (m_openGLPlatformInterface == interface) {
return;
}
m_openGLPlatformInterface = interface;
emit openGLPlatformInterfaceChanged(interface);
}
bool Compositing::windowsBlockCompositing() const
{
return m_windowsBlockCompositing;
}
void Compositing::setWindowsBlockCompositing(bool set)
{
if (compositingRequired()) {
return;
}
if (m_windowsBlockCompositing == set) {
return;
}
m_windowsBlockCompositing = set;
emit windowsBlockCompositingChanged(set);
}
bool Compositing::compositingRequired() const
{
return m_compositingInterface->platformRequiresCompositing();
}
bool Compositing::isRunningPlasma()
{
return qgetenv("XDG_CURRENT_DESKTOP") == "KDE";
}
CompositingType::CompositingType(QObject *parent)
: QAbstractItemModel(parent) {
generateCompositing();
}
void CompositingType::generateCompositing()
{
QHash compositingTypes;
compositingTypes[i18n("OpenGL 3.1")] = CompositingType::OPENGL31_INDEX;
compositingTypes[i18n("OpenGL 2.0")] = CompositingType::OPENGL20_INDEX;
compositingTypes[i18n("XRender")] = CompositingType::XRENDER_INDEX;
CompositingData data;
beginResetModel();
auto it = compositingTypes.begin();
while (it != compositingTypes.end()) {
data.name = it.key();
data.type = it.value();
m_compositingList << data;
it++;
}
std::sort(m_compositingList.begin(), m_compositingList.end(), [](const CompositingData &a, const CompositingData &b) {
- return a.type < b.type;
+ return a.type < b.type;
});
endResetModel();
}
QHash< int, QByteArray > CompositingType::roleNames() const
{
QHash roleNames;
roleNames[NameRole] = "NameRole";
roleNames[TypeRole] = QByteArrayLiteral("type");
return roleNames;
}
QModelIndex CompositingType::index(int row, int column, const QModelIndex &parent) const
{
-
-if (parent.isValid() || column > 0 || column < 0 || row < 0 || row >= m_compositingList.count()) {
+ if (parent.isValid() || column > 0 || column < 0 || row < 0 || row >= m_compositingList.count()) {
return QModelIndex();
}
return createIndex(row, column);
}
QModelIndex CompositingType::parent(const QModelIndex &child) const
{
Q_UNUSED(child)
return QModelIndex();
}
int CompositingType::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 1;
}
int CompositingType::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_compositingList.count();
}
QVariant CompositingType::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
switch (role) {
case Qt::DisplayRole:
case NameRole:
return m_compositingList.at(index.row()).name;
case TypeRole:
return m_compositingList.at(index.row()).type;
default:
return QVariant();
}
}
int CompositingType::compositingTypeForIndex(int row) const
{
return index(row, 0).data(TypeRole).toInt();
}
int CompositingType::indexForCompositingType(int type) const
{
for (int i = 0; i < m_compositingList.count(); ++i) {
if (m_compositingList.at(i).type == type) {
return i;
}
}
return -1;
}
OpenGLPlatformInterfaceModel::OpenGLPlatformInterfaceModel(QObject *parent)
: QAbstractListModel(parent)
{
beginResetModel();
OrgKdeKwinCompositingInterface interface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/Compositor"),
QDBusConnection::sessionBus());
m_keys << interface.supportedOpenGLPlatformInterfaces();
for (const QString &key : m_keys) {
if (key == QStringLiteral("egl")) {
m_names << i18nc("OpenGL Platform Interface", "EGL");
} else if (key == QStringLiteral("glx")) {
m_names << i18nc("OpenGL Platform Interface", "GLX");
} else {
m_names << key;
}
}
endResetModel();
}
OpenGLPlatformInterfaceModel::~OpenGLPlatformInterfaceModel() = default;
int OpenGLPlatformInterfaceModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_keys.count();
}
QHash< int, QByteArray > OpenGLPlatformInterfaceModel::roleNames() const
{
return QHash({
{Qt::DisplayRole, QByteArrayLiteral("display")},
{Qt::UserRole, QByteArrayLiteral("openglPlatformInterface")}
});
}
QVariant OpenGLPlatformInterfaceModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_keys.size() || index.column() != 0) {
return QVariant();
}
switch (role) {
case Qt::DisplayRole:
return m_names.at(index.row());
case Qt::UserRole:
return m_keys.at(index.row());
default:
return QVariant();
}
}
QModelIndex OpenGLPlatformInterfaceModel::indexForKey(const QString &key) const
{
const int keyIndex = m_keys.indexOf(key);
if (keyIndex < 0) {
return QModelIndex();
}
return createIndex(keyIndex, 0);
}
}//end namespace Compositing
}//end namespace KWin
diff --git a/kcmkwin/kwincompositing/compositing.h b/kcmkwin/kwincompositing/compositing.h
index 0646288a6..0eba25282 100644
--- a/kcmkwin/kwincompositing/compositing.h
+++ b/kcmkwin/kwincompositing/compositing.h
@@ -1,185 +1,193 @@
/**************************************************************************
* KWin - the KDE window manager *
* This file is part of the KDE project. *
* *
* Copyright (C) 2013 Antonis Tsiapaliokas *
* *
* 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 COMPOSITING_H
#define COMPOSITING_H
#include
#include
#include
class OrgKdeKwinCompositingInterface;
+class KWinCompositingSetting;
+
namespace KWin {
namespace Compositing {
class OpenGLPlatformInterfaceModel;
class Compositing : public QObject
{
Q_OBJECT
Q_PROPERTY(int animationSpeed READ animationSpeed WRITE setAnimationSpeed NOTIFY animationSpeedChanged)
Q_PROPERTY(int windowThumbnail READ windowThumbnail WRITE setWindowThumbnail NOTIFY windowThumbnailChanged)
Q_PROPERTY(int glScaleFilter READ glScaleFilter WRITE setGlScaleFilter NOTIFY glScaleFilterChanged)
Q_PROPERTY(bool xrScaleFilter READ xrScaleFilter WRITE setXrScaleFilter NOTIFY xrScaleFilterChanged)
Q_PROPERTY(int glSwapStrategy READ glSwapStrategy WRITE setGlSwapStrategy NOTIFY glSwapStrategyChanged)
Q_PROPERTY(int compositingType READ compositingType WRITE setCompositingType NOTIFY compositingTypeChanged)
Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY compositingEnabledChanged)
Q_PROPERTY(KWin::Compositing::OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel READ openGLPlatformInterfaceModel CONSTANT)
Q_PROPERTY(int openGLPlatformInterface READ openGLPlatformInterface WRITE setOpenGLPlatformInterface NOTIFY openGLPlatformInterfaceChanged)
Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged)
Q_PROPERTY(bool compositingRequired READ compositingRequired CONSTANT)
public:
explicit Compositing(QObject *parent = nullptr);
Q_INVOKABLE bool OpenGLIsUnsafe() const;
Q_INVOKABLE bool OpenGLIsBroken();
Q_INVOKABLE void reenableOpenGLDetection();
qreal animationSpeed() const;
int windowThumbnail() const;
int glScaleFilter() const;
bool xrScaleFilter() const;
int glSwapStrategy() const;
int compositingType() const;
bool compositingEnabled() const;
int openGLPlatformInterface() const;
bool windowsBlockCompositing() const;
bool compositingRequired() const;
OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel() const;
void setAnimationSpeed(qreal speed);
void setWindowThumbnail(int index);
void setGlScaleFilter(int index);
void setXrScaleFilter(bool filter);
void setGlSwapStrategy(int strategy);
void setCompositingType(int index);
void setCompositingEnabled(bool enalbed);
void setOpenGLPlatformInterface(int interface);
void setWindowsBlockCompositing(bool set);
void save();
static bool isRunningPlasma();
public Q_SLOTS:
- void reset();
+ void load();
void defaults();
Q_SIGNALS:
- void changed();
+ void changed(bool changed);
+ void defaulted(bool defaulted);
void animationSpeedChanged(qreal);
void windowThumbnailChanged(int);
void glScaleFilterChanged(int);
void xrScaleFilterChanged(int);
void glSwapStrategyChanged(int);
void compositingTypeChanged(int);
void compositingEnabledChanged(bool);
void openGLPlatformInterfaceChanged(int);
void windowsBlockCompositingChanged(bool);
+private Q_SLOTS:
+ void updateSettings();
+
private:
+ void applyValues();
+
qreal m_animationSpeed;
int m_windowThumbnail;
int m_glScaleFilter;
bool m_xrScaleFilter;
int m_glSwapStrategy;
int m_compositingType;
bool m_compositingEnabled;
- bool m_changed;
OpenGLPlatformInterfaceModel *m_openGLPlatformInterfaceModel;
int m_openGLPlatformInterface;
bool m_windowsBlockCompositing;
bool m_windowsBlockingCompositing;
OrgKdeKwinCompositingInterface *m_compositingInterface;
KSharedConfigPtr m_config;
+ KWinCompositingSetting *m_settings;
};
struct CompositingData;
class CompositingType : public QAbstractItemModel
{
Q_OBJECT
Q_ENUMS(CompositingTypeIndex)
public:
enum CompositingTypeIndex {
OPENGL31_INDEX = 0,
OPENGL20_INDEX,
XRENDER_INDEX
};
enum CompositingTypeRoles {
NameRole = Qt::UserRole +1,
TypeRole = Qt::UserRole +2
};
explicit CompositingType(QObject *parent = nullptr);
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash< int, QByteArray > roleNames() const override;
Q_INVOKABLE int compositingTypeForIndex(int row) const;
Q_INVOKABLE int indexForCompositingType(int type) const;
private:
void generateCompositing();
QList m_compositingList;
};
struct CompositingData {
QString name;
CompositingType::CompositingTypeIndex type;
};
class OpenGLPlatformInterfaceModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit OpenGLPlatformInterfaceModel(QObject *parent = nullptr);
~OpenGLPlatformInterfaceModel() override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QModelIndex indexForKey(const QString &key) const;
QHash< int, QByteArray > roleNames() const override;
private:
QStringList m_keys;
QStringList m_names;
};
}//end namespace Compositing
}//end namespace KWin
Q_DECLARE_METATYPE(KWin::Compositing::OpenGLPlatformInterfaceModel*)
#endif
diff --git a/kcmkwin/kwincompositing/compositing.ui b/kcmkwin/kwincompositing/compositing.ui
index ec30fc32f..7d77f3496 100644
--- a/kcmkwin/kwincompositing/compositing.ui
+++ b/kcmkwin/kwincompositing/compositing.ui
@@ -1,307 +1,310 @@
CompositingForm
0
0
526
395
QFormLayout::AllNonFixedFieldsGrow
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
-
-
false
OpenGL compositing (the default) has crashed KWin in the past.
This was most likely due to a driver bug.
If you think that you have meanwhile upgraded to a stable driver,
you can reset this protection but be aware that this might result in an immediate crash!
Alternatively, you might want to use the XRender backend instead.
true
-
false
Scale method "Accurate" is not supported by all hardware and can cause performance regressions and rendering artifacts.
true
-
false
true
-
false
Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized.
true
- -
-
-
- Enable compositor on startup
-
-
-
-
Animation speed:
-
Scale method:
-
-
Crisp
-
Smooth
-
Accurate
-
Scale method:
-
-
Crisp
-
Smooth (slower)
-
Qt::Horizontal
-
Rendering backend:
-
-
Qt::Horizontal
-
Tearing prevention ("vsync"):
-
-
Never
-
Automatic
-
Only when cheap
-
Full screen repaints
-
Re-use screen content
-
Keep window thumbnails:
-
-
Never
-
Only for Shown Windows
-
Always
-
Applications can set a hint to block compositing when the window is open.
This brings performance improvements for e.g. games.
The setting can be overruled by window-specific rules.
Allow applications to block compositing
-
0
0
-
0
0
Qt::Horizontal
QSlider::TicksBelow
1
-
-
Very slow
-
Qt::Horizontal
40
20
-
Instant
+ -
+
+
+ Enable compositor on startup
+
+
+
KMessageWidget
QFrame
1
diff --git a/kcmkwin/kwincompositing/kwincompositing.desktop b/kcmkwin/kwincompositing/kwincompositing.desktop
index 4b699e843..d5c8a97b0 100644
--- a/kcmkwin/kwincompositing/kwincompositing.desktop
+++ b/kcmkwin/kwincompositing/kwincompositing.desktop
@@ -1,128 +1,130 @@
[Desktop Entry]
Exec=kcmshell5 kwincompositing
Icon=preferences-desktop
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=https://userbase.kde.org/Desktop_Effects_Performance#Advanced_Desktop_Effects_Settings
X-KDE-Library=kwincompositing
X-KDE-PluginKeyword=compositing
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=display
X-KDE-Weight=60
Name=Compositor
Name[ast]=Compositor
Name[bs]=Compositor
Name[ca]=Compositor
Name[ca@valencia]=Compositor
Name[cs]=Kompozitor
Name[da]=Compositor
Name[de]=Compositor
Name[el]=Συνθέτης
Name[en_GB]=Compositor
Name[es]=Compositor
Name[et]=Komposiitor
Name[eu]=Konposatzailea
Name[fi]=Koostin
Name[fr]=Compositeur
Name[gl]=Compositor
Name[hu]=Kompozitor
Name[ia]=Compositor
Name[id]=Kompositor
Name[it]=Compositore
Name[ja]=コンポジタ
Name[ko]=컴포지터
Name[lt]=Kompozitorius
Name[nb]=Sammensetter
Name[nds]=Tosamensetten
Name[nl]=Compositor
Name[nn]=Samansetjar
Name[pa]=ਕੰਪੋਜੀਟਰ
Name[pl]=Kompozytor
Name[pt]=Compositor
Name[pt_BR]=Compositor
Name[ro]=Compozitor
Name[ru]=Обеспечение эффектов
Name[sk]=Kompozítor
Name[sl]=Upravljalnik skladnje
Name[sr]=Слагач
Name[sr@ijekavian]=Слагач
Name[sr@ijekavianlatin]=Slagač
Name[sr@latin]=Slagač
Name[sv]=Sammansättning
Name[tr]=Dizgici
Name[uk]=Засіб композиції
Name[vi]=Compositor
Name[x-test]=xxCompositorxx
Name[zh_CN]=混成器
Name[zh_TW]=組合器
Comment=Compositor Settings for Desktop Effects
Comment[bs]=Postavke Compositor-a za Desktop Efekte
Comment[ca]=Arranjament del compositor per als efectes de l'escriptori
Comment[ca@valencia]=Arranjament del compositor pels efectes d'escriptori
Comment[cs]=Nastavení kompozitoru pro efekty pracovní plochy
Comment[da]=Compositor-indstillinger til skrivebordseffekter
Comment[de]=Compositor-Einstellungen für Arbeitsflächen-Effekte
Comment[el]=Ρυθμίσεις συνθέτη για τα εφέ επιφάνειας εργασίας
Comment[en_GB]=Compositor Settings for Desktop Effects
Comment[es]=Configurar las preferencias del compositor para los efectos del escritorio
Comment[et]=Komposiitori seadistused töölauaefektide tarbeks
Comment[eu]=Konposatzailearen ezarpenak mahaigaineko efektuetarako
Comment[fi]=Koostimen asetukset työpöytätehosteita varten
Comment[fr]=Paramétrage du compositeur pour les effets de bureau
Comment[gl]=Configuración do compositor para os efectos de escritorio
Comment[hu]=A kompozitor beállításai az asztali effektusokhoz
Comment[ia]=Preferentias de compositor pro le effectos de scriptorio
Comment[id]=Pengaturan Kompositor untuk Efek Window
Comment[it]=Impostazioni del compositore per gli effetti del desktop
Comment[ja]=デスクトップ効果のためのコンポジタの設定
Comment[ko]=데스크톱 효과에 사용되는 컴포지터 설정
Comment[lt]=Darbalaukio efektų kompozitoriaus nuostatos
Comment[nb]=Sammensetter-innstillinger for skrivebordseffekter
Comment[nds]=Tosamensettoptschonen för de Schriefdischeffekten instellen
Comment[nl]=Instellingen van compositor configureren voor bureaubladeffecten
Comment[nn]=Samansetjarinnstillingar for skrivebordseffektar
Comment[pa]=ਡੈਸਕਟਾਪ ਪਰਭਾਵ ਲਈ ਕੰਪੋਜੀਟਰ ਸੈਟਿੰਗਾਂ
Comment[pl]=Ustawienia kompozytora dla efektów pulpitu
Comment[pt]=Configuração do Compositor para os Efeitos do Ecrã
Comment[pt_BR]=Definições do Compositor para os efeitos da área de trabalho
Comment[ru]=Настройка движка эффектов рабочего стола
Comment[sk]=Nastavenia kompozítora pre efekty plochy
Comment[sl]=Nastavitve upravljalnika skladnje za učinke namizja
Comment[sr]=Поставке слагача за ефекте површи
Comment[sr@ijekavian]=Поставке слагача за ефекте површи
Comment[sr@ijekavianlatin]=Postavke slagača za efekte površi
Comment[sr@latin]=Postavke slagača za efekte površi
Comment[sv]=Sammansättningsinställningar för skrivbordseffekter
Comment[tr]=Masaüstü Efektleri için Dizgici Ayarları
Comment[uk]=Параметри засобу композиції для ефектів стільниці
Comment[vi]=Thiết lập Compositor cho hiệu ứng màn hình
Comment[x-test]=xxCompositor Settings for Desktop Effectsxx
Comment[zh_CN]=桌面特效混成器设置
Comment[zh_TW]=桌面效果使用的組合器設定
X-KDE-Keywords=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects
X-KDE-Keywords[ca]=kwin,finestra,gestor,composició,efecte,efectes 3D,efectes 2D,OpenGL,XRender,arranjament de vídeo,efectes gràfics,efectes de l'escriptori
X-KDE-Keywords[da]=kwin,vindue,håndtering,window,manager,compositing,effekt,3D effekter,2D effekter,OpenGL,XRender,video-indstillinger,grafiske effekter,skrivebordseffekter,desktop effects
+X-KDE-Keywords[en_GB]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects
X-KDE-Keywords[es]=kwin,ventana,gestor,composición,efecto,efectos 3D,efectos 2D,OpenGL,XRender,preferencias de vídeo,efectos gráficos,efectos del escritorio
X-KDE-Keywords[et]=kwin,aken,haldur,komposiit,komposiitor,efekt,3D efektid,ruumilised efektid,2D efektid,OpenGL,XRender,videoseadistused,graafilised efektid,töölauaefektid
X-KDE-Keywords[eu]=kwin,leihoa,kudeatzailea,konposatzailea,efektua,3Dtako efektuak,2Dtako efektuak,OpenGL,XRender,bideo ezarpenak,efektu grafikoak,mahaigaineko efektuak
X-KDE-Keywords[fi]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects,ikkunointiohjelma,ikkunaohjelma,ikkunanhallinta,tehoste,3D-tehosteet,2D-tehosteet,videoasetukset,graafiset tehosteet,työpöytätehosteet
X-KDE-Keywords[fr]=Gestionnaire de fenêtres KWin, kwin,window,manager,compositeur, effet, effets 3D,effets 2D,OpenGL,XRender,paramétrage video,effets graphiques ,effects du bureau
X-KDE-Keywords[ia]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects
X-KDE-Keywords[id]=kwin,window,pengelola,kompositing,efek,efek 3D,efek 2D,OpenGL,XRender,pengaturan video,efek grafis,efek desktop
X-KDE-Keywords[it]=kwin,finestra,gestore,composizione,effetto,effetti 3D,effetti 2D,OpenGL,XRender,impostazioni video,effetti grafici,effetti del desktop
X-KDE-Keywords[ko]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects,3D 효과,2D 효과,비디오 설정,그래픽 설정,그래픽 효과,데스크톱 효과
X-KDE-Keywords[lt]=kwin,langas,langai,tvarkytuvė,tvarkytuve,komponavimas,kompozicionavimas,efektas,efektai,3D efektai,2D efektai,trimačiai efektai,trimaciai efektai,dvimačiai efektai,dvimaciai efektai,OpenGL,XRender,vaizdo nustatymai,vaizdo nuostatos,video nustatymai,video nuostatos,grafiniai efektai,grafikos efektai,darbalaukio efektai,darbastalio efektai
X-KDE-Keywords[nl]=kwin,window,manager,beheerder,compositing,effecten,3D-effecten,2D-effecten,OpenGL,XRender,video-instellingen,grafische effecten,bureaubladeffecten
X-KDE-Keywords[nn]=kwin,vindauge,vindaugshandsamar,samansetjing,effekt,3D-effektar,2D-effektar,OpenGL,XRender,videoinnstillingar,grafiske effektar,skrivebordseffektar
X-KDE-Keywords[pt]=kwin,janela,gestor,composição,efeito,efeitos 3D,efeitos 2D,OpenGL,XRender,configuração do vídeo,efeitos gráficos,efeitos do ecrã
X-KDE-Keywords[pt_BR]=kwin,janela,gerenciador,composição,efeito,efeitos 3D,efeitos 2D,OpenGL,XRender,configurações de vídeo,efeitos gráficos,efeitos da área de trabalho
X-KDE-Keywords[ru]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects,композитинг,композитный диспетчер окон,эффекты рабочего стола,графические эффекты,рендеринг,параметры видео,настройка видео
+X-KDE-Keywords[sl]=kwin,okna,upravljalnik,skladnja,učinek,3D učinki,2D učinki,OpenGL,XRender,nastavitve videa,video,grafični učinki,hitrost animacije,učinki namizja
X-KDE-Keywords[sv]=kwin,fönster,hantering,sammansättning,effekt,3D effekter,2D effekter,OpenGL,XRender,videoinställningar,grafiska effekter,skrivbordseffekter
X-KDE-Keywords[uk]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects,вікно,керування,композитне,композиція,ефект,просторовий,ефекти,плоскі,параметри відео,графічні ефекти,ефекти стільниці
X-KDE-Keywords[x-test]=xxkwinxx,xxwindowxx,xxmanagerxx,xxcompositingxx,xxeffectxx,xx3D effectsxx,xx2D effectsxx,xxOpenGLxx,xxXRenderxx,xxvideo settingsxx,xxgraphical effectsxx,xxdesktop effectsxx
X-KDE-Keywords[zh_CN]=kwin,窗口,管理器,混成,特效,3D 特效,2D 特效,OpenGL,XRender,视频设置,图形特效,桌面特效
X-KDE-Keywords[zh_TW]=kwin,window,manager,compositing,effect,3D effects,2D effects,OpenGL,XRender,video settings,graphical effects,desktop effects,桌面特效,圖形特效,視訊設定,特效,3D,2D,合成,視窗,管理器
diff --git a/kcmkwin/kwincompositing/kwincompositing_setting.kcfg b/kcmkwin/kwincompositing/kwincompositing_setting.kcfg
new file mode 100644
index 000000000..31758a5e8
--- /dev/null
+++ b/kcmkwin/kwincompositing/kwincompositing_setting.kcfg
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+ 1.0
+
+
+
+
+
+
+ 5
+
+
+
+ 2
+
+
+
+ false
+
+
+
+ true
+
+
+
+ true
+
+
+
+ a
+
+
+
+
+
+
+
+
+
+
+ OpenGL
+
+
+
+
+
+
+
+ false
+
+
+
+ true
+
+
+
+ glx
+
+
+
+
+
+
+
+
+
diff --git a/kcmkwin/kwincompositing/kwincompositing_setting.kcfgc b/kcmkwin/kwincompositing/kwincompositing_setting.kcfgc
new file mode 100644
index 000000000..4b6ac5926
--- /dev/null
+++ b/kcmkwin/kwincompositing/kwincompositing_setting.kcfgc
@@ -0,0 +1,5 @@
+File=kwincompositing_setting.kcfg
+ClassName=KWinCompositingSetting
+Mutators=true
+DefaultValueGetters=true
+ParentInConstructor=true
diff --git a/kcmkwin/kwincompositing/main.cpp b/kcmkwin/kwincompositing/main.cpp
index 138cfe863..271559ab5 100644
--- a/kcmkwin/kwincompositing/main.cpp
+++ b/kcmkwin/kwincompositing/main.cpp
@@ -1,227 +1,228 @@
/**************************************************************************
* KWin - the KDE window manager *
* This file is part of the KDE project. *
* *
* Copyright (C) 2013 Antonis Tsiapaliokas *
* Copyright (C) 2013 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 "compositing.h"
#include "ui_compositing.h"
#include
#include
#include
#include
#include
#include
#include
-class KWinCompositingSettings : public KCModule
+class KWinCompositingKCM : public KCModule
{
Q_OBJECT
public:
- explicit KWinCompositingSettings(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
+ explicit KWinCompositingKCM(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
public Q_SLOTS:
void load() override;
void save() override;
void defaults() override;
private:
void init();
KWin::Compositing::Compositing *m_compositing;
Ui_CompositingForm m_form;
};
static const QVector s_animationMultipliers = {8, 4, 2, 1, 0.5, 0.25, 0.125, 0};
-KWinCompositingSettings::KWinCompositingSettings(QWidget *parent, const QVariantList &args)
+KWinCompositingKCM::KWinCompositingKCM(QWidget *parent, const QVariantList &args)
: KCModule(parent, args)
, m_compositing(new KWin::Compositing::Compositing(this))
{
m_form.setupUi(this);
m_form.glCrashedWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning")));
QAction *reenableGLAction = new QAction(i18n("Re-enable OpenGL detection"), this);
connect(reenableGLAction, &QAction::triggered, m_compositing, &KWin::Compositing::Compositing::reenableOpenGLDetection);
connect(reenableGLAction, &QAction::triggered, m_form.glCrashedWarning, &KMessageWidget::animatedHide);
m_form.glCrashedWarning->addAction(reenableGLAction);
m_form.scaleWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning")));
m_form.tearingWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning")));
m_form.windowThumbnailWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning")));
m_form.compositingEnabled->setVisible(!m_compositing->compositingRequired());
m_form.windowsBlockCompositing->setVisible(!m_compositing->compositingRequired());
init();
}
-void KWinCompositingSettings::init()
+void KWinCompositingKCM::init()
{
using namespace KWin::Compositing;
auto currentIndexChangedSignal = static_cast(&QComboBox::currentIndexChanged);
- connect(m_compositing, &Compositing::changed, this, &KWinCompositingSettings::markAsChanged);
+ connect(m_compositing, &Compositing::changed, this, qOverload(&KCModule::changed));
+ connect(m_compositing, &Compositing::defaulted, this, qOverload(&KCModule::defaulted));
// enabled check box
m_form.compositingEnabled->setChecked(m_compositing->compositingEnabled());
connect(m_compositing, &Compositing::compositingEnabledChanged, m_form.compositingEnabled, &QCheckBox::setChecked);
connect(m_form.compositingEnabled, &QCheckBox::toggled, m_compositing, &Compositing::setCompositingEnabled);
// animation speed
m_form.animationSpeed->setMaximum(s_animationMultipliers.size() - 1);
auto setSpeed = [this](const qreal multiplier) {
auto const it = std::lower_bound(s_animationMultipliers.begin(), s_animationMultipliers.end(), multiplier, std::greater());
const int index = std::distance(s_animationMultipliers.begin(), it);
m_form.animationSpeed->setValue(index);
};
setSpeed(m_compositing->animationSpeed());
connect(m_compositing, &Compositing::animationSpeedChanged, m_form.animationSpeed, setSpeed);
connect(m_form.animationSpeed, &QSlider::valueChanged, m_compositing, [this](int index) {
m_compositing->setAnimationSpeed(s_animationMultipliers[index]);
});
if (Compositing::isRunningPlasma()) {
m_form.animationSpeedLabel->hide();
m_form.animationSpeedControls->hide();
}
// gl scale filter
m_form.glScaleFilter->setCurrentIndex(m_compositing->glScaleFilter());
connect(m_compositing, &Compositing::glScaleFilterChanged, m_form.glScaleFilter, &QComboBox::setCurrentIndex);
connect(m_form.glScaleFilter, currentIndexChangedSignal, m_compositing, &Compositing::setGlScaleFilter);
connect(m_form.glScaleFilter, currentIndexChangedSignal,
[this](int index) {
if (index == 2) {
m_form.scaleWarning->animatedShow();
} else {
m_form.scaleWarning->animatedHide();
}
}
);
// xrender scale filter
m_form.xrScaleFilter->setCurrentIndex(m_compositing->xrScaleFilter());
connect(m_compositing, &Compositing::xrScaleFilterChanged, m_form.xrScaleFilter, &QComboBox::setCurrentIndex);
connect(m_form.xrScaleFilter, currentIndexChangedSignal,
[this](int index) {
if (index == 0) {
m_compositing->setXrScaleFilter(false);
} else {
m_compositing->setXrScaleFilter(true);
}
});
// tearing prevention
m_form.tearingPrevention->setCurrentIndex(m_compositing->glSwapStrategy());
connect(m_compositing, &Compositing::glSwapStrategyChanged, m_form.tearingPrevention, &QComboBox::setCurrentIndex);
connect(m_form.tearingPrevention, currentIndexChangedSignal, m_compositing, &Compositing::setGlSwapStrategy);
connect(m_form.tearingPrevention, currentIndexChangedSignal,
[this](int index) {
if (index == 2) {
// only when cheap - tearing
m_form.tearingWarning->setText(i18n("\"Only when cheap\" only prevents tearing for full screen changes like a video."));
m_form.tearingWarning->animatedShow();
} else if (index == 3) {
// full screen repaints
m_form.tearingWarning->setText(i18n("\"Full screen repaints\" can cause performance problems."));
m_form.tearingWarning->animatedShow();
} else if (index == 4) {
// re-use screen content
m_form.tearingWarning->setText(i18n("\"Re-use screen content\" causes severe performance problems on MESA drivers."));
m_form.tearingWarning->animatedShow();
} else {
m_form.tearingWarning->animatedHide();
}
}
);
// windowThumbnail
m_form.windowThumbnail->setCurrentIndex(m_compositing->windowThumbnail());
connect(m_compositing, &Compositing::windowThumbnailChanged, m_form.windowThumbnail, &QComboBox::setCurrentIndex);
connect(m_form.windowThumbnail, currentIndexChangedSignal, m_compositing, &Compositing::setWindowThumbnail);
connect(m_form.windowThumbnail, currentIndexChangedSignal,
[this](int index) {
if (index == 2) {
m_form.windowThumbnailWarning->animatedShow();
} else {
m_form.windowThumbnailWarning->animatedHide();
}
}
);
// windows blocking compositing
m_form.windowsBlockCompositing->setChecked(m_compositing->windowsBlockCompositing());
connect(m_compositing, &Compositing::windowsBlockCompositingChanged, m_form.windowsBlockCompositing, &QCheckBox::setChecked);
connect(m_form.windowsBlockCompositing, &QCheckBox::toggled, m_compositing, &Compositing::setWindowsBlockCompositing);
// compositing type
CompositingType *type = new CompositingType(this);
m_form.type->setModel(type);
auto updateCompositingType = [this, type]() {
m_form.type->setCurrentIndex(type->indexForCompositingType(m_compositing->compositingType()));
};
updateCompositingType();
connect(m_compositing, &Compositing::compositingTypeChanged,
[updateCompositingType]() {
updateCompositingType();
}
);
auto showHideBasedOnType = [this, type]() {
const int currentType = type->compositingTypeForIndex(m_form.type->currentIndex());
m_form.glScaleFilter->setVisible(currentType != CompositingType::XRENDER_INDEX);
m_form.glScaleFilterLabel->setVisible(currentType != CompositingType::XRENDER_INDEX);
m_form.xrScaleFilter->setVisible(currentType == CompositingType::XRENDER_INDEX);
m_form.xrScaleFilterLabel->setVisible(currentType == CompositingType::XRENDER_INDEX);
};
showHideBasedOnType();
connect(m_form.type, currentIndexChangedSignal,
[this, type, showHideBasedOnType]() {
m_compositing->setCompositingType(type->compositingTypeForIndex(m_form.type->currentIndex()));
showHideBasedOnType();
}
);
if (m_compositing->OpenGLIsUnsafe()) {
m_form.glCrashedWarning->animatedShow();
}
}
-void KWinCompositingSettings::load()
+void KWinCompositingKCM::load()
{
KCModule::load();
- m_compositing->reset();
+ m_compositing->load();
}
-void KWinCompositingSettings::defaults()
+void KWinCompositingKCM::defaults()
{
KCModule::defaults();
m_compositing->defaults();
}
-void KWinCompositingSettings::save()
+void KWinCompositingKCM::save()
{
KCModule::save();
m_compositing->save();
}
K_PLUGIN_FACTORY(KWinCompositingConfigFactory,
- registerPlugin("compositing");
+ registerPlugin("compositing");
)
#include "main.moc"
diff --git a/kcmkwin/kwindecoration/kwindecoration.desktop b/kcmkwin/kwindecoration/kwindecoration.desktop
index b00a23332..597173654 100644
--- a/kcmkwin/kwindecoration/kwindecoration.desktop
+++ b/kcmkwin/kwindecoration/kwindecoration.desktop
@@ -1,150 +1,151 @@
[Desktop Entry]
Icon=preferences-desktop-theme-windowdecorations
Exec=kcmshell5 kwindecoration
Categories=Qt;KDE;X-KDE-settings-looknfeel;
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-Library=kcm_kwindecoration
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=applicationstyle
X-KDE-Weight=40
X-DocPath=kcontrol/kwindecoration/index.html
X-KDE-FormFactors=desktop,tablet
Name=Window Decorations
Name[ar]=زخارف النوافذ
Name[bg]=Декорации на прозорците
Name[bs]=Dekoracije prozora
Name[ca]=Decoració de les finestres
Name[ca@valencia]=Decoració de les finestres
Name[cs]=Dekorace oken
Name[da]=Vinduesdekorationer
Name[de]=Fensterdekoration
Name[el]=Διακοσμήσεις παραθύρου
Name[en_GB]=Window Decorations
Name[es]=Decoración de ventanas
Name[et]=Akna dekoratsioonid
Name[eu]=Leiho-apaindurak
Name[fi]=Ikkunakehykset
Name[fr]=Décorations de fenêtres
Name[ga]=Maisiúcháin Fhuinneog
Name[gl]=Decoración da xanela
Name[he]=מסגרת חלון
Name[hi]=विंडो सजावट
Name[hr]=Ukrasi prozora
Name[hu]=Ablakdekorációk
Name[ia]=Decorationes de fenestra
Name[id]=Dekorasi Window
Name[is]=Gluggaskreytingar
Name[it]=Decorazioni delle finestre
Name[ja]=ウィンドウの飾り
Name[kk]=Терезенің безендірулері
Name[km]=ការតុបតែងបង្អួច
Name[kn]=ವಿಂಡೋ ಅಲಂಕಾರಗಳು
Name[ko]=창 장식
Name[lt]=Langų dekoracijos
Name[lv]=Logu dekorācijas
Name[mr]=चौकट सजावट
Name[nb]=Vinduspynt
Name[nds]=Finstern opfladusen
Name[nl]=Vensterdecoraties
Name[nn]=Vindaugspynt
Name[pa]=ਵਿੰਡੋ ਸਜਾਵਟ
Name[pl]=Wygląd okien
Name[pt]=Decorações das Janelas
Name[pt_BR]=Decorações da janela
Name[ro]=Decorații fereastră
Name[ru]=Оформление окон
Name[si]=කවුළු සැරසිලි
Name[sk]=Dekorácie okien
Name[sl]=Okraski oken
Name[sr]=Декорације прозора
Name[sr@ijekavian]=Декорације прозора
Name[sr@ijekavianlatin]=Dekoracije prozora
Name[sr@latin]=Dekoracije prozora
Name[sv]=Fönsterdekorationer
Name[th]=ส่วนตกแต่งหน้าต่าง
Name[tr]=Pencere Dekorasyonları
Name[ug]=كۆزنەك بېزەكلىرى
Name[uk]=Обрамлення вікон
Name[wa]=Gåyotaedjes des fniesses
Name[x-test]=xxWindow Decorationsxx
Name[zh_CN]=窗口装饰
Name[zh_TW]=視窗裝飾
Comment=Configure window titlebars and borders
Comment[ca]=Configura la barra de títol i les vores de les finestres
Comment[ca@valencia]=Configura la barra de títol i les vores de les finestres
Comment[da]=Indstil vinduets titellinjer og kanter
Comment[de]=Titelleiste und Ränder von Fenstern einrichten
Comment[en_GB]=Configure window titlebars and borders
Comment[es]=Configurar barra de título y bordes de las ventanas
Comment[et]=Akende tiitliriba ja raami seadistamine
Comment[eu]=Konfiguratu leihoen titulu-barrak eta ertzak
Comment[fi]=Ikkunan otsikkopalkkien ja reunojen asetukset
Comment[fr]=Configure les barres de titre et les bordures de la fenêtre
Comment[gl]=Configurar as barras de título e os bordos das xanelas
Comment[ia]=Configura barras de titulo e margines
Comment[id]=Konfigurasikan bingkai dan bilah-judul window
Comment[it]=Configura la barra del titolo e i bordi delle finestre
Comment[ko]=창 제목 표시줄과 경계선 설정
Comment[lt]=Konfigūruoti langų antraštės juostas ir rėmelius
Comment[nl]=Titelbalken en randen van venster configureren
Comment[nn]=Set opp tittellinjer og vindaugsrammer
Comment[pl]=Ustawienia pasków tytułów i obramowań okien
Comment[pt]=Configurar as barras de título e contornos das janelas
Comment[pt_BR]=Configure as barras de títulos e bordas da janela
Comment[ru]=Настройка заголовка и границ окон
Comment[sk]=Nastaviť záhlavia a okraje okna
+Comment[sl]=Nastavi naslovne vrstice in robove oken
Comment[sv]=Anpassa namnlister och kanter för fönster
Comment[uk]=Налаштовування смужок заголовків та рамок вікон
Comment[x-test]=xxConfigure window titlebars and bordersxx
Comment[zh_CN]=配置窗口标题栏和边框
Comment[zh_TW]=設定視窗的標題列和邊框
X-KDE-Keywords=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
X-KDE-Keywords[bs]=kwin,prozor,upravitelj,granica,stil,tema,izgled,osjećati,izgled,dugme,držati,ivica,kwm,dekoracija
X-KDE-Keywords[ca]=kwin,finestra,gestor,vora,estil,tema,aspecte,comportament,disposició,botó,gestió,vora,kwm,decoració
X-KDE-Keywords[ca@valencia]=kwin,finestra,gestor,vora,estil,tema,aspecte,comportament,disposició,botó,gestió,vora,kwm,decoració
X-KDE-Keywords[cs]=kwin,okna,správce,okraj,styl,motiv,vzhled,pocit,rozvržení,tlačítko,madlo,okraj,kwm,dekorace
X-KDE-Keywords[da]=kwin,vindueshåndtering,window,manager,kant,stil,tema,udseende,layout,knap,håndtag,kant,kwm,dekoration
X-KDE-Keywords[de]=KWin,Kwm,Fenster,Manager,Rahmen,Design,Stile,Themes,Optik,Erscheinungsbild,Layout,Knöpfe,Ränder,Dekorationen
X-KDE-Keywords[el]=kwin,παράθυρο,διαχειριστής,περίγραμμα,στιλ,θέμα,εμφάνιση,αίσθηση,διάταξη,κουμπί,χειρισμός,άκρη,kwm,διακόσμηση
X-KDE-Keywords[en_GB]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
X-KDE-Keywords[es]=kwin,ventana,gestor,borde,estilo,tema,aspecto,sensación,disposición,botón,asa,borde,kwm,decoración
X-KDE-Keywords[et]=kwin,aken,haldur,piire,stiil,teema,välimus,paigutus,nupp,pide,serv,kwm,dekoratsioon
X-KDE-Keywords[eu]=kwin,leiho,kudeatzaile,ertz,estilo,gai, itxura,izaera,diseinu,botoi,helduleku,kwm,dekorazio,apaindura,apainketa
X-KDE-Keywords[fi]=kwin,ikkuna,hallinta,ikkunointiohjelma,kehys,reunus,tyyli,teema,ulkoasu,toiminta,asettelu,painike,kahva,kulma,reuna,kwm,koriste
X-KDE-Keywords[fr]=kwin, fenêtre, gestionnaire, composition, bordure, style, thème, apparence, comportement, disposition, bouton, prise en main, bord, kwm, décoration
X-KDE-Keywords[ga]=kwin,fuinneog,bainisteoir,imlíne,stíl,téama,cuma,brath,leagan amach,cnaipe,hanla,ciumhais,kwm,maisiúchán
X-KDE-Keywords[gl]=kwin,xanela,xestor,estilo,tema,aparencia,comportamento,aspecto,disposición, botón,asa,bordo,kwm,decoración
X-KDE-Keywords[hu]=kwin,ablak,kezelő,szegély,stílus,téma,kinézet,megjelenés,elrendezés,gomb,kezel,szél,kwm,dekoráció
X-KDE-Keywords[ia]=kwin,fenestra,gerente,margine,stilo,thema,aspecto,sentir,disposition,button,maneator,bordo,kwm,decoration
X-KDE-Keywords[id]=kwin,window,pengelola,batas,gaya,tema,tampilan,rasa,tata letak,tombol,pegangan,bingkai,kwm,dekorasi
X-KDE-Keywords[it]=kwin,gestore,finestre,bordo,stile,tema,aspetto,disposizione,pulsante,gestore,kwm,decorazione
X-KDE-Keywords[kk]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
X-KDE-Keywords[km]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
X-KDE-Keywords[ko]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,창,관리자,테두리,스타일,테마,단추,핸들,경계
X-KDE-Keywords[lt]=kwin,langai,langas,langų,tvarkytuvė,tvarkytuve,rėmelis,remelis,stilius,apipavidalinimas,tema,išvaizda,isvaizda,turinys,išdėstymas,isdestymas,mygtukai,mygtukas,rankena,rankenėlė,rankenele,kraštas,krastas,kraštai,krastai,kwm,dekoracija,dekoracijos
X-KDE-Keywords[nb]=kwin,vindu,behandler,ramme,stil,tema,lås,utforming,knapp,håndtak,kant,kwm
X-KDE-Keywords[nds]=KWin,Finster,Pleger,Rahmen,Stil,Muster,Utsehn,Bedenen,Knoop,Greep,Kant,kwm,Dekoratschoon
X-KDE-Keywords[nl]=kwin,venster,beheerder,grens,stijl,thema,look,feel,indeling,knop,handel,rand,kwm,decoratie
X-KDE-Keywords[nn]=kwin,vindauge,handsamar,ramme,kantlinje,stil,tema,lås,utforming,knapp,handtak,kant,kwm,dekorasjon,pynt
X-KDE-Keywords[pl]=kwin,okno,menadżer,obramowanie,styl,motyw,wygląd,odczucie,układ,przycisk, uchwyt,krawędź,kwm,dekoracja
X-KDE-Keywords[pt]=kwin,gestor,janela,contorno,estilo,tema,aparência,comportamento,disposição,botão,pega,extremo,kwm,decoração
X-KDE-Keywords[pt_BR]=kwin,gerenciador,janela,borda,estilo,tema,aparência,comportamento,layout,botão,canto,extremo,kwm,decoração
X-KDE-Keywords[ru]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,окно,диспетчер,граница,стиль,тема,внешний вид,оформление,разметка,шаблон,кнопка,управление,край
X-KDE-Keywords[sk]=kwin,okno,správca,rám,štýl,téma,vzhľad,cítenie,rozloženie,tlačidlo,spracovanie,okraj,kwm,dekorácia
X-KDE-Keywords[sl]=kwin,okna,okenski upravljalnik,upravljalnik oken,rob,obroba,slog,tema,videz,obnašanje,občutek,razpored,gumbi,ročica,okraski,kwm
X-KDE-Keywords[sr]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,К‑вин,прозор,менаџер,ивица,стила,тема,изглед,осећај,распоред,дугме,ручка,КВМ,декорација
X-KDE-Keywords[sr@ijekavian]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,К‑вин,прозор,менаџер,ивица,стила,тема,изглед,осећај,распоред,дугме,ручка,КВМ,декорација
X-KDE-Keywords[sr@ijekavianlatin]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,KWin,prozor,menadžer,ivica,stila,tema,izgled,osećaj,raspored,dugme,ručka,KWM,dekoracija
X-KDE-Keywords[sr@latin]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,KWin,prozor,menadžer,ivica,stila,tema,izgled,osećaj,raspored,dugme,ručka,KWM,dekoracija
X-KDE-Keywords[sv]=kwin,fönster,hantering,kant,stil,tema,utseende,känsla,layout,knapp,grepp,kant,kwm,dekoration
X-KDE-Keywords[tr]=kwin,pencere,yönetici,kenarlık,biçim,tema,görünüm,şekil,düzen,düğme,kullanım,kenar,kwm,dekorasyon
X-KDE-Keywords[uk]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,вікно,вікна,керування,менеджер,рамка,межа,стиль,тема,вигляд,поведінка,компонування,кнопка,елемент,край,декорації,обрамлення
X-KDE-Keywords[x-test]=xxkwinxx,xxwindowxx,xxmanagerxx,xxborderxx,xxstylexx,xxthemexx,xxlookxx,xxfeelxx,xxlayoutxx,xxbuttonxx,xxhandlexx,xxedgexx,xxkwmxx,xxdecorationxx
X-KDE-Keywords[zh_CN]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration,窗口,管理,边框,样式,主题,外怪,布局,按钮,边界,装饰
X-KDE-Keywords[zh_TW]=kwin,window,manager,border,style,theme,look,feel,layout,button,handle,edge,kwm,decoration
diff --git a/kcmkwin/kwindecoration/package/metadata.desktop b/kcmkwin/kwindecoration/package/metadata.desktop
index 022703438..4755ca936 100644
--- a/kcmkwin/kwindecoration/package/metadata.desktop
+++ b/kcmkwin/kwindecoration/package/metadata.desktop
@@ -1,106 +1,107 @@
[Desktop Entry]
Icon=preferences-system-windows-action
Type=Service
Keywords=
X-KDE-ParentApp=
X-KDE-System-Settings-Parent-Category=applicationstyle
X-KDE-PluginInfo-Author=Valerio Pilo
X-KDE-PluginInfo-Email=vpilo@coldshock.net
X-KDE-PluginInfo-License=GPL-2.0+
X-KDE-PluginInfo-Name=kcm_kwindecoration
X-KDE-PluginInfo-Version=
X-KDE-PluginInfo-Website=https://www.kde.org/plasma-desktop
X-KDE-ServiceTypes=Plasma/Generic
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-KDE-FormFactors=desktop,tablet
Name=Window Decorations
Name[ar]=زخارف النوافذ
Name[bg]=Декорации на прозорците
Name[bs]=Dekoracije prozora
Name[ca]=Decoració de les finestres
Name[ca@valencia]=Decoració de les finestres
Name[cs]=Dekorace oken
Name[da]=Vinduesdekorationer
Name[de]=Fensterdekoration
Name[el]=Διακοσμήσεις παραθύρου
Name[en_GB]=Window Decorations
Name[es]=Decoración de ventanas
Name[et]=Akna dekoratsioonid
Name[eu]=Leiho-apaindurak
Name[fi]=Ikkunakehykset
Name[fr]=Décorations de fenêtres
Name[ga]=Maisiúcháin Fhuinneog
Name[gl]=Decoración da xanela
Name[he]=מסגרת חלון
Name[hi]=विंडो सजावट
Name[hr]=Ukrasi prozora
Name[hu]=Ablakdekorációk
Name[ia]=Decorationes de fenestra
Name[id]=Dekorasi Window
Name[is]=Gluggaskreytingar
Name[it]=Decorazioni delle finestre
Name[ja]=ウィンドウの飾り
Name[kk]=Терезенің безендірулері
Name[km]=ការតុបតែងបង្អួច
Name[kn]=ವಿಂಡೋ ಅಲಂಕಾರಗಳು
Name[ko]=창 장식
Name[lt]=Langų dekoracijos
Name[lv]=Logu dekorācijas
Name[mr]=चौकट सजावट
Name[nb]=Vinduspynt
Name[nds]=Finstern opfladusen
Name[nl]=Vensterdecoraties
Name[nn]=Vindaugspynt
Name[pa]=ਵਿੰਡੋ ਸਜਾਵਟ
Name[pl]=Wygląd okien
Name[pt]=Decorações das Janelas
Name[pt_BR]=Decorações da janela
Name[ro]=Decorații fereastră
Name[ru]=Оформление окон
Name[si]=කවුළු සැරසිලි
Name[sk]=Dekorácie okien
Name[sl]=Okraski oken
Name[sr]=Декорације прозора
Name[sr@ijekavian]=Декорације прозора
Name[sr@ijekavianlatin]=Dekoracije prozora
Name[sr@latin]=Dekoracije prozora
Name[sv]=Fönsterdekorationer
Name[th]=ส่วนตกแต่งหน้าต่าง
Name[tr]=Pencere Dekorasyonları
Name[ug]=كۆزنەك بېزەكلىرى
Name[uk]=Обрамлення вікон
Name[wa]=Gåyotaedjes des fniesses
Name[x-test]=xxWindow Decorationsxx
Name[zh_CN]=窗口装饰
Name[zh_TW]=視窗裝飾
Comment=Configure window titlebars and borders
Comment[ca]=Configura la barra de títol i les vores de les finestres
Comment[ca@valencia]=Configura la barra de títol i les vores de les finestres
Comment[da]=Indstil vinduets titellinjer og kanter
Comment[de]=Titelleiste und Ränder von Fenstern einrichten
Comment[en_GB]=Configure window titlebars and borders
Comment[es]=Configurar barra de título y bordes de las ventanas
Comment[et]=Akende tiitliriba ja raami seadistamine
Comment[eu]=Konfiguratu leihoen titulu-barrak eta ertzak
Comment[fi]=Ikkunan otsikkopalkkien ja reunojen asetukset
Comment[fr]=Configure les barres de titre et les bordures de la fenêtre
Comment[gl]=Configurar as barras de título e os bordos das xanelas
Comment[ia]=Configura barras de titulo e margines
Comment[id]=Konfigurasikan bingkai dan bilah-judul window
Comment[it]=Configura la barra del titolo e i bordi delle finestre
Comment[ko]=창 제목 표시줄과 경계선 설정
Comment[lt]=Konfigūruoti langų antraštės juostas ir rėmelius
Comment[nl]=Titelbalken en randen van venster configureren
Comment[nn]=Set opp tittellinjer og vindaugsrammer
Comment[pl]=Ustawienia pasków tytułów i obramowań okien
Comment[pt]=Configurar as barras de título e contornos das janelas
Comment[pt_BR]=Configure as barras de títulos e bordas da janela
Comment[ru]=Настройка заголовка и границ окон
Comment[sk]=Nastaviť záhlavia a okraje okna
+Comment[sl]=Nastavi naslovne vrstice in robove oken
Comment[sv]=Anpassa namnlister och kanter för fönster
Comment[uk]=Налаштовування смужок заголовків та рамок вікон
Comment[x-test]=xxConfigure window titlebars and bordersxx
Comment[zh_CN]=配置窗口标题栏和边框
Comment[zh_TW]=設定視窗的標題列和邊框
diff --git a/kcmkwin/kwindesktop/kcm_kwin_virtualdesktops.desktop b/kcmkwin/kwindesktop/kcm_kwin_virtualdesktops.desktop
index 933905a5d..be78187d4 100644
--- a/kcmkwin/kwindesktop/kcm_kwin_virtualdesktops.desktop
+++ b/kcmkwin/kwindesktop/kcm_kwin_virtualdesktops.desktop
@@ -1,151 +1,152 @@
[Desktop Entry]
Exec=kcmshell5 kcm_kwin_virtualdesktops
Icon=preferences-desktop-virtual
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kcontrol/kwin_virtualdesktops/index.html
X-KDE-Library=kcm_kwin_virtualdesktops
X-KDE-ParentApp=kcontrol
X-KDE-FormFactors=desktop
X-KDE-System-Settings-Parent-Category=desktopbehavior
X-KDE-Weight=60
Name=Virtual Desktops
Name[ar]=أسطح المكتب الافتراضية
Name[ast]=Escritorios virtuales
Name[bg]=Виртуални работни плотове
Name[bs]=Virtuelne površi
Name[ca]=Escriptoris virtuals
Name[ca@valencia]=Escriptoris virtuals
Name[cs]=Virtuální plochy
Name[da]=Virtuelle skriveborde
Name[de]=Virtuelle Arbeitsflächen
Name[el]=Εικονικές επιφάνειες εργασίες
Name[en_GB]=Virtual Desktops
Name[es]=Escritorios virtuales
Name[et]=Virtuaalsed töölauad
Name[eu]=Alegiazko mahaigaina
Name[fi]=Virtuaalityöpöydät
Name[fr]=Bureaux virtuels
Name[ga]=Deasca Fíorúla
Name[gl]=Escritorios virtuais
Name[gu]=વર્ચ્યુઅલ ડેસ્કટોપો
Name[he]=שולחנות עבודה וירטואליים
Name[hi]=आभासी डेस्कटॉप
Name[hr]=Virtualne radne površine
Name[hu]=Virtuális asztalok
Name[ia]=Scriptorios virtual
Name[id]=Desktop Virtual
Name[is]=Sýndarskjáborð
Name[it]=Desktop virtuali
Name[ja]=仮想デスクトップ
Name[kk]=Виртуалды Үстелдер
Name[km]=ផ្ទៃតុនិម្មិត
Name[kn]=ವಾಸ್ತವಪ್ರಾಯ ಗಣಕತೆರೆಗಳು
Name[ko]=가상 바탕 화면
Name[lt]=Virtualūs darbalaukiai
Name[lv]=Virtuālās darbvirsmas
Name[mr]=आभासी डेस्कटॉप
Name[nb]=Virtuelle skrivebord
Name[nds]=Mehr Schriefdischen
Name[nl]=Virtuele bureaubladen
Name[nn]=Virtuelle skrivebord
Name[pa]=ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ
Name[pl]=Pulpity wirtualne
Name[pt]=Ecrãs Virtuais
Name[pt_BR]=Áreas de trabalho virtuais
Name[ro]=Birouri virtuale
Name[ru]=Рабочие столы
Name[si]=අත්ථ්ය වැඩතල
Name[sk]=Virtuálne pracovné plochy
Name[sl]=Navidezna namizja
Name[sr]=Виртуелне површи
Name[sr@ijekavian]=Виртуелне површи
Name[sr@ijekavianlatin]=Virtuelne površi
Name[sr@latin]=Virtuelne površi
Name[sv]=Virtuella skrivbord
Name[th]=พื้นที่ทำงานเสมือน
Name[tr]=Sanal Masaüstleri
Name[ug]=مەۋھۇم ئۈستەلئۈستى
Name[uk]=Віртуальні стільниці
Name[wa]=Forveyous scribannes
Name[x-test]=xxVirtual Desktopsxx
Name[zh_CN]=虚拟桌面
Name[zh_TW]=虛擬桌面
Comment=Configure navigation, number and layout of virtual desktops
Comment[ca]=Configura la navegació, el nombre i la disposició dels escriptoris virtuals
Comment[da]=Indstil navigation, antal og layout af virtuelle skriveborde
Comment[de]=Navigation, Anzahl und Layout virtueller Arbeitsflächen einrichten
Comment[en_GB]=Configure navigation, number and layout of virtual desktops
Comment[es]=Configurar la navegación, número y disposición de los escritorios virtuales
Comment[et]=Virtuaalsete töölaudade vahel liikumise, nende arvu ja paigutuse seadistamine
Comment[eu]=Konfiguratu nabigatzea, alegiazko mahaigainen kopurua eta antolamendua
Comment[fi]=Aseta virtuaalityöpöytien määrä, asettelu ja niiden välillä siirtyminen
Comment[fr]=Configurer la navigation, le nombre et la disposition des bureaux virtuels
Comment[gl]=Configurar a navegación, cantidade e disposición dos escritorios virtuais
Comment[ia]=Configura navigation, numero e disposition de scriptorios virtual
Comment[id]=Konfigurasikan navigasi, nomor dan tataletak desktop virtual
Comment[it]=Configura navigazione, numero e disposizione dei desktop virtuali
Comment[ko]=가상 바탕 화면 탐색, 개수, 레이아웃 설정
Comment[lt]=Konfigūruoti virtualių darbalaukių naršymą, skaičių ir išdėstymą
Comment[nl]=Navigatie, aantal en indeling van virtuele bureaubladen configureren
Comment[nn]=Set opp navigering, nummer og vising av virtuelle skrivebord
Comment[pl]=Ustawienia poruszania się, liczby oraz układu wirtualnych klawiatur
Comment[pt]=Configura a navegação, número e disposição dos ecrãs virtuais
Comment[pt_BR]=Configura a navegação, quantidade e layout das áreas de trabalho virtuais
Comment[ru]=Число, расположение и способ переключения рабочих столов
Comment[sk]=Nastaviť navigáciu, počet a rozloženie virtuálnych plôch
+Comment[sl]=Nastavi krmarjenje, število in razporeditev navideznih namizij
Comment[sv]=Anpassa navigering, antal och layout av virtuella skrivbord
Comment[uk]=Налаштовування навігації, кількості та компонування віртуальних стільниць
Comment[x-test]=xxConfigure navigation, number and layout of virtual desktopsxx
Comment[zh_CN]=配置虚拟桌面的导航,数目和布局
Comment[zh_TW]=設定虛擬桌面的導覽、數字與佈局
X-KDE-Keywords=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings
X-KDE-Keywords[bs]=pozadina,pozadine,broj,virtuelna pozadina,višestruka pozadina,pejdžer,dodatak pejdžeru,aplet pejdžer,pejdžer postavke
X-KDE-Keywords[ca]=escriptori,escriptoris,nombre,escriptori virtual,múltiples escriptoris,paginador,estri paginador,miniaplicació de paginació,arranjament del paginador
X-KDE-Keywords[ca@valencia]=escriptori,escriptoris,nombre,escriptori virtual,escriptoris múltiples,paginador,estri paginador,miniaplicació de paginació,arranjament de paginador
X-KDE-Keywords[da]=skrivebord,skriveborde,desktop,desktops,virtuelt skrivebord,flere skriveborde,spaces,pager,skrivebordsvælger,pager widget,pager applet
X-KDE-Keywords[de]=Arbeitsfläche,Arbeitsflächen,Desktop,Anzahl,Virtuelle Arbeitsfläche,Mehrere Arbeitsflächen,Arbeitsflächenumschalter,Arbeitsflächenumschalter-Bedienelement,Arbeitsflächenumschalter-Miniprogramm,Arbeitsflächenumschalter-Einstellungen
X-KDE-Keywords[el]=επιφάνεια εργασίας,επιφάνειες εργασίας,αριθμός,εικονική επιφάνεια εργασίας,πολλαπλές επιφάνειες εργασίας,χαρτί,γραφικό συστατικό χαρτιού,μικροεφαρμογή χαρτιού,ρυθμίσεις χαρτιού
X-KDE-Keywords[en_GB]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings
X-KDE-Keywords[es]=escritorio,escritorios,número,escritorio virtual,múltiples escritorios,paginador,control de paginación,miniaplicación del paginador,preferencias del paginador
X-KDE-Keywords[et]=töölaud,töölauad,arv,virtuaalne töölaud,mitu töölauda,töölauavahetaja,töölaudade vahetaja,töölauavahetaja aplett,töölauavahetaja vidin,töölauavahetaja seadistused
X-KDE-Keywords[eu]=mahaigain,mahaigainak,kopuru,mahaigain birtuala,alegiazko mahaigaina,hainbat mahaigain,bilagailu,bilagailuaren trepeta,bilagailuaren miniaplikazioa,bilagailuaren ezarpenak
X-KDE-Keywords[fi]=työpöytä,työpöydät,lukumäärä,virtuaalityöpöytä,monta työpöytää,sivutin,sivutinsovelma,sivuttimen asetukset
X-KDE-Keywords[fr]=bureau, bureaux, numéro, bureau virtuel, bureaux multiples, gestionnaire de bureau, composant graphique du gestionnaire de bureau, paramètres du gestionnaire de bureaux
X-KDE-Keywords[gl]=escritorio,escritorios,número,escritorio virtual,escritorios múltiplos,paxinador, trebello paxinador, miniaplicativo paxinador,configuración do paxinador
X-KDE-Keywords[hu]=asztal,asztalok,szám,virtuális asztal,több asztal,papír,papír felületi elem,papír kisalkalmazás,papírbeállítások
X-KDE-Keywords[ia]=scriptorio,scriptorios,numero,scriptorio virtual,scriptorio multiple,pager, widget de pager, applet de pager, preferentias de pager
X-KDE-Keywords[id]=desktop,desktop,jumlah,desktop virtual,banyak desktop,halaman,widget halaman,applet halaman,pengaturan halaman
X-KDE-Keywords[it]=desktop,numero,desktop virtuali,desktop multipli,cambiadesktop,oggetto cambiadesktop,applet cambiadesktop,impostazioni del cambiadesktop
X-KDE-Keywords[kk]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings
X-KDE-Keywords[km]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings
X-KDE-Keywords[ko]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,데스크톱,가상 데스크톱,다중 데스크톱,바탕 화면,가상 바탕 화면,다중 바탕 화면
X-KDE-Keywords[lt]=darbalaukis,darbastalis,darbalaukiai,darbastaliai,skaičius,numeris,numeriai,skaičiai,skaicius,skaiciai,virtualus darbalaukis,virtualūs darbalaukiai,virtualus darbalaukiai,keli darbalaukiai,keletas darbalaukių,keletas darbalaukiu,puslapiuotojas,perjungiklis,perjungiklio valdiklis,perjungiklio programėlė,perjungiklio programele,perjungiklio nuostatos,perjungiklio nustatymai
X-KDE-Keywords[nb]=skrivebord,antall,virtuelt skrivebord,flere skrivebord,veksler,vekslerelement,veksler-miniprogram,vekslerinnstillinger
X-KDE-Keywords[nds]=Schriefdisch,Schriefdischen,virtuell,mehr,Schriefdisch-Översicht,instellen
X-KDE-Keywords[nl]=bureaublad,bureaubladen,aantal,virtueel bureaublad,meervoudige bureaubladen,pager,pager-widget,pager-applet,pagerinstellingen
X-KDE-Keywords[nn]=skrivebord,mengd,tal,virtuelt skrivebord,fleire skrivebord,vekslar,vekslarelement,vekslarelement,vekslerinnstillinger,vekslaroppsett
X-KDE-Keywords[pa]=ਡੈਸਕਟਾਪ,ਗਿਣਤੀ,ਨੰਬਰ,ਅੰਕ,ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ,ਕਈ ਡੈਸਕਟਾਪ,ਪੇਜ਼ਰ,ਪੇਜ਼ਰ ਵਿਜੈਟ,ਪੇਜ਼ਰ ਐਪਲਿਟ,ਪੇਜ਼ਰ ਸੈਟਿੰਗਾਂ
X-KDE-Keywords[pl]=pulpit,pulpity,liczba,pulpity wirtualne,wiele pulpitów
X-KDE-Keywords[pt]=ecrã,ecrãs,número,ecrã virtual,múltiplos ecrãs,paginador,elemento paginador,'applet' do paginador,configuração do paginador
X-KDE-Keywords[pt_BR]=área de trabalho,áreas de trabalho,desktop,desktops,número,área de trabalho virtual,múltiplas áreas de trabalho,paginador,elemento paginador,miniaplicativo do paginador,configurações do paginador
X-KDE-Keywords[ru]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,рабочий стол,рабочие столы,число,виртуальный рабочий стол,несколько рабочих столов,переключатель,переключение,виджет переключения,аплет переключения,параметры переключения,настройки переключения
X-KDE-Keywords[sk]=plocha,plochy,číslo,virtuálna plocha,viac plôch,pager,widget pagera,applet pagera,nastavenia pagera
X-KDE-Keywords[sl]=namizje,namizja,število namizij,navidezna namizja,več namizij,pozivnik
X-KDE-Keywords[sr]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,површ,број,виртуелна површ,више површи,листач,виџет листача,аплет листача,поставке листача
X-KDE-Keywords[sr@ijekavian]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,површ,број,виртуелна површ,више површи,листач,виџет листача,аплет листача,поставке листача
X-KDE-Keywords[sr@ijekavianlatin]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,površ,broj,virtuelna površ,više površi,listač,vidžet listača,aplet listača,postavke listača
X-KDE-Keywords[sr@latin]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,površ,broj,virtuelna površ,više površi,listač,vidžet listača,aplet listača,postavke listača
X-KDE-Keywords[sv]=skrivbord,antal,virtuellt skrivbord,flera skrivbord,skrivbordsvisning,visningskomponent,visningsminiprogram,visningsinställningar
X-KDE-Keywords[tr]=masaüstü,masaüstleri,sayı,sanal masaüstü,çoklu masaüstü,sayfalayıcı,sayfalayıcı gereci,sayfalayıcı gereci,sayfalayıcı ayarları
X-KDE-Keywords[uk]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,стільниця,стільниці,кількість,віртуальна стільниця,перемикач,пейджер,віджет перемикача,віджет пейджера,аплет перемикання,аплет перемикача,параметри перемикання,параметри перемикача
X-KDE-Keywords[x-test]=xxdesktopxx,xxdesktopsxx,xxnumberxx,xxvirtual desktopxx,xxmultiple desktopsxx,xxpagerxx,xxpager widgetxx,xxpager appletxx,xxpager settingsxx
X-KDE-Keywords[zh_CN]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings,桌面,虚拟桌面,多桌面,分页,分页器,分页器组件,分页器设置
X-KDE-Keywords[zh_TW]=desktop,desktops,number,virtual desktop,multiple desktops,pager,pager widget,pager applet,pager settings
Categories=Qt;KDE;X-KDE-settings-translations;
diff --git a/kcmkwin/kwindesktop/package/contents/ui/main.qml b/kcmkwin/kwindesktop/package/contents/ui/main.qml
index 5e0f39b26..770bc22d6 100644
--- a/kcmkwin/kwindesktop/package/contents/ui/main.qml
+++ b/kcmkwin/kwindesktop/package/contents/ui/main.qml
@@ -1,276 +1,277 @@
/*
* Copyright (C) 2018 Eike Hein
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
import QtQuick 2.5
import QtQuick.Controls 2.5 as QQC2
import QtQuick.Layouts 1.1
import org.kde.kcm 1.2
import org.kde.kirigami 2.10 as Kirigami
import org.kde.plasma.core 2.1 as PlasmaCore
ScrollViewKCM {
id: root
ConfigModule.quickHelp: i18n("This module lets you configure the navigation, number and layout of virtual desktops.")
Connections {
target: kcm.desktopsModel
onReadyChanged: {
rowsSpinBox.value = kcm.desktopsModel.rows;
}
onRowsChanged: {
rowsSpinBox.value = kcm.desktopsModel.rows;
}
}
implicitWidth: Kirigami.Units.gridUnit * 35
implicitHeight: Kirigami.Units.gridUnit * 30
Component {
id: desktopsListItemComponent
Kirigami.SwipeListItem {
id: listItem
contentItem: RowLayout {
QQC2.TextField {
id: nameField
background: null
leftPadding: Kirigami.Units.largeSpacing
topPadding: 0
bottomPadding: 0
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
text: model.display
readOnly: true
onEditingFinished: {
readOnly = true;
Qt.callLater(kcm.desktopsModel.setDesktopName, model.Id, text);
}
}
}
actions: [
Kirigami.Action {
enabled: !model.IsMissing
iconName: "edit-rename"
tooltip: i18nc("@info:tooltip", "Rename")
onTriggered: {
nameField.readOnly = false;
nameField.selectAll();
nameField.forceActiveFocus();
}
},
Kirigami.Action {
enabled: !model.IsMissing
iconName: "edit-delete-remove"
tooltip: i18nc("@info:tooltip", "Remove")
onTriggered: kcm.desktopsModel.removeDesktop(model.Id)
}]
}
}
header: ColumnLayout {
id: messagesLayout
spacing: Kirigami.Units.largeSpacing
Kirigami.InlineMessage {
Layout.fillWidth: true
type: Kirigami.MessageType.Error
text: kcm.desktopsModel.error
visible: kcm.desktopsModel.error != ""
}
Kirigami.InlineMessage {
Layout.fillWidth: true
type: Kirigami.MessageType.Information
text: i18n("Virtual desktops have been changed outside this settings application. Saving now will overwrite the changes.")
visible: kcm.desktopsModel.serverModified
}
}
view: ListView {
id: desktopsList
model: kcm.desktopsModel.ready ? kcm.desktopsModel : null
section.property: "DesktopRow"
section.delegate: Kirigami.ListSectionHeader {
width: desktopsList.width
label: i18n("Row %1", section)
}
delegate: Kirigami.DelegateRecycler {
width: desktopsList.width
sourceComponent: desktopsListItemComponent
}
}
footer: ColumnLayout {
RowLayout {
QQC2.Button {
text: i18nc("@action:button", "Add")
icon.name: "list-add"
onClicked: kcm.desktopsModel.createDesktop(i18n("New Desktop"))
}
Item { // Spacer
Layout.fillWidth: true
}
QQC2.SpinBox {
id: rowsSpinBox
from: 1
to: 20
editable: true
textFromValue: function(value, locale) { return i18np("1 Row", "%1 Rows", value)}
+ valueFromText: function(text, locale) { return parseInt(text, 10); }
onValueModified: kcm.desktopsModel.rows = value
}
}
Kirigami.FormLayout {
QQC2.CheckBox {
id: navWraps
Kirigami.FormData.label: i18n("Options:")
text: i18n("Navigation wraps around")
enabled: !kcm.virtualDesktopsSettings.isImmutable("rollOverDesktops")
checked: kcm.virtualDesktopsSettings.rollOverDesktops
onToggled: kcm.virtualDesktopsSettings.rollOverDesktops = checked
}
RowLayout {
Layout.fillWidth: true
QQC2.CheckBox {
id: animationEnabled
// Let it elide but don't make it push the ComboBox away from it
Layout.fillWidth: true
Layout.maximumWidth: implicitWidth
text: i18n("Show animation when switching:")
checked: kcm.animationsModel.enabled
onToggled: kcm.animationsModel.enabled = checked
}
QQC2.ComboBox {
enabled: animationEnabled.checked
model: kcm.animationsModel
textRole: "NameRole"
currentIndex: kcm.animationsModel.currentIndex
onActivated: kcm.animationsModel.currentIndex = currentIndex
}
QQC2.Button {
enabled: animationEnabled.checked && kcm.animationsModel.currentConfigurable
icon.name: "configure"
onClicked: kcm.configureAnimation()
}
QQC2.Button {
enabled: animationEnabled.checked
icon.name: "dialog-information"
onClicked: kcm.showAboutAnimation()
}
Item {
Layout.fillWidth: true
}
}
RowLayout {
Layout.fillWidth: true
QQC2.CheckBox {
id: osdEnabled
text: i18n("Show on-screen display when switching:")
enabled: !kcm.virtualDesktopsSettings.isImmutable("desktopChangeOsdEnabled")
checked: kcm.virtualDesktopsSettings.desktopChangeOsdEnabled
onToggled: kcm.virtualDesktopsSettings.desktopChangeOsdEnabled = checked
}
QQC2.SpinBox {
id: osdDuration
enabled: osdEnabled.checked && !kcm.virtualDesktopsSettings.isImmutable("popupHideDelay")
from: 0
to: 10000
stepSize: 100
textFromValue: function(value, locale) { return i18n("%1 ms", value)}
value: kcm.virtualDesktopsSettings.popupHideDelay
onValueModified: kcm.virtualDesktopsSettings.popupHideDelay = value
}
}
RowLayout {
Layout.fillWidth: true
Item {
width: units.largeSpacing
}
QQC2.CheckBox {
id: osdTextOnly
enabled: osdEnabled.checked && !kcm.virtualDesktopsSettings.isImmutable("textOnly")
text: i18n("Show desktop layout indicators")
checked: !kcm.virtualDesktopsSettings.textOnly
onToggled: kcm.virtualDesktopsSettings.textOnly = !checked
}
}
}
}
}
diff --git a/kcmkwin/kwindesktop/package/metadata.desktop b/kcmkwin/kwindesktop/package/metadata.desktop
index e7e3fc7d3..75f4c2c5c 100644
--- a/kcmkwin/kwindesktop/package/metadata.desktop
+++ b/kcmkwin/kwindesktop/package/metadata.desktop
@@ -1,102 +1,103 @@
[Desktop Entry]
Name=Virtual Desktops
Name[ar]=أسطح المكتب الافتراضية
Name[ast]=Escritorios virtuales
Name[bg]=Виртуални работни плотове
Name[bs]=Virtuelne površi
Name[ca]=Escriptoris virtuals
Name[ca@valencia]=Escriptoris virtuals
Name[cs]=Virtuální plochy
Name[da]=Virtuelle skriveborde
Name[de]=Virtuelle Arbeitsflächen
Name[el]=Εικονικές επιφάνειες εργασίες
Name[en_GB]=Virtual Desktops
Name[es]=Escritorios virtuales
Name[et]=Virtuaalsed töölauad
Name[eu]=Alegiazko mahaigaina
Name[fi]=Virtuaalityöpöydät
Name[fr]=Bureaux virtuels
Name[ga]=Deasca Fíorúla
Name[gl]=Escritorios virtuais
Name[gu]=વર્ચ્યુઅલ ડેસ્કટોપો
Name[he]=שולחנות עבודה וירטואליים
Name[hi]=आभासी डेस्कटॉप
Name[hr]=Virtualne radne površine
Name[hu]=Virtuális asztalok
Name[ia]=Scriptorios virtual
Name[id]=Desktop Virtual
Name[is]=Sýndarskjáborð
Name[it]=Desktop virtuali
Name[ja]=仮想デスクトップ
Name[kk]=Виртуалды Үстелдер
Name[km]=ផ្ទៃតុនិម្មិត
Name[kn]=ವಾಸ್ತವಪ್ರಾಯ ಗಣಕತೆರೆಗಳು
Name[ko]=가상 바탕 화면
Name[lt]=Virtualūs darbalaukiai
Name[lv]=Virtuālās darbvirsmas
Name[mr]=आभासी डेस्कटॉप
Name[nb]=Virtuelle skrivebord
Name[nds]=Mehr Schriefdischen
Name[nl]=Virtuele bureaubladen
Name[nn]=Virtuelle skrivebord
Name[pa]=ਵਰਚੁਅਲ ਡੈਸਕਟਾਪ
Name[pl]=Pulpity wirtualne
Name[pt]=Ecrãs Virtuais
Name[pt_BR]=Áreas de trabalho virtuais
Name[ro]=Birouri virtuale
Name[ru]=Рабочие столы
Name[si]=අත්ථ්ය වැඩතල
Name[sk]=Virtuálne pracovné plochy
Name[sl]=Navidezna namizja
Name[sr]=Виртуелне површи
Name[sr@ijekavian]=Виртуелне површи
Name[sr@ijekavianlatin]=Virtuelne površi
Name[sr@latin]=Virtuelne površi
Name[sv]=Virtuella skrivbord
Name[th]=พื้นที่ทำงานเสมือน
Name[tr]=Sanal Masaüstleri
Name[ug]=مەۋھۇم ئۈستەلئۈستى
Name[uk]=Віртуальні стільниці
Name[wa]=Forveyous scribannes
Name[x-test]=xxVirtual Desktopsxx
Name[zh_CN]=虚拟桌面
Name[zh_TW]=虛擬桌面
Comment=Configure navigation, number and layout of virtual desktops
Comment[ca]=Configura la navegació, el nombre i la disposició dels escriptoris virtuals
Comment[da]=Indstil navigation, antal og layout af virtuelle skriveborde
Comment[de]=Navigation, Anzahl und Layout virtueller Arbeitsflächen einrichten
Comment[en_GB]=Configure navigation, number and layout of virtual desktops
Comment[es]=Configurar la navegación, número y disposición de los escritorios virtuales
Comment[et]=Virtuaalsete töölaudade vahel liikumise, nende arvu ja paigutuse seadistamine
Comment[eu]=Konfiguratu nabigatzea, alegiazko mahaigainen kopurua eta antolamendua
Comment[fi]=Aseta virtuaalityöpöytien määrä, asettelu ja niiden välillä siirtyminen
Comment[fr]=Configurer la navigation, le nombre et la disposition des bureaux virtuels
Comment[gl]=Configurar a navegación, cantidade e disposición dos escritorios virtuais
Comment[ia]=Configura navigation, numero e disposition de scriptorios virtual
Comment[id]=Konfigurasikan navigasi, nomor dan tataletak desktop virtual
Comment[it]=Configura navigazione, numero e disposizione dei desktop virtuali
Comment[ko]=가상 바탕 화면 탐색, 개수, 레이아웃 설정
Comment[lt]=Konfigūruoti virtualių darbalaukių naršymą, skaičių ir išdėstymą
Comment[nl]=Navigatie, aantal en indeling van virtuele bureaubladen configureren
Comment[nn]=Set opp navigering, nummer og vising av virtuelle skrivebord
Comment[pl]=Ustawienia poruszania się, liczby oraz układu wirtualnych klawiatur
Comment[pt]=Configura a navegação, número e disposição dos ecrãs virtuais
Comment[pt_BR]=Configura a navegação, quantidade e layout das áreas de trabalho virtuais
Comment[ru]=Число, расположение и способ переключения рабочих столов
Comment[sk]=Nastaviť navigáciu, počet a rozloženie virtuálnych plôch
+Comment[sl]=Nastavi krmarjenje, število in razporeditev navideznih namizij
Comment[sv]=Anpassa navigering, antal och layout av virtuella skrivbord
Comment[uk]=Налаштовування навігації, кількості та компонування віртуальних стільниць
Comment[x-test]=xxConfigure navigation, number and layout of virtual desktopsxx
Comment[zh_CN]=配置虚拟桌面的导航,数目和布局
Comment[zh_TW]=設定虛擬桌面的導覽、數字與佈局
Icon=preferences-desktop
Type=Service
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Name=kcm_kwin_virtualdesktops
X-KDE-ServiceTypes=Plasma/Generic
X-Plasma-API=declarativeappletscript
X-KDE-FormFactors=desktop
X-Plasma-MainScript=ui/main.qml
diff --git a/kcmkwin/kwineffects/kcm_kwin_effects.desktop b/kcmkwin/kwineffects/kcm_kwin_effects.desktop
index ee78f454f..36804d58a 100644
--- a/kcmkwin/kwineffects/kcm_kwin_effects.desktop
+++ b/kcmkwin/kwineffects/kcm_kwin_effects.desktop
@@ -1,122 +1,124 @@
[Desktop Entry]
Exec=kcmshell5 kcm_kwin_effects
Icon=preferences-desktop-effects
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kcontrol/kwineffects/index.html
X-KDE-Library=kcm_kwin_effects
X-KDE-PluginKeyword=effects
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=desktopbehavior
X-KDE-Weight=50
X-KDE-FormFactors=desktop,tablet
Name=Desktop Effects
Name[bs]=Efekti površi
Name[ca]=Efectes de l'escriptori
Name[ca@valencia]=Efectes d'escriptori
Name[cs]=Efekty na ploše
Name[da]=Skrivebordseffekter
Name[de]=Arbeitsflächen-Effekte
Name[el]=Εφέ επιφάνειας εργασίας
Name[en_GB]=Desktop Effects
Name[es]=Efectos del escritorio
Name[et]=Töölauaefektid
Name[eu]=Mahaigaineko efektuak
Name[fi]=Työpöytätehosteet
Name[fr]=Effets de bureau
Name[gl]=Efectos do escritorio
Name[he]=הנפשות שולחן עבודה
Name[hu]=Asztali effektusok
Name[ia]=Effectos de scriptorio
Name[id]=Efek Desktop
Name[it]=Effetti del desktop
Name[ja]=デスクトップ効果
Name[ko]=데스크톱 효과
Name[lt]=Darbalaukio efektai
Name[nb]=Skrivebordseffekter
Name[nds]=Schriefdischeffekten
Name[nl]=Bureaubladeffecten
Name[nn]=Skrivebordseffektar
Name[pa]=ਡੈਸਕਟਾਪ ਪਰਭਾਵ
Name[pl]=Efekty pulpitu
Name[pt]=Efeitos do Ecrã
Name[pt_BR]=Efeitos da área de trabalho
Name[ro]=Efecte de birou
Name[ru]=Эффекты
Name[se]=Čállinbeavdeeffeavttat
Name[sk]=Efekty plochy
Name[sl]=Učinki namizja
Name[sr]=Ефекти површи
Name[sr@ijekavian]=Ефекти површи
Name[sr@ijekavianlatin]=Efekti površi
Name[sr@latin]=Efekti površi
Name[sv]=Skrivbordseffekter
Name[tg]=Таъсирҳои мизи корӣ
Name[tr]=Masaüstü Efektleri
Name[uk]=Ефекти стільниці
Name[x-test]=xxDesktop Effectsxx
Name[zh_CN]=桌面特效
Name[zh_TW]=桌面效果
Comment=Configure compositor settings for desktop effects
Comment[ca]=Configura l'arranjament del compositor per als efectes de l'escriptori
Comment[cs]=Nastavení kompozitoru pro efekty pracovní plochy
Comment[da]=Compositor-indstillinger til skrivebordseffekter
Comment[de]=Compositor-Einstellungen für Arbeitsflächen-Effekte einrichten
Comment[en_GB]=Configure compositor settings for desktop effects
Comment[es]=Configurar las preferencias del compositor para los efectos del escritorio
Comment[et]=Komposiitori seadistamine töölauaefektide tarbeks
Comment[eu]=Konfiguratu konposatzailearen ezarpenak mahaigaineko efektuetarako
Comment[fi]=Koostimen asetukset työpöytätehosteille
Comment[fr]=Configurer les paramètres du compositeur pour les effets de bureau
Comment[gl]=Configurar o compositor para os efectos de escritorio
Comment[ia]=Configura preferentias de compositor pro le effectos de scriptorio
Comment[id]=Konfigurasikan pengaturan kompositor untuk efek desktop
Comment[it]=Configura impostazioni del compositore per gli effetti del desktop
Comment[ko]=데스크톱 효과에 사용되는 컴포지터 설정
Comment[lt]=Konfigūruoti darbalaukio efektų kompozitoriaus nuostatas
Comment[nl]=Instellingen van compositor configureren voor bureaubladeffecten
Comment[nn]=Samansetjarinnstillingar for skrivebordseffektar
Comment[pl]=Ustawienia kompozytora dla efektów pulpitu
Comment[pt]=Configuração do compositor para os efeitos do ecrã
Comment[pt_BR]=Defina as configurações do compositor para os efeitos da área de trabalho
Comment[ru]=Настройка движка эффектов рабочего стола
Comment[sk]=Nastavenia kompozítora pre efekty plochy
+Comment[sl]=Nastavitve upravljalnika skladnje za učinke namizja
Comment[sv]=Anpassa sammansättningsinställningar för skrivbordseffekter
Comment[uk]=Налаштовування параметрів засобу композиції для ефектів стільниці
Comment[x-test]=xxConfigure compositor settings for desktop effectsxx
Comment[zh_CN]=配置桌面特效混成器设置
Comment[zh_TW]=設定桌面特效的合成器設定
X-KDE-Keywords=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale effect,screenshot effect,sheet effect,slide effect,sliding popups effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,present windows effect,resize window effect,background contrast effect
X-KDE-Keywords[ca]=kwin,finestra,gestor,efecte,efectes 3D,efectes 2D,efectes gràfics,efectes d'escriptori,animacions,animacions diverses,efectes en la gestió de les finestres,efecte en el canvi de finestra,efecte en el canvi d'escriptori,animacions,animacions a l'escriptori,controladors,configuració dels controladors,renderització,render,efecte d'inversió,efecte d'aspecte de vidre,efecte de lupa,efecte ajudant del desplaçament,efecte de seguiment del ratolí,efecte de zoom,efecte de difuminat,efecte d'esvaïment,efecte d'esvaïment de l'escriptori,efecte de trencament,efecte de lliscament,efecte de ressaltat de la finestra,efecte en l'inici de la sessió,efecte en sortir de la sessió,efecte de làmpada màgica,efecte d'animació de la minimització,efecte de marca del ratolí,efecte d'apropament,efecte de captura de la pantalla,efecte de full,efecte de diapositiva,efecte de missatges emergents lliscants,efecte de miniatures laterals,translucidesa,efecte de translucidesa,transparència,efecte de geometria de la finestra,efecte de finestres sacsejades,efecte de confirmació d'engegada,efecte de diàleg principal,efecte d'enfosquiment en estar inactiu,efecte d'enfosquiment de la pantalla,efecte de diapositiva prèvia,decoració,efecte per a mostrar els FPS,efecte de mostrar el pintat,efecte de canvi de coberta,efecte de cub de l'escriptori,efecte d'animació del cub de l'escriptori,efecte de quadrícula de l'escriptori,efecte de canvi en roda,efecte de presentació de les finestres,efecte de redimensionat de la finestra,efecte de contrast del fons
X-KDE-Keywords[ca@valencia]=kwin,finestra,gestor,efecte,efectes 3D,efectes 2D,efectes gràfics,efectes d'escriptori,animacions,animacions diverses,efectes en la gestió de les finestres,efecte en el canvi de finestra,efecte en el canvi d'escriptori,animacions,animacions en l'escriptori,controladors,configuració dels controladors,renderització,render,efecte d'inversió,efecte d'aspecte de vidre,efecte de lupa,efecte ajudant del desplaçament,efecte de seguiment del ratolí,efecte de zoom,efecte de difuminat,efecte de fosa,efecte de fosa de l'escriptori,efecte de trencament,efecte de lliscament,efecte de ressaltat de la finestra,efecte en l'inici de la sessió,efecte en eixir de la sessió,efecte de làmpada màgica,efecte d'animació de la minimització,efecte de marca del ratolí,efecte d'apropament,efecte de captura de pantalla,efecte de full,efecte de diapositiva,efecte de missatges emergents lliscants,efecte de miniatures laterals,translucidesa,efecte de translucidesa,transparència,efecte de geometria de la finestra,efecte de finestres sacsejades,efecte de retroacció d'inici,efecte de diàleg principal,efecte d'enfosquiment en estar inactiu,efecte d'enfosquiment de la pantalla,efecte de diapositiva prèvia,decoració,efecte per a mostrar els FPS,efecte per a mostrar les zones pintades,efecte de canvi de coberta,efecte de cub de l'escriptori,efecte d'animació del cub de l'escriptori,efecte de graella de l'escriptori,efecte de canvi en roda,efecte de presentació de les finestres,efecte de redimensionat de la finestra,efecte de contrast del fons
X-KDE-Keywords[da]=kwin,vindue,vindueshåndtering,effekter,3D-effekter,2D-effekter,grafiske effekter,skrivebordseffekter,animationer,diverse animationer,vindueshåndteringseffekter,effekt til skift af vinduer,effekt til skrivebordsskift,skrivebordsanimationer,drivere,driverindstillinger,rendering,render,invertereffect,kikkerteffekt,forstørrelsesglaseffekt,hægtehjælpereffekt,følg musen-effekt,zoomeffect,sløreffekt,fade-effect,svæve-effect,fremhæv vindue-effekt,login-effekt,log ud-effekt,magisk lampe-effekt,minimer-effekt,musemærke-effekt,skalerind-effekt,skærmbillede-effekt,glide-effekt,glidende pop-op-effekt,gennemsigtighed,transparens,ugennemsigtighed,vinduesgeometri-effekt,wobbly,blævrende vinduer,eye candy,øjeguf,vis FPS-effekt,cube,terning,gitter,baggrundskontrast-effekt
X-KDE-Keywords[de]=KWin,Fenster,Verwaltung,Effekt,2D-Effekte,3D-Effekte,Grafische Effekte,Desktopeffekte,Arbeitsflächeneffekte,Animation,Fensterverwaltungs-Effekte,Fensterwechsel-Effekte,Desktop-Wechsel,Arbeitsflächenwechsel,Desktop-Animation,Arbeitsflächen-Animation,Treiber,Treibereinstellung,Rendering,Rendern,Invertierungseffekt,Bildschirmlupeneffekt,Vergrößerungseffekt,Einrasteffekt,Maus folgen,Zoomeffekt,Dashboard,Überblendungseffekt,Gleiteneffekt,Fensterhervorhebungs-Effekt,Anmeldungseffekt,Abmeldungseffekt,Animierter Minimierungseffekt,Mausmarkierungseffekt,Skalierungseffekt,Bildschirmeffekt,Blatteffekt,Folieneffekt,Vorschaueffekt,Durchsichtigkeit,Durchsichtigkeitseffekt,Fenstergeometrieffekt,Effekt Wabernde Fenster,Programmstartanzeigeneffekt,Inaktiveffekt,Bildschirmabdunkelungseffekt,FPS-Effekt,Zeichnungsbereicheffekt, 3D-Fenstergalerieeffekt,Desktopgittereffekt,3D-Fensterstapelumschalteffekt,Fensteranzeigeeffekt,Fenstergrößenänderungseffekt,Hintergrundkonstrasteffekt
X-KDE-Keywords[en_GB]=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale effect,screenshot effect,sheet effect,slide effect,sliding popups effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,present windows effect,resize window effect,background contrast effect
X-KDE-Keywords[es]=kwin,ventana,gestor,efecto,efectos 3D,efectos 2D,efectos gráficos,efectos del escritorio,animaciones,animaciones diversas,efectos de la gestión de ventanas,efecto de cambio de ventana,efecto de cambio de escritorio,animaciones,animaciones del escritorio,controladores,preferencias del controlador,renderización,renderizar,efecto de inversión,efecto de espejo,efecto de lupa,efecto auxiliar de instantánea,efecto de seguimiento del ratón,efecto de ampliación,efecto borroso,efecto de desvanecimiento,efecto de desvanecimiento del escritorio,efecto de romper en pedazos,efecto de planeo,efecto de resaltar ventanas,efecto de inicio de sesión,efecto de final de sesión,efecto de lámpara mágica,efecto de animación al minimizar,efecto de marcas del ratón,efecto de escalado,efecto de captura de pantalla,efecto de hoja,efecto de deslizamiento,efecto de ventanas emergentes deslizantes,efecto de miniaturas laterales,transparencia,efecto de transparencia,efecto de geometría de las ventanas, efecto de ventanas gelatinosas,efecto de notificación de inicio,efecto de padre de la ventana,efecto de oscurecer inactiva,efecto de oscurecer la pantalla,efecto atrás,efectos atractivos,efecto de mostrar FPS,efecto de mostrar pintura,efecto de selección de ventana en modo carátula,efecto de cubo del escritorio,efecto de animación del cubo del escritorio,efecto de rejilla del escritorio,efecto de selección de ventana en modo cascada,efecto de presentación de ventanas,efecto de cambiar tamaño de las ventanas,efecto de contraste del fondo
X-KDE-Keywords[et]=kwin,aken,hakdur,efekt,3D efektid,ruumilised efektid,2D efektid,graafikaefektid,töölauaefektid,animatsioonid,eri animatsioonid,aknahaldusefektid,akna lülitamise efekt,töölaua lülitamise efekt,animatsioonid,töölauaanimatsioonid,draiverid,draiveri seadistused,renderdamine,renderdus,inverteerimisefekt,pikksilmaefekt,suurendusklaasiefekt,tõmbe abistaja efekt,hiire jälgimise efekt,suurendusefekt,vidinavaate efekt,plahvatuseefekt,hääbumisefekt,töölaua kadumise efekt,lagunemise efekt,liuglemisefekt,akna esiletõstmise efekt,sisselogimisefekt,väljalogimisefekt,maagilise laterna efekt,minimeerimisanimatsiooni efekt,hiirega tähistamise efekt,skaleerimisefekt,ekraanipildi efekt,leheefekt,slaidiefekt,liuglevate hüpikakende efekt,tegumiriba pisipiltide efekt,kõrvalasuvate pisipiltide efekt,läbipaistvus,läbipaistvuseefekt,akende geomeetria efekt,vonklevate akende efekt,käivitamise tagasiside efekt,dialoogi eellase efekt,tuhmi mitteaktiivse efekt,tuhmi ekraani efekt,tagasiliugumise efekt,silmarõõm,FPS-i näitamise efekt,joonistamise näitamise efekt,kastina lülitamise efekt,vaiplülitamise efekt,töölauakuubiku efekt, töölauakuubiku animatsiooni efekt,töölauavõrgustiku efekt,pööramisega lülitamise efekt,kontuuriefekt,aktiivsete akende efekt, akende suuruse muutmise efekt
X-KDE-Keywords[eu]=kwin,leihoa,kudeatzailea,efektua,3D efektuak,2D efektuak,efektu grafikoak,mahaigaineko efektuak,animazioak,hainbat animazio,leiho kudeaketaren efektuak,leiho-aldatze efektuak,mahaigaina aldatzeko efektua,animazioak,mahaigaineko animazioak,gidariak,gidarien ezarpenak,errendatze,errendatu,alderantzikatu efektua,pantaila-lupa efektua,lupa efektua,atxikitze laguntzaile efektua,jarraitu saguari efektua,zoom efektua,lausotze efektua,desagertze efektua,mahaigain-desagertze efektua,puskatze efektua,irristatze efektua,leiho-nabarmentze efektua,saio-haste efektua,saio-ixte efektua,lanpara magiko efektua,minimizatze-animazio efektua, sagu-marka efektua,eskalatze efektua,pantaila-argazki efektua,orrialde efektua,diapositiba efektua,diapositiba gainerakor efektua,koadro txikiak alboan efektua,zeharrargitasuna,zeharrargitasun efektua,gardentasuna,leiho-geometria efektua,leiho dardartsuak efektua,abio berrelikadura efektua,guraso elkarrizketa-koadro efektua,itzaldu ez-aktiboa efektua,itzaldu pantaila efektua,diapositibak atzera efektua,ikusteko atsegina,atsegina,FPS erakuste efektua,erakutsi pintura efektua,azal aldaketa efektua,kubo-mahaigain efektua,kubo-mahaigain animazio efektua,mahaigain-sareta efektua,perspektiban pilatutako aldatze efektua,aurkeztu leihoak efektua,leihoaren neurri-aldatze efektua,atzealdeko kontraste efektua
X-KDE-Keywords[fi]=kwin,ikkuna,hallinta,tehoste,3D-tehosteet,2D-tehosteet,graafiset tehosteet,työpöytätehosteet,animoinnit,eri animoinnit,ikkunanhallintatehosteet,ikkunanvaihtotehoste,työpöydänvaihtotehoste,animoinnit,työpöytäanimoinnit,ajurit,ajuriasetukset,hahmonnus,hahmonna,käänteistehoste,peilitehoste,suurennuslasitehoste,kiinnitysavustajatehoste,hiiren jäljitystehoste,suurennustehoste,sumennustehoste,häivytystehoste,työpöydän häivytystehoste,hajotustehoste,liukutehoste,ikkunan korostustehoste,kirjautumistehoste,uloskirjautumistehoste,taikalampputehoste,pienennyksen animointitehoste,hiiren jälki -tehoste,skaalaustehoste,ruudunkaappaustehoste,sheet effect,liukutehoste,liukuvat ponnahdusikkunat -tehoste,esikatselukuva reunalla -tehoste,läpikuultavuus,läpikuultavuustehoste,läpinäkyvyys,ikkunageometriatehoste,heiluvat ikkunat -tehoste,käynnistyspalautetehoste,kyselyikkunan isäntäikkuna -tehoste,himmennä passiivinen -tehoste,himmennä näyttö -tehoste,liuku taakse -tehoste,silmäkarkki,karkki,näytä FPS -tehoste,näytä näytönpiirto -tehoste,kansivaihtotehoste,työpöytäkuutiotehoste,työpöytäkuutioanimointitehoste,työpöytäruudukkotehoste,kääntövaihtotehoste,näytä ikkunat -tehoste,ikkunan koonmuuttamistehoste,taustakontrastitehoste
X-KDE-Keywords[fr]=kwin, fenêtre, gestionnaire, effet, effets 3D, effets 2D, effets graphiques, effets de bureau, animations, animations variés, effets de gestion des fenêtres, effets de changement de fenêtre, effets de changement de bureau, animations, animation du bureau, pilotes, paramètres du pilote, rendu, rendre, effet d'inversion, effet de verre, effet de loupe, effet d'aide au positionnement, effet de repérage de la souris, effet de zoom, effet de flou, effet de fondu, effet de fondu du bureau, effet d'effondrement, effet de glissement, effet de mise en valeur de la fenêtre, effet de connexion, effet de déconnexion, effet de lampe magique, effet de minimisation de l'application, effet de marque de la souris, effet de gradation, effet de capture d'écran, effet de feuille, effet de glisse, effet d'annotations glissantes, effet vignettes sur le coté, translucidité, effet de translucidité, transparence, effet de géométrie de la fenêtre, effet de fenêtre en gélatine, effet du témoin de démarrage, effet de dialogue parent, effet d'obscurcissement de fenêtre inactive, effet d'obscurcissement du bureau, effet de glissement en arrière, confort visuel, beauté, effet d'affichage du FPS, effet d'affichage des zones peintes, effet de défilement circulaire, effet de bureaux en cube, effet d'animation de cube de bureaux, effet de bureaux en grille, effet d'empilement en perspective, effet de présentation des fenêtres, effet de redimensionnement des fenêtres, effet de contraste du bureau
X-KDE-Keywords[gl]=kwin,window,xanela,manager,xestor,effect,efecto,3D effects,efectos 3D,2D effects,efectos 2D,configuración de vídeo,graphical effects,efectos gráficos,efectos visuais,desktop effects,efectos de escritorio,animations,animacións,various animations,animacións diversas,varias animacións,animacións variadas,window management effects,efectos de xestión de xanelas,window switching effect,efecto de cambio de xanela,desktop switching effect,efecto de cambio de escritorio,animations,animacións,desktop animations,animacións de escritorio,animacións dos escritorios,animacións do escritorio,drivers,controlador,controladores,driver settings,configuración dos controladores,configuración do controlador,rendering,renderización,renderizado,renderizamento,render,renderizar,invert effect,inverter un efecto,inverter efecto,reverter un efecto,reverter efecto,looking glass effect,efecto de lupa,efecto lupa,magnifier effect,snap helper effect,track mouse effect,efecto de seguir o rato,efecto de seguimento do rato,zoom effect,efecto de ampliación,blur effect,efecto borroso,fade effect,efecto de esvaer,fade desktop effect,efecto de esvaer o escritorio,fall apart effect,efecto de destrución,glide effect,efecto de brillo,highlight window effect,efecto de realzar a xanela,efecto de resaltar a xanela,efecto de salientar a xanela,efecto de salientar a xanela,login effect,efecto de acceder,logout effect,efecto de saír,magic lamp effect,efecto de lámpada máxica,minimize animation effect,efecto de minimizar,mouse mark effect,efecto de marca co rato,scale in effect,efecto de achegar,efecto de cambia de escala,screenshot effect,efecto de captura,sheet effect,efecto de folla,slide effect,efecto de dispositiva,sliding popups effect,thumbnail aside effect,translucency,transparencia,translucidez,translucency effect,efecto de translucidez,efecto de transparencia,transparency,transparencia,window geometry effect,efecto de xeometría da xanela,efecto de xeometría das xanelas,wobbly windows effect,efecto de xanelas a tremer,startup feedback effect,dialog parent effect,efecto do pai do diálogo,dim inactive effect,dim screen effect,efecto de escurecer,slide back effect,eye candy,candy,show FPS effect,efecto de mostrar os FPS,show paint effect,cover switch effect,desktop cube effect,efecto de cubo de escritorio,efecto do cubo de escritorio,efecto de cubo do escritorio,desktop cube animation effect,desktop grid effect,efecto de grade de escritorios,efecto de grade de escritorios,flip switch effect,efecto de interruptor,efecto de contorno,present windows effect,resize window effect,efecto de cambio de tamaño das xanelas,efecto de contraste de fondo
X-KDE-Keywords[hu]=kwin,ablak,kezelő,hatás,3D hatás,2D hatás,grafikai hatások,asztali hatások,animációk,különféle animációk,ablakkezelő hatások,ablakváltó hatások,asztalváltó hatások,animációk,asztali animációk,meghajtók,meghajtó beállítások,leképezés,renderelés,fordított hatás,tükörhatás,nagyító hatás,elkapás segítő hatás,egérkövetés hatás,nagyítás hatás,elmosás,elhalványulás hatás,asztal elhalványulása hatás,széteső hatás,csúszás hatás,ablak kiemelése hatás,belépés hatás,kilépés hatás,varázslámpa hatás,minimalizálás animáció hatás,egérjelölés hatás,méretezés hatás,képernyőkép hatás,munkalap hatás,dia hatás,csúszó felugrók hatás,,bélyegképek félre hatás, áttetszőség,áttetszőség hatás,átlátszóság,ablak geometria hatás,ingó ablak hatás,indulási visszajelzés hatás,párbeszédablak szülő hatás,dim inaktív hatás,dim kijelző hatás,dia vissza hatás,látványelem,édesség,FPS megjelenítése hatás,festék megjelenése hatás,eltakarás váltás hatás,asztal kocka hatás,asztal kockaanimáció hatás,asztal rács hatás,tükrözésváltás hatás,jelenlegi ablakok hatás,ablak átméretezése hatás,háttérkontraszt hatás
X-KDE-Keywords[id]=kwin,window,pengelola,efek,efek 3D,efek 2D,efek grafik,efek desktop,animasi,beragam animasi,efek pengelola window,efek beralih window,efek beralih desktop,animasi,animasi desktop,driver,pengaturan driver,rendering,render,efek kebalikan,efek seperti gelas,efek kaca pembesar,efek penunjang jepret,efek lacak mouse,efek pembesaran,efek buram,efek lesap,efek desktop lesap,efek hancur,efek petak,efek window sorot,efek login,efek logout,efek lampu ajaib,efek animasi minimalkan,efek tanda mouse,efek skala,efek cuplikan layar,efek lembar,efek geser,efek sembul geser,efek gambar-mini disamping,translusensi,efek translusensi,transparan,efek geometri window,efek window goyang,efek feedback pemulaian,efek induk dialog,efek layar suram,efek geser mundur,eye candy,candy,efek tampilkan FPS,efek tampilkan lukisan,efek alih kotak,efek alih sampul,efek kubus desktop,efek animasi kubus desktop,efek kisi desktop,efek alih lipat,efek window hadir,efek ubah ukuran window,efek kontras latarbelakang
X-KDE-Keywords[it]=kwin,finestra,gestore,effetto,effetti 3D,effetti 2D,effetti grafici,effetti del desktop,animazioni,animazioni varie, effetti del gestore delle finestre,effetto dello scambiafinestre,effetto dello scambiatore di desktop,animazioni,animazioni del desktop,driver,impostazioni driver,rendering,render,effetto invertito,effetto vetro,effetto lente,effetto snap helper,effetto traccia mouse,effetto ingrandimento, effetto sfocatura,effetto dissolvenza,effetto dissolvenza desktop,effetto caduta,effetto planatura,effetto evidenziazione finestra,effetto schermata di accesso, effetto disconnessione,effetto lampada magica,effetto animazione di minimizzazione,effetto marcatura mouse, effetto scalatura,effetto schermata,effetto foglio,effetto diapositiva,effetto scivolamento,effetto miniature nella barra delle applicazioni,effetto miniatura su un lato,translucenza,effetto translucenza, trasparenza,effetto geometria finestra,effetto finestre tremolanti,effetto segnale di avvio,effetto finestra madre,effetto oscura finestra inattiva,effetto oscura schermo,effetto scivola all'indietro,gradevole,effetto gradevole,effetto mostra FPS,effetto ridisegno,effetto scambio cubi,effetto scambio copertina,effetto cubi del desktop,effetto animazione cubi del desktop,effetto griglia desktop,effetto scambiatore con inversione,effetto riquadro,effetto finestra presente,effetto ridimensionamento finestra,effetto contrasto dello sfondo
X-KDE-Keywords[ko]=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,dashboard effect,explosion effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale in effect,screenshot effect,sheet effect,slide effect,sliding popups effect,taskbar thumbnails effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,box switch effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,outline effect,present windows effect,resize window effect,창,관리자,효과,3D 효과,2D 효과,그래픽 효과,데스크톱 효과,애니메이션,창 관리자,창 관리자 효과,데스크톱 전환,데스크톱 전환 효과,드라이버,드라이버 설정,렌더링,렌더링 설정,애니메이션 속도,투명 유리 효과,확대 축소 효과,흐림 효과,대시보드 효과,페이드 효과,로그인 효과,창 강조 효과,글라이드 효과,로그아웃 효과,램프 효과,시트 효과,최소화 효과,최대화 효과,팝업 효과
X-KDE-Keywords[lt]=kwin,langas,langai,langų,langu,tvarkytuvė,tvarkytuve,efektas,efektai,3D efektai,2D efektai,trimačiai efektai,trimaciai efektai,dvimačiai efektai,dvimaciai efektai,grafiniai efektai,grafikos efektai,darbalaukio efektai,darbastalio efektai,animacijos,įvairios animacijos,ivairios animacijos,langų tvarkymo efektai,langu tvarkymo efektai,langų valdymo efektai,langu valdymo efektai,langų perjungimo efektai,langu perjungimo efektai,langų perjungiklio efektai,langu perjungiklio efektai,darbalaukio perjungimo efektai,darbastalio perjungimo efektai,darbalaukio perjungiklio efektai,darbastalio perjungiklio efektai,animacijos,darbalaukio animacijos,darbastalio animacijos,tvarkyklės,tvarkykles,tvarkyklė,tvarkykle,tvarkyklės nustatymai,tvarkykles nustatymai,tvarkyklės nuostatos,tvarkykles nuostatos,vaizdavimas,atvaizdavimas,invertavimo efektas,invertavimas,didinamojo stiklo efektas,didinamasis stiklas,didintuvo efektas,didintuvas,pritraukimo pagelbiklio efektas,traukimo pagelbiklio efektas,pritraukimo pagelbiklis,traukimo pagelbiklis,sekti pelę,sekti pele,pelės sekimas,peles sekimas,didinimo efektas,didinimas,suliejimo efektas,suliejimas,išblukimo efektas,išblukimas,isblukimo efektas,isblukimas,atsiradimo efektas,atsiradimas,išnykimo efektas,isnykimo efektas,išnykimas,isnykimas,darbalaukio išblukimo efektas,darbalaukio isblukimo efektas,darbastalio išblukimo efektas,darbastalio isblukimo efektas,subyrėjimo efektas,subyrejimo efektas,subyrėjimas,subyrejimas,byrėjimas,byrejimas,sklandymo efektas,sklandymas,lango paryškinimo efektas,lango paryskinimo efektas,langų paryškinimo efektas,langu paryskinimo efektas,lango paryškinimas,lango paryskinimas,langų paryškinimas,langu paryskinimas,prisijungimo efektas,atsijungimo efektas,magiškos lempos efektas,magiskos lempos efektas,magiška lempa,magiska lempa,suskleidimo animacijos efektas,sumažinimo animacijos efektas,sumazinimo animacijos efektas,suskleidimas,sumažinimas,sumazinimas,žymėjimo pele efektas,zymejimo pele efektas,žymėjimas pele,zymejimas pele,mastelio keitimo efektas,mastelio keitimas,ekrano kopijos efektas,ekrano kopija,ekranvaizdžio efektas,ekranvaizdzio efektas,lapo efektas,lapas,slydimo efektas,slydimas,slidimas,slystančių iškylančiųjų langų efektas,slystanciu iskylanciuju langu efektas,slystantys iškylantieji langai,slystantys iskylantieji langai,miniatiūros šone efektas,miniatiuros sone efektas,dalinis permatomumas,dalinio permatomumo efektas,permatomumas,skaidrumas,lango geometrijos efektas,lango geometrija,svirduliuojančių langų efektas,svirduliuojanciu langu efektas,svirduliuojantys langai,paleidimo grįžtamojo ryšio efektas,paleidimo griztamojo rysio efektas,paleidimo grįžtamasis ryšys,paleidimo griztamasis rysys,paleisties grįžtamasis ryšys,paleisties griztamasis rysys,dialogo viršesnio efektas,dialogo virsesnio efektas,dialogo viršesnis,dialogo virsesnis,pasyviųjų pritemdymo efektas,pasyviuju pritemdymo efektas,pasyviųjų pritemdymas,pasyviuju pritemdymas,pasyvių pritemdymo efektas,pasyviu pritemdymo efektas,pasyvių pritemdymas,pasyviu pritemdymas,ekrano pritemdymo efektas,ekrano pritemdymas,slydimo atgal efektas,slydimas atgal,grožybės,grozybes,gražu,grazu,FPS rodymo efektas,FPS rodymas,kadr./sek.,kadr/sek,kadr./s,kadr/s,kadr./sek. rodymas,piešimo rodymo efektas,piesimo rodymo efektas,piešimo rodymas,piesimo rodymas,viršelių perjungiklio efektas,viršelio perjungiklio efektas,virseliu perjungiklio efektas,viršelių perjungiklis,virseliu perjungiklis,višelių perjungimas,virseliu perjungimas,darbalaukio kubo efektas,darbastalio kubo efektas,darbalaukio kubas,darbastalio kubas,darbalaukio kubo animacijos efektas,darbastalio kubo animacijos efektas,darbalaukio kubo animacija,darbastalio kubo animacija,darbalaukio tinklelio efektas,darbastalio tinklelio efektas,darbalaukio tinklelis,darbastalio tinklelis,kartotekos pavidalo langų perjungiklio efektas,kartotekos pavidalo langu perjungiklio efektas,kartotekos pavidalo langų perjungiklis,kartotekos pavidalo langu perjungiklis,langų pateikimo efektas,langu pateikimo efektas,langų pateikimas,langu pateikimas,langų dydžio keitimo efektas,lango dydžio keitimo efektas,langu dydzio keitimo efektas,lango dydzio keitimo efektas,fono kontrasto efektas,fono kontrastas
X-KDE-Keywords[nl]=kwin,venster,beheerder,effect,3D effecten,2D effecten,grafische effecten,bureaubladeffecten,animaties,verrschillende animaties,vensterbeheereffecten,vensteromschakeleffect,bureaublad-omschakeleffect,animaties,bureaubladanimaties,stuurprogramma's,stuurprogramma-instellingen,rendering,render,inversieeffect,vergrootglaseffect,vergrotingseffect,snaphelpereffect,trackmuiseffect,zoomeffect,vervagingseffect,uitvaageffect,uitvaagbureaubladeffect,uiteenvaleffect,glijeffect,vensteraccentueringseffect,aanmeldeffect,afmeldeffect,magische lampeffect,animatie-effect minimaliseren,muismarkeringseffect,schaaleffect,schermafdrukeffect,bladeneffect,dia-effect,glijdende pop-upseffect,miniatuur-opzijeffect,doorzichtigheid,doorzichtigheidseffect,transparantie,vensterafmetingeneffect,wiebelende vensterseffect,opstartterugkoppeleffect,dialoogoudereffect,dim bij inactiviteitseffect,dim het schermeffect,schuif terugeffect,oogstrelend,snoepgoed,FPS toneneffect,verf toneneffect,vak deksel schakelaareffect,bureaublad kubuseffect,bureaublad kubus animatie-effect,bureaubladrastereffect,omschakeleffect,huidig venstereffect, wijzig grootte van venstereffect, achtergrondcontrasteffect
X-KDE-Keywords[nn]=kwin,vindauge,handsamar,vindaugshandsamar,effekt,3D-effektar,2D-effektar,grafiske effektar,skrivebordeffektar,animasjonar,ymse animasjonar,vindaugsbyteeffektar,effektar ved skrivebordbyte,animasjonar,skrivebordsanimasjonar,drivarar,drivarinnstillingar,oppteikning,oppteiknar,inverteringseffekt,spegeleffekt,lupeeffekt,gripehjelpareffekt,musmerkeeffekt,forstørringseffekt,zoomeffekt,sløringseffekt,uklar-effekt,kontrollpulteffekt,uttoningseffekt,skrivebordtoningseffekt,gå-i-knas-effekt,glidareffekt,framhev vindauge-effekt,innloggingseffekt,utloggingsefffekt,magisk lampe-effekt,animasjonseffekt ved vindaugsminimering,musmerkeeffekt,skaleringseffekt,skjermdumpeffekt,ark-effekt,lysbileteffekt,glidande sprettopp-effekt,effekt for minibilete på sida,gjennomsiktseffekt,gjennomsikt,vindaugsgeometri-effekt,vaklande vindauge-effekt,effekt for oppstartsmelding,effekt for forelderdialog,effekt for mørk inaktiv,effekt for mørk skjerm,gli tilbake-effekt,augesnop,vis FPS-effekt,vis målingseffekt,omslagsbyteeffekt,skrivebordskube-effekt,effekt for animert skrivebordskube,effekt for skrivebordrutenett,effekt for flipp-byte,presenter vindauge-effekt,vindaugsskaleringseffekt,bakgrunnskontrast-effekt
X-KDE-Keywords[pl]=kwin,okno,menadżer,efekt,efekty 3D,efekty 2D,efekty graficzne,efekty pulpitu,animacje,różne animacje,efekty zarządzania oknami,efekty przełączania okien,efekty przełączania pulpitów,animacje,animacje pulpitu,sterowniki,ustawienia sterowników,renderowania, efekt odwrócenia,szkło powiększające,efekt powiększenia,efekt pomocnika przyciągania, efekt śledzenia myszy,efekt przybliżenia,rozmycie,tablica,efekt eksplozji,efekt zanikania,efekt zanikania pulpitu,efekt rozpadania,efekt slajdu,efekt podświetlania okna, efekt logowania,efekt wylogowywania,efekt magicznej lampy,efekt animacji minimalizacji, efekt znacznika myszy,efekt skalowania,efekt zrzutu ekranu,efekt arkusza,efekt slajdu,efekt wysuwających się elementów wyskakujących,efekt prześwitywania,przezroczystość,efekt geometrii okna,efekt chwiejnych okien,efekt odczuć przy starcie,efekt okna rodzica,efekt przyciemniania nieaktywnych,efekt przyciemniania ekranu,efekt przesuwania do tył,efekt pokazania ilości klatek na sekundę
X-KDE-Keywords[pt]=kwin,janela,gestor,composição,efeito,efeitos 3D,efeitos 2D,OpenGL,XRender,configuração do vídeo,efeitos gráficos,efeitos do ecrã,animações,animações diversas,efeitos de gestão das janelas,efeito de mudança de janelas,efeito de mudança de ecrãs,animações,velocidade da animação,animações do ecrã,controladores,configuração dos controladores,desenho,efeito de inversão,efeito de lupa,efeito de lente,efeito de ajuda no ajuste, efeito de seguimento do rato,efeito de ampliação,efeito de borrão,efeito de quadro,efeito de explosão,efeito de desvanecimento,efeito de desvanecimento do ecrã,efeito de destruição,efeito de deslizamento,efeito de realce da janela,efeito na autenticação,efeito do encerramento,efeito de lâmpada mágica,efeito de animação na minimização,efeito de marcação com rato,efeito de escala,efeito de captura do ecrã,efeito de folha,efeito de mensagens deslizantes,efeito de miniaturas na barra de tarefas,efeito de miniaturas laterais,efeito de janelas a tremer,efeito do arranque inicial,efeito da janela-mãe,efeito de escurecimento de janelas inactivas,efeito de deslize para trás,efeitos visuais,beleza,efeito de apresentação das IPS,efeito de pintura,efeito de mudança em caixa,efeito de mudança de capas, efeito de animação do cubo do ecrã,efeito de grelha do ecrã,efeito de mudança por viragem,efeito de destaque,efeito de apresentação das janelas,efeito de dimensionamento das janelas,efeito de contraste do fundo
X-KDE-Keywords[pt_BR]=kwin,janela,gerenciador,efeito,efeitos 3D,efeitos 2D,efeitos gráficos,efeitos da área de trabalho,animações,animações diversas,efeitos do gerenciamento de janelas,efeito de mudança de janelas,efeito de mudança de área de trabalho,animações da área de trabalho,drivers,configuração dos drivers,desenho,renderização,efeito de inversão,efeito de lupa,efeito de lente,efeito de ajuda no ajuste,efeito de rastreamento do mouse,efeito de ampliação,efeito de borrão,efeito de escurecimento,efeito de escurecimento da área de trabalho,efeito de destruição,efeito de deslizamento,efeito de realce da janela,efeito na autenticação,efeito de encerramento de sessão,efeito de lâmpada mágica,efeito de animação na minimização,efeito de marcação com mouse,efeito em escala,efeito de captura de tela,efeito de folha,efeito de slide,efeito de mensagens deslizantes,efeito de miniaturas na barra de tarefas,transparência,efeito de transparência,efeito de geometria de janelas,efeito de janelas trêmulas,efeito do inicialização,efeito da janela-mãe,efeito de escurecimento de janelas inativas,efeito de deslize para trás,efeitos visuais,beleza,efeito de apresentação de FPS,efeito de pintura,efeito de mudança de capas,efeito de animação do cubo da área de trabalho,efeito de grade da área de trabalho,efeito de mudança em pilha,efeito de apresentação das janelas,efeito de dimensionamento das janelas,efeito de contraste de fundo
X-KDE-Keywords[ru]=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale effect,screenshot effect,sheet effect,slide effect,sliding popups effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,present windows effect,resize window effect,background contrast effect,эффекты рабочего стола,графические эффекты,рендеринг,параметры видео,настройка видео,трёхмерные эффекты,двумерные эффекты,эффекты управления окнами,эффекты диспетчера окон,анимация куба рабочих столов,плавная смена рабочих столов,прокрутка,анимация всплывающих окон,анимация появления окна,вход в систему,завершение сеанса,завершение работы,колышущиеся окна,болтающиеся окна,колыхание окон,край экрана,лист,анимация распахивания,анимация максимизации,максимизация окна,распахивание окна,миниатюры окон сбоку,миниатюры окон на краю экрана,полупрозрачность окон,размытие фона,размывание фона,распад закрывающихся окон,растворение закрывающихся окон,рисование на экране,рисование мышью на экране,скольжение окон,анимация сворачивания,сворачивание окон,волшебная лампа,график производительности,производительность эффектов,подсветка отрисовки,подсветка рендеринга,подсветка обновляемых частей экрана,анимация щелчка мышью,инверсия цветов,инвертирование цветов,поиск курсора мыши,разметка экрана,сетка на экране,линейки на экране,экранная разметка,экранная сетка,линза,искажение линзой,лупа,увеличение области экрана,масштаб рабочего стола,изменение масштаба рабочего стола,управление окнами,специальные возможности,инструменты,внешний вид,анимация переключения рабочих столов,все окна,просмотр всех окон,все рабочие столы,просмотр всех рабочих столов,изменение размера окна,масштабирование текстуры окна,куб с рабочими столами,перелистывание окон,управление фокусом,затемнение неактивных окон,затемнение основного окна,затемнение под диалогом,затемнение экрана при административной задаче,соскальзывание окон при смене фокуса,контрастность фона
X-KDE-Keywords[sk]=kwin, okno, manažér, kompozícia, efekt, 3D efekty, 2D efekty, OpenGL, XRender,nastavenia obrazu, grafické efekty, desktop efekty, animácie, rôzneanimácie, efekty správa okien, okno prepínanie efektov, stolnýspínacie efekt, animácie, animácie rýchlosť, stolný animácie, ovládače,nastavenie ovládača, renderovanie, poskytnúť, invertný skutočnosti zrkadlá účinok,lupa efekt, snap pomocník efekt, trať myš efekt, zoom efekt, rozmazaniuúčinok, prístrojová doska efekt, výbuch efekt, fade efekt, fade stolný efekt,rozpadnúť účinok, zostupovej efekt, zvýraznenie okno efekt, efekt prihlásenie, odhlásenieúčinok, čarovnú lampu účinok, minimálny efekt animácie, myši značky efekt, mierkav skutočnosti, screenshot efekt, list efekt, snímka efekt, posuvné vyskakovacie okná účinok,miniatúry na hlavnom paneli efekt, náhľad stranou efekt, priesvitnosť, translucencieúčinok, transparentnosť, okno geometrie efekt, vratkú okná efekt, uvedenie do prevádzkyspätná väzba, dialóg rodič efekt, matný efekt neaktívny, stlmiť obrazovku efekt,posunutím zadnej efekt, pastva pre oči, cukrík zobraziť FPS efekt, zobrazovať farby efekt, boxprepínač efekt, kryt prepínače účinok, desktop, desktop cube efekt kocky animácieúčinok, Desktop Grid efekt, flip switch efekt, obrys účinok, súčasné okná účinok, zmena veľkosti okna efekt, kontrast pozadie efekt
+X-KDE-Keywords[sl]=kwin,upravljalnik oken,učinek,učinki 3d,učinki 2d,grafični učinki,namizni učinki,animacije,upravljanje z okni,preklapljanje oken,preklapljanje namizij,namizne animacije,gonilniki,izrisovanje,upodabljanje,obrni,povečevalno steklo,pripenjalni pomagalnik,sledenje miški,približanje,zabriši,eksplozija,pojemanje,pojemanje namizja,razpad,drsenje,poudari okno,učinek prijave,učinek odjave,čarobna svetilka,animacija skrčenja,risanje,animirano pojavljanje,zaslonska slika,list,drsenje,drseča pojavna okna,sličice za opravilno vrstico,sličica ob strani,prosojnost,prozornost,geometrija okna,majava okna,odziv zagona,nadrejeno pogovorno okno,potemni nedejavno,potemni zaslon,zdrs v ozadje,vidni bonbončki,pokaži sličice na sekundo,izrisovanje,preklapljanje - škatla,preklapljanje - ovitki,kocka z namizji,animacija kocka z namizji,mreža namizij,preklapljanje - sklad,oris,predstavi okna,spreminjanje velikosti okna
X-KDE-Keywords[sv]=kwin,fönster,hanterare,effekt,3D-effekter,grafiska effekter,skrivbordseffekter,animeringar,diverse animeringar,fönsterhanteringseffekter,fönsterbyteseffekt,skrivbordsbyteseffekt,skrivbordsanimeringar,drivrutiner,drivrutininställningar,återgivning,återge,inverteringseffekt,förstoringsglaseffekt,förstoringseffekt,låshjälpeffekt,musföljningseffekt,zoomeffekt,suddighetseffekt,explosionseffekt,borttoningseffekt,skrivbordsborttoningseffekt,sönderfallseffekt,glidningseffekt,fönstermarkeringseffekt,inloggningseffekt,utloggningseffekt,magisk lampeffekt,minimeringsanimeringseffekt,musmarkeringseffekt,inskalningseffekt,skärmbildseffekt,bladeffekt,skjuteffekt,glidande ruteffekt,miniatyrbilder i aktivitetsfältet,miniatyrbild vid sidan om,genomskinlighet,genomskinlighetseffekt,fönstergeometrieffekt,ostadiga fönstereffekt,startgensvarseffekt,dialogrutors ägareffekt,dämpa inaktiva effekt,dämpa skärmen effekt,glid tillbaka effekt,ögongodis,godis.visa ramar/s effekt, visa uppritningseffekt,byte med ruta effekt,skrivbordskubeffekt,animeringseffekt för skrivbordskub,skrivbordsrutnätseffekt,blädderbyteseffekt,befintliga fönstereffekt,ändra fönsterstorlekseffekt,bakgrundskontrasteffekt
X-KDE-Keywords[uk]=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale in effect,screenshot effect,sheet effect,slide effect,sliding popups effect,taskbar thumbnails effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,box switch effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,outline effect,present windows effect,resize window effect,вікно,керування вікнами,менеджер вікон,ефект,просторовий,плоский,параметри відео,графічні ефекти,анімації,анімація,перемикання вікон,драйвери,параметри драйверів,показ,відтворення,інвертування,інверсія,збільшувальне скло,збільшення,прилипання,шлейф за вказівником,шлейф,масштабування,масштаб,зміна розмірів,розмивання,панель,згасання,поява,ковзання,підсвічування,підсвічування вікон,вихід,магічна лампа,чарівна лампа,джин,аркуші,стос,знімок екрана,мініатюри панелі задач,мініатюри,прозорість,ефект прозорості,желе,желейні вікна,супровід запуску,стрибунець,притлумлення,сірість,прикраси,показ частоти,малювання,обкладинки,стрибання,контур,поточні вікна,зміна розмірів
X-KDE-Keywords[x-test]=xxkwinxx,xxwindowxx,xxmanagerxx,xxeffectxx,xx3D effectsxx,xx2D effectsxx,xxgraphical effectsxx,xxdesktop effectsxx,xxanimationsxx,xxvarious animationsxx,xxwindow management effectsxx,xxwindow switching effectxx,xxdesktop switching effectxx,xxanimationsxx,xxdesktop animationsxx,xxdriversxx,xxdriver settingsxx,xxrenderingxx,xxrenderxx,xxinvert effectxx,xxlooking glass effectxx,xxmagnifier effectxx,xxsnap helper effectxx,xxtrack mouse effectxx,xxzoom effectxx,xxblur effectxx,xxfade effectxx,xxfade desktop effectxx,xxfall apart effectxx,xxglide effectxx,xxhighlight window effectxx,xxlogin effectxx,xxlogout effectxx,xxmagic lamp effectxx,xxminimize animation effectxx,xxmouse mark effectxx,xxscale effectxx,xxscreenshot effectxx,xxsheet effectxx,xxslide effectxx,xxsliding popups effectxx,xxthumbnail aside effectxx,xxtranslucencyxx,xxtranslucency effectxx,xxtransparencyxx,xxwindow geometry effectxx,xxwobbly windows effectxx,xxstartup feedback effectxx,xxdialog parent effectxx,xxdim inactive effectxx,xxdim screen effectxx,xxslide back effectxx,xxeye candyxx,xxcandyxx,xxshow FPS effectxx,xxshow paint effectxx,xxcover switch effectxx,xxdesktop cube effectxx,xxdesktop cube animation effectxx,xxdesktop grid effectxx,xxflip switch effectxx,xxpresent windows effectxx,xxresize window effectxx,xxbackground contrast effectxx
X-KDE-Keywords[zh_CN]=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,explosion effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale effect,screenshot effect,sheet effect,slide effect,sliding popups effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,present windows effect,resize window effect,background contrast effect,窗口,管理,特效,3D 特效,2D 特效,图形特效,桌面特效,动画,窗口管理特效,窗口切换特效,桌面切换特效,桌面动画,驱动,去掉设置,渲染,反色,放大镜特效,鼠标跟踪,缩放特效,模糊特效,渐变特效,破碎特效,滑动特效,高亮窗口,登录特效,注销特效,神灯特效,最小化动画,鼠标标记,截屏,飘落,滑动弹出窗口,缩略图置边,透明特效,摇摆窗口,启动反馈特效,黯淡对话框特效,黯淡屏幕特效,视觉效果,显示 FPS 特效,显示绘制区域特效,封面切换特效,桌面立方体特效,桌面立方体动画特效,翻转切换特效,展示窗口特效,调整窗口大小特效,背景对比特效
X-KDE-Keywords[zh_TW]=kwin,window,manager,effect,3D effects,2D effects,graphical effects,desktop effects,animations,various animations,window management effects,window switching effect,desktop switching effect,animations,desktop animations,drivers,driver settings,rendering,render,invert effect,looking glass effect,magnifier effect,snap helper effect,track mouse effect,zoom effect,blur effect,fade effect,fade desktop effect,fall apart effect,glide effect,highlight window effect,login effect,logout effect,magic lamp effect,minimize animation effect,mouse mark effect,scale effect,screenshot effect,sheet effect,slide effect,sliding popups effect,thumbnail aside effect,translucency,translucency effect,transparency,window geometry effect,wobbly windows effect,startup feedback effect,dialog parent effect,dim inactive effect,dim screen effect,slide back effect,eye candy,candy,show FPS effect,show paint effect,cover switch effect,desktop cube effect,desktop cube animation effect,desktop grid effect,flip switch effect,present windows effect,resize window effect,background contrast effect
diff --git a/kcmkwin/kwinoptions/focus.ui b/kcmkwin/kwinoptions/focus.ui
index 735f81c05..d958008d4 100644
--- a/kcmkwin/kwinoptions/focus.ui
+++ b/kcmkwin/kwinoptions/focus.ui
@@ -1,265 +1,298 @@
KWinFocusConfigForm
0
0
600
500
-
Qt::AlignHCenter|Qt::AlignTop
-
Window &activation policy:
- windowFocusPolicyCombo
+ windowFocusPolicy
-
-
+
With this option you can specify how and when windows will be focused.
-
Click to focus
-
Click to focus (mouse precedence)
-
Focus follows mouse
-
Focus follows mouse (mouse precedence)
-
Focus under mouse
-
Focus strictly under mouse
-
&Delay focus by:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- delayFocus
+ kcfg_DelayFocusInterval
-
-
+
This is the delay after which the window the mouse pointer is over will automatically receive focus.
ms
0
3000
100
-
Focus &stealing prevention:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- focusStealing
+ kcfg_FocusStealingPreventionLevel
-
-
+
<html><head/><body><p>This option specifies how much KWin will try to prevent unwanted focus stealing caused by unexpected activation of new windows. (Note: This feature does not work with the <span style=" font-style:italic;">Focus under mouse</span> or <span style=" font-style:italic;">Focus strictly under mouse</span> focus policies.) </p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">None:</span> Prevention is turned off and new windows always become activated.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Low:</span> Prevention is enabled; when some window does not have support for the underlying mechanism and KWin cannot reliably decide whether to activate the window or not, it will be activated. This setting may have both worse and better results than the medium level, depending on the applications.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Medium:</span> Prevention is enabled.</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">High:</span> New windows get activated only if no window is currently active or if they belong to the currently active application. This setting is probably not really usable when not using mouse focus policy.</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Extreme:</span> All windows must be explicitly activated by the user.</li></ul><p>Windows that are prevented from stealing focus are marked as demanding attention, which by default means their taskbar entry will be highlighted. This can be changed in the Notifications control module.</p></body></html>
-
None
-
Low
-
Medium
-
High
-
Extreme
-
Raising windows:
-
-
+
When this option is enabled, the active window will be brought to the front when you click somewhere into the window contents. To change it for inactive windows, you need to change the settings in the Actions tab.
&Click raises active window
-
-
-
+
When this option is enabled, a window in the background will automatically come to the front when the mouse pointer has been over it for some time.
&Raise on hover, delayed by:
-
-
+
This is the delay after which the window that the mouse pointer is over will automatically come to the front.
ms
0
3000
100
-
Multiscreen behavior:
-
-
+
When this option is enabled, the active Xinerama screen (where new windows appear, for example) is the screen containing the mouse pointer. When disabled, the active Xinerama screen is the screen containing the focused window. By default this option is disabled for Click to focus and enabled for other focus policies.
Active screen follows &mouse
-
-
+
When this option is enabled, focus operations are limited only to the active Xinerama screen
&Separate screen focus
-
280
0
Window activation policy description
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
true
-
Qt::Vertical
20
40
KComboBox
QComboBox
-
+
+
+ kcfg_AutoRaise
+ toggled(bool)
+ kcfg_AutoRaiseInterval
+ setEnabled(bool)
+
+
+ 338
+ 189
+
+
+ 485
+ 189
+
+
+
+
+ kcfg_AutoRaise
+ toggled(bool)
+ kcfg_ClickRaise
+ setDisabled(bool)
+
+
+ 338
+ 189
+
+
+ 333
+ 155
+
+
+
+
diff --git a/kcmkwin/kwinoptions/kwinactions.desktop b/kcmkwin/kwinoptions/kwinactions.desktop
index 163a54c20..3d515a348 100644
--- a/kcmkwin/kwinoptions/kwinactions.desktop
+++ b/kcmkwin/kwinoptions/kwinactions.desktop
@@ -1,114 +1,116 @@
[Desktop Entry]
Icon=preferences-system-windows-action
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kwinactions
X-DocPath=kcontrol/windowbehaviour/index.html#titlebar-actions
Icon=preferences-system-windows-actions
X-KDE-Library=kcm_kwinoptions
X-KDE-PluginKeyword=kwinactions
Name=Window Actions
Name[ca]=Accions de la finestra
Name[cs]=Činnosti oken
Name[da]=Vindueshandlinger
Name[de]=Fensteraktionen
Name[en_GB]=Window Actions
Name[es]=Acciones de ventanas
Name[et]=Akna toimingud
Name[eu]=Leihoetako ekintzak
Name[fi]=Ikkunan toiminnot
Name[fr]=Actions de la fenêtre
Name[gl]=Accións da xanela
Name[ia]=Actiones de fenestra
Name[id]=Aksi Window
Name[it]=Azioni delle finestre
Name[ko]=창 동작
Name[lt]=Langų veiksmai
Name[nl]=Vensteracties
Name[nn]=Handlingar for vindauge
Name[pl]=Zachowanie okien
Name[pt]=Acções das Janelas
Name[pt_BR]=Ações da janela
Name[ru]=Действия с окнами
Name[sk]=Akcie okna
+Name[sl]=Dejavnosti oken
Name[sv]=Fönsteråtgärder
Name[uk]=Дії з вікнами
Name[x-test]=xxWindow Actionsxx
Name[zh_CN]=窗口动作
Name[zh_TW]=視窗動作
Comment=Configure mouse actions for windows and titlebars
Comment[ca]=Configura les accions de ratolí per a les finestres i les barres de títol
Comment[cs]=Nastavení činností myši na oknech a pruhu titulku
Comment[da]=Indstil mushandlinger for vinduer og titellinjer
Comment[de]=Mausaktionen für Fenster und Titelleisten einrichten
Comment[en_GB]=Configure mouse actions for windows and titlebars
Comment[es]=Configurar las acciones del ratón para las ventanas y las barras de títulos
Comment[et]=Hiiretoimingute seadistamine akendes ja tiitliribadel
Comment[eu]=Konfiguratu saguaren ekintzak leihoekin eta titulu-barrekin
Comment[fi]=Ikkunoiden ja otsikkopalkkien hiiritoimintojen asetukset
Comment[fr]=Configurer les actions de la souris pour les fenêtres et barres de titres
Comment[gl]=Configurar as accións do rato para xanelas e barras de título
Comment[ia]=Configura actiones de mus per fenestras e barras de titulo
Comment[id]=Konfigurasikan aksi mouse untuk window dan bilah-judul
Comment[it]=Configura azioni del mouse per finestre e barre del titolo
Comment[ko]=창과 제목 표시줄 마우스 동작 설정
Comment[lt]=Konfigūruoti pelės veiksmus langams ir antraštės juostoms
Comment[nl]=Muisacties voor vensters en titelbalken configureren
Comment[nn]=Set opp musehandlingar for vindauge og tittellinjer
Comment[pl]=Ustawienia działań myszy dla okien i pasków tytułu
Comment[pt]=Configurar as acções do rato para as janelas e barras do título
Comment[pt_BR]=Configura as ações do mouse para as janelas e barras de títulos
Comment[ru]=Настройка действий для окон и их заголовков
Comment[sk]=Nastavenie akcií myši pre okná a záhlavia
+Comment[sl]=Nastavi aktivnosti miške za okna in naslovne vrstice
Comment[sv]=Anpassa musåtgärder för fönster och namnlister
Comment[uk]=Налаштовування керування мишею для вікон та смужок заголовків
Comment[x-test]=xxConfigure mouse actions for windows and titlebarsxx
Comment[zh_CN]=配置窗口和标题栏的鼠标动作
Comment[zh_TW]=設定視窗及標題列的滑鼠動作
X-KDE-Keywords=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize
X-KDE-Keywords[bs]=sjena,povećali,povećala,smanjiti,umanjiti,sniziti,izbornik operacija,naslovnica,promjena veličine
X-KDE-Keywords[ca]=ombra,maximitza,maximitza,minimitza,minimitza,abaixa,menú d'operacions,barra de títol,redimensiona
X-KDE-Keywords[ca@valencia]=ombra,maximitza,maximitza,minimitza,minimitza,abaixa,menú d'operacions,barra de títol,redimensiona
X-KDE-Keywords[da]=skyg,maksimer,minimer,nedre,operationsmenu,titellinje,ændr størrelse
X-KDE-Keywords[de]=Fenstermenü,Fensterheber,Maximieren,Minimieren,Nach oben/unten,Titelleiste,Größe ändern
X-KDE-Keywords[el]=σκιά,μεγιστοποίηση,μεγιστοποίηση,ελαχιστοποίηση,ελαχιστοποίηση, χαμηλότερα,μενού λειτουργιών,γραμμή τίτλου,αλλαγή μεγέθους
X-KDE-Keywords[en_GB]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize
X-KDE-Keywords[es]=sombra,maximizar,maximizar,minimizar,minimizar,inferior,menú de operaciones,barra de título,cambio de tamaño
X-KDE-Keywords[et]=varjamine,peitmine,maksimeerimine,minimeerimine,allakerimine,üleskerimine,menüü,tiitliriba,suuruse muutmine
X-KDE-Keywords[eu]=bildu,maximizatu,ikonotu,jaitsi,eragiketa-menua,titulu-barra,tamainaz aldatu
X-KDE-Keywords[fi]=varjosta,rullaa,suurenna,pienennä,laske,toimintovalikko,otsikkopalkki,muuta kokoa
X-KDE-Keywords[fr]=ombre, maximiser, maximise, minimiser, minimise, menu des opérations, barre de titre, redimensionner
X-KDE-Keywords[ga]=scáth,scáthaigh,uasmhéadaigh,íosmhéadaigh,íoslaghdaigh,laghdaigh,roghchlár oibríochta,barra teidil,athraigh méid
X-KDE-Keywords[gl]=sombra,sombrear,maximizar,minimizar,recoller,menú de operacións, barra de título, redimensionar
X-KDE-Keywords[hu]=árnyék,maximalizálás,maximalizálás,minimalizálás,minimalizálás,alacsonyabb,műveletek menü,címsáv,átméretezés
X-KDE-Keywords[ia]=tinta,maximisa,maximisa,minimisa,minimisa,plus basse,menu de operationes,barra de titulo, redimensionar
X-KDE-Keywords[id]=bayangan,maksimalkan,maksimalkan,minimalkan,minimalkan,ke bawah,menu operasi,titlebar,ubah ukuran
X-KDE-Keywords[it]=ombra,massimizza,minimizza,abbassa,menu operazioni,barra del titolo,ridimensiona
X-KDE-Keywords[kk]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize
X-KDE-Keywords[km]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize
X-KDE-Keywords[ko]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,최대화,최소화,제목 표시줄,크기 조정
X-KDE-Keywords[lt]=pridengti,išskleisti,isskleisti,išdidinti,isdidinti,suskleisti,sumažinti,sumazinti,nuleisti į antrą planą,nuleisti i antra plana,operacijų meniu,operaciju meniu,antraštės juosta,antrastes juosta,keisti dydį,keisti dydi
X-KDE-Keywords[nb]=rull,maksimer,minimer,senk,handlinger,meny,tittellinje,endre størrelse
X-KDE-Keywords[nds]=Inrullen,maximeren,minimeren,na achtern,Akschonenmenü,Titelbalken,Finsternmenü,Grött ännern
X-KDE-Keywords[nl]=verdonkeren,maximaliseren,minimaliseren,naar onderen,bedieningsmenu,titelbalk,grootte wijzigen
X-KDE-Keywords[nn]=rull,fald saman,fald ut,samanfalding,maksimer,minimer,senk,handlingar,meny,tittellinje,storleiksendring
X-KDE-Keywords[pl]=zwiń,maksymalizuj,minimalizuj,obniż,operacje na menu,pasek tytułu,zmień rozmiar
X-KDE-Keywords[pt]=enrolar,maximizar,minimizar,baixar,menu de operações,barra de título,dimensionar
X-KDE-Keywords[pt_BR]=enrolar,maximizar,minimizar,baixar,menu de operações,barra de título,redimensionar
X-KDE-Keywords[ru]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,свернуть,распахнуть,убрать вниз,меню операций,меню действий,заголовок окна,заголовок,изменить размер
X-KDE-Keywords[sk]=tieň,maximalizácia,maximalizovanie,minimalizácia,minimalizovanie,nižší,ponuka operácií,záhlavie,zmeniť veľkosť
X-KDE-Keywords[sl]=zvij,povečaj,razpni,pomanjšaj,skrči,dvigni,spusti,naslovna vrstica,spremeni velikost,okenski meni,meni okna
X-KDE-Keywords[sr]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,сенка,максимизуј,минимизуј,спусти,мени радњи,насловна трака,промени величину
X-KDE-Keywords[sr@ijekavian]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,сенка,максимизуј,минимизуј,спусти,мени радњи,насловна трака,промени величину
X-KDE-Keywords[sr@ijekavianlatin]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,senka,maksimizuj,minimizuj,spusti,meni radnji,naslovna traka,promeni veličinu
X-KDE-Keywords[sr@latin]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,senka,maksimizuj,minimizuj,spusti,meni radnji,naslovna traka,promeni veličinu
X-KDE-Keywords[sv]=skugga,maximera,minimera,åtgärdsmeny,namnlist,ändra storlek
X-KDE-Keywords[tr]=geri yükle, gölgele,büyüt,küçült,aşağı al,işlemler menüsü,başlık çubuğu,yeniden boyutlandır
X-KDE-Keywords[uk]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,тінь,максимізувати,розгорнути,згорнути,нижче,меню дій,заголовок,смужка заголовка,розмір,розміри,зміна розмірів
X-KDE-Keywords[x-test]=xxshadexx,xxmaximisexx,xxmaximizexx,xxminimizexx,xxminimisexx,xxlowerxx,xxoperations menuxx,xxtitlebarxx,xxresizexx
X-KDE-Keywords[zh_CN]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize,阴影,最大化,最小化,降低,动作,菜单,标题栏,更改大小
X-KDE-Keywords[zh_TW]=shade,maximise,maximize,minimize,minimise,lower,operations menu,titlebar,resize
diff --git a/kcmkwin/kwinoptions/kwinadvanced.desktop b/kcmkwin/kwinoptions/kwinadvanced.desktop
index 8cac4f583..988d019a2 100644
--- a/kcmkwin/kwinoptions/kwinadvanced.desktop
+++ b/kcmkwin/kwinoptions/kwinadvanced.desktop
@@ -1,95 +1,98 @@
[Desktop Entry]
Icon=preferences-system-windows-actions
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kwinadvanced
X-DocPath=kcontrol/windowbehaviour/index.html#action-advanced
X-KDE-Library=kcm_kwinoptions
X-KDE-PluginKeyword=kwinadvanced
Name=Advanced Window Behavior
Name[ca]=Comportament avançat de les finestres
Name[cs]=Pokročilé chování oken
Name[da]=Avanceret vinduesopførsel
Name[de]=Erweitertes Fensterverhalten
Name[en_GB]=Advanced Window Behaviour
Name[es]=Comportamiento avanzado de las ventanas
Name[et]=Täpsem akende käitumine
Name[eu]=Leihoaren portaera aurreratua
Name[fi]=Ikkunatoiminnan lisäasetukset
Name[fr]=Comportement avancé des fenêtres
Name[gl]=Comportamento avanzado das xanelas
Name[ia]=Comportamento de fenestra avantiate
Name[id]=Perilaku Window Tingkat-Lanjut
Name[it]=Comportamento avanzato delle finestre
Name[ko]=고급 창 행동
Name[lt]=Išplėstinė langų elgsena
Name[nl]=Geavanceerd venstergedrag
Name[nn]=Avansert vindaugsåtferd
Name[pl]=Zaawansowane zachowania okien
Name[pt]=Comportamento Avançado das Janelas
Name[pt_BR]=Comportamento avançado das janelas
Name[ru]=Расширенное поведение окон
Name[sk]=Pokročilé správanie okien
+Name[sl]=Napredno obnašanje oken
Name[sv]=Avancerat fönsterbeteende
Name[uk]=Додаткові параметри вікон
Name[x-test]=xxAdvanced Window Behaviorxx
Name[zh_CN]=高级窗口行为
Name[zh_TW]=進階視窗行為
Comment=Configure advanced window management options
Comment[ca]=Configura les opcions avançades per a la gestió de les finestres
Comment[cs]=Nastavení pokročilých voleb správce oken
Comment[da]=Indstil avancerede vindueshåndteringsegenskaber
Comment[de]=Einstellungen für erweiterte Fensterverwaltung einrichten
Comment[en_GB]=Configure advanced window management options
Comment[es]=Configurar las opciones avanzadas de la gestión de ventanas
Comment[et]=Muude aknahalduse valikute seadistamine
Comment[eu]=Konfiguratu leiho kudeaketa aukera aurreratuak
Comment[fi]=Ikkunanhallinnan lisäasetukset
Comment[fr]=Configurer les options de gestion avancée des fenêtres
Comment[gl]=Configurar as funcionalidades avanzadas da xestión de xanelas
Comment[ia]=Configura optiones avantiate de gestion de fenestra
Comment[id]=Konfigurasikan opsi pengelolaan window tingkat-lanjut
Comment[it]=Configura opzioni avanzate della gestione delle finestre
Comment[ko]=고급 창 관리자 기능 설정
Comment[lt]=Konfigūruoti išplėstines langų tvarkymo parinktis
Comment[nl]=Geavanceerde vensterbeheermogelijkheden configureren
Comment[nn]=Set opp avanserte vindaugshandsamarinnstillingar
Comment[pl]=Zaawansowane ustawienia zarządzania oknami
Comment[pt]=Configurar as funcionalidades de gestão de janelas avançadas
Comment[pt_BR]=Configure as opções avançadas de gerenciamento de janelas
Comment[ru]=Настройка дополнительных возможностей управления окнами
Comment[sk]=Nastaviť pokročilé možnosti správy okien
+Comment[sl]=Nastavi napredne zmožnosti upravljanja oken
Comment[sv]=Anpassa avancerade fönsterhanteringsalternativ
Comment[uk]=Налаштовування додаткових параметрів керування вікнами
Comment[x-test]=xxConfigure advanced window management optionsxx
Comment[zh_CN]=配置高级窗口管理选项
Comment[zh_TW]=設定進階視窗管理選項
X-KDE-Keywords=unshade,unshading,shade,shading,border,hover,active borders,tiling,tabs,tabbing,window,window tabbing,window grouping,window tiling,placement,window placement,placement of windows,window advanced behavior
X-KDE-Keywords[ca]=desplega,desplegament,ombra,vora,passar per sobre,vores actives,mosaic,pestanyes,pestanyes de finestra,finestra,agrupació de les finestres,mosaic de les finestres,col·locació,col·locació de les finestres,comportament avançat de les finestres
X-KDE-Keywords[da]=kant,hover,aktive kanter,tiling,faneblade,vinduesfaneblade,gruppering af vinduer,vinduesplacering,placering,placering af vinduer,avanceret vinduesopførsel
X-KDE-Keywords[en_GB]=unshade,unshading,shade,shading,border,hover,active borders,tiling,tabs,tabbing,window,window tabbing,window grouping,window tiling,placement,window placement,placement of windows,window advanced behaviour
X-KDE-Keywords[es]=desplegar,extender,recoger,plegar,borde,pasada,bordes activos,mosaico,pestañas,páginas en pestañas,ventana,pestañas de páginas,agrupación de ventanas,ventanas en mosaico,posicionamiento,posicionamiento de ventanas,comportamiento avanzado de las ventanas
X-KDE-Keywords[et]=varjamine,piire,kohalviibimine,aktiivsed piirded,paanimine,kaardid,aknad kaartidena,akende rühmitamine,akende paanimine,akende paigutus,akende täpne käitumine,aken,paigutus
X-KDE-Keywords[eu]=zabaldu,zabaltzea,bildu,biltzea,gainetik pasatzea,ertz aktiboak,lauzatze,fitxak,leihoa,leihoen fitxak,leihoak lauza moduan,leihoen kokapena,leihoen jokabide aurreratua
X-KDE-Keywords[fi]=rullauksen avaus,rullauksen avaaminen,rullaus,rullaaminen,kehys,leijunta,aktiiviset reunat,asettelu,välilehdet,ikkunavälilehdet,ikkunoiden ryhmittely,ikkunoiden asettelu,sijoittaminen,sijoittelu,ikkunoiden sijoittaminen,ikkunoiden sijoittelu,ikkunoiden lisäasetukset
X-KDE-Keywords[gl]=dessombrar,dessombramento,sombra,bordo,beira,pasar,bordos activos,beiras activas,xanela,separadores,agrupar xanelas, situación das xanelas,colocación,colocación das xanelas,comportamento avanzado das xanelas
X-KDE-Keywords[id]=tak berbayang,tak bayang,berbayang,batas,melayang,bingkai aktif,pengubinan,tab,pengetaban,window,pengetaban window,pengelompokan window,pengubinan window,penempatan,penempatan window,penempatan si window,perilaku tingkat-lanjut window
X-KDE-Keywords[it]=arrotola,srotola,ombra,ombreggiatura,bordo,sovrapponi,bordi attivi,affiancamento,schede,navigazione a schede,finestre,finestre a schede,raggruppamento finestre,affiancamento finestre,posizionamento,posizionamento finestre,posizionamento delle finestre,comportamento avanzato delle finestre
X-KDE-Keywords[ko]=unshade,unshading,shade,shading,border,hover,active borders,tiling,tabs,tabbing,window,window tabbing,window grouping,window tiling,placement,window placement,placement of windows,window advanced behavior,그림자,경계선,호버,지나다니기,타일,탭,창 탭,창 그룹,창 타일,창 위치,말아 올리기,풀어 내리기,배치,창
X-KDE-Keywords[lt]=atidengti,atidengimas,pridengti,pridengimas,rėmelis,remelis,remas,rėmas,pelės užvedimas,peles uzvedimas,užvesti pelę,uzvesti pele,kortelės,korteles,langas,langai,langų kortelės,langu korteles,langų grupavimas,langu grupavimas,langų išklojimas,langu isklojimas,išdėstymas,isdestymas,padėjimas,padejimas,langų išdėstymas,langu isdestymas,langų padėjimas,langu padejimas,išplėstinė langų elgsena,isplestine langu elgsena,išplėstinė lango elgsena,isplestine lango elgsena,išplėstinis langų elgesys,isplestinis langu elgesys,išplėstinis lango elgesys,isplestinis lango elgesys
X-KDE-Keywords[nl]=verhelderen,verheldering,schaduw,verduistering,rand,boven zweven,actieve randen,schuin achter elkaar,tabbladen,met tabbladen werken,venster,vensterwisseling,verstergroepering,vensters schuin achter elkaar,plaatsing,vensterplaatsing,plaatsing van vensters,geavanceerd gedrag van vensters
X-KDE-Keywords[nn]=opprulling,kant,sveva,aktive kantar,flislegging,faner,vindaugsfaner,vindaugsgruppering,vindaugsflislegging,vindaugsplassering,plassering,plassering av vindauge,avansert vindaugsåtferd
X-KDE-Keywords[pl]=rozwijanie,zwijanie,obramowanie,unoszenie,aktywne obramowania,kafelkowanie,karty,tworzenie kart,okno, umieszczanie okien w kartach,grupowanie okien,kafelkowanie okien,umieszczanie,umieszczanie okien, zaawansowane zachowania okien
X-KDE-Keywords[pt]=sombra,contorno,passagem,contornos activos,lado-a-lado,páginas,páginas da janela,agrupamento de janelas,janelas lado-a-lado,colocação das janelas,comportamento avançado das janelas
X-KDE-Keywords[pt_BR]=enrolar,desenrolar,desenrolando,sombra,contorno,passagem,contornos ativos, lado a lado,janela,páginas,páginas da janela,agrupamento de janelas,janelas lado a lado,colocação das janelas,colocação,comportamento avançado das janelas
X-KDE-Keywords[ru]=unshade,unshading,shade,shading,border,hover,active borders,tiling,tabs,tabbing,window,window tabbing,window grouping,window tiling,placement,window placement,placement of windows,window advanced behavior,затенение,сворачивание в заголовок,разворачивание из заголовка,граница,наведение,активные границы,мозаика,вкладки,окна во вкладках,группировка окон,мозаичный режим,окно,расположение окон,расширенное поведение окон
X-KDE-Keywords[sk]=tieňovanie,okraj,prechod,aktívne okraje,dlaždicovanie,karty,kartovanie okien, zoskupovanie okien,dlaždicovanie okien,umiestnenie okna,poloha okien,pokročilé správanie okien
+X-KDE-Keywords[sl]=osvetljevanje,senčenje,zvijanje,rob,obroba,robovi,obrobe,prehod,lebdenje,tlakovanje,zavihki,združevanje oken,tlakovanje oken,postavljanje oken,postavitev oken,napredno obnašanje oken
X-KDE-Keywords[sv]=skugga,skuggning,kanter,hålla musen över,aktiva kanter,sida vid sida,flikar,fönster,fönsterflikar,fönstergruppering,fönster sida vid sida,placering,fönsterplacering,placering av fönster,avancerat fönsterbeteende
X-KDE-Keywords[uk]=unshade,unshading,shade,shading,border,hover,active borders,tiling,tabs,tabbing,window tabbing,window grouping,window tiling,placement?window placement,placement of windows,window advanced behavior,прибирання тіні,тінь,тіні,границі,межі,краї,активні краї,плитка,тайлінґ,вкладки,мозаїка,вікно з вкладками,групування вікон,розташування,розташування вікон, додаткові ефекти поведінки
X-KDE-Keywords[x-test]=xxunshadexx,xxunshadingxx,xxshadexx,xxshadingxx,xxborderxx,xxhoverxx,xxactive bordersxx,xxtilingxx,xxtabsxx,xxtabbingxx,xxwindowxx,xxwindow tabbingxx,xxwindow groupingxx,xxwindow tilingxx,xxplacementxx,xxwindow placementxx,xxplacement of windowsxx,xxwindow advanced behaviorxx
X-KDE-Keywords[zh_CN]=阴影,投影,边框,边界,悬停,激活边界,平铺,标签,窗口,窗口标签,窗口分组,平铺窗口,窗口位置,窗口高级行为
X-KDE-Keywords[zh_TW]=unshade,unshading,shade,shading,border,hover,active borders,tiling,tabs,tabbing,window,window tabbing,window grouping,window tiling,placement,window placement,placement of windows,window advanced behavior
diff --git a/kcmkwin/kwinoptions/kwinfocus.desktop b/kcmkwin/kwinoptions/kwinfocus.desktop
index 37c519f22..b62ce7aa3 100644
--- a/kcmkwin/kwinoptions/kwinfocus.desktop
+++ b/kcmkwin/kwinoptions/kwinfocus.desktop
@@ -1,94 +1,97 @@
[Desktop Entry]
Icon=preferences-system-windows
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kwinfocus
X-DocPath=kcontrol/windowbehaviour/index.html#action-focus
X-KDE-Library=kcm_kwinoptions
X-KDE-PluginKeyword=kwinfocus
Name=Window Focus Behavior
Name[ca]=Comportament del focus de les finestres
Name[cs]=Chování při zaměření na okno
Name[da]=Opførsel af vinduesfokus
Name[en_GB]=Window Focus Behaviour
Name[es]=Comportamiento del foco de las ventanas
Name[et]=Akende fookuse käitumine
Name[eu]=Leiho fokuaren portaera
Name[fi]=Ikkunoiden kohdistuskäytäntö
Name[fr]=Comportement de focus des fenêtres
Name[gl]=Comportamento do foco das xanelas
Name[ia]=Comportamento de foco de fenestra
Name[id]=Perilaku Fokus Window
Name[it]=Comportamento del fuoco delle finestre
Name[ko]=창 초점 동작
Name[lt]=Langų fokusavimo elgsena
Name[nl]=Focusgedrag venster
Name[nn]=Fokusåtferd for vindauge
Name[pl]=Zachowanie uaktywnienia okien
Name[pt]=Comportamento do Foco da Janela
Name[pt_BR]=Comportamento do foco da janela
Name[ru]=Фокус окон
Name[sk]=Správanie zamerania okien
+Name[sl]=Obnašanje oken pri osredotočanju
Name[sv]=Fönsterfokusbeteende
Name[uk]=Параметри фокусування вікон
Name[x-test]=xxWindow Focus Behaviorxx
Name[zh_CN]=窗口焦点行为
Name[zh_TW]=視窗焦點行為
Comment=Configure window activation policy
Comment[ca]=Configura la política d'activació de les finestres
Comment[cs]=Nastavení pravidel aktivování oken
Comment[da]=Indstil vinduers aktiveringspolitik
Comment[en_GB]=Configure window activation policy
Comment[es]=Configurar la política de activación de ventanas
Comment[et]=Akende aktiveerimise reeglite seadistamine
Comment[eu]=Konfiguratu leihoa aktibatzeko gidalerroak
Comment[fi]=Ikkunoiden aktivointikäytännön asetukset
Comment[fr]=Configurer la politique d'activation des fenêtres
Comment[gl]=Configurar a política de activación de xanelas
Comment[ia]=Configura le politica de activation de fenestra
Comment[id]=Konfigurasikan kebijakan pengaktifan window
Comment[it]=Configura criteri di attivazione delle finestre
Comment[ko]=창 활성화 정책 설정
Comment[lt]=Konfigūruoti langų aktyvavimo politiką
Comment[nl]=Vensteractiveringsbeleid configureren
Comment[nn]=Set opp praksisen for vindaugsaktivering
Comment[pl]=Ustawienia uaktywniania okien
Comment[pt]=Configurar a política de activação da janela
Comment[pt_BR]=Configure a política de ativação de janela
Comment[ru]=Настройка активации окон
Comment[sk]=Nastavenie spôsobu aktivácie okien
+Comment[sl]=Nastavi politiko aktiviranja okna
Comment[sv]=Anpassa policy för fönsteraktivering
Comment[uk]=Налаштовування правил активації вікон
Comment[x-test]=xxConfigure window activation policyxx
Comment[zh_CN]=配置窗口激活策略
Comment[zh_TW]=設定視窗啟用策略
X-KDE-Keywords=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behavior,window screen behavior
X-KDE-Keywords[ca]=focus,elevació automàtica,elevació,elevació en clic,teclat,CDE,alt-tab,tots els escriptoris,focus segueix el ratolí,prevenció del focus,robatori del focus,política del focus,comportament del focus de la finestra,comportament en pantalla de la finestra
X-KDE-Keywords[da]=fokus,autohæv,hæv,klikhæv,tastatur,CDE,alt-tab,alle skriveborde,fokus følger mus,fokusforhindring,stjæler fokus,fokuspolitik,opførsel for vinduesfokus
X-KDE-Keywords[en_GB]=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behaviour,window screen behaviour
X-KDE-Keywords[es]=foco,auto levantar,levantar,clic para levantar,teclado,CDE,alt-tab,todo el escritorio,el foco sigue al ratón,prevención de foco,robo del foco,política del foco,comportamiento del foco de las ventanas,comportamiento de la pantalla de ventanas
X-KDE-Keywords[et]=fookus,asetus,automaatne esiletoomine,klõpsuga esiletoomine,klaviatuur,CDE,alt-tab,kõik töölauad,fookus järgib hiirt,fookuse vältimine,fookuse röövimine,fookuse reegel,akna fookuse käitumine
X-KDE-Keywords[eu]=fokua,automatikoki igo,igo,egin klik igotzeko,teklatu,CDE,alt-tab,mahaigain guztiak,fokuak saguari jarraitzen dio,foku-prebentzioa,foku-lapurreta,fokuaren gidalerro,leihoen fokuaren portaera,leihoen pantailen portaera
X-KDE-Keywords[fi]=kohdistus,sijoitus,automaattinen nosto,automaattinen nostaminen,nosta,nosta napsauttamalla,näppäimistö,alt-sarkain,kaikki työpöydät,kohdistus seuraa hiirtä,kohdistuksen esto,kohdistuksen varastaminen,kohdistustapa,ikkunoiden kohdistuksen toiminta,ikkunoiden näyttötoiminta
X-KDE-Keywords[fr]=focus, agrandissement automatique, agrandissement, clic d'agrandissement, clavier, CDE, alt-tab, tous les bureaux, focus suivi par la souris, prise de focus, politique de focus, comportement du focus des fenêtres, comportement des fenêtres
X-KDE-Keywords[gl]=foco,erguer automaticamente,erguer,erguer ao premer,teclado,CDE,alt-tab,todo o escritorio,foco que segue o rato,prevención do foco,roubar o foco,política de foco,comportamento de foco de xanela,comportamento de pantalla de xanela
X-KDE-Keywords[id]=fokus,auto naik,naikkan,klik naikkan,keyboard,papan ketik,CDE,alt-tab,semua desktop,fokus mengikuti mouse,pencegahan fokus,pencurian fokus,kebijakan fokus,perilaku fokus window,perilaku layar window
X-KDE-Keywords[it]=fuoco,avanzamento automatico,avanzamento,avanzamento con clic,tastiera,CDE,alt-tab,tutti i desktop,il fuoco segue il mouse,impedisci il fuoco,mantieni il fuoco,regole fuoco,comportamento fuoco finestra, comportamento schermo finestra
X-KDE-Keywords[ko]=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behavior,window screen behavior,초점,키보드,모든 데스크톱,초점,초점 훔치기,초점 훔치기 방지,초점 정책,창 초점 행동,창 화면 행동
X-KDE-Keywords[lt]=fokusavimas,fokusas,automatinis iškėlimas,automatinis iskelimas,automatiškai iškelti į pirmą planą,automatiskai iskelti i pirma plana,iškelti į pirmą planą,iskelti i pirma plana,pakelti,pakėlimas,iškėlimas spustelėjus,iskelimas spustelejus,iškėlimas spustelėjant,iskelimas spustelejant,klaviatūra,klaviatura,CDE,alt-tab,visi darbalaukiai,visi darbastaliai,fokusas seka pelę,fokusas seka pele,fokusas seka paskui pelę,fokusas seka paskui pele,fokusavimas seka pelę,fokusavimas seka pele,fokusavimas seka paskui pelę,fokusavimas seka paskui pele,fokuso prevencija,fokusavimo prevencija,fokuso vogimas,fokusavimo vogimas,fokuso politika,fokusavimo politika,langų fokusavimo elgsena,langų fokuso elgsena,langų fokuso elgesys,lango fokuso elgsena,lango fokuso elgesys,langų fokusavimo elgesys,langų ekrano elgsena,langu ekrano elgsena,langų ekrano elgesys,langu ekrano elgesys,lango ekrano elgsena,lango ekrano elgesys
X-KDE-Keywords[nl]=focus,automatisch omhoog komen,omhoog komen,omhoog komen bij klikken,toetsenbord,CDE,alt-tab,alle bureaubladen,focus volgt muis,voorkomen van focus,focus stelen,focusbeleid,focusgedrag in venster,gedrag van vensterscherm
X-KDE-Keywords[nn]=fokus,autohev,hev,klikk-og-hev,tastatur,CDE,alt-tab,alle skrivebord,fokus følgjer mus,fokushindring,fokussteling,fokuspraksis,fokusåtferd for vindauge,vindaugsåtferd på skjerm
X-KDE-Keywords[pl]=uaktywnienie,auto wznoszenie,wznoszenie,wznoszenie na kliknięcie,klawiatura,CDE,alt-tab,wszystkie pulpity
X-KDE-Keywords[pt]=foco,colocação,elevação automática,elevar,elevar ao carregar,teclado,CDE,alt-tab,todos os ecrãs,foco segue o rato,prevenção do foco,roubo do foco,política de foco,comportamento do foco da janela,comportamento da janela no ecrã
X-KDE-Keywords[pt_BR]=foco,elevação automática,elevar,elevar ao clicar,teclado,CDE,alt-tab,todas as áreas de trabalho,foco segue o mouse,prevenção do foco,captura do foco,política de foco,comportamento do foco da janela,comportamento da janela na tela
X-KDE-Keywords[ru]=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behavior,window screen behavior,фокус,активация окон,автоматически,поднятие,поднимать,клавиатура,весь рабочий стол,фокус следует за мышью,фокус под мышью,похищение фокуса,предотвращение перехвата фокуса,поведение фокуса,окон,поведение экрана
X-KDE-Keywords[sk]=zameranie,umiestnenie,automatické zdvihnutie,zdvihnutie,klik na zdvihnutie,klávesnica,CDE,alt-tab, všetky plochy,zameranie nasleduje mys,predchádzanie zameraniu,kradnutie zamerania,politika zamerania, správania zamerania okien,správania okien obrazovky
+X-KDE-Keywords[sl]=fokus,žarišče,postavitev,postavljanje,samodejni dvig,samodejno dvigovanje,dvig,dvigovanje,dvig na klik,tipkovnica,cde,celotno namizje,fokus sledi miški,žarišče sledi miški,preprečevanje fokusa,preprečevanje žarišča,kraja fokusa,kraja žarišča,pravila osredotočanja,pravila za osredotočanje,obnašanje pri osredotočanju oken,obnašanje pri postavljanju oken v žarišče,obnašanje oken
X-KDE-Keywords[sv]=fokus,fönsterbeteende,animering,höj,höj automatiskt,höj med klick,CDE,alt-tab,alla skrivbord,fokus följer musen,förhindra fokus,stjäla fokus,fokusprincip,fönsterfokusbeteende,fönsterskärmbeteende
X-KDE-Keywords[uk]=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behavior,window screen behavior,фокус,фокусування,автопідняття,підняття,клацання,клавіатура,альт-таб,всі стільниці,фокус за мишею,запобігання,перехід фокуса,правила фокусування,поведінка вікон
X-KDE-Keywords[x-test]=xxfocusxx,xxauto raisexx,xxraisexx,xxclick raisexx,xxkeyboardxx,xxCDExx,xxalt-tabxx,xxall desktopxx,xxfocus follows mousexx,xxfocus preventionxx,xxfocus stealingxx,xxfocus policyxx,xxwindow focus behaviorxx,xxwindow screen behaviorxx
X-KDE-Keywords[zh_CN]=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behavior,window screen behavior,焦点,聚焦,自动升起,升起,点击升起,键盘,全部桌面,焦点跟随鼠标,偷取焦点,焦点策略,窗口焦点行为,窗口屏幕行为
X-KDE-Keywords[zh_TW]=focus,auto raise,raise,click raise,keyboard,CDE,alt-tab,all desktop,focus follows mouse,focus prevention,focus stealing,focus policy,window focus behavior,window screen behavior
diff --git a/kcmkwin/kwinoptions/kwinmoving.desktop b/kcmkwin/kwinoptions/kwinmoving.desktop
index 4806ff761..1938bbe52 100644
--- a/kcmkwin/kwinoptions/kwinmoving.desktop
+++ b/kcmkwin/kwinoptions/kwinmoving.desktop
@@ -1,111 +1,113 @@
[Desktop Entry]
Icon=preferences-system-windows-movement
Type=Service
X-KDE-ServiceTypes=KCModule
Exec=kcmshell5 kwinmoving
X-DocPath=kcontrol/windowbehaviour/index.html#action-moving
Icon=preferences-system-windows-move
X-KDE-Library=kcm_kwinoptions
X-KDE-PluginKeyword=kwinmoving
Name=Window Movement
Name[ca]=Moviment de les finestres
Name[cs]=Pohyb oken
Name[da]=Flytning af vinduer
Name[en_GB]=Window Movement
Name[es]=Movimiento de las ventanas
Name[et]=Akna liigutamine
Name[eu]=Leihoaren mugimendua
Name[fi]=Ikkunoiden siirtäminen
Name[fr]=Déplacement des fenêtres
Name[gl]=Movemento das xanelas
Name[ia]=Movimento de fenestra
Name[id]=Pemindahan Window
Name[it]=Spostamento delle finestre
Name[ko]=창 이동
Name[lt]=Langų perkėlimas
Name[nl]=Verplaatsen van vensters
Name[nn]=Vidaugsflytting
Name[pl]=Przesuwanie okien
Name[pt]=Movimentação das Janelas
Name[pt_BR]=Movimento da janela
Name[ru]=Перемещение окон
Name[sk]=Presuny okien
+Name[sl]=Premikanje oken
Name[sv]=Fönsterförflyttning
Name[uk]=Пересування вікон
Name[x-test]=xxWindow Movementxx
Name[zh_CN]=窗口移动
Name[zh_TW]=視窗移動
Comment=Configure window movement options
Comment[ca]=Configura les opcions de moviment de les finestres
Comment[cs]=Nastavit volby pohybu oken
Comment[da]=Indstil flytning af vinduer
Comment[en_GB]=Configure window movement options
Comment[es]=Configurar las opciones del movimiento de las ventanas
Comment[et]=Akende liigutamise seadistamine
Comment[eu]=Konfiguratu leiho mugimenduaren aukerak
Comment[fi]=Ikkunoiden siirtämisen asetukset
Comment[fr]=Configurer les options de déplacement des fenêtres
Comment[gl]=Configurar o movemento das xanelas
Comment[ia]=Configura optiones de movimento de fenestra
Comment[id]=Konfigurasikan opsi pemindahan window
Comment[it]=Configura opzioni di spostamento delle finestre
Comment[ko]=창 이동 옵션 설정
Comment[lt]=Konfigūruoti langų perkėlimo parinktis
Comment[nl]=Opties voor vensterverplaatsing configureren
Comment[nn]=Set opp vindaugsflytting
Comment[pl]=Ustawienia opcji przesuwania okien
Comment[pt]=Configurar as opções de movimentação das janelas
Comment[pt_BR]=Configure as opções de movimento da janela
Comment[ru]=Настройка поведения при перемещении окон
Comment[sk]=Nastavenie spôsobu presunu okien
+Comment[sl]=Nastavi možnosti premikanja okna
Comment[sv]=Anpassa alternativ för fönsterförflyttning
Comment[uk]=Налаштовування параметрів пересування вікон
Comment[x-test]=xxConfigure window movement optionsxx
Comment[zh_CN]=配置窗口移动选项
Comment[zh_TW]=設定視窗移動選項
X-KDE-Keywords=moving,smart,cascade,maximize,maximise,snap zone,snap,border
X-KDE-Keywords[bs]=pomjeranje,pametno,kaskada,povećali,povećalo,namjestiti zonu,namjestiti,granica
X-KDE-Keywords[ca]=moviment,intel·ligent,cascada,maximització,zona d'ajust,ajust,vora
X-KDE-Keywords[ca@valencia]=moviment,intel·ligent,cascada,maximització,zona d'ajust,ajust,vora
X-KDE-Keywords[da]=flytning,smart,kaskade,maksimer,hægtzone,hægt,kant
X-KDE-Keywords[de]=Verschieben,Gestaffelt,Maximieren,Minimieren,Einrastzone,Ränder
X-KDE-Keywords[el]=κίνηση,έξυπνη,διαδοχική,μεγιστοποίηση,ελαχιστοποίηση,snap zone,snap,περίγραμμα
X-KDE-Keywords[en_GB]=moving,smart,cascade,maximize,maximise,snap zone,snap,border
X-KDE-Keywords[es]=movimiento,inteligente,cascada,maximizar,maximizar,zona de instantánea,instantánea,borde
X-KDE-Keywords[et]=liigutamine,nutikas,kaskaad,maksimeerimine,haardetsoon,haaramine,piire
X-KDE-Keywords[eu]=lekuz aldatzea,adimendun,kaskada,maximizatu,atxikitze-eremu,atxikitu,ertz
X-KDE-Keywords[fi]=siirtäminen,älykäs,porrastus,suurentaminen,tarttuminen,kiinnitysalue,tartunta,kiinnitys,kiinnittyminen,reuna
X-KDE-Keywords[fr]=déplacement, intelligent, cascade, maximiser, maximise, zone de rupture, rupture, bordure
X-KDE-Keywords[gl]=mover,intelixente,solapar,fervenza,maximizar,minimizar,zona de adherencia, adherencia,bordo,beira,bordo
X-KDE-Keywords[hu]=mozgatás,intelligens,lépcsőzetes,maximalizálás,maximalizálás,vonzási távolság,szegély
X-KDE-Keywords[ia]=movente,intelligente,cascada,maximisa,maximisa,zona de ruptura,ruptura,margine
X-KDE-Keywords[id]=pemindahan,cerdas,kaskade,maksimalkan,maksimalkan,zona jepret,jepret,bingkai
X-KDE-Keywords[it]=spostamento,intelligente,cascata,massimizza,zona di aggancio,agganciamento,bordo
X-KDE-Keywords[kk]=moving,smart,cascade,maximize,maximise,snap zone,snap,border
X-KDE-Keywords[km]=moving,smart,cascade,maximize,maximise,snap zone,snap,border
X-KDE-Keywords[ko]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,이동,스마트,계단식,최대화,경계선
X-KDE-Keywords[lt]=perkėlimas,perkelti,perkelimas,išmanus,ismanus,mažiausias persidengimas,maziausias persidengimas,mažiausio persidengimo,maziausio persidengimo,pakopomis,kaskada,išskleisti,isskleisti,isdidinti,išdidinti,pritraukimo zona,traukimo zona,pritraukimas,traukimas,rėmelis,remelis,rėmas,remas
X-KDE-Keywords[nb]=flytting,smart,kaskade,maksimer,gripesone,gripe,kant
X-KDE-Keywords[nds]=Bewegen,klook,överenanner,maximeren,Andockrebeet,andocken,Rahmen,Kant
X-KDE-Keywords[nl]=verplaatsen,smart,cascade,maximaliseren,zone vastzetten,vastzetten,grens
X-KDE-Keywords[nn]=flytting,smart,kaskade,maksimering,gripesone,gripa,kant
X-KDE-Keywords[pl]=przesuwanie,elegancki,kaskada,maksymalizuj,obszar przyciągania,przyciągaj,obramowanie
X-KDE-Keywords[pt]=movimento,inteligente,cascata,maximizar,ajuste à zona,ajuste,contorno
X-KDE-Keywords[pt_BR]=movimento,movimentação,inteligente,cascata,maximizar,ajuste à área,ajuste,borda
X-KDE-Keywords[ru]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,перемещение,каскад,распахнуть,свернуть,захват,привязка,граница
X-KDE-Keywords[sk]=presun,smart,kaskáda,maximalizácia,miinmalizácia,oblasť prichytenia,prichytenie,rám
X-KDE-Keywords[sl]=premikanje,pametno premikanje,kaskada,povečaj,razpni,območje pripenjanja,pripenjanje,rob,robovi,obroba,obrobe
X-KDE-Keywords[sr]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,померање,паметно,наслагано,максимизуј,зона лепљења,лепљење,ивица
X-KDE-Keywords[sr@ijekavian]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,померање,паметно,наслагано,максимизуј,зона лепљења,лепљење,ивица
X-KDE-Keywords[sr@ijekavianlatin]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,pomeranje,pametno,naslagano,maksimizuj,zona lepljenja,lepljenje,ivica
X-KDE-Keywords[sr@latin]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,pomeranje,pametno,naslagano,maksimizuj,zona lepljenja,lepljenje,ivica
X-KDE-Keywords[sv]=flytta,smart,kaskad,maximera,låszon,lås,kanter
X-KDE-Keywords[tr]=taşıma,akıllı,döşeme,büyütme,en büyük,kopma alanı,kopma,kenarlık
X-KDE-Keywords[uk]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,пересування,кмітливе,каскадом,максимізувати,розгорнути,прилипання,зона прилипання,межа
X-KDE-Keywords[x-test]=xxmovingxx,xxsmartxx,xxcascadexx,xxmaximizexx,xxmaximisexx,xxsnap zonexx,xxsnapxx,xxborderxx
X-KDE-Keywords[zh_CN]=moving,smart,cascade,maximize,maximise,snap zone,snap,border,移动,智能,最大化,级联,吸附区,吸附,边框
X-KDE-Keywords[zh_TW]=moving,smart,cascade,maximize,maximise,snap zone,snap,border
diff --git a/kcmkwin/kwinoptions/kwinoptions.desktop b/kcmkwin/kwinoptions/kwinoptions.desktop
index 69668445c..8185251ac 100644
--- a/kcmkwin/kwinoptions/kwinoptions.desktop
+++ b/kcmkwin/kwinoptions/kwinoptions.desktop
@@ -1,174 +1,175 @@
[Desktop Entry]
Exec=kcmshell5 kwinoptions
Icon=preferences-system-windows-actions
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kcontrol/windowbehaviour/index.html
X-KDE-Library=kcm_kwinoptions
X-KDE-PluginKeyword=kwinoptions
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=windowmanagement
X-KDE-Weight=40
Name=Window Behavior
Name[af]=Venstergedrag
Name[ar]=سلوك النوافذ
Name[be]=Паводзіны вокнаў
Name[be@latin]=Pavodziny akna
Name[bg]=Поведение на прозорците
Name[bn]=উইণ্ডো আচরণ
Name[bn_IN]=উইন্ডোর আচরণ
Name[br]=Emzalc'h ar prenester
Name[bs]=Ponašanje prozora
Name[ca]=Comportament de les finestres
Name[ca@valencia]=Comportament de les finestres
Name[cs]=Chování oken
Name[csb]=Ùchòwanié òkna
Name[cy]=Ymddygiad Ffenestri
Name[da]=Vinduesopførsel
Name[de]=Fensterverhalten
Name[el]=Συμπεριφορά παραθύρων
Name[en_GB]=Window Behaviour
Name[eo]=Fenestrokonduto
Name[es]=Comportamiento de las ventanas
Name[et]=Akende käitumine
Name[eu]=Leihoaren portaera
Name[fa]=رفتار پنجره
Name[fi]=Ikkunoiden toiminta
Name[fr]=Comportement des fenêtres
Name[fy]=Finstergedrach
Name[ga]=Oibriú na bhFuinneog
Name[gl]=Comportamento das xanelas
Name[gu]=વિન્ડો વર્તણૂક
Name[he]=התנהגות חלונות
Name[hi]=विंडो व्यवहार
Name[hne]=विंडो व्यवहार
Name[hr]=Ponašanje prozora
Name[hu]=Ablakműveletek
Name[ia]=Comportamento de fenestra
Name[id]=Perilaku Window
Name[is]=Hegðun glugga
Name[it]=Comportamento delle finestre
Name[ja]=ウィンドウの挙動
Name[ka]=ფანჯრის ქცევა
Name[kk]=Терезе қасиеттері
Name[km]=ឥរិយាបថបង្អួច
Name[kn]=ಕಿಟಕಿ ವರ್ತನೆ
Name[ko]=창 동작
Name[ku]=Helwesta Paceyan
Name[lt]=Langų elgsena
Name[lv]=Logu izturēšanās
Name[mai]=विंडो व्यवहार
Name[mk]=Однесување на прозорци
Name[ml]=ജാലകത്തിന്റെ വിശേഷത
Name[mr]=चौकट वर्तन
Name[nb]=Vindusoppførsel
Name[nds]=Finsterbedregen
Name[ne]=सञ्झ्याल व्यवहार
Name[nl]=Venstergedrag
Name[nn]=Vindaugsåtferd
Name[pa]=ਵਿੰਡੋ ਰਵੱਈਆ
Name[pl]=Zachowania okien
Name[pt]=Comportamento das Janelas
Name[pt_BR]=Comportamento das janelas
Name[ro]=Comportament fereastră
Name[ru]=Поведение окон
Name[se]=Láseláhtten
Name[si]=කවුළු හැසිරීම
Name[sk]=Správanie okien
Name[sl]=Obnašanje oken
Name[sr]=Понашање прозора
Name[sr@ijekavian]=Понашање прозора
Name[sr@ijekavianlatin]=Ponašanje prozora
Name[sr@latin]=Ponašanje prozora
Name[sv]=Fönsterbeteende
Name[ta]=சாளர நடத்தை
Name[te]=విండో ప్రవర్తన
Name[th]=พฤติกรรมของหน้าต่าง
Name[tr]=Pencere Davranışı
Name[ug]=كۆزنەكنىڭ ئىش-ھەرىكەتلىرى
Name[uk]=Поведінка вікон
Name[uz]=Oynaning xususiyatlari
Name[uz@cyrillic]=Ойнанинг хусусиятлари
Name[vi]=Ứng xử của Cửa sổ
Name[wa]=Dujhance des fniesses
Name[xh]=Ukuziphatha kwe Window
Name[x-test]=xxWindow Behaviorxx
Name[zh_CN]=窗口行为
Name[zh_TW]=視窗行為
Comment=Configure window actions and behavior
Comment[ca]=Configura les accions i comportament de les finestres
Comment[cs]=Nastavte činností a chování oken
Comment[da]=Indstil vindueshandlinger og -opførsel
Comment[de]=Fenster-Aktionen und -verhalten einrichten
Comment[en_GB]=Configure window actions and behaviour
Comment[es]=Configurar las acciones y el comportamiento de las ventanas
Comment[et]=Akende toimingute ja käitumise seadistamine
Comment[eu]=Konfiguratu leihoaren ekintzak eta jokabidea
Comment[fi]=Ikkunatoimintojen asetukset
Comment[fr]=Configurer les actions et le comportement des fenêtres
Comment[gl]=Configurar o comportamento e as accións das xanelas
Comment[ia]=Cnfigura comportamento e actiones de fenestra
Comment[id]=Konfigurasikan perilaku dan aksi window
Comment[it]=Configura azioni e comportamento delle finestre
Comment[ko]=창 동작과 행동 설정
Comment[lt]=Konfigūruoti langų veiksmus ir elgseną
Comment[nl]=Vensteracties en gedrag configureren
Comment[nn]=Set opp utsjånad og åtferd for vindauge
Comment[pl]=Ustawienia działań i zachowań okien
Comment[pt]=Configurar as acções e comportamento das janelas
Comment[pt_BR]=Configure as ações e comportamento das janelas
Comment[ru]=Настройка поведения окон
Comment[sk]=Nastaviť akcie a správanie okien
+Comment[sl]=Nastavi dejanja in obnašanje oken
Comment[sv]=Anpassa fönsteråtgärder och beteende
Comment[uk]=Налаштовування реакції та поведінки вікон
Comment[x-test]=xxConfigure window actions and behaviorxx
Comment[zh_CN]=配置窗口操作和行为
Comment[zh_TW]=設定視窗動作及行為
X-KDE-Keywords=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick
X-KDE-Keywords[bs]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,fokus,pozicioniranje,ponašanje prozora,akcije prozora,animacija,podizanje,okvir,naslovna traka
X-KDE-Keywords[ca]=focus,emplaçament,comportament de la finestra,accions de la finestra,animació,elevació,elevació automàtica,finestres,marc,barra de títol,clic doble
X-KDE-Keywords[ca@valencia]=focus,emplaçament,comportament de la finestra,accions de la finestra,animació,elevació,elevació automàtica,finestres,marc,barra de títol,clic doble
X-KDE-Keywords[da]=fokus,placering,vinduesopførsel,vindueshandlinger,animation,hæv,autohæv,vinduesramme,titelbjælke,dobbeltklik
X-KDE-Keywords[de]=Aktivierung,Platzierung,Fensterverhalten,Fensteraktionen,Animation,Nach vorn/hinten, Fenster,Rahmen,Umrandung,Titelleiste,Doppelklick
X-KDE-Keywords[el]=εστίαση,τοποθέτηση,συμπεριφορά παραθύρου,κίνηση εικόνας,αύξηση,αυτόματη αύξηση,παράθυρα,πλαίσιο,γραμμή τίτλου,διπλό κλικ
X-KDE-Keywords[en_GB]=focus,placement,window behaviour,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick
X-KDE-Keywords[es]=foco,posicionamiento,comportamiento de las ventanas,acciones de las ventanas,animación,elevación,autoelevación,ventanas,marco,barra de título,doble clic
X-KDE-Keywords[et]=fookus,asetus,paigutus,akende käitumine,aknatoimingud,animeerimine,animatsioon,esiletoomine,automaatne esiletoomine,aknad,raam,tiitliriba,topeltklõps
X-KDE-Keywords[eu]=foku,kokaleku,leihoen portaera,leiho-ekintzak,animazio,igo,automatikoki igo,leihoak,marko,titulu-barra,klik bikoitz
X-KDE-Keywords[fi]=kohdistus,sijoittelu,sijoitus,ikkunoiden toiminta,ikkunoiden toiminnot,animaatio,nosta,automaattinen nosto,ikkunat,kehys,otsikkopalkki,kaksoisnapsautus,tuplanapsautus,kaksoisklikkaus,tuplaklikkaus
X-KDE-Keywords[fr]=focus, placement, comportement de la fenêtre, actions sur les fenêtres, animation, agrandissement, agrandissement automatique, fenêtres, cadre, barre de titre, double clic
X-KDE-Keywords[gl]=foco,posicionamento,comportamento das xanelas,accións das xanelas, animación,xanelas,moldura,barra de título,marco
X-KDE-Keywords[hu]=fókusz,elhelyezés,ablakműködés,ablakműveletek,animáció,felemelés,automatikus felemelés,ablakok,keret,címsor,dupla kattintás
X-KDE-Keywords[ia]=focus,placiamento,comportamento de fenestra,actiones de fenestra,animation,altiar,auto altiar,fenestras,quadro,barra de titulo,duple click
X-KDE-Keywords[id]=fokus,penempatan,perilaku window,aksi window,animasi,naikkan,naikkan otomatis,window,bingkai,titlebar,klik ganda
X-KDE-Keywords[it]=fuoco,posizionamento,comportamento della finestra,azioni delle finestre,animazione,sollevamento,sollevamento automatico,finestre,riquadro,barra del titolo,doppio clic
X-KDE-Keywords[ko]=focus,placement,window behavior,animation,raise,auto raise,windows,frame,titlebar,doubleclick,초점,위치,창 행동,애니메이션,올리기,창,프레임,제목 표시줄
X-KDE-Keywords[lt]=fokusas,fokusavimas,išdėstymas,isdestymas,padėjimas,padejimas,lango elgsena,langų elgsena,langu elgsena,lango elgesys,langų elgsesys,langu elgesys,lango veiksmai,langų veiksmai,langu veiksmai,animacija,animacijos,iškelti į pirmą planą,iskelti i pirma plana,iškėlimas į pirmą planą,iskelimas i pirma plana,automatiškai iškelti į pirmą planą,automatiskai iskelti i pirma plana,automatinis iškėlimas į pirmą planą,automatinis iskelimas i pirma plana,langas,langai,rėmelis,remelis,rėmas,remas,antraštės juosta,antrastes juosta,pavadinimo juosta,dvikartis spustelėjimas,dvikartis spustelejimas,dvigubas spustelėjimas,dvigubas spustelejimas
X-KDE-Keywords[nb]=fokus,plassering,vindusoppførsel,vindushandlinger,animering,hev,autohev,vinduer,ramme,tittellinje,dobbeltklikk
X-KDE-Keywords[nds]=Fokus,Platzeren,Finsterbedregen,Finsterakschonen,Animeren,na vörn,automaatsch,Finstern,Rahmen,Titelbalken,Dubbelklick
X-KDE-Keywords[nl]=focus,plaatsing,venstegedrag,vensteracties,animatie,omhoog,automatisch omhoog,vensters,frame,titelbalk,dubbelklik
X-KDE-Keywords[nn]=fokus,plassering,vindaugsåtferd,vindaugshandlingar,animering,hev,autohev,vindauge,ramme,tittellinje,dobbeltklikk
X-KDE-Keywords[pl]=uaktywnienie,umieszczenie,zachowanie okna,działania okien,animacja,wzniesienie,auto-wzniesienie, okna,ramka,pasek tytułu,podwójne kliknięcie
X-KDE-Keywords[pt]=foco,colocação,comportamento da janela,acções das janelas,animação,elevar,elevar automaticamente,janelas,contorno,barra de título,duplo-click
X-KDE-Keywords[pt_BR]=foco,colocação,comportamento da janela,ações da janela,animação,elevar,elevar automaticamente,janelas,contorno,barra de título,clique duplo
X-KDE-Keywords[ru]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,фокус,местоположение,поведение окон,анимация,увеличение,автоувеличение,окна,рамка,заголовок,двойной щелчок,действия над окнами
X-KDE-Keywords[sk]=zameranie,umiestnenie,správanie okien,animácia,zdvihnúť,automaticky zdvihnúť,okná,rám,záhlavie,dvojklik
X-KDE-Keywords[sl]=fokus,žarišče,postavitev,postavljanje,obnašanje oken,dejanja oken,animacija,dvig,samodejni dvig,okna,okvir,naslovna vrstica,dvojni klik,dvoklik
X-KDE-Keywords[sr]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,фокус,постављење,понашање прозора,радње над прозорима,анимација,подигни,аутоматско подизање,прозор,оквир,насловна трака,двоклик
X-KDE-Keywords[sr@ijekavian]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,фокус,постављење,понашање прозора,радње над прозорима,анимација,подигни,аутоматско подизање,прозор,оквир,насловна трака,двоклик
X-KDE-Keywords[sr@ijekavianlatin]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,fokus,postavljenje,ponašanje prozora,radnje nad prozorima,animacija,podigni,automatsko podizanje,prozor,okvir,naslovna traka,dvoklik
X-KDE-Keywords[sr@latin]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,fokus,postavljenje,ponašanje prozora,radnje nad prozorima,animacija,podigni,automatsko podizanje,prozor,okvir,naslovna traka,dvoklik
X-KDE-Keywords[sv]=fokus,placering,fönsterbeteende,animering,höj,höj automatiskt,fönster,ram,namnlist,dubbelklick
X-KDE-Keywords[tr]=odak,yerleşim,pencere davranışı,pencere eylemleri,canlandırma,yükselt,otomatik yükselt,pencereler,çerçeve,başlık çubuğu,çift tıklama
X-KDE-Keywords[uk]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,фокус,розташування,місце,вікно,поведінка,поведінка вікон,дії,реакція,дії з вікнами,реакція вікон,анімація,підняти,підняття,автоматична,автоматично,рамка,заголовок,смужка заголовка,клацання,подвійне
X-KDE-Keywords[x-test]=xxfocusxx,xxplacementxx,xxwindow behaviorxx,xxwindow actionsxx,xxanimationxx,xxraisexx,xxauto raisexx,xxwindowsxx,xxframexx,xxtitlebarxx,xxdoubleclickxx
X-KDE-Keywords[zh_CN]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick,焦点,位置,窗口行为,窗口动作,动画,升起,自动升起,窗口,边框,标题栏,双击
X-KDE-Keywords[zh_TW]=focus,placement,window behavior,window actions,animation,raise,auto raise,windows,frame,titlebar,doubleclick
Categories=Qt;KDE;X-KDE-settings-looknfeel;
diff --git a/kcmkwin/kwinoptions/kwinoptions_settings.kcfg b/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
index 5ad052b04..959c0dd6d 100644
--- a/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
+++ b/kcmkwin/kwinoptions/kwinoptions_settings.kcfg
@@ -1,322 +1,368 @@
false
10
0
100
10
0
100
0
0
100
false
false
250
0
0
true
Maximize
Maximize
MaximizeVerticalOnly
MaximizeVerticalOnly
+
+ ClickToFocus
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+ 750
+ 0
+
+
+
+ 300
+ 0
+
+
+
+ false
+
+
+
+ true
+
+
+
+ false
+
+
+
+ true
+
+
+
+ 1
+ 0
+ 4
+
+
Raise
Nothing
OperationsMenu
Nothing
ActivateAndRaise
Nothing
OperationsMenu
ActivateRaisePassClick
ActivatePassClick
ActivatePassClick
Scroll
Alt
Move
ToggleRaiseAndLower
Resize
Nothing
diff --git a/kcmkwin/kwinoptions/kwinoptions_settings.kcfgc b/kcmkwin/kwinoptions/kwinoptions_settings.kcfgc
index 7135009fb..2deb14378 100644
--- a/kcmkwin/kwinoptions/kwinoptions_settings.kcfgc
+++ b/kcmkwin/kwinoptions/kwinoptions_settings.kcfgc
@@ -1,6 +1,5 @@
File=kwinoptions_settings.kcfg
ClassName=KWinOptionsSettings
Mutators=true
DefaultValueGetters=true
ParentInConstructor=true
-Singleton=true
diff --git a/kcmkwin/kwinoptions/main.cpp b/kcmkwin/kwinoptions/main.cpp
index d056e5a62..2116567c7 100644
--- a/kcmkwin/kwinoptions/main.cpp
+++ b/kcmkwin/kwinoptions/main.cpp
@@ -1,244 +1,237 @@
/*
*
* Copyright (c) 2001 Waldo Bastian
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "main.h"
#include
//Added by qt3to4:
#include
#include
#include
#include
#include
#include
#include
#include "mouse.h"
#include "windows.h"
+#include "kwinoptions_settings.h"
K_PLUGIN_FACTORY_DECLARATION(KWinOptionsFactory)
class KFocusConfigStandalone : public KFocusConfig
{
Q_OBJECT
public:
KFocusConfigStandalone(QWidget* parent, const QVariantList &)
- : KFocusConfig(true, new KConfig("kwinrc"), parent)
+ : KFocusConfig(true, new KWinOptionsSettings(this), parent)
{}
};
class KMovingConfigStandalone : public KMovingConfig
{
Q_OBJECT
public:
KMovingConfigStandalone(QWidget* parent, const QVariantList &)
- : KMovingConfig(true, parent)
+ : KMovingConfig(true, new KWinOptionsSettings(this), parent)
{}
};
class KAdvancedConfigStandalone : public KAdvancedConfig
{
Q_OBJECT
public:
KAdvancedConfigStandalone(QWidget* parent, const QVariantList &)
- : KAdvancedConfig(true, parent)
+ : KAdvancedConfig(true, new KWinOptionsSettings(this), parent)
{}
};
KWinOptions::KWinOptions(QWidget *parent, const QVariantList &)
: KCModule(parent)
{
- mConfig = new KConfig("kwinrc");
+ mSettings = new KWinOptionsSettings(this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
tab = new QTabWidget(this);
layout->addWidget(tab);
- mFocus = new KFocusConfig(false, mConfig, this);
+ mFocus = new KFocusConfig(false, mSettings, this);
mFocus->setObjectName(QLatin1String("KWin Focus Config"));
tab->addTab(mFocus, i18n("&Focus"));
connect(mFocus, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
+ connect(mFocus, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
- mTitleBarActions = new KTitleBarActionsConfig(false, this);
+ // Need to relay unmanagedWidgetDefaultState and unmanagedWidgetChangeState to wrapping KCModule
+ connect(mFocus, &KFocusConfig::unmanagedWidgetDefaulted, this, &KWinOptions::unmanagedWidgetDefaultState);
+ connect(mFocus, &KFocusConfig::unmanagedWidgetStateChanged, this, &KWinOptions::unmanagedWidgetChangeState);
+
+ mTitleBarActions = new KTitleBarActionsConfig(false, mSettings, this);
mTitleBarActions->setObjectName(QLatin1String("KWin TitleBar Actions"));
tab->addTab(mTitleBarActions, i18n("Titlebar A&ctions"));
connect(mTitleBarActions, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
connect(mTitleBarActions, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
- mWindowActions = new KWindowActionsConfig(false, this);
+ mWindowActions = new KWindowActionsConfig(false, mSettings, this);
mWindowActions->setObjectName(QLatin1String("KWin Window Actions"));
tab->addTab(mWindowActions, i18n("W&indow Actions"));
connect(mWindowActions, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
connect(mWindowActions, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
- mMoving = new KMovingConfig(false, this);
+ mMoving = new KMovingConfig(false, mSettings, this);
mMoving->setObjectName(QLatin1String("KWin Moving"));
tab->addTab(mMoving, i18n("Mo&vement"));
connect(mMoving, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
connect(mMoving, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
- mAdvanced = new KAdvancedConfig(false, this);
+ mAdvanced = new KAdvancedConfig(false, mSettings, this);
mAdvanced->setObjectName(QLatin1String("KWin Advanced"));
tab->addTab(mAdvanced, i18n("Adva&nced"));
connect(mAdvanced, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
connect(mAdvanced, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
KAboutData *about =
new KAboutData(QStringLiteral("kcmkwinoptions"), i18n("Window Behavior Configuration Module"),
QString(), QString(), KAboutLicense::GPL,
i18n("(c) 1997 - 2002 KWin and KControl Authors"));
about->addAuthor(i18n("Matthias Ettrich"), QString(), "ettrich@kde.org");
about->addAuthor(i18n("Waldo Bastian"), QString(), "bastian@kde.org");
about->addAuthor(i18n("Cristian Tibirna"), QString(), "tibirna@kde.org");
about->addAuthor(i18n("Matthias Kalle Dalheimer"), QString(), "kalle@kde.org");
about->addAuthor(i18n("Daniel Molkentin"), QString(), "molkentin@kde.org");
about->addAuthor(i18n("Wynn Wilkes"), QString(), "wynnw@caldera.com");
about->addAuthor(i18n("Pat Dowler"), QString(), "dowler@pt1B1106.FSH.UVic.CA");
about->addAuthor(i18n("Bernd Wuebben"), QString(), "wuebben@kde.org");
about->addAuthor(i18n("Matthias Hoelzer-Kluepfel"), QString(), "hoelzer@kde.org");
setAboutData(about);
}
-KWinOptions::~KWinOptions()
-{
- delete mConfig;
-}
-
void KWinOptions::load()
{
- mConfig->reparseConfiguration();
- mFocus->load();
mTitleBarActions->load();
mWindowActions->load();
mMoving->load();
mAdvanced->load();
- emit KCModule::changed(false);
+ // mFocus is last because it may send unmanagedWidgetStateChanged
+ // that need to have the final word
+ mFocus->load();
}
-
void KWinOptions::save()
{
mFocus->save();
mTitleBarActions->save();
mWindowActions->save();
mMoving->save();
mAdvanced->save();
emit KCModule::changed(false);
- // Send signal to kwin
- mConfig->sync();
+
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
void KWinOptions::defaults()
{
- mFocus->defaults();
mTitleBarActions->defaults();
mWindowActions->defaults();
mMoving->defaults();
mAdvanced->defaults();
+ // mFocus is last because it may send unmanagedWidgetDefaulted
+ // that need to have the final word
+ mFocus->defaults();
}
QString KWinOptions::quickHelp() const
{
return i18n("Window Behavior
Here you can customize the way windows behave when being"
" moved, resized or clicked on. You can also specify a focus policy as well as a placement"
" policy for new windows.
"
" Please note that this configuration will not take effect if you do not use"
" KWin as your window manager. If you do use a different window manager, please refer to its documentation"
" for how to customize window behavior.
");
}
KActionsOptions::KActionsOptions(QWidget *parent, const QVariantList &)
: KCModule(parent)
{
- mConfig = new KConfig("kwinrc");
+ mSettings = new KWinOptionsSettings(this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
tab = new QTabWidget(this);
layout->addWidget(tab);
- mTitleBarActions = new KTitleBarActionsConfig(false, this);
+ mTitleBarActions = new KTitleBarActionsConfig(false, mSettings, this);
mTitleBarActions->setObjectName(QLatin1String("KWin TitleBar Actions"));
tab->addTab(mTitleBarActions, i18n("&Titlebar Actions"));
connect(mTitleBarActions, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
connect(mTitleBarActions, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
- mWindowActions = new KWindowActionsConfig(false, this);
+ mWindowActions = new KWindowActionsConfig(false, mSettings, this);
mWindowActions->setObjectName(QLatin1String("KWin Window Actions"));
tab->addTab(mWindowActions, i18n("Window Actio&ns"));
connect(mWindowActions, qOverload(&KCModule::changed), this, qOverload(&KCModule::changed));
connect(mWindowActions, qOverload(&KCModule::defaulted), this, qOverload(&KCModule::defaulted));
}
-KActionsOptions::~KActionsOptions()
-{
- delete mConfig;
-}
-
void KActionsOptions::load()
{
mTitleBarActions->load();
mWindowActions->load();
}
void KActionsOptions::save()
{
mTitleBarActions->save();
mWindowActions->save();
emit KCModule::changed(false);
- // Send signal to kwin
- mConfig->sync();
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
void KActionsOptions::defaults()
{
mTitleBarActions->defaults();
mWindowActions->defaults();
}
void KActionsOptions::moduleChanged(bool state)
{
emit KCModule::changed(state);
}
K_PLUGIN_FACTORY_DEFINITION(KWinOptionsFactory,
registerPlugin("kwinactions");
registerPlugin("kwinfocus");
registerPlugin("kwinmoving");
registerPlugin("kwinadvanced");
registerPlugin("kwinoptions");
)
#include "main.moc"
-#include "moc_main.cpp"
diff --git a/kcmkwin/kwinoptions/main.h b/kcmkwin/kwinoptions/main.h
index 50a8bcd8a..f85d61d5a 100644
--- a/kcmkwin/kwinoptions/main.h
+++ b/kcmkwin/kwinoptions/main.h
@@ -1,93 +1,90 @@
/*
* main.h
*
* Copyright (c) 2001 Waldo Bastian
*
* Requires the Qt widget libraries, available at no cost at
* https://www.qt.io/
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __MAIN_H__
#define __MAIN_H__
#include
#include
-class KConfig;
+class KWinOptionsSettings;
class KFocusConfig;
class KTitleBarActionsConfig;
class KWindowActionsConfig;
class KAdvancedConfig;
class KMovingConfig;
class KWinOptions : public KCModule
{
Q_OBJECT
public:
KWinOptions(QWidget *parent, const QVariantList &args);
- ~KWinOptions() override;
void load() override;
void save() override;
void defaults() override;
QString quickHelp() const override;
private:
QTabWidget *tab;
KFocusConfig *mFocus;
KTitleBarActionsConfig *mTitleBarActions;
KWindowActionsConfig *mWindowActions;
KMovingConfig *mMoving;
KAdvancedConfig *mAdvanced;
- KConfig *mConfig;
+ KWinOptionsSettings *mSettings;
};
class KActionsOptions : public KCModule
{
Q_OBJECT
public:
KActionsOptions(QWidget *parent, const QVariantList &args);
- ~KActionsOptions() override;
void load() override;
void save() override;
void defaults() override;
protected Q_SLOTS:
void moduleChanged(bool state);
-
private:
QTabWidget *tab;
KTitleBarActionsConfig *mTitleBarActions;
KWindowActionsConfig *mWindowActions;
- KConfig *mConfig;
+ KWinOptionsSettings *mSettings;
};
#endif
diff --git a/kcmkwin/kwinoptions/mouse.cpp b/kcmkwin/kwinoptions/mouse.cpp
index 8be4dc6ff..22c8a3031 100644
--- a/kcmkwin/kwinoptions/mouse.cpp
+++ b/kcmkwin/kwinoptions/mouse.cpp
@@ -1,223 +1,225 @@
/*
*
* Copyright (c) 1998 Matthias Ettrich
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mouse.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kwinoptions_settings.h"
namespace
{
QPixmap maxButtonPixmaps[3];
void createMaxButtonPixmaps()
{
char const *maxButtonXpms[][3 + 13] = {
{
nullptr, nullptr, nullptr,
"...............",
".......#.......",
"......###......",
".....#####.....",
"..#....#....#..",
".##....#....##.",
"###############",
".##....#....##.",
"..#....#....#..",
".....#####.....",
"......###......",
".......#.......",
"..............."
},
{
nullptr, nullptr, nullptr,
"...............",
".......#.......",
"......###......",
".....#####.....",
".......#.......",
".......#.......",
".......#.......",
".......#.......",
".......#.......",
".....#####.....",
"......###......",
".......#.......",
"..............."
},
{
nullptr, nullptr, nullptr,
"...............",
"...............",
"...............",
"...............",
"..#.........#..",
".##.........##.",
"###############",
".##.........##.",
"..#.........#..",
"...............",
"...............",
"...............",
"..............."
},
};
QByteArray baseColor(". c " + KColorScheme(QPalette::Active, KColorScheme::View).background().color().name().toLatin1());
QByteArray textColor("# c " + KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name().toLatin1());
for (int t = 0; t < 3; ++t) {
maxButtonXpms[t][0] = "15 13 2 1";
maxButtonXpms[t][1] = baseColor.constData();
maxButtonXpms[t][2] = textColor.constData();
maxButtonPixmaps[t] = QPixmap(maxButtonXpms[t]);
maxButtonPixmaps[t].setMask(maxButtonPixmaps[t].createHeuristicMask());
}
}
} // namespace
KWinMouseConfigForm::KWinMouseConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(parent);
}
KWinActionsConfigForm::KWinActionsConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(parent);
}
void KTitleBarActionsConfig::paletteChanged()
{
createMaxButtonPixmaps();
for (int i=0; i<3; ++i) {
m_ui->kcfg_MaximizeButtonLeftClickCommand->setItemIcon(i, maxButtonPixmaps[i]);
m_ui->kcfg_MaximizeButtonMiddleClickCommand->setItemIcon(i, maxButtonPixmaps[i]);
m_ui->kcfg_MaximizeButtonRightClickCommand->setItemIcon(i, maxButtonPixmaps[i]);
}
}
-KTitleBarActionsConfig::KTitleBarActionsConfig(bool _standAlone, QWidget *parent)
+KTitleBarActionsConfig::KTitleBarActionsConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
: KCModule(parent), standAlone(_standAlone)
, m_ui(new KWinMouseConfigForm(this))
+ , m_settings(settings)
{
- addConfig(KWinOptionsSettings::self(), this);
+ addConfig(m_settings, this);
// create the items for the maximize button actions
createMaxButtonPixmaps();
for (int i=0; i<3; ++i) {
m_ui->kcfg_MaximizeButtonLeftClickCommand->addItem(maxButtonPixmaps[i], QString());
m_ui->kcfg_MaximizeButtonMiddleClickCommand->addItem(maxButtonPixmaps[i], QString());
m_ui->kcfg_MaximizeButtonRightClickCommand->addItem(maxButtonPixmaps[i], QString());
}
createMaximizeButtonTooltips(m_ui->kcfg_MaximizeButtonLeftClickCommand);
createMaximizeButtonTooltips(m_ui->kcfg_MaximizeButtonMiddleClickCommand);
createMaximizeButtonTooltips(m_ui->kcfg_MaximizeButtonRightClickCommand);
load();
}
void KTitleBarActionsConfig::createMaximizeButtonTooltips(KComboBox *combo)
{
combo->setItemData(0, i18n("Maximize"), Qt::ToolTipRole);
combo->setItemData(1, i18n("Maximize (vertical only)"), Qt::ToolTipRole);
combo->setItemData(2, i18n("Maximize (horizontal only)"), Qt::ToolTipRole);
}
void KTitleBarActionsConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
// Workaround KCModule::showEvent() calling load(), see bug 163817
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KTitleBarActionsConfig::changeEvent(QEvent *ev)
{
if (ev->type() == QEvent::PaletteChange) {
paletteChanged();
}
ev->accept();
}
void KTitleBarActionsConfig::save()
{
KCModule::save();
if (standAlone) {
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
}
-KWindowActionsConfig::KWindowActionsConfig(bool _standAlone, QWidget *parent)
+KWindowActionsConfig::KWindowActionsConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
: KCModule(parent), standAlone(_standAlone)
, m_ui(new KWinActionsConfigForm(this))
+ , m_settings(settings)
{
- addConfig(KWinOptionsSettings::self(), this);
+ addConfig(m_settings, this);
load();
}
void KWindowActionsConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KWindowActionsConfig::save()
{
KCModule::save();
if (standAlone) {
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
}
diff --git a/kcmkwin/kwinoptions/mouse.h b/kcmkwin/kwinoptions/mouse.h
index cbb5f4352..b6cf62a48 100644
--- a/kcmkwin/kwinoptions/mouse.h
+++ b/kcmkwin/kwinoptions/mouse.h
@@ -1,96 +1,100 @@
/*
* mouse.h
*
* Copyright (c) 1998 Matthias Ettrich
*
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KKWMMOUSECONFIG_H__
#define __KKWMMOUSECONFIG_H__
class KConfig;
#include
#include
#include
#include "ui_actions.h"
#include "ui_mouse.h"
+class KWinOptionsSettings;
+
class KWinMouseConfigForm : public QWidget, public Ui::KWinMouseConfigForm
{
Q_OBJECT
public:
explicit KWinMouseConfigForm(QWidget* parent);
};
class KWinActionsConfigForm : public QWidget, public Ui::KWinActionsConfigForm
{
Q_OBJECT
public:
explicit KWinActionsConfigForm(QWidget* parent);
};
class KTitleBarActionsConfig : public KCModule
{
Q_OBJECT
public:
- KTitleBarActionsConfig(bool _standAlone, QWidget *parent);
+ KTitleBarActionsConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent);
void save() override;
protected:
void showEvent(QShowEvent *ev) override;
void changeEvent(QEvent *ev) override;
private:
bool standAlone;
KWinMouseConfigForm *m_ui;
+ KWinOptionsSettings *m_settings;
void createMaximizeButtonTooltips(KComboBox* combo);
private Q_SLOTS:
void paletteChanged();
};
class KWindowActionsConfig : public KCModule
{
Q_OBJECT
public:
- KWindowActionsConfig(bool _standAlone, QWidget *parent);
+ KWindowActionsConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent);
void save() override;
protected:
void showEvent(QShowEvent *ev) override;
private:
bool standAlone;
KWinActionsConfigForm *m_ui;
+ KWinOptionsSettings *m_settings;
};
#endif
diff --git a/kcmkwin/kwinoptions/windows.cpp b/kcmkwin/kwinoptions/windows.cpp
index a05015031..ecc81b653 100644
--- a/kcmkwin/kwinoptions/windows.cpp
+++ b/kcmkwin/kwinoptions/windows.cpp
@@ -1,442 +1,305 @@
/*
* windows.cpp
*
* Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca
* Copyright (c) 2001 Waldo Bastian bastian@kde.org
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
#include "windows.h"
#include "kwinoptions_settings.h"
#include
#include
-// kwin config keywords
-#define KWIN_FOCUS "FocusPolicy"
-#define KWIN_AUTORAISE_INTERVAL "AutoRaiseInterval"
-#define KWIN_AUTORAISE "AutoRaise"
-#define KWIN_DELAYFOCUS_INTERVAL "DelayFocusInterval"
-#define KWIN_CLICKRAISE "ClickRaise"
-#define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel"
-#define KWIN_INACTIVE_SKIP_TASKBAR "InactiveTabsSkipTaskbar"
-#define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus"
-#define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen"
-
-#define CLICK_TO_FOCUS 0
-#define FOCUS_FOLLOWS_MOUSE 2
-#define FOCUS_UNDER_MOUSE 4
-#define FOCUS_STRICTLY_UNDER_MOUSE 5
+#include "kwinoptions_settings.h"
+#include
-
-KFocusConfig::~KFocusConfig()
-{
- if (standAlone)
- delete config;
-}
+#define CLICK_TO_FOCUS 0
+#define CLICK_TO_FOCUS_MOUSE_PRECEDENT 1
+#define FOCUS_FOLLOWS_MOUSE 2
+#define FOCUS_FOLLOWS_MOUSE_PRECEDENT 3
+#define FOCUS_UNDER_MOUSE 4
+#define FOCUS_STRICTLY_UNDER_MOUSE 5
KWinFocusConfigForm::KWinFocusConfigForm(QWidget* parent)
: QWidget(parent)
{
setupUi(parent);
}
-// removed the LCD display over the slider - this is not good GUI design :) RNolden 051701
-KFocusConfig::KFocusConfig(bool _standAlone, KConfig *_config, QWidget * parent)
- : KCModule(parent), config(_config), standAlone(_standAlone)
+KFocusConfig::KFocusConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget * parent)
+ : KCModule(parent), standAlone(_standAlone)
, m_ui(new KWinFocusConfigForm(this))
+ , m_settings(settings)
{
- connect(m_ui->focusStealing, SIGNAL(activated(int)), SLOT(changed()));
- connect(m_ui->windowFocusPolicyCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed()));
- connect(m_ui->windowFocusPolicyCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(focusPolicyChanged()));
- connect(m_ui->windowFocusPolicyCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setDelayFocusEnabled()));
- connect(m_ui->windowFocusPolicyCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateActiveMouseScreen()));
- connect(m_ui->autoRaiseOn, SIGNAL(clicked()), SLOT(changed()));
- connect(m_ui->autoRaiseOn, SIGNAL(toggled(bool)), SLOT(autoRaiseOnTog(bool)));
- connect(m_ui->clickRaiseOn, SIGNAL(clicked()), SLOT(changed()));
- connect(m_ui->autoRaise, SIGNAL(valueChanged(int)), SLOT(changed()));
- connect(m_ui->delayFocus, SIGNAL(valueChanged(int)), SLOT(changed()));
- connect(m_ui->separateScreenFocus, SIGNAL(clicked()), SLOT(changed()));
- connect(m_ui->activeMouseScreen, SIGNAL(clicked()), SLOT(changed()));
-
- connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), SLOT(updateMultiScreen()));
+ addConfig(m_settings, this);
+
+ connect(m_ui->windowFocusPolicy, qOverload(&QComboBox::currentIndexChanged), this, &KFocusConfig::focusPolicyChanged);
+
+ connect(qApp, &QGuiApplication::screenAdded, this, &KFocusConfig::updateMultiScreen);
+ connect(qApp, &QGuiApplication::screenRemoved, this, &KFocusConfig::updateMultiScreen);
updateMultiScreen();
load();
}
void KFocusConfig::updateMultiScreen()
{
m_ui->multiscreenBehaviorLabel->setVisible(QApplication::screens().count() > 1);
- m_ui->activeMouseScreen->setVisible(QApplication::screens().count() > 1);
- m_ui->separateScreenFocus->setVisible(QApplication::screens().count() > 1);
-}
-
-
-int KFocusConfig::getFocus()
-{
- int policy = m_ui->windowFocusPolicyCombo->currentIndex();
- if (policy == 1 || policy == 3)
- --policy; // fix the NextFocusPrefersMouse condition
- return policy;
-}
-
-void KFocusConfig::setFocus(int foc)
-{
- m_ui->windowFocusPolicyCombo->setCurrentIndex(foc);
-
- // this will disable/hide the auto raise delay widget if focus==click
- focusPolicyChanged();
-}
-
-void KFocusConfig::setAutoRaiseInterval(int tb)
-{
- m_ui->autoRaise->setValue(tb);
-}
-
-void KFocusConfig::setDelayFocusInterval(int tb)
-{
- m_ui->delayFocus->setValue(tb);
-}
-
-int KFocusConfig::getAutoRaiseInterval()
-{
- return m_ui->autoRaise->value();
-}
-
-int KFocusConfig::getDelayFocusInterval()
-{
- return m_ui->delayFocus->value();
-}
-
-void KFocusConfig::setAutoRaise(bool on)
-{
- m_ui->autoRaiseOn->setChecked(on);
-}
-
-void KFocusConfig::setClickRaise(bool on)
-{
- m_ui->clickRaiseOn->setChecked(on);
+ m_ui->kcfg_ActiveMouseScreen->setVisible(QApplication::screens().count() > 1);
+ m_ui->kcfg_SeparateScreenFocus->setVisible(QApplication::screens().count() > 1);
}
void KFocusConfig::focusPolicyChanged()
{
- switch (m_ui->windowFocusPolicyCombo->currentIndex()) {
- case 0:
+ int selectedFocusPolicy = 0;
+ bool selectedNextFocusPrefersMouseItem = false;
+ const bool loadedNextFocusPrefersMouseItem = m_settings->nextFocusPrefersMouse();
+
+ int focusPolicy = m_ui->windowFocusPolicy->currentIndex();
+ switch (focusPolicy) {
+ case CLICK_TO_FOCUS:
m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("Click to focus: A window becomes active when you click into it. This behavior is common on other operating systems and likely what you want."));
+ selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::ClickToFocus;
break;
- case 1:
+ case CLICK_TO_FOCUS_MOUSE_PRECEDENT:
m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("Click to focus (mouse precedence): Mostly the same as Click to focus. If an active window has to be chosen by the system (eg. because the currently active one was closed) the window under the mouse is the preferred candidate. Unusual, but possible variant of Click to focus."));
+ selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::ClickToFocus;
+ selectedNextFocusPrefersMouseItem = true;
break;
- case 2:
+ case FOCUS_FOLLOWS_MOUSE:
m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("Focus follows mouse: Moving the mouse onto a window will activate it. Eg. windows randomly appearing under the mouse will not gain the focus. Focus stealing prevention takes place as usual. Think as Click to focus just without having to actually click."));
+ selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse;
break;
- case 3:
+ case FOCUS_FOLLOWS_MOUSE_PRECEDENT:
m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("This is mostly the same as Focus follows mouse. If an active window has to be chosen by the system (eg. because the currently active one was closed) the window under the mouse is the preferred candidate. Choose this, if you want a hover controlled focus."));
+ selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse;
+ selectedNextFocusPrefersMouseItem = true;
break;
- case 4:
+ case FOCUS_UNDER_MOUSE:
m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("Focus under mouse: The focus always remains on the window under the mouse.
Warning: Focus stealing prevention and the tabbox ('Alt+Tab') contradict the activation policy and will not work. You very likely want to use Focus follows mouse (mouse precedence) instead!"));
+ selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusUnderMouse;
break;
- case 5:
+ case FOCUS_STRICTLY_UNDER_MOUSE:
m_ui->windowFocusPolicyDescriptionLabel->setText(i18n("Focus strictly under mouse: The focus is always on the window under the mouse (in doubt nowhere) very much like the focus behavior in an unmanaged legacy X11 environment.
Warning: Focus stealing prevention and the tabbox ('Alt+Tab') contradict the activation policy and will not work. You very likely want to use Focus follows mouse (mouse precedence) instead!"));
+ selectedFocusPolicy = KWinOptionsSettings::EnumFocusPolicy::FocusStrictlyUnderMouse;
break;
}
- int policyIndex = getFocus();
-
- // the auto raise related widgets are: autoRaise
- m_ui->autoRaiseOn->setEnabled(policyIndex != CLICK_TO_FOCUS);
- autoRaiseOnTog(policyIndex != CLICK_TO_FOCUS && m_ui->autoRaiseOn->isChecked());
-
- m_ui->focusStealing->setDisabled(policyIndex == FOCUS_UNDER_MOUSE || policyIndex == FOCUS_STRICTLY_UNDER_MOUSE);
- m_ui->focusStealingLabel->setEnabled(m_ui->focusStealing->isEnabled());
+ const bool changed = m_settings->focusPolicy() != selectedFocusPolicy || loadedNextFocusPrefersMouseItem != selectedNextFocusPrefersMouseItem;
+ unmanagedWidgetChangeState(changed);
+ emit unmanagedWidgetStateChanged(changed);
- setDelayFocusEnabled();
+ const bool isDefault = focusPolicy == CLICK_TO_FOCUS;
+ unmanagedWidgetDefaultState(isDefault);
+ emit unmanagedWidgetDefaulted(isDefault);
-}
+ // the auto raise related widgets are: autoRaise
+ m_ui->kcfg_AutoRaise->setEnabled(focusPolicy != CLICK_TO_FOCUS && focusPolicy != CLICK_TO_FOCUS_MOUSE_PRECEDENT);
-void KFocusConfig::setDelayFocusEnabled()
-{
- int policyIndex = getFocus();
+ m_ui->kcfg_FocusStealingPreventionLevel->setDisabled(focusPolicy == FOCUS_UNDER_MOUSE || focusPolicy == FOCUS_STRICTLY_UNDER_MOUSE);
// the delayed focus related widgets are: delayFocus
- m_ui->delayFocusOnLabel->setEnabled(policyIndex != CLICK_TO_FOCUS);
- delayFocusOnTog(policyIndex != CLICK_TO_FOCUS);
-}
-
-void KFocusConfig::autoRaiseOnTog(bool a)
-{
- m_ui->autoRaise->setEnabled(a);
- m_ui->clickRaiseOn->setEnabled(!a);
-}
-
-void KFocusConfig::delayFocusOnTog(bool a)
-{
- m_ui->delayFocus->setEnabled(a);
-}
+ m_ui->delayFocusOnLabel->setEnabled(focusPolicy != CLICK_TO_FOCUS);
+ m_ui->kcfg_DelayFocusInterval->setEnabled(focusPolicy != CLICK_TO_FOCUS);
-void KFocusConfig::setFocusStealing(int l)
-{
- l = qMax(0, qMin(4, l));
- m_ui->focusStealing->setCurrentIndex(l);
-}
-
-void KFocusConfig::setSeparateScreenFocus(bool s)
-{
- m_ui->separateScreenFocus->setChecked(s);
-}
-
-void KFocusConfig::setActiveMouseScreen(bool a)
-{
- m_ui->activeMouseScreen->setChecked(a);
-}
-
-void KFocusConfig::updateActiveMouseScreen()
-{
// on by default for non click to focus policies
- KConfigGroup cfg(config, "Windows");
- if (!cfg.hasKey(KWIN_ACTIVE_MOUSE_SCREEN))
- setActiveMouseScreen(getFocus() != 0);
+ if (m_settings->activeMouseScreen() == m_settings->defaultActiveMouseScreenValue()) {
+ m_ui->kcfg_ActiveMouseScreen->setChecked(focusPolicy != CLICK_TO_FOCUS && focusPolicy != CLICK_TO_FOCUS_MOUSE_PRECEDENT);
+ }
}
void KFocusConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KFocusConfig::load(void)
{
- QString key;
-
- KConfigGroup cg(config, "Windows");
-
- const bool focusNextToMouse = cg.readEntry("NextFocusPrefersMouse", false);
-
- key = cg.readEntry(KWIN_FOCUS);
- if (key == "ClickToFocus")
- setFocus(CLICK_TO_FOCUS + focusNextToMouse);
- else if (key == "FocusFollowsMouse")
- setFocus(FOCUS_FOLLOWS_MOUSE + focusNextToMouse);
- else if (key == "FocusUnderMouse")
- setFocus(FOCUS_UNDER_MOUSE);
- else if (key == "FocusStrictlyUnderMouse")
- setFocus(FOCUS_STRICTLY_UNDER_MOUSE);
+ KCModule::load();
- int k = cg.readEntry(KWIN_AUTORAISE_INTERVAL, 750);
- setAutoRaiseInterval(k);
+ const bool loadedNextFocusPrefersMouseItem = m_settings->nextFocusPrefersMouse();
- k = cg.readEntry(KWIN_DELAYFOCUS_INTERVAL, 300);
- setDelayFocusInterval(k);
+ int focusPolicy = m_settings->focusPolicy();
- setAutoRaise(cg.readEntry(KWIN_AUTORAISE, false));
- setClickRaise(cg.readEntry(KWIN_CLICKRAISE, true));
- focusPolicyChanged(); // this will disable/hide the auto raise delay widget if focus==click
-
- setSeparateScreenFocus(cg.readEntry(KWIN_SEPARATE_SCREEN_FOCUS, false));
- // on by default for non click to focus policies
- setActiveMouseScreen(cg.readEntry(KWIN_ACTIVE_MOUSE_SCREEN, getFocus() != 0));
-
-// setFocusStealing( cg.readEntry(KWIN_FOCUS_STEALING, 2 ));
- // TODO default to low for now
- setFocusStealing(cg.readEntry(KWIN_FOCUS_STEALING, 1));
-
-
- emit KCModule::changed(false);
+ switch (focusPolicy) {
+ // the ClickToFocus and FocusFollowsMouse have special values when
+ // NextFocusPrefersMouse is true
+ case KWinOptionsSettings::EnumFocusPolicy::ClickToFocus:
+ m_ui->windowFocusPolicy->setCurrentIndex(CLICK_TO_FOCUS + loadedNextFocusPrefersMouseItem);
+ break;
+ case KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse:
+ m_ui->windowFocusPolicy->setCurrentIndex(FOCUS_FOLLOWS_MOUSE + loadedNextFocusPrefersMouseItem);
+ break;
+ default:
+ // +2 to ignore the two special values
+ m_ui->windowFocusPolicy->setCurrentIndex(focusPolicy + 2);
+ break;
+ }
}
void KFocusConfig::save(void)
{
- int v;
-
- KConfigGroup cg(config, "Windows");
-
- v = getFocus();
- if (v == CLICK_TO_FOCUS)
- cg.writeEntry(KWIN_FOCUS, "ClickToFocus");
- else if (v == FOCUS_UNDER_MOUSE)
- cg.writeEntry(KWIN_FOCUS, "FocusUnderMouse");
- else if (v == FOCUS_STRICTLY_UNDER_MOUSE)
- cg.writeEntry(KWIN_FOCUS, "FocusStrictlyUnderMouse");
- else
- cg.writeEntry(KWIN_FOCUS, "FocusFollowsMouse");
-
- cg.writeEntry("NextFocusPrefersMouse", v != m_ui->windowFocusPolicyCombo->currentIndex());
-
- v = getAutoRaiseInterval();
- if (v < 0) v = 0;
- cg.writeEntry(KWIN_AUTORAISE_INTERVAL, v);
-
- v = getDelayFocusInterval();
- if (v < 0) v = 0;
- cg.writeEntry(KWIN_DELAYFOCUS_INTERVAL, v);
-
- cg.writeEntry(KWIN_AUTORAISE, m_ui->autoRaiseOn->isChecked());
-
- cg.writeEntry(KWIN_CLICKRAISE, m_ui->clickRaiseOn->isChecked());
-
- cg.writeEntry(KWIN_SEPARATE_SCREEN_FOCUS, m_ui->separateScreenFocus->isChecked());
- cg.writeEntry(KWIN_ACTIVE_MOUSE_SCREEN, m_ui->activeMouseScreen->isChecked());
-
- cg.writeEntry(KWIN_FOCUS_STEALING, m_ui->focusStealing->currentIndex());
+ KCModule::save();
- cg.writeEntry(KWIN_SEPARATE_SCREEN_FOCUS, m_ui->separateScreenFocus->isChecked());
- cg.writeEntry(KWIN_ACTIVE_MOUSE_SCREEN, m_ui->activeMouseScreen->isChecked());
+ int idxFocusPolicy = m_ui->windowFocusPolicy->currentIndex();
+ switch (idxFocusPolicy) {
+ case CLICK_TO_FOCUS:
+ case CLICK_TO_FOCUS_MOUSE_PRECEDENT:
+ m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::ClickToFocus);
+ break;
+ case FOCUS_FOLLOWS_MOUSE:
+ case FOCUS_FOLLOWS_MOUSE_PRECEDENT:
+ // the ClickToFocus and FocusFollowsMouse have special values when
+ // NextFocusPrefersMouse is true
+ m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::FocusFollowsMouse);
+ break;
+ case FOCUS_UNDER_MOUSE:
+ m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::FocusUnderMouse);
+ break;
+ case FOCUS_STRICTLY_UNDER_MOUSE:
+ m_settings->setFocusPolicy(KWinOptionsSettings::EnumFocusPolicy::FocusStrictlyUnderMouse);
+ break;
+ }
+ m_settings->setNextFocusPrefersMouse(idxFocusPolicy == CLICK_TO_FOCUS_MOUSE_PRECEDENT || idxFocusPolicy == FOCUS_FOLLOWS_MOUSE_PRECEDENT);
+ m_settings->save();
if (standAlone) {
- config->sync();
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
emit KCModule::changed(false);
}
void KFocusConfig::defaults()
{
- setAutoRaiseInterval(0);
- setDelayFocusInterval(0);
- setFocus(CLICK_TO_FOCUS);
- setAutoRaise(false);
- setClickRaise(true);
- setSeparateScreenFocus(false);
-
-// setFocusStealing(2);
- // TODO default to low for now
- setFocusStealing(1);
-
- // on by default for non click to focus policies
- setActiveMouseScreen(getFocus() != 0);
- setDelayFocusEnabled();
- emit KCModule::changed(true);
+ KCModule::defaults();
+ m_ui->windowFocusPolicy->setCurrentIndex(CLICK_TO_FOCUS);
}
KWinAdvancedConfigForm::KWinAdvancedConfigForm(QWidget* parent)
: QWidget(parent)
{
setupUi(parent);
}
-KAdvancedConfig::~KAdvancedConfig()
-{
-}
-
-KAdvancedConfig::KAdvancedConfig(bool _standAlone, QWidget *parent)
- : KCModule(parent), m_config(KWinOptionsSettings::self()), standAlone(_standAlone)
+KAdvancedConfig::KAdvancedConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
+ : KCModule(parent), standAlone(_standAlone)
, m_ui(new KWinAdvancedConfigForm(this))
+ , m_settings(settings)
{
- addConfig(m_config, this);
+ addConfig(m_settings, this);
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Smart, "Smart");
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Maximizing, "Maximizing");
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Cascade, "Cascade");
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Random, "Random");
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::Centered, "Centered");
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::ZeroCornered, "ZeroCornered");
m_ui->kcfg_Placement->setItemData(KWinOptionsSettings::PlacementChoices::UnderMouse, "UnderMouse");
load();
}
void KAdvancedConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KAdvancedConfig::save(void)
{
KCModule::save();
if (standAlone) {
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
}
KWinMovingConfigForm::KWinMovingConfigForm(QWidget* parent)
: QWidget(parent)
{
setupUi(parent);
}
-KMovingConfig::~KMovingConfig()
-{
-}
-
-KMovingConfig::KMovingConfig(bool _standAlone, QWidget *parent)
- : KCModule(parent), m_config(KWinOptionsSettings::self()), standAlone(_standAlone)
+KMovingConfig::KMovingConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent)
+ : KCModule(parent), m_config(settings), standAlone(_standAlone)
, m_ui(new KWinMovingConfigForm(this))
{
addConfig(m_config, this);
load();
}
void KMovingConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KMovingConfig::save(void)
{
- m_config->save();
+ KCModule::save();
if (standAlone) {
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
// and reconfigure the effect
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/Effects"),
QDBusConnection::sessionBus());
if (m_config->geometryTip()) {
interface.loadEffect(KWin::BuiltInEffects::nameForEffect(KWin::BuiltInEffect::WindowGeometry));
} else {
interface.unloadEffect(KWin::BuiltInEffects::nameForEffect(KWin::BuiltInEffect::WindowGeometry));
}
}
diff --git a/kcmkwin/kwinoptions/windows.h b/kcmkwin/kwinoptions/windows.h
index 80f6ac3d6..938411998 100644
--- a/kcmkwin/kwinoptions/windows.h
+++ b/kcmkwin/kwinoptions/windows.h
@@ -1,155 +1,134 @@
/*
* windows.h
*
* Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca
* Copyright (c) 2001 Waldo Bastian bastian@kde.org
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KKWMWINDOWS_H
#define KKWMWINDOWS_H
#include
#include
#include "ui_advanced.h"
#include "ui_focus.h"
#include "ui_moving.h"
class QRadioButton;
class QCheckBox;
class QPushButton;
class KComboBox;
class QGroupBox;
class QLabel;
class QSlider;
class QGroupBox;
class QSpinBox;
class KColorButton;
class KWinOptionsSettings;
class KWinFocusConfigForm : public QWidget, public Ui::KWinFocusConfigForm
{
Q_OBJECT
public:
explicit KWinFocusConfigForm(QWidget* parent);
};
class KWinMovingConfigForm : public QWidget, public Ui::KWinMovingConfigForm
{
Q_OBJECT
public:
explicit KWinMovingConfigForm(QWidget* parent);
};
class KWinAdvancedConfigForm : public QWidget, public Ui::KWinAdvancedConfigForm
{
Q_OBJECT
public:
explicit KWinAdvancedConfigForm(QWidget* parent);
};
class KFocusConfig : public KCModule
{
Q_OBJECT
public:
- KFocusConfig(bool _standAlone, KConfig *_config, QWidget *parent);
- ~KFocusConfig() override;
+ KFocusConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent);
void load() override;
void save() override;
void defaults() override;
+Q_SIGNALS:
+ void unmanagedWidgetDefaulted(bool defaulted);
+ void unmanagedWidgetStateChanged(bool changed);
+
protected:
void showEvent(QShowEvent *ev) override;
private Q_SLOTS:
- void setDelayFocusEnabled();
void focusPolicyChanged();
- void autoRaiseOnTog(bool);//CT 23Oct1998
- void delayFocusOnTog(bool);
- void updateActiveMouseScreen();
void updateMultiScreen();
- void changed() {
- emit KCModule::changed(true);
- }
-
private:
- int getFocus(void);
- int getAutoRaiseInterval(void);
- int getDelayFocusInterval(void);
-
- void setFocus(int);
- void setAutoRaiseInterval(int);
- void setAutoRaise(bool);
- void setDelayFocusInterval(int);
- void setClickRaise(bool);
- void setSeparateScreenFocus(bool);
- void setActiveMouseScreen(bool);
-
- void setFocusStealing(int);
-
- KConfig *config;
bool standAlone;
KWinFocusConfigForm *m_ui;
+ KWinOptionsSettings *m_settings;
};
class KMovingConfig : public KCModule
{
Q_OBJECT
public:
- KMovingConfig(bool _standAlone, QWidget *parent);
- ~KMovingConfig() override;
+ KMovingConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent);
void save() override;
protected:
void showEvent(QShowEvent *ev) override;
private:
KWinOptionsSettings *m_config;
bool standAlone;
KWinMovingConfigForm *m_ui;
};
class KAdvancedConfig : public KCModule
{
Q_OBJECT
public:
- KAdvancedConfig(bool _standAlone, QWidget *parent);
- ~KAdvancedConfig() override;
+ KAdvancedConfig(bool _standAlone, KWinOptionsSettings *settings, QWidget *parent);
void save() override;
protected:
void showEvent(QShowEvent *ev) override;
private:
- KWinOptionsSettings *m_config;
bool standAlone;
KWinAdvancedConfigForm *m_ui;
+ KWinOptionsSettings *m_settings;
};
#endif // KKWMWINDOWS_H
diff --git a/kcmkwin/kwinrules/CMakeLists.txt b/kcmkwin/kwinrules/CMakeLists.txt
index 406cffa66..1ccf777a6 100644
--- a/kcmkwin/kwinrules/CMakeLists.txt
+++ b/kcmkwin/kwinrules/CMakeLists.txt
@@ -1,77 +1,56 @@
# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcmkwinrules\")
add_definitions(-DKCMRULES)
-########### next target ###############
-
include_directories(../../)
-set(kwinrules_MOC_HDRS ../../cursor.h ../../plugins/platforms/x11/standalone/x11cursor.h)
-qt5_wrap_cpp(kwinrules_MOC_SRCS ${kwinrules_MOC_HDRS})
set(kwinrules_SRCS
../../rulebooksettings.cpp
+ ../../cursor.cpp
+ ../../plugins/platforms/x11/standalone/x11cursor.cpp
+ ../../rules.cpp
+ ../../placement.cpp
+ ../../utils.cpp
+ kwinsrc.cpp
optionsmodel.cpp
ruleitem.cpp
rulesmodel.cpp
- rulesdialog.cpp
- main.cpp
- kwinsrc.cpp
- ${kwinrules_MOC_SRCS}
)
kconfig_add_kcfg_files(kwinrules_SRCS ../../rulesettings.kcfgc)
kconfig_add_kcfg_files(kwinrules_SRCS ../../rulebooksettingsbase.kcfgc)
-add_executable(kwin_rules_dialog ${kwinrules_SRCS})
+add_library(KWinRulesObjects STATIC ${kwinrules_SRCS})
set(kwin_kcm_rules_XCB_LIBS
XCB::CURSOR
XCB::XCB
XCB::XFIXES
)
set(kcm_libs
+ Qt5::Quick
Qt5::QuickWidgets
KF5::I18n
+ KF5::QuickAddons
KF5::WindowSystem
KF5::XmlGui
)
if (KWIN_BUILD_ACTIVITIES)
set(kcm_libs ${kcm_libs} KF5::Activities)
endif()
+target_link_libraries(KWinRulesObjects ${kcm_libs} ${kwin_kcm_rules_XCB_LIBS})
-target_link_libraries(kwin_rules_dialog ${kcm_libs} ${kwin_kcm_rules_XCB_LIBS})
-
+add_executable(kwin_rules_dialog main.cpp rulesdialog.cpp)
+target_link_libraries(kwin_rules_dialog KWinRulesObjects)
install(TARGETS kwin_rules_dialog DESTINATION ${LIBEXEC_INSTALL_DIR})
-########### next target ###############
-
-set(kcmkwinrules_SRCS
- kcmrules.cpp
- ${kwinrules_SRCS}
-)
-
-add_library(kcm_kwinrules MODULE ${kcmkwinrules_SRCS})
-
-target_link_libraries(kcm_kwinrules
- Qt5::Quick
-
- KF5::I18n
- KF5::QuickAddons
-
- ${kcm_libs}
- ${kwin_kcm_rules_XCB_LIBS}
-)
-
+add_library(kcm_kwinrules MODULE kcmrules.cpp)
+target_link_libraries(kcm_kwinrules KWinRulesObjects)
kcoreaddons_desktop_to_json(kcm_kwinrules "kcm_kwinrules.desktop" SERVICE_TYPES kcmodule.desktop)
-########### install files ###############
-
-# This desktop file is installed only for retrocompatibility with sycoca
-install(TARGETS kcm_kwinrules DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms)
-install(FILES kcm_kwinrules.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
-
+install(TARGETS kcm_kwinrules DESTINATION ${PLUGIN_INSTALL_DIR}/kcms)
+install(FILES kcm_kwinrules.desktop DESTINATION ${SERVICES_INSTALL_DIR})
kpackage_install_package(package kcm_kwinrules kcms)
-
diff --git a/kcmkwin/kwinrules/kwinsrc.cpp b/kcmkwin/kwinrules/kwinsrc.cpp
index 4c4482d93..75173a0a3 100644
--- a/kcmkwin/kwinrules/kwinsrc.cpp
+++ b/kcmkwin/kwinrules/kwinsrc.cpp
@@ -1,53 +1,45 @@
/*
* Copyright (c) 2004 Lubos Lunak
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-// Include some code from kwin core in order to avoid
-// double implementation.
-
-#include "../../cursor.cpp"
-#include "../../plugins/platforms/x11/standalone/x11cursor.cpp"
-#include "../../rules.cpp"
-#include "../../placement.cpp"
-#include "../../options.cpp"
-#include "../../utils.cpp"
+#include
KWin::InputRedirection *KWin::InputRedirection::s_self = nullptr;
Qt::MouseButtons KWin::InputRedirection::qtButtonStates() const
{
return Qt::NoButton;
}
Qt::KeyboardModifiers KWin::InputRedirection::keyboardModifiers() const
{
return Qt::NoModifier;
}
void KWin::InputRedirection::warpPointer(const QPointF&)
{
}
bool KWin::InputRedirection::supportsPointerWarping() const
{
return false;
}
QPointF KWin::InputRedirection::globalPointer() const
{
return QPointF();
}
diff --git a/kcmkwin/kwinscreenedges/kwinscreenedges.desktop b/kcmkwin/kwinscreenedges/kwinscreenedges.desktop
index a85e52b25..b61adb2c4 100644
--- a/kcmkwin/kwinscreenedges/kwinscreenedges.desktop
+++ b/kcmkwin/kwinscreenedges/kwinscreenedges.desktop
@@ -1,152 +1,153 @@
[Desktop Entry]
Exec=kcmshell5 kwinscreenedges
Icon=preferences-desktop-gestures-screenedges
Type=Service
X-KDE-ServiceTypes=KCModule
X-DocPath=kcontrol/kwinscreenedges/index.html
X-KDE-Library=kcm_kwinscreenedges
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=desktopbehavior
X-KDE-Weight=50
Name=Screen Edges
Name[ar]=حواف الشاشة
Name[bg]=Краища на екрана
Name[bs]=Ivice ekrana
Name[ca]=Vores de la pantalla
Name[ca@valencia]=Vores de la pantalla
Name[cs]=Hrany obrazovky
Name[csb]=Nórtë ekranu
Name[da]=Skærmkanter
Name[de]=Bildschirmränder
Name[el]=Άκρα οθόνης
Name[en_GB]=Screen Edges
Name[eo]=Ekrananguloj
Name[es]=Bordes de pantalla
Name[et]=Ekraani servad
Name[eu]=Pantailaren ertzak
Name[fi]=Näytön reunat
Name[fr]=Bords de l'écran
Name[fy]=Skerm rânen
Name[ga]=Ciumhaiseanna Scáileáin
Name[gl]=Bordos da pantalla
Name[gu]=સ્ક્રિનનાં ખૂણાઓ
Name[he]=קצוות מסך
Name[hi]=स्क्रीन सीमाएँ
Name[hr]=Rubovi ekrana
Name[hu]=Képernyőszélek
Name[ia]=Margines de schermo
Name[id]=Tepian Layar
Name[is]=Skjájaðrar
Name[it]=Lati dello schermo
Name[ja]=スクリーンエッジ
Name[kk]=Экран жиектері
Name[km]=គែមអេក្រង់
Name[kn]=ತೆರೆ ಅಂಚುಗಳು
Name[ko]=화면 경계
Name[lt]=Ekrano kraštai
Name[lv]=Ekrāna malas
Name[mai]=स्क्रीन किनार
Name[mk]=Рабови на екранот
Name[ml]=സ്ക്രീന് അതിരുകള്
Name[mr]=स्क्रीनच्या कडा
Name[nb]=Skjermkanter
Name[nds]=Schirmkanten
Name[nl]=Schermranden
Name[nn]=Skjermkantar
Name[pa]=ਸਕਰੀਨ ਬਾਹੀਆਂ
Name[pl]=Krawędzie ekranu
Name[pt]=Extremos do Ecrã
Name[pt_BR]=Contornos da tela
Name[ro]=Muchiile ecranului
Name[ru]=Края экрана
Name[si]=තිර මුළු
Name[sk]=Okraje obrazovky
Name[sl]=Robovi zaslona
Name[sr]=Ивице екрана
Name[sr@ijekavian]=Ивице екрана
Name[sr@ijekavianlatin]=Ivice ekrana
Name[sr@latin]=Ivice ekrana
Name[sv]=Skärmkanter
Name[tg]=Канорҳои экран
Name[th]=ขอบจอ
Name[tr]=Ekran Kenarları
Name[ug]=ئېكران گىرۋەكلىرى
Name[uk]=Краї екрана
Name[wa]=Boirds del waitroûle
Name[x-test]=xxScreen Edgesxx
Name[zh_CN]=屏幕边缘
Name[zh_TW]=螢幕邊緣
Comment=Configure active screen corners and edges
Comment[ca]=Configura les cantonades i vores actives de la pantalla
Comment[da]=Indstil aktive skærmhjørner- og kanter
Comment[de]=Aktive Bildschirmränder und -ecken einrichten
Comment[en_GB]=Configure active screen corners and edges
Comment[es]=Configurar los bordes y las esquinas de pantalla activos
Comment[et]=Aktiivsete ekraani nurkade ja servade seadistamine
Comment[eu]=Konfiguratu pantailaren izkina eta ertz aktiboak
Comment[fi]=Aseta näytön aktiiviset reunat ja kulmat
Comment[fr]=Configurer les bords et les coins d'écran actifs
Comment[gl]=Configurar os bordos e esquinas activos da pantalla
Comment[hu]=Aktív képernyősarkok és szélek beállítása
Comment[ia]=Configura margines e angulos de schermo active
Comment[id]=Konfigurasikan tepian dan sudut layar aktif
Comment[it]=Configura angoli e bordi attivi dello schermo
Comment[ko]=활성 화면 경계와 꼭짓점 설정
Comment[lt]=Konfigūruoti aktyvaus ekrano kampus ir kraštus
Comment[nl]=Actieve schermhoeken en -randen configureren
Comment[nn]=Set opp aktive skjermhjørne og skjermkantar
Comment[pl]=Ustawienia czułych narożników i krawędzi ekranu
Comment[pt]=Configurar os cantos e extremos do ecrã activo
Comment[pt_BR]=Configura os cantos e bordas da tela ativa
Comment[ru]=Настройка действий для краёв и углов экрана
Comment[sk]=Nastavenie aktívnych okrajov obrazovky a hrán
+Comment[sl]=Nastavi dejavne kote in robove okna
Comment[sv]=Anpassa aktiva skärmhörn och kanter
Comment[uk]=Налаштовування активних кутів і країв екрана
Comment[x-test]=xxConfigure active screen corners and edgesxx
Comment[zh_CN]=配置活动屏幕的边角和边缘
Comment[zh_TW]=設定作用中螢幕角落與邊緣
X-KDE-Keywords=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners
X-KDE-Keywords[bs]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners, prozor, menadćer, efekt, uigao, ivica, akcija, prebacivanje, desktop ivice, ivice ekrana, maksimitiranje prozora, ponašanje ekrana, virtualni desktop
X-KDE-Keywords[ca]=kwin,finestra,gestor,efecte,cantonada,vora,acció,canvi,escriptori,vores de la pantalla del kwin,vores de l'escriptori,vores de la pantalla,maximitza les finestres,finestres en mosaic,costat de la pantalla,comportament de la pantalla,canvi d'escriptori,escriptori virtual,cantonades de la pantalla
X-KDE-Keywords[ca@valencia]=kwin,finestra,gestor,efecte,cantó,vora,acció,canvi,escriptori,vores de pantalla de kwin,vores d'escriptori,vores de pantalla,maximitza finestres,mosaic de les finestres,costat de pantalla,comportament de pantalla,canvi d'escriptori,escriptori virtual,cantons de la pantalla
X-KDE-Keywords[da]=kwin,vindue,håndtering,manager,effekt,hjørne,kant,handling,skift,skrivebord,kwin skærmkanter,skrivebordskanter,skærmkanter,maksimer vinduer,tile windows,fliser,felter,siden af skærmen,skærmens opførsel,skift skrivebord,virtuelle skriveborde,skærmhjørner,hjørner
X-KDE-Keywords[de]=KWin,Fenster,Verwaltung,Effekt,Kante,Rand,Aktion,Wechseln,Desktop,Arbeitsfläche,KWin Bildschirmkanten,Desktopkanten,Bildschirmkanten,Fenster maximieren,Fenster kacheln,Bildschirmseite,Bildschirmverhalten,Desktop wechseln,Arbeitsfläche wechseln,Virtueller Desktop,Virtuelle Arbeitsfläche,Bildschirmecken
X-KDE-Keywords[el]=kwin,παράθυρο,διαχειριστής,εφέ,άκρη,περίγραμμα,ενέργεια,εναλλαγή,επιφάνεια εργασίας,άκρες οθόνης kwin,άκρες επιφάνειας εργασίας,άκρες οθόνης,μεγιστοποίηση παραθύρων,παράθεση παραθύρων,πλευρά οθόνης,συμπεριφορά οθόνης,εναλλαγή επιφάνειας εργασίας,εικονική επιφάνεια εργασίας,γωνίες οθόνης
X-KDE-Keywords[en_GB]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximise windows,tile windows,side of screen,screen behaviour,switch desktop,virtual desktop,screen corners
X-KDE-Keywords[es]=kwin,ventana,gestor,efecto,esquina,borde,acción,cambiar,escritorio,bordes de pantalla de kwin,bordes del escritorio,bordes de la pantalla,maximizar ventanas,ventanas en mosaico,lado de la pantalla,comportamiento de la pantalla,cambiar escritorio,escritorio virtual,esquinas de la pantalla
X-KDE-Keywords[et]=kwin,aken,haldur,efekt.nurk,serv,piire,toiming,lülitamine,töölaud,kwini ekraani servad,töölaua servad,ekraani servad,akende maksimeerimine,akende paanimine,ekraani äär,ekraani käitumine,töölaua lülitamine,virtuaalne töölaud,ekraani nurgad
X-KDE-Keywords[eu]=kwin,leiho,kudeatzaile,efektu,izkin,ertz,ekintza,aldatu,mahaigain,kwin pantailaren ertzak,mahaigainaren ertzak,pantailen ertzak,maximizatu leihoak,lauzatu leihoak,leihoaren alboa,pantailaren portaera,aldatu mahaigaina,mahaigain birtuala,alegiazko mahaigaina,pantailaren izkinak
X-KDE-Keywords[fi]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,ikkunamanageri,ikkunointiohjelma,tehoste,kulma,reuna,vaihda,vaihto,työpöytä,näytön reunat,työpöydän reunat,suurenna ikkuna,kasaa ikkunat,näytön toiminta,vaihda työpöytää,virtuaalityöpöytä,näytön reunat
X-KDE-Keywords[fr]=kwin, fenêtre, gestionnaire, effet, bord, coin, bordure, action, bascule, bureau, bords de l'écran kwin, bords du bureau, bords de l'écran, maximisation des fenêtres, mosaïque de fenêtres, cotés de l'écran, comportement de l'écran, changement de bureau, bureaux virtuels, coins de l'écran
X-KDE-Keywords[gl]=kwin,xanela,xestor,efecto,esquina,beira,bordo,bordo,acción,trocar,escritorio,bordo do escritorio,maximizar xanelas,escritorio virtual,esquinas da pantalla
X-KDE-Keywords[hu]=kwin,ablak,kezelő,effektus,sarok,szél,szegély,művelet,váltás,asztal,kwin képernyőszél,asztalszél,képernyőszél,ablakok maximalizálása,ablakcím,képernyőoldal,képernyő működése,asztalváltás,virtuális asztal,képernyősarkok
X-KDE-Keywords[ia]=kwin,fenestra,gerente,effecto,bordo,margine,action,commuta,scriptorio,bordos de schermo de kwin,bordos de scriptorio,bordos de scriptorio,maximisa fenestras,tegula fenestras,parte de schermo, comportamento de schermo,commuta scriptorio,scriptorio virtual,angulos de schermo
X-KDE-Keywords[id]=kwin,window,pengelola,efek,sudut,,tepi,bingkai,aksi,alihkan,desktop,tepian layar kwin,tepian desktop,tepian layar,maksimalkan window,ubinkan window,sisi layar,perilaku layar,alihkan desktop,virtualkan desktop,sudut layar
X-KDE-Keywords[it]=kwin,finestra,gestore,effetto,angolo,bordo,azione,scambiatore,desktop,bordi schermo kwin,bordi desktop,bordi schermo,massimizza finestre,affianca finestre,lato dello schermo,comportamento schermo,scambia desktop,desktop virtuale,angoli dello schermo
X-KDE-Keywords[ko]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,창,관리자,효과,경계,경계선,동작,액션,전환,kwin 화면 경계,화면 경계,창 최대화,최대화,바둑판식 배열,화면 행동,데스크톱 전환,가상 데스크톱,화면 모서리,꼭짓점,바탕 화면 전환,가상 바탕 화면
X-KDE-Keywords[lt]=kwin,langas,langų,lango,langu,tvarkytuvė,tvarkytuve,efektas,efektai,kampas,kampai,kraštas,krastas,veiksmas,veiksmai,perjungti,perjungiklis,darbalaukis,darbalaukio,kwin ekrano kraštai,kwin ekrano kraštas,kwin ekrano krastas,kwin ekrano krastai,darbalaukio kraštai,darbalaukio kraštas,darbalaukio krastas,darbalaukio krastai,ekrano kraštai,ekrano krastai,ekrano kraštas,ekrano krastas,išskleisti langus,isskleisti langus,langų išskleidimas,langu isskleidimas,lango išskleidimas,lango isskleidimas,išskleisti langą,isskleisti langa,iškloti langą,iškloti langus,iskloti langa,iskloti langus,ekrano šonas,ekrano sonas,ekrano pusė,ekrano puse,ekrano šonai,ekrano sonai,ekrano elgsena,ekrano elgesys,perjungti darbalaukį,perjungti darbalauki,darbalaukio perjungimas,virtualus darbalaukis,virtualūs darbalaukiai,virtualus darbalaukiai,ekrano kampas,ekrano kampai
X-KDE-Keywords[nb]=kwin,vindu,behandler,effekt,kant,hjørne,ramme,handling,bytte,skrivebord,kwin skjermkanter,skrivebordkanter,skjermkanter,maksimere vinduer,flislegge vinduer,skjermside,skjermoppførsel,bytte skrivebord,virtuelt skrivebord,skjermhjørner
X-KDE-Keywords[nds]=KWin,Finster,Pleger,Effekt,Hörn,Kant,Rahmen,Akschoon,wesseln,Schriefdisch,maximeren,kacheln,Schirmkant,Schirmbedregen,Schirmhuuk
X-KDE-Keywords[nl]=kwin,venster,beheerder,effect,hoek,kant,rand,actie,omschakelen,bureaublad,schermranden van kwin,bureaubladkanten,schermkanten,vensters maximaliseren,venster schuin achter elkaar,zijkant van het scherm,schermgedrag,bureaublad omschakelen,virtueel bureaublad,schermhoeken
X-KDE-Keywords[nn]=kwin,vindauge,handsamar,effekt,kant,hjørne,ramme,handling,byte,skrivebord,kwin skjermkantar,skrivebordskantar,skjermkantar,maksimera vindauge,flisleggja vindauge,skjermside,skjermåtferd,byte skrivebord,virtuelt skrivebord,skjermhjørne
X-KDE-Keywords[pl]=kwin,okno,menadżer,efekt,narożnik,krawędź,obramowanie,działanie,przełącz,pulpit, krawędzie ekranu kwin,krawędzie pulpitu,krawędzie ekranu,maksymalizacja okien, kafelkowanie okien,strona ekranu,zachowanie ekranu,przełączanie pulpitu,wirtualny pulpit, krawędzie ekranu
X-KDE-Keywords[pt]=kwin,janela,gestor,efeito,extremo,contorno,acção,mudar,ecrã,extremos do ecrã no kwin,extremos do ecrã,maximizar as janelas,janelas lado-a-lado,lado do ecrã,comportamento do ecrã,mudar de ecrã,ecrã virtual,cantos do ecrã
X-KDE-Keywords[pt_BR]=kwin,janela,gerenciador,efeito,canto,contorno,borda,ação,mudar,área de trabalho,cantos da área de trabalho no kwin,cantos da área de trabalho,maximizar as janelas,janelas lado a lado,lado da tela,comportamento da tela,mudar de área de trabalho virtual,desktop,cantos da tela
X-KDE-Keywords[ru]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,окно,окон,диспетчер,эффект,край,граница,действие,переключить,рабочий стол,края экрана kwin,края экрана,края рабочего стола,распахнуть окна,мозаика окон,край экрана,поведение экрана,переключить рабочий стол,виртуальный рабочий стол,углы рабочего стола,углы экрана
X-KDE-Keywords[sk]=kwin,okno, správca,efekt,okraj,hrana,akcia,prepnúť,plocha,okraje obrazovky kwin, efekty plochy,okraje obrazovky,maximalizovať okná,dlaždicové okná,strana obrazovky, správanie obrazovky,prepnúť plochu,virtuálna plocha,okraje obrazovky
X-KDE-Keywords[sl]=kwin,okno,upravljalnik oken,upravljanje oken,učinki,kot,rob,obroba,dejanje,preklopi,preklapljanje,robovi zaslona,robovi namizja,razpni okna,povečaj okna,tlakuj okna,rob zaslona,obnašanje zaslona,preklopi namizje,preklapljanje namizij,navidezno namizje,koti zaslona
X-KDE-Keywords[sr]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,К‑вин,прозор,менаџер,ефекат,угао,ивица,радња,пребаци,површ,ивице екрана,ивице површи,максимизовање прозора,поплочавање прозора,странице прозора,понашање прозора,мењање површи,виртуелна површ,углови екрана
X-KDE-Keywords[sr@ijekavian]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,К‑вин,прозор,менаџер,ефекат,угао,ивица,радња,пребаци,површ,ивице екрана,ивице површи,максимизовање прозора,поплочавање прозора,странице прозора,понашање прозора,мењање површи,виртуелна површ,углови екрана
X-KDE-Keywords[sr@ijekavianlatin]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,KWin,prozor,menadžer,efekat,ugao,ivica,radnja,prebaci,površ,ivice ekrana,ivice površi,maksimizovanje prozora,popločavanje prozora,stranice prozora,ponašanje prozora,menjanje površi,virtuelna površ,uglovi ekrana
X-KDE-Keywords[sr@latin]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,KWin,prozor,menadžer,efekat,ugao,ivica,radnja,prebaci,površ,ivice ekrana,ivice površi,maksimizovanje prozora,popločavanje prozora,stranice prozora,ponašanje prozora,menjanje površi,virtuelna površ,uglovi ekrana
X-KDE-Keywords[sv]=kwin,fönster,hanterare,effekt,kant,gräns,åtgärd,byta,skrivbord,kwin skärmkanter,skrivbordskanter,maximera fönster,lägg fönster sida vid sida,skärmsidan, skärmbeteende,skrivbordsbyte,virtuellt skrivbord,skärmhörn
X-KDE-Keywords[tr]=kwin,pencere,yönetici,efekt,kenar,kenarlık,eylem,seç,masaüstü,kwin ekran kenarlıkları,kenarlıklar,masaüstü kenarları,ekran kenarları,pencereleri büyüt,pencereleri döşe,ekranın kenarı,ekran davranışı,masaüstünü seç,sanal masaüstü,ekran köşeleri
X-KDE-Keywords[uk]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,вікно,керування,край,кут,межа,сторона,бік,дія,перемикання,стільниця,краї екрана,максимізація,мозаїка,плитка,край екрана,поведінка екрана,перемикання стільниць,віртуальна стільниця
X-KDE-Keywords[x-test]=xxkwinxx,xxwindowxx,xxmanagerxx,xxeffectxx,xxcornerxx,xxedgexx,xxborderxx,xxactionxx,xxswitchxx,xxdesktopxx,xxkwin screen edgesxx,xxdesktop edgesxx,xxscreen edgesxx,xxmaximize windowsxx,xxtile windowsxx,xxside of screenxx,xxscreen behaviorxx,xxswitch desktopxx,xxvirtual desktopxx,xxscreen cornersxx
X-KDE-Keywords[zh_CN]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,窗口,管理,特效,角,边缘,动作,切换,桌面,kwin 屏幕边缘,屏幕边缘,桌面边缘,最大化窗口,平铺窗口,屏幕行为,桌面切换,虚拟桌面,屏幕角落
X-KDE-Keywords[zh_TW]= kwin,window,manager,effect,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners
diff --git a/kcmkwin/kwinscreenedges/kwintouchscreen.desktop b/kcmkwin/kwinscreenedges/kwintouchscreen.desktop
index 2099988fa..baa9e48af 100644
--- a/kcmkwin/kwinscreenedges/kwintouchscreen.desktop
+++ b/kcmkwin/kwinscreenedges/kwintouchscreen.desktop
@@ -1,118 +1,119 @@
[Desktop Entry]
Exec=kcmshell5 kwintouchscreen
Icon=preferences-desktop-gestures-touch
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-Library=kcm_kwintouchscreen
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=desktopbehavior
X-KDE-Weight=50
Name=Touch Screen
Name[ast]=Pantalla táutil
Name[ca]=Pantalla tàctil
Name[ca@valencia]=Pantalla tàctil
Name[cs]=Dotyková obrazovka
Name[da]=Touchskærm
Name[de]=Touchscreen
Name[el]=Οθόνη αφής
Name[en_GB]=Touch Screen
Name[es]=Pantalla táctil
Name[et]=Puuteekraan
Name[eu]=Ukimen-pantaila
Name[fi]=Kosketusnäyttö
Name[fr]=Écran tactile
Name[gl]=Pantalla táctil
Name[he]=מסך מגע
Name[hu]=Érintőképernyő
Name[ia]=Schermo a tacto
Name[id]=Layar Sentuh
Name[it]=Schermo a sfioramento
Name[ko]=터치 스크린
Name[lt]=Jutiklinis ekranas
Name[nl]=Aanraakscherm
Name[nn]=Trykkskjerm
Name[pa]=ਟੱਚ ਸਕਰੀਨ
Name[pl]=Ekran dotykowy
Name[pt]=Ecrã Táctil
Name[pt_BR]=Touch Screen
Name[ru]=Сенсорный экран
Name[sk]=Dotyková obrazovka
Name[sl]=Zaslon na dotik
Name[sr]=Додирник
Name[sr@ijekavian]=Додирник
Name[sr@ijekavianlatin]=Dodirnik
Name[sr@latin]=Dodirnik
Name[sv]=Pekskärm
Name[tr]=Dokunmatik Ekran
Name[uk]=Сенсорна панель
Name[x-test]=xxTouch Screenxx
Name[zh_CN]=触摸屏
Name[zh_TW]=觸控螢幕
Comment=Configure touch screen swipe gestures
Comment[ca]=Configura els gestos de lliscament en la pantalla tàctil
Comment[da]=Indstil strygegestusser til touchskærme
Comment[de]=Wischgesten für Touchscreens einrichten
Comment[en_GB]=Configure touch screen swipe gestures
Comment[es]=Configurar los gestos de deslizamiento en pantalla táctil
Comment[et]=Puuteekraani žestide seadistamine
Comment[eu]=Konfiguratu ukimen-pantailako kolpe arinen keinuak
Comment[fi]=Aseta kosketusnäytön pyyhkäisyeleet
Comment[fr]=Configurer les mouvements sur l'écran tactile
Comment[gl]=Configurar os xestos de pantalla táctil
Comment[hu]=Érintőképernyő-gesztusok beállítása
Comment[id]=Konfigurasikan gestur usapan layar sentuh
Comment[it]=Configura gesti dello schermo a sfioramento
Comment[ko]=터치 스크린 밀기 제스처 설정
Comment[lt]=Konfigūruoti jutiklinio ekrano perbraukimų gestus
Comment[nl]=Veeggebaren voor aanraakscherm configureren
Comment[nn]=Set opp fingerrørsler på trykkskjerm
Comment[pl]=Ustawienia gestów na ekranie dotykowym
Comment[pt]=Configurar os gestos para deslizar o ecrã táctil
Comment[pt_BR]=Configura os gestos na tela sensível ao toque
Comment[ru]=Действия при проведении по сенсорному экрану
Comment[sk]=Nastaviť ťahacie gestá dotykovej obrazovky
+Comment[sl]=Nastavi kretnje vlečenja za zaslon na dotik
Comment[sv]=Anpassa draggester för pekskärm
Comment[uk]=Налаштовування жестів на сенсорній панелі
Comment[x-test]=xxConfigure touch screen swipe gesturesxx
Comment[zh_CN]=配置触摸屏滑动手势
Comment[zh_TW]=設定觸控螢幕滑動手勢
X-KDE-Keywords=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen
X-KDE-Keywords[ca]=kwin,finestra,gestor,efecte,vora,frontera,acció,canvi,escriptori,vores de l'escriptori,vores de la pantalla,costat de la pantalla,comportament de la pantalla,pantalla tàctil
X-KDE-Keywords[ca@valencia]=kwin,finestra,gestor,efecte,vora,borde,acció,canvi,escriptori,vores d'escriptori,vores de pantalla,costat de pantalla,comportament de la pantalla,pantalla tàctil
X-KDE-Keywords[da]=kwin,vindue,håndtering,manager,effekt,hjørne,kant,handling,skift,skrivebord,kwin skærmkanter,skrivebordskanter,skærmkanter,maksimer vinduer,tile windows,fliser,felter,siden af skærmen,skærmens opførsel,touch,skift skrivebord,virtuelle skriveborde,skærmhjørner,hjørner
X-KDE-Keywords[de]=KWin,Fenster,Verwaltung,Effekt,Kante,Rand,Aktion,Wechseln,Desktop,Arbeitsfläche,Bildschirmkanten,Desktopkanten,Bildschirmseite,Bildschirmverhalten,Touchscreen
X-KDE-Keywords[el]=kwin,παράθυρο,διαχειριστής,εφέ,άκρη,περίγραμμα,ενέργεια,εναλλαγή,επιφάνεια εργασίας,άκρες επιφάνειας εργασίας,άκρες οθόνης,πλευρά οθόνης,συμπεριφορά οθόνης, οθόνη αφής
X-KDE-Keywords[en_GB]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behaviour,touch screen
X-KDE-Keywords[es]=kwin,ventana,gestor,efecto,esquina,borde,acción,cambiar,escritorio,bordes del escritorio,bordes de la pantalla,lado de la pantalla,comportamiento de la pantalla,pantalla táctil
X-KDE-Keywords[et]=kwin,aken,haldur,efekt,nurk,serv,piire,toiming,lülitamine,töölaud,töölaua servad,ekraani servad,ekraani äär,ekraani käitumine,puuteekraan
X-KDE-Keywords[eu]=kwin,leiho,kudeatzaile,efektu,izkin,ertz,ekintza,aldatu,mahaigain,mahaigainaren ertzak,pantailen ertzak,pantailaren aldea,pantailaren portaera,ukipen-pantaila
X-KDE-Keywords[fi]=kwin,ikkuna,hallinta,tehoste,kulma,laita,reuna,toiminto,vaihda,työpöytä,työpöydän reunat,näytön reunat,näytön laita,näytön käyttäytyminen,kosketusnäyttö
X-KDE-Keywords[fr]=kwin, fenêtre, gestionnaire, effet, bord, bordure, action, bascule, bureau, bords du bureau, bords de l'écran, côté de l'écran, comportement de l'écran, écran tactile
X-KDE-Keywords[gl]=kwin,window,xanela,manager,xestor,effect,efecto,edge,beira,bordo,contorno,esquina,border,action,acción,switch,cambiar,conmutar,trocar,desktop,escritorio,desktop edges,screen edges,pantalla,side of screen,screen behavior,comportamento,touch screen,táctil
X-KDE-Keywords[hu]=kwin,ablak,kezelő,effektus,szél,szegély,művelet,váltás,asztal,asztalszél,képernyőszél,képernyőoldal,képernyő működése,érintőképernyő
X-KDE-Keywords[id]=kwin,window,pengelola,efek,tepi,bingkai,aksi,alih,desktop,tepian desktop,tepian layar,sisi layar,perilaku layar,layar sentuh
X-KDE-Keywords[it]=kwin,finestra,gestore,effetto,angolo,bordo,azione,scambiatore,desktop,bordi desktop,bordi schermo,lato dello schermo,comportamento schermo,schermo a sfioramento
X-KDE-Keywords[ko]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,창,관리자,효과,경계,경계선,동작,액션,데스크톱,화면 경계,경계,터치,터치 스크린,터치스크린,바탕 화면
X-KDE-Keywords[lt]=kwin,lango,langų,langu,tvarkytuvė,tvarkytuve,efektas,efektai,kraštas,krastas,rėmelis,remelis,rėmas,remas,veiksmas,veiksmai,perjungti,perjugimo,perjungimas,darbalaukis,darbalaukio,darbalaukio kraštai,darbalaukio kraštas,darbalaukio krastai,darbalaukio krastas,ekrano kraštai,ekrano krastai,ekrano kraštas,ekrano krastas,ekrano šonas,ekrano sonas,ekrano pusė,ekrano puse,ekrano elgsena,ekrano elgsesys,jutiklinis ekranas,jutiminis ekranas,jautrusis ekranas,touchscreen,touch screen
X-KDE-Keywords[nl]=kwin,venster,beheerder,effect,kant,rand,actie,omschakelen,bureaublad,bureaubladkanten,schermkanten,zijkant van het scherm,schermgedrag,aanraakscherm
X-KDE-Keywords[nn]=kwin,vindauge,handsamar,effekt,kant,ramme,handling,byte,skrivebord,skrivebordkantar,skjermkantar,skjermside,skjermåtferd,trykkskjerm
X-KDE-Keywords[pl]=kwin,okno,menadżer,efekt,krawędź,obramowanie,działanie,przełącz,pulpit,krawędzie pulpitu,krawędzie ekranu,strona ekranu,zachowanie ekranu,ekran dotykowy
X-KDE-Keywords[pt]=kwin,janela,gestor,efeito,extremo,contorno,acção,mudar,ecrã,extremos do ecrã no kwin,extremos do ecrã,maximizar as janelas,janelas lado-a-lado,lado do ecrã,comportamento do ecrã,ecrã táctil
X-KDE-Keywords[pt_BR]=kwin,janela,gerenciador,efeito,canto,contorno,borda,ação,mudar,área de trabalho,cantos da área de trabalho, desktop,lado da tela,comportamento da tela,touch screen
X-KDE-Keywords[ru]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,окно,окон,диспетчер,эффект,край,граница,действие,переключить,рабочий стол,края экрана kwin,края экрана,края рабочего стола,распахнуть окна,мозаика окон,край экрана,поведение экрана,переключить рабочий стол,виртуальный рабочий стол,углы рабочего стола,углы экрана,тачскрин,сенсорный экран,touch screen
X-KDE-Keywords[sk]=Kwin, okná, manažér, efekt, okraj, hranice, akcie, prepínač, desktop, okraje plochy,Okraje obrazovky, bočná strana obrazovky, správanie obrazovky, dotyková obrazovka
X-KDE-Keywords[sl]=kwin,okno,upravljalnik oken,upravljanje oken,učinki,rob,obroba,dejanje,preklopi,preklapljanje,robovi namizja,robovi zaslona,rob zaslona,obnašanje zaslona,zaslon na dotik
X-KDE-Keywords[sr]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,К‑вин,прозор,менаџер,ефекат,ивица,радња,пребаци,површ,ивице екрана,ивице површи,странице прозора,понашање прозора,додирник
X-KDE-Keywords[sr@ijekavian]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,К‑вин,прозор,менаџер,ефекат,ивица,радња,пребаци,површ,ивице екрана,ивице површи,странице прозора,понашање прозора,додирник
X-KDE-Keywords[sr@ijekavianlatin]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,KWin,prozor,menadžer,efekat,ivica,radnja,prebaci,površ,ivice ekrana,ivice površi,stranice prozora,ponašanje prozora,dodirnik
X-KDE-Keywords[sr@latin]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,KWin,prozor,menadžer,efekat,ivica,radnja,prebaci,površ,ivice ekrana,ivice površi,stranice prozora,ponašanje prozora,dodirnik
X-KDE-Keywords[sv]=kwin,fönster,hanterare,effekt,kant,gräns,åtgärd,byta,skrivbord,skrivbordskanter,skärmkanter,skärmsidan,skärmbeteende,pekskärm
X-KDE-Keywords[tr]=kwin,pencere,yönetici,efekt,kenar,sınır,eylem,geçiş,masaüstü,masaüstü kenarları,ekran kenarları,ekranın yan tarafı,ekran davranışı,dokunmatik ekran
X-KDE-Keywords[uk]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen,вікно,керування,край,кут,межа,сторона,бік,дія,перемикання,стільниця,плитка,край екрана,поведінка екрана,перемикання стільниць,віртуальна стільниця,сенсорна панель
X-KDE-Keywords[x-test]=xxkwinxx,xxwindowxx,xxmanagerxx,xxeffectxx,xxedgexx,xxborderxx,xxactionxx,xxswitchxx,xxdesktopxx,xxdesktop edgesxx,xxscreen edgesxx,xxside of screenxx,xxscreen behaviorxx,xxtouch screenxx
X-KDE-Keywords[zh_CN]=kwin,window,manager,effect,corner,edge,border,action,switch,desktop,kwin screen edges,desktop edges,screen edges,maximize windows,tile windows,side of screen,screen behavior,switch desktop,virtual desktop,screen corners,窗口,管理,特效,角,边缘,动作,切换,桌面,kwin 屏幕边缘,屏幕边缘,桌面边缘,最大化窗口,平铺窗口,屏幕行为,桌面切换,虚拟桌面,屏幕角落
X-KDE-Keywords[zh_TW]=kwin,window,manager,effect,edge,border,action,switch,desktop,desktop edges,screen edges,side of screen,screen behavior,touch screen
diff --git a/kcmkwin/kwintabbox/CMakeLists.txt b/kcmkwin/kwintabbox/CMakeLists.txt
index da71fdcf1..6a7fc3515 100644
--- a/kcmkwin/kwintabbox/CMakeLists.txt
+++ b/kcmkwin/kwintabbox/CMakeLists.txt
@@ -1,42 +1,43 @@
# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwintabbox\")
include_directories(${KWin_SOURCE_DIR}/effects ${KWin_SOURCE_DIR}/tabbox ${KWin_SOURCE_DIR})
########### next target ###############
set(kcm_kwintabbox_PART_SRCS
${KWin_SOURCE_DIR}/tabbox/tabboxconfig.cpp
layoutpreview.cpp
main.cpp
thumbnailitem.cpp
+ kwintabboxconfigform.cpp
)
ki18n_wrap_ui(kcm_kwintabbox_PART_SRCS main.ui)
qt5_add_dbus_interface(kcm_kwintabbox_PART_SRCS ${KWin_SOURCE_DIR}/org.kde.kwin.Effects.xml kwin_effects_interface)
kconfig_add_kcfg_files(kcm_kwintabbox_PART_SRCS kwintabboxsettings.kcfgc kwinswitcheffectsettings.kcfgc kwinpluginssettings.kcfgc)
add_library(kcm_kwintabbox MODULE ${kcm_kwintabbox_PART_SRCS})
target_link_libraries(kcm_kwintabbox
Qt5::Quick
KF5::Completion
KF5::GlobalAccel
KF5::I18n
KF5::KCMUtils
KF5::NewStuff
KF5::Package
KF5::Service
XCB::XCB
kwin4_effect_builtins
)
install(TARGETS kcm_kwintabbox DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install(FILES kwintabbox.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(FILES thumbnails/konqueror.png thumbnails/kmail.png thumbnails/systemsettings.png thumbnails/dolphin.png DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwintabbox)
install(FILES kwinswitcher.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR})
diff --git a/kcmkwin/kwintabbox/kwintabboxconfigform.cpp b/kcmkwin/kwintabbox/kwintabboxconfigform.cpp
new file mode 100644
index 000000000..cdd6a4eb4
--- /dev/null
+++ b/kcmkwin/kwintabbox/kwintabboxconfigform.cpp
@@ -0,0 +1,353 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2009 Martin Gräßlin
+Copyright (C) 2020 Cyril Rossi
+
+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 "kwintabboxconfigform.h"
+#include "ui_main.h"
+
+#include
+
+#include
+#include
+#include
+
+
+namespace KWin
+{
+
+using namespace TabBox;
+
+KWinTabBoxConfigForm::KWinTabBoxConfigForm(TabboxType type, QWidget *parent)
+ : QWidget(parent)
+ , m_type(type)
+ , ui(new Ui::KWinTabBoxConfigForm)
+{
+ ui->setupUi(this);
+
+ ui->effectConfigButton->setIcon(QIcon::fromTheme(QStringLiteral("view-preview")));
+
+ if (QApplication::screens().count() < 2) {
+ ui->filterScreens->hide();
+ ui->screenFilter->hide();
+ }
+
+ connect(ui->effectConfigButton, &QPushButton::clicked, this, &KWinTabBoxConfigForm::effectConfigButtonClicked);
+
+ connect(ui->kcfg_ShowTabBox, SIGNAL(clicked(bool)), SLOT(tabBoxToggled(bool)));
+
+ connect(ui->filterScreens, SIGNAL(clicked(bool)), SLOT(onFilterScreen()));
+ connect(ui->currentScreen, SIGNAL(clicked(bool)), SLOT(onFilterScreen()));
+ connect(ui->otherScreens, SIGNAL(clicked(bool)), SLOT(onFilterScreen()));
+
+ connect(ui->filterDesktops, SIGNAL(clicked(bool)), SLOT(onFilterDesktop()));
+ connect(ui->currentDesktop, SIGNAL(clicked(bool)), SLOT(onFilterDesktop()));
+ connect(ui->otherDesktops, SIGNAL(clicked(bool)), SLOT(onFilterDesktop()));
+
+ connect(ui->filterActivities, SIGNAL(clicked(bool)), SLOT(onFilterActivites()));
+ connect(ui->currentActivity, SIGNAL(clicked(bool)), SLOT(onFilterActivites()));
+ connect(ui->otherActivities, SIGNAL(clicked(bool)), SLOT(onFilterActivites()));
+
+ connect(ui->filterMinimization, SIGNAL(clicked(bool)), SLOT(onFilterMinimization()));
+ connect(ui->visibleWindows, SIGNAL(clicked(bool)), SLOT(onFilterMinimization()));
+ connect(ui->hiddenWindows, SIGNAL(clicked(bool)), SLOT(onFilterMinimization()));
+
+ connect(ui->oneAppWindow, SIGNAL(clicked(bool)), SLOT(onApplicationMode()));
+ connect(ui->showDesktop, SIGNAL(clicked(bool)), SLOT(onShowDesktopMode()));
+
+ connect(ui->switchingModeCombo, SIGNAL(currentIndexChanged(int)), SLOT(onSwitchingMode()));
+ connect(ui->effectCombo, SIGNAL(currentIndexChanged(int)), SLOT(onEffectCombo()));
+
+ auto addShortcut = [this](const char *name, KKeySequenceWidget *widget, const QKeySequence &sequence = QKeySequence()) {
+ QAction *a = m_actionCollection->addAction(name);
+ a->setProperty("isConfigurationAction", true);
+ widget->setProperty("shortcutAction", name);
+ a->setText(i18n(name));
+ KGlobalAccel::self()->setShortcut(a, QList() << sequence);
+ connect(widget, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(shortcutChanged(QKeySequence)));
+ };
+
+ // Shortcut config. The shortcut belongs to the component "kwin"!
+ m_actionCollection = new KActionCollection(this, QStringLiteral("kwin"));
+ m_actionCollection->setComponentDisplayName(i18n("KWin"));
+ m_actionCollection->setConfigGroup("Navigation");
+ m_actionCollection->setConfigGlobal(true);
+
+ if (TabboxType::Main == m_type) {
+ addShortcut("Walk Through Windows", ui->scAll, Qt::ALT + Qt::Key_Tab);
+ addShortcut("Walk Through Windows (Reverse)", ui->scAllReverse, Qt::ALT + Qt::SHIFT + Qt::Key_Backtab);
+ addShortcut("Walk Through Windows of Current Application", ui->scCurrent, Qt::ALT + Qt::Key_QuoteLeft);
+ addShortcut("Walk Through Windows of Current Application (Reverse)", ui->scCurrentReverse, Qt::ALT + Qt::Key_AsciiTilde);
+ } else if (TabboxType::Alternative == m_type) {
+ addShortcut("Walk Through Windows Alternative", ui->scAll);
+ addShortcut("Walk Through Windows Alternative (Reverse)", ui->scAllReverse);
+ addShortcut("Walk Through Windows of Current Application Alternative", ui->scCurrent);
+ addShortcut("Walk Through Windows of Current Application Alternative (Reverse)", ui->scCurrentReverse);
+ }
+}
+
+KWinTabBoxConfigForm::~KWinTabBoxConfigForm()
+{
+ delete ui;
+}
+
+bool KWinTabBoxConfigForm::highlightWindows() const
+{
+ return ui->kcfg_HighlightWindows->isChecked();
+}
+
+bool KWinTabBoxConfigForm::showTabBox() const
+{
+ return ui->kcfg_ShowTabBox->isChecked();
+}
+
+int KWinTabBoxConfigForm::filterScreen() const
+{
+ if (ui->filterScreens->isChecked()) {
+ return ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients;
+ } else {
+ return TabBoxConfig::IgnoreMultiScreen;
+ }
+}
+
+int KWinTabBoxConfigForm::filterDesktop() const
+{
+ if (ui->filterDesktops->isChecked()) {
+ return ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients;
+ } else {
+ return TabBoxConfig::AllDesktopsClients;
+ }
+}
+
+int KWinTabBoxConfigForm::filterActivities() const
+{
+ if (ui->filterActivities->isChecked()) {
+ return ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients;
+ } else {
+ return TabBoxConfig::AllActivitiesClients;
+ }
+}
+
+int KWinTabBoxConfigForm::filterMinimization() const
+{
+ if (ui->filterMinimization->isChecked()) {
+ return ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients;
+ } else {
+ return TabBoxConfig::IgnoreMinimizedStatus;
+ }
+}
+
+int KWinTabBoxConfigForm::applicationMode() const
+{
+ return ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications;
+}
+
+int KWinTabBoxConfigForm::showDesktopMode() const
+{
+ return ui->showDesktop->isChecked() ? TabBoxConfig::ShowDesktopClient : TabBoxConfig::DoNotShowDesktopClient;
+}
+
+int KWinTabBoxConfigForm::switchingMode() const
+{
+ return ui->switchingModeCombo->currentIndex();
+}
+
+QString KWinTabBoxConfigForm::layoutName() const
+{
+ return ui->effectCombo->currentData().toString();
+}
+
+void KWinTabBoxConfigForm::setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode)
+{
+ ui->filterScreens->setChecked(mode != TabBoxConfig::IgnoreMultiScreen);
+ ui->currentScreen->setChecked(mode == TabBoxConfig::OnlyCurrentScreenClients);
+ ui->otherScreens->setChecked(mode == TabBoxConfig::ExcludeCurrentScreenClients);
+}
+
+void KWinTabBoxConfigForm::setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode)
+{
+ ui->filterDesktops->setChecked(mode != TabBoxConfig::AllDesktopsClients);
+ ui->currentDesktop->setChecked(mode == TabBoxConfig::OnlyCurrentDesktopClients);
+ ui->otherDesktops->setChecked(mode == TabBoxConfig::ExcludeCurrentDesktopClients);
+}
+
+void KWinTabBoxConfigForm::setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode)
+{
+ ui->filterActivities->setChecked(mode != TabBoxConfig::AllActivitiesClients);
+ ui->currentActivity->setChecked(mode == TabBoxConfig::OnlyCurrentActivityClients);
+ ui->otherActivities->setChecked(mode == TabBoxConfig::ExcludeCurrentActivityClients);
+}
+
+void KWinTabBoxConfigForm::setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode)
+{
+ ui->filterMinimization->setChecked(mode != TabBoxConfig::IgnoreMinimizedStatus);
+ ui->visibleWindows->setChecked(mode == TabBoxConfig::ExcludeMinimizedClients);
+ ui->hiddenWindows->setChecked(mode == TabBoxConfig::OnlyMinimizedClients);
+}
+
+void KWinTabBoxConfigForm::setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode)
+{
+ ui->oneAppWindow->setChecked(mode == TabBoxConfig::OneWindowPerApplication);
+}
+
+void KWinTabBoxConfigForm::setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode)
+{
+ ui->showDesktop->setChecked(mode == TabBoxConfig::ShowDesktopClient);
+}
+
+void KWinTabBoxConfigForm::setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode)
+{
+ ui->switchingModeCombo->setCurrentIndex(mode);
+}
+
+void KWinTabBoxConfigForm::setLayoutName(const QString &layoutName)
+{
+ ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(layoutName));
+}
+
+void KWinTabBoxConfigForm::setEffectComboModel(QStandardItemModel *model)
+{
+ int index = ui->effectCombo->currentIndex();
+ QVariant data = ui->effectCombo->itemData(index);
+
+ ui->effectCombo->setModel(model);
+
+ if (data.isValid()) {
+ ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(data));
+ } else if (index != -1) {
+ ui->effectCombo->setCurrentIndex(index);
+ }
+}
+
+QVariant KWinTabBoxConfigForm::effectComboCurrentData(int role) const
+{
+ return ui->effectCombo->currentData(role);
+}
+
+void KWinTabBoxConfigForm::loadShortcuts()
+{
+ auto loadShortcut = [this](KKeySequenceWidget *widget) {
+ QString actionName = widget->property("shortcutAction").toString();
+ qDebug() << "load shortcut for " << actionName;
+ if (QAction *action = m_actionCollection->action(actionName)) {
+ auto shortcuts = KGlobalAccel::self()->shortcut(action);
+ if (!shortcuts.isEmpty()) {
+ widget->setKeySequence(shortcuts.first());
+ }
+ }
+ };
+
+ loadShortcut(ui->scAll);
+ loadShortcut(ui->scAllReverse);
+ loadShortcut(ui->scCurrent);
+ loadShortcut(ui->scCurrentReverse);
+}
+
+void KWinTabBoxConfigForm::resetShortcuts()
+{
+ QString action;
+ auto resetShortcut = [this](KKeySequenceWidget *widget, const QKeySequence &sequence = QKeySequence()) {
+ const QString action = widget->property("shortcutAction").toString();
+ QAction *a = m_actionCollection->action(action);
+ KGlobalAccel::self()->setShortcut(a, QList() << sequence, KGlobalAccel::NoAutoloading);
+ };
+ if (TabboxType::Main == m_type) {
+ resetShortcut(ui->scAll, Qt::ALT + Qt::Key_Tab);
+ resetShortcut(ui->scAllReverse, Qt::ALT + Qt::SHIFT + Qt::Key_Backtab);
+ resetShortcut(ui->scCurrent, Qt::ALT + Qt::Key_QuoteLeft);
+ resetShortcut(ui->scCurrentReverse, Qt::ALT + Qt::Key_AsciiTilde);
+ } else if (TabboxType::Alternative == m_type) {
+ resetShortcut(ui->scAll);
+ resetShortcut(ui->scAllReverse);
+ resetShortcut(ui->scCurrent);
+ resetShortcut(ui->scCurrentReverse);
+ }
+ m_actionCollection->writeSettings();
+}
+
+void KWinTabBoxConfigForm::tabBoxToggled(bool on)
+{
+ // Highlight Windows options is availabled if no TabBox effect is selected
+ // or if Tabbox is not builtin effet.
+ on = !on || ui->effectCombo->currentData(AddonEffect).toBool();
+ ui->kcfg_HighlightWindows->setEnabled(on);
+}
+
+void KWinTabBoxConfigForm::onFilterScreen()
+{
+ emit filterScreenChanged(filterScreen());
+}
+
+void KWinTabBoxConfigForm::onFilterDesktop()
+{
+ emit filterDesktopChanged(filterDesktop());
+}
+
+void KWinTabBoxConfigForm::onFilterActivites()
+{
+ emit filterActivitiesChanged(filterActivities());
+}
+
+void KWinTabBoxConfigForm::onFilterMinimization()
+{
+ emit filterMinimizationChanged(filterMinimization());
+}
+
+void KWin::KWinTabBoxConfigForm::onApplicationMode()
+{
+ emit applicationModeChanged(applicationMode());
+}
+
+void KWinTabBoxConfigForm::onShowDesktopMode()
+{
+ emit showDesktopModeChanged(showDesktopMode());
+}
+
+void KWinTabBoxConfigForm::onSwitchingMode()
+{
+ emit switchingModeChanged(switchingMode());
+}
+
+void KWinTabBoxConfigForm::onEffectCombo()
+{
+ const bool isAddonEffect = ui->effectCombo->currentData(AddonEffect).toBool();
+ ui->effectConfigButton->setIcon(QIcon::fromTheme(isAddonEffect ? "view-preview" : "configure"));
+ if (!ui->kcfg_ShowTabBox->isChecked()) {
+ return;
+ }
+ ui->kcfg_HighlightWindows->setEnabled(isAddonEffect);
+
+ emit layoutNameChanged(layoutName());
+}
+
+void KWinTabBoxConfigForm::shortcutChanged(const QKeySequence &seq)
+{
+ QString action;
+ if (sender()) {
+ action = sender()->property("shortcutAction").toString();
+ }
+ if (action.isEmpty()) {
+ return;
+ }
+ QAction *a = m_actionCollection->action(action);
+ KGlobalAccel::self()->setShortcut(a, QList() << seq, KGlobalAccel::NoAutoloading);
+ m_actionCollection->writeSettings();
+}
+
+} // namespace
diff --git a/kcmkwin/kwintabbox/kwintabboxconfigform.h b/kcmkwin/kwintabbox/kwintabboxconfigform.h
new file mode 100644
index 000000000..08fabde5f
--- /dev/null
+++ b/kcmkwin/kwintabbox/kwintabboxconfigform.h
@@ -0,0 +1,122 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2009 Martin Gräßlin
+Copyright (C) 2020 Cyril Rossi
+
+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 __KWINTABBOXCONFIGFORM_H__
+#define __KWINTABBOXCONFIGFORM_H__
+
+#include
+#include
+
+#include "tabboxconfig.h"
+
+class KShortcutsEditor;
+class KActionCollection;
+
+namespace Ui
+{
+class KWinTabBoxConfigForm;
+}
+
+namespace KWin
+{
+
+class KWinTabBoxConfigForm : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum class TabboxType
+ {
+ Main,
+ Alternative,
+ };
+
+
+ enum EffectComboRole
+ {
+ LayoutPath = Qt::UserRole + 1,
+ AddonEffect, // i.e not builtin effects
+ };
+
+ explicit KWinTabBoxConfigForm(TabboxType type, QWidget *parent = nullptr);
+ ~KWinTabBoxConfigForm() override;
+
+ bool highlightWindows() const;
+ bool showTabBox() const;
+ int filterScreen() const;
+ int filterDesktop() const;
+ int filterActivities() const;
+ int filterMinimization() const;
+ int applicationMode() const;
+ int showDesktopMode() const;
+ int switchingMode() const;
+ QString layoutName() const;
+
+ void setFilterScreen(TabBox::TabBoxConfig::ClientMultiScreenMode mode);
+ void setFilterDesktop(TabBox::TabBoxConfig::ClientDesktopMode mode);
+ void setFilterActivities(TabBox::TabBoxConfig::ClientActivitiesMode mode);
+ void setFilterMinimization(TabBox::TabBoxConfig::ClientMinimizedMode mode);
+ void setApplicationMode(TabBox::TabBoxConfig::ClientApplicationsMode mode);
+ void setShowDesktopMode(TabBox::TabBoxConfig::ShowDesktopMode mode);
+ void setSwitchingModeChanged(TabBox::TabBoxConfig::ClientSwitchingMode mode);
+ void setLayoutName(const QString &layoutName);
+
+ // EffectCombo Data Model
+ void setEffectComboModel(QStandardItemModel *model);
+ QVariant effectComboCurrentData(int role = Qt::UserRole) const;
+
+ void loadShortcuts();
+ void resetShortcuts();
+
+Q_SIGNALS:
+ void filterScreenChanged(int value);
+ void filterDesktopChanged(int value);
+ void filterActivitiesChanged(int value);
+ void filterMinimizationChanged(int value);
+ void applicationModeChanged(int value);
+ void showDesktopModeChanged(int value);
+ void switchingModeChanged(int value);
+ void layoutNameChanged(const QString &layoutName);
+ void effectConfigButtonClicked();
+
+private Q_SLOTS:
+ void tabBoxToggled(bool on);
+ void onFilterScreen();
+ void onFilterDesktop();
+ void onFilterActivites();
+ void onFilterMinimization();
+ void onApplicationMode();
+ void onShowDesktopMode();
+ void onSwitchingMode();
+ void onEffectCombo();
+ void shortcutChanged(const QKeySequence &seq);
+
+private:
+ KActionCollection *m_actionCollection = nullptr;
+ KShortcutsEditor *m_editor = nullptr;
+
+ TabboxType m_type;
+ Ui::KWinTabBoxConfigForm *ui;
+};
+
+} // namespace
+
+#endif
diff --git a/kcmkwin/kwintabbox/main.cpp b/kcmkwin/kwintabbox/main.cpp
index 551cabf0b..20897de92 100644
--- a/kcmkwin/kwintabbox/main.cpp
+++ b/kcmkwin/kwintabbox/main.cpp
@@ -1,565 +1,474 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin
Copyright (C) 2020 Cyril Rossi
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 "main.h"
#include
#include
// Qt
#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
+#include
// KDE
-#include
#include
-#include
#include
#include
#include
#include
#include
-#include
#include
// Plasma
#include
#include
// own
+#include "kwintabboxconfigform.h"
#include "layoutpreview.h"
#include "kwintabboxsettings.h"
#include "kwinswitcheffectsettings.h"
#include "kwinpluginssettings.h"
K_PLUGIN_FACTORY(KWinTabBoxConfigFactory, registerPlugin();)
namespace KWin
{
using namespace TabBox;
-KWinTabBoxConfigForm::KWinTabBoxConfigForm(QWidget* parent)
- : QWidget(parent)
-{
- setupUi(this);
-}
KWinTabBoxConfig::KWinTabBoxConfig(QWidget* parent, const QVariantList& args)
: KCModule(parent, args)
, m_config(KSharedConfig::openConfig("kwinrc"))
, m_tabBoxConfig(new TabBoxSettings(QStringLiteral("TabBox"), this))
, m_tabBoxAlternativeConfig(new TabBoxSettings(QStringLiteral("TabBoxAlternative"), this))
, m_coverSwitchConfig(new SwitchEffectSettings(QStringLiteral("Effect-CoverSwitch"), this))
, m_flipSwitchConfig(new SwitchEffectSettings(QStringLiteral("Effect-FlipSwitch"), this))
, m_pluginsConfig(new PluginsSettings(this))
{
QTabWidget* tabWidget = new QTabWidget(this);
- m_primaryTabBoxUi = new KWinTabBoxConfigForm(tabWidget);
- m_alternativeTabBoxUi = new KWinTabBoxConfigForm(tabWidget);
+ m_primaryTabBoxUi = new KWinTabBoxConfigForm(KWinTabBoxConfigForm::TabboxType::Main, tabWidget);
+ m_alternativeTabBoxUi = new KWinTabBoxConfigForm(KWinTabBoxConfigForm::TabboxType::Alternative, tabWidget);
tabWidget->addTab(m_primaryTabBoxUi, i18n("Main"));
tabWidget->addTab(m_alternativeTabBoxUi, i18n("Alternative"));
QPushButton* ghnsButton = new QPushButton(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff")), i18n("Get New Task Switchers..."));
connect(ghnsButton, SIGNAL(clicked(bool)), SLOT(slotGHNS()));
QHBoxLayout* buttonBar = new QHBoxLayout();
QSpacerItem* buttonBarSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
buttonBar->addItem(buttonBarSpacer);
buttonBar->addWidget(ghnsButton);
QVBoxLayout* layout = new QVBoxLayout(this);
KTitleWidget* infoLabel = new KTitleWidget(tabWidget);
infoLabel->setText(i18n("Focus policy settings limit the functionality of navigating through windows."),
KTitleWidget::InfoMessage);
infoLabel->setPixmap(KTitleWidget::InfoMessage, KTitleWidget::ImageLeft);
layout->addWidget(infoLabel,0);
layout->addWidget(tabWidget,1);
layout->addLayout(buttonBar);
setLayout(layout);
-#define ADD_SHORTCUT(_NAME_, _CUT_, _BTN_) \
- a = m_actionCollection->addAction(_NAME_);\
- a->setProperty("isConfigurationAction", true);\
- _BTN_->setProperty("shortcutAction", _NAME_);\
- a->setText(i18n(_NAME_));\
- KGlobalAccel::self()->setShortcut(a, QList() << _CUT_); \
- connect(_BTN_, SIGNAL(keySequenceChanged(QKeySequence)), SLOT(shortcutChanged(QKeySequence)))
-
- // Shortcut config. The shortcut belongs to the component "kwin"!
- m_actionCollection = new KActionCollection(this, QStringLiteral("kwin"));
- m_actionCollection->setComponentDisplayName(i18n("KWin"));
- m_actionCollection->setConfigGroup("Navigation");
- m_actionCollection->setConfigGlobal(true);
- QAction* a;
- ADD_SHORTCUT("Walk Through Windows", Qt::ALT + Qt::Key_Tab, m_primaryTabBoxUi->scAll);
- ADD_SHORTCUT("Walk Through Windows (Reverse)", Qt::ALT + Qt::SHIFT + Qt::Key_Backtab,
- m_primaryTabBoxUi->scAllReverse);
- ADD_SHORTCUT("Walk Through Windows Alternative", QKeySequence(), m_alternativeTabBoxUi->scAll);
- ADD_SHORTCUT("Walk Through Windows Alternative (Reverse)", QKeySequence(), m_alternativeTabBoxUi->scAllReverse);
- ADD_SHORTCUT("Walk Through Windows of Current Application", Qt::ALT + Qt::Key_QuoteLeft,
- m_primaryTabBoxUi->scCurrent);
- ADD_SHORTCUT("Walk Through Windows of Current Application (Reverse)", Qt::ALT + Qt::Key_AsciiTilde,
- m_primaryTabBoxUi->scCurrentReverse);
- ADD_SHORTCUT("Walk Through Windows of Current Application Alternative", QKeySequence(), m_alternativeTabBoxUi->scCurrent);
- ADD_SHORTCUT("Walk Through Windows of Current Application Alternative (Reverse)", QKeySequence(),
- m_alternativeTabBoxUi->scCurrentReverse);
-#undef ADD_SHORTCUT
+ addConfig(m_tabBoxConfig, m_primaryTabBoxUi);
+ addConfig(m_tabBoxAlternativeConfig, m_alternativeTabBoxUi);
- initLayoutLists();
- KWinTabBoxConfigForm *ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi };
- for (int i = 0; i < 2; ++i) {
- ui[i]->effectConfigButton->setIcon(QIcon::fromTheme(QStringLiteral("view-preview")));
-
- connect(ui[i]->highlightWindowCheck, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->showTabBox, SIGNAL(clicked(bool)), SLOT(tabBoxToggled(bool)));
- connect(ui[i]->effectCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed()));
- connect(ui[i]->effectCombo, SIGNAL(currentIndexChanged(int)), SLOT(effectSelectionChanged(int)));
- connect(ui[i]->effectConfigButton, SIGNAL(clicked(bool)), SLOT(configureEffectClicked()));
-
- connect(ui[i]->switchingModeCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed()));
- connect(ui[i]->showDesktop, SIGNAL(clicked(bool)), SLOT(changed()));
-
- connect(ui[i]->filterDesktops, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->currentDesktop, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->otherDesktops, SIGNAL(clicked(bool)), SLOT(changed()));
-
- connect(ui[i]->filterActivities, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->currentActivity, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->otherActivities, SIGNAL(clicked(bool)), SLOT(changed()));
-
- connect(ui[i]->filterScreens, SIGNAL(clicked(bool)), SLOT(changed()));
- if (QApplication::screens().count() < 2) {
- ui[i]->filterScreens->hide();
- ui[i]->screenFilter->hide();
- } else {
- connect(ui[i]->currentScreen, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->otherScreens, SIGNAL(clicked(bool)), SLOT(changed()));
- }
+ createConnections(m_primaryTabBoxUi, m_tabBoxConfig);
+ createConnections(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
- connect(ui[i]->oneAppWindow, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->filterMinimization, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->visibleWindows, SIGNAL(clicked(bool)), SLOT(changed()));
- connect(ui[i]->hiddenWindows, SIGNAL(clicked(bool)), SLOT(changed()));
- }
+ initLayoutLists();
// check focus policy - we don't offer configs for unreasonable focus policies
KConfigGroup config(m_config, "Windows");
QString policy = config.readEntry("FocusPolicy", "ClickToFocus");
if ((policy == "FocusUnderMouse") || (policy == "FocusStrictlyUnderMouse")) {
tabWidget->setEnabled(false);
infoLabel->show();
} else {
infoLabel->hide();
}
}
KWinTabBoxConfig::~KWinTabBoxConfig()
{
}
-
static QList availableLnFPackages()
{
QList packages;
QStringList paths;
const QStringList dataPaths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
for (const QString &path : dataPaths) {
QDir dir(path + QLatin1String("/plasma/look-and-feel"));
paths << dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
}
const auto &p = paths;
for (const QString &path : p) {
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel"));
pkg.setPath(path);
pkg.setFallbackPackage(KPackage::Package());
if (!pkg.filePath("defaults").isEmpty()) {
KSharedConfigPtr conf = KSharedConfig::openConfig(pkg.filePath("defaults"));
KConfigGroup cg = KConfigGroup(conf, "kwinrc");
cg = KConfigGroup(&cg, "WindowSwitcher");
if (!cg.readEntry("LayoutName", QString()).isEmpty()) {
packages << pkg;
}
}
}
return packages;
}
void KWinTabBoxConfig::initLayoutLists()
{
// search the effect names
- QString coverswitch = BuiltInEffects::effectData(BuiltInEffect::CoverSwitch).displayName;
- QString flipswitch = BuiltInEffects::effectData(BuiltInEffect::FlipSwitch).displayName;
+ m_coverSwitch = BuiltInEffects::effectData(BuiltInEffect::CoverSwitch).name;
+ m_flipSwitch = BuiltInEffects::effectData(BuiltInEffect::FlipSwitch).name;
QList offers = KPackage::PackageLoader::self()->listPackages("KWin/WindowSwitcher");
QStringList layoutNames, layoutPlugins, layoutPaths;
const auto lnfPackages = availableLnFPackages();
for (const auto &package : lnfPackages) {
const auto &metaData = package.metadata();
layoutNames << metaData.name();
layoutPlugins << metaData.pluginId();
layoutPaths << package.filePath("windowswitcher", QStringLiteral("WindowSwitcher.qml"));
}
for (const auto &offer : offers) {
const QString pluginName = offer.pluginId();
if (offer.value("X-Plasma-API") != "declarativeappletscript") {
continue;
}
//we don't have a proper servicetype
if (offer.value("X-KWin-Exclude-Listing") == QStringLiteral("true")) {
continue;
}
const QString scriptName = offer.value("X-Plasma-MainScript");
const QString scriptFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QLatin1String("kwin/tabbox/") + pluginName + QLatin1String("/contents/")
+ scriptName);
if (scriptFile.isNull()) {
continue;
}
layoutNames << offer.name();
layoutPlugins << pluginName;
layoutPaths << scriptFile;
}
+
KWinTabBoxConfigForm *ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi };
for (int i=0; i<2; ++i) {
- int index = ui[i]->effectCombo->currentIndex();
- QVariant data = ui[i]->effectCombo->itemData(index);
- ui[i]->effectCombo->clear();
- ui[i]->effectCombo->addItem(coverswitch);
- ui[i]->effectCombo->addItem(flipswitch);
+ QStandardItemModel *model = new QStandardItemModel;
+
+ QStandardItem *coverItem = new QStandardItem(BuiltInEffects::effectData(BuiltInEffect::CoverSwitch).displayName);
+ coverItem->setData(m_coverSwitch, Qt::UserRole);
+ coverItem->setData(false, KWinTabBoxConfigForm::AddonEffect);
+ model->appendRow(coverItem);
+
+ QStandardItem *flipItem = new QStandardItem(BuiltInEffects::effectData(BuiltInEffect::FlipSwitch).displayName);
+ flipItem->setData(m_flipSwitch, Qt::UserRole);
+ flipItem->setData(false, KWinTabBoxConfigForm::AddonEffect);
+ model->appendRow(flipItem);
+
for (int j = 0; j < layoutNames.count(); ++j) {
- ui[i]->effectCombo->addItem(layoutNames[j], layoutPlugins[j]);
- ui[i]->effectCombo->setItemData(ui[i]->effectCombo->count() - 1, layoutPaths[j], Qt::UserRole+1);
- }
- if (data.isValid()) {
- ui[i]->effectCombo->setCurrentIndex(ui[i]->effectCombo->findData(data));
- } else if (index != -1) {
- ui[i]->effectCombo->setCurrentIndex(index);
+ QStandardItem *item = new QStandardItem(layoutNames[j]);
+ item->setData(layoutPlugins[j], Qt::UserRole);
+ item->setData(layoutPaths[j], KWinTabBoxConfigForm::LayoutPath);
+ item->setData(true, KWinTabBoxConfigForm::AddonEffect);
+ model->appendRow(item);
}
+ model->sort(0);
+ ui[i]->setEffectComboModel(model);
}
}
+void KWinTabBoxConfig::createConnections(KWinTabBoxConfigForm *form, TabBoxSettings *config)
+{
+ connect(form, SIGNAL(effectConfigButtonClicked()), this, SLOT(configureEffectClicked()));
+
+ connect(form, SIGNAL(filterScreenChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(filterDesktopChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(filterActivitiesChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(filterMinimizationChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(applicationModeChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(showDesktopModeChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(switchingModeChanged(int)), this, SLOT(updateUnmanagedState()));
+ connect(form, SIGNAL(layoutNameChanged(QString)), this, SLOT(updateUnmanagedState()));
+}
+
+void KWinTabBoxConfig::updateUnmanagedState()
+{
+ bool isNeedSave = false;
+ isNeedSave |= updateUnmanagedIsNeedSave(m_primaryTabBoxUi, m_tabBoxConfig);
+ isNeedSave |= updateUnmanagedIsNeedSave(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
+
+ unmanagedWidgetChangeState(isNeedSave);
+
+ bool isDefault = true;
+ isDefault &= updateUnmanagedIsDefault(m_primaryTabBoxUi, m_tabBoxConfig);
+ isDefault &= updateUnmanagedIsDefault(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
+
+ unmanagedWidgetDefaultState(isDefault);
+}
+
+bool KWinTabBoxConfig::updateUnmanagedIsNeedSave(const KWinTabBoxConfigForm *form, const TabBoxSettings *config)
+{
+ bool isNeedSave = false;
+ isNeedSave |= form->filterScreen() != config->multiScreenMode();
+ isNeedSave |= form->filterDesktop() != config->desktopMode();
+ isNeedSave |= form->filterActivities() != config->activitiesMode();
+ isNeedSave |= form->filterMinimization() != config->minimizedMode();
+ isNeedSave |= form->applicationMode() != config->applicationsMode();
+ isNeedSave |= form->showDesktopMode() != config->showDesktopMode();
+ isNeedSave |= form->switchingMode() != config->switchingMode();
+ isNeedSave |= form->layoutName() != config->layoutName();
+
+ return isNeedSave;
+}
+
+bool KWinTabBoxConfig::updateUnmanagedIsDefault(const KWinTabBoxConfigForm *form, const TabBoxSettings *config)
+{
+ bool isDefault = true;
+ isDefault &= form->filterScreen() == config->defaultMultiScreenModeValue();
+ isDefault &= form->filterDesktop() == config->defaultDesktopModeValue();
+ isDefault &= form->filterActivities() == config->defaultActivitiesModeValue();
+ isDefault &= form->filterMinimization() == config->defaultMinimizedModeValue();
+ isDefault &= form->applicationMode() == config->defaultApplicationsModeValue();
+ isDefault &= form->showDesktopMode() == config->defaultShowDesktopModeValue();
+ isDefault &= form->switchingMode() == config->defaultSwitchingModeValue();
+ isDefault &= form->layoutName() == config->defaultLayoutNameValue();
+
+ return isDefault;
+}
+
void KWinTabBoxConfig::load()
{
KCModule::load();
m_tabBoxConfig->load();
m_tabBoxAlternativeConfig->load();
+ updateUiFromConfig(m_primaryTabBoxUi, m_tabBoxConfig);
+ updateUiFromConfig(m_alternativeTabBoxUi , m_tabBoxAlternativeConfig);
+
m_coverSwitchConfig->load();
m_flipSwitchConfig->load();
m_pluginsConfig->load();
- updateUiFromConfig(m_primaryTabBoxUi, m_tabBoxConfig);
- updateUiFromConfig(m_alternativeTabBoxUi , m_tabBoxAlternativeConfig);
-
if (m_pluginsConfig->coverswitchEnabled()) {
if (m_coverSwitchConfig->tabBox()) {
- m_primaryTabBoxUi->effectCombo->setCurrentIndex(CoverSwitch);
+ m_primaryTabBoxUi->setLayoutName(m_coverSwitch);
}
if (m_coverSwitchConfig->tabBoxAlternative()) {
- m_alternativeTabBoxUi->effectCombo->setCurrentIndex(CoverSwitch);
+ m_alternativeTabBoxUi->setLayoutName(m_coverSwitch);
}
}
if (m_pluginsConfig->flipswitchEnabled()) {
if (m_flipSwitchConfig->tabBox()) {
- m_primaryTabBoxUi->effectCombo->setCurrentIndex(FlipSwitch);
+ m_primaryTabBoxUi->setLayoutName(m_flipSwitch);
}
if (m_flipSwitchConfig->tabBoxAlternative()) {
- m_alternativeTabBoxUi->effectCombo->setCurrentIndex(FlipSwitch);
+ m_alternativeTabBoxUi->setLayoutName(m_flipSwitch);
}
}
- KWinTabBoxConfigForm* ui[2] = { m_primaryTabBoxUi, m_alternativeTabBoxUi };
- for (int i = 0; i < 2; ++i) {
- QString action;
-#define LOAD_SHORTCUT(_BTN_)\
- action = ui[i]->_BTN_->property("shortcutAction").toString();\
- qDebug() << "load shortcut for " << action;\
- if (QAction *a = m_actionCollection->action(action)) { \
- auto shortcuts = KGlobalAccel::self()->shortcut(a); \
- if (!shortcuts.isEmpty()) \
- ui[i]->_BTN_->setKeySequence(shortcuts.first()); \
- }
- LOAD_SHORTCUT(scAll);
- LOAD_SHORTCUT(scAllReverse);
- LOAD_SHORTCUT(scCurrent);
- LOAD_SHORTCUT(scCurrentReverse);
-#undef LOAD_SHORTCUT
- }
- emit changed(false);
+ m_primaryTabBoxUi->loadShortcuts();
+ m_alternativeTabBoxUi->loadShortcuts();
+
+ updateUnmanagedState();
}
void KWinTabBoxConfig::save()
{
- KCModule::save();
-
- // sync ui to config
- updateConfigFromUi(m_primaryTabBoxUi, m_tabBoxConfig);
- updateConfigFromUi(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
- m_tabBoxConfig->save();
- m_tabBoxAlternativeConfig->save();
-
// effects
- bool highlightWindows = m_primaryTabBoxUi->highlightWindowCheck->isChecked() ||
- m_alternativeTabBoxUi->highlightWindowCheck->isChecked();
- const bool coverSwitch = m_primaryTabBoxUi->showTabBox->isChecked() &&
- m_primaryTabBoxUi->effectCombo->currentIndex() == CoverSwitch;
- const bool flipSwitch = m_primaryTabBoxUi->showTabBox->isChecked() &&
- m_primaryTabBoxUi->effectCombo->currentIndex() == FlipSwitch;
- const bool coverSwitchAlternative = m_alternativeTabBoxUi->showTabBox->isChecked() &&
- m_alternativeTabBoxUi->effectCombo->currentIndex() == CoverSwitch;
- const bool flipSwitchAlternative = m_alternativeTabBoxUi->showTabBox->isChecked() &&
- m_alternativeTabBoxUi->effectCombo->currentIndex() == FlipSwitch;
+ const bool highlightWindows = m_primaryTabBoxUi->highlightWindows() || m_alternativeTabBoxUi->highlightWindows();
+ const bool coverSwitch = m_primaryTabBoxUi->showTabBox()
+ && m_primaryTabBoxUi->effectComboCurrentData().toString() == m_coverSwitch;
+ const bool flipSwitch = m_primaryTabBoxUi->showTabBox()
+ && m_primaryTabBoxUi->effectComboCurrentData().toString() == m_flipSwitch;
+ const bool coverSwitchAlternative = m_alternativeTabBoxUi->showTabBox()
+ && m_alternativeTabBoxUi->effectComboCurrentData().toString() == m_coverSwitch;
+ const bool flipSwitchAlternative = m_alternativeTabBoxUi->showTabBox()
+ && m_alternativeTabBoxUi->effectComboCurrentData().toString() == m_flipSwitch;
// activate effects if not active
if (coverSwitch || coverSwitchAlternative) {
m_pluginsConfig->setCoverswitchEnabled(true);
}
if (flipSwitch || flipSwitchAlternative) {
m_pluginsConfig->setFlipswitchEnabled(true);
}
if (highlightWindows) {
m_pluginsConfig->setHighlightwindowEnabled(true);
}
m_pluginsConfig->save();
m_coverSwitchConfig->setTabBox(coverSwitch);
m_coverSwitchConfig->setTabBoxAlternative(coverSwitchAlternative);
m_coverSwitchConfig->save();
m_flipSwitchConfig->setTabBox(flipSwitch);
m_flipSwitchConfig->setTabBoxAlternative(flipSwitchAlternative);
m_flipSwitchConfig->save();
+ updateConfigFromUi(m_primaryTabBoxUi, m_tabBoxConfig);
+ updateConfigFromUi(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
+
+ m_tabBoxConfig->save();
+ m_tabBoxAlternativeConfig->save();
+
+ KCModule::save();
+ updateUnmanagedState();
+
// Reload KWin.
QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
// and reconfigure the effects
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
QStringLiteral("/Effects"),
QDBusConnection::sessionBus());
interface.reconfigureEffect(BuiltInEffects::nameForEffect(BuiltInEffect::CoverSwitch));
interface.reconfigureEffect(BuiltInEffects::nameForEffect(BuiltInEffect::FlipSwitch));
-
- emit changed(false);
}
void KWinTabBoxConfig::defaults()
{
- KCModule::defaults();
-
- m_tabBoxConfig->setDefaults();
- m_tabBoxAlternativeConfig->setDefaults();
-
- m_pluginsConfig->setDefaults();
m_coverSwitchConfig->setDefaults();
m_flipSwitchConfig->setDefaults();
- updateUiFromConfig(m_primaryTabBoxUi, m_tabBoxConfig);
- updateUiFromConfig(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
-
- QString action;
- auto RESET_SHORTCUT = [this](KKeySequenceWidget *widget, const QKeySequence &sequence = QKeySequence()) {
- const QString action = widget->property("shortcutAction").toString();
- QAction *a = m_actionCollection->action(action);
- KGlobalAccel::self()->setShortcut(a, QList() << sequence, KGlobalAccel::NoAutoloading);
- };
- RESET_SHORTCUT(m_primaryTabBoxUi->scAll, Qt::ALT + Qt::Key_Tab);
- RESET_SHORTCUT(m_primaryTabBoxUi->scAllReverse, Qt::ALT + Qt::SHIFT + Qt::Key_Backtab);
- RESET_SHORTCUT(m_alternativeTabBoxUi->scAll);
- RESET_SHORTCUT(m_alternativeTabBoxUi->scAllReverse);
- RESET_SHORTCUT(m_primaryTabBoxUi->scCurrent, Qt::ALT + Qt::Key_QuoteLeft);
- RESET_SHORTCUT(m_primaryTabBoxUi->scCurrentReverse, Qt::ALT + Qt::Key_AsciiTilde);
- RESET_SHORTCUT(m_alternativeTabBoxUi->scCurrent);
- RESET_SHORTCUT(m_alternativeTabBoxUi->scCurrentReverse);
- m_actionCollection->writeSettings();
- emit changed(true);
-}
+ updateUiFromDefaultConfig(m_primaryTabBoxUi, m_tabBoxConfig);
+ updateUiFromDefaultConfig(m_alternativeTabBoxUi, m_tabBoxAlternativeConfig);
-void KWinTabBoxConfig::updateUiFromConfig(KWinTabBoxConfigForm *ui, const KWin::TabBox::TabBoxSettings *config)
-{
-#define CONFIGURE(SETTING, MODE, IS, VALUE) ui->SETTING->setChecked(config->MODE##Mode() IS TabBoxConfig::VALUE)
- CONFIGURE(filterDesktops, desktop, !=, AllDesktopsClients);
- CONFIGURE(currentDesktop, desktop, ==, OnlyCurrentDesktopClients);
- CONFIGURE(otherDesktops, desktop, ==, ExcludeCurrentDesktopClients);
- CONFIGURE(filterActivities, activities, !=, AllActivitiesClients);
- CONFIGURE(currentActivity, activities, ==, OnlyCurrentActivityClients);
- CONFIGURE(otherActivities, activities, ==, ExcludeCurrentActivityClients);
- CONFIGURE(filterScreens, multiScreen, !=, IgnoreMultiScreen);
- CONFIGURE(currentScreen, multiScreen, ==, OnlyCurrentScreenClients);
- CONFIGURE(otherScreens, multiScreen, ==, ExcludeCurrentScreenClients);
- CONFIGURE(oneAppWindow, applications, ==, OneWindowPerApplication);
- CONFIGURE(filterMinimization, minimized, !=, IgnoreMinimizedStatus);
- CONFIGURE(visibleWindows, minimized, ==, ExcludeMinimizedClients);
- CONFIGURE(hiddenWindows, minimized, ==, OnlyMinimizedClients);
-
- ui->switchingModeCombo->setCurrentIndex(config->switchingMode());
-
- // check boxes
- ui->showTabBox->setChecked(config->showTabBox());
- ui->highlightWindowCheck->setChecked(config->highlightWindows());
- ui->effectCombo->setCurrentIndex(ui->effectCombo->findData(config->layoutName()));
- CONFIGURE(showDesktop, showDesktop, ==, ShowDesktopClient);
-#undef CONFIGURE
+ m_primaryTabBoxUi->resetShortcuts();
+ m_alternativeTabBoxUi->resetShortcuts();
+
+ KCModule::defaults();
+ updateUnmanagedState();
}
-void KWinTabBoxConfig::updateConfigFromUi(const KWin::KWinTabBoxConfigForm *ui, TabBoxSettings *config)
+void KWinTabBoxConfig::updateUiFromConfig(KWinTabBoxConfigForm *form, const KWin::TabBox::TabBoxSettings *config)
{
- if (ui->filterDesktops->isChecked()) {
- config->setDesktopMode(ui->currentDesktop->isChecked() ? TabBoxConfig::OnlyCurrentDesktopClients : TabBoxConfig::ExcludeCurrentDesktopClients);
- } else {
- config->setDesktopMode(TabBoxConfig::AllDesktopsClients);
- }
- if (ui->filterActivities->isChecked()) {
- config->setActivitiesMode(ui->currentActivity->isChecked() ? TabBoxConfig::OnlyCurrentActivityClients : TabBoxConfig::ExcludeCurrentActivityClients);
- } else {
- config->setActivitiesMode(TabBoxConfig::AllActivitiesClients);
- }
- if (ui->filterScreens->isChecked()) {
- config->setMultiScreenMode(ui->currentScreen->isChecked() ? TabBoxConfig::OnlyCurrentScreenClients : TabBoxConfig::ExcludeCurrentScreenClients);
- } else {
- config->setMultiScreenMode(TabBoxConfig::IgnoreMultiScreen);
- }
- config->setApplicationsMode(ui->oneAppWindow->isChecked() ? TabBoxConfig::OneWindowPerApplication : TabBoxConfig::AllWindowsAllApplications);
- if (ui->filterMinimization->isChecked()) {
- config->setMinimizedMode(ui->visibleWindows->isChecked() ? TabBoxConfig::ExcludeMinimizedClients : TabBoxConfig::OnlyMinimizedClients);
- } else {
- config->setMinimizedMode(TabBoxConfig::IgnoreMinimizedStatus);
- }
-
- config->setSwitchingMode(TabBoxConfig::ClientSwitchingMode(ui->switchingModeCombo->currentIndex()));
-
- config->setShowTabBox(ui->showTabBox->isChecked());
- config->setHighlightWindows(ui->highlightWindowCheck->isChecked());
- if (ui->effectCombo->currentIndex() >= Layout) {
- config->setLayoutName(ui->effectCombo->itemData(ui->effectCombo->currentIndex()).toString());
- }
- config->setShowDesktopMode(ui->showDesktop->isChecked() ? TabBoxConfig::ShowDesktopClient : TabBoxConfig::DoNotShowDesktopClient);
+ form->setFilterScreen(static_cast(config->multiScreenMode()));
+ form->setFilterDesktop(static_cast(config->desktopMode()));
+ form->setFilterActivities(static_cast(config->activitiesMode()));
+ form->setFilterMinimization(static_cast(config->minimizedMode()));
+ form->setApplicationMode(static_cast(config->applicationsMode()));
+ form->setShowDesktopMode(static_cast(config->showDesktopMode()));
+ form->setSwitchingModeChanged(static_cast(config->switchingMode()));
+ form->setLayoutName(config->layoutName());
}
-#define CHECK_CURRENT_TABBOX_UI \
- Q_ASSERT(sender());\
- KWinTabBoxConfigForm *ui = nullptr;\
- QObject *dad = sender();\
- while (!ui && (dad = dad->parent()))\
- ui = qobject_cast(dad);\
- Q_ASSERT(ui);
-
-void KWinTabBoxConfig::effectSelectionChanged(int index)
+void KWinTabBoxConfig::updateConfigFromUi(const KWinTabBoxConfigForm *form, TabBoxSettings *config)
{
- CHECK_CURRENT_TABBOX_UI
- ui->effectConfigButton->setIcon(QIcon::fromTheme(index < Layout ? "configure" : "view-preview"));
- if (!ui->showTabBox->isChecked())
- return;
- ui->highlightWindowCheck->setEnabled(index >= Layout);
+ config->setMultiScreenMode(form->filterScreen());
+ config->setDesktopMode(form->filterDesktop());
+ config->setActivitiesMode(form->filterActivities());
+ config->setMinimizedMode(form->filterMinimization());
+ config->setApplicationsMode(form->applicationMode());
+ config->setShowDesktopMode(form->showDesktopMode());
+ config->setSwitchingMode(form->switchingMode());
+ config->setLayoutName(form->layoutName());
}
-void KWinTabBoxConfig::tabBoxToggled(bool on)
+void KWinTabBoxConfig::updateUiFromDefaultConfig(KWinTabBoxConfigForm *form, const KWin::TabBox::TabBoxSettings *config)
{
- CHECK_CURRENT_TABBOX_UI
- on = !on || ui->effectCombo->currentIndex() >= Layout;
- ui->highlightWindowCheck->setEnabled(on);
- markAsChanged();
+ form->setFilterScreen(static_cast(config->defaultMultiScreenModeValue()));
+ form->setFilterDesktop(static_cast(config->defaultDesktopModeValue()));
+ form->setFilterActivities(static_cast(config->defaultActivitiesModeValue()));
+ form->setFilterMinimization(static_cast(config->defaultMinimizedModeValue()));
+ form->setApplicationMode(static_cast(config->defaultApplicationsModeValue()));
+ form->setShowDesktopMode(static_cast(config->defaultShowDesktopModeValue()));
+ form->setSwitchingModeChanged(static_cast(config->defaultSwitchingModeValue()));
+ form->setLayoutName(config->defaultLayoutNameValue());
}
void KWinTabBoxConfig::configureEffectClicked()
{
- CHECK_CURRENT_TABBOX_UI
+ auto form = qobject_cast(sender());
+ Q_ASSERT(form);
- const int effect = ui->effectCombo->currentIndex();
- if (effect >= Layout) {
- // TODO: here we need to show the preview
- new LayoutPreview(ui->effectCombo->itemData(effect, Qt::UserRole+1).toString(), this);
+ if (form->effectComboCurrentData(KWinTabBoxConfigForm::AddonEffect).toBool()) {
+ // Show the preview for addon effect
+ new LayoutPreview(form->effectComboCurrentData(KWinTabBoxConfigForm::LayoutPath).toString(), this);
} else {
+ // For builtin effect, display a configuration dialog
QPointer configDialog = new QDialog(this);
configDialog->setLayout(new QVBoxLayout);
- configDialog->setWindowTitle(ui->effectCombo->currentText());
+ configDialog->setWindowTitle(form->effectComboCurrentData(Qt::DisplayRole).toString());
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel|QDialogButtonBox::RestoreDefaults, configDialog);
connect(buttonBox, SIGNAL(accepted()), configDialog, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), configDialog, SLOT(reject()));
- const QString name = BuiltInEffects::nameForEffect(effect == CoverSwitch ? BuiltInEffect::CoverSwitch : BuiltInEffect::FlipSwitch);
-
+ const QString name = form->effectComboCurrentData().toString();
KCModule *kcm = KPluginTrader::createInstanceFromQuery(QStringLiteral("kwin/effects/configs/"), QString(),
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(name),
- configDialog);
+ configDialog);
if (!kcm) {
delete configDialog;
return;
}
connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, kcm, &KCModule::defaults);
QWidget *showWidget = new QWidget(configDialog);
QVBoxLayout *layout = new QVBoxLayout;
showWidget->setLayout(layout);
layout->addWidget(kcm);
configDialog->layout()->addWidget(showWidget);
configDialog->layout()->addWidget(buttonBox);
if (configDialog->exec() == QDialog::Accepted) {
kcm->save();
} else {
kcm->load();
}
delete configDialog;
}
}
-void KWinTabBoxConfig::shortcutChanged(const QKeySequence &seq)
-{
- QString action;
- if (sender())
- action = sender()->property("shortcutAction").toString();
- if (action.isEmpty())
- return;
- QAction *a = m_actionCollection->action(action);
- KGlobalAccel::self()->setShortcut(a, QList() << seq, KGlobalAccel::NoAutoloading);
- m_actionCollection->writeSettings();
-}
-
void KWinTabBoxConfig::slotGHNS()
{
QPointer downloadDialog = new KNS3::DownloadDialog("kwinswitcher.knsrc", this);
if (downloadDialog->exec() == QDialog::Accepted) {
if (!downloadDialog->changedEntries().isEmpty()) {
initLayoutLists();
}
}
delete downloadDialog;
}
} // namespace
#include "main.moc"
diff --git a/kcmkwin/kwintabbox/main.h b/kcmkwin/kwintabbox/main.h
index a6d962962..1cac4bc4b 100644
--- a/kcmkwin/kwintabbox/main.h
+++ b/kcmkwin/kwintabbox/main.h
@@ -1,98 +1,86 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin
Copyright (C) 2020 Cyril Rossi
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 __MAIN_H__
#define __MAIN_H__
#include
#include
-
-#include "ui_main.h"
-
-class KShortcutsEditor;
-class KActionCollection;
+#include "tabboxconfig.h"
namespace KWin
{
+class KWinTabBoxConfigForm;
enum class BuiltInEffect;
namespace TabBox
{
class TabBoxSettings;
class SwitchEffectSettings;
class PluginsSettings;
}
-
-class KWinTabBoxConfigForm : public QWidget, public Ui::KWinTabBoxConfigForm
-{
- Q_OBJECT
-
-public:
- explicit KWinTabBoxConfigForm(QWidget* parent);
-};
-
class KWinTabBoxConfig : public KCModule
{
Q_OBJECT
public:
explicit KWinTabBoxConfig(QWidget* parent, const QVariantList& args);
~KWinTabBoxConfig() override;
public Q_SLOTS:
void save() override;
void load() override;
void defaults() override;
private Q_SLOTS:
- void effectSelectionChanged(int index);
+ void updateUnmanagedState();
void configureEffectClicked();
- void tabBoxToggled(bool on);
- void shortcutChanged(const QKeySequence &seq);
void slotGHNS();
+
private:
- void updateUiFromConfig(KWinTabBoxConfigForm *ui, const TabBox::TabBoxSettings *config);
- void updateConfigFromUi(const KWinTabBoxConfigForm *ui, TabBox::TabBoxSettings *config);
+ void updateUiFromConfig(KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config);
+ void updateConfigFromUi(const KWinTabBoxConfigForm *form, TabBox::TabBoxSettings *config);
+ void updateUiFromDefaultConfig(KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config);
void initLayoutLists();
+ void createConnections(KWinTabBoxConfigForm *form, TabBox::TabBoxSettings *config);
+ bool updateUnmanagedIsNeedSave(const KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config);
+ bool updateUnmanagedIsDefault(const KWinTabBoxConfigForm *form, const TabBox::TabBoxSettings *config);
private:
- enum Mode {
- CoverSwitch = 0,
- FlipSwitch = 1,
- Layout = 2
- };
- KWinTabBoxConfigForm* m_primaryTabBoxUi;
- KWinTabBoxConfigForm* m_alternativeTabBoxUi;
+ KWinTabBoxConfigForm *m_primaryTabBoxUi = nullptr;
+ KWinTabBoxConfigForm *m_alternativeTabBoxUi = nullptr;
KSharedConfigPtr m_config;
- KActionCollection* m_actionCollection;
- KShortcutsEditor* m_editor;
+
TabBox::TabBoxSettings *m_tabBoxConfig;
TabBox::TabBoxSettings *m_tabBoxAlternativeConfig;
TabBox::SwitchEffectSettings *m_coverSwitchConfig;
TabBox::SwitchEffectSettings *m_flipSwitchConfig;
TabBox::PluginsSettings *m_pluginsConfig;
+ // Builtin effects' names
+ QString m_coverSwitch;
+ QString m_flipSwitch;
};
} // namespace
#endif
diff --git a/kcmkwin/kwintabbox/main.ui b/kcmkwin/kwintabbox/main.ui
index 9147dad94..e702e358b 100644
--- a/kcmkwin/kwintabbox/main.ui
+++ b/kcmkwin/kwintabbox/main.ui
@@ -1,699 +1,699 @@
KWinTabBoxConfigForm
0
0
658
418
-
Qt::Horizontal
40
20
-
-
Content
true
-
Include "Show Desktop" icon
-
0
0
-
Recently used
-
Stacking order
-
Only one window per application
false
-
Sort order:
switchingModeCombo
-
Qt::Horizontal
40
20
-
Filter windows by
true
-
Virtual desktops
false
-
false
0
0
0
0
-
Qt::Horizontal
QSizePolicy::Fixed
24
20
-
Current desktop
-
All other desktops
-
Activities
false
-
false
0
0
0
0
-
Qt::Horizontal
QSizePolicy::Fixed
24
20
-
Current activity
-
All other activities
-
Screens
false
-
false
0
0
0
0
-
Qt::Horizontal
QSizePolicy::Fixed
24
20
-
Current screen
-
All other screens
-
Minimization
false
-
false
0
0
0
0
-
Qt::Horizontal
QSizePolicy::Fixed
24
20
-
Visible windows
-
Hidden windows
-
Qt::Vertical
20
40
-
Qt::Vertical
20
40
-
Shortcuts
true
-
Forward
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Qt::Horizontal
-
75
true
All windows
Qt::AlignCenter
-
Reverse
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Forward
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Reverse
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
75
true
Current application
Qt::AlignCenter
-
-
-
Visualization
true
-
0
0
0
0
-
0
0
The effect to replace the list window when desktop effects are active.
-
0
0
-
-
+
true
-
-
+
The currently selected window will be highlighted by fading out all other windows. This option requires desktop effects to be active.
Show selected window
-
Qt::Vertical
-
Qt::Horizontal
40
20
KKeySequenceWidget
QWidget
KComboBox
QComboBox
- highlightWindowCheck
- showTabBox
+ kcfg_HighlightWindows
+ kcfg_ShowTabBox
effectCombo
effectConfigButton
switchingModeCombo
showDesktop
oneAppWindow
filterDesktops
currentDesktop
otherDesktops
filterActivities
currentActivity
otherActivities
filterScreens
currentScreen
otherScreens
filterMinimization
visibleWindows
hiddenWindows
filterDesktops
toggled(bool)
desktopFilter
setEnabled(bool)
541
172
701
197
filterActivities
toggled(bool)
activityFilter
setEnabled(bool)
543
222
701
247
filterScreens
toggled(bool)
screenFilter
setEnabled(bool)
555
272
701
297
filterMinimization
toggled(bool)
minimizationFilter
setEnabled(bool)
558
322
701
347
- showTabBox
+ kcfg_ShowTabBox
toggled(bool)
widget_6
setEnabled(bool)
164
125
230
108
diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h
index 1101dbce3..abff491b9 100644
--- a/libkwineffects/kwineffects.h
+++ b/libkwineffects/kwineffects.h
@@ -1,4019 +1,4019 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006 Lubos Lunak
Copyright (C) 2009 Lucas Murray
Copyright (C) 2010, 2011 Martin Gräßlin
Copyright (C) 2018 Vlad Zahorodnii
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 KWINEFFECTS_H
#define KWINEFFECTS_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class KConfigGroup;
class QFont;
class QGraphicsScale;
class QKeyEvent;
class QMatrix4x4;
class QAction;
/**
* Logging category to be used inside the KWin effects.
* Do not use in this library.
*/
Q_DECLARE_LOGGING_CATEGORY(KWINEFFECTS)
namespace KWayland {
namespace Server {
class SurfaceInterface;
class Display;
}
}
namespace KWin
{
class PaintDataPrivate;
class WindowPaintDataPrivate;
class EffectWindow;
class EffectWindowGroup;
class EffectFrame;
class EffectFramePrivate;
class EffectQuickView;
class Effect;
class WindowQuad;
class GLShader;
class XRenderPicture;
class WindowQuadList;
class WindowPrePaintData;
class WindowPaintData;
class ScreenPrePaintData;
class ScreenPaintData;
typedef QPair< QString, Effect* > EffectPair;
typedef QList< KWin::EffectWindow* > EffectWindowList;
/** @defgroup kwineffects KWin effects library
* KWin effects library contains necessary classes for creating new KWin
* compositing effects.
*
* @section creating Creating new effects
* This example will demonstrate the basics of creating an effect. We'll use
* CoolEffect as the class name, cooleffect as internal name and
* "Cool Effect" as user-visible name of the effect.
*
* This example doesn't demonstrate how to write the effect's code. For that,
* see the documentation of the Effect class.
*
* @subsection creating-class CoolEffect class
* First you need to create CoolEffect class which has to be a subclass of
* @ref KWin::Effect. In that class you can reimplement various virtual
* methods to control how and where the windows are drawn.
*
* @subsection creating-macro KWIN_EFFECT_FACTORY macro
* This library provides a specialized KPluginFactory subclass and macros to
* create a sub class. This subclass of KPluginFactory has to be used, otherwise
* KWin won't load the plugin. Use the @ref KWIN_EFFECT_FACTORY macro to create the
* plugin factory.
*
* @subsection creating-buildsystem Buildsystem
* To build the effect, you can use the KWIN_ADD_EFFECT() cmake macro which
* can be found in effects/CMakeLists.txt file in KWin's source. First
* argument of the macro is the name of the library that will contain
* your effect. Although not strictly required, it is usually a good idea to
* use the same name as your effect's internal name there. Following arguments
* to the macro are the files containing your effect's source. If our effect's
* source is in cooleffect.cpp, we'd use following:
* @code
* KWIN_ADD_EFFECT(cooleffect cooleffect.cpp)
* @endcode
*
* This macro takes care of compiling your effect. You'll also need to install
* your effect's .desktop file, so the example CMakeLists.txt file would be
* as follows:
* @code
* KWIN_ADD_EFFECT(cooleffect cooleffect.cpp)
* install( FILES cooleffect.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
* @endcode
*
* @subsection creating-desktop Effect's .desktop file
* You will also need to create .desktop file to set name, description, icon
* and other properties of your effect. Important fields of the .desktop file
* are:
* @li Name User-visible name of your effect
* @li Icon Name of the icon of the effect
* @li Comment Short description of the effect
* @li Type must be "Service"
* @li X-KDE-ServiceTypes must be "KWin/Effect"
* @li X-KDE-PluginInfo-Name effect's internal name as passed to the KWIN_EFFECT macro plus "kwin4_effect_" prefix
* @li X-KDE-PluginInfo-Category effect's category. Should be one of Appearance, Accessibility, Window Management, Demos, Tests, Misc
* @li X-KDE-PluginInfo-EnabledByDefault whether the effect should be enabled by default (use sparingly). Default is false
* @li X-KDE-Library name of the library containing the effect. This is the first argument passed to the KWIN_ADD_EFFECT macro in cmake file plus "kwin4_effect_" prefix.
*
* Example cooleffect.desktop file follows:
* @code
[Desktop Entry]
Name=Cool Effect
Comment=The coolest effect you've ever seen
Icon=preferences-system-windows-effect-cooleffect
Type=Service
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=My Name
X-KDE-PluginInfo-Email=my@email.here
X-KDE-PluginInfo-Name=kwin4_effect_cooleffect
X-KDE-PluginInfo-Category=Misc
X-KDE-Library=kwin4_effect_cooleffect
* @endcode
*
*
* @section accessing Accessing windows and workspace
* Effects can gain access to the properties of windows and workspace via
* EffectWindow and EffectsHandler classes.
*
* There is one global EffectsHandler object which you can access using the
* @ref effects pointer.
* For each window, there is an EffectWindow object which can be used to read
* window properties such as position and also to change them.
*
* For more information about this, see the documentation of the corresponding
* classes.
*
* @{
*/
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
-#define KWIN_EFFECT_API_VERSION_MINOR 229
+#define KWIN_EFFECT_API_VERSION_MINOR 230
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
enum WindowQuadType {
WindowQuadError, // for the stupid default ctor
WindowQuadContents,
WindowQuadDecoration,
// Shadow Quad types
WindowQuadShadow, // OpenGL only. The other shadow types are only used by Xrender
WindowQuadShadowTop,
WindowQuadShadowTopRight,
WindowQuadShadowRight,
WindowQuadShadowBottomRight,
WindowQuadShadowBottom,
WindowQuadShadowBottomLeft,
WindowQuadShadowLeft,
WindowQuadShadowTopLeft,
EFFECT_QUAD_TYPE_START = 100 ///< @internal
};
/**
* EffectWindow::setData() and EffectWindow::data() global roles.
* All values between 0 and 999 are reserved for global roles.
*/
enum DataRole {
// Grab roles are used to force all other animations to ignore the window.
// The value of the data is set to the Effect's `this` value.
WindowAddedGrabRole = 1,
WindowClosedGrabRole,
WindowMinimizedGrabRole,
WindowUnminimizedGrabRole,
WindowForceBlurRole, ///< For fullscreen effects to enforce blurring of windows,
WindowBlurBehindRole, ///< For single windows to blur behind
WindowForceBackgroundContrastRole, ///< For fullscreen effects to enforce the background contrast,
WindowBackgroundContrastRole, ///< For single windows to enable Background contrast
LanczosCacheRole
};
/**
* Style types used by @ref EffectFrame.
* @since 4.6
*/
enum EffectFrameStyle {
EffectFrameNone, ///< Displays no frame around the contents.
EffectFrameUnstyled, ///< Displays a basic box around the contents.
EffectFrameStyled ///< Displays a Plasma-styled frame around the contents.
};
/**
* Infinite region (i.e. a special region type saying that everything needs to be painted).
*/
KWINEFFECTS_EXPORT inline
QRect infiniteRegion()
{
// INT_MIN / 2 because width/height is used (INT_MIN+INT_MAX==-1)
return QRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX);
}
/**
* @short Base class for all KWin effects
*
* This is the base class for all effects. By reimplementing virtual methods
* of this class, you can customize how the windows are painted.
*
* The virtual methods are used for painting and need to be implemented for
* custom painting.
*
* In order to react to state changes (e.g. a window gets closed) the effect
* should provide slots for the signals emitted by the EffectsHandler.
*
* @section Chaining
* Most methods of this class are called in chain style. This means that when
* effects A and B area active then first e.g. A::paintWindow() is called and
* then from within that method B::paintWindow() is called (although
* indirectly). To achieve this, you need to make sure to call corresponding
* method in EffectsHandler class from each such method (using @ref effects
* pointer):
* @code
* void MyEffect::postPaintScreen()
* {
* // Do your own processing here
* ...
* // Call corresponding EffectsHandler method
* effects->postPaintScreen();
* }
* @endcode
*
* @section Effectsptr Effects pointer
* @ref effects pointer points to the global EffectsHandler object that you can
* use to interact with the windows.
*
* @section painting Painting stages
* Painting of windows is done in three stages:
* @li First, the prepaint pass.
* Here you can specify how the windows will be painted, e.g. that they will
* be translucent and transformed.
* @li Second, the paint pass.
* Here the actual painting takes place. You can change attributes such as
* opacity of windows as well as apply transformations to them. You can also
* paint something onto the screen yourself.
* @li Finally, the postpaint pass.
* Here you can mark windows, part of windows or even the entire screen for
* repainting to create animations.
*
* For each stage there are *Screen() and *Window() methods. The window method
* is called for every window which the screen method is usually called just
* once.
*
* @section OpenGL
* Effects can use OpenGL if EffectsHandler::isOpenGLCompositing() returns @c true.
* The OpenGL context may not always be current when code inside the effect is
* executed. The framework ensures that the OpenGL context is current when the Effect
* gets created, destroyed or reconfigured and during the painting stages. All virtual
* methods which have the OpenGL context current are documented.
*
* If OpenGL code is going to be executed outside the painting stages, e.g. in reaction
* to a global shortcut, it is the task of the Effect to make the OpenGL context current:
* @code
* effects->makeOpenGLContextCurrent();
* @endcode
*
* There is in general no need to call the matching doneCurrent method.
*/
class KWINEFFECTS_EXPORT Effect : public QObject
{
Q_OBJECT
public:
/** Flags controlling how painting is done. */
// TODO: is that ok here?
enum {
/**
* Window (or at least part of it) will be painted opaque.
*/
PAINT_WINDOW_OPAQUE = 1 << 0,
/**
* Window (or at least part of it) will be painted translucent.
*/
PAINT_WINDOW_TRANSLUCENT = 1 << 1,
/**
* Window will be painted with transformed geometry.
*/
PAINT_WINDOW_TRANSFORMED = 1 << 2,
/**
* Paint only a region of the screen (can be optimized, cannot
* be used together with TRANSFORMED flags).
*/
PAINT_SCREEN_REGION = 1 << 3,
/**
* The whole screen will be painted with transformed geometry.
* Forces the entire screen to be painted.
*/
PAINT_SCREEN_TRANSFORMED = 1 << 4,
/**
* At least one window will be painted with transformed geometry.
* Forces the entire screen to be painted.
*/
PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
/**
* Clear whole background as the very first step, without optimizing it
*/
PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
// PAINT_DECORATION_ONLY = 1 << 7 has been deprecated
/**
* Window will be painted with a lanczos filter.
*/
PAINT_WINDOW_LANCZOS = 1 << 8
// PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS = 1 << 9 has been removed
};
enum Feature {
Nothing = 0,
Resize,
GeometryTip,
Outline, /**< @deprecated */
ScreenInversion,
Blur,
Contrast,
HighlightWindows
};
/**
* Constructs new Effect object.
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when the Effect is constructed.
*/
Effect();
/**
* Destructs the Effect object.
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when the Effect is destroyed.
*/
~Effect() override;
/**
* Flags describing which parts of configuration have changed.
*/
enum ReconfigureFlag {
ReconfigureAll = 1 << 0 /// Everything needs to be reconfigured.
};
Q_DECLARE_FLAGS(ReconfigureFlags, ReconfigureFlag)
/**
* Called when configuration changes (either the effect's or KWin's global).
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when the Effect is reconfigured. If this method is called from within the Effect it is
* required to ensure that the context is current if the implementation does OpenGL calls.
*/
virtual void reconfigure(ReconfigureFlags flags);
/**
* Called when another effect requests the proxy for this effect.
*/
virtual void* proxy();
/**
* Called before starting to paint the screen.
* In this method you can:
* @li set whether the windows or the entire screen will be transformed
* @li change the region of the screen that will be painted
* @li do various housekeeping tasks such as initing your effect's variables
for the upcoming paint pass or updating animation's progress
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void prePaintScreen(ScreenPrePaintData& data, int time);
/**
* In this method you can:
* @li paint something on top of the windows (by painting after calling
* effects->paintScreen())
* @li paint multiple desktops and/or multiple copies of the same desktop
* by calling effects->paintScreen() multiple times
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data);
/**
* Called after all the painting has been finished.
* In this method you can:
* @li schedule next repaint in case of animations
* You shouldn't paint anything here.
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void postPaintScreen();
/**
* Called for every window before the actual paint pass
* In this method you can:
* @li enable or disable painting of the window (e.g. enable paiting of minimized window)
* @li set window to be painted with translucency
* @li set window to be transformed
* @li request the window to be divided into multiple parts
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
/**
* This is the main method for painting windows.
* In this method you can:
* @li do various transformations
* @li change opacity of the window
* @li change brightness and/or saturation, if it's supported
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data);
/**
* Called for every window after all painting has been finished.
* In this method you can:
* @li schedule next repaint for individual window(s) in case of animations
* You shouldn't paint anything here.
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void postPaintWindow(EffectWindow* w);
/**
* This method is called directly before painting an @ref EffectFrame.
* You can implement this method if you need to bind a shader or perform
* other operations before the frame is rendered.
* @param frame The EffectFrame which will be rendered
* @param region Region to restrict painting to
* @param opacity Opacity of text/icon
* @param frameOpacity Opacity of background
* @since 4.6
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void paintEffectFrame(EffectFrame* frame, const QRegion ®ion, double opacity, double frameOpacity);
/**
* Called on Transparent resizes.
* return true if your effect substitutes questioned feature
*/
virtual bool provides(Feature);
/**
* Performs the @p feature with the @p arguments.
*
* This allows to have specific protocols between KWin core and an Effect.
*
* The method is supposed to return @c true if it performed the features,
* @c false otherwise.
*
* The default implementation returns @c false.
* @since 5.8
*/
virtual bool perform(Feature feature, const QVariantList &arguments);
/**
* Can be called to draw multiple copies (e.g. thumbnails) of a window.
* You can change window's opacity/brightness/etc here, but you can't
* do any transformations.
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
virtual void drawWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data);
/**
* Define new window quads so that they can be transformed by other effects.
* It's up to the effect to keep track of them.
*/
virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList);
virtual void windowInputMouseEvent(QEvent* e);
virtual void grabbedKeyboardEvent(QKeyEvent* e);
/**
* Overwrite this method to indicate whether your effect will be doing something in
* the next frame to be rendered. If the method returns @c false the effect will be
* excluded from the chained methods in the next rendered frame.
*
* This method is called always directly before the paint loop begins. So it is totally
* fine to e.g. react on a window event, issue a repaint to trigger an animation and
* change a flag to indicate that this method returns @c true.
*
* As the method is called each frame, you should not perform complex calculations.
* Best use just a boolean flag.
*
* The default implementation of this method returns @c true.
* @since 4.8
*/
virtual bool isActive() const;
/**
* Reimplement this method to provide online debugging.
* This could be as trivial as printing specific detail information about the effect state
* but could also be used to move the effect in and out of a special debug modes, clear bogus
* data, etc.
* Notice that the functions is const by intent! Whenever you alter the state of the object
* due to random user input, you should do so with greatest care, hence const_cast<> your
* object - signalling "let me alone, i know what i'm doing"
* @param parameter A freeform string user input for your effect to interpret.
* @since 4.11
*/
virtual QString debug(const QString ¶meter) const;
/**
* Reimplement this method to indicate where in the Effect chain the Effect should be placed.
*
* A low number indicates early chain position, thus before other Effects got called, a high
* number indicates a late position. The returned number should be in the interval [0, 100].
* The default value is 0.
*
* In KWin4 this information was provided in the Effect's desktop file as property
* X-KDE-Ordering. In the case of Scripted Effects this property is still used.
*
* @since 5.0
*/
virtual int requestedEffectChainPosition() const;
/**
* A touch point was pressed.
*
* If the effect wants to exclusively use the touch event it should return @c true.
* If @c false is returned the touch event is passed to further effects.
*
* In general an Effect should only return @c true if it is the exclusive effect getting
* input events. E.g. has grabbed mouse events.
*
* Default implementation returns @c false.
*
* @param id The unique id of the touch point
* @param pos The position of the touch point in global coordinates
* @param time Timestamp
*
* @see touchMotion
* @see touchUp
* @since 5.8
*/
virtual bool touchDown(qint32 id, const QPointF &pos, quint32 time);
/**
* A touch point moved.
*
* If the effect wants to exclusively use the touch event it should return @c true.
* If @c false is returned the touch event is passed to further effects.
*
* In general an Effect should only return @c true if it is the exclusive effect getting
* input events. E.g. has grabbed mouse events.
*
* Default implementation returns @c false.
*
* @param id The unique id of the touch point
* @param pos The position of the touch point in global coordinates
* @param time Timestamp
*
* @see touchDown
* @see touchUp
* @since 5.8
*/
virtual bool touchMotion(qint32 id, const QPointF &pos, quint32 time);
/**
* A touch point was released.
*
* If the effect wants to exclusively use the touch event it should return @c true.
* If @c false is returned the touch event is passed to further effects.
*
* In general an Effect should only return @c true if it is the exclusive effect getting
* input events. E.g. has grabbed mouse events.
*
* Default implementation returns @c false.
*
* @param id The unique id of the touch point
* @param time Timestamp
*
* @see touchDown
* @see touchMotion
* @since 5.8
*/
virtual bool touchUp(qint32 id, quint32 time);
static QPoint cursorPos();
/**
* Read animation time from the configuration and possibly adjust using animationTimeFactor().
* The configuration value in the effect should also have special value 'default' (set using
* QSpinBox::setSpecialValueText()) with the value 0. This special value is adjusted
* using the global animation speed, otherwise the exact time configured is returned.
* @param cfg configuration group to read value from
* @param key configuration key to read value from
* @param defaultTime default animation time in milliseconds
*/
// return type is intentionally double so that one can divide using it without losing data
static double animationTime(const KConfigGroup& cfg, const QString& key, int defaultTime);
/**
* @overload Use this variant if the animation time is hardcoded and not configurable
* in the effect itself.
*/
static double animationTime(int defaultTime);
/**
* @overload Use this variant if animation time is provided through a KConfigXT generated class
* having a property called "duration".
*/
template
int animationTime(int defaultDuration);
/**
* Linearly interpolates between @p x and @p y.
*
* Returns @p x when @p a = 0; returns @p y when @p a = 1.
*/
static double interpolate(double x, double y, double a) {
return x * (1 - a) + y * a;
}
/** Helper to set WindowPaintData and QRegion to necessary transformations so that
* a following drawWindow() would put the window at the requested geometry (useful for thumbnails)
*/
static void setPositionTransformations(WindowPaintData& data, QRect& region, EffectWindow* w,
const QRect& r, Qt::AspectRatioMode aspect);
public Q_SLOTS:
virtual bool borderActivated(ElectricBorder border);
protected:
xcb_connection_t *xcbConnection() const;
xcb_window_t x11RootWindow() const;
/**
* An implementing class can call this with it's kconfig compiled singleton class.
* This method will perform the instance on the class.
* @since 5.9
*/
template
void initConfig();
};
/**
* Prefer the KWIN_EFFECT_FACTORY macros.
*/
class KWINEFFECTS_EXPORT EffectPluginFactory : public KPluginFactory
{
Q_OBJECT
public:
EffectPluginFactory();
~EffectPluginFactory() override;
/**
* Returns whether the Effect is supported.
*
* An Effect can implement this method to determine at runtime whether the Effect is supported.
*
* If the current compositing backend is not supported it should return @c false.
*
* This method is optional, by default @c true is returned.
*/
virtual bool isSupported() const;
/**
* Returns whether the Effect should get enabled by default.
*
* This function provides a way for an effect to override the default at runtime,
* e.g. based on the capabilities of the hardware.
*
* This method is optional; the effect doesn't have to provide it.
*
* Note that this function is only called if the supported() function returns true,
* and if X-KDE-PluginInfo-EnabledByDefault is set to true in the .desktop file.
*
* This method is optional, by default @c true is returned.
*/
virtual bool enabledByDefault() const;
/**
* This method returns the created Effect.
*/
virtual KWin::Effect *createEffect() const = 0;
};
/**
* Defines an EffectPluginFactory sub class with customized isSupported and enabledByDefault methods.
*
* If the Effect to be created does not need the isSupported or enabledByDefault methods prefer
* the simplified KWIN_EFFECT_FACTORY, KWIN_EFFECT_FACTORY_SUPPORTED or KWIN_EFFECT_FACTORY_ENABLED
* macros which create an EffectPluginFactory with a useable default value.
*
* The macro also adds a useable K_EXPORT_PLUGIN_VERSION to the definition. KWin will not load
* any Effect with a non-matching plugin version. This API is not providing binary compatibility
* and thus the effect plugin must be compiled against the same kwineffects library version as
* KWin.
*
* @param factoryName The name to be used for the EffectPluginFactory
* @param className The class name of the Effect sub class which is to be created by the factory
* @param jsonFile Name of the json file to be compiled into the plugin as metadata
* @param supported Source code to go into the isSupported() method, must return a boolean
* @param enabled Source code to go into the enabledByDefault() method, must return a boolean
*/
#define KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, supported, enabled ) \
class factoryName : public KWin::EffectPluginFactory \
{ \
Q_OBJECT \
Q_PLUGIN_METADATA(IID KPluginFactory_iid FILE jsonFile) \
Q_INTERFACES(KPluginFactory) \
public: \
explicit factoryName() {} \
~factoryName() {} \
bool isSupported() const override { \
supported \
} \
bool enabledByDefault() const override { \
enabled \
} \
KWin::Effect *createEffect() const override { \
return new className(); \
} \
}; \
K_EXPORT_PLUGIN_VERSION(quint32(KWIN_EFFECT_API_VERSION))
#define KWIN_EFFECT_FACTORY_ENABLED( factoryName, className, jsonFile, enabled ) \
KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, return true;, enabled )
#define KWIN_EFFECT_FACTORY_SUPPORTED( factoryName, classname, jsonFile, supported ) \
KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, supported, return true; )
#define KWIN_EFFECT_FACTORY( factoryName, classname, jsonFile ) \
KWIN_EFFECT_FACTORY_SUPPORTED_ENABLED( factoryName, className, jsonFile, return true;, return true; )
/**
* @short Manager class that handles all the effects.
*
* This class creates Effect objects and calls it's appropriate methods.
*
* Effect objects can call methods of this class to interact with the
* workspace, e.g. to activate or move a specific window, change current
* desktop or create a special input window to receive mouse and keyboard
* events.
*/
class KWINEFFECTS_EXPORT EffectsHandler : public QObject
{
Q_OBJECT
Q_PROPERTY(int currentDesktop READ currentDesktop WRITE setCurrentDesktop NOTIFY desktopChanged)
Q_PROPERTY(QString currentActivity READ currentActivity NOTIFY currentActivityChanged)
Q_PROPERTY(KWin::EffectWindow *activeWindow READ activeWindow WRITE activateWindow NOTIFY windowActivated)
Q_PROPERTY(QSize desktopGridSize READ desktopGridSize)
Q_PROPERTY(int desktopGridWidth READ desktopGridWidth)
Q_PROPERTY(int desktopGridHeight READ desktopGridHeight)
Q_PROPERTY(int workspaceWidth READ workspaceWidth)
Q_PROPERTY(int workspaceHeight READ workspaceHeight)
/**
* The number of desktops currently used. Minimum number of desktops is 1, maximum 20.
*/
Q_PROPERTY(int desktops READ numberOfDesktops WRITE setNumberOfDesktops NOTIFY numberDesktopsChanged)
Q_PROPERTY(bool optionRollOverDesktops READ optionRollOverDesktops)
Q_PROPERTY(int activeScreen READ activeScreen)
Q_PROPERTY(int numScreens READ numScreens NOTIFY numberScreensChanged)
/**
* Factor by which animation speed in the effect should be modified (multiplied).
* If configurable in the effect itself, the option should have also 'default'
* animation speed. The actual value should be determined using animationTime().
* Note: The factor can be also 0, so make sure your code can cope with 0ms time
* if used manually.
*/
Q_PROPERTY(qreal animationTimeFactor READ animationTimeFactor)
Q_PROPERTY(QList< KWin::EffectWindow* > stackingOrder READ stackingOrder)
/**
* Whether window decorations use the alpha channel.
*/
Q_PROPERTY(bool decorationsHaveAlpha READ decorationsHaveAlpha)
/**
* Whether the window decorations support blurring behind the decoration.
*/
Q_PROPERTY(bool decorationSupportsBlurBehind READ decorationSupportsBlurBehind)
Q_PROPERTY(CompositingType compositingType READ compositingType CONSTANT)
Q_PROPERTY(QPoint cursorPos READ cursorPos)
Q_PROPERTY(QSize virtualScreenSize READ virtualScreenSize NOTIFY virtualScreenSizeChanged)
Q_PROPERTY(QRect virtualScreenGeometry READ virtualScreenGeometry NOTIFY virtualScreenGeometryChanged)
Q_PROPERTY(bool hasActiveFullScreenEffect READ hasActiveFullScreenEffect NOTIFY hasActiveFullScreenEffectChanged)
/**
* The status of the session i.e if the user is logging out
* @since 5.18
*/
Q_PROPERTY(KWin::SessionState sessionState READ sessionState NOTIFY sessionStateChanged)
friend class Effect;
public:
explicit EffectsHandler(CompositingType type);
~EffectsHandler() override;
// for use by effects
virtual void prePaintScreen(ScreenPrePaintData& data, int time) = 0;
virtual void paintScreen(int mask, const QRegion ®ion, ScreenPaintData& data) = 0;
virtual void postPaintScreen() = 0;
virtual void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) = 0;
virtual void paintWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data) = 0;
virtual void postPaintWindow(EffectWindow* w) = 0;
virtual void paintEffectFrame(EffectFrame* frame, const QRegion ®ion, double opacity, double frameOpacity) = 0;
virtual void drawWindow(EffectWindow* w, int mask, const QRegion ®ion, WindowPaintData& data) = 0;
virtual void buildQuads(EffectWindow* w, WindowQuadList& quadList) = 0;
virtual QVariant kwinOption(KWinOption kwopt) = 0;
/**
* Sets the cursor while the mouse is intercepted.
* @see startMouseInterception
* @since 4.11
*/
virtual void defineCursor(Qt::CursorShape shape) = 0;
virtual QPoint cursorPos() const = 0;
virtual bool grabKeyboard(Effect* effect) = 0;
virtual void ungrabKeyboard() = 0;
/**
* Ensures that all mouse events are sent to the @p effect.
* No window will get the mouse events. Only fullscreen effects providing a custom user interface should
* be using this method. The input events are delivered to Effect::windowInputMouseEvent.
*
* @note This method does not perform an X11 mouse grab. On X11 a fullscreen input window is raised above
* all other windows, but no grab is performed.
*
* @param effect The effect
* @param shape Sets the cursor to be used while the mouse is intercepted
* @see stopMouseInterception
* @see Effect::windowInputMouseEvent
* @since 4.11
*/
virtual void startMouseInterception(Effect *effect, Qt::CursorShape shape) = 0;
/**
* Releases the hold mouse interception for @p effect
* @see startMouseInterception
* @since 4.11
*/
virtual void stopMouseInterception(Effect *effect) = 0;
/**
* @brief Registers a global shortcut with the provided @p action.
*
* @param shortcut The global shortcut which should trigger the action
* @param action The action which gets triggered when the shortcut matches
*/
virtual void registerGlobalShortcut(const QKeySequence &shortcut, QAction *action) = 0;
/**
* @brief Registers a global pointer shortcut with the provided @p action.
*
* @param modifiers The keyboard modifiers which need to be holded
* @param pointerButtons The pointer buttons which need to be pressed
* @param action The action which gets triggered when the shortcut matches
*/
virtual void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) = 0;
/**
* @brief Registers a global axis shortcut with the provided @p action.
*
* @param modifiers The keyboard modifiers which need to be holded
* @param axis The direction in which the axis needs to be moved
* @param action The action which gets triggered when the shortcut matches
*/
virtual void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) = 0;
/**
* @brief Registers a global touchpad swipe gesture shortcut with the provided @p action.
*
* @param direction The direction for the swipe
* @param action The action which gets triggered when the gesture triggers
* @since 5.10
*/
virtual void registerTouchpadSwipeShortcut(SwipeDirection direction, QAction *action) = 0;
/**
* Retrieve the proxy class for an effect if it has one. Will return NULL if
* the effect isn't loaded or doesn't have a proxy class.
*/
virtual void* getProxy(QString name) = 0;
// Mouse polling
virtual void startMousePolling() = 0;
virtual void stopMousePolling() = 0;
virtual void reserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
virtual void unreserveElectricBorder(ElectricBorder border, Effect *effect) = 0;
/**
* Registers the given @p action for the given @p border to be activated through
* a touch swipe gesture.
*
* If the @p border gets triggered through a touch swipe gesture the QAction::triggered
* signal gets invoked.
*
* To unregister the touch screen action either delete the @p action or
* invoke unregisterTouchBorder.
*
* @see unregisterTouchBorder
* @since 5.10
*/
virtual void registerTouchBorder(ElectricBorder border, QAction *action) = 0;
/**
* Unregisters the given @p action for the given touch @p border.
*
* @see registerTouchBorder
* @since 5.10
*/
virtual void unregisterTouchBorder(ElectricBorder border, QAction *action) = 0;
// functions that allow controlling windows/desktop
virtual void activateWindow(KWin::EffectWindow* c) = 0;
virtual KWin::EffectWindow* activeWindow() const = 0 ;
Q_SCRIPTABLE virtual void moveWindow(KWin::EffectWindow* w, const QPoint& pos, bool snap = false, double snapAdjust = 1.0) = 0;
/**
* Moves the window to the specific desktop
* Setting desktop to NET::OnAllDesktops will set the window on all desktops
*/
Q_SCRIPTABLE virtual void windowToDesktop(KWin::EffectWindow* w, int desktop) = 0;
/**
* Moves a window to the given desktops
* On X11, the window will end up on the last window in the list
* Setting this to an empty list will set the window on all desktops
*
* @arg desktopIds a list of desktops the window should be placed on. NET::OnAllDesktops is not a valid desktop X11Id
*/
Q_SCRIPTABLE virtual void windowToDesktops(KWin::EffectWindow* w, const QVector &desktopIds) = 0;
Q_SCRIPTABLE virtual void windowToScreen(KWin::EffectWindow* w, int screen) = 0;
virtual void setShowingDesktop(bool showing) = 0;
// Activities
/**
* @returns The ID of the current activity.
*/
virtual QString currentActivity() const = 0;
// Desktops
/**
* @returns The ID of the current desktop.
*/
virtual int currentDesktop() const = 0;
/**
* @returns Total number of desktops currently in existence.
*/
virtual int numberOfDesktops() const = 0;
/**
* Set the current desktop to @a desktop.
*/
virtual void setCurrentDesktop(int desktop) = 0;
/**
* Sets the total number of desktops to @a desktops.
*/
virtual void setNumberOfDesktops(int desktops) = 0;
/**
* @returns The size of desktop layout in grid units.
*/
virtual QSize desktopGridSize() const = 0;
/**
* @returns The width of desktop layout in grid units.
*/
virtual int desktopGridWidth() const = 0;
/**
* @returns The height of desktop layout in grid units.
*/
virtual int desktopGridHeight() const = 0;
/**
* @returns The width of desktop layout in pixels.
*/
virtual int workspaceWidth() const = 0;
/**
* @returns The height of desktop layout in pixels.
*/
virtual int workspaceHeight() const = 0;
/**
* @returns The ID of the desktop at the point @a coords or 0 if no desktop exists at that
* point. @a coords is to be in grid units.
*/
virtual int desktopAtCoords(QPoint coords) const = 0;
/**
* @returns The coords of desktop @a id in grid units.
*/
virtual QPoint desktopGridCoords(int id) const = 0;
/**
* @returns The coords of the top-left corner of desktop @a id in pixels.
*/
virtual QPoint desktopCoords(int id) const = 0;
/**
* @returns The ID of the desktop above desktop @a id. Wraps around to the bottom of
* the layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE virtual int desktopAbove(int desktop = 0, bool wrap = true) const = 0;
/**
* @returns The ID of the desktop to the right of desktop @a id. Wraps around to the
* left of the layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE virtual int desktopToRight(int desktop = 0, bool wrap = true) const = 0;
/**
* @returns The ID of the desktop below desktop @a id. Wraps around to the top of the
* layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE virtual int desktopBelow(int desktop = 0, bool wrap = true) const = 0;
/**
* @returns The ID of the desktop to the left of desktop @a id. Wraps around to the
* right of the layout if @a wrap is set. If @a id is not set use the current one.
*/
Q_SCRIPTABLE virtual int desktopToLeft(int desktop = 0, bool wrap = true) const = 0;
Q_SCRIPTABLE virtual QString desktopName(int desktop) const = 0;
virtual bool optionRollOverDesktops() const = 0;
virtual int activeScreen() const = 0; // Xinerama
virtual int numScreens() const = 0; // Xinerama
Q_SCRIPTABLE virtual int screenNumber(const QPoint& pos) const = 0; // Xinerama
virtual QRect clientArea(clientAreaOption, int screen, int desktop) const = 0;
virtual QRect clientArea(clientAreaOption, const EffectWindow* c) const = 0;
virtual QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const = 0;
/**
* The bounding size of all screens combined. Overlapping areas
* are not counted multiple times.
*
* @see virtualScreenGeometry()
* @see virtualScreenSizeChanged()
* @since 5.0
*/
virtual QSize virtualScreenSize() const = 0;
/**
* The bounding geometry of all outputs combined. Always starts at (0,0) and has
* virtualScreenSize as it's size.
*
* @see virtualScreenSize()
* @see virtualScreenGeometryChanged()
* @since 5.0
*/
virtual QRect virtualScreenGeometry() const = 0;
/**
* Factor by which animation speed in the effect should be modified (multiplied).
* If configurable in the effect itself, the option should have also 'default'
* animation speed. The actual value should be determined using animationTime().
* Note: The factor can be also 0, so make sure your code can cope with 0ms time
* if used manually.
*/
virtual double animationTimeFactor() const = 0;
virtual WindowQuadType newWindowQuadType() = 0;
Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(WId id) const = 0;
Q_SCRIPTABLE virtual KWin::EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const = 0;
/**
* Finds the EffectWindow for the internal window @p w.
* If there is no such window @c null is returned.
*
* On Wayland this returns the internal window. On X11 it returns an Unamanged with the
* window id matching that of the provided window @p w.
*
* @since 5.16
*/
Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
/**
* Finds the EffectWindow for the Toplevel with KWin internal @p id.
* If there is no such window @c null is returned.
*
* @since 5.16
*/
Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(const QUuid &id) const = 0;
virtual EffectWindowList stackingOrder() const = 0;
// window will be temporarily painted as if being at the top of the stack
Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow* w, bool set) = 0;
virtual void setTabBoxWindow(EffectWindow*) = 0;
virtual void setTabBoxDesktop(int) = 0;
virtual EffectWindowList currentTabBoxWindowList() const = 0;
virtual void refTabBox() = 0;
virtual void unrefTabBox() = 0;
virtual void closeTabBox() = 0;
virtual QList< int > currentTabBoxDesktopList() const = 0;
virtual int currentTabBoxDesktop() const = 0;
virtual EffectWindow* currentTabBoxWindow() const = 0;
virtual void setActiveFullScreenEffect(Effect* e) = 0;
virtual Effect* activeFullScreenEffect() const = 0;
/**
* Schedules the entire workspace to be repainted next time.
* If you call it during painting (including prepaint) then it does not
* affect the current painting.
*/
Q_SCRIPTABLE virtual void addRepaintFull() = 0;
Q_SCRIPTABLE virtual void addRepaint(const QRect& r) = 0;
Q_SCRIPTABLE virtual void addRepaint(const QRegion& r) = 0;
Q_SCRIPTABLE virtual void addRepaint(int x, int y, int w, int h) = 0;
CompositingType compositingType() const;
/**
* @brief Whether the Compositor is OpenGL based (either GL 1 or 2).
*
* @return bool @c true in case of OpenGL based Compositor, @c false otherwise
*/
bool isOpenGLCompositing() const;
virtual unsigned long xrenderBufferPicture() = 0;
/**
* @brief Provides access to the QPainter which is rendering to the back buffer.
*
* Only relevant for CompositingType QPainterCompositing. For all other compositing types
* @c null is returned.
*
* @return QPainter* The Scene's QPainter or @c null.
*/
virtual QPainter *scenePainter() = 0;
virtual void reconfigure() = 0;
virtual QByteArray readRootProperty(long atom, long type, int format) const = 0;
/**
* @brief Announces support for the feature with the given name. If no other Effect
* has announced support for this feature yet, an X11 property will be installed on
* the root window.
*
* The Effect will be notified for events through the signal propertyNotify().
*
* To remove the support again use removeSupportProperty. When an Effect is
* destroyed it is automatically taken care of removing the support. It is not
* required to call removeSupportProperty in the Effect's cleanup handling.
*
* @param propertyName The name of the property to announce support for
* @param effect The effect which announces support
* @return xcb_atom_t The created X11 atom
* @see removeSupportProperty
* @since 4.11
*/
virtual xcb_atom_t announceSupportProperty(const QByteArray &propertyName, Effect *effect) = 0;
/**
* @brief Removes support for the feature with the given name. If there is no other Effect left
* which has announced support for the given property, the property will be removed from the
* root window.
*
* In case the Effect had not registered support, calling this function does not change anything.
*
* @param propertyName The name of the property to remove support for
* @param effect The effect which had registered the property.
* @see announceSupportProperty
* @since 4.11
*/
virtual void removeSupportProperty(const QByteArray &propertyName, Effect *effect) = 0;
/**
* Returns @a true if the active window decoration has shadow API hooks.
*/
virtual bool hasDecorationShadows() const = 0;
/**
* Returns @a true if the window decorations use the alpha channel, and @a false otherwise.
* @since 4.5
*/
virtual bool decorationsHaveAlpha() const = 0;
/**
* Returns @a true if the window decorations support blurring behind the decoration, and @a false otherwise
* @since 4.6
*/
virtual bool decorationSupportsBlurBehind() const = 0;
/**
* Creates a new frame object. If the frame does not have a static size
* then it will be located at @a position with @a alignment. A
* non-static frame will automatically adjust its size to fit the contents.
* @returns A new @ref EffectFrame. It is the responsibility of the caller to delete the
* EffectFrame.
* @since 4.6
*/
virtual EffectFrame* effectFrame(EffectFrameStyle style, bool staticSize = true,
const QPoint& position = QPoint(-1, -1), Qt::Alignment alignment = Qt::AlignCenter) const = 0;
/**
* Allows an effect to trigger a reload of itself.
* This can be used by an effect which needs to be reloaded when screen geometry changes.
* It is possible that the effect cannot be loaded again as it's supported method does no longer
* hold.
* @param effect The effect to reload
* @since 4.8
*/
virtual void reloadEffect(Effect *effect) = 0;
/**
* Whether the screen is currently considered as locked.
* Note for technical reasons this is not always possible to detect. The screen will only
* be considered as locked if the screen locking process implements the
* org.freedesktop.ScreenSaver interface.
*
* @returns @c true if the screen is currently locked, @c false otherwise
* @see screenLockingChanged
* @since 4.11
*/
virtual bool isScreenLocked() const = 0;
/**
* @brief Makes the OpenGL compositing context current.
*
* If the compositing backend is not using OpenGL, this method returns @c false.
*
* @return bool @c true if the context became current, @c false otherwise.
*/
virtual bool makeOpenGLContextCurrent() = 0;
/**
* @brief Makes a null OpenGL context current resulting in no context
* being current.
*
* If the compositing backend is not OpenGL based, this method is a noop.
*
* There is normally no reason for an Effect to call this method.
*/
virtual void doneOpenGLContextCurrent() = 0;
virtual xcb_connection_t *xcbConnection() const = 0;
virtual xcb_window_t x11RootWindow() const = 0;
/**
* Interface to the Wayland display: this is relevant only
* on Wayland, on X11 it will be nullptr
* @since 5.5
*/
virtual KWayland::Server::Display *waylandDisplay() const = 0;
/**
* Whether animations are supported by the Scene.
* If this method returns @c false Effects are supposed to not
* animate transitions.
*
* @returns Whether the Scene can drive animations
* @since 5.8
*/
virtual bool animationsSupported() const = 0;
/**
* The current cursor image of the Platform.
* @see cursorPos
* @since 5.9
*/
virtual PlatformCursorImage cursorImage() const = 0;
/**
* The cursor image should be hidden.
* @see showCursor
* @since 5.9
*/
virtual void hideCursor() = 0;
/**
* The cursor image should be shown again after having been hidden.
* @see hideCursor
* @since 5.9
*/
virtual void showCursor() = 0;
/**
* Starts an interactive window selection process.
*
* Once the user selected a window the @p callback is invoked with the selected EffectWindow as
* argument. In case the user cancels the interactive window selection or selecting a window is currently
* not possible (e.g. screen locked) the @p callback is invoked with a @c nullptr argument.
*
* During the interactive window selection the cursor is turned into a crosshair cursor.
*
* @param callback The function to invoke once the interactive window selection ends
* @since 5.9
*/
virtual void startInteractiveWindowSelection(std::function callback) = 0;
/**
* Starts an interactive position selection process.
*
* Once the user selected a position on the screen the @p callback is invoked with
* the selected point as argument. In case the user cancels the interactive position selection
* or selecting a position is currently not possible (e.g. screen locked) the @p callback
* is invoked with a point at @c -1 as x and y argument.
*
* During the interactive window selection the cursor is turned into a crosshair cursor.
*
* @param callback The function to invoke once the interactive position selection ends
* @since 5.9
*/
virtual void startInteractivePositionSelection(std::function callback) = 0;
/**
* Shows an on-screen-message. To hide it again use hideOnScreenMessage.
*
* @param message The message to show
* @param iconName The optional themed icon name
* @see hideOnScreenMessage
* @since 5.9
*/
virtual void showOnScreenMessage(const QString &message, const QString &iconName = QString()) = 0;
/**
* Flags for how to hide a shown on-screen-message
* @see hideOnScreenMessage
* @since 5.9
*/
enum class OnScreenMessageHideFlag {
/**
* The on-screen-message should skip the close window animation.
* @see EffectWindow::skipsCloseAnimation
*/
SkipsCloseAnimation = 1
};
Q_DECLARE_FLAGS(OnScreenMessageHideFlags, OnScreenMessageHideFlag)
/**
* Hides a previously shown on-screen-message again.
* @param flags The flags for how to hide the message
* @see showOnScreenMessage
* @since 5.9
*/
virtual void hideOnScreenMessage(OnScreenMessageHideFlags flags = OnScreenMessageHideFlags()) = 0;
/*
* @returns The configuration used by the EffectsHandler.
* @since 5.10
*/
virtual KSharedConfigPtr config() const = 0;
/**
* @returns The global input configuration (kcminputrc)
* @since 5.10
*/
virtual KSharedConfigPtr inputConfig() const = 0;
/**
* Returns if activeFullScreenEffect is set
*/
virtual bool hasActiveFullScreenEffect() const = 0;
/**
* Render the supplied EffectQuickView onto the scene
* It can be called at any point during the scene rendering
* @since 5.18
*/
virtual void renderEffectQuickView(EffectQuickView *effectQuickView) const = 0;
/**
* The status of the session i.e if the user is logging out
* @since 5.18
*/
virtual SessionState sessionState() const = 0;
Q_SIGNALS:
/**
* Signal emitted when the current desktop changed.
* @param oldDesktop The previously current desktop
* @param newDesktop The new current desktop
* @param with The window which is taken over to the new desktop, can be NULL
* @since 4.9
*/
void desktopChanged(int oldDesktop, int newDesktop, KWin::EffectWindow *with);
/**
* @since 4.7
* @deprecated
*/
void desktopChanged(int oldDesktop, int newDesktop);
/**
* Signal emitted when a window moved to another desktop
* NOTICE that this does NOT imply that the desktop has changed
* The @param window which is moved to the new desktop
* @param oldDesktop The previous desktop of the window
* @param newDesktop The new desktop of the window
* @since 4.11.4
*/
void desktopPresenceChanged(KWin::EffectWindow *window, int oldDesktop, int newDesktop);
/**
* Signal emitted when the number of currently existing desktops is changed.
* @param old The previous number of desktops in used.
* @see EffectsHandler::numberOfDesktops.
* @since 4.7
*/
void numberDesktopsChanged(uint old);
/**
* Signal emitted when the number of screens changed.
* @since 5.0
*/
void numberScreensChanged();
/**
* Signal emitted when the desktop showing ("dashboard") state changed
* The desktop is risen to the keepAbove layer, you may want to elevate
* windows or such.
* @since 5.3
*/
void showingDesktopChanged(bool);
/**
* Signal emitted when a new window has been added to the Workspace.
* @param w The added window
* @since 4.7
*/
void windowAdded(KWin::EffectWindow *w);
/**
* Signal emitted when a window is being removed from the Workspace.
* An effect which wants to animate the window closing should connect
* to this signal and reference the window by using
* refWindow
* @param w The window which is being closed
* @since 4.7
*/
void windowClosed(KWin::EffectWindow *w);
/**
* Signal emitted when a window get's activated.
* @param w The new active window, or @c NULL if there is no active window.
* @since 4.7
*/
void windowActivated(KWin::EffectWindow *w);
/**
* Signal emitted when a window is deleted.
* This means that a closed window is not referenced any more.
* An effect bookkeeping the closed windows should connect to this
* signal to clean up the internal references.
* @param w The window which is going to be deleted.
* @see EffectWindow::refWindow
* @see EffectWindow::unrefWindow
* @see windowClosed
* @since 4.7
*/
void windowDeleted(KWin::EffectWindow *w);
/**
* Signal emitted when a user begins a window move or resize operation.
* To figure out whether the user resizes or moves the window use
* isUserMove or isUserResize.
* Whenever the geometry is updated the signal @ref windowStepUserMovedResized
* is emitted with the current geometry.
* The move/resize operation ends with the signal @ref windowFinishUserMovedResized.
* Only one window can be moved/resized by the user at the same time!
* @param w The window which is being moved/resized
* @see windowStepUserMovedResized
* @see windowFinishUserMovedResized
* @see EffectWindow::isUserMove
* @see EffectWindow::isUserResize
* @since 4.7
*/
void windowStartUserMovedResized(KWin::EffectWindow *w);
/**
* Signal emitted during a move/resize operation when the user changed the geometry.
* Please note: KWin supports two operation modes. In one mode all changes are applied
* instantly. This means the window's geometry matches the passed in @p geometry. In the
* other mode the geometry is changed after the user ended the move/resize mode.
* The @p geometry differs from the window's geometry. Also the window's pixmap still has
* the same size as before. Depending what the effect wants to do it would be recommended
* to scale/translate the window.
* @param w The window which is being moved/resized
* @param geometry The geometry of the window in the current move/resize step.
* @see windowStartUserMovedResized
* @see windowFinishUserMovedResized
* @see EffectWindow::isUserMove
* @see EffectWindow::isUserResize
* @since 4.7
*/
void windowStepUserMovedResized(KWin::EffectWindow *w, const QRect &geometry);
/**
* Signal emitted when the user finishes move/resize of window @p w.
* @param w The window which has been moved/resized
* @see windowStartUserMovedResized
* @see windowFinishUserMovedResized
* @since 4.7
*/
void windowFinishUserMovedResized(KWin::EffectWindow *w);
/**
* Signal emitted when the maximized state of the window @p w changed.
* A window can be in one of four states:
* @li restored: both @p horizontal and @p vertical are @c false
* @li horizontally maximized: @p horizontal is @c true and @p vertical is @c false
* @li vertically maximized: @p horizontal is @c false and @p vertical is @c true
* @li completely maximized: both @p horizontal and @p vertical are @c true
* @param w The window whose maximized state changed
* @param horizontal If @c true maximized horizontally
* @param vertical If @c true maximized vertically
* @since 4.7
*/
void windowMaximizedStateChanged(KWin::EffectWindow *w, bool horizontal, bool vertical);
/**
* Signal emitted when the geometry or shape of a window changed.
* This is caused if the window changes geometry without user interaction.
* E.g. the decoration is changed. This is in opposite to windowUserMovedResized
* which is caused by direct user interaction.
* @param w The window whose geometry changed
* @param old The previous geometry
* @see windowUserMovedResized
* @since 4.7
*/
void windowGeometryShapeChanged(KWin::EffectWindow *w, const QRect &old);
/**
* This signal is emitted when the frame geometry of a window changed.
* @param window The window whose geometry changed
* @param oldGeometry The previous geometry
* @since 5.19
*/
void windowFrameGeometryChanged(KWin::EffectWindow *window, const QRect &oldGeometry);
/**
* Signal emitted when the padding of a window changed. (eg. shadow size)
* @param w The window whose geometry changed
* @param old The previous expandedGeometry()
* @since 4.9
*/
void windowPaddingChanged(KWin::EffectWindow *w, const QRect &old);
/**
* Signal emitted when the windows opacity is changed.
* @param w The window whose opacity level is changed.
* @param oldOpacity The previous opacity level
* @param newOpacity The new opacity level
* @since 4.7
*/
void windowOpacityChanged(KWin::EffectWindow *w, qreal oldOpacity, qreal newOpacity);
/**
* Signal emitted when a window got minimized.
* @param w The window which was minimized
* @since 4.7
*/
void windowMinimized(KWin::EffectWindow *w);
/**
* Signal emitted when a window got unminimized.
* @param w The window which was unminimized
* @since 4.7
*/
void windowUnminimized(KWin::EffectWindow *w);
/**
* Signal emitted when a window either becomes modal (ie. blocking for its main client) or looses that state.
* @param w The window which was unminimized
* @since 4.11
*/
void windowModalityChanged(KWin::EffectWindow *w);
/**
* Signal emitted when a window either became unresponsive (eg. app froze or crashed)
* or respoonsive
* @param w The window that became (un)responsive
* @param unresponsive Whether the window is responsive or unresponsive
* @since 5.10
*/
void windowUnresponsiveChanged(KWin::EffectWindow *w, bool unresponsive);
/**
* Signal emitted when an area of a window is scheduled for repainting.
* Use this signal in an effect if another area needs to be synced as well.
* @param w The window which is scheduled for repainting
* @param r Always empty.
* @since 4.7
*/
void windowDamaged(KWin::EffectWindow *w, const QRect &r);
/**
* Signal emitted when a tabbox is added.
* An effect who wants to replace the tabbox with itself should use refTabBox.
* @param mode The TabBoxMode.
* @see refTabBox
* @see tabBoxClosed
* @see tabBoxUpdated
* @see tabBoxKeyEvent
* @since 4.7
*/
void tabBoxAdded(int mode);
/**
* Signal emitted when the TabBox was closed by KWin core.
* An effect which referenced the TabBox should use unrefTabBox to unref again.
* @see unrefTabBox
* @see tabBoxAdded
* @since 4.7
*/
void tabBoxClosed();
/**
* Signal emitted when the selected TabBox window changed or the TabBox List changed.
* An effect should only response to this signal if it referenced the TabBox with refTabBox.
* @see refTabBox
* @see currentTabBoxWindowList
* @see currentTabBoxDesktopList
* @see currentTabBoxWindow
* @see currentTabBoxDesktop
* @since 4.7
*/
void tabBoxUpdated();
/**
* Signal emitted when a key event, which is not handled by TabBox directly is, happens while
* TabBox is active. An effect might use the key event to e.g. change the selected window.
* An effect should only response to this signal if it referenced the TabBox with refTabBox.
* @param event The key event not handled by TabBox directly
* @see refTabBox
* @since 4.7
*/
void tabBoxKeyEvent(QKeyEvent* event);
void currentTabAboutToChange(KWin::EffectWindow* from, KWin::EffectWindow* to);
void tabAdded(KWin::EffectWindow* from, KWin::EffectWindow* to); // from merged with to
void tabRemoved(KWin::EffectWindow* c, KWin::EffectWindow* group); // c removed from group
/**
* Signal emitted when mouse changed.
* If an effect needs to get updated mouse positions, it needs to first call startMousePolling.
* For a fullscreen effect it is better to use an input window and react on windowInputMouseEvent.
* @param pos The new mouse position
* @param oldpos The previously mouse position
* @param buttons The pressed mouse buttons
* @param oldbuttons The previously pressed mouse buttons
* @param modifiers Pressed keyboard modifiers
* @param oldmodifiers Previously pressed keyboard modifiers.
* @see startMousePolling
* @since 4.7
*/
void mouseChanged(const QPoint& pos, const QPoint& oldpos,
Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers);
/**
* Signal emitted when the cursor shape changed.
* You'll likely want to query the current cursor as reaction: xcb_xfixes_get_cursor_image_unchecked
* Connection to this signal is tracked, so if you don't need it anymore, disconnect from it to stop cursor event filtering
*/
void cursorShapeChanged();
/**
* Receives events registered for using registerPropertyType.
* Use readProperty() to get the property data.
* Note that the property may be already set on the window, so doing the same
* processing from windowAdded() (e.g. simply calling propertyNotify() from it)
* is usually needed.
* @param w The window whose property changed, is @c null if it is a root window property
* @param atom The property
* @since 4.7
*/
void propertyNotify(KWin::EffectWindow* w, long atom);
/**
* Signal emitted after the screen geometry changed (e.g. add of a monitor).
* Effects using displayWidth()/displayHeight() to cache information should
* react on this signal and update the caches.
* @param size The new screen size
* @since 4.8
*/
void screenGeometryChanged(const QSize &size);
/**
* This signal is emitted when the global
* activity is changed
* @param id id of the new current activity
* @since 4.9
*/
void currentActivityChanged(const QString &id);
/**
* This signal is emitted when a new activity is added
* @param id id of the new activity
* @since 4.9
*/
void activityAdded(const QString &id);
/**
* This signal is emitted when the activity
* is removed
* @param id id of the removed activity
* @since 4.9
*/
void activityRemoved(const QString &id);
/**
* This signal is emitted when the screen got locked or unlocked.
* @param locked @c true if the screen is now locked, @c false if it is now unlocked
* @since 4.11
*/
void screenLockingChanged(bool locked);
/**
* This signal is emitted just before the screen locker tries to grab keys and lock the screen
* Effects should release any grabs immediately
* @since 5.17
*/
void screenAboutToLock();
/**
* This signels is emitted when ever the stacking order is change, ie. a window is risen
* or lowered
* @since 4.10
*/
void stackingOrderChanged();
/**
* This signal is emitted when the user starts to approach the @p border with the mouse.
* The @p factor describes how far away the mouse is in a relative mean. The values are in
* [0.0, 1.0] with 0.0 being emitted when first entered and on leaving. The value 1.0 means that
* the @p border is reached with the mouse. So the values are well suited for animations.
* The signal is always emitted when the mouse cursor position changes.
* @param border The screen edge which is being approached
* @param factor Value in range [0.0,1.0] to describe how close the mouse is to the border
* @param geometry The geometry of the edge which is being approached
* @since 4.11
*/
void screenEdgeApproaching(ElectricBorder border, qreal factor, const QRect &geometry);
/**
* Emitted whenever the virtualScreenSize changes.
* @see virtualScreenSize()
* @since 5.0
*/
void virtualScreenSizeChanged();
/**
* Emitted whenever the virtualScreenGeometry changes.
* @see virtualScreenGeometry()
* @since 5.0
*/
void virtualScreenGeometryChanged();
/**
* The window @p w gets shown again. The window was previously
* initially shown with windowAdded and hidden with windowHidden.
*
* @see windowHidden
* @see windowAdded
* @since 5.8
*/
void windowShown(KWin::EffectWindow *w);
/**
* The window @p w got hidden but not yet closed.
* This can happen when a window is still being used and is supposed to be shown again
* with windowShown. On X11 an example is autohiding panels. On Wayland every
* window first goes through the window hidden state and might get shown again, or might
* get closed the normal way.
*
* @see windowShown
* @see windowClosed
* @since 5.8
*/
void windowHidden(KWin::EffectWindow *w);
/**
* This signal gets emitted when the data on EffectWindow @p w for @p role changed.
*
* An Effect can connect to this signal to read the new value and react on it.
* E.g. an Effect which does not operate on windows grabbed by another Effect wants
* to cancel the already scheduled animation if another Effect adds a grab.
*
* @param w The EffectWindow for which the data changed
* @param role The data role which changed
* @see EffectWindow::setData
* @see EffectWindow::data
* @since 5.8.4
*/
void windowDataChanged(KWin::EffectWindow *w, int role);
/**
* The xcb connection changed, either a new xcbConnection got created or the existing one
* got destroyed.
* Effects can use this to refetch the properties they want to set.
*
* When the xcbConnection changes also the x11RootWindow becomes invalid.
* @see xcbConnection
* @see x11RootWindow
* @since 5.11
*/
void xcbConnectionChanged();
/**
* This signal is emitted when active fullscreen effect changed.
*
* @see activeFullScreenEffect
* @see setActiveFullScreenEffect
* @since 5.14
*/
void activeFullScreenEffectChanged();
/**
* This signal is emitted when active fullscreen effect changed to being
* set or unset
*
* @see activeFullScreenEffect
* @see setActiveFullScreenEffect
* @since 5.15
*/
void hasActiveFullScreenEffectChanged();
/**
* This signal is emitted when the keep above state of @p w was changed.
*
* @param w The window whose the keep above state was changed.
* @since 5.15
*/
void windowKeepAboveChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the keep below state of @p was changed.
*
* @param w The window whose the keep below state was changed.
* @since 5.15
*/
void windowKeepBelowChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the full screen state of @p w was changed.
*
* @param w The window whose the full screen state was changed.
* @since 5.15
*/
void windowFullScreenChanged(KWin::EffectWindow *w);
/**
* This signal is emitted when the session state was changed
* @since 5.18
*/
void sessionStateChanged();
protected:
QVector< EffectPair > loaded_effects;
//QHash< QString, EffectFactory* > effect_factories;
CompositingType compositing_type;
};
/**
* @short Representation of a window used by/for Effect classes.
*
* The purpose is to hide internal data and also to serve as a single
* representation for the case when Client/Unmanaged becomes Deleted.
*/
class KWINEFFECTS_EXPORT EffectWindow : public QObject
{
Q_OBJECT
Q_PROPERTY(bool alpha READ hasAlpha CONSTANT)
Q_PROPERTY(QRect geometry READ geometry)
Q_PROPERTY(QRect expandedGeometry READ expandedGeometry)
Q_PROPERTY(int height READ height)
Q_PROPERTY(qreal opacity READ opacity)
Q_PROPERTY(QPoint pos READ pos)
Q_PROPERTY(int screen READ screen)
Q_PROPERTY(QSize size READ size)
Q_PROPERTY(int width READ width)
Q_PROPERTY(int x READ x)
Q_PROPERTY(int y READ y)
Q_PROPERTY(int desktop READ desktop)
Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops)
Q_PROPERTY(bool onCurrentDesktop READ isOnCurrentDesktop)
Q_PROPERTY(QRect rect READ rect)
Q_PROPERTY(QString windowClass READ windowClass)
Q_PROPERTY(QString windowRole READ windowRole)
/**
* Returns whether the window is a desktop background window (the one with wallpaper).
* See _NET_WM_WINDOW_TYPE_DESKTOP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool desktopWindow READ isDesktop)
/**
* Returns whether the window is a dock (i.e. a panel).
* See _NET_WM_WINDOW_TYPE_DOCK at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dock READ isDock)
/**
* Returns whether the window is a standalone (detached) toolbar window.
* See _NET_WM_WINDOW_TYPE_TOOLBAR at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool toolbar READ isToolbar)
/**
* Returns whether the window is a torn-off menu.
* See _NET_WM_WINDOW_TYPE_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool menu READ isMenu)
/**
* Returns whether the window is a "normal" window, i.e. an application or any other window
* for which none of the specialized window types fit.
* See _NET_WM_WINDOW_TYPE_NORMAL at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool normalWindow READ isNormalWindow)
/**
* Returns whether the window is a dialog window.
* See _NET_WM_WINDOW_TYPE_DIALOG at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dialog READ isDialog)
/**
* Returns whether the window is a splashscreen. Note that many (especially older) applications
* do not support marking their splash windows with this type.
* See _NET_WM_WINDOW_TYPE_SPLASH at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool splash READ isSplash)
/**
* Returns whether the window is a utility window, such as a tool window.
* See _NET_WM_WINDOW_TYPE_UTILITY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool utility READ isUtility)
/**
* Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open
* from the applications menubar).
* See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dropdownMenu READ isDropdownMenu)
/**
* Returns whether the window is a popup menu (that is not a torn-off or dropdown menu).
* See _NET_WM_WINDOW_TYPE_POPUP_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool popupMenu READ isPopupMenu)
/**
* Returns whether the window is a tooltip.
* See _NET_WM_WINDOW_TYPE_TOOLTIP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool tooltip READ isTooltip)
/**
* Returns whether the window is a window with a notification.
* See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool notification READ isNotification)
/**
* Returns whether the window is a window with a critical notification.
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION
*/
Q_PROPERTY(bool criticalNotification READ isCriticalNotification)
/**
* Returns whether the window is an on screen display window
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY
*/
Q_PROPERTY(bool onScreenDisplay READ isOnScreenDisplay)
/**
* Returns whether the window is a combobox popup.
* See _NET_WM_WINDOW_TYPE_COMBO at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool comboBox READ isComboBox)
/**
* Returns whether the window is a Drag&Drop icon.
* See _NET_WM_WINDOW_TYPE_DND at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(bool dndIcon READ isDNDIcon)
/**
* Returns the NETWM window type
* See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(int windowType READ windowType)
/**
* Whether this EffectWindow is managed by KWin (it has control over its placement and other
* aspects, as opposed to override-redirect windows that are entirely handled by the application).
*/
Q_PROPERTY(bool managed READ isManaged)
/**
* Whether this EffectWindow represents an already deleted window and only kept for the compositor for animations.
*/
Q_PROPERTY(bool deleted READ isDeleted)
/**
* Whether the window has an own shape
*/
Q_PROPERTY(bool shaped READ hasOwnShape)
/**
* The Window's shape
*/
Q_PROPERTY(QRegion shape READ shape)
/**
* The Caption of the window. Read from WM_NAME property together with a suffix for hostname and shortcut.
*/
Q_PROPERTY(QString caption READ caption)
/**
* Whether the window is set to be kept above other windows.
*/
Q_PROPERTY(bool keepAbove READ keepAbove)
/**
* Whether the window is set to be kept below other windows.
*/
Q_PROPERTY(bool keepBelow READ keepBelow)
/**
* Whether the window is minimized.
*/
Q_PROPERTY(bool minimized READ isMinimized WRITE setMinimized)
/**
* Whether the window represents a modal window.
*/
Q_PROPERTY(bool modal READ isModal)
/**
* Whether the window is moveable. Even if it is not moveable, it might be possible to move
* it to another screen.
* @see moveableAcrossScreens
*/
Q_PROPERTY(bool moveable READ isMovable)
/**
* Whether the window can be moved to another screen.
* @see moveable
*/
Q_PROPERTY(bool moveableAcrossScreens READ isMovableAcrossScreens)
/**
* By how much the window wishes to grow/shrink at least. Usually QSize(1,1).
* MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all.
*/
Q_PROPERTY(QSize basicUnit READ basicUnit)
/**
* Whether the window is currently being moved by the user.
*/
Q_PROPERTY(bool move READ isUserMove)
/**
* Whether the window is currently being resized by the user.
*/
Q_PROPERTY(bool resize READ isUserResize)
/**
* The optional geometry representing the minimized Client in e.g a taskbar.
* See _NET_WM_ICON_GEOMETRY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
Q_PROPERTY(QRect iconGeometry READ iconGeometry)
/**
* Returns whether the window is any of special windows types (desktop, dock, splash, ...),
* i.e. window types that usually don't have a window frame and the user does not use window
* management (moving, raising,...) on them.
*/
Q_PROPERTY(bool specialWindow READ isSpecialWindow)
Q_PROPERTY(QIcon icon READ icon)
/**
* Whether the window should be excluded from window switching effects.
*/
Q_PROPERTY(bool skipSwitcher READ isSkipSwitcher)
/**
* Geometry of the actual window contents inside the whole (including decorations) window.
*/
Q_PROPERTY(QRect contentsRect READ contentsRect)
/**
* Geometry of the transparent rect in the decoration.
* May be different from contentsRect if the decoration is extended into the client area.
*/
Q_PROPERTY(QRect decorationInnerRect READ decorationInnerRect)
Q_PROPERTY(bool hasDecoration READ hasDecoration)
Q_PROPERTY(QStringList activities READ activities)
Q_PROPERTY(bool onCurrentActivity READ isOnCurrentActivity)
Q_PROPERTY(bool onAllActivities READ isOnAllActivities)
/**
* Whether the decoration currently uses an alpha channel.
* @since 4.10
*/
Q_PROPERTY(bool decorationHasAlpha READ decorationHasAlpha)
/**
* Whether the window is currently visible to the user, that is:
*
* - Not minimized
* - On current desktop
* - On current activity
*
* @since 4.11
*/
Q_PROPERTY(bool visible READ isVisible)
/**
* Whether the window does not want to be animated on window close.
* In case this property is @c true it is not useful to start an animation on window close.
* The window will not be visible, but the animation hooks are executed.
* @since 5.0
*/
Q_PROPERTY(bool skipsCloseAnimation READ skipsCloseAnimation)
/**
* Interface to the corresponding wayland surface.
* relevant only in Wayland, on X11 it will be nullptr
*/
Q_PROPERTY(KWayland::Server::SurfaceInterface *surface READ surface)
/**
* Whether the window is fullscreen.
* @since 5.6
*/
Q_PROPERTY(bool fullScreen READ isFullScreen)
/**
* Whether this client is unresponsive.
*
* When an application failed to react on a ping request in time, it is
* considered unresponsive. This usually indicates that the application froze or crashed.
*
* @since 5.10
*/
Q_PROPERTY(bool unresponsive READ isUnresponsive)
/**
* Whether this is a Wayland client.
* @since 5.15
*/
Q_PROPERTY(bool waylandClient READ isWaylandClient CONSTANT)
/**
* Whether this is an X11 client.
* @since 5.15
*/
Q_PROPERTY(bool x11Client READ isX11Client CONSTANT)
/**
* Whether the window is a popup.
*
* A popup is a window that can be used to implement tooltips, combo box popups,
* popup menus and other similar user interface concepts.
*
* @since 5.15
*/
Q_PROPERTY(bool popupWindow READ isPopupWindow CONSTANT)
/**
* KWin internal window. Specific to Wayland platform.
*
* If the EffectWindow does not reference an internal window, this property is @c null.
* @since 5.16
*/
Q_PROPERTY(QWindow *internalWindow READ internalWindow CONSTANT)
/**
* Whether this EffectWindow represents the outline.
*
* When compositing is turned on, the outline is an actual window.
*
* @since 5.16
*/
Q_PROPERTY(bool outline READ isOutline CONSTANT)
/**
* The PID of the application this window belongs to.
*
* @since 5.18
*/
Q_PROPERTY(bool outline READ isOutline CONSTANT)
public:
/** Flags explaining why painting should be disabled */
enum {
/** Window will not be painted */
PAINT_DISABLED = 1 << 0,
/** Window will not be painted because it is deleted */
PAINT_DISABLED_BY_DELETE = 1 << 1,
/** Window will not be painted because of which desktop it's on */
PAINT_DISABLED_BY_DESKTOP = 1 << 2,
/** Window will not be painted because it is minimized */
PAINT_DISABLED_BY_MINIMIZE = 1 << 3,
/** Deprecated, tab groups have been removed: Window will not be painted because it is not the active window in a client group */
PAINT_DISABLED_BY_TAB_GROUP = 1 << 4,
/** Window will not be painted because it's not on the current activity */
PAINT_DISABLED_BY_ACTIVITY = 1 << 5
};
explicit EffectWindow(QObject *parent = nullptr);
~EffectWindow() override;
virtual void enablePainting(int reason) = 0;
virtual void disablePainting(int reason) = 0;
virtual bool isPaintingEnabled() = 0;
Q_SCRIPTABLE virtual void addRepaint(const QRect &r) = 0;
Q_SCRIPTABLE virtual void addRepaint(int x, int y, int w, int h) = 0;
Q_SCRIPTABLE virtual void addRepaintFull() = 0;
Q_SCRIPTABLE virtual void addLayerRepaint(const QRect &r) = 0;
Q_SCRIPTABLE virtual void addLayerRepaint(int x, int y, int w, int h) = 0;
virtual void refWindow() = 0;
virtual void unrefWindow() = 0;
virtual bool isDeleted() const = 0;
virtual bool isMinimized() const = 0;
virtual double opacity() const = 0;
virtual bool hasAlpha() const = 0;
bool isOnCurrentActivity() const;
Q_SCRIPTABLE bool isOnActivity(const QString &id) const;
bool isOnAllActivities() const;
virtual QStringList activities() const = 0;
Q_SCRIPTABLE bool isOnDesktop(int d) const;
bool isOnCurrentDesktop() const;
bool isOnAllDesktops() const;
/**
* The desktop this window is in. This makes sense only on X11
* where desktops are mutually exclusive, on Wayland it's the last
* desktop the window has been added to.
* use desktops() instead.
* @see desktops()
* @deprecated
*/
#ifndef KWIN_NO_DEPRECATED
virtual int KWIN_DEPRECATED desktop() const = 0; // prefer isOnXXX()
#endif
/**
* All the desktops by number that the window is in. On X11 this list will always have
* a length of 1, on Wayland can be any subset.
* If the list is empty it means the window is on all desktops
*/
virtual QVector desktops() const = 0;
virtual int x() const = 0;
virtual int y() const = 0;
virtual int width() const = 0;
virtual int height() const = 0;
/**
* By how much the window wishes to grow/shrink at least. Usually QSize(1,1).
* MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all.
*/
virtual QSize basicUnit() const = 0;
/**
* @deprecated Use frameGeometry() instead.
*/
virtual QRect geometry() const = 0;
/**
* Returns the geometry of the window excluding server-side and client-side
* drop-shadows.
*
* @since 5.18
*/
virtual QRect frameGeometry() const = 0;
/**
* Returns the geometry of the pixmap or buffer attached to this window.
*
* For X11 clients, this method returns server-side geometry of the Toplevel.
*
* For Wayland clients, this method returns rectangle that the main surface
* occupies on the screen, in global screen coordinates.
*
* @since 5.18
*/
virtual QRect bufferGeometry() const = 0;
/**
* Geometry of the window including decoration and potentially shadows.
* May be different from geometry() if the window has a shadow.
* @since 4.9
*/
virtual QRect expandedGeometry() const = 0;
virtual QRegion shape() const = 0;
virtual int screen() const = 0;
/** @internal Do not use */
virtual bool hasOwnShape() const = 0; // only for shadow effect, for now
virtual QPoint pos() const = 0;
virtual QSize size() const = 0;
virtual QRect rect() const = 0;
virtual bool isMovable() const = 0;
virtual bool isMovableAcrossScreens() const = 0;
virtual bool isUserMove() const = 0;
virtual bool isUserResize() const = 0;
virtual QRect iconGeometry() const = 0;
/**
* Geometry of the actual window contents inside the whole (including decorations) window.
*/
virtual QRect contentsRect() const = 0;
/**
* Geometry of the transparent rect in the decoration.
* May be different from contentsRect() if the decoration is extended into the client area.
* @since 4.5
*/
virtual QRect decorationInnerRect() const = 0;
bool hasDecoration() const;
virtual bool decorationHasAlpha() const = 0;
virtual QByteArray readProperty(long atom, long type, int format) const = 0;
virtual void deleteProperty(long atom) const = 0;
virtual QString caption() const = 0;
virtual QIcon icon() const = 0;
virtual QString windowClass() const = 0;
virtual QString windowRole() const = 0;
virtual const EffectWindowGroup* group() const = 0;
/**
* Returns whether the window is a desktop background window (the one with wallpaper).
* See _NET_WM_WINDOW_TYPE_DESKTOP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isDesktop() const = 0;
/**
* Returns whether the window is a dock (i.e. a panel).
* See _NET_WM_WINDOW_TYPE_DOCK at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isDock() const = 0;
/**
* Returns whether the window is a standalone (detached) toolbar window.
* See _NET_WM_WINDOW_TYPE_TOOLBAR at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isToolbar() const = 0;
/**
* Returns whether the window is a torn-off menu.
* See _NET_WM_WINDOW_TYPE_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isMenu() const = 0;
/**
* Returns whether the window is a "normal" window, i.e. an application or any other window
* for which none of the specialized window types fit.
* See _NET_WM_WINDOW_TYPE_NORMAL at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isNormalWindow() const = 0; // normal as in 'NET::Normal or NET::Unknown non-transient'
/**
* Returns whether the window is any of special windows types (desktop, dock, splash, ...),
* i.e. window types that usually don't have a window frame and the user does not use window
* management (moving, raising,...) on them.
*/
virtual bool isSpecialWindow() const = 0;
/**
* Returns whether the window is a dialog window.
* See _NET_WM_WINDOW_TYPE_DIALOG at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isDialog() const = 0;
/**
* Returns whether the window is a splashscreen. Note that many (especially older) applications
* do not support marking their splash windows with this type.
* See _NET_WM_WINDOW_TYPE_SPLASH at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isSplash() const = 0;
/**
* Returns whether the window is a utility window, such as a tool window.
* See _NET_WM_WINDOW_TYPE_UTILITY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isUtility() const = 0;
/**
* Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open
* from the applications menubar).
* See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isDropdownMenu() const = 0;
/**
* Returns whether the window is a popup menu (that is not a torn-off or dropdown menu).
* See _NET_WM_WINDOW_TYPE_POPUP_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isPopupMenu() const = 0; // a context popup, not dropdown, not torn-off
/**
* Returns whether the window is a tooltip.
* See _NET_WM_WINDOW_TYPE_TOOLTIP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isTooltip() const = 0;
/**
* Returns whether the window is a window with a notification.
* See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isNotification() const = 0;
/**
* Returns whether the window is a window with a critical notification.
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION
*/
virtual bool isCriticalNotification() const = 0;
/**
* Returns whether the window is an on screen display window
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY
*/
virtual bool isOnScreenDisplay() const = 0;
/**
* Returns whether the window is a combobox popup.
* See _NET_WM_WINDOW_TYPE_COMBO at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isComboBox() const = 0;
/**
* Returns whether the window is a Drag&Drop icon.
* See _NET_WM_WINDOW_TYPE_DND at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isDNDIcon() const = 0;
/**
* Returns the NETWM window type
* See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual NET::WindowType windowType() const = 0;
/**
* Returns whether the window is managed by KWin (it has control over its placement and other
* aspects, as opposed to override-redirect windows that are entirely handled by the application).
*/
virtual bool isManaged() const = 0; // whether it's managed or override-redirect
/**
* Returns whether or not the window can accept keyboard focus.
*/
virtual bool acceptsFocus() const = 0;
/**
* Returns whether or not the window is kept above all other windows.
*/
virtual bool keepAbove() const = 0;
/**
* Returns whether the window is kept below all other windows.
*/
virtual bool keepBelow() const = 0;
virtual bool isModal() const = 0;
Q_SCRIPTABLE virtual KWin::EffectWindow* findModal() = 0;
Q_SCRIPTABLE virtual QList mainWindows() const = 0;
/**
* Returns whether the window should be excluded from window switching effects.
* @since 4.5
*/
virtual bool isSkipSwitcher() const = 0;
/**
* Returns the unmodified window quad list. Can also be used to force rebuilding.
*/
virtual WindowQuadList buildQuads(bool force = false) const = 0;
void setMinimized(bool minimize);
virtual void minimize() = 0;
virtual void unminimize() = 0;
Q_SCRIPTABLE virtual void closeWindow() = 0;
/// deprecated
virtual bool isCurrentTab() const = 0;
/**
* @since 4.11
*/
bool isVisible() const;
/**
* @since 5.0
*/
virtual bool skipsCloseAnimation() const = 0;
/**
* @since 5.5
*/
virtual KWayland::Server::SurfaceInterface *surface() const = 0;
/**
* @since 5.6
*/
virtual bool isFullScreen() const = 0;
/**
* @since 5.10
*/
virtual bool isUnresponsive() const = 0;
/**
* @since 5.15
*/
virtual bool isWaylandClient() const = 0;
/**
* @since 5.15
*/
virtual bool isX11Client() const = 0;
/**
* @since 5.15
*/
virtual bool isPopupWindow() const = 0;
/**
* @since 5.16
*/
virtual QWindow *internalWindow() const = 0;
/**
* @since 5.16
*/
virtual bool isOutline() const = 0;
/**
* @since 5.18
*/
virtual pid_t pid() const = 0;
/**
* Can be used to by effects to store arbitrary data in the EffectWindow.
*
* Invoking this method will emit the signal EffectsHandler::windowDataChanged.
* @see EffectsHandler::windowDataChanged
*/
Q_SCRIPTABLE virtual void setData(int role, const QVariant &data) = 0;
Q_SCRIPTABLE virtual QVariant data(int role) const = 0;
/**
* @brief References the previous window pixmap to prevent discarding.
*
* This method allows to reference the previous window pixmap in case that a window changed
* its size, which requires a new window pixmap. By referencing the previous (and then outdated)
* window pixmap an effect can for example cross fade the current window pixmap with the previous
* one. This allows for smoother transitions for window geometry changes.
*
* If an effect calls this method on a window it also needs to call unreferencePreviousWindowPixmap
* once it does no longer need the previous window pixmap.
*
* Note: the window pixmap is not kept forever even when referenced. If the geometry changes again, so that
* a new window pixmap is created, the previous window pixmap will be exchanged with the current one. This
* means it's still possible to have rendering glitches. An effect is supposed to track for itself the changes
* to the window's geometry and decide how the transition should continue in such a situation.
*
* @see unreferencePreviousWindowPixmap
* @since 4.11
*/
virtual void referencePreviousWindowPixmap() = 0;
/**
* @brief Unreferences the previous window pixmap. Only relevant after referencePreviousWindowPixmap had
* been called.
*
* @see referencePreviousWindowPixmap
* @since 4.11
*/
virtual void unreferencePreviousWindowPixmap() = 0;
private:
class Private;
QScopedPointer d;
};
class KWINEFFECTS_EXPORT EffectWindowGroup
{
public:
virtual ~EffectWindowGroup();
virtual EffectWindowList members() const = 0;
};
struct GLVertex2D
{
QVector2D position;
QVector2D texcoord;
};
struct GLVertex3D
{
QVector3D position;
QVector2D texcoord;
};
/**
* @short Vertex class
*
* A vertex is one position in a window. WindowQuad consists of four WindowVertex objects
* and represents one part of a window.
*/
class KWINEFFECTS_EXPORT WindowVertex
{
public:
WindowVertex();
WindowVertex(const QPointF &position, const QPointF &textureCoordinate);
WindowVertex(double x, double y, double tx, double ty);
double x() const { return px; }
double y() const { return py; }
double u() const { return tx; }
double v() const { return ty; }
double originalX() const { return ox; }
double originalY() const { return oy; }
double textureX() const { return tx; }
double textureY() const { return ty; }
void move(double x, double y);
void setX(double x);
void setY(double y);
private:
friend class WindowQuad;
friend class WindowQuadList;
double px, py; // position
double ox, oy; // origional position
double tx, ty; // texture coords
};
/**
* @short Class representing one area of a window.
*
* WindowQuads consists of four WindowVertex objects and represents one part of a window.
*/
// NOTE: This class expects the (original) vertices to be in the clockwise order starting from topleft.
class KWINEFFECTS_EXPORT WindowQuad
{
public:
explicit WindowQuad(WindowQuadType type, int id = -1);
WindowQuad makeSubQuad(double x1, double y1, double x2, double y2) const;
WindowVertex& operator[](int index);
const WindowVertex& operator[](int index) const;
WindowQuadType type() const;
void setUVAxisSwapped(bool value) { uvSwapped = value; }
bool uvAxisSwapped() const { return uvSwapped; }
int id() const;
bool decoration() const;
bool effect() const;
double left() const;
double right() const;
double top() const;
double bottom() const;
double originalLeft() const;
double originalRight() const;
double originalTop() const;
double originalBottom() const;
bool smoothNeeded() const;
bool isTransformed() const;
private:
friend class WindowQuadList;
WindowVertex verts[ 4 ];
WindowQuadType quadType; // 0 - contents, 1 - decoration
bool uvSwapped;
int quadID;
};
class KWINEFFECTS_EXPORT WindowQuadList
: public QList< WindowQuad >
{
public:
WindowQuadList splitAtX(double x) const;
WindowQuadList splitAtY(double y) const;
WindowQuadList makeGrid(int maxquadsize) const;
WindowQuadList makeRegularGrid(int xSubdivisions, int ySubdivisions) const;
WindowQuadList select(WindowQuadType type) const;
WindowQuadList filterOut(WindowQuadType type) const;
bool smoothNeeded() const;
void makeInterleavedArrays(unsigned int type, GLVertex2D *vertices, const QMatrix4x4 &matrix) const;
void makeArrays(float** vertices, float** texcoords, const QSizeF &size, bool yInverted) const;
bool isTransformed() const;
};
class KWINEFFECTS_EXPORT WindowPrePaintData
{
public:
int mask;
/**
* Region that will be painted, in screen coordinates.
*/
QRegion paint;
/**
* The clip region will be subtracted from paint region of following windows.
* I.e. window will definitely cover it's clip region
*/
QRegion clip;
WindowQuadList quads;
/**
* Simple helper that sets data to say the window will be painted as non-opaque.
* Takes also care of changing the regions.
*/
void setTranslucent();
/**
* Helper to mark that this window will be transformed
*/
void setTransformed();
};
class KWINEFFECTS_EXPORT PaintData
{
public:
virtual ~PaintData();
/**
* @returns scale factor in X direction.
* @since 4.10
*/
qreal xScale() const;
/**
* @returns scale factor in Y direction.
* @since 4.10
*/
qreal yScale() const;
/**
* @returns scale factor in Z direction.
* @since 4.10
*/
qreal zScale() const;
/**
* Sets the scale factor in X direction to @p scale
* @param scale The scale factor in X direction
* @since 4.10
*/
void setXScale(qreal scale);
/**
* Sets the scale factor in Y direction to @p scale
* @param scale The scale factor in Y direction
* @since 4.10
*/
void setYScale(qreal scale);
/**
* Sets the scale factor in Z direction to @p scale
* @param scale The scale factor in Z direction
* @since 4.10
*/
void setZScale(qreal scale);
/**
* Sets the scale factor in X and Y direction.
* @param scale The scale factor for X and Y direction
* @since 4.10
*/
void setScale(const QVector2D &scale);
/**
* Sets the scale factor in X, Y and Z direction
* @param scale The scale factor for X, Y and Z direction
* @since 4.10
*/
void setScale(const QVector3D &scale);
const QGraphicsScale &scale() const;
const QVector3D &translation() const;
/**
* @returns the translation in X direction.
* @since 4.10
*/
qreal xTranslation() const;
/**
* @returns the translation in Y direction.
* @since 4.10
*/
qreal yTranslation() const;
/**
* @returns the translation in Z direction.
* @since 4.10
*/
qreal zTranslation() const;
/**
* Sets the translation in X direction to @p translate.
* @since 4.10
*/
void setXTranslation(qreal translate);
/**
* Sets the translation in Y direction to @p translate.
* @since 4.10
*/
void setYTranslation(qreal translate);
/**
* Sets the translation in Z direction to @p translate.
* @since 4.10
*/
void setZTranslation(qreal translate);
/**
* Performs a translation by adding the values component wise.
* @param x Translation in X direction
* @param y Translation in Y direction
* @param z Translation in Z direction
* @since 4.10
*/
void translate(qreal x, qreal y = 0.0, qreal z = 0.0);
/**
* Performs a translation by adding the values component wise.
* Overloaded method for convenience.
* @param translate The translation
* @since 4.10
*/
void translate(const QVector3D &translate);
/**
* Sets the rotation angle.
* @param angle The new rotation angle.
* @since 4.10
* @see rotationAngle()
*/
void setRotationAngle(qreal angle);
/**
* Returns the rotation angle.
* Initially 0.0.
* @returns The current rotation angle.
* @since 4.10
* @see setRotationAngle
*/
qreal rotationAngle() const;
/**
* Sets the rotation origin.
* @param origin The new rotation origin.
* @since 4.10
* @see rotationOrigin()
*/
void setRotationOrigin(const QVector3D &origin);
/**
* Returns the rotation origin. That is the point in space which is fixed during the rotation.
* Initially this is 0/0/0.
* @returns The rotation's origin
* @since 4.10
* @see setRotationOrigin()
*/
QVector3D rotationOrigin() const;
/**
* Sets the rotation axis.
* Set a component to 1.0 to rotate around this axis and to 0.0 to disable rotation around the
* axis.
* @param axis A vector holding information on which axis to rotate
* @since 4.10
* @see rotationAxis()
*/
void setRotationAxis(const QVector3D &axis);
/**
* Sets the rotation axis.
* Overloaded method for convenience.
* @param axis The axis around which should be rotated.
* @since 4.10
* @see rotationAxis()
*/
void setRotationAxis(Qt::Axis axis);
/**
* The current rotation axis.
* By default the rotation is (0/0/1) which means a rotation around the z axis.
* @returns The current rotation axis.
* @since 4.10
* @see setRotationAxis
*/
QVector3D rotationAxis() const;
protected:
PaintData();
PaintData(const PaintData &other);
private:
PaintDataPrivate * const d;
};
class KWINEFFECTS_EXPORT WindowPaintData : public PaintData
{
public:
explicit WindowPaintData(EffectWindow* w);
explicit WindowPaintData(EffectWindow* w, const QMatrix4x4 &screenProjectionMatrix);
WindowPaintData(const WindowPaintData &other);
~WindowPaintData() override;
/**
* Scales the window by @p scale factor.
* Multiplies all three components by the given factor.
* @since 4.10
*/
WindowPaintData& operator*=(qreal scale);
/**
* Scales the window by @p scale factor.
* Performs a component wise multiplication on x and y components.
* @since 4.10
*/
WindowPaintData& operator*=(const QVector2D &scale);
/**
* Scales the window by @p scale factor.
* Performs a component wise multiplication.
* @since 4.10
*/
WindowPaintData& operator*=(const QVector3D &scale);
/**
* Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
* @since 4.10
*/
WindowPaintData& operator+=(const QPointF &translation);
/**
* Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
WindowPaintData& operator+=(const QPoint &translation);
/**
* Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
WindowPaintData& operator+=(const QVector2D &translation);
/**
* Translates the window by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
WindowPaintData& operator+=(const QVector3D &translation);
/**
* Window opacity, in range 0 = transparent to 1 = fully opaque
* @see setOpacity
* @since 4.10
*/
qreal opacity() const;
/**
* Sets the window opacity to the new @p opacity.
* If you want to modify the existing opacity level consider using multiplyOpacity.
* @param opacity The new opacity level
* @since 4.10
*/
void setOpacity(qreal opacity);
/**
* Multiplies the current opacity with the @p factor.
* @param factor Factor with which the opacity should be multiplied
* @return New opacity level
* @since 4.10
*/
qreal multiplyOpacity(qreal factor);
/**
* Saturation of the window, in range [0; 1]
* 1 means that the window is unchanged, 0 means that it's completely
* unsaturated (greyscale). 0.5 would make the colors less intense,
* but not completely grey
* Use EffectsHandler::saturationSupported() to find out whether saturation
* is supported by the system, otherwise this value has no effect.
* @return The current saturation
* @see setSaturation()
* @since 4.10
*/
qreal saturation() const;
/**
* Sets the window saturation level to @p saturation.
* If you want to modify the existing saturation level consider using multiplySaturation.
* @param saturation The new saturation level
* @since 4.10
*/
void setSaturation(qreal saturation) const;
/**
* Multiplies the current saturation with @p factor.
* @param factor with which the saturation should be multiplied
* @return New saturation level
* @since 4.10
*/
qreal multiplySaturation(qreal factor);
/**
* Brightness of the window, in range [0; 1]
* 1 means that the window is unchanged, 0 means that it's completely
* black. 0.5 would make it 50% darker than usual
*/
qreal brightness() const;
/**
* Sets the window brightness level to @p brightness.
* If you want to modify the existing brightness level consider using multiplyBrightness.
* @param brightness The new brightness level
*/
void setBrightness(qreal brightness);
/**
* Multiplies the current brightness level with @p factor.
* @param factor with which the brightness should be multiplied.
* @return New brightness level
* @since 4.10
*/
qreal multiplyBrightness(qreal factor);
/**
* The screen number for which the painting should be done.
* This affects color correction (different screens may need different
* color correction lookup tables because they have different ICC profiles).
* @return screen for which painting should be done
*/
int screen() const;
/**
* @param screen New screen number
* A value less than 0 will indicate that a default profile should be done.
*/
void setScreen(int screen) const;
/**
* @brief Sets the cross fading @p factor to fade over with previously sized window.
* If @c 1.0 only the current window is used, if @c 0.0 only the previous window is used.
*
* By default only the current window is used. This factor can only make any visual difference
* if the previous window get referenced.
*
* @param factor The cross fade factor between @c 0.0 (previous window) and @c 1.0 (current window)
* @see crossFadeProgress
*/
void setCrossFadeProgress(qreal factor);
/**
* @see setCrossFadeProgress
*/
qreal crossFadeProgress() const;
/**
* Sets the projection matrix that will be used when painting the window.
*
* The default projection matrix can be overridden by setting this matrix
* to a non-identity matrix.
*/
void setProjectionMatrix(const QMatrix4x4 &matrix);
/**
* Returns the current projection matrix.
*
* The default value for this matrix is the identity matrix.
*/
QMatrix4x4 projectionMatrix() const;
/**
* Returns a reference to the projection matrix.
*/
QMatrix4x4 &rprojectionMatrix();
/**
* Sets the model-view matrix that will be used when painting the window.
*
* The default model-view matrix can be overridden by setting this matrix
* to a non-identity matrix.
*/
void setModelViewMatrix(const QMatrix4x4 &matrix);
/**
* Returns the current model-view matrix.
*
* The default value for this matrix is the identity matrix.
*/
QMatrix4x4 modelViewMatrix() const;
/**
* Returns a reference to the model-view matrix.
*/
QMatrix4x4 &rmodelViewMatrix();
/**
* Returns The projection matrix as used by the current screen painting pass
* including screen transformations.
*
* @since 5.6
*/
QMatrix4x4 screenProjectionMatrix() const;
WindowQuadList quads;
/**
* Shader to be used for rendering, if any.
*/
GLShader* shader;
private:
WindowPaintDataPrivate * const d;
};
class KWINEFFECTS_EXPORT ScreenPaintData : public PaintData
{
public:
ScreenPaintData();
ScreenPaintData(const QMatrix4x4 &projectionMatrix, const QRect &outputGeometry = QRect());
ScreenPaintData(const ScreenPaintData &other);
~ScreenPaintData() override;
/**
* Scales the screen by @p scale factor.
* Multiplies all three components by the given factor.
* @since 4.10
*/
ScreenPaintData& operator*=(qreal scale);
/**
* Scales the screen by @p scale factor.
* Performs a component wise multiplication on x and y components.
* @since 4.10
*/
ScreenPaintData& operator*=(const QVector2D &scale);
/**
* Scales the screen by @p scale factor.
* Performs a component wise multiplication.
* @since 4.10
*/
ScreenPaintData& operator*=(const QVector3D &scale);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* @since 4.10
*/
ScreenPaintData& operator+=(const QPointF &translation);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
ScreenPaintData& operator+=(const QPoint &translation);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
ScreenPaintData& operator+=(const QVector2D &translation);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
ScreenPaintData& operator+=(const QVector3D &translation);
ScreenPaintData& operator=(const ScreenPaintData &rhs);
/**
* The projection matrix used by the scene for the current rendering pass.
* On non-OpenGL compositors it's set to Identity matrix.
* @since 5.6
*/
QMatrix4x4 projectionMatrix() const;
/**
* The geometry of the currently rendered output.
* Only set for per-output rendering (e.g. Wayland).
*
* This geometry can be used as a hint about the native window the OpenGL context
* is bound. OpenGL calls need to be translated to this geometry.
* @since 5.9
*/
QRect outputGeometry() const;
private:
class Private;
QScopedPointer d;
};
class KWINEFFECTS_EXPORT ScreenPrePaintData
{
public:
int mask;
QRegion paint;
};
/**
* @short Helper class for restricting painting area only to allowed area.
*
* This helper class helps specifying areas that should be painted, clipping
* out the rest. The simplest usage is creating an object on the stack
* and giving it the area that is allowed to be painted to. When the object
* is destroyed, the restriction will be removed.
* Note that all painting code must use paintArea() to actually perform the clipping.
*/
class KWINEFFECTS_EXPORT PaintClipper
{
public:
/**
* Calls push().
*/
explicit PaintClipper(const QRegion& allowed_area);
/**
* Calls pop().
*/
~PaintClipper();
/**
* Allows painting only in the given area. When areas have been already
* specified, painting is allowed only in the intersection of all areas.
*/
static void push(const QRegion& allowed_area);
/**
* Removes the given area. It must match the top item in the stack.
*/
static void pop(const QRegion& allowed_area);
/**
* Returns true if any clipping should be performed.
*/
static bool clip();
/**
* If clip() returns true, this function gives the resulting area in which
* painting is allowed. It is usually simpler to use the helper Iterator class.
*/
static QRegion paintArea();
/**
* Helper class to perform the clipped painting. The usage is:
* @code
* for ( PaintClipper::Iterator iterator;
* !iterator.isDone();
* iterator.next())
* { // do the painting, possibly use iterator.boundingRect()
* }
* @endcode
*/
class KWINEFFECTS_EXPORT Iterator
{
public:
Iterator();
~Iterator();
bool isDone();
void next();
QRect boundingRect() const;
private:
struct Data;
Data* data;
};
private:
QRegion area;
static QStack< QRegion >* areas;
};
/**
* @internal
*/
template
class KWINEFFECTS_EXPORT Motion
{
public:
/**
* Creates a new motion object. "Strength" is the amount of
* acceleration that is applied to the object when the target
* changes and "smoothness" relates to how fast the object
* can change its direction and speed.
*/
explicit Motion(T initial, double strength, double smoothness);
/**
* Creates an exact copy of another motion object, including
* position, target and velocity.
*/
Motion(const Motion &other);
~Motion();
inline T value() const {
return m_value;
}
inline void setValue(const T value) {
m_value = value;
}
inline T target() const {
return m_target;
}
inline void setTarget(const T target) {
m_start = m_value;
m_target = target;
}
inline T velocity() const {
return m_velocity;
}
inline void setVelocity(const T velocity) {
m_velocity = velocity;
}
inline double strength() const {
return m_strength;
}
inline void setStrength(const double strength) {
m_strength = strength;
}
inline double smoothness() const {
return m_smoothness;
}
inline void setSmoothness(const double smoothness) {
m_smoothness = smoothness;
}
inline T startValue() {
return m_start;
}
/**
* The distance between the current position and the target.
*/
inline T distance() const {
return m_target - m_value;
}
/**
* Calculates the new position if not at the target. Called
* once per frame only.
*/
void calculate(const int msec);
/**
* Place the object on top of the target immediately,
* bypassing all movement calculation.
*/
void finish();
private:
T m_value;
T m_start;
T m_target;
T m_velocity;
double m_strength;
double m_smoothness;
};
/**
* @short A single 1D motion dynamics object.
*
* This class represents a single object that can be moved around a
* 1D space. Although it can be used directly by itself it is
* recommended to use a motion manager instead.
*/
class KWINEFFECTS_EXPORT Motion1D : public Motion
{
public:
explicit Motion1D(double initial = 0.0, double strength = 0.08, double smoothness = 4.0);
Motion1D(const Motion1D &other);
~Motion1D();
};
/**
* @short A single 2D motion dynamics object.
*
* This class represents a single object that can be moved around a
* 2D space. Although it can be used directly by itself it is
* recommended to use a motion manager instead.
*/
class KWINEFFECTS_EXPORT Motion2D : public Motion
{
public:
explicit Motion2D(QPointF initial = QPointF(), double strength = 0.08, double smoothness = 4.0);
Motion2D(const Motion2D &other);
~Motion2D();
};
/**
* @short Helper class for motion dynamics in KWin effects.
*
* This motion manager class is intended to help KWin effect authors
* move windows across the screen smoothly and naturally. Once
* windows are registered by the manager the effect can issue move
* commands with the moveWindow() methods. The position of any
* managed window can be determined in realtime by the
* transformedGeometry() method. As the manager knows if any windows
* are moving at any given time it can also be used as a notifier as
* to see whether the effect is active or not.
*/
class KWINEFFECTS_EXPORT WindowMotionManager
{
public:
/**
* Creates a new window manager object.
*/
explicit WindowMotionManager(bool useGlobalAnimationModifier = true);
~WindowMotionManager();
/**
* Register a window for managing.
*/
void manage(EffectWindow *w);
/**
* Register a list of windows for managing.
*/
inline void manage(const EffectWindowList &list) {
for (int i = 0; i < list.size(); i++)
manage(list.at(i));
}
/**
* Deregister a window. All transformations applied to the
* window will be permanently removed and cannot be recovered.
*/
void unmanage(EffectWindow *w);
/**
* Deregister all windows, returning the manager to its
* originally initiated state.
*/
void unmanageAll();
/**
* Determine the new positions for windows that have not
* reached their target. Called once per frame, usually in
* prePaintScreen(). Remember to set the
* Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS flag.
*/
void calculate(int time);
/**
* Modify a registered window's paint data to make it appear
* at its real location on the screen. Usually called in
* paintWindow(). Remember to flag the window as having been
* transformed in prePaintWindow() by calling
* WindowPrePaintData::setTransformed()
*/
void apply(EffectWindow *w, WindowPaintData &data);
/**
* Set all motion targets and values back to where the
* windows were before transformations. The same as
* unmanaging then remanaging all windows.
*/
void reset();
/**
* Resets the motion target and current value of a single
* window.
*/
void reset(EffectWindow *w);
/**
* Ask the manager to move the window to the target position
* with the specified scale. If `yScale` is not provided or
* set to 0.0, `scale` will be used as the scale in the
* vertical direction as well as in the horizontal direction.
*/
void moveWindow(EffectWindow *w, QPoint target, double scale = 1.0, double yScale = 0.0);
/**
* This is an overloaded method, provided for convenience.
*
* Ask the manager to move the window to the target rectangle.
* Automatically determines scale.
*/
inline void moveWindow(EffectWindow *w, QRect target) {
// TODO: Scale might be slightly different in the comparison due to rounding
moveWindow(w, target.topLeft(),
target.width() / double(w->width()), target.height() / double(w->height()));
}
/**
* Retrieve the current tranformed geometry of a registered
* window.
*/
QRectF transformedGeometry(EffectWindow *w) const;
/**
* Sets the current transformed geometry of a registered window to the given geometry.
* @see transformedGeometry
* @since 4.5
*/
void setTransformedGeometry(EffectWindow *w, const QRectF &geometry);
/**
* Retrieve the current target geometry of a registered
* window.
*/
QRectF targetGeometry(EffectWindow *w) const;
/**
* Return the window that has its transformed geometry under
* the specified point. It is recommended to use the stacking
* order as it's what the user sees, but it is slightly
* slower to process.
*/
EffectWindow* windowAtPoint(QPoint point, bool useStackingOrder = true) const;
/**
* Return a list of all currently registered windows.
*/
inline EffectWindowList managedWindows() const {
return m_managedWindows.keys();
}
/**
* Returns whether or not a specified window is being managed
* by this manager object.
*/
inline bool isManaging(EffectWindow *w) const {
return m_managedWindows.contains(w);
}
/**
* Returns whether or not this manager object is actually
* managing any windows or not.
*/
inline bool managingWindows() const {
return !m_managedWindows.empty();
}
/**
* Returns whether all windows have reached their targets yet
* or not. Can be used to see if an effect should be
* processed and displayed or not.
*/
inline bool areWindowsMoving() const {
return !m_movingWindowsSet.isEmpty();
}
/**
* Returns whether a window has reached its targets yet
* or not.
*/
inline bool isWindowMoving(EffectWindow *w) const {
return m_movingWindowsSet.contains(w);
}
private:
bool m_useGlobalAnimationModifier;
struct WindowMotion {
// TODO: Rotation, etc?
Motion2D translation; // Absolute position
Motion2D scale; // xScale and yScale
};
QHash m_managedWindows;
QSet m_movingWindowsSet;
};
/**
* @short Helper class for displaying text and icons in frames.
*
* Paints text and/or and icon with an optional frame around them. The
* available frames includes one that follows the default Plasma theme and
* another that doesn't.
* It is recommended to use this class whenever displaying text.
*/
class KWINEFFECTS_EXPORT EffectFrame
{
public:
EffectFrame();
virtual ~EffectFrame();
/**
* Delete any existing textures to free up graphics memory. They will
* be automatically recreated the next time they are required.
*/
virtual void free() = 0;
/**
* Render the frame.
*/
virtual void render(const QRegion ®ion = infiniteRegion(), double opacity = 1.0, double frameOpacity = 1.0) = 0;
virtual void setPosition(const QPoint& point) = 0;
/**
* Set the text alignment for static frames and the position alignment
* for non-static.
*/
virtual void setAlignment(Qt::Alignment alignment) = 0;
virtual Qt::Alignment alignment() const = 0;
virtual void setGeometry(const QRect& geometry, bool force = false) = 0;
virtual const QRect& geometry() const = 0;
virtual void setText(const QString& text) = 0;
virtual const QString& text() const = 0;
virtual void setFont(const QFont& font) = 0;
virtual const QFont& font() const = 0;
/**
* Set the icon that will appear on the left-hand size of the frame.
*/
virtual void setIcon(const QIcon& icon) = 0;
virtual const QIcon& icon() const = 0;
virtual void setIconSize(const QSize& size) = 0;
virtual const QSize& iconSize() const = 0;
/**
* Sets the geometry of a selection.
* To remove the selection set a null rect.
* @param selection The geometry of the selection in screen coordinates.
*/
virtual void setSelection(const QRect& selection) = 0;
/**
* @param shader The GLShader for rendering.
*/
virtual void setShader(GLShader* shader) = 0;
/**
* @returns The GLShader used for rendering or null if none.
*/
virtual GLShader* shader() const = 0;
/**
* @returns The style of this EffectFrame.
*/
virtual EffectFrameStyle style() const = 0;
/**
* If @p enable is @c true cross fading between icons and text is enabled
* By default disabled. Use setCrossFadeProgress to cross fade.
* Cross Fading is currently only available if OpenGL is used.
* @param enable @c true enables cross fading, @c false disables it again
* @see isCrossFade
* @see setCrossFadeProgress
* @since 4.6
*/
void enableCrossFade(bool enable);
/**
* @returns @c true if cross fading is enabled, @c false otherwise
* @see enableCrossFade
* @since 4.6
*/
bool isCrossFade() const;
/**
* Sets the current progress for cross fading the last used icon/text
* with current icon/text to @p progress.
* A value of 0.0 means completely old icon/text, a value of 1.0 means
* completely current icon/text.
* Default value is 1.0. You have to enable cross fade before using it.
* Cross Fading is currently only available if OpenGL is used.
* @see enableCrossFade
* @see isCrossFade
* @see crossFadeProgress
* @since 4.6
*/
void setCrossFadeProgress(qreal progress);
/**
* @returns The current progress for cross fading
* @see setCrossFadeProgress
* @see enableCrossFade
* @see isCrossFade
* @since 4.6
*/
qreal crossFadeProgress() const;
/**
* Returns The projection matrix as used by the current screen painting pass
* including screen transformations.
*
* This matrix is only valid during a rendering pass started by render.
*
* @since 5.6
* @see render
* @see EffectsHandler::paintEffectFrame
* @see Effect::paintEffectFrame
*/
QMatrix4x4 screenProjectionMatrix() const;
protected:
void setScreenProjectionMatrix(const QMatrix4x4 &projection);
private:
EffectFramePrivate* const d;
};
/**
* The TimeLine class is a helper for controlling animations.
*/
class KWINEFFECTS_EXPORT TimeLine
{
public:
/**
* Direction of the timeline.
*
* When the direction of the timeline is Forward, the progress
* value will go from 0.0 to 1.0.
*
* When the direction of the timeline is Backward, the progress
* value will go from 1.0 to 0.0.
*/
enum Direction {
Forward,
Backward
};
/**
* Constructs a new instance of TimeLine.
*
* @param duration Duration of the timeline, in milliseconds
* @param direction Direction of the timeline
* @since 5.14
*/
explicit TimeLine(std::chrono::milliseconds duration = std::chrono::milliseconds(1000),
Direction direction = Forward);
TimeLine(const TimeLine &other);
~TimeLine();
/**
* Returns the current value of the timeline.
*
* @since 5.14
*/
qreal value() const;
/**
* Updates the progress of the timeline.
*
* @note The delta value should be a non-negative number, i.e. it
* should be greater or equal to 0.
*
* @param delta The number milliseconds passed since last frame
* @since 5.14
*/
void update(std::chrono::milliseconds delta);
/**
* Returns the number of elapsed milliseconds.
*
* @see setElapsed
* @since 5.14
*/
std::chrono::milliseconds elapsed() const;
/**
* Sets the number of elapsed milliseconds.
*
* This method overwrites previous value of elapsed milliseconds.
* If the new value of elapsed milliseconds is greater or equal
* to duration of the timeline, the timeline will be finished, i.e.
* proceeding TimeLine::done method calls will return @c true.
* Please don't use it. Instead, use TimeLine::update.
*
* @note The new number of elapsed milliseconds should be a non-negative
* number, i.e. it should be greater or equal to 0.
*
* @param elapsed The new number of elapsed milliseconds
* @see elapsed
* @since 5.14
*/
void setElapsed(std::chrono::milliseconds elapsed);
/**
* Returns the duration of the timeline.
*
* @returns Duration of the timeline, in milliseconds
* @see setDuration
* @since 5.14
*/
std::chrono::milliseconds duration() const;
/**
* Sets the duration of the timeline.
*
* In addition to setting new value of duration, the timeline will
* try to retarget the number of elapsed milliseconds to match
* as close as possible old progress value. If the new duration
* is much smaller than old duration, there is a big chance that
* the timeline will be finished after setting new duration.
*
* @note The new duration should be a positive number, i.e. it
* should be greater or equal to 1.
*
* @param duration The new duration of the timeline, in milliseconds
* @see duration
* @since 5.14
*/
void setDuration(std::chrono::milliseconds duration);
/**
* Returns the direction of the timeline.
*
* @returns Direction of the timeline(TimeLine::Forward or TimeLine::Backward)
* @see setDirection
* @see toggleDirection
* @since 5.14
*/
Direction direction() const;
/**
* Sets the direction of the timeline.
*
* @param direction The new direction of the timeline
* @see direction
* @see toggleDirection
* @since 5.14
*/
void setDirection(Direction direction);
/**
* Toggles the direction of the timeline.
*
* If the direction of the timeline was TimeLine::Forward, it becomes
* TimeLine::Backward, and vice verca.
*
* @see direction
* @see setDirection
* @since 5.14
*/
void toggleDirection();
/**
* Returns the easing curve of the timeline.
*
* @see setEasingCurve
* @since 5.14
*/
QEasingCurve easingCurve() const;
/**
* Sets new easing curve.
*
* @param easingCurve An easing curve to be set
* @see easingCurve
* @since 5.14
*/
void setEasingCurve(const QEasingCurve &easingCurve);
/**
* Sets new easing curve by providing its type.
*
* @param type Type of the easing curve(e.g. QEasingCurve::InCubic, etc)
* @see easingCurve
* @since 5.14
*/
void setEasingCurve(QEasingCurve::Type type);
/**
* Returns whether the timeline is currently in progress.
*
* @see done
* @since 5.14
*/
bool running() const;
/**
* Returns whether the timeline is finished.
*
* @see reset
* @since 5.14
*/
bool done() const;
/**
* Resets the timeline to initial state.
*
* @since 5.14
*/
void reset();
enum class RedirectMode {
Strict,
Relaxed
};
/**
* Returns the redirect mode for the source position.
*
* The redirect mode controls behavior of the timeline when its direction is
* changed at the source position, e.g. what should we do when the timeline
* initially goes forward and we change its direction to go backward.
*
* In the strict mode, the timeline will stop.
*
* In the relaxed mode, the timeline will go in the new direction. For example,
* if the timeline goes forward(from 0 to 1), then with the new direction it
* will go backward(from 1 to 0).
*
* The default is RedirectMode::Relaxed.
*
* @see targetRedirectMode
* @since 5.15
*/
RedirectMode sourceRedirectMode() const;
/**
* Sets the redirect mode for the source position.
*
* @param mode The new mode.
* @since 5.15
*/
void setSourceRedirectMode(RedirectMode mode);
/**
* Returns the redirect mode for the target position.
*
* The redirect mode controls behavior of the timeline when its direction is
* changed at the target position.
*
* In the strict mode, subsequent update calls won't have any effect on the
* current value of the timeline.
*
* In the relaxed mode, the timeline will go in the new direction.
*
* The default is RedirectMode::Strict.
*
* @see sourceRedirectMode
* @since 5.15
*/
RedirectMode targetRedirectMode() const;
/**
* Sets the redirect mode for the target position.
*
* @param mode The new mode.
* @since 5.15
*/
void setTargetRedirectMode(RedirectMode mode);
TimeLine &operator=(const TimeLine &other);
private:
qreal progress() const;
private:
class Data;
QSharedDataPointer d;
};
/**
* Pointer to the global EffectsHandler object.
*/
extern KWINEFFECTS_EXPORT EffectsHandler* effects;
/***************************************************************
WindowVertex
***************************************************************/
inline
WindowVertex::WindowVertex()
: px(0), py(0), ox(0), oy(0), tx(0), ty(0)
{
}
inline
WindowVertex::WindowVertex(double _x, double _y, double _tx, double _ty)
: px(_x), py(_y), ox(_x), oy(_y), tx(_tx), ty(_ty)
{
}
inline
WindowVertex::WindowVertex(const QPointF &position, const QPointF &texturePosition)
: px(position.x()), py(position.y()), ox(position.x()), oy(position.y()), tx(texturePosition.x()), ty(texturePosition.y())
{
}
inline
void WindowVertex::move(double x, double y)
{
px = x;
py = y;
}
inline
void WindowVertex::setX(double x)
{
px = x;
}
inline
void WindowVertex::setY(double y)
{
py = y;
}
/***************************************************************
WindowQuad
***************************************************************/
inline
WindowQuad::WindowQuad(WindowQuadType t, int id)
: quadType(t)
, uvSwapped(false)
, quadID(id)
{
}
inline
WindowVertex& WindowQuad::operator[](int index)
{
Q_ASSERT(index >= 0 && index < 4);
return verts[ index ];
}
inline
const WindowVertex& WindowQuad::operator[](int index) const
{
Q_ASSERT(index >= 0 && index < 4);
return verts[ index ];
}
inline
WindowQuadType WindowQuad::type() const
{
Q_ASSERT(quadType != WindowQuadError);
return quadType;
}
inline
int WindowQuad::id() const
{
return quadID;
}
inline
bool WindowQuad::decoration() const
{
Q_ASSERT(quadType != WindowQuadError);
return quadType == WindowQuadDecoration;
}
inline
bool WindowQuad::effect() const
{
Q_ASSERT(quadType != WindowQuadError);
return quadType >= EFFECT_QUAD_TYPE_START;
}
inline
bool WindowQuad::isTransformed() const
{
return !(verts[ 0 ].px == verts[ 0 ].ox && verts[ 0 ].py == verts[ 0 ].oy
&& verts[ 1 ].px == verts[ 1 ].ox && verts[ 1 ].py == verts[ 1 ].oy
&& verts[ 2 ].px == verts[ 2 ].ox && verts[ 2 ].py == verts[ 2 ].oy
&& verts[ 3 ].px == verts[ 3 ].ox && verts[ 3 ].py == verts[ 3 ].oy);
}
inline
double WindowQuad::left() const
{
return qMin(verts[ 0 ].px, qMin(verts[ 1 ].px, qMin(verts[ 2 ].px, verts[ 3 ].px)));
}
inline
double WindowQuad::right() const
{
return qMax(verts[ 0 ].px, qMax(verts[ 1 ].px, qMax(verts[ 2 ].px, verts[ 3 ].px)));
}
inline
double WindowQuad::top() const
{
return qMin(verts[ 0 ].py, qMin(verts[ 1 ].py, qMin(verts[ 2 ].py, verts[ 3 ].py)));
}
inline
double WindowQuad::bottom() const
{
return qMax(verts[ 0 ].py, qMax(verts[ 1 ].py, qMax(verts[ 2 ].py, verts[ 3 ].py)));
}
inline
double WindowQuad::originalLeft() const
{
return verts[ 0 ].ox;
}
inline
double WindowQuad::originalRight() const
{
return verts[ 2 ].ox;
}
inline
double WindowQuad::originalTop() const
{
return verts[ 0 ].oy;
}
inline
double WindowQuad::originalBottom() const
{
return verts[ 2 ].oy;
}
/***************************************************************
Motion
***************************************************************/
template
Motion::Motion(T initial, double strength, double smoothness)
: m_value(initial)
, m_start(initial)
, m_target(initial)
, m_velocity()
, m_strength(strength)
, m_smoothness(smoothness)
{
}
template
Motion::Motion(const Motion &other)
: m_value(other.value())
, m_start(other.target())
, m_target(other.target())
, m_velocity(other.velocity())
, m_strength(other.strength())
, m_smoothness(other.smoothness())
{
}
template
Motion::~Motion()
{
}
template
void Motion::calculate(const int msec)
{
if (m_value == m_target && m_velocity == T()) // At target and not moving
return;
// Poor man's time independent calculation
int steps = qMax(1, msec / 5);
for (int i = 0; i < steps; i++) {
T diff = m_target - m_value;
T strength = diff * m_strength;
m_velocity = (m_smoothness * m_velocity + strength) / (m_smoothness + 1.0);
m_value += m_velocity;
}
}
template
void Motion::finish()
{
m_value = m_target;
m_velocity = T();
}
/***************************************************************
Effect
***************************************************************/
template
int Effect::animationTime(int defaultDuration)
{
return animationTime(T::duration() != 0 ? T::duration() : defaultDuration);
}
template
void Effect::initConfig()
{
T::instance(effects->config());
}
} // namespace
Q_DECLARE_METATYPE(KWin::EffectWindow*)
Q_DECLARE_METATYPE(QList)
Q_DECLARE_METATYPE(KWin::TimeLine)
Q_DECLARE_METATYPE(KWin::TimeLine::Direction)
/** @} */
#endif // KWINEFFECTS_H
diff --git a/libkwineffects/kwinglplatform.cpp b/libkwineffects/kwinglplatform.cpp
index 6e8e37732..3373f9cdb 100644
--- a/libkwineffects/kwinglplatform.cpp
+++ b/libkwineffects/kwinglplatform.cpp
@@ -1,1280 +1,1279 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2010 Fredrik Höglund
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 "kwinglplatform.h"
// include kwinglutils_funcs.h to avoid the redeclaration issues
// between qopengl.h and epoxy/gl.h
#include "kwinglutils_funcs.h"
#include
-#include
+#include
#include
#include
#include
#include
#include
#include
#include
namespace KWin
{
GLPlatform *GLPlatform::s_platform = nullptr;
static qint64 parseVersionString(const QByteArray &version)
{
// Skip any leading non digit
int start = 0;
while (start < version.length() && !QChar::fromLatin1(version[start]).isDigit())
start++;
// Strip any non digit, non '.' characters from the end
int end = start;
while (end < version.length() && (version[end] == '.' || QChar::fromLatin1(version[end]).isDigit()))
end++;
const QByteArray result = version.mid(start, end-start);
const QList tokens = result.split('.');
const qint64 major = tokens.at(0).toInt();
const qint64 minor = tokens.count() > 1 ? tokens.at(1).toInt() : 0;
const qint64 patch = tokens.count() > 2 ? tokens.at(2).toInt() : 0;
return kVersionNumber(major, minor, patch);
}
static qint64 getXServerVersion()
{
qint64 major, minor, patch;
major = 0;
minor = 0;
patch = 0;
if (xcb_connection_t *c = connection()) {
auto setup = xcb_get_setup(c);
const QByteArray vendorName(xcb_setup_vendor(setup), xcb_setup_vendor_length(setup));
if (vendorName.contains("X.Org")) {
const int release = setup->release_number;
major = (release / 10000000);
minor = (release / 100000) % 100;
patch = (release / 1000) % 100;
}
}
return kVersionNumber(major, minor, patch);
}
static qint64 getKernelVersion()
{
struct utsname name;
uname(&name);
if (qstrcmp(name.sysname, "Linux") == 0)
return parseVersionString(name.release);
return 0;
}
// Extracts the portion of a string that matches a regular expression
-static QString extract(const QString &string, const QString &match, int offset = 0)
+static QString extract(const QString &text, const QString &pattern)
{
- QString result;
- QRegExp rx(match);
- int pos = rx.indexIn(string, offset);
- if (pos != -1)
- result = string.mid(pos, rx.matchedLength());
- return result;
+ const QRegularExpression regexp(pattern);
+ const QRegularExpressionMatch match = regexp.match(text);
+ if (!match.hasMatch())
+ return QString();
+ return match.captured();
}
static ChipClass detectRadeonClass(const QByteArray &chipset)
{
if (chipset.isEmpty())
return UnknownRadeon;
if (chipset.contains("R100") ||
chipset.contains("RV100") ||
chipset.contains("RS100"))
return R100;
if (chipset.contains("RV200") ||
chipset.contains("RS200") ||
chipset.contains("R200") ||
chipset.contains("RV250") ||
chipset.contains("RS300") ||
chipset.contains("RV280"))
return R200;
if (chipset.contains("R300") ||
chipset.contains("R350") ||
chipset.contains("R360") ||
chipset.contains("RV350") ||
chipset.contains("RV370") ||
chipset.contains("RV380"))
return R300;
if (chipset.contains("R420") ||
chipset.contains("R423") ||
chipset.contains("R430") ||
chipset.contains("R480") ||
chipset.contains("R481") ||
chipset.contains("RV410") ||
chipset.contains("RS400") ||
chipset.contains("RC410") ||
chipset.contains("RS480") ||
chipset.contains("RS482") ||
chipset.contains("RS600") ||
chipset.contains("RS690") ||
chipset.contains("RS740"))
return R400;
if (chipset.contains("RV515") ||
chipset.contains("R520") ||
chipset.contains("RV530") ||
chipset.contains("R580") ||
chipset.contains("RV560") ||
chipset.contains("RV570"))
return R500;
if (chipset.contains("R600") ||
chipset.contains("RV610") ||
chipset.contains("RV630") ||
chipset.contains("RV670") ||
chipset.contains("RV620") ||
chipset.contains("RV635") ||
chipset.contains("RS780") ||
chipset.contains("RS880"))
return R600;
if (chipset.contains("R700") ||
chipset.contains("RV770") ||
chipset.contains("RV730") ||
chipset.contains("RV710") ||
chipset.contains("RV740"))
return R700;
if (chipset.contains("EVERGREEN") || // Not an actual chipset, but returned by R600G in 7.9
chipset.contains("CEDAR") ||
chipset.contains("REDWOOD") ||
chipset.contains("JUNIPER") ||
chipset.contains("CYPRESS") ||
chipset.contains("HEMLOCK") ||
chipset.contains("PALM"))
return Evergreen;
if (chipset.contains("SUMO") ||
chipset.contains("SUMO2") ||
chipset.contains("BARTS") ||
chipset.contains("TURKS") ||
chipset.contains("CAICOS") ||
chipset.contains("CAYMAN"))
return NorthernIslands;
if (chipset.contains("TAHITI") ||
chipset.contains("PITCAIRN") ||
chipset.contains("VERDE") ||
chipset.contains("OLAND") ||
chipset.contains("HAINAN")) {
return SouthernIslands;
}
if (chipset.contains("BONAIRE") ||
chipset.contains("KAVERI") ||
chipset.contains("KABINI") ||
chipset.contains("HAWAII") ||
chipset.contains("MULLINS")) {
return SeaIslands;
}
if (chipset.contains("TONGA") ||
chipset.contains("TOPAZ") ||
chipset.contains("FIJI") ||
chipset.contains("CARRIZO") ||
chipset.contains("STONEY")) {
return VolcanicIslands;
}
if (chipset.contains("POLARIS10") ||
chipset.contains("POLARIS11") ||
chipset.contains("POLARIS12") ||
chipset.contains("VEGAM")) {
return ArcticIslands;
}
if (chipset.contains("VEGA10") ||
chipset.contains("VEGA12") ||
chipset.contains("VEGA20") ||
chipset.contains("RAVEN") ||
chipset.contains("RAVEN2") ||
chipset.contains("RENOIR") ||
chipset.contains("ARCTURUS")) {
return Vega;
}
if (chipset.contains("NAVI10") ||
chipset.contains("NAVI12") ||
chipset.contains("NAVI14")) {
return Navi;
}
const QString chipset16 = QString::fromLatin1(chipset);
QString name = extract(chipset16, QStringLiteral("HD [0-9]{4}")); // HD followed by a space and 4 digits
if (!name.isEmpty()) {
const int id = name.rightRef(4).toInt();
if (id == 6250 || id == 6310) // Palm
return Evergreen;
if (id >= 6000 && id < 7000)
return NorthernIslands; // HD 6xxx
if (id >= 5000 && id < 6000)
return Evergreen; // HD 5xxx
if (id >= 4000 && id < 5000)
return R700; // HD 4xxx
if (id >= 2000 && id < 4000) // HD 2xxx/3xxx
return R600;
return UnknownRadeon;
}
name = extract(chipset16, QStringLiteral("X[0-9]{3,4}")); // X followed by 3-4 digits
if (!name.isEmpty()) {
const int id = name.midRef(1, -1).toInt();
// X1xxx
if (id >= 1300)
return R500;
// X7xx, X8xx, X12xx, 2100
if ((id >= 700 && id < 1000) || id >= 1200)
return R400;
// X200, X3xx, X5xx, X6xx, X10xx, X11xx
if ((id >= 300 && id < 700) || (id >= 1000 && id < 1200))
return R300;
return UnknownRadeon;
}
name = extract(chipset16, QStringLiteral("\\b[0-9]{4}\\b")); // A group of 4 digits
if (!name.isEmpty()) {
const int id = name.toInt();
// 7xxx
if (id >= 7000 && id < 8000)
return R100;
// 8xxx, 9xxx
if (id >= 8000 && id < 9500)
return R200;
// 9xxx
if (id >= 9500)
return R300;
if (id == 2100)
return R400;
}
return UnknownRadeon;
}
static ChipClass detectNVidiaClass(const QString &chipset)
{
QString name = extract(chipset, QStringLiteral("\\bNV[0-9,A-F]{2}\\b")); // NV followed by two hexadecimal digits
if (!name.isEmpty()) {
const int id = chipset.midRef(2, -1).toInt(nullptr, 16); // Strip the 'NV' from the id
switch(id & 0xf0) {
case 0x00:
case 0x10:
return NV10;
case 0x20:
return NV20;
case 0x30:
return NV30;
case 0x40:
case 0x60:
return NV40;
case 0x50:
case 0x80:
case 0x90:
case 0xA0:
return G80;
default:
return UnknownNVidia;
}
}
if (chipset.contains(QLatin1String("GeForce2")) || chipset.contains(QLatin1String("GeForce 256")))
return NV10;
if (chipset.contains(QLatin1String("GeForce3")))
return NV20;
if (chipset.contains(QLatin1String("GeForce4"))) {
if (chipset.contains(QLatin1String("MX 420")) ||
chipset.contains(QLatin1String("MX 440")) || // including MX 440SE
chipset.contains(QLatin1String("MX 460")) ||
chipset.contains(QLatin1String("MX 4000")) ||
chipset.contains(QLatin1String("PCX 4300")))
return NV10;
return NV20;
}
// GeForce 5,6,7,8,9
name = extract(chipset, QStringLiteral("GeForce (FX |PCX |Go )?\\d{4}(M|\\b)")).trimmed();
if (!name.isEmpty()) {
if (!name[name.length() - 1].isDigit())
name.chop(1);
const int id = name.rightRef(4).toInt();
if (id < 6000)
return NV30;
if (id >= 6000 && id < 8000)
return NV40;
if (id >= 8000)
return G80;
return UnknownNVidia;
}
// GeForce 100/200/300/400/500
name = extract(chipset, QStringLiteral("GeForce (G |GT |GTX |GTS )?\\d{3}(M|\\b)")).trimmed();
if (!name.isEmpty()) {
if (!name[name.length() - 1].isDigit())
name.chop(1);
const int id = name.rightRef(3).toInt();
if (id >= 100 && id < 600) {
if (id >= 400)
return GF100;
return G80;
}
return UnknownNVidia;
}
return UnknownNVidia;
}
static inline ChipClass detectNVidiaClass(const QByteArray &chipset)
{
return detectNVidiaClass(QString::fromLatin1(chipset));
}
static ChipClass detectIntelClass(const QByteArray &chipset)
{
// see mesa repository: src/mesa/drivers/dri/intel/intel_context.c
// GL 1.3, DX8? SM ?
if (chipset.contains("845G") ||
chipset.contains("830M") ||
chipset.contains("852GM/855GM") ||
chipset.contains("865G"))
return I8XX;
// GL 1.4, DX 9.0, SM 2.0
if (chipset.contains("915G") ||
chipset.contains("E7221G") ||
chipset.contains("915GM") ||
chipset.contains("945G") || // DX 9.0c
chipset.contains("945GM") ||
chipset.contains("945GME") ||
chipset.contains("Q33") || // GL1.5
chipset.contains("Q35") ||
chipset.contains("G33") ||
chipset.contains("965Q") || // GMA 3000, but apparently considered gen 4 by the driver
chipset.contains("946GZ") || // GMA 3000, but apparently considered gen 4 by the driver
chipset.contains("IGD"))
return I915;
// GL 2.0, DX 9.0c, SM 3.0
if (chipset.contains("965G") ||
chipset.contains("G45/G43") || // SM 4.0
chipset.contains("965GM") || // GL 2.1
chipset.contains("965GME/GLE") ||
chipset.contains("GM45") ||
chipset.contains("Q45/Q43") ||
chipset.contains("G41") ||
chipset.contains("B43") ||
chipset.contains("Ironlake"))
return I965;
// GL 3.1, CL 1.1, DX 10.1
if (chipset.contains("Sandybridge")) {
return SandyBridge;
}
// GL4.0, CL1.1, DX11, SM 5.0
if (chipset.contains("Ivybridge")) {
return IvyBridge;
}
// GL4.0, CL1.2, DX11.1, SM 5.0
if (chipset.contains("Haswell")) {
return Haswell;
}
return UnknownIntel;
}
static ChipClass detectQualcommClass(const QByteArray &chipClass)
{
if (!chipClass.contains("Adreno")) {
return UnknownChipClass;
}
const auto parts = chipClass.split(' ');
if (parts.count() < 3) {
return UnknownAdreno;
}
bool ok = false;
const int value = parts.at(2).toInt(&ok);
if (ok) {
if (value >= 100 && value < 200) {
return Adreno1XX;
}
if (value >= 200 && value < 300) {
return Adreno2XX;
}
if (value >= 300 && value < 400) {
return Adreno3XX;
}
if (value >= 400 && value < 500) {
return Adreno4XX;
}
if (value >= 500 && value < 600) {
return Adreno5XX;
}
}
return UnknownAdreno;
}
QString GLPlatform::versionToString(qint64 version)
{
return QString::fromLatin1(versionToString8(version));
}
QByteArray GLPlatform::versionToString8(qint64 version)
{
int major = (version >> 32);
int minor = (version >> 16) & 0xffff;
int patch = version & 0xffff;
QByteArray string = QByteArray::number(major) + '.' + QByteArray::number(minor);
if (patch != 0)
string += '.' + QByteArray::number(patch);
return string;
}
QString GLPlatform::driverToString(Driver driver)
{
return QString::fromLatin1(driverToString8(driver));
}
QByteArray GLPlatform::driverToString8(Driver driver)
{
switch(driver) {
case Driver_R100:
return QByteArrayLiteral("Radeon");
case Driver_R200:
return QByteArrayLiteral("R200");
case Driver_R300C:
return QByteArrayLiteral("R300C");
case Driver_R300G:
return QByteArrayLiteral("R300G");
case Driver_R600C:
return QByteArrayLiteral("R600C");
case Driver_R600G:
return QByteArrayLiteral("R600G");
case Driver_RadeonSI:
return QByteArrayLiteral("RadeonSI");
case Driver_Nouveau:
return QByteArrayLiteral("Nouveau");
case Driver_Intel:
return QByteArrayLiteral("Intel");
case Driver_NVidia:
return QByteArrayLiteral("NVIDIA");
case Driver_Catalyst:
return QByteArrayLiteral("Catalyst");
case Driver_Swrast:
return QByteArrayLiteral("Software rasterizer");
case Driver_Softpipe:
return QByteArrayLiteral("softpipe");
case Driver_Llvmpipe:
return QByteArrayLiteral("LLVMpipe");
case Driver_VirtualBox:
return QByteArrayLiteral("VirtualBox (Chromium)");
case Driver_VMware:
return QByteArrayLiteral("VMware (SVGA3D)");
case Driver_Qualcomm:
return QByteArrayLiteral("Qualcomm");
case Driver_Virgl:
return QByteArrayLiteral("Virgl (virtio-gpu, Qemu/KVM guest)");
default:
return QByteArrayLiteral("Unknown");
}
}
QString GLPlatform::chipClassToString(ChipClass chipClass)
{
return QString::fromLatin1(chipClassToString8(chipClass));
}
QByteArray GLPlatform::chipClassToString8(ChipClass chipClass)
{
switch(chipClass) {
case R100:
return QByteArrayLiteral("R100");
case R200:
return QByteArrayLiteral("R200");
case R300:
return QByteArrayLiteral("R300");
case R400:
return QByteArrayLiteral("R400");
case R500:
return QByteArrayLiteral("R500");
case R600:
return QByteArrayLiteral("R600");
case R700:
return QByteArrayLiteral("R700");
case Evergreen:
return QByteArrayLiteral("EVERGREEN");
case NorthernIslands:
return QByteArrayLiteral("Northern Islands");
case SouthernIslands:
return QByteArrayLiteral("Southern Islands");
case SeaIslands:
return QByteArrayLiteral("Sea Islands");
case VolcanicIslands:
return QByteArrayLiteral("Volcanic Islands");
case ArcticIslands:
return QByteArrayLiteral("Arctic Islands");
case Vega:
return QByteArrayLiteral("Vega");
case Navi:
return QByteArrayLiteral("Navi");
case NV10:
return QByteArrayLiteral("NV10");
case NV20:
return QByteArrayLiteral("NV20");
case NV30:
return QByteArrayLiteral("NV30");
case NV40:
return QByteArrayLiteral("NV40/G70");
case G80:
return QByteArrayLiteral("G80/G90");
case GF100:
return QByteArrayLiteral("GF100");
case I8XX:
return QByteArrayLiteral("i830/i835");
case I915:
return QByteArrayLiteral("i915/i945");
case I965:
return QByteArrayLiteral("i965");
case SandyBridge:
return QByteArrayLiteral("SandyBridge");
case IvyBridge:
return QByteArrayLiteral("IvyBridge");
case Haswell:
return QByteArrayLiteral("Haswell");
case Adreno1XX:
return QByteArrayLiteral("Adreno 1xx series");
case Adreno2XX:
return QByteArrayLiteral("Adreno 2xx series");
case Adreno3XX:
return QByteArrayLiteral("Adreno 3xx series");
case Adreno4XX:
return QByteArrayLiteral("Adreno 4xx series");
case Adreno5XX:
return QByteArrayLiteral("Adreno 5xx series");
default:
return QByteArrayLiteral("Unknown");
}
}
// -------
GLPlatform::GLPlatform()
: m_driver(Driver_Unknown),
m_chipClass(UnknownChipClass),
m_recommendedCompositor(XRenderCompositing),
m_glVersion(0),
m_glslVersion(0),
m_mesaVersion(0),
m_driverVersion(0),
m_galliumVersion(0),
m_serverVersion(0),
m_kernelVersion(0),
m_looseBinding(false),
m_supportsGLSL(false),
m_limitedGLSL(false),
m_textureNPOT(false),
m_limitedNPOT(false),
m_virtualMachine(false),
m_preferBufferSubData(false),
m_platformInterface(NoOpenGLPlatformInterface),
m_gles(false)
{
}
GLPlatform::~GLPlatform()
{
}
void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
{
m_platformInterface = platformInterface;
m_vendor = (const char*)glGetString(GL_VENDOR);
m_renderer = (const char*)glGetString(GL_RENDERER);
m_version = (const char*)glGetString(GL_VERSION);
// Parse the OpenGL version
const QList versionTokens = m_version.split(' ');
if (versionTokens.count() > 0) {
const QByteArray version = QByteArray(m_version);
m_glVersion = parseVersionString(version);
if (platformInterface == EglPlatformInterface) {
// only EGL can have OpenGLES, GLX is OpenGL only
if (version.startsWith("OpenGL ES")) {
// from GLES 2: "Returns a version or release number of the form OpenGLES."
// from GLES 3: "Returns a version or release number." and "The version number uses one of these forms: major_number.minor_number major_number.minor_number.release_number"
m_gles = true;
}
}
}
if (!isGLES() && m_glVersion >= kVersionNumber(3, 0)) {
int count;
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (int i = 0; i < count; i++) {
const char *name = (const char *) glGetStringi(GL_EXTENSIONS, i);
m_extensions.insert(name);
}
} else {
const QByteArray extensions = (const char *) glGetString(GL_EXTENSIONS);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
const QList extensionsList = extensions.split(' ');
m_extensions = {extensionsList.constBegin(), extensionsList.constEnd()};
#else
m_extensions = extensions.split(' ').toSet();
#endif
}
// Parse the Mesa version
const int mesaIndex = versionTokens.indexOf("Mesa");
if (mesaIndex != -1) {
const QByteArray &version = versionTokens.at(mesaIndex + 1);
m_mesaVersion = parseVersionString(version);
}
if (isGLES()) {
m_supportsGLSL = true;
m_textureNPOT = true;
} else {
m_supportsGLSL = m_extensions.contains("GL_ARB_shader_objects") &&
m_extensions.contains("GL_ARB_fragment_shader") &&
m_extensions.contains("GL_ARB_vertex_shader");
m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two");
}
m_serverVersion = getXServerVersion();
m_kernelVersion = getKernelVersion();
m_glslVersion = 0;
m_glsl_version.clear();
if (m_supportsGLSL) {
// Parse the GLSL version
m_glsl_version = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
m_glslVersion = parseVersionString(m_glsl_version);
}
m_chipset = QByteArrayLiteral("Unknown");
m_preferBufferSubData = false;
// Mesa classic drivers
// ====================================================
// Radeon
if (m_renderer.startsWith("Mesa DRI R")) {
// Sample renderer string: Mesa DRI R600 (RV740 94B3) 20090101 x86/MMX/SSE2 TCL DRI2
const QList tokens = m_renderer.split(' ');
const QByteArray &chipClass = tokens.at(2);
m_chipset = tokens.at(3).mid(1, -1); // Strip the leading '('
if (chipClass == "R100")
// Vendor: Tungsten Graphics, Inc.
m_driver = Driver_R100;
else if (chipClass == "R200")
// Vendor: Tungsten Graphics, Inc.
m_driver = Driver_R200;
else if (chipClass == "R300")
// Vendor: DRI R300 Project
m_driver = Driver_R300C;
else if (chipClass == "R600")
// Vendor: Advanced Micro Devices, Inc.
m_driver = Driver_R600C;
m_chipClass = detectRadeonClass(m_chipset);
}
// Intel
else if (m_renderer.contains("Intel")) {
// Vendor: Tungsten Graphics, Inc.
// Sample renderer string: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100328 2010Q1
QByteArray chipset;
if (m_renderer.startsWith("Intel(R) Integrated Graphics Device"))
chipset = "IGD";
else
chipset = m_renderer;
m_driver = Driver_Intel;
m_chipClass = detectIntelClass(chipset);
}
// Properietary drivers
// ====================================================
else if (m_vendor == "ATI Technologies Inc.") {
m_chipClass = detectRadeonClass(m_renderer);
m_driver = Driver_Catalyst;
if (versionTokens.count() > 1 && versionTokens.at(2)[0] == '(')
m_driverVersion = parseVersionString(versionTokens.at(1));
else if (versionTokens.count() > 0)
m_driverVersion = parseVersionString(versionTokens.at(0));
else
m_driverVersion = 0;
}
else if (m_vendor == "NVIDIA Corporation") {
m_chipClass = detectNVidiaClass(m_renderer);
m_driver = Driver_NVidia;
int index = versionTokens.indexOf("NVIDIA");
if (versionTokens.count() > index)
m_driverVersion = parseVersionString(versionTokens.at(index + 1));
else
m_driverVersion = 0;
}
else if (m_vendor == "Qualcomm") {
m_driver = Driver_Qualcomm;
m_chipClass = detectQualcommClass(m_renderer);
}
else if (m_renderer == "Software Rasterizer") {
m_driver = Driver_Swrast;
}
// Virtual Hardware
// ====================================================
else if (m_vendor == "Humper" && m_renderer == "Chromium") {
// Virtual Box
m_driver = Driver_VirtualBox;
const int index = versionTokens.indexOf("Chromium");
if (versionTokens.count() > index)
m_driverVersion = parseVersionString(versionTokens.at(index + 1));
else
m_driverVersion = 0;
}
// Gallium drivers
// ====================================================
else {
const QList tokens = m_renderer.split(' ');
if (m_renderer.contains("Gallium")) {
// Sample renderer string: Gallium 0.4 on AMD RV740
m_galliumVersion = parseVersionString(tokens.at(1));
m_chipset = (tokens.at(3) == "AMD" || tokens.at(3) == "ATI") ?
tokens.at(4) : tokens.at(3);
}
else {
// The renderer string does not contain "Gallium" anymore.
m_chipset = tokens.at(0);
// We don't know the actual version anymore, but it's at least 0.4.
m_galliumVersion = kVersionNumber(0, 4, 0);
}
// R300G
if (m_vendor == QByteArrayLiteral("X.Org R300 Project")) {
m_chipClass = detectRadeonClass(m_chipset);
m_driver = Driver_R300G;
}
// R600G
else if (m_vendor == "X.Org" &&
(m_renderer.contains("R6") ||
m_renderer.contains("R7") ||
m_renderer.contains("RV6") ||
m_renderer.contains("RV7") ||
m_renderer.contains("RS780") ||
m_renderer.contains("RS880") ||
m_renderer.contains("CEDAR") ||
m_renderer.contains("REDWOOD") ||
m_renderer.contains("JUNIPER") ||
m_renderer.contains("CYPRESS") ||
m_renderer.contains("HEMLOCK") ||
m_renderer.contains("PALM") ||
m_renderer.contains("EVERGREEN") ||
m_renderer.contains("SUMO") ||
m_renderer.contains("SUMO2") ||
m_renderer.contains("BARTS") ||
m_renderer.contains("TURKS") ||
m_renderer.contains("CAICOS") ||
m_renderer.contains("CAYMAN"))) {
m_chipClass = detectRadeonClass(m_chipset);
m_driver = Driver_R600G;
}
// RadeonSI
else if (m_vendor == "X.Org" &&
(m_renderer.contains("TAHITI") ||
m_renderer.contains("PITCAIRN") ||
m_renderer.contains("VERDE") ||
m_renderer.contains("OLAND") ||
m_renderer.contains("HAINAN") ||
m_renderer.contains("BONAIRE") ||
m_renderer.contains("KAVERI") ||
m_renderer.contains("KABINI") ||
m_renderer.contains("HAWAII") ||
m_renderer.contains("MULLINS") ||
m_renderer.contains("TOPAZ") ||
m_renderer.contains("TONGA") ||
m_renderer.contains("FIJI") ||
m_renderer.contains("CARRIZO") ||
m_renderer.contains("STONEY") ||
m_renderer.contains("POLARIS10") ||
m_renderer.contains("POLARIS11") ||
m_renderer.contains("POLARIS12") ||
m_renderer.contains("VEGAM") ||
m_renderer.contains("VEGA10") ||
m_renderer.contains("VEGA12") ||
m_renderer.contains("VEGA20") ||
m_renderer.contains("RAVEN") ||
m_renderer.contains("RAVEN2") ||
m_renderer.contains("RENOIR") ||
m_renderer.contains("ARCTURUS") ||
m_renderer.contains("NAVI10") ||
m_renderer.contains("NAVI12") ||
m_renderer.contains("NAVI14"))) {
m_chipClass = detectRadeonClass(m_renderer);
m_driver = Driver_RadeonSI;
}
// Nouveau
else if (m_vendor == "nouveau") {
m_chipClass = detectNVidiaClass(m_chipset);
m_driver = Driver_Nouveau;
}
// softpipe
else if (m_vendor == "VMware, Inc." && m_chipset == "softpipe" ) {
m_driver = Driver_Softpipe;
}
// llvmpipe
else if (m_vendor == "VMware, Inc." && m_chipset == "llvmpipe") {
m_driver = Driver_Llvmpipe;
}
// SVGA3D
else if (m_vendor == "VMware, Inc." && m_chipset.contains("SVGA3D")) {
m_driver = Driver_VMware;
}
// virgl
else if (m_renderer == "virgl") {
m_driver = Driver_Virgl;
}
}
// Driver/GPU specific features
// ====================================================
if (isRadeon()) {
// R200 technically has a programmable pipeline, but since it's SM 1.4,
// it's too limited to to be of any practical value to us.
if (m_chipClass < R300)
m_supportsGLSL = false;
m_limitedGLSL = false;
m_limitedNPOT = false;
if (m_chipClass < R600) {
if (driver() == Driver_Catalyst)
m_textureNPOT = m_limitedNPOT = false; // Software fallback
else if (driver() == Driver_R300G)
m_limitedNPOT = m_textureNPOT;
m_limitedGLSL = m_supportsGLSL;
}
if (m_chipClass < R300) {
// fallback to XRender for R100 and R200
m_recommendedCompositor = XRenderCompositing;
} else if (m_chipClass < R600) {
// XRender due to NPOT limitations not supported by KWin's shaders
m_recommendedCompositor = XRenderCompositing;
} else {
m_recommendedCompositor = OpenGL2Compositing;
}
if (driver() == Driver_R600G ||
(driver() == Driver_R600C && m_renderer.contains("DRI2"))) {
m_looseBinding = true;
}
}
if (isNvidia()) {
if (m_driver == Driver_NVidia && m_chipClass < NV40)
m_supportsGLSL = false; // High likelihood of software emulation
if (m_driver == Driver_NVidia) {
m_looseBinding = true;
m_preferBufferSubData = true;
}
if (m_chipClass < NV40) {
m_recommendedCompositor = XRenderCompositing;
} else {
m_recommendedCompositor = OpenGL2Compositing;
}
m_limitedNPOT = m_textureNPOT && m_chipClass < NV40;
m_limitedGLSL = m_supportsGLSL && m_chipClass < G80;
}
if (isIntel()) {
if (m_chipClass < I915)
m_supportsGLSL = false;
m_limitedGLSL = m_supportsGLSL && m_chipClass < I965;
// see https://bugs.freedesktop.org/show_bug.cgi?id=80349#c1
m_looseBinding = false;
if (m_chipClass < I915) {
m_recommendedCompositor = XRenderCompositing;
} else {
m_recommendedCompositor = OpenGL2Compositing;
}
}
if (isMesaDriver() && platformInterface == EglPlatformInterface) {
// According to the reference implementation in
// mesa/demos/src/egl/opengles1/texture_from_pixmap
// the mesa egl implementation does not require a strict binding (so far).
m_looseBinding = true;
}
if (isSoftwareEmulation()) {
if (m_driver < Driver_Llvmpipe) {
// we recommend XRender
m_recommendedCompositor = XRenderCompositing;
// Software emulation does not provide GLSL
m_limitedGLSL = m_supportsGLSL = false;
} else {
// llvmpipe does support GLSL
m_recommendedCompositor = OpenGL2Compositing;
m_limitedGLSL = false;
m_supportsGLSL = true;
}
}
if (m_driver == Driver_Qualcomm) {
if (m_chipClass == Adreno1XX) {
m_recommendedCompositor = NoCompositing;
} else {
// all other drivers support at least GLES 2
m_recommendedCompositor = OpenGL2Compositing;
}
}
if (m_chipClass == UnknownChipClass && m_driver == Driver_Unknown) {
// we don't know the hardware. Let's be optimistic and assume OpenGL compatible hardware
m_recommendedCompositor = OpenGL2Compositing;
m_supportsGLSL = true;
}
if (isVirtualBox()) {
m_virtualMachine = true;
m_recommendedCompositor = OpenGL2Compositing;
}
if (isVMware()) {
m_virtualMachine = true;
m_recommendedCompositor = OpenGL2Compositing;
}
if (m_driver == Driver_Virgl) {
m_virtualMachine = true;
m_recommendedCompositor = OpenGL2Compositing;
}
// and force back to shader supported on gles, we wouldn't have got a context if not supported
if (isGLES()) {
m_supportsGLSL = true;
m_limitedGLSL = false;
}
}
static void print(const QByteArray &label, const QByteArray &setting)
{
std::cout << std::setw(40) << std::left
<< label.data() << setting.data() << std::endl;
}
void GLPlatform::printResults() const
{
print(QByteArrayLiteral("OpenGL vendor string:"), m_vendor);
print(QByteArrayLiteral("OpenGL renderer string:"), m_renderer);
print(QByteArrayLiteral("OpenGL version string:"), m_version);
if (m_supportsGLSL)
print(QByteArrayLiteral("OpenGL shading language version string:"), m_glsl_version);
print(QByteArrayLiteral("Driver:"), driverToString8(m_driver));
if (!isMesaDriver())
print(QByteArrayLiteral("Driver version:"), versionToString8(m_driverVersion));
print(QByteArrayLiteral("GPU class:"), chipClassToString8(m_chipClass));
print(QByteArrayLiteral("OpenGL version:"), versionToString8(m_glVersion));
if (m_supportsGLSL)
print(QByteArrayLiteral("GLSL version:"), versionToString8(m_glslVersion));
if (isMesaDriver())
print(QByteArrayLiteral("Mesa version:"), versionToString8(mesaVersion()));
//if (galliumVersion() > 0)
// print("Gallium version:", versionToString(m_galliumVersion));
if (serverVersion() > 0)
print(QByteArrayLiteral("X server version:"), versionToString8(m_serverVersion));
if (kernelVersion() > 0)
print(QByteArrayLiteral("Linux kernel version:"), versionToString8(m_kernelVersion));
print(QByteArrayLiteral("Requires strict binding:"), !m_looseBinding ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
print(QByteArrayLiteral("GLSL shaders:"), m_supportsGLSL ? (m_limitedGLSL ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Texture NPOT support:"), m_textureNPOT ? (m_limitedNPOT ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no"));
print(QByteArrayLiteral("Virtual Machine:"), m_virtualMachine ? QByteArrayLiteral("yes") : QByteArrayLiteral("no"));
}
bool GLPlatform::supports(GLFeature feature) const
{
switch(feature) {
case LooseBinding:
return m_looseBinding;
case GLSL:
return m_supportsGLSL;
case LimitedGLSL:
return m_limitedGLSL;
case TextureNPOT:
return m_textureNPOT;
case LimitedNPOT:
return m_limitedNPOT;
default:
return false;
}
}
qint64 GLPlatform::glVersion() const
{
return m_glVersion;
}
qint64 GLPlatform::glslVersion() const
{
return m_glslVersion;
}
qint64 GLPlatform::mesaVersion() const
{
return m_mesaVersion;
}
qint64 GLPlatform::galliumVersion() const
{
return m_galliumVersion;
}
qint64 GLPlatform::serverVersion() const
{
return m_serverVersion;
}
qint64 GLPlatform::kernelVersion() const
{
return m_kernelVersion;
}
qint64 GLPlatform::driverVersion() const
{
if (isMesaDriver())
return mesaVersion();
return m_driverVersion;
}
Driver GLPlatform::driver() const
{
return m_driver;
}
ChipClass GLPlatform::chipClass() const
{
return m_chipClass;
}
bool GLPlatform::isMesaDriver() const
{
return mesaVersion() > 0;
}
bool GLPlatform::isGalliumDriver() const
{
return galliumVersion() > 0;
}
bool GLPlatform::isRadeon() const
{
return m_chipClass >= R100 && m_chipClass <= UnknownRadeon;
}
bool GLPlatform::isNvidia() const
{
return m_chipClass >= NV10 && m_chipClass <= UnknownNVidia;
}
bool GLPlatform::isIntel() const
{
return m_chipClass >= I8XX && m_chipClass <= UnknownIntel;
}
bool GLPlatform::isVirtualBox() const
{
return m_driver == Driver_VirtualBox;
}
bool GLPlatform::isVMware() const
{
return m_driver == Driver_VMware;
}
bool GLPlatform::isVirgl() const
{
return m_driver == Driver_Virgl;
}
bool GLPlatform::isSoftwareEmulation() const
{
return m_driver == Driver_Softpipe || m_driver == Driver_Swrast || m_driver == Driver_Llvmpipe;
}
bool GLPlatform::isAdreno() const
{
return m_chipClass >= Adreno1XX && m_chipClass <= UnknownAdreno;
}
const QByteArray &GLPlatform::glRendererString() const
{
return m_renderer;
}
const QByteArray &GLPlatform::glVendorString() const
{
return m_vendor;
}
const QByteArray &GLPlatform::glVersionString() const
{
return m_version;
}
const QByteArray &GLPlatform::glShadingLanguageVersionString() const
{
return m_glsl_version;
}
bool GLPlatform::isLooseBinding() const
{
return m_looseBinding;
}
bool GLPlatform::isVirtualMachine() const
{
return m_virtualMachine;
}
CompositingType GLPlatform::recommendedCompositor() const
{
return m_recommendedCompositor;
}
bool GLPlatform::preferBufferSubData() const
{
return m_preferBufferSubData;
}
OpenGLPlatformInterface GLPlatform::platformInterface() const
{
return m_platformInterface;
}
bool GLPlatform::isGLES() const
{
return m_gles;
}
void GLPlatform::cleanup()
{
delete s_platform;
s_platform = nullptr;
}
} // namespace KWin
diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp
index 413b04460..c5e00f06e 100644
--- a/libkwineffects/kwinglutils.cpp
+++ b/libkwineffects/kwinglutils.cpp
@@ -1,2329 +1,2319 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006-2007 Rivo Laks
Copyright (C) 2010, 2011 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 "kwinglutils.h"
// need to call GLTexturePrivate::initStatic()
#include "kwingltexture_p.h"
#include "kwineffects.h"
#include "kwinglplatform.h"
#include "logging_p.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEBUG_GLRENDERTARGET 0
#ifdef __GNUC__
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
#else
# define likely(x) (x)
# define unlikely(x) (x)
#endif
namespace KWin
{
// Variables
// List of all supported GL extensions
static QList glExtensions;
// Functions
void initGL(const std::function &resolveFunction)
{
// Get list of supported OpenGL extensions
if (hasGLVersion(3, 0)) {
int count;
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (int i = 0; i < count; i++) {
const QByteArray name = (const char *) glGetStringi(GL_EXTENSIONS, i);
glExtensions << name;
}
} else
glExtensions = QByteArray((const char*)glGetString(GL_EXTENSIONS)).split(' ');
// handle OpenGL extensions functions
glResolveFunctions(resolveFunction);
GLTexturePrivate::initStatic();
GLRenderTarget::initStatic();
GLVertexBuffer::initStatic();
}
void cleanupGL()
{
ShaderManager::cleanup();
GLTexturePrivate::cleanup();
GLRenderTarget::cleanup();
GLVertexBuffer::cleanup();
GLPlatform::cleanup();
glExtensions.clear();
}
bool hasGLVersion(int major, int minor, int release)
{
return GLPlatform::instance()->glVersion() >= kVersionNumber(major, minor, release);
}
bool hasGLExtension(const QByteArray &extension)
{
return glExtensions.contains(extension);
}
QList openGLExtensions()
{
return glExtensions;
}
static QString formatGLError(GLenum err)
{
switch(err) {
case GL_NO_ERROR: return QStringLiteral("GL_NO_ERROR");
case GL_INVALID_ENUM: return QStringLiteral("GL_INVALID_ENUM");
case GL_INVALID_VALUE: return QStringLiteral("GL_INVALID_VALUE");
case GL_INVALID_OPERATION: return QStringLiteral("GL_INVALID_OPERATION");
case GL_STACK_OVERFLOW: return QStringLiteral("GL_STACK_OVERFLOW");
case GL_STACK_UNDERFLOW: return QStringLiteral("GL_STACK_UNDERFLOW");
case GL_OUT_OF_MEMORY: return QStringLiteral("GL_OUT_OF_MEMORY");
default: return QLatin1String("0x") + QString::number(err, 16);
}
}
bool checkGLError(const char* txt)
{
GLenum err = glGetError();
if (err == GL_CONTEXT_LOST) {
qCWarning(LIBKWINGLUTILS) << "GL error: context lost";
return true;
}
bool hasError = false;
while (err != GL_NO_ERROR) {
qCWarning(LIBKWINGLUTILS) << "GL error (" << txt << "): " << formatGLError(err);
hasError = true;
err = glGetError();
if (err == GL_CONTEXT_LOST) {
qCWarning(LIBKWINGLUTILS) << "GL error: context lost";
break;
}
}
return hasError;
}
//****************************************
// GLShader
//****************************************
GLShader::GLShader(unsigned int flags)
: mValid(false)
, mLocationsResolved(false)
, mExplicitLinking(flags & ExplicitLinking)
{
mProgram = glCreateProgram();
}
GLShader::GLShader(const QString& vertexfile, const QString& fragmentfile, unsigned int flags)
: mValid(false)
, mLocationsResolved(false)
, mExplicitLinking(flags & ExplicitLinking)
{
mProgram = glCreateProgram();
loadFromFiles(vertexfile, fragmentfile);
}
GLShader::~GLShader()
{
if (mProgram) {
glDeleteProgram(mProgram);
}
}
bool GLShader::loadFromFiles(const QString &vertexFile, const QString &fragmentFile)
{
QFile vf(vertexFile);
if (!vf.open(QIODevice::ReadOnly)) {
qCCritical(LIBKWINGLUTILS) << "Couldn't open" << vertexFile << "for reading!";
return false;
}
const QByteArray vertexSource = vf.readAll();
QFile ff(fragmentFile);
if (!ff.open(QIODevice::ReadOnly)) {
qCCritical(LIBKWINGLUTILS) << "Couldn't open" << fragmentFile << "for reading!";
return false;
}
const QByteArray fragmentSource = ff.readAll();
return load(vertexSource, fragmentSource);
}
bool GLShader::link()
{
// Be optimistic
mValid = true;
glLinkProgram(mProgram);
// Get the program info log
int maxLength, length;
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &maxLength);
QByteArray log(maxLength, 0);
glGetProgramInfoLog(mProgram, maxLength, &length, log.data());
// Make sure the program linked successfully
int status;
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
if (status == 0) {
qCCritical(LIBKWINGLUTILS) << "Failed to link shader:" << "\n" << log;
mValid = false;
} else if (length > 0) {
qCDebug(LIBKWINGLUTILS) << "Shader link log:" << log;
}
return mValid;
}
const QByteArray GLShader::prepareSource(GLenum shaderType, const QByteArray &source) const
{
Q_UNUSED(shaderType)
// Prepare the source code
QByteArray ba;
if (GLPlatform::instance()->isGLES() && GLPlatform::instance()->glslVersion() < kVersionNumber(3, 0)) {
ba.append("precision highp float;\n");
}
- if (ShaderManager::instance()->isShaderDebug()) {
- ba.append("#define KWIN_SHADER_DEBUG 1\n");
- }
ba.append(source);
if (GLPlatform::instance()->isGLES() && GLPlatform::instance()->glslVersion() >= kVersionNumber(3, 0)) {
ba.replace("#version 140", "#version 300 es\n\nprecision highp float;\n");
}
return ba;
}
bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &source) const
{
GLuint shader = glCreateShader(shaderType);
QByteArray preparedSource = prepareSource(shaderType, source);
const char* src = preparedSource.constData();
glShaderSource(shader, 1, &src, nullptr);
// Compile the shader
glCompileShader(shader);
// Get the shader info log
int maxLength, length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
QByteArray log(maxLength, 0);
glGetShaderInfoLog(shader, maxLength, &length, log.data());
// Check the status
int status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
const char *typeName = (shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment");
qCCritical(LIBKWINGLUTILS) << "Failed to compile" << typeName << "shader:" << "\n" << log;
} else if (length > 0)
qCDebug(LIBKWINGLUTILS) << "Shader compile log:" << log;
if (status != 0)
glAttachShader(program, shader);
glDeleteShader(shader);
return status != 0;
}
bool GLShader::load(const QByteArray &vertexSource, const QByteArray &fragmentSource)
{
// Make sure shaders are actually supported
if (!(GLPlatform::instance()->supports(GLSL) &&
// we lack shader branching for Texture2DRectangle everywhere - and it's probably not worth it
GLPlatform::instance()->supports(TextureNPOT))) {
qCCritical(LIBKWINGLUTILS) << "Shaders are not supported";
return false;
}
mValid = false;
// Compile the vertex shader
if (!vertexSource.isEmpty()) {
bool success = compile(mProgram, GL_VERTEX_SHADER, vertexSource);
if (!success)
return false;
}
// Compile the fragment shader
if (!fragmentSource.isEmpty()) {
bool success = compile(mProgram, GL_FRAGMENT_SHADER, fragmentSource);
if (!success)
return false;
}
if (mExplicitLinking)
return true;
// link() sets mValid
return link();
}
void GLShader::bindAttributeLocation(const char *name, int index)
{
glBindAttribLocation(mProgram, index, name);
}
void GLShader::bindFragDataLocation(const char *name, int index)
{
if (!GLPlatform::instance()->isGLES() && (hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_EXT_gpu_shader4"))))
glBindFragDataLocation(mProgram, index, name);
}
void GLShader::bind()
{
glUseProgram(mProgram);
}
void GLShader::unbind()
{
glUseProgram(0);
}
void GLShader::resolveLocations()
{
if (mLocationsResolved)
return;
mMatrixLocation[TextureMatrix] = uniformLocation("textureMatrix");
mMatrixLocation[ProjectionMatrix] = uniformLocation("projection");
mMatrixLocation[ModelViewMatrix] = uniformLocation("modelview");
mMatrixLocation[ModelViewProjectionMatrix] = uniformLocation("modelViewProjectionMatrix");
mMatrixLocation[WindowTransformation] = uniformLocation("windowTransformation");
mMatrixLocation[ScreenTransformation] = uniformLocation("screenTransformation");
mVec2Location[Offset] = uniformLocation("offset");
mVec4Location[ModulationConstant] = uniformLocation("modulation");
mFloatLocation[Saturation] = uniformLocation("saturation");
mColorLocation[Color] = uniformLocation("geometryColor");
mVec4Location[TextureClamp] = uniformLocation("textureClamp");
mLocationsResolved = true;
}
int GLShader::uniformLocation(const char *name)
{
const int location = glGetUniformLocation(mProgram, name);
return location;
}
bool GLShader::setUniform(GLShader::MatrixUniform uniform, const QMatrix4x4 &matrix)
{
resolveLocations();
return setUniform(mMatrixLocation[uniform], matrix);
}
bool GLShader::setUniform(GLShader::Vec2Uniform uniform, const QVector2D &value)
{
resolveLocations();
return setUniform(mVec2Location[uniform], value);
}
bool GLShader::setUniform(GLShader::Vec4Uniform uniform, const QVector4D &value)
{
resolveLocations();
return setUniform(mVec4Location[uniform], value);
}
bool GLShader::setUniform(GLShader::FloatUniform uniform, float value)
{
resolveLocations();
return setUniform(mFloatLocation[uniform], value);
}
bool GLShader::setUniform(GLShader::IntUniform uniform, int value)
{
resolveLocations();
return setUniform(mIntLocation[uniform], value);
}
bool GLShader::setUniform(GLShader::ColorUniform uniform, const QVector4D &value)
{
resolveLocations();
return setUniform(mColorLocation[uniform], value);
}
bool GLShader::setUniform(GLShader::ColorUniform uniform, const QColor &value)
{
resolveLocations();
return setUniform(mColorLocation[uniform], value);
}
bool GLShader::setUniform(const char *name, float value)
{
const int location = uniformLocation(name);
return setUniform(location, value);
}
bool GLShader::setUniform(const char *name, int value)
{
const int location = uniformLocation(name);
return setUniform(location, value);
}
bool GLShader::setUniform(const char *name, const QVector2D& value)
{
const int location = uniformLocation(name);
return setUniform(location, value);
}
bool GLShader::setUniform(const char *name, const QVector3D& value)
{
const int location = uniformLocation(name);
return setUniform(location, value);
}
bool GLShader::setUniform(const char *name, const QVector4D& value)
{
const int location = uniformLocation(name);
return setUniform(location, value);
}
bool GLShader::setUniform(const char *name, const QMatrix4x4& value)
{
const int location = uniformLocation(name);
return setUniform(location, value);
}
bool GLShader::setUniform(const char *name, const QColor& color)
{
const int location = uniformLocation(name);
return setUniform(location, color);
}
bool GLShader::setUniform(int location, float value)
{
if (location >= 0) {
glUniform1f(location, value);
}
return (location >= 0);
}
bool GLShader::setUniform(int location, int value)
{
if (location >= 0) {
glUniform1i(location, value);
}
return (location >= 0);
}
bool GLShader::setUniform(int location, const QVector2D &value)
{
if (location >= 0) {
glUniform2fv(location, 1, (const GLfloat*)&value);
}
return (location >= 0);
}
bool GLShader::setUniform(int location, const QVector3D &value)
{
if (location >= 0) {
glUniform3fv(location, 1, (const GLfloat*)&value);
}
return (location >= 0);
}
bool GLShader::setUniform(int location, const QVector4D &value)
{
if (location >= 0) {
glUniform4fv(location, 1, (const GLfloat*)&value);
}
return (location >= 0);
}
bool GLShader::setUniform(int location, const QMatrix4x4 &value)
{
if (location >= 0) {
GLfloat m[16];
const auto *data = value.constData();
// i is column, j is row for m
for (int i = 0; i < 16; ++i) {
m[i] = data[i];
}
glUniformMatrix4fv(location, 1, GL_FALSE, m);
}
return (location >= 0);
}
bool GLShader::setUniform(int location, const QColor &color)
{
if (location >= 0) {
glUniform4f(location, color.redF(), color.greenF(), color.blueF(), color.alphaF());
}
return (location >= 0);
}
int GLShader::attributeLocation(const char* name)
{
int location = glGetAttribLocation(mProgram, name);
return location;
}
bool GLShader::setAttribute(const char* name, float value)
{
int location = attributeLocation(name);
if (location >= 0) {
glVertexAttrib1f(location, value);
}
return (location >= 0);
}
QMatrix4x4 GLShader::getUniformMatrix4x4(const char* name)
{
int location = uniformLocation(name);
if (location >= 0) {
GLfloat m[16];
glGetnUniformfv(mProgram, location, sizeof(m), m);
QMatrix4x4 matrix(m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14],
m[3], m[7], m[11], m[15]);
matrix.optimize();
return matrix;
} else {
return QMatrix4x4();
}
}
//****************************************
// ShaderManager
//****************************************
ShaderManager *ShaderManager::s_shaderManager = nullptr;
ShaderManager *ShaderManager::instance()
{
if (!s_shaderManager) {
s_shaderManager = new ShaderManager();
}
return s_shaderManager;
}
void ShaderManager::cleanup()
{
delete s_shaderManager;
s_shaderManager = nullptr;
}
ShaderManager::ShaderManager()
{
- m_debug = qstrcmp(qgetenv("KWIN_GL_DEBUG"), "1") == 0;
-
const qint64 coreVersionNumber = GLPlatform::instance()->isGLES() ? kVersionNumber(3, 0) : kVersionNumber(1, 40);
if (GLPlatform::instance()->glslVersion() >= coreVersionNumber) {
m_resourcePath = QStringLiteral(":/effect-shaders-1.40/");
} else {
m_resourcePath = QStringLiteral(":/effect-shaders-1.10/");
}
}
ShaderManager::~ShaderManager()
{
while (!m_boundShaders.isEmpty()) {
popShader();
}
qDeleteAll(m_shaderHash);
m_shaderHash.clear();
}
static bool fuzzyCompare(const QVector4D &lhs, const QVector4D &rhs)
{
const float epsilon = 1.0f / 255.0f;
return lhs[0] >= rhs[0] - epsilon && lhs[0] <= rhs[0] + epsilon &&
lhs[1] >= rhs[1] - epsilon && lhs[1] <= rhs[1] + epsilon &&
lhs[2] >= rhs[2] - epsilon && lhs[2] <= rhs[2] + epsilon &&
lhs[3] >= rhs[3] - epsilon && lhs[3] <= rhs[3] + epsilon;
}
static bool checkPixel(int x, int y, const QVector4D &expected, const char *file, int line)
{
uint8_t data[4];
glReadnPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 4, data);
const QVector4D pixel{data[0] / 255.f, data[1] / 255.f, data[2] / 255.f, data[3] / 255.f};
if (fuzzyCompare(pixel, expected))
return true;
QMessageLogger(file, line, nullptr).warning() << "Pixel was" << pixel << "expected" << expected;
return false;
}
#define CHECK_PIXEL(x, y, expected) \
checkPixel(x, y, expected, __FILE__, __LINE__)
static QVector4D adjustSaturation(const QVector4D &color, float saturation)
{
const float gray = QVector3D::dotProduct(color.toVector3D(), {0.2126, 0.7152, 0.0722});
return QVector4D{gray, gray, gray, color.w()} * (1.0f - saturation) + color * saturation;
}
bool ShaderManager::selfTest()
{
bool pass = true;
if (!GLRenderTarget::supported()) {
qCWarning(LIBKWINGLUTILS) << "Framebuffer objects not supported - skipping shader tests";
return true;
}
if (GLPlatform::instance()->isNvidia() && GLPlatform::instance()->glRendererString().contains("Quadro")) {
qCWarning(LIBKWINGLUTILS) << "Skipping self test as it is reported to return false positive results on Quadro hardware";
return true;
}
if (GLPlatform::instance()->isMesaDriver() && GLPlatform::instance()->mesaVersion() >= kVersionNumber(17, 0)) {
qCWarning(LIBKWINGLUTILS) << "Skipping self test as it is reported to return false positive results on Mesa drivers";
return true;
}
// Create the source texture
QImage image(2, 2, QImage::Format_ARGB32_Premultiplied);
image.setPixel(0, 0, 0xffff0000); // Red
image.setPixel(1, 0, 0xff00ff00); // Green
image.setPixel(0, 1, 0xff0000ff); // Blue
image.setPixel(1, 1, 0xffffffff); // White
GLTexture src(image);
src.setFilter(GL_NEAREST);
// Create the render target
GLTexture dst(GL_RGBA8, 32, 32);
GLRenderTarget fbo(dst);
GLRenderTarget::pushRenderTarget(&fbo);
// Set up the vertex buffer
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
const GLVertexAttrib attribs[] {
{ VA_Position, 2, GL_FLOAT, offsetof(GLVertex2D, position) },
{ VA_TexCoord, 2, GL_FLOAT, offsetof(GLVertex2D, texcoord) },
};
vbo->setAttribLayout(attribs, 2, sizeof(GLVertex2D));
GLVertex2D *verts = (GLVertex2D*) vbo->map(6 * sizeof(GLVertex2D));
verts[0] = GLVertex2D{{0, 0}, {0, 0}}; // Top left
verts[1] = GLVertex2D{{0, 32}, {0, 1}}; // Bottom left
verts[2] = GLVertex2D{{32, 0}, {1, 0}}; // Top right
verts[3] = GLVertex2D{{32, 0}, {1, 0}}; // Top right
verts[4] = GLVertex2D{{0, 32}, {0, 1}}; // Bottom left
verts[5] = GLVertex2D{{32, 32}, {1, 1}}; // Bottom right
vbo->unmap();
vbo->bindArrays();
glViewport(0, 0, 32, 32);
glClearColor(0, 0, 0, 0);
// Set up the projection matrix
QMatrix4x4 matrix;
matrix.ortho(QRect(0, 0, 32, 32));
// Bind the source texture
src.bind();
const QVector4D red {1.0f, 0.0f, 0.0f, 1.0f};
const QVector4D green {0.0f, 1.0f, 0.0f, 1.0f};
const QVector4D blue {0.0f, 0.0f, 1.0f, 1.0f};
const QVector4D white {1.0f, 1.0f, 1.0f, 1.0f};
// Note: To see the line number in error messages, set
// QT_MESSAGE_PATTERN="%{message} (%{file}:%{line})"
// Test solid color
GLShader *shader = pushShader(ShaderTrait::UniformColor);
if (shader->isValid()) {
glClear(GL_COLOR_BUFFER_BIT);
shader->setUniform(GLShader::ModelViewProjectionMatrix, matrix);
shader->setUniform(GLShader::Color, green);
vbo->draw(GL_TRIANGLES, 0, 6);
pass = CHECK_PIXEL(8, 24, green) && pass;
pass = CHECK_PIXEL(24, 24, green) && pass;
pass = CHECK_PIXEL(8, 8, green) && pass;
pass = CHECK_PIXEL(24, 8, green) && pass;
} else {
pass = false;
}
popShader();
// Test texture mapping
shader = pushShader(ShaderTrait::MapTexture);
if (shader->isValid()) {
glClear(GL_COLOR_BUFFER_BIT);
shader->setUniform(GLShader::ModelViewProjectionMatrix, matrix);
vbo->draw(GL_TRIANGLES, 0, 6);
pass = CHECK_PIXEL(8, 24, red) && pass;
pass = CHECK_PIXEL(24, 24, green) && pass;
pass = CHECK_PIXEL(8, 8, blue) && pass;
pass = CHECK_PIXEL(24, 8, white) && pass;
} else {
pass = false;
}
popShader();
// Test saturation filter
shader = pushShader(ShaderTrait::MapTexture | ShaderTrait::AdjustSaturation);
if (shader->isValid()) {
glClear(GL_COLOR_BUFFER_BIT);
const float saturation = .3;
shader->setUniform(GLShader::ModelViewProjectionMatrix, matrix);
shader->setUniform(GLShader::Saturation, saturation);
vbo->draw(GL_TRIANGLES, 0, 6);
pass = CHECK_PIXEL(8, 24, adjustSaturation(red, saturation)) && pass;
pass = CHECK_PIXEL(24, 24, adjustSaturation(green, saturation)) && pass;
pass = CHECK_PIXEL(8, 8, adjustSaturation(blue, saturation)) && pass;
pass = CHECK_PIXEL(24, 8, adjustSaturation(white, saturation)) && pass;
} else {
pass = false;
}
popShader();
// Test modulation filter
shader = pushShader(ShaderTrait::MapTexture | ShaderTrait::Modulate);
if (shader->isValid()) {
glClear(GL_COLOR_BUFFER_BIT);
const QVector4D modulation{.3f, .4f, .5f, .6f};
shader->setUniform(GLShader::ModelViewProjectionMatrix, matrix);
shader->setUniform(GLShader::ModulationConstant, modulation);
vbo->draw(GL_TRIANGLES, 0, 6);
pass = CHECK_PIXEL(8, 24, red * modulation) && pass;
pass = CHECK_PIXEL(24, 24, green * modulation) && pass;
pass = CHECK_PIXEL(8, 8, blue * modulation) && pass;
pass = CHECK_PIXEL(24, 8, white * modulation) && pass;
} else {
pass = false;
}
popShader();
// Test saturation + modulation
shader = pushShader(ShaderTrait::MapTexture | ShaderTrait::AdjustSaturation | ShaderTrait::Modulate);
if (shader->isValid()) {
glClear(GL_COLOR_BUFFER_BIT);
const QVector4D modulation{.3f, .4f, .5f, .6f};
const float saturation = .3;
shader->setUniform(GLShader::ModelViewProjectionMatrix, matrix);
shader->setUniform(GLShader::ModulationConstant, modulation);
shader->setUniform(GLShader::Saturation, saturation);
vbo->draw(GL_TRIANGLES, 0, 6);
pass = CHECK_PIXEL(8, 24, adjustSaturation(red * modulation, saturation)) && pass;
pass = CHECK_PIXEL(24, 24, adjustSaturation(green * modulation, saturation)) && pass;
pass = CHECK_PIXEL(8, 8, adjustSaturation(blue * modulation, saturation)) && pass;
pass = CHECK_PIXEL(24, 8, adjustSaturation(white * modulation, saturation)) && pass;
} else {
pass = false;
}
popShader();
vbo->unbindArrays();
GLRenderTarget::popRenderTarget();
return pass;
}
QByteArray ShaderManager::generateVertexSource(ShaderTraits traits) const
{
QByteArray source;
QTextStream stream(&source);
GLPlatform * const gl = GLPlatform::instance();
QByteArray attribute, varying;
if (!gl->isGLES()) {
const bool glsl_140 = gl->glslVersion() >= kVersionNumber(1, 40);
attribute = glsl_140 ? QByteArrayLiteral("in") : QByteArrayLiteral("attribute");
varying = glsl_140 ? QByteArrayLiteral("out") : QByteArrayLiteral("varying");
if (glsl_140)
stream << "#version 140\n\n";
} else {
const bool glsl_es_300 = gl->glslVersion() >= kVersionNumber(3, 0);
attribute = glsl_es_300 ? QByteArrayLiteral("in") : QByteArrayLiteral("attribute");
varying = glsl_es_300 ? QByteArrayLiteral("out") : QByteArrayLiteral("varying");
if (glsl_es_300)
stream << "#version 300 es\n\n";
}
stream << attribute << " vec4 position;\n";
if (traits & ShaderTrait::MapTexture) {
stream << attribute << " vec4 texcoord;\n\n";
stream << varying << " vec2 texcoord0;\n\n";
} else
stream << "\n";
stream << "uniform mat4 modelViewProjectionMatrix;\n\n";
stream << "void main()\n{\n";
if (traits & ShaderTrait::MapTexture)
stream << " texcoord0 = texcoord.st;\n";
stream << " gl_Position = modelViewProjectionMatrix * position;\n";
stream << "}\n";
stream.flush();
return source;
}
QByteArray ShaderManager::generateFragmentSource(ShaderTraits traits) const
{
QByteArray source;
QTextStream stream(&source);
GLPlatform * const gl = GLPlatform::instance();
QByteArray varying, output, textureLookup;
if (!gl->isGLES()) {
const bool glsl_140 = gl->glslVersion() >= kVersionNumber(1, 40);
if (glsl_140)
stream << "#version 140\n\n";
varying = glsl_140 ? QByteArrayLiteral("in") : QByteArrayLiteral("varying");
textureLookup = glsl_140 ? QByteArrayLiteral("texture") : QByteArrayLiteral("texture2D");
output = glsl_140 ? QByteArrayLiteral("fragColor") : QByteArrayLiteral("gl_FragColor");
} else {
const bool glsl_es_300 = GLPlatform::instance()->glslVersion() >= kVersionNumber(3, 0);
if (glsl_es_300)
stream << "#version 300 es\n\n";
// From the GLSL ES specification:
//
// "The fragment language has no default precision qualifier for floating point types."
stream << "precision highp float;\n\n";
varying = glsl_es_300 ? QByteArrayLiteral("in") : QByteArrayLiteral("varying");
textureLookup = glsl_es_300 ? QByteArrayLiteral("texture") : QByteArrayLiteral("texture2D");
output = glsl_es_300 ? QByteArrayLiteral("fragColor") : QByteArrayLiteral("gl_FragColor");
}
if (traits & ShaderTrait::MapTexture) {
stream << "uniform sampler2D sampler;\n";
if (traits & ShaderTrait::Modulate)
stream << "uniform vec4 modulation;\n";
if (traits & ShaderTrait::AdjustSaturation)
stream << "uniform float saturation;\n";
stream << "\n" << varying << " vec2 texcoord0;\n";
} else if (traits & ShaderTrait::UniformColor)
stream << "uniform vec4 geometryColor;\n";
if (traits & ShaderTrait::ClampTexture) {
stream << "uniform vec4 textureClamp;\n";
}
if (output != QByteArrayLiteral("gl_FragColor"))
stream << "\nout vec4 " << output << ";\n";
stream << "\nvoid main(void)\n{\n";
if (traits & ShaderTrait::MapTexture) {
stream << "vec2 texcoordC = texcoord0;\n";
if (traits & ShaderTrait::ClampTexture) {
stream << "texcoordC.x = clamp(texcoordC.x, textureClamp.x, textureClamp.z);\n";
stream << "texcoordC.y = clamp(texcoordC.y, textureClamp.y, textureClamp.w);\n";
}
if (traits & (ShaderTrait::Modulate | ShaderTrait::AdjustSaturation)) {
stream << " vec4 texel = " << textureLookup << "(sampler, texcoordC);\n";
if (traits & ShaderTrait::Modulate)
stream << " texel *= modulation;\n";
if (traits & ShaderTrait::AdjustSaturation)
stream << " texel.rgb = mix(vec3(dot(texel.rgb, vec3(0.2126, 0.7152, 0.0722))), texel.rgb, saturation);\n";
stream << " " << output << " = texel;\n";
} else {
stream << " " << output << " = " << textureLookup << "(sampler, texcoordC);\n";
}
} else if (traits & ShaderTrait::UniformColor)
stream << " " << output << " = geometryColor;\n";
stream << "}";
stream.flush();
return source;
}
GLShader *ShaderManager::generateShader(ShaderTraits traits)
{
return generateCustomShader(traits);
}
GLShader *ShaderManager::generateCustomShader(ShaderTraits traits, const QByteArray &vertexSource, const QByteArray &fragmentSource)
{
const QByteArray vertex = vertexSource.isEmpty() ? generateVertexSource(traits) : vertexSource;
const QByteArray fragment = fragmentSource.isEmpty() ? generateFragmentSource(traits) : fragmentSource;
#if 0
qCDebug(LIBKWINGLUTILS) << "**************";
qCDebug(LIBKWINGLUTILS) << vertex;
qCDebug(LIBKWINGLUTILS) << "**************";
qCDebug(LIBKWINGLUTILS) << fragment;
qCDebug(LIBKWINGLUTILS) << "**************";
#endif
GLShader *shader = new GLShader(GLShader::ExplicitLinking);
shader->load(vertex, fragment);
shader->bindAttributeLocation("position", VA_Position);
shader->bindAttributeLocation("texcoord", VA_TexCoord);
shader->bindFragDataLocation("fragColor", 0);
shader->link();
return shader;
}
GLShader *ShaderManager::generateShaderFromResources(ShaderTraits traits, const QString &vertexFile, const QString &fragmentFile)
{
auto loadShaderFile = [this] (const QString &fileName) {
QFile file(m_resourcePath + fileName);
if (file.open(QIODevice::ReadOnly)) {
return file.readAll();
}
qCCritical(LIBKWINGLUTILS) << "Failed to read shader " << fileName;
return QByteArray();
};
QByteArray vertexSource;
QByteArray fragmentSource;
if (!vertexFile.isEmpty()) {
vertexSource = loadShaderFile(vertexFile);
if (vertexSource.isEmpty()) {
return new GLShader();
}
}
if (!fragmentFile.isEmpty()) {
fragmentSource = loadShaderFile(fragmentFile);
if (fragmentSource.isEmpty()) {
return new GLShader();
}
}
return generateCustomShader(traits, vertexSource, fragmentSource);
}
GLShader *ShaderManager::shader(ShaderTraits traits)
{
GLShader *shader = m_shaderHash.value(traits);
if (!shader) {
shader = generateShader(traits);
m_shaderHash.insert(traits, shader);
}
return shader;
}
GLShader *ShaderManager::getBoundShader() const
{
if (m_boundShaders.isEmpty()) {
return nullptr;
} else {
return m_boundShaders.top();
}
}
bool ShaderManager::isShaderBound() const
{
return !m_boundShaders.isEmpty();
}
-bool ShaderManager::isShaderDebug() const
-{
- return m_debug;
-}
-
GLShader *ShaderManager::pushShader(ShaderTraits traits)
{
GLShader *shader = this->shader(traits);
pushShader(shader);
return shader;
}
void ShaderManager::pushShader(GLShader *shader)
{
// only bind shader if it is not already bound
if (shader != getBoundShader()) {
shader->bind();
}
m_boundShaders.push(shader);
}
void ShaderManager::popShader()
{
if (m_boundShaders.isEmpty()) {
return;
}
GLShader *shader = m_boundShaders.pop();
if (m_boundShaders.isEmpty()) {
// no more shader bound - unbind
shader->unbind();
} else if (shader != m_boundShaders.top()) {
// only rebind if a different shader is on top of stack
m_boundShaders.top()->bind();
}
}
void ShaderManager::bindFragDataLocations(GLShader *shader)
{
shader->bindFragDataLocation("fragColor", 0);
}
void ShaderManager::bindAttributeLocations(GLShader *shader) const
{
shader->bindAttributeLocation("vertex", VA_Position);
shader->bindAttributeLocation("texCoord", VA_TexCoord);
}
GLShader *ShaderManager::loadShaderFromCode(const QByteArray &vertexSource, const QByteArray &fragmentSource)
{
GLShader *shader = new GLShader(GLShader::ExplicitLinking);
shader->load(vertexSource, fragmentSource);
bindAttributeLocations(shader);
bindFragDataLocations(shader);
shader->link();
return shader;
}
/*** GLRenderTarget ***/
bool GLRenderTarget::sSupported = false;
bool GLRenderTarget::s_blitSupported = false;
QStack GLRenderTarget::s_renderTargets = QStack();
QSize GLRenderTarget::s_virtualScreenSize;
QRect GLRenderTarget::s_virtualScreenGeometry;
qreal GLRenderTarget::s_virtualScreenScale = 1.0;
GLint GLRenderTarget::s_virtualScreenViewport[4];
GLuint GLRenderTarget::s_kwinFramebuffer = 0;
void GLRenderTarget::initStatic()
{
if (GLPlatform::instance()->isGLES()) {
sSupported = true;
s_blitSupported = hasGLVersion(3, 0);
} else {
sSupported = hasGLVersion(3, 0) ||
hasGLExtension(QByteArrayLiteral("GL_ARB_framebuffer_object")) ||
hasGLExtension(QByteArrayLiteral("GL_EXT_framebuffer_object"));
s_blitSupported = hasGLVersion(3, 0) ||
hasGLExtension(QByteArrayLiteral("GL_ARB_framebuffer_object")) ||
hasGLExtension(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
}
}
void GLRenderTarget::cleanup()
{
Q_ASSERT(s_renderTargets.isEmpty());
sSupported = false;
s_blitSupported = false;
}
bool GLRenderTarget::isRenderTargetBound()
{
return !s_renderTargets.isEmpty();
}
bool GLRenderTarget::blitSupported()
{
return s_blitSupported;
}
void GLRenderTarget::pushRenderTarget(GLRenderTarget* target)
{
if (s_renderTargets.isEmpty()) {
glGetIntegerv(GL_VIEWPORT, s_virtualScreenViewport);
}
target->enable();
s_renderTargets.push(target);
}
void GLRenderTarget::pushRenderTargets(QStack targets)
{
if (s_renderTargets.isEmpty()) {
glGetIntegerv(GL_VIEWPORT, s_virtualScreenViewport);
}
targets.top()->enable();
s_renderTargets.append(targets);
}
GLRenderTarget* GLRenderTarget::popRenderTarget()
{
GLRenderTarget* ret = s_renderTargets.pop();
ret->setTextureDirty();
if (!s_renderTargets.isEmpty()) {
s_renderTargets.top()->enable();
} else {
ret->disable();
glViewport (s_virtualScreenViewport[0], s_virtualScreenViewport[1], s_virtualScreenViewport[2], s_virtualScreenViewport[3]);
}
return ret;
}
GLRenderTarget::GLRenderTarget()
{
// Reset variables
mValid = false;
mTexture = GLTexture();
}
GLRenderTarget::GLRenderTarget(const GLTexture& color)
{
// Reset variables
mValid = false;
mTexture = color;
// Make sure FBO is supported
if (sSupported && !mTexture.isNull()) {
initFBO();
} else
qCCritical(LIBKWINGLUTILS) << "Render targets aren't supported!";
}
GLRenderTarget::~GLRenderTarget()
{
if (mValid) {
glDeleteFramebuffers(1, &mFramebuffer);
}
}
bool GLRenderTarget::enable()
{
if (!mValid) {
initFBO();
}
if (!valid()) {
qCCritical(LIBKWINGLUTILS) << "Can't enable invalid render target!";
return false;
}
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glViewport(0, 0, mTexture.width(), mTexture.height());
mTexture.setDirty();
return true;
}
bool GLRenderTarget::disable()
{
if (!mValid) {
initFBO();
}
if (!valid()) {
qCCritical(LIBKWINGLUTILS) << "Can't disable invalid render target!";
return false;
}
glBindFramebuffer(GL_FRAMEBUFFER, s_kwinFramebuffer);
mTexture.setDirty();
return true;
}
static QString formatFramebufferStatus(GLenum status)
{
switch(status) {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
// An attachment is the wrong type / is invalid / has 0 width or height
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
// There are no images attached to the framebuffer
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
case GL_FRAMEBUFFER_UNSUPPORTED:
// A format or the combination of formats of the attachments is unsupported
return QStringLiteral("GL_FRAMEBUFFER_UNSUPPORTED");
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
// Not all attached images have the same width and height
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT");
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
// The color attachments don't have the same format
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT");
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
// The attachments don't have the same number of samples
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE");
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
// The draw buffer is missing
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER");
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
// The read buffer is missing
return QStringLiteral("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER");
default:
return QStringLiteral("Unknown (0x") + QString::number(status, 16) + QStringLiteral(")");
}
}
void GLRenderTarget::initFBO()
{
#if DEBUG_GLRENDERTARGET
GLenum err = glGetError();
if (err != GL_NO_ERROR)
qCCritical(LIBKWINGLUTILS) << "Error status when entering GLRenderTarget::initFBO: " << formatGLError(err);
#endif
glGenFramebuffers(1, &mFramebuffer);
#if DEBUG_GLRENDERTARGET
if ((err = glGetError()) != GL_NO_ERROR) {
qCCritical(LIBKWINGLUTILS) << "glGenFramebuffers failed: " << formatGLError(err);
return;
}
#endif
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
#if DEBUG_GLRENDERTARGET
if ((err = glGetError()) != GL_NO_ERROR) {
qCCritical(LIBKWINGLUTILS) << "glBindFramebuffer failed: " << formatGLError(err);
glDeleteFramebuffers(1, &mFramebuffer);
return;
}
#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
mTexture.target(), mTexture.texture(), 0);
#if DEBUG_GLRENDERTARGET
if ((err = glGetError()) != GL_NO_ERROR) {
qCCritical(LIBKWINGLUTILS) << "glFramebufferTexture2D failed: " << formatGLError(err);
glBindFramebuffer(GL_FRAMEBUFFER, s_kwinFramebuffer);
glDeleteFramebuffers(1, &mFramebuffer);
return;
}
#endif
const GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, s_kwinFramebuffer);
if (status != GL_FRAMEBUFFER_COMPLETE) {
// We have an incomplete framebuffer, consider it invalid
if (status == 0)
qCCritical(LIBKWINGLUTILS) << "glCheckFramebufferStatus failed: " << formatGLError(glGetError());
else
qCCritical(LIBKWINGLUTILS) << "Invalid framebuffer status: " << formatFramebufferStatus(status);
glDeleteFramebuffers(1, &mFramebuffer);
return;
}
mValid = true;
}
void GLRenderTarget::blitFromFramebuffer(const QRect &source, const QRect &destination, GLenum filter)
{
if (!GLRenderTarget::blitSupported()) {
return;
}
if (!mValid) {
initFBO();
}
GLRenderTarget::pushRenderTarget(this);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, s_kwinFramebuffer);
const QRect s = source.isNull() ? s_virtualScreenGeometry : source;
const QRect d = destination.isNull() ? QRect(0, 0, mTexture.width(), mTexture.height()) : destination;
glBlitFramebuffer((s.x() - s_virtualScreenGeometry.x()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() - (s.y() - s_virtualScreenGeometry.y() + s.height())) * s_virtualScreenScale,
(s.x() - s_virtualScreenGeometry.x() + s.width()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() - (s.y() - s_virtualScreenGeometry.y())) * s_virtualScreenScale,
d.x(), mTexture.height() - d.y() - d.height(), d.x() + d.width(), mTexture.height() - d.y(),
GL_COLOR_BUFFER_BIT, filter);
GLRenderTarget::popRenderTarget();
}
void GLRenderTarget::attachTexture(const GLTexture& target)
{
if (!mValid) {
initFBO();
}
if (mTexture.texture() == target.texture()) {
return;
}
pushRenderTarget(this);
mTexture = target;
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
mTexture.target(), mTexture.texture(), 0);
popRenderTarget();
}
void GLRenderTarget::detachTexture()
{
if (mTexture.isNull()) {
return;
}
pushRenderTarget(this);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
mTexture.target(), 0, 0);
popRenderTarget();
}
// ------------------------------------------------------------------
static const uint16_t indices[] = {
1, 0, 3, 3, 2, 1, 5, 4, 7, 7, 6, 5, 9, 8, 11, 11, 10, 9,
13, 12, 15, 15, 14, 13, 17, 16, 19, 19, 18, 17, 21, 20, 23, 23, 22, 21,
25, 24, 27, 27, 26, 25, 29, 28, 31, 31, 30, 29, 33, 32, 35, 35, 34, 33,
37, 36, 39, 39, 38, 37, 41, 40, 43, 43, 42, 41, 45, 44, 47, 47, 46, 45,
49, 48, 51, 51, 50, 49, 53, 52, 55, 55, 54, 53, 57, 56, 59, 59, 58, 57,
61, 60, 63, 63, 62, 61, 65, 64, 67, 67, 66, 65, 69, 68, 71, 71, 70, 69,
73, 72, 75, 75, 74, 73, 77, 76, 79, 79, 78, 77, 81, 80, 83, 83, 82, 81,
85, 84, 87, 87, 86, 85, 89, 88, 91, 91, 90, 89, 93, 92, 95, 95, 94, 93,
97, 96, 99, 99, 98, 97, 101, 100, 103, 103, 102, 101, 105, 104, 107, 107, 106, 105,
109, 108, 111, 111, 110, 109, 113, 112, 115, 115, 114, 113, 117, 116, 119, 119, 118, 117,
121, 120, 123, 123, 122, 121, 125, 124, 127, 127, 126, 125, 129, 128, 131, 131, 130, 129,
133, 132, 135, 135, 134, 133, 137, 136, 139, 139, 138, 137, 141, 140, 143, 143, 142, 141,
145, 144, 147, 147, 146, 145, 149, 148, 151, 151, 150, 149, 153, 152, 155, 155, 154, 153,
157, 156, 159, 159, 158, 157, 161, 160, 163, 163, 162, 161, 165, 164, 167, 167, 166, 165,
169, 168, 171, 171, 170, 169, 173, 172, 175, 175, 174, 173, 177, 176, 179, 179, 178, 177,
181, 180, 183, 183, 182, 181, 185, 184, 187, 187, 186, 185, 189, 188, 191, 191, 190, 189,
193, 192, 195, 195, 194, 193, 197, 196, 199, 199, 198, 197, 201, 200, 203, 203, 202, 201,
205, 204, 207, 207, 206, 205, 209, 208, 211, 211, 210, 209, 213, 212, 215, 215, 214, 213,
217, 216, 219, 219, 218, 217, 221, 220, 223, 223, 222, 221, 225, 224, 227, 227, 226, 225,
229, 228, 231, 231, 230, 229, 233, 232, 235, 235, 234, 233, 237, 236, 239, 239, 238, 237,
241, 240, 243, 243, 242, 241, 245, 244, 247, 247, 246, 245, 249, 248, 251, 251, 250, 249,
253, 252, 255, 255, 254, 253, 257, 256, 259, 259, 258, 257, 261, 260, 263, 263, 262, 261,
265, 264, 267, 267, 266, 265, 269, 268, 271, 271, 270, 269, 273, 272, 275, 275, 274, 273,
277, 276, 279, 279, 278, 277, 281, 280, 283, 283, 282, 281, 285, 284, 287, 287, 286, 285,
289, 288, 291, 291, 290, 289, 293, 292, 295, 295, 294, 293, 297, 296, 299, 299, 298, 297,
301, 300, 303, 303, 302, 301, 305, 304, 307, 307, 306, 305, 309, 308, 311, 311, 310, 309,
313, 312, 315, 315, 314, 313, 317, 316, 319, 319, 318, 317, 321, 320, 323, 323, 322, 321,
325, 324, 327, 327, 326, 325, 329, 328, 331, 331, 330, 329, 333, 332, 335, 335, 334, 333,
337, 336, 339, 339, 338, 337, 341, 340, 343, 343, 342, 341, 345, 344, 347, 347, 346, 345,
349, 348, 351, 351, 350, 349, 353, 352, 355, 355, 354, 353, 357, 356, 359, 359, 358, 357,
361, 360, 363, 363, 362, 361, 365, 364, 367, 367, 366, 365, 369, 368, 371, 371, 370, 369,
373, 372, 375, 375, 374, 373, 377, 376, 379, 379, 378, 377, 381, 380, 383, 383, 382, 381,
385, 384, 387, 387, 386, 385, 389, 388, 391, 391, 390, 389, 393, 392, 395, 395, 394, 393,
397, 396, 399, 399, 398, 397, 401, 400, 403, 403, 402, 401, 405, 404, 407, 407, 406, 405,
409, 408, 411, 411, 410, 409, 413, 412, 415, 415, 414, 413, 417, 416, 419, 419, 418, 417,
421, 420, 423, 423, 422, 421, 425, 424, 427, 427, 426, 425, 429, 428, 431, 431, 430, 429,
433, 432, 435, 435, 434, 433, 437, 436, 439, 439, 438, 437, 441, 440, 443, 443, 442, 441,
445, 444, 447, 447, 446, 445, 449, 448, 451, 451, 450, 449, 453, 452, 455, 455, 454, 453,
457, 456, 459, 459, 458, 457, 461, 460, 463, 463, 462, 461, 465, 464, 467, 467, 466, 465,
469, 468, 471, 471, 470, 469, 473, 472, 475, 475, 474, 473, 477, 476, 479, 479, 478, 477,
481, 480, 483, 483, 482, 481, 485, 484, 487, 487, 486, 485, 489, 488, 491, 491, 490, 489,
493, 492, 495, 495, 494, 493, 497, 496, 499, 499, 498, 497, 501, 500, 503, 503, 502, 501,
505, 504, 507, 507, 506, 505, 509, 508, 511, 511, 510, 509, 513, 512, 515, 515, 514, 513,
517, 516, 519, 519, 518, 517, 521, 520, 523, 523, 522, 521, 525, 524, 527, 527, 526, 525,
529, 528, 531, 531, 530, 529, 533, 532, 535, 535, 534, 533, 537, 536, 539, 539, 538, 537,
541, 540, 543, 543, 542, 541, 545, 544, 547, 547, 546, 545, 549, 548, 551, 551, 550, 549,
553, 552, 555, 555, 554, 553, 557, 556, 559, 559, 558, 557, 561, 560, 563, 563, 562, 561,
565, 564, 567, 567, 566, 565, 569, 568, 571, 571, 570, 569, 573, 572, 575, 575, 574, 573,
577, 576, 579, 579, 578, 577, 581, 580, 583, 583, 582, 581, 585, 584, 587, 587, 586, 585,
589, 588, 591, 591, 590, 589, 593, 592, 595, 595, 594, 593, 597, 596, 599, 599, 598, 597,
601, 600, 603, 603, 602, 601, 605, 604, 607, 607, 606, 605, 609, 608, 611, 611, 610, 609,
613, 612, 615, 615, 614, 613, 617, 616, 619, 619, 618, 617, 621, 620, 623, 623, 622, 621,
625, 624, 627, 627, 626, 625, 629, 628, 631, 631, 630, 629, 633, 632, 635, 635, 634, 633,
637, 636, 639, 639, 638, 637, 641, 640, 643, 643, 642, 641, 645, 644, 647, 647, 646, 645,
649, 648, 651, 651, 650, 649, 653, 652, 655, 655, 654, 653, 657, 656, 659, 659, 658, 657,
661, 660, 663, 663, 662, 661, 665, 664, 667, 667, 666, 665, 669, 668, 671, 671, 670, 669,
673, 672, 675, 675, 674, 673, 677, 676, 679, 679, 678, 677, 681, 680, 683, 683, 682, 681,
685, 684, 687, 687, 686, 685, 689, 688, 691, 691, 690, 689, 693, 692, 695, 695, 694, 693,
697, 696, 699, 699, 698, 697, 701, 700, 703, 703, 702, 701, 705, 704, 707, 707, 706, 705,
709, 708, 711, 711, 710, 709, 713, 712, 715, 715, 714, 713, 717, 716, 719, 719, 718, 717,
721, 720, 723, 723, 722, 721, 725, 724, 727, 727, 726, 725, 729, 728, 731, 731, 730, 729,
733, 732, 735, 735, 734, 733, 737, 736, 739, 739, 738, 737, 741, 740, 743, 743, 742, 741,
745, 744, 747, 747, 746, 745, 749, 748, 751, 751, 750, 749, 753, 752, 755, 755, 754, 753,
757, 756, 759, 759, 758, 757, 761, 760, 763, 763, 762, 761, 765, 764, 767, 767, 766, 765,
769, 768, 771, 771, 770, 769, 773, 772, 775, 775, 774, 773, 777, 776, 779, 779, 778, 777,
781, 780, 783, 783, 782, 781, 785, 784, 787, 787, 786, 785, 789, 788, 791, 791, 790, 789,
793, 792, 795, 795, 794, 793, 797, 796, 799, 799, 798, 797, 801, 800, 803, 803, 802, 801,
805, 804, 807, 807, 806, 805, 809, 808, 811, 811, 810, 809, 813, 812, 815, 815, 814, 813,
817, 816, 819, 819, 818, 817, 821, 820, 823, 823, 822, 821, 825, 824, 827, 827, 826, 825,
829, 828, 831, 831, 830, 829, 833, 832, 835, 835, 834, 833, 837, 836, 839, 839, 838, 837,
841, 840, 843, 843, 842, 841, 845, 844, 847, 847, 846, 845, 849, 848, 851, 851, 850, 849,
853, 852, 855, 855, 854, 853, 857, 856, 859, 859, 858, 857, 861, 860, 863, 863, 862, 861,
865, 864, 867, 867, 866, 865, 869, 868, 871, 871, 870, 869, 873, 872, 875, 875, 874, 873,
877, 876, 879, 879, 878, 877, 881, 880, 883, 883, 882, 881, 885, 884, 887, 887, 886, 885,
889, 888, 891, 891, 890, 889, 893, 892, 895, 895, 894, 893, 897, 896, 899, 899, 898, 897,
901, 900, 903, 903, 902, 901, 905, 904, 907, 907, 906, 905, 909, 908, 911, 911, 910, 909,
913, 912, 915, 915, 914, 913, 917, 916, 919, 919, 918, 917, 921, 920, 923, 923, 922, 921,
925, 924, 927, 927, 926, 925, 929, 928, 931, 931, 930, 929, 933, 932, 935, 935, 934, 933,
937, 936, 939, 939, 938, 937, 941, 940, 943, 943, 942, 941, 945, 944, 947, 947, 946, 945,
949, 948, 951, 951, 950, 949, 953, 952, 955, 955, 954, 953, 957, 956, 959, 959, 958, 957,
961, 960, 963, 963, 962, 961, 965, 964, 967, 967, 966, 965, 969, 968, 971, 971, 970, 969,
973, 972, 975, 975, 974, 973, 977, 976, 979, 979, 978, 977, 981, 980, 983, 983, 982, 981,
985, 984, 987, 987, 986, 985, 989, 988, 991, 991, 990, 989, 993, 992, 995, 995, 994, 993,
997, 996, 999, 999, 998, 997, 1001, 1000, 1003, 1003, 1002, 1001, 1005, 1004, 1007, 1007, 1006, 1005,
1009, 1008, 1011, 1011, 1010, 1009, 1013, 1012, 1015, 1015, 1014, 1013, 1017, 1016, 1019, 1019, 1018, 1017,
1021, 1020, 1023, 1023, 1022, 1021, 1025, 1024, 1027, 1027, 1026, 1025, 1029, 1028, 1031, 1031, 1030, 1029,
1033, 1032, 1035, 1035, 1034, 1033, 1037, 1036, 1039, 1039, 1038, 1037, 1041, 1040, 1043, 1043, 1042, 1041,
1045, 1044, 1047, 1047, 1046, 1045, 1049, 1048, 1051, 1051, 1050, 1049, 1053, 1052, 1055, 1055, 1054, 1053,
1057, 1056, 1059, 1059, 1058, 1057, 1061, 1060, 1063, 1063, 1062, 1061, 1065, 1064, 1067, 1067, 1066, 1065,
1069, 1068, 1071, 1071, 1070, 1069, 1073, 1072, 1075, 1075, 1074, 1073, 1077, 1076, 1079, 1079, 1078, 1077,
1081, 1080, 1083, 1083, 1082, 1081, 1085, 1084, 1087, 1087, 1086, 1085, 1089, 1088, 1091, 1091, 1090, 1089,
1093, 1092, 1095, 1095, 1094, 1093, 1097, 1096, 1099, 1099, 1098, 1097, 1101, 1100, 1103, 1103, 1102, 1101,
1105, 1104, 1107, 1107, 1106, 1105, 1109, 1108, 1111, 1111, 1110, 1109, 1113, 1112, 1115, 1115, 1114, 1113,
1117, 1116, 1119, 1119, 1118, 1117, 1121, 1120, 1123, 1123, 1122, 1121, 1125, 1124, 1127, 1127, 1126, 1125,
1129, 1128, 1131, 1131, 1130, 1129, 1133, 1132, 1135, 1135, 1134, 1133, 1137, 1136, 1139, 1139, 1138, 1137,
1141, 1140, 1143, 1143, 1142, 1141, 1145, 1144, 1147, 1147, 1146, 1145, 1149, 1148, 1151, 1151, 1150, 1149,
1153, 1152, 1155, 1155, 1154, 1153, 1157, 1156, 1159, 1159, 1158, 1157, 1161, 1160, 1163, 1163, 1162, 1161,
1165, 1164, 1167, 1167, 1166, 1165, 1169, 1168, 1171, 1171, 1170, 1169, 1173, 1172, 1175, 1175, 1174, 1173,
1177, 1176, 1179, 1179, 1178, 1177, 1181, 1180, 1183, 1183, 1182, 1181, 1185, 1184, 1187, 1187, 1186, 1185,
1189, 1188, 1191, 1191, 1190, 1189, 1193, 1192, 1195, 1195, 1194, 1193, 1197, 1196, 1199, 1199, 1198, 1197,
1201, 1200, 1203, 1203, 1202, 1201, 1205, 1204, 1207, 1207, 1206, 1205, 1209, 1208, 1211, 1211, 1210, 1209,
1213, 1212, 1215, 1215, 1214, 1213, 1217, 1216, 1219, 1219, 1218, 1217, 1221, 1220, 1223, 1223, 1222, 1221,
1225, 1224, 1227, 1227, 1226, 1225, 1229, 1228, 1231, 1231, 1230, 1229, 1233, 1232, 1235, 1235, 1234, 1233,
1237, 1236, 1239, 1239, 1238, 1237, 1241, 1240, 1243, 1243, 1242, 1241, 1245, 1244, 1247, 1247, 1246, 1245,
1249, 1248, 1251, 1251, 1250, 1249, 1253, 1252, 1255, 1255, 1254, 1253, 1257, 1256, 1259, 1259, 1258, 1257,
1261, 1260, 1263, 1263, 1262, 1261, 1265, 1264, 1267, 1267, 1266, 1265, 1269, 1268, 1271, 1271, 1270, 1269,
1273, 1272, 1275, 1275, 1274, 1273, 1277, 1276, 1279, 1279, 1278, 1277, 1281, 1280, 1283, 1283, 1282, 1281,
1285, 1284, 1287, 1287, 1286, 1285, 1289, 1288, 1291, 1291, 1290, 1289, 1293, 1292, 1295, 1295, 1294, 1293,
1297, 1296, 1299, 1299, 1298, 1297, 1301, 1300, 1303, 1303, 1302, 1301, 1305, 1304, 1307, 1307, 1306, 1305,
1309, 1308, 1311, 1311, 1310, 1309, 1313, 1312, 1315, 1315, 1314, 1313, 1317, 1316, 1319, 1319, 1318, 1317,
1321, 1320, 1323, 1323, 1322, 1321, 1325, 1324, 1327, 1327, 1326, 1325, 1329, 1328, 1331, 1331, 1330, 1329,
1333, 1332, 1335, 1335, 1334, 1333, 1337, 1336, 1339, 1339, 1338, 1337, 1341, 1340, 1343, 1343, 1342, 1341,
1345, 1344, 1347, 1347, 1346, 1345, 1349, 1348, 1351, 1351, 1350, 1349, 1353, 1352, 1355, 1355, 1354, 1353,
1357, 1356, 1359, 1359, 1358, 1357, 1361, 1360, 1363, 1363, 1362, 1361, 1365, 1364, 1367, 1367, 1366, 1365,
1369, 1368, 1371, 1371, 1370, 1369, 1373, 1372, 1375, 1375, 1374, 1373, 1377, 1376, 1379, 1379, 1378, 1377,
1381, 1380, 1383, 1383, 1382, 1381, 1385, 1384, 1387, 1387, 1386, 1385, 1389, 1388, 1391, 1391, 1390, 1389,
1393, 1392, 1395, 1395, 1394, 1393, 1397, 1396, 1399, 1399, 1398, 1397, 1401, 1400, 1403, 1403, 1402, 1401,
1405, 1404, 1407, 1407, 1406, 1405, 1409, 1408, 1411, 1411, 1410, 1409, 1413, 1412, 1415, 1415, 1414, 1413,
1417, 1416, 1419, 1419, 1418, 1417, 1421, 1420, 1423, 1423, 1422, 1421, 1425, 1424, 1427, 1427, 1426, 1425,
1429, 1428, 1431, 1431, 1430, 1429, 1433, 1432, 1435, 1435, 1434, 1433, 1437, 1436, 1439, 1439, 1438, 1437,
1441, 1440, 1443, 1443, 1442, 1441, 1445, 1444, 1447, 1447, 1446, 1445, 1449, 1448, 1451, 1451, 1450, 1449,
1453, 1452, 1455, 1455, 1454, 1453, 1457, 1456, 1459, 1459, 1458, 1457, 1461, 1460, 1463, 1463, 1462, 1461,
1465, 1464, 1467, 1467, 1466, 1465, 1469, 1468, 1471, 1471, 1470, 1469, 1473, 1472, 1475, 1475, 1474, 1473,
1477, 1476, 1479, 1479, 1478, 1477, 1481, 1480, 1483, 1483, 1482, 1481, 1485, 1484, 1487, 1487, 1486, 1485,
1489, 1488, 1491, 1491, 1490, 1489, 1493, 1492, 1495, 1495, 1494, 1493, 1497, 1496, 1499, 1499, 1498, 1497,
1501, 1500, 1503, 1503, 1502, 1501, 1505, 1504, 1507, 1507, 1506, 1505, 1509, 1508, 1511, 1511, 1510, 1509,
1513, 1512, 1515, 1515, 1514, 1513, 1517, 1516, 1519, 1519, 1518, 1517, 1521, 1520, 1523, 1523, 1522, 1521,
1525, 1524, 1527, 1527, 1526, 1525, 1529, 1528, 1531, 1531, 1530, 1529, 1533, 1532, 1535, 1535, 1534, 1533,
1537, 1536, 1539, 1539, 1538, 1537, 1541, 1540, 1543, 1543, 1542, 1541, 1545, 1544, 1547, 1547, 1546, 1545,
1549, 1548, 1551, 1551, 1550, 1549, 1553, 1552, 1555, 1555, 1554, 1553, 1557, 1556, 1559, 1559, 1558, 1557,
1561, 1560, 1563, 1563, 1562, 1561, 1565, 1564, 1567, 1567, 1566, 1565, 1569, 1568, 1571, 1571, 1570, 1569,
1573, 1572, 1575, 1575, 1574, 1573, 1577, 1576, 1579, 1579, 1578, 1577, 1581, 1580, 1583, 1583, 1582, 1581,
1585, 1584, 1587, 1587, 1586, 1585, 1589, 1588, 1591, 1591, 1590, 1589, 1593, 1592, 1595, 1595, 1594, 1593,
1597, 1596, 1599, 1599, 1598, 1597, 1601, 1600, 1603, 1603, 1602, 1601, 1605, 1604, 1607, 1607, 1606, 1605,
1609, 1608, 1611, 1611, 1610, 1609, 1613, 1612, 1615, 1615, 1614, 1613, 1617, 1616, 1619, 1619, 1618, 1617,
1621, 1620, 1623, 1623, 1622, 1621, 1625, 1624, 1627, 1627, 1626, 1625, 1629, 1628, 1631, 1631, 1630, 1629,
1633, 1632, 1635, 1635, 1634, 1633, 1637, 1636, 1639, 1639, 1638, 1637, 1641, 1640, 1643, 1643, 1642, 1641,
1645, 1644, 1647, 1647, 1646, 1645, 1649, 1648, 1651, 1651, 1650, 1649, 1653, 1652, 1655, 1655, 1654, 1653,
1657, 1656, 1659, 1659, 1658, 1657, 1661, 1660, 1663, 1663, 1662, 1661, 1665, 1664, 1667, 1667, 1666, 1665,
1669, 1668, 1671, 1671, 1670, 1669, 1673, 1672, 1675, 1675, 1674, 1673, 1677, 1676, 1679, 1679, 1678, 1677,
1681, 1680, 1683, 1683, 1682, 1681, 1685, 1684, 1687, 1687, 1686, 1685, 1689, 1688, 1691, 1691, 1690, 1689,
1693, 1692, 1695, 1695, 1694, 1693, 1697, 1696, 1699, 1699, 1698, 1697, 1701, 1700, 1703, 1703, 1702, 1701,
1705, 1704, 1707, 1707, 1706, 1705, 1709, 1708, 1711, 1711, 1710, 1709, 1713, 1712, 1715, 1715, 1714, 1713,
1717, 1716, 1719, 1719, 1718, 1717, 1721, 1720, 1723, 1723, 1722, 1721, 1725, 1724, 1727, 1727, 1726, 1725,
1729, 1728, 1731, 1731, 1730, 1729, 1733, 1732, 1735, 1735, 1734, 1733, 1737, 1736, 1739, 1739, 1738, 1737,
1741, 1740, 1743, 1743, 1742, 1741, 1745, 1744, 1747, 1747, 1746, 1745, 1749, 1748, 1751, 1751, 1750, 1749,
1753, 1752, 1755, 1755, 1754, 1753, 1757, 1756, 1759, 1759, 1758, 1757, 1761, 1760, 1763, 1763, 1762, 1761,
1765, 1764, 1767, 1767, 1766, 1765, 1769, 1768, 1771, 1771, 1770, 1769, 1773, 1772, 1775, 1775, 1774, 1773,
1777, 1776, 1779, 1779, 1778, 1777, 1781, 1780, 1783, 1783, 1782, 1781, 1785, 1784, 1787, 1787, 1786, 1785,
1789, 1788, 1791, 1791, 1790, 1789, 1793, 1792, 1795, 1795, 1794, 1793, 1797, 1796, 1799, 1799, 1798, 1797,
1801, 1800, 1803, 1803, 1802, 1801, 1805, 1804, 1807, 1807, 1806, 1805, 1809, 1808, 1811, 1811, 1810, 1809,
1813, 1812, 1815, 1815, 1814, 1813, 1817, 1816, 1819, 1819, 1818, 1817, 1821, 1820, 1823, 1823, 1822, 1821,
1825, 1824, 1827, 1827, 1826, 1825, 1829, 1828, 1831, 1831, 1830, 1829, 1833, 1832, 1835, 1835, 1834, 1833,
1837, 1836, 1839, 1839, 1838, 1837, 1841, 1840, 1843, 1843, 1842, 1841, 1845, 1844, 1847, 1847, 1846, 1845,
1849, 1848, 1851, 1851, 1850, 1849, 1853, 1852, 1855, 1855, 1854, 1853, 1857, 1856, 1859, 1859, 1858, 1857,
1861, 1860, 1863, 1863, 1862, 1861, 1865, 1864, 1867, 1867, 1866, 1865, 1869, 1868, 1871, 1871, 1870, 1869,
1873, 1872, 1875, 1875, 1874, 1873, 1877, 1876, 1879, 1879, 1878, 1877, 1881, 1880, 1883, 1883, 1882, 1881,
1885, 1884, 1887, 1887, 1886, 1885, 1889, 1888, 1891, 1891, 1890, 1889, 1893, 1892, 1895, 1895, 1894, 1893,
1897, 1896, 1899, 1899, 1898, 1897, 1901, 1900, 1903, 1903, 1902, 1901, 1905, 1904, 1907, 1907, 1906, 1905,
1909, 1908, 1911, 1911, 1910, 1909, 1913, 1912, 1915, 1915, 1914, 1913, 1917, 1916, 1919, 1919, 1918, 1917,
1921, 1920, 1923, 1923, 1922, 1921, 1925, 1924, 1927, 1927, 1926, 1925, 1929, 1928, 1931, 1931, 1930, 1929,
1933, 1932, 1935, 1935, 1934, 1933, 1937, 1936, 1939, 1939, 1938, 1937, 1941, 1940, 1943, 1943, 1942, 1941,
1945, 1944, 1947, 1947, 1946, 1945, 1949, 1948, 1951, 1951, 1950, 1949, 1953, 1952, 1955, 1955, 1954, 1953,
1957, 1956, 1959, 1959, 1958, 1957, 1961, 1960, 1963, 1963, 1962, 1961, 1965, 1964, 1967, 1967, 1966, 1965,
1969, 1968, 1971, 1971, 1970, 1969, 1973, 1972, 1975, 1975, 1974, 1973, 1977, 1976, 1979, 1979, 1978, 1977,
1981, 1980, 1983, 1983, 1982, 1981, 1985, 1984, 1987, 1987, 1986, 1985, 1989, 1988, 1991, 1991, 1990, 1989,
1993, 1992, 1995, 1995, 1994, 1993, 1997, 1996, 1999, 1999, 1998, 1997, 2001, 2000, 2003, 2003, 2002, 2001,
2005, 2004, 2007, 2007, 2006, 2005, 2009, 2008, 2011, 2011, 2010, 2009, 2013, 2012, 2015, 2015, 2014, 2013,
2017, 2016, 2019, 2019, 2018, 2017, 2021, 2020, 2023, 2023, 2022, 2021, 2025, 2024, 2027, 2027, 2026, 2025,
2029, 2028, 2031, 2031, 2030, 2029, 2033, 2032, 2035, 2035, 2034, 2033, 2037, 2036, 2039, 2039, 2038, 2037,
2041, 2040, 2043, 2043, 2042, 2041, 2045, 2044, 2047, 2047, 2046, 2045
};
template
T align(T value, int bytes)
{
return (value + bytes - 1) & ~T(bytes - 1);
}
class IndexBuffer
{
public:
IndexBuffer();
~IndexBuffer();
void accommodate(int count);
void bind();
private:
GLuint m_buffer;
size_t m_size;
int m_count;
};
IndexBuffer::IndexBuffer()
{
// The maximum number of quads we can render with 16 bit indices is 16,384.
// But we start with 512 and grow the buffer as needed.
m_size = sizeof(indices);
m_count = m_size / (6 * sizeof(uint16_t));
glGenBuffers(1, &m_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}
IndexBuffer::~IndexBuffer()
{
glDeleteBuffers(1, &m_buffer);
}
void IndexBuffer::accommodate(int count)
{
// Check if we need to grow the buffer.
if (count <= m_count)
return;
count = align(count, 128);
size_t size = 6 * sizeof(uint16_t) * count;
// Create a new buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
// Use the GPU to copy the data from the old object to the new object,
glBindBuffer(GL_COPY_READ_BUFFER, m_buffer);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ELEMENT_ARRAY_BUFFER, 0, 0, m_size);
glDeleteBuffers(1, &m_buffer);
glFlush(); // Needed to work around what appears to be a CP DMA issue in r600g
// Map the new object and fill in the uninitialized section
const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
uint16_t *map = (uint16_t *) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, m_size, size - m_size, access);
const uint16_t index[] = { 1, 0, 3, 3, 2, 1 };
for (int i = m_count; i < count; i++) {
for (int j = 0; j < 6; j++)
*(map++) = i * 4 + index[j];
}
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
m_buffer = buffer;
m_count = count;
m_size = size;
}
void IndexBuffer::bind()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
}
// ------------------------------------------------------------------
class BitRef
{
public:
BitRef(uint32_t &bitfield, int bit) : m_bitfield(bitfield), m_mask(1 << bit) {}
void operator = (bool val) {
if (val)
m_bitfield |= m_mask;
else
m_bitfield &= ~m_mask;
}
operator bool () const { return m_bitfield & m_mask; }
private:
uint32_t &m_bitfield;
int const m_mask;
};
// ------------------------------------------------------------------
class Bitfield
{
public:
Bitfield() : m_bitfield(0) {}
Bitfield(uint32_t bits) : m_bitfield(bits) {}
void set(int i) { m_bitfield |= (1 << i); }
void clear(int i) { m_bitfield &= ~(1 << i); }
BitRef operator [] (int i) { return BitRef(m_bitfield, i); }
operator uint32_t () const { return m_bitfield; }
private:
uint32_t m_bitfield;
};
// ------------------------------------------------------------------
class BitfieldIterator
{
public:
BitfieldIterator(uint32_t bitfield) : m_bitfield(bitfield) {}
bool hasNext() const { return m_bitfield != 0; }
int next() {
const int bit = ffs(m_bitfield) - 1;
m_bitfield ^= (1 << bit);
return bit;
}
private:
uint32_t m_bitfield;
};
// ------------------------------------------------------------------
struct VertexAttrib
{
int size;
GLenum type;
int offset;
};
// ------------------------------------------------------------------
struct BufferFence
{
GLsync sync;
intptr_t nextEnd;
bool signaled() const
{
GLint value;
glGetSynciv(sync, GL_SYNC_STATUS, 1, nullptr, &value);
return value == GL_SIGNALED;
}
};
static void deleteAll(std::deque &fences)
{
for (const BufferFence &fence : fences)
glDeleteSync(fence.sync);
fences.clear();
}
// ------------------------------------------------------------------
template
struct FrameSizesArray
{
public:
FrameSizesArray() {
m_array.fill(0);
}
void push(size_t size) {
m_array[m_index] = size;
m_index = (m_index + 1) % Count;
}
size_t average() const {
size_t sum = 0;
for (size_t size : m_array)
sum += size;
return sum / Count;
}
private:
std::array m_array;
int m_index = 0;
};
//*********************************
// GLVertexBufferPrivate
//*********************************
class GLVertexBufferPrivate
{
public:
GLVertexBufferPrivate(GLVertexBuffer::UsageHint usageHint)
: vertexCount(0)
, persistent(false)
, useColor(false)
, color(0, 0, 0, 255)
, bufferSize(0)
, bufferEnd(0)
, mappedSize(0)
, frameSize(0)
, nextOffset(0)
, baseAddress(0)
, map(nullptr)
{
glGenBuffers(1, &buffer);
switch(usageHint) {
case GLVertexBuffer::Dynamic:
usage = GL_DYNAMIC_DRAW;
break;
case GLVertexBuffer::Static:
usage = GL_STATIC_DRAW;
break;
default:
usage = GL_STREAM_DRAW;
break;
}
}
~GLVertexBufferPrivate() {
deleteAll(fences);
if (buffer != 0) {
glDeleteBuffers(1, &buffer);
map = nullptr;
}
}
void interleaveArrays(float *array, int dim, const float *vertices, const float *texcoords, int count);
void bindArrays();
void unbindArrays();
void reallocateBuffer(size_t size);
GLvoid *mapNextFreeRange(size_t size);
void reallocatePersistentBuffer(size_t size);
bool awaitFence(intptr_t offset);
GLvoid *getIdleRange(size_t size);
GLuint buffer;
GLenum usage;
int stride;
int vertexCount;
static GLVertexBuffer *streamingBuffer;
static bool haveBufferStorage;
static bool haveSyncFences;
static bool hasMapBufferRange;
static bool supportsIndexedQuads;
QByteArray dataStore;
bool persistent;
bool useColor;
QVector4D color;
size_t bufferSize;
intptr_t bufferEnd;
size_t mappedSize;
size_t frameSize;
intptr_t nextOffset;
intptr_t baseAddress;
uint8_t *map;
std::deque fences;
FrameSizesArray<4> frameSizes;
VertexAttrib attrib[VertexAttributeCount];
Bitfield enabledArrays;
static IndexBuffer *s_indexBuffer;
};
bool GLVertexBufferPrivate::hasMapBufferRange = false;
bool GLVertexBufferPrivate::supportsIndexedQuads = false;
GLVertexBuffer *GLVertexBufferPrivate::streamingBuffer = nullptr;
bool GLVertexBufferPrivate::haveBufferStorage = false;
bool GLVertexBufferPrivate::haveSyncFences = false;
IndexBuffer *GLVertexBufferPrivate::s_indexBuffer = nullptr;
void GLVertexBufferPrivate::interleaveArrays(float *dst, int dim,
const float *vertices, const float *texcoords,
int count)
{
if (!texcoords) {
memcpy((void *) dst, vertices, dim * sizeof(float) * count);
return;
}
switch (dim)
{
case 2:
for (int i = 0; i < count; i++) {
*(dst++) = *(vertices++);
*(dst++) = *(vertices++);
*(dst++) = *(texcoords++);
*(dst++) = *(texcoords++);
}
break;
case 3:
for (int i = 0; i < count; i++) {
*(dst++) = *(vertices++);
*(dst++) = *(vertices++);
*(dst++) = *(vertices++);
*(dst++) = *(texcoords++);
*(dst++) = *(texcoords++);
}
break;
default:
for (int i = 0; i < count; i++) {
for (int j = 0; j < dim; j++)
*(dst++) = *(vertices++);
*(dst++) = *(texcoords++);
*(dst++) = *(texcoords++);
}
}
}
void GLVertexBufferPrivate::bindArrays()
{
if (useColor) {
GLShader *shader = ShaderManager::instance()->getBoundShader();
shader->setUniform(GLShader::Color, color);
}
glBindBuffer(GL_ARRAY_BUFFER, buffer);
BitfieldIterator it(enabledArrays);
while (it.hasNext()) {
const int index = it.next();
glVertexAttribPointer(index, attrib[index].size, attrib[index].type, GL_FALSE, stride,
(const GLvoid *) (baseAddress + attrib[index].offset));
glEnableVertexAttribArray(index);
}
}
void GLVertexBufferPrivate::unbindArrays()
{
BitfieldIterator it(enabledArrays);
while (it.hasNext())
glDisableVertexAttribArray(it.next());
}
void GLVertexBufferPrivate::reallocatePersistentBuffer(size_t size)
{
if (buffer != 0) {
// This also unmaps and unbinds the buffer
glDeleteBuffers(1, &buffer);
buffer = 0;
deleteAll(fences);
}
if (buffer == 0)
glGenBuffers(1, &buffer);
// Round the size up to 64 kb
size_t minSize = qMax(frameSizes.average() * 3, 128 * 1024);
bufferSize = align(qMax(size, minSize), 64 * 1024);
const GLbitfield storage = GL_DYNAMIC_STORAGE_BIT;
const GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferStorage(GL_ARRAY_BUFFER, bufferSize, nullptr, storage | access);
map = (uint8_t *) glMapBufferRange(GL_ARRAY_BUFFER, 0, bufferSize, access);
nextOffset = 0;
bufferEnd = bufferSize;
}
bool GLVertexBufferPrivate::awaitFence(intptr_t end)
{
// Skip fences until we reach the end offset
while (!fences.empty() && fences.front().nextEnd < end) {
glDeleteSync(fences.front().sync);
fences.pop_front();
}
Q_ASSERT(!fences.empty());
// Wait on the next fence
const BufferFence &fence = fences.front();
if (!fence.signaled()) {
qCDebug(LIBKWINGLUTILS) << "Stalling on VBO fence";
const GLenum ret = glClientWaitSync(fence.sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000);
if (ret == GL_TIMEOUT_EXPIRED || ret == GL_WAIT_FAILED) {
qCCritical(LIBKWINGLUTILS) << "Wait failed";
return false;
}
}
glDeleteSync(fence.sync);
// Update the end pointer
bufferEnd = fence.nextEnd;
fences.pop_front();
return true;
}
GLvoid *GLVertexBufferPrivate::getIdleRange(size_t size)
{
if (unlikely(size > bufferSize))
reallocatePersistentBuffer(size * 2);
// Handle wrap-around
if (unlikely(nextOffset + size > bufferSize)) {
nextOffset = 0;
bufferEnd -= bufferSize;
for (BufferFence &fence : fences)
fence.nextEnd -= bufferSize;
// Emit a fence now
BufferFence fence;
fence.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
fence.nextEnd = bufferSize;
fences.emplace_back(fence);
}
if (unlikely(nextOffset + intptr_t(size) > bufferEnd)) {
if (!awaitFence(nextOffset + size))
return nullptr;
}
return map + nextOffset;
}
void GLVertexBufferPrivate::reallocateBuffer(size_t size)
{
// Round the size up to 4 Kb for streaming/dynamic buffers.
const size_t minSize = 32768; // Minimum size for streaming buffers
const size_t alloc = usage != GL_STATIC_DRAW ? align(qMax(size, minSize), 4096) : size;
glBufferData(GL_ARRAY_BUFFER, alloc, nullptr, usage);
bufferSize = alloc;
}
GLvoid *GLVertexBufferPrivate::mapNextFreeRange(size_t size)
{
GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
if ((nextOffset + size) > bufferSize) {
// Reallocate the data store if it's too small.
if (size > bufferSize) {
reallocateBuffer(size);
} else {
access |= GL_MAP_INVALIDATE_BUFFER_BIT;
access ^= GL_MAP_UNSYNCHRONIZED_BIT;
}
nextOffset = 0;
}
return glMapBufferRange(GL_ARRAY_BUFFER, nextOffset, size, access);
}
//*********************************
// GLVertexBuffer
//*********************************
QRect GLVertexBuffer::s_virtualScreenGeometry;
qreal GLVertexBuffer::s_virtualScreenScale;
GLVertexBuffer::GLVertexBuffer(UsageHint hint)
: d(new GLVertexBufferPrivate(hint))
{
}
GLVertexBuffer::~GLVertexBuffer()
{
delete d;
}
void GLVertexBuffer::setData(const void *data, size_t size)
{
GLvoid *ptr = map(size);
memcpy(ptr, data, size);
unmap();
}
void GLVertexBuffer::setData(int vertexCount, int dim, const float* vertices, const float* texcoords)
{
const GLVertexAttrib layout[] = {
{ VA_Position, dim, GL_FLOAT, 0 },
{ VA_TexCoord, 2, GL_FLOAT, int(dim * sizeof(float)) }
};
int stride = (texcoords ? dim + 2 : dim) * sizeof(float);
int attribCount = texcoords ? 2 : 1;
setAttribLayout(layout, attribCount, stride);
setVertexCount(vertexCount);
GLvoid *ptr = map(vertexCount * stride);
d->interleaveArrays((float *) ptr, dim, vertices, texcoords, vertexCount);
unmap();
}
GLvoid *GLVertexBuffer::map(size_t size)
{
d->mappedSize = size;
d->frameSize += size;
if (d->persistent)
return d->getIdleRange(size);
glBindBuffer(GL_ARRAY_BUFFER, d->buffer);
bool preferBufferSubData = GLPlatform::instance()->preferBufferSubData();
if (GLVertexBufferPrivate::hasMapBufferRange && !preferBufferSubData)
return (GLvoid *) d->mapNextFreeRange(size);
// If we can't map the buffer we allocate local memory to hold the
// buffer data and return a pointer to it. The data will be submitted
// to the actual buffer object when the user calls unmap().
if (size_t(d->dataStore.size()) < size)
d->dataStore.resize(size);
return (GLvoid *) d->dataStore.data();
}
void GLVertexBuffer::unmap()
{
if (d->persistent) {
d->baseAddress = d->nextOffset;
d->nextOffset += align(d->mappedSize, 16); // Align to 16 bytes for SSE
d->mappedSize = 0;
return;
}
bool preferBufferSubData = GLPlatform::instance()->preferBufferSubData();
if (GLVertexBufferPrivate::hasMapBufferRange && !preferBufferSubData) {
glUnmapBuffer(GL_ARRAY_BUFFER);
d->baseAddress = d->nextOffset;
d->nextOffset += align(d->mappedSize, 16); // Align to 16 bytes for SSE
} else {
// Upload the data from local memory to the buffer object
if (preferBufferSubData) {
if ((d->nextOffset + d->mappedSize) > d->bufferSize) {
d->reallocateBuffer(d->mappedSize);
d->nextOffset = 0;
}
glBufferSubData(GL_ARRAY_BUFFER, d->nextOffset, d->mappedSize, d->dataStore.constData());
d->baseAddress = d->nextOffset;
d->nextOffset += align(d->mappedSize, 16); // Align to 16 bytes for SSE
} else {
glBufferData(GL_ARRAY_BUFFER, d->mappedSize, d->dataStore.data(), d->usage);
d->baseAddress = 0;
}
// Free the local memory buffer if it's unlikely to be used again
if (d->usage == GL_STATIC_DRAW)
d->dataStore = QByteArray();
}
d->mappedSize = 0;
}
void GLVertexBuffer::setVertexCount(int count)
{
d->vertexCount = count;
}
void GLVertexBuffer::setAttribLayout(const GLVertexAttrib *attribs, int count, int stride)
{
// Start by disabling all arrays
d->enabledArrays = 0;
for (int i = 0; i < count; i++) {
const int index = attribs[i].index;
Q_ASSERT(index >= 0 && index < VertexAttributeCount);
Q_ASSERT(!d->enabledArrays[index]);
d->attrib[index].size = attribs[i].size;
d->attrib[index].type = attribs[i].type;
d->attrib[index].offset = attribs[i].relativeOffset;
d->enabledArrays[index] = true;
}
d->stride = stride;
}
void GLVertexBuffer::render(GLenum primitiveMode)
{
render(infiniteRegion(), primitiveMode, false);
}
void GLVertexBuffer::render(const QRegion& region, GLenum primitiveMode, bool hardwareClipping)
{
d->bindArrays();
draw(region, primitiveMode, 0, d->vertexCount, hardwareClipping);
d->unbindArrays();
}
void GLVertexBuffer::bindArrays()
{
d->bindArrays();
}
void GLVertexBuffer::unbindArrays()
{
d->unbindArrays();
}
void GLVertexBuffer::draw(GLenum primitiveMode, int first, int count)
{
draw(infiniteRegion(), primitiveMode, first, count, false);
}
void GLVertexBuffer::draw(const QRegion ®ion, GLenum primitiveMode, int first, int count, bool hardwareClipping)
{
if (primitiveMode == GL_QUADS) {
IndexBuffer *&indexBuffer = GLVertexBufferPrivate::s_indexBuffer;
if (!indexBuffer)
indexBuffer = new IndexBuffer;
indexBuffer->bind();
indexBuffer->accommodate(count / 4);
count = count * 6 / 4;
if (!hardwareClipping) {
glDrawElementsBaseVertex(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, nullptr, first);
} else {
// Clip using scissoring
for (const QRect &r : region) {
glScissor((r.x() - s_virtualScreenGeometry.x()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() + s_virtualScreenGeometry.y() - r.y() - r.height()) * s_virtualScreenScale,
r.width() * s_virtualScreenScale,
r.height() * s_virtualScreenScale);
glDrawElementsBaseVertex(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, nullptr, first);
}
}
return;
}
if (!hardwareClipping) {
glDrawArrays(primitiveMode, first, count);
} else {
// Clip using scissoring
for (const QRect &r : region) {
glScissor((r.x() - s_virtualScreenGeometry.x()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() + s_virtualScreenGeometry.y() - r.y() - r.height()) * s_virtualScreenScale,
r.width() * s_virtualScreenScale,
r.height() * s_virtualScreenScale);
glDrawArrays(primitiveMode, first, count);
}
}
}
bool GLVertexBuffer::supportsIndexedQuads()
{
return GLVertexBufferPrivate::supportsIndexedQuads;
}
bool GLVertexBuffer::isUseColor() const
{
return d->useColor;
}
void GLVertexBuffer::setUseColor(bool enable)
{
d->useColor = enable;
}
void GLVertexBuffer::setColor(const QColor& color, bool enable)
{
d->useColor = enable;
d->color = QVector4D(color.redF(), color.greenF(), color.blueF(), color.alphaF());
}
void GLVertexBuffer::reset()
{
d->useColor = false;
d->color = QVector4D(0, 0, 0, 1);
d->vertexCount = 0;
}
void GLVertexBuffer::endOfFrame()
{
if (!d->persistent)
return;
// Emit a fence if we have uploaded data
if (d->frameSize > 0) {
d->frameSizes.push(d->frameSize);
d->frameSize = 0;
// Force the buffer to be reallocated at the beginning of the next frame
// if the average frame size is greater than half the size of the buffer
if (unlikely(d->frameSizes.average() > d->bufferSize / 2)) {
deleteAll(d->fences);
glDeleteBuffers(1, &d->buffer);
d->buffer = 0;
d->bufferSize = 0;
d->nextOffset = 0;
d->map = nullptr;
} else {
BufferFence fence;
fence.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
fence.nextEnd = d->nextOffset + d->bufferSize;
d->fences.emplace_back(fence);
}
}
}
void GLVertexBuffer::framePosted()
{
if (!d->persistent)
return;
// Remove finished fences from the list and update the bufferEnd offset
while (d->fences.size() > 1 && d->fences.front().signaled()) {
const BufferFence &fence = d->fences.front();
glDeleteSync(fence.sync);
d->bufferEnd = fence.nextEnd;
d->fences.pop_front();
}
}
void GLVertexBuffer::initStatic()
{
if (GLPlatform::instance()->isGLES()) {
bool haveBaseVertex = hasGLExtension(QByteArrayLiteral("GL_OES_draw_elements_base_vertex"));
bool haveCopyBuffer = hasGLVersion(3, 0);
bool haveMapBufferRange = hasGLExtension(QByteArrayLiteral("GL_EXT_map_buffer_range"));
GLVertexBufferPrivate::hasMapBufferRange = haveMapBufferRange;
GLVertexBufferPrivate::supportsIndexedQuads = haveBaseVertex && haveCopyBuffer && haveMapBufferRange;
GLVertexBufferPrivate::haveBufferStorage = hasGLExtension("GL_EXT_buffer_storage");
GLVertexBufferPrivate::haveSyncFences = hasGLVersion(3, 0);
} else {
bool haveBaseVertex = hasGLVersion(3, 2) || hasGLExtension(QByteArrayLiteral("GL_ARB_draw_elements_base_vertex"));
bool haveCopyBuffer = hasGLVersion(3, 1) || hasGLExtension(QByteArrayLiteral("GL_ARB_copy_buffer"));
bool haveMapBufferRange = hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_ARB_map_buffer_range"));
GLVertexBufferPrivate::hasMapBufferRange = haveMapBufferRange;
GLVertexBufferPrivate::supportsIndexedQuads = haveBaseVertex && haveCopyBuffer && haveMapBufferRange;
GLVertexBufferPrivate::haveBufferStorage = hasGLVersion(4, 4) || hasGLExtension("GL_ARB_buffer_storage");
GLVertexBufferPrivate::haveSyncFences = hasGLVersion(3, 2) || hasGLExtension("GL_ARB_sync");
}
GLVertexBufferPrivate::s_indexBuffer = nullptr;
GLVertexBufferPrivate::streamingBuffer = new GLVertexBuffer(GLVertexBuffer::Stream);
if (GLVertexBufferPrivate::haveBufferStorage && GLVertexBufferPrivate::haveSyncFences) {
if (qgetenv("KWIN_PERSISTENT_VBO") != QByteArrayLiteral("0")) {
GLVertexBufferPrivate::streamingBuffer->d->persistent = true;
}
}
}
void GLVertexBuffer::cleanup()
{
delete GLVertexBufferPrivate::s_indexBuffer;
GLVertexBufferPrivate::s_indexBuffer = nullptr;
GLVertexBufferPrivate::hasMapBufferRange = false;
GLVertexBufferPrivate::supportsIndexedQuads = false;
delete GLVertexBufferPrivate::streamingBuffer;
GLVertexBufferPrivate::streamingBuffer = nullptr;
}
GLVertexBuffer *GLVertexBuffer::streamingBuffer()
{
return GLVertexBufferPrivate::streamingBuffer;
}
} // namespace
diff --git a/libkwineffects/kwinglutils.h b/libkwineffects/kwinglutils.h
index cea03f39d..39f0a780c 100644
--- a/libkwineffects/kwinglutils.h
+++ b/libkwineffects/kwinglutils.h
@@ -1,837 +1,829 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006-2007 Rivo Laks
Copyright (C) 2010, 2011 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_GLUTILS_H
#define KWIN_GLUTILS_H
// kwin
#include
#include "kwinglutils_funcs.h"
#include "kwingltexture.h"
// Qt
#include
#include
/** @addtogroup kwineffects */
/** @{ */
class QVector2D;
class QVector3D;
class QVector4D;
class QMatrix4x4;
template< class K, class V > class QHash;
namespace KWin
{
class GLVertexBuffer;
class GLVertexBufferPrivate;
// Initializes OpenGL stuff. This includes resolving function pointers as
// well as checking for GL version and extensions
// Note that GL context has to be created by the time this function is called
typedef void (*resolveFuncPtr)();
void KWINGLUTILS_EXPORT initGL(const std::function &resolveFunction);
// Cleans up all resources hold by the GL Context
void KWINGLUTILS_EXPORT cleanupGL();
bool KWINGLUTILS_EXPORT hasGLVersion(int major, int minor, int release = 0);
// use for both OpenGL and GLX extensions
bool KWINGLUTILS_EXPORT hasGLExtension(const QByteArray &extension);
// detect OpenGL error (add to various places in code to pinpoint the place)
bool KWINGLUTILS_EXPORT checkGLError(const char* txt);
QList KWINGLUTILS_EXPORT openGLExtensions();
class KWINGLUTILS_EXPORT GLShader
{
public:
enum Flags {
NoFlags = 0,
ExplicitLinking = (1 << 0)
};
GLShader(const QString &vertexfile, const QString &fragmentfile, unsigned int flags = NoFlags);
~GLShader();
bool isValid() const {
return mValid;
}
void bindAttributeLocation(const char *name, int index);
void bindFragDataLocation(const char *name, int index);
bool link();
int uniformLocation(const char* name);
bool setUniform(const char* name, float value);
bool setUniform(const char* name, int value);
bool setUniform(const char* name, const QVector2D& value);
bool setUniform(const char* name, const QVector3D& value);
bool setUniform(const char* name, const QVector4D& value);
bool setUniform(const char* name, const QMatrix4x4& value);
bool setUniform(const char* name, const QColor& color);
bool setUniform(int location, float value);
bool setUniform(int location, int value);
bool setUniform(int location, const QVector2D &value);
bool setUniform(int location, const QVector3D &value);
bool setUniform(int location, const QVector4D &value);
bool setUniform(int location, const QMatrix4x4 &value);
bool setUniform(int location, const QColor &value);
int attributeLocation(const char* name);
bool setAttribute(const char* name, float value);
/**
* @return The value of the uniform as a matrix
* @since 4.7
*/
QMatrix4x4 getUniformMatrix4x4(const char* name);
enum MatrixUniform {
TextureMatrix = 0,
ProjectionMatrix,
ModelViewMatrix,
ModelViewProjectionMatrix,
WindowTransformation,
ScreenTransformation,
MatrixCount
};
enum Vec2Uniform {
Offset,
Vec2UniformCount
};
enum Vec4Uniform {
ModulationConstant,
TextureClamp,
Vec4UniformCount
};
enum FloatUniform {
Saturation,
FloatUniformCount
};
enum IntUniform {
AlphaToOne, ///< @deprecated no longer used
IntUniformCount
};
enum ColorUniform {
Color,
ColorUniformCount
};
bool setUniform(MatrixUniform uniform, const QMatrix4x4 &matrix);
bool setUniform(Vec2Uniform uniform, const QVector2D &value);
bool setUniform(Vec4Uniform uniform, const QVector4D &value);
bool setUniform(FloatUniform uniform, float value);
bool setUniform(IntUniform uniform, int value);
bool setUniform(ColorUniform uniform, const QVector4D &value);
bool setUniform(ColorUniform uniform, const QColor &value);
protected:
GLShader(unsigned int flags = NoFlags);
bool loadFromFiles(const QString& vertexfile, const QString& fragmentfile);
bool load(const QByteArray &vertexSource, const QByteArray &fragmentSource);
const QByteArray prepareSource(GLenum shaderType, const QByteArray &sourceCode) const;
bool compile(GLuint program, GLenum shaderType, const QByteArray &sourceCode) const;
void bind();
void unbind();
void resolveLocations();
private:
unsigned int mProgram;
bool mValid:1;
bool mLocationsResolved:1;
bool mExplicitLinking:1;
int mMatrixLocation[MatrixCount];
int mVec2Location[Vec2UniformCount];
int mVec4Location[Vec4UniformCount];
int mFloatLocation[FloatUniformCount];
int mIntLocation[IntUniformCount];
int mColorLocation[ColorUniformCount];
friend class ShaderManager;
};
enum class ShaderTrait {
MapTexture = (1 << 0),
UniformColor = (1 << 1),
Modulate = (1 << 2),
AdjustSaturation = (1 << 3),
ClampTexture = (1 << 4),
};
Q_DECLARE_FLAGS(ShaderTraits, ShaderTrait)
/**
* @short Manager for Shaders.
*
* This class provides some built-in shaders to be used by both compositing scene and effects.
* The ShaderManager provides methods to bind a built-in or a custom shader and keeps track of
* the shaders which have been bound. When a shader is unbound the previously bound shader
* will be rebound.
*
* @author Martin Gräßlin
* @since 4.7
*/
class KWINGLUTILS_EXPORT ShaderManager
{
public:
/**
* Returns a shader with the given traits, creating it if necessary.
*/
GLShader *shader(ShaderTraits traits);
/**
* @return The currently bound shader or @c null if no shader is bound.
*/
GLShader *getBoundShader() const;
/**
* @return @c true if a shader is bound, @c false otherwise
*/
bool isShaderBound() const;
- /**
- * Is @c true if the environment variable KWIN_GL_DEBUG is set to 1.
- * In that case shaders are compiled with KWIN_SHADER_DEBUG defined.
- * @returns @c true if shaders are compiled with debug information
- * @since 4.8
- */
- bool isShaderDebug() const;
/**
* Pushes the current shader onto the stack and binds a shader
* with the given traits.
*/
GLShader *pushShader(ShaderTraits traits);
/**
* Binds the @p shader.
* To unbind the shader use popShader. A previous bound shader will be rebound.
* To bind a built-in shader use the more specific method.
* @param shader The shader to be bound
* @see popShader
*/
void pushShader(GLShader *shader);
/**
* Unbinds the currently bound shader and rebinds a previous stored shader.
* If there is no previous shader, no shader will be rebound.
* It is not safe to call this method if there is no bound shader.
* @see pushShader
* @see getBoundShader
*/
void popShader();
/**
* Creates a GLShader with the specified sources.
* The difference to GLShader is that it does not need to be loaded from files.
* @param vertexSource The source code of the vertex shader
* @param fragmentSource The source code of the fragment shader.
* @return The created shader
*/
GLShader *loadShaderFromCode(const QByteArray &vertexSource, const QByteArray &fragmentSource);
/**
* Creates a custom shader with the given @p traits and custom @p vertexSource and or @p fragmentSource.
* If the @p vertexSource is empty a vertex shader with the given @p traits is generated.
* If it is not empty the @p vertexSource is used as the source for the vertex shader.
*
* The same applies for argument @p fragmentSource just for the fragment shader.
*
* So if both @p vertesSource and @p fragmentSource are provided the @p traits are ignored.
* If neither are provided a new shader following the @p traits is generated.
*
* @param traits The shader traits for generating the shader
* @param vertexSource optional vertex shader source code to be used instead of shader traits
* @param fragmentSource optional fragment shader source code to be used instead of shader traits
* @return new generated shader
* @since 5.6
*/
GLShader *generateCustomShader(ShaderTraits traits, const QByteArray &vertexSource = QByteArray(), const QByteArray &fragmentSource = QByteArray());
/**
* Creates a custom shader with the given @p traits and custom @p vertexFile and or @p fragmentFile.
* The file names specified in @p vertexFile and @p fragmentFile are relative paths to the shaders
* resource file shipped together with KWin. This means this method can only be used for built-in
* effects, for 3rd party effects generateCustomShader should be used.
*
* If the @p vertexFile is empty a vertex shader with the given @p traits is generated.
* If it is not empty the @p vertexFile is used as the source for the vertex shader.
*
* The same applies for argument @p fragmentFile just for the fragment shader.
*
* So if both @p vertexFile and @p fragmentFile are provided the @p traits are ignored.
* If neither are provided a new shader following the @p traits is generated.
*
* @param traits The shader traits for generating the shader
* @param vertexFile optional vertex shader source code to be used instead of shader traits
* @param fragmentFile optional fragment shader source code to be used instead of shader traits
* @return new generated shader
* @see generateCustomShader
* @since 5.6
*/
GLShader *generateShaderFromResources(ShaderTraits traits, const QString &vertexFile = QString(), const QString &fragmentFile = QString());
/**
* Compiles and tests the dynamically generated shaders.
* Returns true if successful and false otherwise.
*/
bool selfTest();
/**
* @return a pointer to the ShaderManager instance
*/
static ShaderManager *instance();
/**
* @internal
*/
static void cleanup();
private:
ShaderManager();
~ShaderManager();
void bindFragDataLocations(GLShader *shader);
void bindAttributeLocations(GLShader *shader) const;
QByteArray generateVertexSource(ShaderTraits traits) const;
QByteArray generateFragmentSource(ShaderTraits traits) const;
GLShader *generateShader(ShaderTraits traits);
QStack m_boundShaders;
QHash m_shaderHash;
- bool m_debug;
QString m_resourcePath;
static ShaderManager *s_shaderManager;
};
/**
* An helper class to push a Shader on to ShaderManager's stack and ensuring that the Shader
* gets popped again from the stack automatically once the object goes out of life.
*
* How to use:
* @code
* {
* GLShader *myCustomShaderIWantToPush;
* ShaderBinder binder(myCustomShaderIWantToPush);
* // do stuff with the shader being pushed on the stack
* }
* // here the Shader is automatically popped as helper does no longer exist.
* @endcode
*
* @since 4.10
*/
class KWINGLUTILS_EXPORT ShaderBinder
{
public:
/**
* @brief Pushes the given @p shader to the ShaderManager's stack.
*
* @param shader The Shader to push on the stack
* @see ShaderManager::pushShader
*/
explicit ShaderBinder(GLShader *shader);
/**
* @brief Pushes the Shader with the given @p traits to the ShaderManager's stack.
*
* @param traits The traits describing the shader
* @see ShaderManager::pushShader
* @since 5.6
*/
explicit ShaderBinder(ShaderTraits traits);
~ShaderBinder();
/**
* @return The Shader pushed to the Stack.
*/
GLShader *shader();
private:
GLShader *m_shader;
};
inline
ShaderBinder::ShaderBinder(GLShader *shader)
: m_shader(shader)
{
ShaderManager::instance()->pushShader(shader);
}
inline
ShaderBinder::ShaderBinder(ShaderTraits traits)
: m_shader(nullptr)
{
m_shader = ShaderManager::instance()->pushShader(traits);
}
inline
ShaderBinder::~ShaderBinder()
{
ShaderManager::instance()->popShader();
}
inline
GLShader* ShaderBinder::shader()
{
return m_shader;
}
/**
* @short Render target object
*
* Render target object enables you to render onto a texture. This texture can
* later be used to e.g. do post-processing of the scene.
*
* @author Rivo Laks
*/
class KWINGLUTILS_EXPORT GLRenderTarget
{
public:
/**
* Constructs a GLRenderTarget
* @since 5.13
*/
explicit GLRenderTarget();
/**
* Constructs a GLRenderTarget
* @param color texture where the scene will be rendered onto
*/
explicit GLRenderTarget(const GLTexture& color);
~GLRenderTarget();
/**
* Enables this render target.
* All OpenGL commands from now on affect this render target until the
* @ref disable method is called
*/
bool enable();
/**
* Disables this render target, activating whichever target was active
* when @ref enable was called.
*/
bool disable();
/**
* Sets the target texture
* @param target texture where the scene will be rendered on
* @since 4.8
*/
void attachTexture(const GLTexture& target);
/**
* Detaches the texture that is currently attached to this framebuffer object.
* @since 5.13
*/
void detachTexture();
bool valid() const {
return mValid;
}
void setTextureDirty() {
mTexture.setDirty();
}
static void initStatic();
static bool supported() {
return sSupported;
}
/**
* Pushes the render target stack of the input parameter in reverse order.
* @param targets The stack of GLRenderTargets
* @since 5.13
*/
static void pushRenderTargets(QStack targets);
static void pushRenderTarget(GLRenderTarget *target);
static GLRenderTarget *popRenderTarget();
static bool isRenderTargetBound();
/**
* Whether the GL_EXT_framebuffer_blit extension is supported.
* This functionality is not available in OpenGL ES 2.0.
*
* @returns whether framebuffer blitting is supported.
* @since 4.8
*/
static bool blitSupported();
/**
* Blits the content of the current draw framebuffer into the texture attached to this FBO.
*
* Be aware that framebuffer blitting may not be supported on all hardware. Use blitSupported to check whether
* it is supported.
* @param source Geometry in screen coordinates which should be blitted, if not specified complete framebuffer is used
* @param destination Geometry in attached texture, if not specified complete texture is used as destination
* @param filter The filter to use if blitted content needs to be scaled.
* @see blitSupported
* @since 4.8
*/
void blitFromFramebuffer(const QRect &source = QRect(), const QRect &destination = QRect(), GLenum filter = GL_LINEAR);
/**
* Sets the virtual screen size to @p s.
* @since 5.2
*/
static void setVirtualScreenSize(const QSize &s) {
s_virtualScreenSize = s;
}
/**
* Sets the virtual screen geometry to @p g.
* This is the geometry of the OpenGL window currently being rendered to
* in the virtual geometry space the rendering geometries use.
* @see virtualScreenGeometry
* @since 5.9
*/
static void setVirtualScreenGeometry(const QRect &g) {
s_virtualScreenGeometry = g;
}
/**
* The geometry of the OpenGL window currently being rendered to
* in the virtual geometry space the rendering system uses.
* @see setVirtualScreenGeometry
* @since 5.9
*/
static QRect virtualScreenGeometry() {
return s_virtualScreenGeometry;
}
/**
* The scale of the OpenGL window currently being rendered to
*
* @returns the ratio between the virtual geometry space the rendering
* system uses and the target
* @since 5.10
*/
static void setVirtualScreenScale(qreal scale) {
s_virtualScreenScale = scale;
}
static qreal virtualScreenScale() {
return s_virtualScreenScale;
}
/**
* The framebuffer of KWin's OpenGL window or other object currently being rendered to
*
* @since 5.18
*/
static void setKWinFramebuffer(GLuint fb) {
s_kwinFramebuffer = fb;
}
protected:
void initFBO();
private:
friend void KWin::cleanupGL();
static void cleanup();
static bool sSupported;
static bool s_blitSupported;
static QStack s_renderTargets;
static QSize s_virtualScreenSize;
static QRect s_virtualScreenGeometry;
static qreal s_virtualScreenScale;
static GLint s_virtualScreenViewport[4];
static GLuint s_kwinFramebuffer;
GLTexture mTexture;
bool mValid;
GLuint mFramebuffer;
};
enum VertexAttributeType {
VA_Position = 0,
VA_TexCoord = 1,
VertexAttributeCount = 2
};
/**
* Describes the format of a vertex attribute stored in a buffer object.
*
* The attribute format consists of the attribute index, the number of
* vector components, the data type, and the offset of the first element
* relative to the start of the vertex data.
*/
struct GLVertexAttrib
{
int index; /** The attribute index */
int size; /** The number of components [1..4] */
GLenum type; /** The type (e.g. GL_FLOAT) */
int relativeOffset; /** The relative offset of the attribute */
};
/**
* @short Vertex Buffer Object
*
* This is a short helper class to use vertex buffer objects (VBO). A VBO can be used to buffer
* vertex data and to store them on graphics memory. It is the only allowed way to pass vertex
* data to the GPU in OpenGL ES 2 and OpenGL 3 with forward compatible mode.
*
* If VBOs are not supported on the used OpenGL profile this class falls back to legacy
* rendering using client arrays. Therefore this class should always be used for rendering geometries.
*
* @author Martin Gräßlin
* @since 4.6
*/
class KWINGLUTILS_EXPORT GLVertexBuffer
{
public:
/**
* Enum to define how often the vertex data in the buffer object changes.
*/
enum UsageHint {
Dynamic, ///< frequent changes, but used several times for rendering
Static, ///< No changes to data
Stream ///< Data only used once for rendering, updated very frequently
};
explicit GLVertexBuffer(UsageHint hint);
~GLVertexBuffer();
/**
* Specifies how interleaved vertex attributes are laid out in
* the buffer object.
*
* Note that the attributes and the stride should be 32 bit aligned
* or a performance penalty may be incurred.
*
* For some hardware the optimal stride is a multiple of 32 bytes.
*
* Example:
*
* struct Vertex {
* QVector3D position;
* QVector2D texcoord;
* };
*
* const GLVertexAttrib attribs[] = {
* { VA_Position, 3, GL_FLOAT, offsetof(Vertex, position) },
* { VA_TexCoord, 2, GL_FLOAT, offsetof(Vertex, texcoord) }
* };
*
* Vertex vertices[6];
* vbo->setAttribLayout(attribs, 2, sizeof(Vertex));
* vbo->setData(vertices, sizeof(vertices));
*/
void setAttribLayout(const GLVertexAttrib *attribs, int count, int stride);
/**
* Uploads data into the buffer object's data store.
*/
void setData(const void *data, size_t sizeInBytes);
/**
* Sets the number of vertices that will be drawn by the render() method.
*/
void setVertexCount(int count);
/**
* Sets the vertex data.
* @param numberVertices The number of vertices in the arrays
* @param dim The dimension of the vertices: 2 for x/y, 3 for x/y/z
* @param vertices The vertices, size must equal @a numberVertices * @a dim
* @param texcoords The texture coordinates for each vertex.
* Size must equal 2 * @a numberVertices.
*/
void setData(int numberVertices, int dim, const float* vertices, const float* texcoords);
/**
* Maps an unused range of the data store into the client's address space.
*
* The data store will be reallocated if it is smaller than the given size.
*
* The buffer object is mapped for writing, not reading. Attempts to read from
* the mapped buffer range may result in system errors, including program
* termination. The data in the mapped region is undefined until it has been
* written to. If subsequent GL calls access unwritten memory, the results are
* undefined and system errors, including program termination, may occur.
*
* No GL calls that access the buffer object must be made while the buffer
* object is mapped. The returned pointer must not be passed as a parameter
* value to any GL function.
*
* It is assumed that the GL_ARRAY_BUFFER_BINDING will not be changed while
* the buffer object is mapped.
*/
GLvoid *map(size_t size);
/**
* Flushes the mapped buffer range and unmaps the buffer.
*/
void unmap();
/**
* Binds the vertex arrays to the context.
*/
void bindArrays();
/**
* Disables the vertex arrays.
*/
void unbindArrays();
/**
* Draws count vertices beginning with first.
*/
void draw(GLenum primitiveMode, int first, int count);
/**
* Draws count vertices beginning with first.
*/
void draw(const QRegion ®ion, GLenum primitiveMode, int first, int count, bool hardwareClipping = false);
/**
* Renders the vertex data in given @a primitiveMode.
* Please refer to OpenGL documentation of glDrawArrays or glDrawElements for allowed
* values for @a primitiveMode. Best is to use GL_TRIANGLES or similar to be future
* compatible.
*/
void render(GLenum primitiveMode);
/**
* Same as above restricting painting to @a region if @a hardwareClipping is true.
* It's within the caller's responsibility to enable GL_SCISSOR_TEST.
*/
void render(const QRegion& region, GLenum primitiveMode, bool hardwareClipping = false);
/**
* Sets the color the geometry will be rendered with.
* For legacy rendering glColor is used before rendering the geometry.
* For core shader a uniform "geometryColor" is expected and is set.
* @param color The color to render the geometry
* @param enableColor Whether the geometry should be rendered with a color or not
* @see setUseColor
* @see isUseColor
* @since 4.7
*/
void setColor(const QColor& color, bool enableColor = true);
/**
* @return @c true if geometry will be painted with a color, @c false otherwise
* @see setUseColor
* @see setColor
* @since 4.7
*/
bool isUseColor() const;
/**
* Enables/Disables rendering the geometry with a color.
* If no color is set an opaque, black color is used.
* @param enable Enable/Disable rendering with color
* @see isUseColor
* @see setColor
* @since 4.7
*/
void setUseColor(bool enable);
/**
* Resets the instance to default values.
* Useful for shared buffers.
* @since 4.7
*/
void reset();
/**
* Notifies the vertex buffer that we are done painting the frame.
*
* @internal
*/
void endOfFrame();
/**
* Notifies the vertex buffer that we have posted the frame.
*
* @internal
*/
void framePosted();
/**
* @internal
*/
static void initStatic();
/**
* @internal
*/
static void cleanup();
/**
* Returns true if indexed quad mode is supported, and false otherwise.
*/
static bool supportsIndexedQuads();
/**
* @return A shared VBO for streaming data
* @since 4.7
*/
static GLVertexBuffer *streamingBuffer();
/**
* Sets the virtual screen geometry to @p g.
* This is the geometry of the OpenGL window currently being rendered to
* in the virtual geometry space the rendering geometries use.
* @since 5.9
*/
static void setVirtualScreenGeometry(const QRect &g) {
s_virtualScreenGeometry = g;
}
/**
* The scale of the OpenGL window currently being rendered to
*
* @returns the ratio between the virtual geometry space the rendering
* system uses and the target
* @since 5.11.3
*/
static void setVirtualScreenScale(qreal s) {
s_virtualScreenScale = s;
}
private:
GLVertexBufferPrivate* const d;
static QRect s_virtualScreenGeometry;
static qreal s_virtualScreenScale;
};
} // namespace
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::ShaderTraits)
/** @} */
#endif
diff --git a/plugins/kdecorations/aurorae/themes/plastik/code/plastikplugin.cpp b/plugins/kdecorations/aurorae/themes/plastik/code/plastikplugin.cpp
index 25d11251f..e121d6d94 100644
--- a/plugins/kdecorations/aurorae/themes/plastik/code/plastikplugin.cpp
+++ b/plugins/kdecorations/aurorae/themes/plastik/code/plastikplugin.cpp
@@ -1,33 +1,31 @@
/********************************************************************
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 .
*********************************************************************/
#include "plastikplugin.h"
#include "plastikbutton.h"
#include
void PlastikPlugin::registerTypes(const char *uri)
{
Q_UNUSED(uri)
}
void PlastikPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.kwin.decorations.plastik"));
engine->addImageProvider(QLatin1String("plastik"), new KWin::PlastikButtonProvider());
QQmlExtensionPlugin::initializeEngine(engine, uri);
}
-
-#include "moc_plastikplugin.cpp"
diff --git a/plugins/kpackage/effect/kwin-packagestructure-effect.desktop b/plugins/kpackage/effect/kwin-packagestructure-effect.desktop
index 439d4a9d9..b7b8c007b 100644
--- a/plugins/kpackage/effect/kwin-packagestructure-effect.desktop
+++ b/plugins/kpackage/effect/kwin-packagestructure-effect.desktop
@@ -1,41 +1,42 @@
[Desktop Entry]
Name=KWin Effect
Name[ca]=Efecte del KWin
Name[ca@valencia]=Efecte de KWin
Name[cs]=Efekt KWinu
Name[da]=KWin-effekt
Name[de]=KWin-Effekt
Name[el]=Εφέ KWin
Name[en_GB]=KWin Effect
Name[es]=Efecto de KWin
Name[et]=KWini efekt
Name[eu]=KWin efektua
Name[fi]=KWin-tehoste
Name[fr]=Effet KWin
Name[gl]=Efecto de KWin
Name[hu]=KWin effektus
Name[ia]=Effecto de KWin
Name[id]=Efek KWin
Name[it]=Effetto di KWin
Name[ko]=KWin 효과
Name[lt]=KWin efektas
Name[nl]=KWin-effect
Name[nn]=KWin-effekt
Name[pl]=Efekt KWin
Name[pt]=Efeito do KWin
Name[pt_BR]=Efeito do KWin
Name[ru]=Эффект диспетчера окон
Name[sk]=Efekty KWin
+Name[sl]=Učinek KWin
Name[sv]=Kwin-effekt
Name[uk]=Ефект KWin
Name[x-test]=xxKWin Effectxx
Name[zh_CN]=KWin 效果
Name[zh_TW]=KWin 效果
Type=Service
X-KDE-ServiceTypes=KPackage/PackageStructure
X-KDE-Library=kwin_packagestructure_effect
X-KDE-PluginInfo-Author=Vlad Zahorodnii
X-KDE-PluginInfo-Email=vlad.zahorodnii@kde.org
X-KDE-PluginInfo-Name=KWin/Effect
X-KDE-PluginInfo-Version=1
diff --git a/plugins/platforms/wayland/wayland_backend.cpp b/plugins/platforms/wayland/wayland_backend.cpp
index c88d08871..2a6bde797 100644
--- a/plugins/platforms/wayland/wayland_backend.cpp
+++ b/plugins/platforms/wayland/wayland_backend.cpp
@@ -1,840 +1,840 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright 2019 Roman Gilg
Copyright 2013 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 "wayland_backend.h"
#if HAVE_WAYLAND_EGL
#include "egl_wayland_backend.h"
#endif
#include "logging.h"
#include "scene_qpainter_wayland_backend.h"
#include "wayland_output.h"
#include "composite.h"
#include "cursor.h"
#include "input.h"
#include "main.h"
#include "outputscreens.h"
#include "pointer_input.h"
#include "screens.h"
#include "wayland_cursor_theme.h"
#include "wayland_server.h"
#include
#include
#include
#include
#include
#include