Make it possible to build KWin without libxcb

Now that we have Wayland around, there's a whole branch of dependencies
that shouldn't be necessary anymore.
This allows to build KWin without all of it, allowing us to have a much
more compact alignment for cases where all the legacy software isn't
necessary anymore.

Bundle KWindowSystem X11-specific headers into it too, since it's part
of the same process.

Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
This commit is contained in:
Aleix Pol Gonzalez 2023-12-15 17:58:46 +01:00 committed by Aleix Pol Gonzalez
parent 94121c2a42
commit bf1ce85474
94 changed files with 1484 additions and 740 deletions

View file

@ -11,4 +11,4 @@ suse_tumbleweed_qt66_reduced_featureset:
extends: suse_tumbleweed_qt66 extends: suse_tumbleweed_qt66
script: script:
- git config --global --add safe.directory $CI_PROJECT_DIR - git config --global --add safe.directory $CI_PROJECT_DIR
- python3 -u ci-utilities/run-ci-build.py --project $CI_PROJECT_NAME --branch $CI_COMMIT_REF_NAME --platform Linux --extra-cmake-args="-DKWIN_BUILD_KCMS=OFF -DKWIN_BUILD_SCREENLOCKER=OFF -DKWIN_BUILD_TABBOX=OFF -DKWIN_BUILD_ACTIVITIES=OFF -DKWIN_BUILD_RUNNERS=OFF -DKWIN_BUILD_NOTIFICATIONS=OFF -DKWIN_BUILD_GLOBALSHORTCUTS=OFF" --skip-publishing - python3 -u ci-utilities/run-ci-build.py --project $CI_PROJECT_NAME --branch $CI_COMMIT_REF_NAME --platform Linux --extra-cmake-args="-DKWIN_BUILD_KCMS=OFF -DKWIN_BUILD_SCREENLOCKER=OFF -DKWIN_BUILD_TABBOX=OFF -DKWIN_BUILD_ACTIVITIES=OFF -DKWIN_BUILD_RUNNERS=OFF -DKWIN_BUILD_NOTIFICATIONS=OFF -DKWIN_BUILD_GLOBALSHORTCUTS=OFF -DKWIN_BUILD_X11=OFF" --skip-publishing

View file

@ -47,6 +47,7 @@ option(KWIN_BUILD_KCMS "Enable building of KWin configuration modules." ON)
option(KWIN_BUILD_NOTIFICATIONS "Enable building of KWin with knotifications support" ON) option(KWIN_BUILD_NOTIFICATIONS "Enable building of KWin with knotifications support" ON)
option(KWIN_BUILD_SCREENLOCKER "Enable building of KWin lockscreen functionality" ON) option(KWIN_BUILD_SCREENLOCKER "Enable building of KWin lockscreen functionality" ON)
option(KWIN_BUILD_TABBOX "Enable building of KWin Tabbox functionality" ON) option(KWIN_BUILD_TABBOX "Enable building of KWin Tabbox functionality" ON)
option(KWIN_BUILD_X11 "Enable building kwin_x11 and Xwayland support" ON)
find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Concurrent Concurrent
@ -232,8 +233,58 @@ else()
set(HAVE_XKBCOMMON_NO_SECURE_GETENV 0) set(HAVE_XKBCOMMON_NO_SECURE_GETENV 0)
endif() endif()
pkg_check_modules(XKBX11 IMPORTED_TARGET xkbcommon-x11 REQUIRED) if (KWIN_BUILD_X11)
add_feature_info(XKBX11 XKBX11_FOUND "Required for handling keyboard events in X11 backend") pkg_check_modules(XKBX11 IMPORTED_TARGET xkbcommon-x11 REQUIRED)
add_feature_info(XKBX11 XKBX11_FOUND "Required for handling keyboard events in X11 backend")
# All the required XCB components
find_package(XCB 1.10 REQUIRED COMPONENTS
COMPOSITE
CURSOR
DAMAGE
DRI3
GLX
ICCCM
IMAGE
KEYSYMS
PRESENT
RANDR
RENDER
SHAPE
SHM
SYNC
XCB
XFIXES
XKB
XINERAMA
)
set_package_properties(XCB PROPERTIES TYPE REQUIRED)
find_package(X11_XCB)
set_package_properties(X11_XCB PROPERTIES
PURPOSE "Required for building X11 windowed backend of kwin_wayland"
TYPE OPTIONAL
)
find_package(Xwayland)
set_package_properties(Xwayland PROPERTIES
URL "https://x.org"
DESCRIPTION "Xwayland X server"
TYPE RUNTIME
PURPOSE "Needed for running kwin_wayland"
)
set(HAVE_XWAYLAND_LISTENFD ${Xwayland_HAVE_LISTENFD})
set(HAVE_GLX ${epoxy_HAS_GLX})
get_target_property(QT_DISABLED_FEATURES Qt6::Gui QT_DISABLED_PUBLIC_FEATURES)
if("xcb_glx_plugin" IN_LIST QT_DISABLED_FEATURES)
message(STATUS "Disable GLX because Qt6::Gui was built without xcb_glx_plugin")
set(HAVE_GLX false)
endif()
# for kwin internal things
set(HAVE_X11_XCB ${X11_XCB_FOUND})
endif()
find_package(Libinput 1.19) find_package(Libinput 1.19)
set_package_properties(Libinput PROPERTIES TYPE REQUIRED PURPOSE "Required for input handling on Wayland.") set_package_properties(Libinput PROPERTIES TYPE REQUIRED PURPOSE "Required for input handling on Wayland.")
@ -282,35 +333,6 @@ set_package_properties(lcms2 PROPERTIES
PURPOSE "Required for the color management system" PURPOSE "Required for the color management system"
) )
# All the required XCB components
find_package(XCB 1.10 REQUIRED COMPONENTS
COMPOSITE
CURSOR
DAMAGE
DRI3
GLX
ICCCM
IMAGE
KEYSYMS
PRESENT
RANDR
RENDER
SHAPE
SHM
SYNC
XCB
XFIXES
XKB
XINERAMA
)
set_package_properties(XCB PROPERTIES TYPE REQUIRED)
find_package(X11_XCB)
set_package_properties(X11_XCB PROPERTIES
PURPOSE "Required for building X11 windowed backend of kwin_wayland"
TYPE OPTIONAL
)
find_package(Freetype) find_package(Freetype)
set_package_properties(Freetype PROPERTIES set_package_properties(Freetype PROPERTIES
DESCRIPTION "A font rendering engine" DESCRIPTION "A font rendering engine"
@ -324,15 +346,6 @@ set_package_properties(Fontconfig PROPERTIES
PURPOSE "Needed for KWin's QPA plugin." 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"
)
set(HAVE_XWAYLAND_LISTENFD ${Xwayland_HAVE_LISTENFD})
find_package(Libcap) find_package(Libcap)
set_package_properties(Libcap PROPERTIES set_package_properties(Libcap PROPERTIES
TYPE OPTIONAL TYPE OPTIONAL
@ -382,16 +395,6 @@ ecm_find_qmlmodule(org.kde.plasma.components 2.0)
cmake_dependent_option(KWIN_BUILD_ACTIVITIES "Enable building of KWin with kactivities support" ON "PlasmaActivities_FOUND" OFF) cmake_dependent_option(KWIN_BUILD_ACTIVITIES "Enable building of KWin with kactivities support" ON "PlasmaActivities_FOUND" OFF)
option(KWIN_BUILD_RUNNERS "Enable building of KWin with krunner support" ON) option(KWIN_BUILD_RUNNERS "Enable building of KWin with krunner support" ON)
set(HAVE_GLX ${epoxy_HAS_GLX})
get_target_property(QT_DISABLED_FEATURES Qt6::Gui QT_DISABLED_PUBLIC_FEATURES)
if("xcb_glx_plugin" IN_LIST QT_DISABLED_FEATURES)
message(STATUS "Disable GLX because Qt6::Gui was built without xcb_glx_plugin")
set(HAVE_GLX false)
endif()
# for kwin internal things
set(HAVE_X11_XCB ${X11_XCB_FOUND})
check_symbol_exists(SCHED_RESET_ON_FORK "sched.h" HAVE_SCHED_RESET_ON_FORK) check_symbol_exists(SCHED_RESET_ON_FORK "sched.h" HAVE_SCHED_RESET_ON_FORK)
add_feature_info("SCHED_RESET_ON_FORK" add_feature_info("SCHED_RESET_ON_FORK"
HAVE_SCHED_RESET_ON_FORK HAVE_SCHED_RESET_ON_FORK

View file

@ -45,82 +45,97 @@ ecm_mark_as_test(testVirtualDesktops)
######################################################## ########################################################
# Test ClientMachine # Test ClientMachine
######################################################## ########################################################
set(testClientMachine_SRCS if(KWIN_BUILD_X11)
../src/client_machine.cpp set(testClientMachine_SRCS
test_client_machine.cpp ../src/client_machine.cpp
xcb_scaling_mock.cpp test_client_machine.cpp
) xcb_scaling_mock.cpp
add_executable(testClientMachine ${testClientMachine_SRCS}) )
set_target_properties(testClientMachine PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") add_executable(testClientMachine ${testClientMachine_SRCS})
set_target_properties(testClientMachine PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW")
target_link_libraries(testClientMachine target_link_libraries(testClientMachine
Qt::Concurrent Qt::Concurrent
Qt::GuiPrivate Qt::GuiPrivate
Qt::Test Qt::Test
Qt::Widgets Qt::Widgets
KF6::ConfigCore KF6::ConfigCore
KF6::WindowSystem KF6::WindowSystem
XCB::XCB XCB::XCB
XCB::XFIXES XCB::XFIXES
${X11_X11_LIB} # to make jenkins happy ${X11_X11_LIB} # to make jenkins happy
) )
add_test(NAME kwin-testClientMachine COMMAND testClientMachine) add_test(NAME kwin-testClientMachine COMMAND testClientMachine)
ecm_mark_as_test(testClientMachine) ecm_mark_as_test(testClientMachine)
######################################################## ########################################################
# Test XcbWrapper # Test XcbWrapper
######################################################## ########################################################
add_executable(testXcbWrapper test_xcb_wrapper.cpp xcb_scaling_mock.cpp) add_executable(testXcbWrapper test_xcb_wrapper.cpp xcb_scaling_mock.cpp)
target_link_libraries(testXcbWrapper target_link_libraries(testXcbWrapper
Qt::GuiPrivate Qt::GuiPrivate
Qt::Test Qt::Test
Qt::Widgets Qt::Widgets
KF6::ConfigCore KF6::ConfigCore
KF6::WindowSystem KF6::WindowSystem
XCB::XCB XCB::XCB
) )
add_test(NAME kwin-testXcbWrapper COMMAND testXcbWrapper) add_test(NAME kwin-testXcbWrapper COMMAND testXcbWrapper)
ecm_mark_as_test(testXcbWrapper) ecm_mark_as_test(testXcbWrapper)
add_executable(testXcbSizeHints test_xcb_size_hints.cpp xcb_scaling_mock.cpp) add_executable(testXcbSizeHints test_xcb_size_hints.cpp xcb_scaling_mock.cpp)
set_target_properties(testXcbSizeHints PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") set_target_properties(testXcbSizeHints PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW")
target_link_libraries(testXcbSizeHints target_link_libraries(testXcbSizeHints
Qt::GuiPrivate Qt::GuiPrivate
Qt::Test Qt::Test
Qt::Widgets Qt::Widgets
KF6::ConfigCore KF6::ConfigCore
KF6::WindowSystem KF6::WindowSystem
XCB::ICCCM XCB::ICCCM
XCB::XCB XCB::XCB
) )
add_test(NAME kwin-testXcbSizeHints COMMAND testXcbSizeHints) add_test(NAME kwin-testXcbSizeHints COMMAND testXcbSizeHints)
ecm_mark_as_test(testXcbSizeHints) ecm_mark_as_test(testXcbSizeHints)
######################################################## ########################################################
# Test XcbWindow # Test XcbWindow
######################################################## ########################################################
add_executable(testXcbWindow test_xcb_window.cpp xcb_scaling_mock.cpp) add_executable(testXcbWindow test_xcb_window.cpp xcb_scaling_mock.cpp)
target_link_libraries(testXcbWindow target_link_libraries(testXcbWindow
Qt::GuiPrivate Qt::GuiPrivate
Qt::Test Qt::Test
Qt::Widgets Qt::Widgets
KF6::ConfigCore KF6::ConfigCore
KF6::WindowSystem KF6::WindowSystem
XCB::XCB XCB::XCB
) )
add_test(NAME kwin-testXcbWindow COMMAND testXcbWindow) add_test(NAME kwin-testXcbWindow COMMAND testXcbWindow)
ecm_mark_as_test(testXcbWindow) ecm_mark_as_test(testXcbWindow)
########################################################
# Test X11 TimestampUpdate
########################################################
add_executable(testX11TimestampUpdate test_x11_timestamp_update.cpp)
target_link_libraries(testX11TimestampUpdate
KF6::CoreAddons
Qt::Test
Qt::GuiPrivate
kwin
)
add_test(NAME kwin-testX11TimestampUpdate COMMAND testX11TimestampUpdate)
ecm_mark_as_test(testX11TimestampUpdate)
endif()
######################################################## ########################################################
# Test OnScreenNotification # Test OnScreenNotification
@ -161,19 +176,6 @@ target_link_libraries(testGestures
add_test(NAME kwin-testGestures COMMAND testGestures) add_test(NAME kwin-testGestures COMMAND testGestures)
ecm_mark_as_test(testGestures) ecm_mark_as_test(testGestures)
########################################################
# Test X11 TimestampUpdate
########################################################
add_executable(testX11TimestampUpdate test_x11_timestamp_update.cpp)
target_link_libraries(testX11TimestampUpdate
KF6::CoreAddons
Qt::Test
Qt::GuiPrivate
kwin
)
add_test(NAME kwin-testX11TimestampUpdate COMMAND testX11TimestampUpdate)
ecm_mark_as_test(testX11TimestampUpdate)
set(testOpenGLContextAttributeBuilder_SRCS set(testOpenGLContextAttributeBuilder_SRCS
../src/opengl/abstract_opengl_context_attribute_builder.cpp ../src/opengl/abstract_opengl_context_attribute_builder.cpp
../src/opengl/egl_context_attribute_builder.cpp ../src/opengl/egl_context_attribute_builder.cpp

View file

@ -39,7 +39,6 @@ target_link_libraries(LibDrmTest
KF6::WindowSystem KF6::WindowSystem
KF6::CoreAddons KF6::CoreAddons
KF6::I18n KF6::I18n
XCB::XCB
PkgConfig::Libxcvt PkgConfig::Libxcvt
gbm::gbm gbm::gbm
Libdrm::Libdrm Libdrm::Libdrm

View file

@ -14,7 +14,10 @@ kwineffects_unit_tests(
timelinetest timelinetest
) )
add_executable(kwinglplatformtest kwinglplatformtest.cpp mock_gl.cpp ../../src/opengl/glplatform.cpp ../../src/opengl/openglcontext.cpp ../../src/utils/version.cpp)
add_test(NAME kwineffects-kwinglplatformtest COMMAND kwinglplatformtest) if (KWIN_BUILD_X11 AND ARGS_LIBS MATCHES .*XCB.*)
target_link_libraries(kwinglplatformtest Qt::Test Qt::Gui KF6::ConfigCore XCB::XCB) add_executable(kwinglplatformtest kwinglplatformtest.cpp mock_gl.cpp ../../src/opengl/glplatform.cpp ../../src/opengl/openglcontext.cpp ../../src/utils/version.cpp)
ecm_mark_as_test(kwinglplatformtest) add_test(NAME kwineffects-kwinglplatformtest COMMAND kwinglplatformtest)
target_link_libraries(kwinglplatformtest Qt::Test Qt::Gui KF6::ConfigCore XCB::XCB)
ecm_mark_as_test(kwinglplatformtest)
endif()

View file

@ -33,20 +33,21 @@ target_sources(KWinIntegrationTestFramework PRIVATE
target_link_libraries(KWinIntegrationTestFramework target_link_libraries(KWinIntegrationTestFramework
PUBLIC PUBLIC
Qt::Test Qt::Test
Qt::Concurrent
Plasma::KWaylandClient Plasma::KWaylandClient
Wayland::Client Wayland::Client
Libdrm::Libdrm Libdrm::Libdrm
kwin kwin
PRIVATE PRIVATE
# Own libraries
KWinXwaylandServerModule
# Static plugins # Static plugins
KWinQpaPlugin KWinQpaPlugin
KF6WindowSystemKWinPlugin KF6WindowSystemKWinPlugin
KF6IdleTimeKWinPlugin KF6IdleTimeKWinPlugin
) )
if(KWIN_BUILD_X11)
target_link_libraries(KWinIntegrationTestFramework PRIVATE KWinXwaylandServerModule)
endif()
if(TARGET KF6GlobalAccelKWinPlugin) if(TARGET KF6GlobalAccelKWinPlugin)
target_link_libraries(KWinIntegrationTestFramework PUBLIC KF6GlobalAccelKWinPlugin) target_link_libraries(KWinIntegrationTestFramework PUBLIC KF6GlobalAccelKWinPlugin)
endif() endif()
@ -60,6 +61,9 @@ function(integrationTest)
set(oneValueArgs NAME) set(oneValueArgs NAME)
set(multiValueArgs SRCS LIBS) set(multiValueArgs SRCS LIBS)
cmake_parse_arguments(ARGS "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(ARGS "${optionArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT KWIN_BUILD_X11 AND ARGS_LIBS MATCHES XCB::)
return()
endif()
add_executable(${ARGS_NAME} ${ARGS_SRCS}) add_executable(${ARGS_NAME} ${ARGS_SRCS})
target_link_libraries(${ARGS_NAME} KWinIntegrationTestFramework Qt::Test ${ARGS_LIBS}) target_link_libraries(${ARGS_NAME} KWinIntegrationTestFramework Qt::Test ${ARGS_LIBS})
if(${ARGS_BUILTIN_EFFECTS}) if(${ARGS_BUILTIN_EFFECTS})
@ -67,8 +71,9 @@ function(integrationTest)
endif() endif()
add_test(NAME kwin-${ARGS_NAME} COMMAND dbus-run-session ${CMAKE_BINARY_DIR}/bin/${ARGS_NAME}) add_test(NAME kwin-${ARGS_NAME} COMMAND dbus-run-session ${CMAKE_BINARY_DIR}/bin/${ARGS_NAME})
endfunction() endfunction()
if(KWIN_BUILD_X11)
integrationTest(NAME testDontCrashGlxgears SRCS dont_crash_glxgears.cpp LIBS KF6::I18n KDecoration2::KDecoration) integrationTest(NAME testDontCrashGlxgears SRCS dont_crash_glxgears.cpp LIBS KF6::I18n KDecoration2::KDecoration)
endif()
if (KWIN_BUILD_SCREENLOCKER) if (KWIN_BUILD_SCREENLOCKER)
integrationTest(NAME testLockScreen SRCS lockscreen.cpp LIBS KF6::GlobalAccel) integrationTest(NAME testLockScreen SRCS lockscreen.cpp LIBS KF6::GlobalAccel)
endif() endif()
@ -82,11 +87,9 @@ integrationTest(NAME testPlatformCursor SRCS platformcursor.cpp)
integrationTest(NAME testDontCrashCancelAnimation SRCS dont_crash_cancel_animation.cpp LIBS KDecoration2::KDecoration) integrationTest(NAME testDontCrashCancelAnimation SRCS dont_crash_cancel_animation.cpp LIBS KDecoration2::KDecoration)
integrationTest(NAME testTransientPlacement SRCS transient_placement.cpp) integrationTest(NAME testTransientPlacement SRCS transient_placement.cpp)
integrationTest(NAME testDebugConsole SRCS debug_console_test.cpp) integrationTest(NAME testDebugConsole SRCS debug_console_test.cpp)
integrationTest(NAME testDontCrashEmptyDeco SRCS dont_crash_empty_deco.cpp LIBS KDecoration2::KDecoration)
integrationTest(NAME testPlasmaSurface SRCS plasma_surface_test.cpp) integrationTest(NAME testPlasmaSurface SRCS plasma_surface_test.cpp)
integrationTest(NAME testMaximized SRCS maximize_test.cpp LIBS KDecoration2::KDecoration KF6::Package) integrationTest(NAME testMaximized SRCS maximize_test.cpp LIBS KDecoration2::KDecoration KF6::Package)
integrationTest(NAME testXdgShellWindow SRCS xdgshellwindow_test.cpp LIBS KDecoration2::KDecoration) integrationTest(NAME testXdgShellWindow SRCS xdgshellwindow_test.cpp LIBS KDecoration2::KDecoration)
integrationTest(NAME testXwaylandSelections SRCS xwayland_selections_test.cpp)
integrationTest(NAME testSceneOpenGL SRCS scene_opengl_test.cpp ) integrationTest(NAME testSceneOpenGL SRCS scene_opengl_test.cpp )
integrationTest(NAME testSceneOpenGLES SRCS scene_opengl_es_test.cpp ) integrationTest(NAME testSceneOpenGLES SRCS scene_opengl_es_test.cpp )
integrationTest(NAME testScreenChanges SRCS screen_changes_test.cpp) integrationTest(NAME testScreenChanges SRCS screen_changes_test.cpp)
@ -131,7 +134,11 @@ integrationTest(NAME testXwaylandServerRestart SRCS xwaylandserver_restart_test.
integrationTest(NAME testFakeInput SRCS fakeinput_test.cpp) integrationTest(NAME testFakeInput SRCS fakeinput_test.cpp)
integrationTest(NAME testSecurityContext SRCS security_context_test.cpp) integrationTest(NAME testSecurityContext SRCS security_context_test.cpp)
integrationTest(NAME testStickyKeys SRCS sticky_keys_test.cpp) integrationTest(NAME testStickyKeys SRCS sticky_keys_test.cpp)
integrationTest(NAME testXinerama SRCS xinerama_test.cpp) if(KWIN_BUILD_X11)
integrationTest(NAME testDontCrashEmptyDeco SRCS dont_crash_empty_deco.cpp LIBS KDecoration2::KDecoration)
integrationTest(NAME testXwaylandSelections SRCS xwayland_selections_test.cpp)
integrationTest(NAME testXinerama SRCS xinerama_test.cpp)
endif()
qt_add_dbus_interfaces(DBUS_SRCS ${CMAKE_BINARY_DIR}/src/org.kde.kwin.VirtualKeyboard.xml) qt_add_dbus_interfaces(DBUS_SRCS ${CMAKE_BINARY_DIR}/src/org.kde.kwin.VirtualKeyboard.xml)
integrationTest(NAME testVirtualKeyboardDBus SRCS test_virtualkeyboard_dbus.cpp ${DBUS_SRCS}) integrationTest(NAME testVirtualKeyboardDBus SRCS test_virtualkeyboard_dbus.cpp ${DBUS_SRCS})

View file

@ -11,11 +11,14 @@
#include "core/output.h" #include "core/output.h"
#include "debug_console.h" #include "debug_console.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "utils/xcbutils.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h" #include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h"
#endif
#include <KWayland/Client/compositor.h> #include <KWayland/Client/compositor.h>
#include <KWayland/Client/connection_thread.h> #include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/shm_pool.h> #include <KWayland/Client/shm_pool.h>
@ -38,8 +41,10 @@ private Q_SLOTS:
void cleanup(); void cleanup();
void topLevelTest_data(); void topLevelTest_data();
void topLevelTest(); void topLevelTest();
#if KWIN_BUILD_X11
void testX11Window(); void testX11Window();
void testX11Unmanaged(); void testX11Unmanaged();
#endif
void testWaylandClient(); void testWaylandClient();
void testInternalWindow(); void testInternalWindow();
void testClosingDebugConsole(); void testClosingDebugConsole();
@ -109,6 +114,7 @@ void DebugConsoleTest::topLevelTest()
} }
} }
#if KWIN_BUILD_X11
void DebugConsoleTest::testX11Window() void DebugConsoleTest::testX11Window()
{ {
DebugConsoleModel model; DebugConsoleModel model;
@ -281,6 +287,7 @@ void DebugConsoleTest::testX11Unmanaged()
QVERIFY(!model.hasChildren(unmanagedTopLevelIndex)); QVERIFY(!model.hasChildren(unmanagedTopLevelIndex));
QVERIFY(!model2.hasChildren(model2.index(1, 0, QModelIndex()))); QVERIFY(!model2.hasChildren(model2.index(1, 0, QModelIndex())));
} }
#endif
void DebugConsoleTest::testWaylandClient() void DebugConsoleTest::testWaylandClient()
{ {

View file

@ -15,7 +15,9 @@
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h" #include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#include <KDecoration2/Decoration> #include <KDecoration2/Decoration>

View file

@ -15,11 +15,14 @@
#include "inputmethod.h" #include "inputmethod.h"
#include "placement.h" #include "placement.h"
#include "pluginmanager.h" #include "pluginmanager.h"
#include "utils/xcbutils.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h"
#include "xwayland/xwayland.h" #include "xwayland/xwayland.h"
#include "xwayland/xwaylandlauncher.h" #include "xwayland/xwaylandlauncher.h"
#endif
#include <KPluginMetaData> #include <KPluginMetaData>
@ -99,7 +102,9 @@ WaylandTestApplication::~WaylandTestApplication()
if (effects) { if (effects) {
effects->unloadAllEffects(); effects->unloadAllEffects();
} }
#if KWIN_BUILD_X11
m_xwayland.reset(); m_xwayland.reset();
#endif
destroyVirtualInputDevices(); destroyVirtualInputDevices();
destroyColorManager(); destroyColorManager();
destroyWorkspace(); destroyWorkspace();
@ -179,10 +184,12 @@ void WaylandTestApplication::continueStartupWithScene()
qFatal("Failed to initialize the Wayland server, exiting now"); qFatal("Failed to initialize the Wayland server, exiting now");
} }
#if KWIN_BUILD_X11
if (operationMode() == OperationModeXwayland) { if (operationMode() == OperationModeXwayland) {
m_xwayland = std::make_unique<Xwl::Xwayland>(this); m_xwayland = std::make_unique<Xwl::Xwayland>(this);
m_xwayland->init(); m_xwayland->init();
} }
#endif
notifyStarted(); notifyStarted();
} }
@ -202,10 +209,12 @@ Test::VirtualInputDevice *WaylandTestApplication::virtualTouch() const
return m_virtualTouch.get(); return m_virtualTouch.get();
} }
#if KWIN_BUILD_X11
XwaylandInterface *WaylandTestApplication::xwayland() const XwaylandInterface *WaylandTestApplication::xwayland() const
{ {
return m_xwayland.get(); return m_xwayland.get();
} }
#endif
Test::FractionalScaleManagerV1::~FractionalScaleManagerV1() Test::FractionalScaleManagerV1::~FractionalScaleManagerV1()
{ {

View file

@ -68,10 +68,12 @@ class ScreencastingV1;
namespace KWin namespace KWin
{ {
#if KWIN_BUILD_X11
namespace Xwl namespace Xwl
{ {
class Xwayland; class Xwayland;
} }
#endif
namespace Test namespace Test
{ {
@ -93,7 +95,9 @@ public:
Test::VirtualInputDevice *virtualPointer() const; Test::VirtualInputDevice *virtualPointer() const;
Test::VirtualInputDevice *virtualKeyboard() const; Test::VirtualInputDevice *virtualKeyboard() const;
Test::VirtualInputDevice *virtualTouch() const; Test::VirtualInputDevice *virtualTouch() const;
#if KWIN_BUILD_X11
XwaylandInterface *xwayland() const override; XwaylandInterface *xwayland() const override;
#endif
protected: protected:
void performStartup() override; void performStartup() override;
@ -104,8 +108,9 @@ private:
void createVirtualInputDevices(); void createVirtualInputDevices();
void destroyVirtualInputDevices(); void destroyVirtualInputDevices();
#if KWIN_BUILD_X11
std::unique_ptr<Xwl::Xwayland> m_xwayland; std::unique_ptr<Xwl::Xwayland> m_xwayland;
#endif
QString m_inputMethodServerToStart; QString m_inputMethodServerToStart;
std::unique_ptr<Test::VirtualInputDevice> m_virtualPointer; std::unique_ptr<Test::VirtualInputDevice> m_virtualPointer;
@ -766,13 +771,14 @@ bool renderNodeAvailable();
* with X on demand * with X on demand
*/ */
#if KWIN_BUILD_X11
struct XcbConnectionDeleter struct XcbConnectionDeleter
{ {
void operator()(xcb_connection_t *pointer); void operator()(xcb_connection_t *pointer);
}; };
typedef std::unique_ptr<xcb_connection_t, XcbConnectionDeleter> XcbConnectionPtr; typedef std::unique_ptr<xcb_connection_t, XcbConnectionDeleter> XcbConnectionPtr;
XcbConnectionPtr createX11Connection(); XcbConnectionPtr createX11Connection();
#endif
MockInputMethod *inputMethod(); MockInputMethod *inputMethod();
KWayland::Client::Surface *inputPanelSurface(); KWayland::Client::Surface *inputPanelSurface();

View file

@ -1183,6 +1183,7 @@ bool renderNodeAvailable()
}); });
} }
#if KWIN_BUILD_X11
void XcbConnectionDeleter::operator()(xcb_connection_t *pointer) void XcbConnectionDeleter::operator()(xcb_connection_t *pointer)
{ {
xcb_disconnect(pointer); xcb_disconnect(pointer);
@ -1200,6 +1201,7 @@ Test::XcbConnectionPtr createX11Connection()
e.exec(); e.exec();
return Test::XcbConnectionPtr(future.result()); return Test::XcbConnectionPtr(future.result());
} }
#endif
WaylandOutputManagementV2::WaylandOutputManagementV2(struct ::wl_registry *registry, int id, int version) WaylandOutputManagementV2::WaylandOutputManagementV2(struct ::wl_registry *registry, int id, int version)
: QObject() : QObject()

View file

@ -9,12 +9,15 @@
#include "kwin_wayland_test.h" #include "kwin_wayland_test.h"
#include "main.h" #include "main.h"
#include "utils/xcbutils.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h" #include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h"
#endif
#include <KWayland/Client/surface.h> #include <KWayland/Client/surface.h>
using namespace KWin; using namespace KWin;
@ -28,8 +31,9 @@ private Q_SLOTS:
void initTestCase(); void initTestCase();
void init(); void init();
void cleanup(); void cleanup();
#if KWIN_BUILD_X11
void testNetCurrentDesktop(); void testNetCurrentDesktop();
#endif
void testLastDesktopRemoved(); void testLastDesktopRemoved();
void testWindowOnMultipleDesktops(); void testWindowOnMultipleDesktops();
void testRemoveDesktopWithWindow(); void testRemoveDesktopWithWindow();
@ -52,6 +56,7 @@ void VirtualDesktopTest::initTestCase()
kwinApp()->start(); kwinApp()->start();
QVERIFY(applicationStartedSpy.wait()); QVERIFY(applicationStartedSpy.wait());
#if KWIN_BUILD_X11
if (kwinApp()->x11Connection()) { if (kwinApp()->x11Connection()) {
// verify the current desktop x11 property on startup, see BUG: 391034 // verify the current desktop x11 property on startup, see BUG: 391034
Xcb::Atom currentDesktopAtom("_NET_CURRENT_DESKTOP"); Xcb::Atom currentDesktopAtom("_NET_CURRENT_DESKTOP");
@ -61,6 +66,7 @@ void VirtualDesktopTest::initTestCase()
QCOMPARE(currentDesktop.value(0, &ok), 0); QCOMPARE(currentDesktop.value(0, &ok), 0);
QVERIFY(ok); QVERIFY(ok);
} }
#endif
} }
void VirtualDesktopTest::init() void VirtualDesktopTest::init()
@ -75,6 +81,7 @@ void VirtualDesktopTest::cleanup()
Test::destroyWaylandConnection(); Test::destroyWaylandConnection();
} }
#if KWIN_BUILD_X11
void VirtualDesktopTest::testNetCurrentDesktop() void VirtualDesktopTest::testNetCurrentDesktop()
{ {
if (!kwinApp()->x11Connection()) { if (!kwinApp()->x11Connection()) {
@ -115,6 +122,7 @@ void VirtualDesktopTest::testNetCurrentDesktop()
QCOMPARE(currentDesktop.value(0, &ok), 0); QCOMPARE(currentDesktop.value(0, &ok), 0);
QVERIFY(ok); QVERIFY(ok);
} }
#endif
void VirtualDesktopTest::testLastDesktopRemoved() void VirtualDesktopTest::testLastDesktopRemoved()
{ {

View file

@ -37,13 +37,11 @@ target_sources(kwin PRIVATE
3rdparty/xcursor.c 3rdparty/xcursor.c
activation.cpp activation.cpp
appmenu.cpp appmenu.cpp
atoms.cpp
client_machine.cpp client_machine.cpp
colors/colordevice.cpp colors/colordevice.cpp
colors/colormanager.cpp colors/colormanager.cpp
compositor.cpp compositor.cpp
compositor_wayland.cpp compositor_wayland.cpp
compositor_x11.cpp
core/colorlut.cpp core/colorlut.cpp
core/colorlut3d.cpp core/colorlut3d.cpp
core/colorpipelinestage.cpp core/colorpipelinestage.cpp
@ -96,11 +94,9 @@ target_sources(kwin PRIVATE
effect/offscreenquickview.cpp effect/offscreenquickview.cpp
effect/quickeffect.cpp effect/quickeffect.cpp
effect/timeline.cpp effect/timeline.cpp
events.cpp
focuschain.cpp focuschain.cpp
ftrace.cpp ftrace.cpp
gestures.cpp gestures.cpp
group.cpp
hide_cursor_spy.cpp hide_cursor_spy.cpp
idle_inhibition.cpp idle_inhibition.cpp
idledetector.cpp idledetector.cpp
@ -125,8 +121,6 @@ target_sources(kwin PRIVATE
main.cpp main.cpp
modifier_only_shortcuts.cpp modifier_only_shortcuts.cpp
mousebuttons.cpp mousebuttons.cpp
moving_client_x11_filter.cpp
netinfo.cpp
onscreennotification.cpp onscreennotification.cpp
opengl/abstract_opengl_context_attribute_builder.cpp opengl/abstract_opengl_context_attribute_builder.cpp
opengl/egl_context_attribute_builder.cpp opengl/egl_context_attribute_builder.cpp
@ -160,7 +154,6 @@ target_sources(kwin PRIVATE
pointer_input.cpp pointer_input.cpp
popup_input_filter.cpp popup_input_filter.cpp
resources.qrc resources.qrc
rootinfo_filter.cpp
rulebooksettings.cpp rulebooksettings.cpp
rules.cpp rules.cpp
scene/cursordelegate_opengl.cpp scene/cursordelegate_opengl.cpp
@ -180,7 +173,6 @@ target_sources(kwin PRIVATE
scene/surfaceitem.cpp scene/surfaceitem.cpp
scene/surfaceitem_internal.cpp scene/surfaceitem_internal.cpp
scene/surfaceitem_wayland.cpp scene/surfaceitem_wayland.cpp
scene/surfaceitem_x11.cpp
scene/windowitem.cpp scene/windowitem.cpp
scene/workspacescene.cpp scene/workspacescene.cpp
scene/workspacescene_opengl.cpp scene/workspacescene_opengl.cpp
@ -203,7 +195,6 @@ target_sources(kwin PRIVATE
scripting/workspace_wrapper.cpp scripting/workspace_wrapper.cpp
shadow.cpp shadow.cpp
sm.cpp sm.cpp
syncalarmx11filter.cpp
tablet_input.cpp tablet_input.cpp
tabletmodemanager.cpp tabletmodemanager.cpp
tiles/customtile.cpp tiles/customtile.cpp
@ -216,16 +207,11 @@ target_sources(kwin PRIVATE
virtualdesktops.cpp virtualdesktops.cpp
virtualdesktopsdbustypes.cpp virtualdesktopsdbustypes.cpp
virtualkeyboard_dbus.cpp virtualkeyboard_dbus.cpp
was_user_interaction_x11_filter.cpp
wayland_server.cpp wayland_server.cpp
waylandshellintegration.cpp waylandshellintegration.cpp
waylandwindow.cpp waylandwindow.cpp
window.cpp window.cpp
window_property_notify_x11_filter.cpp
workspace.cpp workspace.cpp
x11eventfilter.cpp
x11syncmanager.cpp
x11window.cpp
xdgactivationv1.cpp xdgactivationv1.cpp
xdgshellintegration.cpp xdgshellintegration.cpp
xdgshellwindow.cpp xdgshellwindow.cpp
@ -260,21 +246,6 @@ target_link_libraries(kwin
KDecoration2::KDecoration KDecoration2::KDecoration
KDecoration2::KDecoration2Private KDecoration2::KDecoration2Private
XCB::COMPOSITE
XCB::CURSOR
XCB::DAMAGE
XCB::GLX
XCB::ICCCM
XCB::KEYSYMS
XCB::RANDR
XCB::RENDER
XCB::SHAPE
XCB::SHM
XCB::SYNC
XCB::XCB
XCB::XFIXES
XCB::XINERAMA
UDev::UDev UDev::UDev
XKB::XKB XKB::XKB
EGL::EGL EGL::EGL
@ -290,6 +261,43 @@ if (TARGET K::KGlobalAccelD)
target_link_libraries(kwin PRIVATE K::KGlobalAccelD) target_link_libraries(kwin PRIVATE K::KGlobalAccelD)
endif() endif()
if (KWIN_BUILD_X11)
target_sources(kwin
PRIVATE
atoms.cpp
events.cpp
compositor_x11.cpp
group.cpp
moving_client_x11_filter.cpp
netinfo.cpp
rootinfo_filter.cpp
scene/surfaceitem_x11.cpp
syncalarmx11filter.cpp
was_user_interaction_x11_filter.cpp
window_property_notify_x11_filter.cpp
x11eventfilter.cpp
x11syncmanager.cpp
x11window.cpp
)
target_link_libraries(kwin
PRIVATE
XCB::COMPOSITE
XCB::CURSOR
XCB::DAMAGE
XCB::GLX
XCB::ICCCM
XCB::KEYSYMS
XCB::RANDR
XCB::RENDER
XCB::SHAPE
XCB::SHM
XCB::SYNC
XCB::XCB
XCB::XFIXES
XCB::XINERAMA
)
endif()
if (KWIN_BUILD_NOTIFICATIONS) if (KWIN_BUILD_NOTIFICATIONS)
target_link_libraries(kwin PRIVATE KF6::Notifications) target_link_libraries(kwin PRIVATE KF6::Notifications)
endif() endif()
@ -331,7 +339,10 @@ add_subdirectory(platformsupport)
add_subdirectory(plugins) add_subdirectory(plugins)
add_subdirectory(utils) add_subdirectory(utils)
add_subdirectory(wayland) add_subdirectory(wayland)
add_subdirectory(xwayland)
if (KWIN_BUILD_X11)
add_subdirectory(xwayland)
endif()
if (KWIN_BUILD_ACTIVITIES) if (KWIN_BUILD_ACTIVITIES)
target_sources(kwin PRIVATE activities.cpp) target_sources(kwin PRIVATE activities.cpp)
@ -351,9 +362,12 @@ if (KWIN_BUILD_TABBOX)
tabbox/tabbox_logging.cpp tabbox/tabbox_logging.cpp
tabbox/tabboxconfig.cpp tabbox/tabboxconfig.cpp
tabbox/tabboxhandler.cpp tabbox/tabboxhandler.cpp
tabbox/x11_filter.cpp
) )
add_subdirectory(tabbox/switchers) add_subdirectory(tabbox/switchers)
if (KWIN_BUILD_X11)
target_sources(kwin PRIVATE tabbox/x11_filter.cpp)
endif()
endif() endif()
qt_generate_dbus_interface(virtualkeyboard_dbus.h org.kde.kwin.VirtualKeyboard.xml OPTIONS -A) qt_generate_dbus_interface(virtualkeyboard_dbus.h org.kde.kwin.VirtualKeyboard.xml OPTIONS -A)
@ -361,19 +375,21 @@ qt_generate_dbus_interface(tabletmodemanager.h org.kde.KWin.TabletModeManager.xm
generate_export_header(kwin EXPORT_FILE_NAME kwin_export.h) generate_export_header(kwin EXPORT_FILE_NAME kwin_export.h)
add_executable(kwin_x11 main_x11.cpp) if (KWIN_BUILD_X11)
target_link_libraries(kwin_x11 add_executable(kwin_x11 main_x11.cpp)
KWinX11Platform target_link_libraries(kwin_x11
kwin KWinX11Platform
KF6::GlobalAccel kwin
) KF6::GlobalAccel
target_compile_definitions(kwin_x11 PRIVATE )
-DTRANSLATION_DOMAIN=\"kwin\" target_compile_definitions(kwin_x11 PRIVATE
) -DTRANSLATION_DOMAIN=\"kwin\"
kcoreaddons_target_static_plugins(kwin_x11 NAMESPACE "kwin/effects/plugins") )
kcoreaddons_target_static_plugins(kwin_x11 NAMESPACE "kwin/effects/plugins")
install(TARGETS kwin_x11 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
endif()
install(TARGETS kwin EXPORT KWinTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS kwin EXPORT KWinTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(TARGETS kwin_x11 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
add_executable(kwin_wayland main_wayland.cpp) add_executable(kwin_wayland main_wayland.cpp)
@ -391,9 +407,12 @@ endif()
target_link_libraries(kwin_wayland target_link_libraries(kwin_wayland
kwin kwin
KWinXwaylandServerModule
KF6::Crash KF6::Crash
KF6::I18n
) )
if (KWIN_BUILD_X11)
target_link_libraries(kwin_wayland KWinXwaylandServerModule)
endif()
target_compile_definitions(kwin_wayland PRIVATE target_compile_definitions(kwin_wayland PRIVATE
-DTRANSLATION_DOMAIN=\"kwin\" -DTRANSLATION_DOMAIN=\"kwin\"
) )
@ -446,12 +465,15 @@ install(
install(EXPORT KWinTargets DESTINATION "${KDE_INSTALL_CMAKEPACKAGEDIR}/KWin" FILE KWinTargets.cmake NAMESPACE KWin:: ) install(EXPORT KWinTargets DESTINATION "${KDE_INSTALL_CMAKEPACKAGEDIR}/KWin" FILE KWinTargets.cmake NAMESPACE KWin:: )
if (KWIN_BUILD_X11)
install(FILES atoms.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kwin COMPONENT Devel)
endif()
install(FILES install(FILES
${CMAKE_CURRENT_BINARY_DIR}/config-kwin.h ${CMAKE_CURRENT_BINARY_DIR}/config-kwin.h
${CMAKE_CURRENT_BINARY_DIR}/kwin_export.h ${CMAKE_CURRENT_BINARY_DIR}/kwin_export.h
activities.h activities.h
appmenu.h appmenu.h
atoms.h
client_machine.h client_machine.h
compositor.h compositor.h
cursor.h cursor.h

View file

@ -17,22 +17,26 @@
#include "cursor.h" #include "cursor.h"
#include "focuschain.h" #include "focuschain.h"
#include "netinfo.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
#endif #endif
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include <KLocalizedString> #if KWIN_BUILD_X11
#include <kstartupinfo.h>
#include <kstringhandler.h>
#include "atoms.h" #include "atoms.h"
#include "group.h" #include "group.h"
#include "netinfo.h"
#include "x11window.h"
#include <kstartupinfo.h>
#endif
#include <KLocalizedString>
#include <kstringhandler.h>
#include "rules.h" #include "rules.h"
#include "useractions.h" #include "useractions.h"
#include "window.h"
#include <QDebug> #include <QDebug>
namespace KWin namespace KWin
@ -259,9 +263,11 @@ void Workspace::setActiveWindow(Window *window)
updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active
#if KWIN_BUILD_X11
if (rootInfo()) { if (rootInfo()) {
rootInfo()->setActiveClient(m_activeWindow); rootInfo()->setActiveClient(m_activeWindow);
} }
#endif
Q_EMIT windowActivated(m_activeWindow); Q_EMIT windowActivated(m_activeWindow);
--m_setActiveWindowRecursion; --m_setActiveWindowRecursion;
@ -330,6 +336,7 @@ void Workspace::activateWindow(Window *window, bool force)
requestFocus(window, force); requestFocus(window, force);
} }
#if KWIN_BUILD_X11
// Don't update user time for windows that have focus stealing workaround. // Don't update user time for windows that have focus stealing workaround.
// As they usually belong to the current active window but fail to provide // As they usually belong to the current active window but fail to provide
// this information, updating their user time would make the user time // this information, updating their user time would make the user time
@ -341,6 +348,7 @@ void Workspace::activateWindow(Window *window, bool force)
// updateUserTime is X11 specific // updateUserTime is X11 specific
x11Window->updateUserTime(); x11Window->updateUserTime();
} }
#endif
m_quickTileCombineTimer->stop(); m_quickTileCombineTimer->stop();
} }
@ -558,7 +566,7 @@ void Workspace::setShouldGetFocus(Window *window)
// a window to be fully raised upon its own request (XRaiseWindow), // a window to be fully raised upon its own request (XRaiseWindow),
// if refused, it will be raised only on top of windows belonging // if refused, it will be raised only on top of windows belonging
// to the same application // to the same application
bool Workspace::allowFullClientRaising(const KWin::Window *window, xcb_timestamp_t time) bool Workspace::allowFullClientRaising(const KWin::Window *window, uint32_t time)
{ {
int level = window->rules()->checkFSP(options->focusStealingPreventionLevel()); int level = window->rules()->checkFSP(options->focusStealingPreventionLevel());
if (sessionManager()->state() == SessionState::Saving && level <= 2) { // <= normal if (sessionManager()->state() == SessionState::Saving && level <= 2) { // <= normal
@ -583,10 +591,14 @@ bool Workspace::allowFullClientRaising(const KWin::Window *window, xcb_timestamp
if (level == 3) { // high if (level == 3) { // high
return false; return false;
} }
#if KWIN_BUILD_X11
xcb_timestamp_t user_time = ac->userTime(); xcb_timestamp_t user_time = ac->userTime();
qCDebug(KWIN_CORE) << "Raising, compared:" << time << ":" << user_time qCDebug(KWIN_CORE) << "Raising, compared:" << time << ":" << user_time
<< ":" << (NET::timestampCompare(time, user_time) >= 0); << ":" << (NET::timestampCompare(time, user_time) >= 0);
return NET::timestampCompare(time, user_time) >= 0; // time >= user_time return NET::timestampCompare(time, user_time) >= 0; // time >= user_time
#else
return true;
#endif
} }
/** /**
@ -601,7 +613,9 @@ bool Workspace::restoreFocus()
// a timestamp *sigh*, kwin's timestamp would be older than the timestamp // a timestamp *sigh*, kwin's timestamp would be older than the timestamp
// that was used by whoever caused the focus change, and therefore // that was used by whoever caused the focus change, and therefore
// the attempt to restore the focus would fail due to old timestamp // the attempt to restore the focus would fail due to old timestamp
#if KWIN_BUILD_X11
kwinApp()->updateXTime(); kwinApp()->updateXTime();
#endif
if (should_get_focus.count() > 0) { if (should_get_focus.count() > 0) {
return requestFocus(should_get_focus.last()); return requestFocus(should_get_focus.last());
} else if (m_lastActiveWindow) { } else if (m_lastActiveWindow) {
@ -620,312 +634,4 @@ void Workspace::windowAttentionChanged(Window *window, bool set)
} }
} }
//********************************************
// Client
//********************************************
/**
* Updates the user time (time of last action in the active window).
* This is called inside kwin for every action with the window
* that qualifies for user interaction (clicking on it, activate it
* externally, etc.).
*/
void X11Window::updateUserTime(xcb_timestamp_t time)
{
// copied in Group::updateUserTime
if (time == XCB_TIME_CURRENT_TIME) {
kwinApp()->updateXTime();
time = xTime();
}
if (time != -1U
&& (m_userTime == XCB_TIME_CURRENT_TIME
|| NET::timestampCompare(time, m_userTime) > 0)) { // time > user_time
m_userTime = time;
shade_below = nullptr; // do not hover re-shade a window after it got interaction
}
group()->updateUserTime(m_userTime);
}
xcb_timestamp_t X11Window::readUserCreationTime() const
{
Xcb::Property prop(false, window(), atoms->kde_net_wm_user_creation_time, XCB_ATOM_CARDINAL, 0, 1);
return prop.value<xcb_timestamp_t>(-1);
}
xcb_timestamp_t X11Window::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data,
bool session) const
{
xcb_timestamp_t time = info->userTime();
// qDebug() << "User timestamp, initial:" << time;
//^^ this deadlocks kwin --replace sometimes.
// newer ASN timestamp always replaces user timestamp, unless user timestamp is 0
// helps e.g. with konqy reusing
if (asn_data != nullptr && time != 0) {
if (asn_id->timestamp() != 0
&& (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) {
time = asn_id->timestamp();
}
}
qCDebug(KWIN_CORE) << "User timestamp, ASN:" << time;
if (time == -1U) {
// The window doesn't have any timestamp.
// If it's the first window for its application
// (i.e. there's no other window from the same app),
// use the _KDE_NET_WM_USER_CREATION_TIME trick.
// Otherwise, refuse activation of a window
// from already running application if this application
// is not the active one (unless focus stealing prevention is turned off).
X11Window *act = dynamic_cast<X11Window *>(workspace()->mostRecentlyActivatedWindow());
if (act != nullptr && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) {
bool first_window = true;
auto sameApplicationActiveHackPredicate = [this](const X11Window *cl) {
// ignore already existing splashes, toolbars, utilities and menus,
// as the app may show those before the main window
return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
&& cl != this && X11Window::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive);
};
if (isTransient()) {
auto clientMainClients = [this]() {
QList<X11Window *> ret;
const auto mcs = mainWindows();
for (auto mc : mcs) {
if (X11Window *c = dynamic_cast<X11Window *>(mc)) {
ret << c;
}
}
return ret;
};
if (act->hasTransient(this, true)) {
; // is transient for currently active window, even though it's not
// the same app (e.g. kcookiejar dialog) -> allow activation
} else if (groupTransient() && findInList<X11Window, X11Window>(clientMainClients(), sameApplicationActiveHackPredicate) == nullptr) {
; // standalone transient
} else {
first_window = false;
}
} else {
if (workspace()->findClient(sameApplicationActiveHackPredicate)) {
first_window = false;
}
}
// don't refuse if focus stealing prevention is turned off
if (!first_window && rules()->checkFSP(options->focusStealingPreventionLevel()) > 0) {
qCDebug(KWIN_CORE) << "User timestamp, already exists:" << 0;
return 0; // refuse activation
}
}
// Creation time would just mess things up during session startup,
// as possibly many apps are started up at the same time.
// If there's no active window yet, no timestamp will be needed,
// as plain Workspace::allowWindowActivation() will return true
// in such case. And if there's already active window,
// it's better not to activate the new one.
// Unless it was the active window at the time
// of session saving and there was no user interaction yet,
// this check will be done in manage().
if (session) {
return -1U;
}
time = readUserCreationTime();
}
qCDebug(KWIN_CORE) << "User timestamp, final:" << this << ":" << time;
return time;
}
xcb_timestamp_t X11Window::userTime() const
{
xcb_timestamp_t time = m_userTime;
if (time == 0) { // doesn't want focus after showing
return 0;
}
Q_ASSERT(group() != nullptr);
if (time == -1U
|| (group()->userTime() != -1U
&& NET::timestampCompare(group()->userTime(), time) > 0)) {
time = group()->userTime();
}
return time;
}
void X11Window::doSetActive()
{
updateUrgency(); // demand attention again if it's still urgent
info->setState(isActive() ? NET::Focused : NET::States(), NET::Focused);
}
void X11Window::startupIdChanged()
{
KStartupInfoId asn_id;
KStartupInfoData asn_data;
bool asn_valid = workspace()->checkStartupNotification(window(), asn_id, asn_data);
if (!asn_valid) {
return;
}
// If the ASN contains desktop, move it to the desktop, otherwise move it to the current
// desktop (since the new ASN should make the window act like if it's a new application
// launched). However don't affect the window's desktop if it's set to be on all desktops.
if (asn_data.desktop() != 0 && !isOnAllDesktops()) {
if (asn_data.desktop() == -1) {
workspace()->sendWindowToDesktops(this, {}, true);
} else {
if (VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(asn_data.desktop())) {
workspace()->sendWindowToDesktops(this, {desktop}, true);
}
}
}
if (asn_data.xinerama() != -1) {
Output *output = workspace()->xineramaIndexToOutput(asn_data.xinerama());
if (output) {
workspace()->sendWindowToOutput(this, output);
}
}
const xcb_timestamp_t timestamp = asn_id.timestamp();
if (timestamp != 0) {
bool activate = allowWindowActivation(timestamp);
if (activate) {
workspace()->activateWindow(this);
} else {
demandAttention();
}
}
}
void X11Window::updateUrgency()
{
if (info->urgency()) {
demandAttention();
}
}
namespace FSP
{
enum Level {
None = 0,
Low,
Medium,
High,
Extreme,
};
}
// focus_in -> the window got FocusIn event
bool X11Window::allowWindowActivation(xcb_timestamp_t time, bool focus_in)
{
auto window = this;
// options->focusStealingPreventionLevel :
// 0 - none - old KWin behaviour, new windows always get focus
// 1 - low - focus stealing prevention is applied normally, when unsure, activation is allowed
// 2 - normal - focus stealing prevention is applied normally, when unsure, activation is not allowed,
// this is the default
// 3 - high - new window gets focus only if it belongs to the active application,
// or when no window is currently active
// 4 - extreme - no window gets focus without user intervention
if (time == -1U) {
time = window->userTime();
}
const FSP::Level level = (FSP::Level)window->rules()->checkFSP(options->focusStealingPreventionLevel());
if (workspace()->sessionManager()->state() == SessionState::Saving && level <= FSP::Medium) { // <= normal
return true;
}
Window *ac = workspace()->mostRecentlyActivatedWindow();
if (focus_in) {
if (workspace()->inShouldGetFocus(window)) {
return true; // FocusIn was result of KWin's action
}
// Before getting FocusIn, the active Client already
// got FocusOut, and therefore got deactivated.
ac = workspace()->lastActiveWindow();
}
if (time == 0) { // explicitly asked not to get focus
if (!window->rules()->checkAcceptFocus(false)) {
return false;
}
}
const FSP::Level protection = (FSP::Level)(ac ? ac->rules()->checkFPP(2) : FSP::None);
// stealing is unconditionally allowed (NETWM behavior)
if (level == FSP::None || protection == FSP::None) {
return true;
}
// The active window "grabs" the focus or stealing is generally forbidden
if (level == FSP::Extreme || protection == FSP::Extreme) {
return false;
}
// No active window, it's ok to pass focus
// NOTICE that extreme protection needs to be handled before to allow protection on unmanged windows
if (ac == nullptr || ac->isDesktop()) {
qCDebug(KWIN_CORE) << "Activation: No window active, allowing";
return true; // no active window -> always allow
}
// TODO window urgency -> return true?
// Unconditionally allow intra-window passing around for lower stealing protections
// unless the active window has High interest
if (Window::belongToSameApplication(window, ac, Window::SameApplicationCheck::RelaxedForActive) && protection < FSP::High) {
qCDebug(KWIN_CORE) << "Activation: Belongs to active application";
return true;
}
// High FPS, not intr-window change. Only allow if the active window has only minor interest
if (level > FSP::Medium && protection > FSP::Low) {
return false;
}
if (time == -1U) { // no time known
qCDebug(KWIN_CORE) << "Activation: No timestamp at all";
// Only allow for Low protection unless active window has High interest in focus
if (level < FSP::Medium && protection < FSP::High) {
return true;
}
// no timestamp at all, don't activate - because there's also creation timestamp
// done on CreateNotify, this case should happen only in case application
// maps again already used window, i.e. this won't happen after app startup
return false;
}
// Low or medium FSP, usertime comparism is possible
const xcb_timestamp_t user_time = ac->userTime();
qCDebug(KWIN_CORE) << "Activation, compared:" << window << ":" << time << ":" << user_time
<< ":" << (NET::timestampCompare(time, user_time) >= 0);
return NET::timestampCompare(time, user_time) >= 0; // time >= user_time
}
//****************************************
// Group
//****************************************
void Group::startupIdChanged()
{
KStartupInfoId asn_id;
KStartupInfoData asn_data;
bool asn_valid = workspace()->checkStartupNotification(leader_wid, asn_id, asn_data);
if (!asn_valid) {
return;
}
if (asn_id.timestamp() != 0 && user_time != -1U
&& NET::timestampCompare(asn_id.timestamp(), user_time) > 0) {
user_time = asn_id.timestamp();
}
}
void Group::updateUserTime(xcb_timestamp_t time)
{
// copy of X11Window::updateUserTime
if (time == XCB_CURRENT_TIME) {
kwinApp()->updateXTime();
time = xTime();
}
if (time != -1U
&& (user_time == XCB_CURRENT_TIME
|| NET::timestampCompare(time, user_time) > 0)) { // time > user_time
user_time = time;
}
}
} // namespace } // namespace

View file

@ -8,8 +8,11 @@
*/ */
#include "activities.h" #include "activities.h"
// KWin // KWin
#include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
// KDE // KDE
#include <KConfigGroup> #include <KConfigGroup>
// Qt // Qt
@ -173,6 +176,7 @@ void Activities::reallyStop(const QString &id)
QSet<QByteArray> saveSessionIds; QSet<QByteArray> saveSessionIds;
QSet<QByteArray> dontCloseSessionIds; QSet<QByteArray> dontCloseSessionIds;
#if KWIN_BUILD_X11
const auto windows = ws->windows(); const auto windows = ws->windows();
for (auto *const window : windows) { for (auto *const window : windows) {
auto x11Window = qobject_cast<X11Window *>(window); auto x11Window = qobject_cast<X11Window *>(window);
@ -206,8 +210,8 @@ void Activities::reallyStop(const QString &id)
} }
} }
} }
ws->sessionManager()->storeSubSession(id, saveSessionIds); ws->sessionManager()->storeSubSession(id, saveSessionIds);
#endif
QStringList saveAndClose; QStringList saveAndClose;
QStringList saveOnly; QStringList saveOnly;

View file

@ -9,8 +9,8 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#include "appmenu.h" #include "appmenu.h"
#include "window.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
#include <appmenu_interface.h> #include <appmenu_interface.h>
#include <QDBusObjectPath> #include <QDBusObjectPath>

View file

@ -11,8 +11,6 @@
#pragma once #pragma once
// Qt // Qt
#include <QObject> #include <QObject>
// xcb
#include <xcb/xcb.h>
class QPoint; class QPoint;
class OrgKdeKappmenuInterface; class OrgKdeKappmenuInterface;

View file

@ -11,6 +11,12 @@
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include "utils/xcbutils.h" #include "utils/xcbutils.h"
namespace KWin namespace KWin

View file

@ -3,4 +3,7 @@ add_subdirectory(fakeinput)
add_subdirectory(libinput) add_subdirectory(libinput)
add_subdirectory(virtual) add_subdirectory(virtual)
add_subdirectory(wayland) add_subdirectory(wayland)
add_subdirectory(x11)
if (KWIN_BUILD_X11)
add_subdirectory(x11)
endif()

View file

@ -8,11 +8,17 @@
*/ */
// own // own
#include "client_machine.h" #include "client_machine.h"
#include "effect/xcb.h"
#include "main.h" #include "main.h"
#include "utils/common.h" #include "utils/common.h"
#if KWIN_BUILD_X11
#include "effect/xcb.h"
#endif
// KF5 // KF5
#if KWIN_BUILD_X11
#include <NETWM> #include <NETWM>
#endif
// Qt // Qt
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QtConcurrentRun> #include <QtConcurrentRun>
@ -167,6 +173,7 @@ ClientMachine::~ClientMachine()
{ {
} }
#if KWIN_BUILD_X11
void ClientMachine::resolve(xcb_window_t window, xcb_window_t clientLeader) void ClientMachine::resolve(xcb_window_t window, xcb_window_t clientLeader)
{ {
if (m_resolved) { if (m_resolved) {
@ -186,6 +193,7 @@ void ClientMachine::resolve(xcb_window_t window, xcb_window_t clientLeader)
checkForLocalhost(); checkForLocalhost();
m_resolved = true; m_resolved = true;
} }
#endif
void ClientMachine::checkForLocalhost() void ClientMachine::checkForLocalhost()
{ {

View file

@ -8,9 +8,13 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#include <QObject> #include <QObject>
#include <memory> #include <memory>
#if KWIN_BUILD_X11
#include <xcb/xcb.h> #include <xcb/xcb.h>
#endif
// forward declaration // forward declaration
struct addrinfo; struct addrinfo;
@ -57,7 +61,9 @@ public:
explicit ClientMachine(QObject *parent = nullptr); explicit ClientMachine(QObject *parent = nullptr);
~ClientMachine() override; ~ClientMachine() override;
#if KWIN_BUILD_X11
void resolve(xcb_window_t window, xcb_window_t clientLeader); void resolve(xcb_window_t window, xcb_window_t clientLeader);
#endif
const QString &hostName() const; const QString &hostName() const;
bool isLocal() const; bool isLocal() const;
static QString localhost(); static QString localhost();

View file

@ -45,14 +45,14 @@ Compositor *Compositor::self()
Compositor::Compositor(QObject *workspace) Compositor::Compositor(QObject *workspace)
: QObject(workspace) : QObject(workspace)
{ {
#if KWIN_BUILD_X11
// 2 sec which should be enough to restart the compositor. // 2 sec which should be enough to restart the compositor.
static const int compositorLostMessageDelay = 2000; static const int compositorLostMessageDelay = 2000;
m_unusedSupportPropertyTimer.setInterval(compositorLostMessageDelay); m_unusedSupportPropertyTimer.setInterval(compositorLostMessageDelay);
m_unusedSupportPropertyTimer.setSingleShot(true); m_unusedSupportPropertyTimer.setSingleShot(true);
connect(&m_unusedSupportPropertyTimer, &QTimer::timeout, connect(&m_unusedSupportPropertyTimer, &QTimer::timeout,
this, &Compositor::deleteUnusedSupportProperties); this, &Compositor::deleteUnusedSupportProperties);
#endif
// Delay the call to start by one event cycle. // Delay the call to start by one event cycle.
// The ctor of this class is invoked from the Workspace ctor, that means before // The ctor of this class is invoked from the Workspace ctor, that means before
// Workspace is completely constructed, so calling Workspace::self() would result // Workspace is completely constructed, so calling Workspace::self() would result
@ -66,7 +66,9 @@ Compositor::Compositor(QObject *workspace)
Compositor::~Compositor() Compositor::~Compositor()
{ {
#if KWIN_BUILD_X11
deleteUnusedSupportProperties(); deleteUnusedSupportProperties();
#endif
s_compositor = nullptr; s_compositor = nullptr;
} }
@ -94,6 +96,7 @@ void Compositor::removeSuperLayer(RenderLayer *layer)
delete layer; delete layer;
} }
#if KWIN_BUILD_X11
void Compositor::keepSupportProperty(xcb_atom_t atom) void Compositor::keepSupportProperty(xcb_atom_t atom)
{ {
m_unusedSupportProperties.removeAll(atom); m_unusedSupportProperties.removeAll(atom);
@ -120,6 +123,7 @@ void Compositor::deleteUnusedSupportProperties()
m_unusedSupportProperties.clear(); m_unusedSupportProperties.clear();
} }
} }
#endif
void Compositor::reinitialize() void Compositor::reinitialize()
{ {

View file

@ -9,8 +9,12 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#include <kwin_export.h> #include <kwin_export.h>
#if KWIN_BUILD_X11
#include <xcb/xcb.h> #include <xcb/xcb.h>
#endif
#include <QHash> #include <QHash>
#include <QObject> #include <QObject>
@ -80,9 +84,11 @@ public:
return s_compositor != nullptr && s_compositor->isActive(); return s_compositor != nullptr && s_compositor->isActive();
} }
#if KWIN_BUILD_X11
// for delayed supportproperty management of effects // for delayed supportproperty management of effects
void keepSupportProperty(xcb_atom_t atom); void keepSupportProperty(xcb_atom_t atom);
void removeSupportProperty(xcb_atom_t atom); void removeSupportProperty(xcb_atom_t atom);
#endif
/** /**
* Whether Compositing is possible in the Platform. * Whether Compositing is possible in the Platform.
@ -134,7 +140,9 @@ private Q_SLOTS:
void handleFrameRequested(RenderLoop *renderLoop); void handleFrameRequested(RenderLoop *renderLoop);
protected: protected:
#if KWIN_BUILD_X11
void deleteUnusedSupportProperties(); void deleteUnusedSupportProperties();
#endif
Output *findOutput(RenderLoop *loop) const; Output *findOutput(RenderLoop *loop) const;
@ -147,8 +155,10 @@ protected:
void framePass(RenderLayer *layer, OutputFrame *frame); void framePass(RenderLayer *layer, OutputFrame *frame);
State m_state = State::Off; State m_state = State::Off;
#if KWIN_BUILD_X11
QList<xcb_atom_t> m_unusedSupportProperties; QList<xcb_atom_t> m_unusedSupportProperties;
QTimer m_unusedSupportPropertyTimer; QTimer m_unusedSupportPropertyTimer;
#endif
std::unique_ptr<WorkspaceScene> m_scene; std::unique_ptr<WorkspaceScene> m_scene;
std::unique_ptr<CursorScene> m_cursorScene; std::unique_ptr<CursorScene> m_cursorScene;
std::unique_ptr<RenderBackend> m_backend; std::unique_ptr<RenderBackend> m_backend;

View file

@ -10,6 +10,7 @@
#cmakedefine01 KWIN_BUILD_TABBOX #cmakedefine01 KWIN_BUILD_TABBOX
#cmakedefine01 KWIN_BUILD_ACTIVITIES #cmakedefine01 KWIN_BUILD_ACTIVITIES
#cmakedefine01 KWIN_BUILD_GLOBALSHORTCUTS #cmakedefine01 KWIN_BUILD_GLOBALSHORTCUTS
#cmakedefine01 KWIN_BUILD_X11
constexpr QLatin1String KWIN_CONFIG("kwinrc"); constexpr QLatin1String KWIN_CONFIG("kwinrc");
constexpr QLatin1String KWIN_VERSION_STRING("${PROJECT_VERSION}"); constexpr QLatin1String KWIN_VERSION_STRING("${PROJECT_VERSION}");
constexpr QLatin1String XCB_VERSION_STRING("${XCB_VERSION}"); constexpr QLatin1String XCB_VERSION_STRING("${XCB_VERSION}");

View file

@ -17,7 +17,10 @@
#include "main.h" #include "main.h"
#include "scene/workspacescene.h" #include "scene/workspacescene.h"
#include "utils/common.h" #include "utils/common.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h" #include "utils/xcbutils.h"
#endif
// KDE // KDE
#include <KConfig> #include <KConfig>
#include <KConfigGroup> #include <KConfigGroup>
@ -222,6 +225,7 @@ void Cursor::markAsRendered(std::chrono::milliseconds timestamp)
Q_EMIT rendered(timestamp); Q_EMIT rendered(timestamp);
} }
#if KWIN_BUILD_X11
xcb_cursor_t Cursor::x11Cursor(CursorShape shape) xcb_cursor_t Cursor::x11Cursor(CursorShape shape)
{ {
return x11Cursor(shape.name()); return x11Cursor(shape.name());
@ -261,6 +265,7 @@ xcb_cursor_t Cursor::x11Cursor(const QByteArray &name)
xcb_cursor_context_free(ctx); xcb_cursor_context_free(ctx);
return cursor; return cursor;
} }
#endif
void Cursor::doSetPos() void Cursor::doSetPos()
{ {

View file

@ -32,15 +32,16 @@
#include "wayland_server.h" #include "wayland_server.h"
#include "waylandwindow.h" #include "waylandwindow.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
#include "xkb.h" #include "xkb.h"
#include <cerrno> #include <cerrno>
#if KWIN_BUILD_X11
#include "x11window.h"
#endif
#include "ui_debug_console.h" #include "ui_debug_console.h"
// frameworks // frameworks
#include <KLocalizedString> #include <KLocalizedString>
#include <NETWM>
// Qt // Qt
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QMetaProperty> #include <QMetaProperty>
@ -48,6 +49,7 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QScopeGuard> #include <QScopeGuard>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QWindow>
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <wayland-server-core.h> #include <wayland-server-core.h>
@ -932,6 +934,7 @@ DebugConsoleModel::DebugConsoleModel(QObject *parent)
void DebugConsoleModel::handleWindowAdded(Window *window) void DebugConsoleModel::handleWindowAdded(Window *window)
{ {
#if KWIN_BUILD_X11
if (auto x11 = qobject_cast<X11Window *>(window)) { if (auto x11 = qobject_cast<X11Window *>(window)) {
if (x11->isUnmanaged()) { if (x11->isUnmanaged()) {
add(s_x11UnmanagedId - 1, m_unmanageds, x11); add(s_x11UnmanagedId - 1, m_unmanageds, x11);
@ -940,6 +943,7 @@ void DebugConsoleModel::handleWindowAdded(Window *window)
} }
return; return;
} }
#endif
if (auto wayland = qobject_cast<WaylandWindow *>(window)) { if (auto wayland = qobject_cast<WaylandWindow *>(window)) {
add(s_waylandWindowId - 1, m_waylandWindows, wayland); add(s_waylandWindowId - 1, m_waylandWindows, wayland);
@ -954,6 +958,7 @@ void DebugConsoleModel::handleWindowAdded(Window *window)
void DebugConsoleModel::handleWindowRemoved(Window *window) void DebugConsoleModel::handleWindowRemoved(Window *window)
{ {
#if KWIN_BUILD_X11
if (auto x11 = qobject_cast<X11Window *>(window)) { if (auto x11 = qobject_cast<X11Window *>(window)) {
if (x11->isUnmanaged()) { if (x11->isUnmanaged()) {
remove(s_x11UnmanagedId - 1, m_unmanageds, x11); remove(s_x11UnmanagedId - 1, m_unmanageds, x11);
@ -962,6 +967,7 @@ void DebugConsoleModel::handleWindowRemoved(Window *window)
} }
return; return;
} }
#endif
if (auto wayland = qobject_cast<WaylandWindow *>(window)) { if (auto wayland = qobject_cast<WaylandWindow *>(window)) {
remove(s_waylandWindowId - 1, m_waylandWindows, wayland); remove(s_waylandWindowId - 1, m_waylandWindows, wayland);
@ -1020,9 +1026,17 @@ int DebugConsoleModel::rowCount(const QModelIndex &parent) const
} }
if (parent.internalId() < s_idDistance * (s_x11WindowId + 1)) { if (parent.internalId() < s_idDistance * (s_x11WindowId + 1)) {
#if KWIN_BUILD_X11
return propertyCount(parent, &DebugConsoleModel::x11Window); return propertyCount(parent, &DebugConsoleModel::x11Window);
#else
return 0;
#endif
} else if (parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) { } else if (parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) {
#if KWIN_BUILD_X11
return propertyCount(parent, &DebugConsoleModel::unmanaged); return propertyCount(parent, &DebugConsoleModel::unmanaged);
#else
return 0;
#endif
} else if (parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) { } else if (parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) {
return propertyCount(parent, &DebugConsoleModel::waylandWindow); return propertyCount(parent, &DebugConsoleModel::waylandWindow);
} else if (parent.internalId() < s_idDistance * (s_workspaceInternalId + 1)) { } else if (parent.internalId() < s_idDistance * (s_workspaceInternalId + 1)) {
@ -1085,9 +1099,17 @@ QModelIndex DebugConsoleModel::index(int row, int column, const QModelIndex &par
// index for a property (third level) // index for a property (third level)
if (parent.internalId() < s_idDistance * (s_x11WindowId + 1)) { if (parent.internalId() < s_idDistance * (s_x11WindowId + 1)) {
#if KWIN_BUILD_X11
return indexForProperty(row, column, parent, &DebugConsoleModel::x11Window); return indexForProperty(row, column, parent, &DebugConsoleModel::x11Window);
#else
return {};
#endif
} else if (parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) { } else if (parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) {
#if KWIN_BUILD_X11
return indexForProperty(row, column, parent, &DebugConsoleModel::unmanaged); return indexForProperty(row, column, parent, &DebugConsoleModel::unmanaged);
#else
return {};
#endif
} else if (parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) { } else if (parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) {
return indexForProperty(row, column, parent, &DebugConsoleModel::waylandWindow); return indexForProperty(row, column, parent, &DebugConsoleModel::waylandWindow);
} else if (parent.internalId() < s_idDistance * (s_workspaceInternalId + 1)) { } else if (parent.internalId() < s_idDistance * (s_workspaceInternalId + 1)) {
@ -1233,10 +1255,12 @@ QVariant DebugConsoleModel::data(const QModelIndex &index, int role) const
return propertyData(w, index, role); return propertyData(w, index, role);
} else if (InternalWindow *w = internalWindow(index)) { } else if (InternalWindow *w = internalWindow(index)) {
return propertyData(w, index, role); return propertyData(w, index, role);
#if KWIN_BUILD_X11
} else if (X11Window *w = x11Window(index)) { } else if (X11Window *w = x11Window(index)) {
return propertyData(w, index, role); return propertyData(w, index, role);
} else if (X11Window *u = unmanaged(index)) { } else if (X11Window *u = unmanaged(index)) {
return propertyData(u, index, role); return propertyData(u, index, role);
#endif
} }
} else { } else {
if (index.column() != 0) { if (index.column() != 0) {
@ -1248,10 +1272,14 @@ QVariant DebugConsoleModel::data(const QModelIndex &index, int role) const
}; };
switch (index.parent().internalId()) { switch (index.parent().internalId()) {
case s_x11WindowId: case s_x11WindowId:
#if KWIN_BUILD_X11
return windowData<X11Window>(index, role, m_x11Windows, [](X11Window *c) -> QString { return windowData<X11Window>(index, role, m_x11Windows, [](X11Window *c) -> QString {
return QStringLiteral("0x%1: %2").arg(c->window(), 0, 16).arg(c->caption()); return QStringLiteral("0x%1: %2").arg(c->window(), 0, 16).arg(c->caption());
}); });
#endif
break;
case s_x11UnmanagedId: { case s_x11UnmanagedId: {
#if KWIN_BUILD_X11
if (index.row() >= m_unmanageds.count()) { if (index.row() >= m_unmanageds.count()) {
return QVariant(); return QVariant();
} }
@ -1259,6 +1287,7 @@ QVariant DebugConsoleModel::data(const QModelIndex &index, int role) const
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
return QStringLiteral("0x%1").arg(u->window(), 0, 16); return QStringLiteral("0x%1").arg(u->window(), 0, 16);
} }
#endif
break; break;
} }
case s_waylandWindowId: case s_waylandWindowId:

View file

@ -12,7 +12,9 @@
#include "decorationpalette.h" #include "decorationpalette.h"
#include "window.h" #include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#include <KDecoration2/DecoratedClient> #include <KDecoration2/DecoratedClient>
#include <KDecoration2/Decoration> #include <KDecoration2/Decoration>
@ -136,17 +138,21 @@ DELEGATE(bool, isShaded, isShade)
WId DecoratedClientImpl::windowId() const WId DecoratedClientImpl::windowId() const
{ {
#if KWIN_BUILD_X11
if (X11Window *x11Window = qobject_cast<X11Window *>(m_window)) { if (X11Window *x11Window = qobject_cast<X11Window *>(m_window)) {
return x11Window->window(); return x11Window->window();
} }
#endif
return 0; return 0;
} }
WId DecoratedClientImpl::decorationId() const WId DecoratedClientImpl::decorationId() const
{ {
#if KWIN_BUILD_X11
if (X11Window *x11Window = qobject_cast<X11Window *>(m_window)) { if (X11Window *x11Window = qobject_cast<X11Window *>(m_window)) {
return x11Window->frameId(); return x11Window->frameId();
} }
#endif
return 0; return 0;
} }

View file

@ -42,8 +42,9 @@
#include "wayland_server.h" #include "wayland_server.h"
#include "window_property_notify_x11_filter.h" #include "window_property_notify_x11_filter.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
#endif #endif
@ -68,7 +69,7 @@
namespace KWin namespace KWin
{ {
#if KWIN_BUILD_X11
static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom_t type, int format) static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom_t type, int format)
{ {
if (win == XCB_WINDOW_NONE) { if (win == XCB_WINDOW_NONE) {
@ -108,6 +109,7 @@ static xcb_atom_t registerSupportProperty(const QByteArray &propertyName)
// TODO: add to _NET_SUPPORTED // TODO: add to _NET_SUPPORTED
return atomReply->atom; return atomReply->atom;
} }
#endif
//**************************************** //****************************************
// EffectsHandler // EffectsHandler
@ -200,6 +202,7 @@ EffectsHandler::EffectsHandler(Compositor *compositor, WorkspaceScene *scene)
connect(kwinApp()->screenLockerWatcher(), &ScreenLockerWatcher::aboutToLock, this, &EffectsHandler::screenAboutToLock); connect(kwinApp()->screenLockerWatcher(), &ScreenLockerWatcher::aboutToLock, this, &EffectsHandler::screenAboutToLock);
#endif #endif
#if KWIN_BUILD_X11
connect(kwinApp(), &Application::x11ConnectionChanged, this, [this]() { connect(kwinApp(), &Application::x11ConnectionChanged, this, [this]() {
registered_atoms.clear(); registered_atoms.clear();
for (auto it = m_propertiesForEffects.keyBegin(); it != m_propertiesForEffects.keyEnd(); it++) { for (auto it = m_propertiesForEffects.keyBegin(); it != m_propertiesForEffects.keyEnd(); it++) {
@ -222,6 +225,7 @@ EffectsHandler::EffectsHandler(Compositor *compositor, WorkspaceScene *scene)
if (kwinApp()->x11Connection()) { if (kwinApp()->x11Connection()) {
m_x11WindowPropertyNotify = std::make_unique<WindowPropertyNotifyX11Filter>(this); m_x11WindowPropertyNotify = std::make_unique<WindowPropertyNotifyX11Filter>(this);
} }
#endif
// connect all clients // connect all clients
for (Window *window : ws->windows()) { for (Window *window : ws->windows()) {
@ -244,6 +248,7 @@ EffectsHandler::~EffectsHandler()
KWin::effects = nullptr; KWin::effects = nullptr;
} }
#if KWIN_BUILD_X11
xcb_window_t EffectsHandler::x11RootWindow() const xcb_window_t EffectsHandler::x11RootWindow() const
{ {
return kwinApp()->x11RootWindow(); return kwinApp()->x11RootWindow();
@ -253,6 +258,7 @@ xcb_connection_t *EffectsHandler::xcbConnection() const
{ {
return kwinApp()->x11Connection(); return kwinApp()->x11Connection();
} }
#endif
CompositingType EffectsHandler::compositingType() const CompositingType EffectsHandler::compositingType() const
{ {
@ -638,6 +644,7 @@ bool EffectsHandler::hasKeyboardGrab() const
return keyboard_grab_effect != nullptr; return keyboard_grab_effect != nullptr;
} }
#if KWIN_BUILD_X11
void EffectsHandler::registerPropertyType(long atom, bool reg) void EffectsHandler::registerPropertyType(long atom, bool reg)
{ {
if (reg) { if (reg) {
@ -692,13 +699,18 @@ void EffectsHandler::removeSupportProperty(const QByteArray &propertyName, Effec
m_propertiesForEffects.remove(propertyName); m_propertiesForEffects.remove(propertyName);
m_compositor->removeSupportProperty(atom); // delayed removal m_compositor->removeSupportProperty(atom); // delayed removal
} }
#endif
QByteArray EffectsHandler::readRootProperty(long atom, long type, int format) const QByteArray EffectsHandler::readRootProperty(long atom, long type, int format) const
{ {
#if KWIN_BUILD_X11
if (!kwinApp()->x11Connection()) { if (!kwinApp()->x11Connection()) {
return QByteArray(); return QByteArray();
} }
return readWindowProperty(kwinApp()->x11RootWindow(), atom, type, format); return readWindowProperty(kwinApp()->x11RootWindow(), atom, type, format);
#else
return {};
#endif
} }
void EffectsHandler::activateWindow(EffectWindow *effectWindow) void EffectsHandler::activateWindow(EffectWindow *effectWindow)
@ -859,15 +871,16 @@ double EffectsHandler::animationTimeFactor() const
EffectWindow *EffectsHandler::findWindow(WId id) const EffectWindow *EffectsHandler::findWindow(WId id) const
{ {
#if KWIN_BUILD_X11
if (X11Window *w = Workspace::self()->findClient(Predicate::WindowMatch, id)) { if (X11Window *w = Workspace::self()->findClient(Predicate::WindowMatch, id)) {
return w->effectWindow(); return w->effectWindow();
} }
if (X11Window *w = Workspace::self()->findUnmanaged(id)) { if (X11Window *w = Workspace::self()->findUnmanaged(id)) {
return w->effectWindow(); return w->effectWindow();
} }
#endif
return nullptr; return nullptr;
} }
EffectWindow *EffectsHandler::findWindow(SurfaceInterface *surf) const EffectWindow *EffectsHandler::findWindow(SurfaceInterface *surf) const
{ {
if (waylandServer()) { if (waylandServer()) {
@ -1197,10 +1210,12 @@ void EffectsHandler::destroyEffect(Effect *effect)
stopMouseInterception(effect); stopMouseInterception(effect);
#if KWIN_BUILD_X11
const QList<QByteArray> properties = m_propertiesForEffects.keys(); const QList<QByteArray> properties = m_propertiesForEffects.keys();
for (const QByteArray &property : properties) { for (const QByteArray &property : properties) {
removeSupportProperty(property, effect); removeSupportProperty(property, effect);
} }
#endif
delete effect; delete effect;
} }

View file

@ -12,6 +12,7 @@
#pragma once #pragma once
#include "config-kwin.h"
#include "effect/effect.h" #include "effect/effect.h"
#include "effect/effectwindow.h" #include "effect/effectwindow.h"
@ -29,7 +30,9 @@
#include <functional> #include <functional>
#if KWIN_BUILD_X11
#include <xcb/xcb.h> #include <xcb/xcb.h>
#endif
class KConfigGroup; class KConfigGroup;
class QFont; class QFont;
@ -480,6 +483,8 @@ public:
void reconfigure(); void reconfigure();
QByteArray readRootProperty(long atom, long type, int format) const; QByteArray readRootProperty(long atom, long type, int format) const;
#if KWIN_BUILD_X11
/** /**
* @brief Announces support for the feature with the given name. If no other Effect * @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 * has announced support for this feature yet, an X11 property will be installed on
@ -511,6 +516,7 @@ public:
* @since 4.11 * @since 4.11
*/ */
void removeSupportProperty(const QByteArray &propertyName, Effect *effect); void removeSupportProperty(const QByteArray &propertyName, Effect *effect);
#endif
/** /**
* Returns @a true if the active window decoration has shadow API hooks. * Returns @a true if the active window decoration has shadow API hooks.
@ -570,8 +576,10 @@ public:
*/ */
void doneOpenGLContextCurrent(); void doneOpenGLContextCurrent();
#if KWIN_BUILD_X11
xcb_connection_t *xcbConnection() const; xcb_connection_t *xcbConnection() const;
xcb_window_t x11RootWindow() const; xcb_window_t x11RootWindow() const;
#endif
/** /**
* Interface to the Wayland display: this is relevant only * Interface to the Wayland display: this is relevant only
@ -741,10 +749,12 @@ public:
void highlightWindows(const QList<EffectWindow *> &windows); void highlightWindows(const QList<EffectWindow *> &windows);
#if KWIN_BUILD_X11
bool isPropertyTypeRegistered(xcb_atom_t atom) const bool isPropertyTypeRegistered(xcb_atom_t atom) const
{ {
return registered_atoms.contains(atom); return registered_atoms.contains(atom);
} }
#endif
Q_SIGNALS: Q_SIGNALS:
/** /**
@ -987,6 +997,7 @@ Q_SIGNALS:
*/ */
void windowDataChanged(KWin::EffectWindow *w, int role); void windowDataChanged(KWin::EffectWindow *w, int role);
#if KWIN_BUILD_X11
/** /**
* The xcb connection changed, either a new xcbConnection got created or the existing one * The xcb connection changed, either a new xcbConnection got created or the existing one
* got destroyed. * got destroyed.
@ -998,6 +1009,7 @@ Q_SIGNALS:
* @since 5.11 * @since 5.11
*/ */
void xcbConnectionChanged(); void xcbConnectionChanged();
#endif
/** /**
* This signal is emitted when active fullscreen effect changed. * This signal is emitted when active fullscreen effect changed.
@ -1082,7 +1094,9 @@ protected:
Effect *keyboard_grab_effect; Effect *keyboard_grab_effect;
Effect *fullscreen_effect; Effect *fullscreen_effect;
QMultiMap<int, EffectPair> effect_order; QMultiMap<int, EffectPair> effect_order;
#if KWIN_BUILD_X11
QHash<long, int> registered_atoms; QHash<long, int> registered_atoms;
#endif
QList<EffectPair> loaded_effects; QList<EffectPair> loaded_effects;
CompositingType compositing_type; CompositingType compositing_type;
EffectsList m_activeEffects; EffectsList m_activeEffects;
@ -1090,7 +1104,9 @@ protected:
EffectsIterator m_currentPaintWindowIterator; EffectsIterator m_currentPaintWindowIterator;
EffectsIterator m_currentPaintScreenIterator; EffectsIterator m_currentPaintScreenIterator;
typedef QHash<QByteArray, QList<Effect *>> PropertyEffectMap; typedef QHash<QByteArray, QList<Effect *>> PropertyEffectMap;
#if KWIN_BUILD_X11
PropertyEffectMap m_propertiesForEffects; PropertyEffectMap m_propertiesForEffects;
#endif
QHash<QByteArray, qulonglong> m_managedProperties; QHash<QByteArray, qulonglong> m_managedProperties;
Compositor *m_compositor; Compositor *m_compositor;
WorkspaceScene *m_scene; WorkspaceScene *m_scene;

View file

@ -10,12 +10,15 @@
#include "effect/effectwindow.h" #include "effect/effectwindow.h"
#include "core/output.h" #include "core/output.h"
#include "effect/effecthandler.h" #include "effect/effecthandler.h"
#include "group.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "scene/windowitem.h" #include "scene/windowitem.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "waylandwindow.h" #include "waylandwindow.h"
#if KWIN_BUILD_X11
#include "group.h"
#include "x11window.h" #include "x11window.h"
#endif
namespace KWin namespace KWin
{ {
@ -54,7 +57,11 @@ EffectWindow::EffectWindow(WindowItem *windowItem)
d->managed = d->m_window->isClient(); d->managed = d->m_window->isClient();
d->m_waylandWindow = qobject_cast<KWin::WaylandWindow *>(d->m_window) != nullptr; d->m_waylandWindow = qobject_cast<KWin::WaylandWindow *>(d->m_window) != nullptr;
#if KWIN_BUILD_X11
d->m_x11Window = qobject_cast<KWin::X11Window *>(d->m_window) != nullptr; d->m_x11Window = qobject_cast<KWin::X11Window *>(d->m_window) != nullptr;
#else
d->m_x11Window = false;
#endif
connect(d->m_window, &Window::hiddenChanged, this, [this]() { connect(d->m_window, &Window::hiddenChanged, this, [this]() {
Q_EMIT windowHiddenChanged(this); Q_EMIT windowHiddenChanged(this);
@ -210,9 +217,11 @@ void EffectWindow::addLayerRepaint(const QRect &r)
const EffectWindowGroup *EffectWindow::group() const const EffectWindowGroup *EffectWindow::group() const
{ {
#if KWIN_BUILD_X11
if (Group *group = d->m_window->group()) { if (Group *group = d->m_window->group()) {
return group->effectGroup(); return group->effectGroup();
} }
#endif
return nullptr; return nullptr;
} }
@ -302,9 +311,11 @@ WINDOW_HELPER(bool, isInputMethod, isInputMethod)
qlonglong EffectWindow::windowId() const qlonglong EffectWindow::windowId() const
{ {
#if KWIN_BUILD_X11
if (X11Window *x11Window = qobject_cast<X11Window *>(d->m_window)) { if (X11Window *x11Window = qobject_cast<X11Window *>(d->m_window)) {
return x11Window->window(); return x11Window->window();
} }
#endif
return 0; return 0;
} }
@ -325,9 +336,11 @@ WindowType EffectWindow::windowType() const
QSizeF EffectWindow::basicUnit() const QSizeF EffectWindow::basicUnit() const
{ {
#if KWIN_BUILD_X11
if (auto window = qobject_cast<X11Window *>(d->m_window)) { if (auto window = qobject_cast<X11Window *>(d->m_window)) {
return window->basicUnit(); return window->basicUnit();
} }
#endif
return QSize(1, 1); return QSize(1, 1);
} }
@ -343,6 +356,7 @@ KDecoration2::Decoration *EffectWindow::decoration() const
QByteArray EffectWindow::readProperty(long atom, long type, int format) const QByteArray EffectWindow::readProperty(long atom, long type, int format) const
{ {
#if KWIN_BUILD_X11
auto x11Window = qobject_cast<X11Window *>(d->m_window); auto x11Window = qobject_cast<X11Window *>(d->m_window);
if (!x11Window) { if (!x11Window) {
return QByteArray(); return QByteArray();
@ -363,10 +377,13 @@ QByteArray EffectWindow::readProperty(long atom, long type, int format) const
} }
return prop.toByteArray(format, type); return prop.toByteArray(format, type);
} }
#endif
return {};
} }
void EffectWindow::deleteProperty(long int atom) const void EffectWindow::deleteProperty(long int atom) const
{ {
#if KWIN_BUILD_X11
auto x11Window = qobject_cast<X11Window *>(d->m_window); auto x11Window = qobject_cast<X11Window *>(d->m_window);
if (!x11Window) { if (!x11Window) {
return; return;
@ -375,6 +392,7 @@ void EffectWindow::deleteProperty(long int atom) const
return; return;
} }
xcb_delete_property(kwinApp()->x11Connection(), x11Window->window(), atom); xcb_delete_property(kwinApp()->x11Connection(), x11Window->window(), atom);
#endif
} }
EffectWindow *EffectWindow::findModal() EffectWindow *EffectWindow::findModal()
@ -495,12 +513,14 @@ EffectWindowGroup::~EffectWindowGroup()
QList<EffectWindow *> EffectWindowGroup::members() const QList<EffectWindow *> EffectWindowGroup::members() const
{ {
const auto memberList = m_group->members();
QList<EffectWindow *> ret; QList<EffectWindow *> ret;
#if KWIN_BUILD_X11
const auto memberList = m_group->members();
ret.reserve(memberList.size()); ret.reserve(memberList.size());
std::transform(std::cbegin(memberList), std::cend(memberList), std::back_inserter(ret), [](auto window) { std::transform(std::cbegin(memberList), std::cend(memberList), std::back_inserter(ret), [](auto window) {
return window->effectWindow(); return window->effectWindow();
}); });
#endif
return ret; return ret;
} }

View file

@ -9,11 +9,13 @@
#pragma once #pragma once
#include "core/output.h"
#include "kwin_export.h" #include "kwin_export.h"
#include "globals.h" #include "globals.h"
#include <QObject> #include <QObject>
#include <QWindow>
class QWindow; class QWindow;

View file

@ -8,6 +8,11 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include <QGuiApplication> #include <QGuiApplication>
#include <kwin_export.h> #include <kwin_export.h>

View file

@ -13,6 +13,7 @@
#include "workspace.h" #include "workspace.h"
#include "x11window.h" #include "x11window.h"
#include <KStartupInfo>
#include <KX11Extras> #include <KX11Extras>
#include <QDebug> #include <QDebug>
@ -116,4 +117,32 @@ void Group::lostLeader()
} }
} }
void Group::startupIdChanged()
{
KStartupInfoId asn_id;
KStartupInfoData asn_data;
bool asn_valid = workspace()->checkStartupNotification(leader_wid, asn_id, asn_data);
if (!asn_valid) {
return;
}
if (asn_id.timestamp() != 0 && user_time != -1U
&& NET::timestampCompare(asn_id.timestamp(), user_time) > 0) {
user_time = asn_id.timestamp();
}
}
void Group::updateUserTime(xcb_timestamp_t time)
{
// copy of X11Window::updateUserTime
if (time == XCB_CURRENT_TIME) {
kwinApp()->updateXTime();
time = xTime();
}
if (time != -1U
&& (user_time == XCB_CURRENT_TIME
|| NET::timestampCompare(time, user_time) > 0)) { // time > user_time
user_time = time;
}
}
} // namespace } // namespace

View file

@ -10,6 +10,11 @@
#pragma once #pragma once
#include <config-kwin.h>
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include "utils/common.h" #include "utils/common.h"
#include <netwm.h> #include <netwm.h>

View file

@ -15,6 +15,9 @@ ecm_qt_declare_logging_category(kwin_wayland_wrapper
Warning Warning
) )
target_link_libraries(kwin_wayland_wrapper Qt::Core Qt::DBus KF6::DBusAddons KF6::CoreAddons KWinXwaylandCommon) target_link_libraries(kwin_wayland_wrapper Qt::Core Qt::DBus KF6::DBusAddons KF6::CoreAddons)
if (KWIN_BUILD_X11)
target_link_libraries(kwin_wayland_wrapper KWinXwaylandCommon)
endif()
set_property(TARGET kwin_wayland_wrapper PROPERTY C_STANDARD 11) set_property(TARGET kwin_wayland_wrapper PROPERTY C_STANDARD 11)
install(TARGETS kwin_wayland_wrapper ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS kwin_wayland_wrapper ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

View file

@ -20,6 +20,8 @@
* Usage kwin_wayland_wrapper [argForKwin] [argForKwin] ... * Usage kwin_wayland_wrapper [argForKwin] [argForKwin] ...
*/ */
#include "config-kwin.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDBusConnection> #include <QDBusConnection>
#include <QDebug> #include <QDebug>
@ -33,8 +35,11 @@
#include "wl-socket.h" #include "wl-socket.h"
#include "wrapper_logging.h" #include "wrapper_logging.h"
#if KWIN_BUILD_X11
#include "xauthority.h" #include "xauthority.h"
#include "xwaylandsocket.h" #include "xwaylandsocket.h"
#endif
using namespace std::chrono_literals; using namespace std::chrono_literals;
@ -55,10 +60,13 @@ private:
int m_crashCount = 0; int m_crashCount = 0;
QProcess *m_kwinProcess = nullptr; QProcess *m_kwinProcess = nullptr;
std::unique_ptr<KWin::XwaylandSocket> m_xwlSocket;
QTemporaryFile m_xauthorityFile;
const std::chrono::microseconds m_watchdogInterval; const std::chrono::microseconds m_watchdogInterval;
bool m_watchdogIntervalOk; bool m_watchdogIntervalOk;
#if KWIN_BUILD_X11
std::unique_ptr<KWin::XwaylandSocket> m_xwlSocket;
QTemporaryFile m_xauthorityFile;
#endif
}; };
KWinWrapper::KWinWrapper(QObject *parent) KWinWrapper::KWinWrapper(QObject *parent)
@ -71,6 +79,7 @@ KWinWrapper::KWinWrapper(QObject *parent)
qFatal("Could not create wayland socket"); qFatal("Could not create wayland socket");
} }
#if KWIN_BUILD_X11
if (qApp->arguments().contains(QLatin1String("--xwayland"))) { if (qApp->arguments().contains(QLatin1String("--xwayland"))) {
m_xwlSocket = std::make_unique<KWin::XwaylandSocket>(KWin::XwaylandSocket::OperationMode::TransferFdsOnExec); m_xwlSocket = std::make_unique<KWin::XwaylandSocket>(KWin::XwaylandSocket::OperationMode::TransferFdsOnExec);
if (!m_xwlSocket->isValid()) { if (!m_xwlSocket->isValid()) {
@ -85,6 +94,7 @@ KWinWrapper::KWinWrapper(QObject *parent)
} }
} }
} }
#endif
} }
KWinWrapper::~KWinWrapper() KWinWrapper::~KWinWrapper()
@ -102,6 +112,7 @@ void KWinWrapper::run()
args << "--wayland-fd" << QString::number(wl_socket_get_fd(m_socket)); args << "--wayland-fd" << QString::number(wl_socket_get_fd(m_socket));
args << "--socket" << QString::fromUtf8(wl_socket_get_display_name(m_socket)); args << "--socket" << QString::fromUtf8(wl_socket_get_display_name(m_socket));
#if KWIN_BUILD_X11
if (m_xwlSocket) { if (m_xwlSocket) {
const auto xwaylandFileDescriptors = m_xwlSocket->fileDescriptors(); const auto xwaylandFileDescriptors = m_xwlSocket->fileDescriptors();
for (const int &fileDescriptor : xwaylandFileDescriptors) { for (const int &fileDescriptor : xwaylandFileDescriptors) {
@ -112,6 +123,7 @@ void KWinWrapper::run()
args << "--xwayland-xauthority" << m_xauthorityFile.fileName(); args << "--xwayland-xauthority" << m_xauthorityFile.fileName();
} }
} }
#endif
// attach our main process arguments // attach our main process arguments
// the first entry is dropped as it will be our program name // the first entry is dropped as it will be our program name
@ -143,12 +155,14 @@ void KWinWrapper::run()
QProcessEnvironment env; QProcessEnvironment env;
env.insert("WAYLAND_DISPLAY", QString::fromUtf8(wl_socket_get_display_name(m_socket))); env.insert("WAYLAND_DISPLAY", QString::fromUtf8(wl_socket_get_display_name(m_socket)));
#if KWIN_BUILD_X11
if (m_xwlSocket) { if (m_xwlSocket) {
env.insert("DISPLAY", m_xwlSocket->name()); env.insert("DISPLAY", m_xwlSocket->name());
if (m_xauthorityFile.open()) { if (m_xauthorityFile.open()) {
env.insert("XAUTHORITY", m_xauthorityFile.fileName()); env.insert("XAUTHORITY", m_xauthorityFile.fileName());
} }
} }
#endif
auto envSyncJob = new KUpdateLaunchEnvironmentJob(env); auto envSyncJob = new KUpdateLaunchEnvironmentJob(env);
connect(envSyncJob, &KUpdateLaunchEnvironmentJob::finished, this, []() { connect(envSyncJob, &KUpdateLaunchEnvironmentJob::finished, this, []() {
// The service name is merely there to indicate to the world that we're up and ready with all envs exported // The service name is merely there to indicate to the world that we're up and ready with all envs exported

View file

@ -30,7 +30,9 @@
#include "tablet_input.h" #include "tablet_input.h"
#include "touch_input.h" #include "touch_input.h"
#include "wayland/xdgtopleveldrag_v1.h" #include "wayland/xdgtopleveldrag_v1.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#if KWIN_BUILD_TABBOX #if KWIN_BUILD_TABBOX
#include "tabbox/tabbox.h" #include "tabbox/tabbox.h"
#endif #endif
@ -2363,10 +2365,11 @@ static AbstractDropHandler *dropHandler(Window *window)
if (dropTarget) { if (dropTarget) {
return dropTarget; return dropTarget;
} }
#if KWIN_BUILD_X11
if (qobject_cast<X11Window *>(window) && kwinApp()->xwayland()) { if (qobject_cast<X11Window *>(window) && kwinApp()->xwayland()) {
return kwinApp()->xwayland()->xwlDropHandler(); return kwinApp()->xwayland()->xwlDropHandler();
} }
#endif
return nullptr; return nullptr;
} }

View file

@ -34,7 +34,6 @@
#include <KLocalizedString> #include <KLocalizedString>
#include <KShell> #include <KShell>
#include <KKeyServer>
#include <QDBusConnection> #include <QDBusConnection>
#include <QDBusMessage> #include <QDBusMessage>
@ -43,6 +42,7 @@
#include <QMenu> #include <QMenu>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#include <private/qxkbcommon_p.h>
#include <unistd.h> #include <unistd.h>
#include <xkbcommon/xkbcommon-keysyms.h> #include <xkbcommon/xkbcommon-keysyms.h>
@ -60,13 +60,14 @@ static std::vector<quint32> textToKey(const QString &text)
return {}; return {};
} }
const QList<int> syms(KKeyServer::keyQtToSymXs(sequence[0])); QKeyEvent ev(QEvent::KeyPress, sequence[0], Qt::NoModifier);
const QList<xkb_keysym_t> syms(QXkbCommon::toKeysym(&ev));
if (syms.empty()) { if (syms.empty()) {
return {}; return {};
} }
std::optional<int> keyCode; std::optional<xkb_keycode_t> keyCode;
for (int sym : syms) { for (xkb_keysym_t sym : syms) {
auto code = input()->keyboard()->xkb()->keycodeFromKeysym(sym); auto code = input()->keyboard()->xkb()->keycodeFromKeysym(sym);
if (code) { if (code) {
keyCode = code; keyCode = code;

View file

@ -20,11 +20,13 @@ kconfig_add_kcfg_files(kwinrules_SRCS ../../rulebooksettingsbase.kcfgc)
add_library(KWinRulesObjects STATIC ${kwinrules_SRCS}) add_library(KWinRulesObjects STATIC ${kwinrules_SRCS})
set_property(TARGET KWinRulesObjects PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET KWinRulesObjects PROPERTY POSITION_INDEPENDENT_CODE ON)
set(kwin_kcm_rules_XCB_LIBS if (KWIN_BUILD_X11)
XCB::CURSOR set(kwin_kcm_rules_XCB_LIBS
XCB::XCB XCB::CURSOR
XCB::XFIXES XCB::XCB
) XCB::XFIXES
)
endif()
set(kcm_libs set(kcm_libs
Qt::Quick Qt::Quick

View file

@ -27,8 +27,12 @@ target_link_libraries(kcm_kwintabbox
KF6::Package KF6::Package
KF6::Service KF6::Service
KF6::XmlGui # For kkeysequencewidget KF6::XmlGui # For kkeysequencewidget
XCB::XCB
) )
if (KWIN_BUILD_X11)
target_link_libraries(kcm_kwintabbox
XCB::XCB
)
endif()
########### install files ############### ########### install files ###############
install(FILES thumbnails/falkon.png install(FILES thumbnails/falkon.png

View file

@ -11,9 +11,11 @@
#include "wayland/seat.h" #include "wayland/seat.h"
#include "wayland/xdgforeign_v2.h" #include "wayland/xdgforeign_v2.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "x11window.h"
#include "xdgactivationv1.h" #include "xdgactivationv1.h"
#include "xdgshellwindow.h" #include "xdgshellwindow.h"
#if KWIN_BUILD_X11
#include "x11window.h"
#endif
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
@ -25,7 +27,11 @@ namespace KWin
KillPrompt::KillPrompt(Window *window) KillPrompt::KillPrompt(Window *window)
: m_window(window) : m_window(window)
{ {
#if KWIN_BUILD_X11
Q_ASSERT(qobject_cast<X11Window *>(window) || qobject_cast<XdgToplevelWindow *>(window)); Q_ASSERT(qobject_cast<X11Window *>(window) || qobject_cast<XdgToplevelWindow *>(window));
#else
Q_ASSERT(qobject_cast<XdgToplevelWindow *>(window));
#endif
m_process.setProcessChannelMode(QProcess::ForwardedChannels); m_process.setProcessChannelMode(QProcess::ForwardedChannels);
@ -58,6 +64,7 @@ void KillPrompt::start(quint32 timestamp)
QString appId = !m_window->desktopFileName().isEmpty() ? m_window->desktopFileName() : m_window->resourceClass(); QString appId = !m_window->desktopFileName().isEmpty() ? m_window->desktopFileName() : m_window->resourceClass();
QString platform; QString platform;
#if KWIN_BUILD_X11
if (auto *x11Window = qobject_cast<X11Window *>(m_window)) { if (auto *x11Window = qobject_cast<X11Window *>(m_window)) {
platform = QStringLiteral("xcb"); platform = QStringLiteral("xcb");
wid = QString::number(x11Window->window()); wid = QString::number(x11Window->window());
@ -65,7 +72,9 @@ void KillPrompt::start(quint32 timestamp)
if (!x11Window->clientMachine()->isLocal()) { if (!x11Window->clientMachine()->isLocal()) {
hostname = x11Window->clientMachine()->hostName(); hostname = x11Window->clientMachine()->hostName();
} }
} else if (auto *xdgToplevel = qobject_cast<XdgToplevelWindow *>(m_window)) { } else
#endif
if (auto *xdgToplevel = qobject_cast<XdgToplevelWindow *>(m_window)) {
platform = QStringLiteral("wayland"); platform = QStringLiteral("wayland");
auto *exported = waylandServer()->exportAsForeign(xdgToplevel->surface()); auto *exported = waylandServer()->exportAsForeign(xdgToplevel->surface());
wid = exported->handle(); wid = exported->handle();

View file

@ -67,9 +67,7 @@
#include "compositor.h" #include "compositor.h"
#include "effect/effecthandler.h" #include "effect/effecthandler.h"
#include "focuschain.h" #include "focuschain.h"
#include "group.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "netinfo.h"
#include "rules.h" #include "rules.h"
#include "screenedge.h" #include "screenedge.h"
#include "tabbox/tabbox.h" #include "tabbox/tabbox.h"
@ -77,7 +75,11 @@
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "group.h"
#include "netinfo.h"
#include "x11window.h" #include "x11window.h"
#endif
#include <array> #include <array>
@ -103,7 +105,9 @@ void Workspace::updateStackingOrder(bool propagate_new_windows)
force_restacking = false; force_restacking = false;
stacking_order = new_stacking_order; stacking_order = new_stacking_order;
if (changed || propagate_new_windows) { if (changed || propagate_new_windows) {
#if KWIN_BUILD_X11
propagateWindows(propagate_new_windows); propagateWindows(propagate_new_windows);
#endif
for (int i = 0; i < stacking_order.size(); ++i) { for (int i = 0; i < stacking_order.size(); ++i) {
stacking_order[i]->setStackingOrder(i); stacking_order[i]->setStackingOrder(i);
@ -117,6 +121,7 @@ void Workspace::updateStackingOrder(bool propagate_new_windows)
} }
} }
#if KWIN_BUILD_X11
/** /**
* Some fullscreen effects have to raise the screenedge on top of an input window, thus all windows * Some fullscreen effects have to raise the screenedge on top of an input window, thus all windows
* this function puts them back where they belong for regular use and is some cheap variant of * this function puts them back where they belong for regular use and is some cheap variant of
@ -214,6 +219,7 @@ void Workspace::propagateWindows(bool propagate_new_windows)
} }
rootInfo()->setClientListStacking(cl.constData(), cl.size()); rootInfo()->setClientListStacking(cl.constData(), cl.size());
} }
#endif
/** /**
* Returns topmost visible window. Windows on the dock, the desktop * Returns topmost visible window. Windows on the dock, the desktop
@ -306,6 +312,8 @@ void Workspace::lowerWindow(Window *window, bool nogroup)
unconstrained_stacking_order.removeAll(window); unconstrained_stacking_order.removeAll(window);
unconstrained_stacking_order.prepend(window); unconstrained_stacking_order.prepend(window);
// TODO How X11-specific is this implementation?
#if KWIN_BUILD_X11
if (!nogroup && window->isTransient()) { if (!nogroup && window->isTransient()) {
// lower also all windows in the group, in their reversed stacking order // lower also all windows in the group, in their reversed stacking order
QList<X11Window *> wins; QList<X11Window *> wins;
@ -318,6 +326,7 @@ void Workspace::lowerWindow(Window *window, bool nogroup)
} }
} }
} }
#endif
} }
void Workspace::lowerWindowWithinApplication(Window *window) void Workspace::lowerWindowWithinApplication(Window *window)
@ -416,6 +425,7 @@ void Workspace::raiseWindowRequest(Window *window, NET::RequestSource src, xcb_t
} }
} }
#if KWIN_BUILD_X11
void Workspace::lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t /*timestamp*/) void Workspace::lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t /*timestamp*/)
{ {
// If the window has support for all this focus stealing prevention stuff, // If the window has support for all this focus stealing prevention stuff,
@ -428,6 +438,7 @@ void Workspace::lowerWindowRequest(X11Window *window, NET::RequestSource src, xc
lowerWindowWithinApplication(window); lowerWindowWithinApplication(window);
} }
} }
#endif
void Workspace::lowerWindowRequest(Window *window) void Workspace::lowerWindowRequest(Window *window)
{ {
@ -470,6 +481,7 @@ void Workspace::restackWindowUnderActive(Window *window)
restack(window, m_activeWindow); restack(window, m_activeWindow);
} }
#if KWIN_BUILD_X11
void Workspace::restoreSessionStackingOrder(X11Window *window) void Workspace::restoreSessionStackingOrder(X11Window *window)
{ {
if (window->sessionStackingOrder() < 0) { if (window->sessionStackingOrder() < 0) {
@ -515,14 +527,16 @@ static Layer layerForWindow(const X11Window *window)
return layer; return layer;
} }
#endif
static Layer computeLayer(const Window *window) static Layer computeLayer(const Window *window)
{ {
#if KWIN_BUILD_X11
if (auto x11Window = qobject_cast<const X11Window *>(window)) { if (auto x11Window = qobject_cast<const X11Window *>(window)) {
return layerForWindow(x11Window); return layerForWindow(x11Window);
} else {
return window->layer();
} }
#endif
return window->layer();
} }
/** /**
@ -635,11 +649,13 @@ QList<T *> ensureStackingOrderInList(const QList<Window *> &stackingOrder, const
} }
} }
#if KWIN_BUILD_X11
// Ensure list is in stacking order // Ensure list is in stacking order
QList<X11Window *> Workspace::ensureStackingOrder(const QList<X11Window *> &list) const QList<X11Window *> Workspace::ensureStackingOrder(const QList<X11Window *> &list) const
{ {
return ensureStackingOrderInList(stacking_order, list); return ensureStackingOrderInList(stacking_order, list);
} }
#endif
QList<Window *> Workspace::ensureStackingOrder(const QList<Window *> &list) const QList<Window *> Workspace::ensureStackingOrder(const QList<Window *> &list) const
{ {
@ -651,6 +667,7 @@ QList<Window *> Workspace::unconstrainedStackingOrder() const
return unconstrained_stacking_order; return unconstrained_stacking_order;
} }
#if KWIN_BUILD_X11
void Workspace::updateXStackingOrder() void Workspace::updateXStackingOrder()
{ {
// we use our stacking order for managed windows, but X's for override-redirect windows // we use our stacking order for managed windows, but X's for override-redirect windows
@ -672,100 +689,6 @@ void Workspace::updateXStackingOrder()
updateStackingOrder(); updateStackingOrder();
} }
} }
#endif
//*******************************
// Client
//*******************************
void X11Window::restackWindow(xcb_window_t above, int detail, NET::RequestSource src, xcb_timestamp_t timestamp, bool send_event)
{
X11Window *other = nullptr;
if (detail == XCB_STACK_MODE_OPPOSITE) {
other = workspace()->findClient(Predicate::WindowMatch, above);
if (!other) {
workspace()->raiseOrLowerWindow(this);
return;
}
auto it = workspace()->stackingOrder().constBegin(),
end = workspace()->stackingOrder().constEnd();
while (it != end) {
if (*it == this) {
detail = XCB_STACK_MODE_ABOVE;
break;
} else if (*it == other) {
detail = XCB_STACK_MODE_BELOW;
break;
}
++it;
}
} else if (detail == XCB_STACK_MODE_TOP_IF) {
other = workspace()->findClient(Predicate::WindowMatch, above);
if (other && other->frameGeometry().intersects(frameGeometry())) {
workspace()->raiseWindowRequest(this, src, timestamp);
}
return;
} else if (detail == XCB_STACK_MODE_BOTTOM_IF) {
other = workspace()->findClient(Predicate::WindowMatch, above);
if (other && other->frameGeometry().intersects(frameGeometry())) {
workspace()->lowerWindowRequest(this, src, timestamp);
}
return;
}
if (!other) {
other = workspace()->findClient(Predicate::WindowMatch, above);
}
if (other && detail == XCB_STACK_MODE_ABOVE) {
auto it = workspace()->stackingOrder().constEnd(),
begin = workspace()->stackingOrder().constBegin();
while (--it != begin) {
if (*it == other) { // the other one is top on stack
it = begin; // invalidate
src = NET::FromTool; // force
break;
}
X11Window *window = qobject_cast<X11Window *>(*it);
if (!window || !((*it)->isNormalWindow() && window->isShown() && (*it)->isOnCurrentDesktop() && (*it)->isOnCurrentActivity() && (*it)->isOnOutput(output()))) {
continue; // irrelevant windows
}
if (*(it - 1) == other) {
break; // "it" is the one above the target one, stack below "it"
}
}
if (it != begin && (*(it - 1) == other)) {
other = qobject_cast<X11Window *>(*it);
} else {
other = nullptr;
}
}
if (other) {
workspace()->restack(this, other);
} else if (detail == XCB_STACK_MODE_BELOW) {
workspace()->lowerWindowRequest(this, src, timestamp);
} else if (detail == XCB_STACK_MODE_ABOVE) {
workspace()->raiseWindowRequest(this, src, timestamp);
}
if (send_event) {
sendSyntheticConfigureNotify();
}
}
bool X11Window::belongsToDesktop() const
{
const auto members = group()->members();
for (const X11Window *window : members) {
if (window->isDesktop()) {
return true;
}
}
return false;
}
} // namespace } // namespace

View file

@ -11,7 +11,9 @@
#include "config-kwin.h" #include "config-kwin.h"
#if KWIN_BUILD_X11
#include "atoms.h" #include "atoms.h"
#endif
#include "colors/colormanager.h" #include "colors/colormanager.h"
#include "compositor.h" #include "compositor.h"
#include "core/outputbackend.h" #include "core/outputbackend.h"
@ -32,10 +34,13 @@
#include "screenedge.h" #include "screenedge.h"
#include "sm.h" #include "sm.h"
#include "tabletmodemanager.h" #include "tabletmodemanager.h"
#include "utils/xcbutils.h"
#include "wayland/surface.h" #include "wayland/surface.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h"
#include "x11eventfilter.h" #include "x11eventfilter.h"
#endif
#if KWIN_BUILD_SCREENLOCKER #if KWIN_BUILD_SCREENLOCKER
#include "screenlockerwatcher.h" #include "screenlockerwatcher.h"
@ -59,11 +64,13 @@
#endif #endif
#include <unistd.h> #include <unistd.h>
#if KWIN_BUILD_X11
// xcb // xcb
#include <xcb/damage.h> #include <xcb/damage.h>
#ifndef XCB_GE_GENERIC #ifndef XCB_GE_GENERIC
#define XCB_GE_GENERIC 35 #define XCB_GE_GENERIC 35
#endif #endif
#endif
Q_DECLARE_METATYPE(KSharedConfigPtr) Q_DECLARE_METATYPE(KSharedConfigPtr)
@ -71,12 +78,16 @@ namespace KWin
{ {
Options *options; Options *options;
#if KWIN_BUILD_X11
Atoms *atoms; Atoms *atoms;
#endif
int Application::crashes = 0; int Application::crashes = 0;
Application::Application(Application::OperationMode mode, int &argc, char **argv) Application::Application(Application::OperationMode mode, int &argc, char **argv)
: QApplication(argc, argv) : QApplication(argc, argv)
#if KWIN_BUILD_X11
, m_eventFilter(new XcbEventFilter()) , m_eventFilter(new XcbEventFilter())
#endif
, m_configLock(false) , m_configLock(false)
, m_config(KSharedConfig::openConfig(QStringLiteral("kwinrc"))) , m_config(KSharedConfig::openConfig(QStringLiteral("kwinrc")))
, m_kxkbConfig() , m_kxkbConfig()
@ -150,8 +161,10 @@ void Application::notifyStarted()
void Application::destroyAtoms() void Application::destroyAtoms()
{ {
#if KWIN_BUILD_X11
delete atoms; delete atoms;
atoms = nullptr; atoms = nullptr;
#endif
} }
void Application::destroyPlatform() void Application::destroyPlatform()
@ -262,7 +275,9 @@ void Application::createInput()
void Application::createAtoms() void Application::createAtoms()
{ {
#if KWIN_BUILD_X11
atoms = new Atoms; atoms = new Atoms;
#endif
} }
void Application::createOptions() void Application::createOptions()
@ -295,6 +310,7 @@ TabletModeManager *Application::tabletModeManager() const
return m_tabletModeManager.get(); return m_tabletModeManager.get();
} }
#if KWIN_BUILD_X11
void Application::installNativeX11EventFilter() void Application::installNativeX11EventFilter()
{ {
installNativeEventFilter(m_eventFilter.get()); installNativeEventFilter(m_eventFilter.get());
@ -304,6 +320,7 @@ void Application::removeNativeX11EventFilter()
{ {
removeNativeEventFilter(m_eventFilter.get()); removeNativeEventFilter(m_eventFilter.get());
} }
#endif
void Application::destroyInput() void Application::destroyInput()
{ {
@ -358,6 +375,7 @@ void Application::createEffectsHandler(Compositor *compositor, WorkspaceScene *s
new EffectsHandler(compositor, scene); new EffectsHandler(compositor, scene);
} }
#if KWIN_BUILD_X11
void Application::registerEventFilter(X11EventFilter *filter) void Application::registerEventFilter(X11EventFilter *filter)
{ {
if (filter->isGenericEvent()) { if (filter->isGenericEvent()) {
@ -378,6 +396,7 @@ static X11EventFilterContainer *takeEventFilter(X11EventFilter *eventFilter,
} }
return nullptr; return nullptr;
} }
#endif
void Application::setXwaylandScale(qreal scale) void Application::setXwaylandScale(qreal scale)
{ {
@ -403,12 +422,15 @@ void Application::applyXwaylandScale()
} }
xwaylandGroup.sync(); xwaylandGroup.sync();
#if KWIN_BUILD_X11
if (x11Connection()) { if (x11Connection()) {
// rerun the fonts kcm init that does the appropriate xrdb call with the new settings // rerun the fonts kcm init that does the appropriate xrdb call with the new settings
QProcess::startDetached("kcminit", {"kcm_fonts_init", "kcm_style_init"}); QProcess::startDetached("kcminit", {"kcm_fonts_init", "kcm_style_init"});
} }
#endif
} }
#if KWIN_BUILD_X11
void Application::unregisterEventFilter(X11EventFilter *filter) void Application::unregisterEventFilter(X11EventFilter *filter)
{ {
X11EventFilterContainer *container = nullptr; X11EventFilterContainer *container = nullptr;
@ -625,6 +647,8 @@ bool XcbEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
return false; return false;
} }
#endif
QProcessEnvironment Application::processStartupEnvironment() const QProcessEnvironment Application::processStartupEnvironment() const
{ {
return m_processEnvironment; return m_processEnvironment;

View file

@ -21,7 +21,9 @@
#include <QApplication> #include <QApplication>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#if KWIN_BUILD_X11
#include <xcb/xcb.h> #include <xcb/xcb.h>
#endif
class KPluginMetaData; class KPluginMetaData;
class QCommandLineParser; class QCommandLineParser;
@ -69,9 +71,11 @@ private:
class KWIN_EXPORT Application : public QApplication class KWIN_EXPORT Application : public QApplication
{ {
Q_OBJECT Q_OBJECT
#if KWIN_BUILD_X11
Q_PROPERTY(quint32 x11Time READ x11Time WRITE setX11Time) Q_PROPERTY(quint32 x11Time READ x11Time WRITE setX11Time)
Q_PROPERTY(quint32 x11RootWindow READ x11RootWindow CONSTANT) Q_PROPERTY(quint32 x11RootWindow READ x11RootWindow CONSTANT)
Q_PROPERTY(void *x11Connection READ x11Connection NOTIFY x11ConnectionChanged) Q_PROPERTY(void *x11Connection READ x11Connection NOTIFY x11ConnectionChanged)
#endif
Q_PROPERTY(KSharedConfigPtr config READ config WRITE setConfig) Q_PROPERTY(KSharedConfigPtr config READ config WRITE setConfig)
Q_PROPERTY(KSharedConfigPtr kxkbConfig READ kxkbConfig WRITE setKxkbConfig) Q_PROPERTY(KSharedConfigPtr kxkbConfig READ kxkbConfig WRITE setKxkbConfig)
public: public:
@ -140,6 +144,7 @@ public:
void setupCommandLine(QCommandLineParser *parser); void setupCommandLine(QCommandLineParser *parser);
void processCommandLine(QCommandLineParser *parser); void processCommandLine(QCommandLineParser *parser);
#if KWIN_BUILD_X11
void registerEventFilter(X11EventFilter *filter); void registerEventFilter(X11EventFilter *filter);
void unregisterEventFilter(X11EventFilter *filter); void unregisterEventFilter(X11EventFilter *filter);
bool dispatchEvent(xcb_generic_event_t *event); bool dispatchEvent(xcb_generic_event_t *event);
@ -163,6 +168,7 @@ public:
*/ */
void updateXTime(); void updateXTime();
void updateX11Time(xcb_generic_event_t *event); void updateX11Time(xcb_generic_event_t *event);
#endif
static void setCrashCount(int count); static void setCrashCount(int count);
static bool wasCrash(); static bool wasCrash();
@ -174,6 +180,7 @@ public:
*/ */
static void createAboutData(); static void createAboutData();
#if KWIN_BUILD_X11
/** /**
* @returns the X11 root window. * @returns the X11 root window.
*/ */
@ -197,7 +204,6 @@ public:
{ {
return m_connection; return m_connection;
} }
/** /**
* Inheriting classes should use this method to set the X11 root window * Inheriting classes should use this method to set the X11 root window
* before accessing any X11 specific code pathes. * before accessing any X11 specific code pathes.
@ -218,6 +224,7 @@ public:
{ {
m_compositeWindow = window; m_compositeWindow = window;
} }
#endif
qreal xwaylandScale() const qreal xwaylandScale() const
{ {
@ -372,19 +379,23 @@ protected:
static int crashes; static int crashes;
private: private:
#if KWIN_BUILD_X11
QList<QPointer<X11EventFilterContainer>> m_eventFilters; QList<QPointer<X11EventFilterContainer>> m_eventFilters;
QList<QPointer<X11EventFilterContainer>> m_genericEventFilters; QList<QPointer<X11EventFilterContainer>> m_genericEventFilters;
std::unique_ptr<XcbEventFilter> m_eventFilter; std::unique_ptr<XcbEventFilter> m_eventFilter;
#endif
bool m_followLocale1 = false; bool m_followLocale1 = false;
bool m_configLock; bool m_configLock;
KSharedConfigPtr m_config; KSharedConfigPtr m_config;
KSharedConfigPtr m_kxkbConfig; KSharedConfigPtr m_kxkbConfig;
KSharedConfigPtr m_inputConfig; KSharedConfigPtr m_inputConfig;
OperationMode m_operationMode; OperationMode m_operationMode;
#if KWIN_BUILD_X11
xcb_timestamp_t m_x11Time = XCB_TIME_CURRENT_TIME; xcb_timestamp_t m_x11Time = XCB_TIME_CURRENT_TIME;
xcb_window_t m_rootWindow = XCB_WINDOW_NONE; xcb_window_t m_rootWindow = XCB_WINDOW_NONE;
xcb_window_t m_compositeWindow = XCB_WINDOW_NONE; xcb_window_t m_compositeWindow = XCB_WINDOW_NONE;
xcb_connection_t *m_connection = nullptr; xcb_connection_t *m_connection = nullptr;
#endif
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
bool m_useKActivities = true; bool m_useKActivities = true;
#endif #endif

View file

@ -25,8 +25,11 @@
#include "wayland/seat.h" #include "wayland/seat.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "xwayland/xwayland.h" #include "xwayland/xwayland.h"
#include "xwayland/xwaylandlauncher.h" #include "xwayland/xwaylandlauncher.h"
#endif
// KDE // KDE
#include <KCrash> #include <KCrash>
@ -121,7 +124,9 @@ ApplicationWayland::~ApplicationWayland()
if (effects) { if (effects) {
effects->unloadAllEffects(); effects->unloadAllEffects();
} }
#if KWIN_BUILD_X11
m_xwayland.reset(); m_xwayland.reset();
#endif
destroyColorManager(); destroyColorManager();
destroyWorkspace(); destroyWorkspace();
@ -132,10 +137,12 @@ ApplicationWayland::~ApplicationWayland()
void ApplicationWayland::performStartup() void ApplicationWayland::performStartup()
{ {
#if KWIN_BUILD_X11
if (m_startXWayland) { if (m_startXWayland) {
setOperationMode(OperationModeXwayland); setOperationMode(OperationModeXwayland);
setXwaylandScale(config()->group(QStringLiteral("Xwayland")).readEntry("Scale", 1.0)); setXwaylandScale(config()->group(QStringLiteral("Xwayland")).readEntry("Scale", 1.0));
} }
#endif
createOptions(); createOptions();
if (!outputBackend()->initialize()) { if (!outputBackend()->initialize()) {
@ -162,6 +169,7 @@ void ApplicationWayland::continueStartupWithScene()
qFatal("Failed to initialze the Wayland server, exiting now"); qFatal("Failed to initialze the Wayland server, exiting now");
} }
#if KWIN_BUILD_X11
if (operationMode() == OperationModeXwayland) { if (operationMode() == OperationModeXwayland) {
m_xwayland = std::make_unique<Xwl::Xwayland>(this); m_xwayland = std::make_unique<Xwl::Xwayland>(this);
m_xwayland->xwaylandLauncher()->setListenFDs(m_xwaylandListenFds); m_xwayland->xwaylandLauncher()->setListenFDs(m_xwaylandListenFds);
@ -170,6 +178,7 @@ void ApplicationWayland::continueStartupWithScene()
m_xwayland->init(); m_xwayland->init();
connect(m_xwayland.get(), &Xwl::Xwayland::started, this, &ApplicationWayland::applyXwaylandScale); connect(m_xwayland.get(), &Xwl::Xwayland::started, this, &ApplicationWayland::applyXwaylandScale);
} }
#endif
startSession(); startSession();
notifyStarted(); notifyStarted();
} }
@ -247,10 +256,12 @@ void ApplicationWayland::startSession()
} }
} }
#if KWIN_BUILD_X11
XwaylandInterface *ApplicationWayland::xwayland() const XwaylandInterface *ApplicationWayland::xwayland() const
{ {
return m_xwayland.get(); return m_xwayland.get();
} }
#endif
} // namespace } // namespace
@ -287,14 +298,18 @@ int main(int argc, char *argv[])
KWin::Application::createAboutData(); KWin::Application::createAboutData();
#if KWIN_BUILD_X11
QCommandLineOption xwaylandOption(QStringLiteral("xwayland"), QCommandLineOption xwaylandOption(QStringLiteral("xwayland"),
i18n("Start a rootless Xwayland server.")); i18n("Start a rootless Xwayland server."));
#endif
QCommandLineOption waylandSocketOption(QStringList{QStringLiteral("s"), QStringLiteral("socket")}, QCommandLineOption waylandSocketOption(QStringList{QStringLiteral("s"), QStringLiteral("socket")},
i18n("Name of the Wayland socket to listen on. If not set \"wayland-0\" is used."), i18n("Name of the Wayland socket to listen on. If not set \"wayland-0\" is used."),
QStringLiteral("socket")); QStringLiteral("socket"));
#if KWIN_BUILD_X11
QCommandLineOption x11DisplayOption(QStringLiteral("x11-display"), QCommandLineOption x11DisplayOption(QStringLiteral("x11-display"),
i18n("The X11 Display to use in windowed mode on platform X11."), i18n("The X11 Display to use in windowed mode on platform X11."),
QStringLiteral("display")); QStringLiteral("display"));
#endif
QCommandLineOption waylandDisplayOption(QStringLiteral("wayland-display"), QCommandLineOption waylandDisplayOption(QStringLiteral("wayland-display"),
i18n("The Wayland Display to use in windowed mode on platform Wayland."), i18n("The Wayland Display to use in windowed mode on platform Wayland."),
QStringLiteral("display")); QStringLiteral("display"));
@ -342,14 +357,18 @@ int main(int argc, char *argv[])
QCommandLineParser parser; QCommandLineParser parser;
a.setupCommandLine(&parser); a.setupCommandLine(&parser);
#if KWIN_BUILD_X11
parser.addOption(xwaylandOption); parser.addOption(xwaylandOption);
#endif
parser.addOption(waylandSocketOption); parser.addOption(waylandSocketOption);
parser.addOption(waylandSocketFdOption); parser.addOption(waylandSocketFdOption);
parser.addOption(xwaylandListenFdOption); parser.addOption(xwaylandListenFdOption);
parser.addOption(xwaylandDisplayOption); parser.addOption(xwaylandDisplayOption);
parser.addOption(xwaylandXAuthorityOption); parser.addOption(xwaylandXAuthorityOption);
parser.addOption(replaceOption); parser.addOption(replaceOption);
#if KWIN_BUILD_X11
parser.addOption(x11DisplayOption); parser.addOption(x11DisplayOption);
#endif
parser.addOption(waylandDisplayOption); parser.addOption(waylandDisplayOption);
parser.addOption(virtualFbOption); parser.addOption(virtualFbOption);
parser.addOption(widthOption); parser.addOption(widthOption);
@ -429,8 +448,10 @@ int main(int argc, char *argv[])
// Decide what backend to use. // Decide what backend to use.
if (parser.isSet(drmOption)) { if (parser.isSet(drmOption)) {
backendType = BackendType::Kms; backendType = BackendType::Kms;
#if KWIN_BUILD_X11
} else if (parser.isSet(x11DisplayOption)) { } else if (parser.isSet(x11DisplayOption)) {
backendType = BackendType::X11; backendType = BackendType::X11;
#endif
} else if (parser.isSet(waylandDisplayOption)) { } else if (parser.isSet(waylandDisplayOption)) {
backendType = BackendType::Wayland; backendType = BackendType::Wayland;
} else if (parser.isSet(virtualFbOption)) { } else if (parser.isSet(virtualFbOption)) {
@ -539,6 +560,7 @@ int main(int argc, char *argv[])
a.setOutputBackend(std::move(outputBackend)); a.setOutputBackend(std::move(outputBackend));
break; break;
} }
#if KWIN_BUILD_X11
case BackendType::X11: { case BackendType::X11: {
QString display = parser.value(x11DisplayOption); QString display = parser.value(x11DisplayOption);
if (display.isEmpty()) { if (display.isEmpty()) {
@ -553,6 +575,7 @@ int main(int argc, char *argv[])
})); }));
break; break;
} }
#endif
case BackendType::Wayland: { case BackendType::Wayland: {
QString socketName = parser.value(waylandDisplayOption); QString socketName = parser.value(waylandDisplayOption);
if (socketName.isEmpty()) { if (socketName.isEmpty()) {
@ -576,6 +599,7 @@ int main(int argc, char *argv[])
} }
a.setProcessStartupEnvironment(environment); a.setProcessStartupEnvironment(environment);
#if KWIN_BUILD_X11
if (parser.isSet(xwaylandOption)) { if (parser.isSet(xwaylandOption)) {
a.setStartXwayland(true); a.setStartXwayland(true);
@ -601,6 +625,7 @@ int main(int argc, char *argv[])
} }
} }
} }
#endif
a.setApplicationsToStart(parser.positionalArguments()); a.setApplicationsToStart(parser.positionalArguments());
a.setInputMethodServerToStart(parser.value(inputMethodOption)); a.setInputMethodServerToStart(parser.value(inputMethodOption));

View file

@ -25,6 +25,7 @@ public:
ApplicationWayland(int &argc, char **argv); ApplicationWayland(int &argc, char **argv);
~ApplicationWayland() override; ~ApplicationWayland() override;
#if KWIN_BUILD_X11
void setStartXwayland(bool start) void setStartXwayland(bool start)
{ {
m_startXWayland = start; m_startXWayland = start;
@ -41,6 +42,8 @@ public:
{ {
m_xwaylandXauthority = xauthority; m_xwaylandXauthority = xauthority;
} }
XwaylandInterface *xwayland() const override;
#endif
void setApplicationsToStart(const QStringList &applications) void setApplicationsToStart(const QStringList &applications)
{ {
m_applicationsToStart = applications; m_applicationsToStart = applications;
@ -54,8 +57,6 @@ public:
m_sessionArgument = session; m_sessionArgument = session;
} }
XwaylandInterface *xwayland() const override;
protected: protected:
void performStartup() override; void performStartup() override;
@ -64,15 +65,17 @@ private:
void startSession(); void startSession();
void refreshSettings(const KConfigGroup &group, const QByteArrayList &names); void refreshSettings(const KConfigGroup &group, const QByteArrayList &names);
bool m_startXWayland = false;
QStringList m_applicationsToStart; QStringList m_applicationsToStart;
QString m_inputMethodServerToStart; QString m_inputMethodServerToStart;
QString m_sessionArgument; QString m_sessionArgument;
#if KWIN_BUILD_X11
bool m_startXWayland = false;
std::unique_ptr<Xwl::Xwayland> m_xwayland; std::unique_ptr<Xwl::Xwayland> m_xwayland;
QList<int> m_xwaylandListenFds; QList<int> m_xwaylandListenFds;
QString m_xwaylandDisplay; QString m_xwaylandDisplay;
QString m_xwaylandXauthority; QString m_xwaylandXauthority;
#endif
KConfigWatcher::Ptr m_settingsWatcher; KConfigWatcher::Ptr m_settingsWatcher;
}; };

View file

@ -11,6 +11,12 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include <NETWM> #include <NETWM>
#include <memory> #include <memory>

View file

@ -10,10 +10,13 @@
#include "opengl/glplatform.h" #include "opengl/glplatform.h"
// include kwinglutils_funcs.h to avoid the redeclaration issues // include kwinglutils_funcs.h to avoid the redeclaration issues
// between qopengl.h and epoxy/gl.h // between qopengl.h and epoxy/gl.h
#include "effect/xcb.h"
#include "opengl/glutils_funcs.h" #include "opengl/glutils_funcs.h"
#include <epoxy/gl.h> #include <epoxy/gl.h>
#if KWIN_BUILD_X11
#include "effect/xcb.h"
#endif
#include <QDebug> #include <QDebug>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QRegularExpression> #include <QRegularExpression>

View file

@ -18,9 +18,12 @@
#include "rules.h" #include "rules.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif #endif
#endif
#include "window.h"
#include <QTextStream> #include <QTextStream>
#include <QTimer> #include <QTimer>

View file

@ -13,11 +13,14 @@
#include "core/rendertarget.h" #include "core/rendertarget.h"
#include "core/renderviewport.h" #include "core/renderviewport.h"
#include "effect/effecthandler.h" #include "effect/effecthandler.h"
#include "utils/xcbutils.h"
#include "wayland/contrast.h" #include "wayland/contrast.h"
#include "wayland/display.h" #include "wayland/display.h"
#include "wayland/surface.h" #include "wayland/surface.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h"
#endif
#include <QCoreApplication> #include <QCoreApplication>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QTimer> #include <QTimer>
@ -40,9 +43,11 @@ ContrastEffect::ContrastEffect()
// ### Hackish way to announce support. // ### Hackish way to announce support.
// Should be included in _NET_SUPPORTED instead. // Should be included in _NET_SUPPORTED instead.
if (m_shader && m_shader->isValid()) { if (m_shader && m_shader->isValid()) {
#if KWIN_BUILD_X11
if (effects->xcbConnection()) { if (effects->xcbConnection()) {
m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this); m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this);
} }
#endif
if (effects->waylandDisplay()) { if (effects->waylandDisplay()) {
if (!s_contrastManagerRemoveTimer) { if (!s_contrastManagerRemoveTimer) {
s_contrastManagerRemoveTimer = new QTimer(QCoreApplication::instance()); s_contrastManagerRemoveTimer = new QTimer(QCoreApplication::instance());
@ -61,13 +66,16 @@ ContrastEffect::ContrastEffect()
connect(effects, &EffectsHandler::windowAdded, this, &ContrastEffect::slotWindowAdded); connect(effects, &EffectsHandler::windowAdded, this, &ContrastEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowDeleted, this, &ContrastEffect::slotWindowDeleted); connect(effects, &EffectsHandler::windowDeleted, this, &ContrastEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::propertyNotify, this, &ContrastEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::virtualScreenGeometryChanged, this, &ContrastEffect::slotScreenGeometryChanged); connect(effects, &EffectsHandler::virtualScreenGeometryChanged, this, &ContrastEffect::slotScreenGeometryChanged);
#if KWIN_BUILD_X11
connect(effects, &EffectsHandler::propertyNotify, this, &ContrastEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
if (m_shader && m_shader->isValid()) { if (m_shader && m_shader->isValid()) {
m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this); m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this);
} }
}); });
#endif
// Fetch the contrast regions for all windows // Fetch the contrast regions for all windows
const QList<EffectWindow *> windowList = effects->stackingOrder(); const QList<EffectWindow *> windowList = effects->stackingOrder();
@ -102,10 +110,11 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w)
{ {
QRegion region; QRegion region;
QMatrix4x4 matrix; QMatrix4x4 matrix;
float colorTransform[16];
bool valid = false; bool valid = false;
#if KWIN_BUILD_X11
if (m_net_wm_contrast_region != XCB_ATOM_NONE) { if (m_net_wm_contrast_region != XCB_ATOM_NONE) {
float colorTransform[16];
const QByteArray value = w->readProperty(m_net_wm_contrast_region, m_net_wm_contrast_region, 32); const QByteArray value = w->readProperty(m_net_wm_contrast_region, m_net_wm_contrast_region, 32);
if (value.size() > 0 && !((value.size() - (16 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) { if (value.size() > 0 && !((value.size() - (16 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) {
@ -129,6 +138,7 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w)
valid = !value.isNull(); valid = !value.isNull();
} }
#endif
SurfaceInterface *surf = w->surface(); SurfaceInterface *surf = w->surface();
@ -217,12 +227,14 @@ void ContrastEffect::slotWindowDeleted(EffectWindow *w)
} }
} }
#if KWIN_BUILD_X11
void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom) void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom)
{ {
if (w && atom == m_net_wm_contrast_region && m_net_wm_contrast_region != XCB_ATOM_NONE) { if (w && atom == m_net_wm_contrast_region && m_net_wm_contrast_region != XCB_ATOM_NONE) {
updateContrastRegion(w); updateContrastRegion(w);
} }
} }
#endif
QMatrix4x4 ContrastEffect::colorMatrix(qreal contrast, qreal intensity, qreal saturation) QMatrix4x4 ContrastEffect::colorMatrix(qreal contrast, qreal intensity, qreal saturation)
{ {

View file

@ -49,7 +49,9 @@ public:
public Q_SLOTS: public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w); void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowDeleted(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w);
#if KWIN_BUILD_X11
void slotPropertyNotify(KWin::EffectWindow *w, long atom); void slotPropertyNotify(KWin::EffectWindow *w, long atom);
#endif
void slotScreenGeometryChanged(); void slotScreenGeometryChanged();
private: private:
@ -62,7 +64,10 @@ private:
private: private:
std::unique_ptr<ContrastShader> m_shader; std::unique_ptr<ContrastShader> m_shader;
#if KWIN_BUILD_X11
long m_net_wm_contrast_region = 0; long m_net_wm_contrast_region = 0;
#endif
QHash<const EffectWindow *, QMetaObject::Connection> m_contrastChangedConnections; // used only in Wayland to keep track of effect changed QHash<const EffectWindow *, QMetaObject::Connection> m_contrastChangedConnections; // used only in Wayland to keep track of effect changed
struct Data struct Data
{ {

View file

@ -15,11 +15,14 @@
#include "core/renderviewport.h" #include "core/renderviewport.h"
#include "effect/effecthandler.h" #include "effect/effecthandler.h"
#include "opengl/glplatform.h" #include "opengl/glplatform.h"
#include "utils/xcbutils.h"
#include "wayland/blur.h" #include "wayland/blur.h"
#include "wayland/display.h" #include "wayland/display.h"
#include "wayland/surface.h" #include "wayland/surface.h"
#if KWIN_BUILD_X11
#include "utils/xcbutils.h"
#endif
#include <QGuiApplication> #include <QGuiApplication>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QScreen> #include <QScreen>
@ -94,9 +97,11 @@ BlurEffect::BlurEffect()
initBlurStrengthValues(); initBlurStrengthValues();
reconfigure(ReconfigureAll); reconfigure(ReconfigureAll);
#if KWIN_BUILD_X11
if (effects->xcbConnection()) { if (effects->xcbConnection()) {
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
} }
#endif
if (effects->waylandDisplay()) { if (effects->waylandDisplay()) {
if (!s_blurManagerRemoveTimer) { if (!s_blurManagerRemoveTimer) {
@ -116,10 +121,12 @@ BlurEffect::BlurEffect()
connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded); connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowDeleted, this, &BlurEffect::slotWindowDeleted); connect(effects, &EffectsHandler::windowDeleted, this, &BlurEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::screenRemoved, this, &BlurEffect::slotScreenRemoved); connect(effects, &EffectsHandler::screenRemoved, this, &BlurEffect::slotScreenRemoved);
#if KWIN_BUILD_X11
connect(effects, &EffectsHandler::propertyNotify, this, &BlurEffect::slotPropertyNotify); connect(effects, &EffectsHandler::propertyNotify, this, &BlurEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
}); });
#endif
// Fetch the blur regions for all windows // Fetch the blur regions for all windows
const auto stackingOrder = effects->stackingOrder(); const auto stackingOrder = effects->stackingOrder();
@ -215,6 +222,7 @@ void BlurEffect::updateBlurRegion(EffectWindow *w)
std::optional<QRegion> content; std::optional<QRegion> content;
std::optional<QRegion> frame; std::optional<QRegion> frame;
#if KWIN_BUILD_X11
if (net_wm_blur_region != XCB_ATOM_NONE) { if (net_wm_blur_region != XCB_ATOM_NONE) {
const QByteArray value = w->readProperty(net_wm_blur_region, XCB_ATOM_CARDINAL, 32); const QByteArray value = w->readProperty(net_wm_blur_region, XCB_ATOM_CARDINAL, 32);
QRegion region; QRegion region;
@ -232,6 +240,7 @@ void BlurEffect::updateBlurRegion(EffectWindow *w)
content = region; content = region;
} }
} }
#endif
SurfaceInterface *surf = w->surface(); SurfaceInterface *surf = w->surface();
@ -305,12 +314,14 @@ void BlurEffect::slotScreenRemoved(KWin::Output *screen)
} }
} }
#if KWIN_BUILD_X11
void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom) void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom)
{ {
if (w && atom == net_wm_blur_region && net_wm_blur_region != XCB_ATOM_NONE) { if (w && atom == net_wm_blur_region && net_wm_blur_region != XCB_ATOM_NONE) {
updateBlurRegion(w); updateBlurRegion(w);
} }
} }
#endif
void BlurEffect::setupDecorationConnections(EffectWindow *w) void BlurEffect::setupDecorationConnections(EffectWindow *w)
{ {

View file

@ -71,7 +71,9 @@ public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w); void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowDeleted(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w);
void slotScreenRemoved(KWin::Output *screen); void slotScreenRemoved(KWin::Output *screen);
#if KWIN_BUILD_X11
void slotPropertyNotify(KWin::EffectWindow *w, long atom); void slotPropertyNotify(KWin::EffectWindow *w, long atom);
#endif
void setupDecorationConnections(EffectWindow *w); void setupDecorationConnections(EffectWindow *w);
private: private:
@ -114,7 +116,9 @@ private:
} m_noisePass; } m_noisePass;
bool m_valid = false; bool m_valid = false;
#if KWIN_BUILD_X11
long net_wm_blur_region = 0; long net_wm_blur_region = 0;
#endif
QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top) QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top)
QRegion m_currentBlur; // keeps track of the currently blured area of the windows(from bottom to top) QRegion m_currentBlur; // keeps track of the currently blured area of the windows(from bottom to top)
Output *m_currentScreen = nullptr; Output *m_currentScreen = nullptr;

View file

@ -14,4 +14,4 @@ target_sources(buttonsrebind PRIVATE
main.cpp main.cpp
buttonrebindsfilter.cpp buttonrebindsfilter.cpp
) )
target_link_libraries(buttonsrebind PRIVATE kwin KF6::WindowSystem XKB::XKB) target_link_libraries(buttonsrebind PRIVATE kwin Qt::GuiPrivate XKB::XKB)

View file

@ -13,8 +13,6 @@
#include "keyboard_input.h" #include "keyboard_input.h"
#include "xkb.h" #include "xkb.h"
#include <KKeyServer>
#include <QMetaEnum> #include <QMetaEnum>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
@ -23,6 +21,8 @@
#include <optional> #include <optional>
#include <utility> #include <utility>
#include <private/qxkbcommon_p.h>
// Tells us that we are already in a binding event // Tells us that we are already in a binding event
class RebindScope class RebindScope
{ {
@ -300,7 +300,8 @@ bool ButtonRebindsFilter::sendKeySequence(const QKeySequence &keys, bool pressed
} }
} }
const QList<int> syms(KKeyServer::keyQtToSymXs(keys[0])); QKeyEvent ev(QEvent::KeyPress, keys[0], Qt::NoModifier);
const QList<xkb_keysym_t> syms(QXkbCommon::toKeysym(&ev));
if (syms.empty()) { if (syms.empty()) {
qCWarning(KWIN_BUTTONREBINDS) << "Could not convert" << keys << "to keysym"; qCWarning(KWIN_BUTTONREBINDS) << "Could not convert" << keys << "to keysym";
return false; return false;

View file

@ -23,17 +23,19 @@ HighlightWindowEffect::HighlightWindowEffect()
, m_fadeDuration(animationTime(150)) , m_fadeDuration(animationTime(150))
, m_monitorWindow(nullptr) , m_monitorWindow(nullptr)
{ {
#if KWIN_BUILD_X11
// TODO KF6 remove atom support // TODO KF6 remove atom support
m_atom = effects->announceSupportProperty("_KDE_WINDOW_HIGHLIGHT", this); m_atom = effects->announceSupportProperty("_KDE_WINDOW_HIGHLIGHT", this);
connect(effects, &EffectsHandler::windowAdded, this, &HighlightWindowEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &HighlightWindowEffect::slotWindowClosed);
connect(effects, &EffectsHandler::windowDeleted, this, &HighlightWindowEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::propertyNotify, this, [this](EffectWindow *w, long atom) {
slotPropertyNotify(w, atom, nullptr);
});
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
m_atom = effects->announceSupportProperty("_KDE_WINDOW_HIGHLIGHT", this); m_atom = effects->announceSupportProperty("_KDE_WINDOW_HIGHLIGHT", this);
}); });
connect(effects, &EffectsHandler::propertyNotify, this, [this](EffectWindow *w, long atom) {
slotPropertyNotify(w, atom, nullptr);
});
#endif
connect(effects, &EffectsHandler::windowAdded, this, &HighlightWindowEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &HighlightWindowEffect::slotWindowClosed);
connect(effects, &EffectsHandler::windowDeleted, this, &HighlightWindowEffect::slotWindowDeleted);
QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/HighlightWindow"), QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/HighlightWindow"),
QStringLiteral("org.kde.KWin.HighlightWindow"), QStringLiteral("org.kde.KWin.HighlightWindow"),
@ -93,7 +95,9 @@ void HighlightWindowEffect::slotWindowAdded(EffectWindow *w)
complete(animationId); complete(animationId);
} }
} }
#if KWIN_BUILD_X11
slotPropertyNotify(w, m_atom, w); // Check initial value slotPropertyNotify(w, m_atom, w); // Check initial value
#endif
} }
void HighlightWindowEffect::slotWindowClosed(EffectWindow *w) void HighlightWindowEffect::slotWindowClosed(EffectWindow *w)
@ -108,6 +112,7 @@ void HighlightWindowEffect::slotWindowDeleted(EffectWindow *w)
m_animations.remove(w); m_animations.remove(w);
} }
#if KWIN_BUILD_X11
void HighlightWindowEffect::slotPropertyNotify(EffectWindow *w, long a, EffectWindow *addedWindow) void HighlightWindowEffect::slotPropertyNotify(EffectWindow *w, long a, EffectWindow *addedWindow)
{ {
if (a != m_atom || m_atom == XCB_ATOM_NONE) { if (a != m_atom || m_atom == XCB_ATOM_NONE) {
@ -156,6 +161,7 @@ void HighlightWindowEffect::slotPropertyNotify(EffectWindow *w, long a, EffectWi
} }
prepareHighlighting(); prepareHighlighting();
} }
#endif
void HighlightWindowEffect::prepareHighlighting() void HighlightWindowEffect::prepareHighlighting()
{ {

View file

@ -9,6 +9,8 @@
#pragma once #pragma once
#include "config-kwin.h"
#include "effect/animationeffect.h" #include "effect/animationeffect.h"
namespace KWin namespace KWin
@ -35,7 +37,9 @@ public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w); void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowClosed(KWin::EffectWindow *w); void slotWindowClosed(KWin::EffectWindow *w);
void slotWindowDeleted(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w);
#if KWIN_BUILD_X11
void slotPropertyNotify(KWin::EffectWindow *w, long atom, EffectWindow *addedWindow = nullptr); void slotPropertyNotify(KWin::EffectWindow *w, long atom, EffectWindow *addedWindow = nullptr);
#endif
private: private:
quint64 startGhostAnimation(EffectWindow *window); quint64 startGhostAnimation(EffectWindow *window);
@ -48,7 +52,9 @@ private:
void finishHighlighting(); void finishHighlighting();
void highlightWindows(const QList<KWin::EffectWindow *> &windows); void highlightWindows(const QList<KWin::EffectWindow *> &windows);
#if KWIN_BUILD_X11
long m_atom; long m_atom;
#endif
QList<EffectWindow *> m_highlightedWindows; QList<EffectWindow *> m_highlightedWindows;
QHash<EffectWindow *, quint64> m_animations; QHash<EffectWindow *, quint64> m_animations;
QEasingCurve m_easingCurve; QEasingCurve m_easingCurve;

View file

@ -46,15 +46,19 @@ namespace KWin
KscreenEffect::KscreenEffect() KscreenEffect::KscreenEffect()
: Effect() : Effect()
#if KWIN_BUILD_X11
, m_atom(effects->waylandDisplay() ? XCB_ATOM_NONE : effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this)) , m_atom(effects->waylandDisplay() ? XCB_ATOM_NONE : effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this))
#endif
{ {
KscreenConfig::instance(effects->config()); KscreenConfig::instance(effects->config());
#if KWIN_BUILD_X11
if (!effects->waylandDisplay()) { if (!effects->waylandDisplay()) {
connect(effects, &EffectsHandler::propertyNotify, this, &KscreenEffect::propertyNotify); connect(effects, &EffectsHandler::propertyNotify, this, &KscreenEffect::propertyNotify);
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_KWIN_KSCREEN_SUPPORT"), this); m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_KWIN_KSCREEN_SUPPORT"), this);
}); });
} }
#endif
reconfigure(ReconfigureAll); reconfigure(ReconfigureAll);
const QList<Output *> screens = effects->screens(); const QList<Output *> screens = effects->screens();
@ -173,6 +177,7 @@ void KscreenEffect::setState(ScreenState &state, FadeOutState newState)
effects->addRepaintFull(); effects->addRepaintFull();
} }
#if KWIN_BUILD_X11
void KscreenEffect::propertyNotify(EffectWindow *window, long int atom) void KscreenEffect::propertyNotify(EffectWindow *window, long int atom)
{ {
if (window || atom != m_atom || m_atom == XCB_ATOM_NONE) { if (window || atom != m_atom || m_atom == XCB_ATOM_NONE) {
@ -191,6 +196,7 @@ void KscreenEffect::propertyNotify(EffectWindow *window, long int atom)
setState(m_xcbState, FadeOutState(data[0])); setState(m_xcbState, FadeOutState(data[0]));
} }
#endif
void KscreenEffect::switchState(ScreenState &state) void KscreenEffect::switchState(ScreenState &state)
{ {
@ -202,19 +208,29 @@ void KscreenEffect::switchState(ScreenState &state)
state.m_state = StateNormal; state.m_state = StateNormal;
value = 0l; value = 0l;
} }
#if KWIN_BUILD_X11
if (value != -1l && m_atom != XCB_ATOM_NONE) { if (value != -1l && m_atom != XCB_ATOM_NONE) {
xcb_change_property(effects->xcbConnection(), XCB_PROP_MODE_REPLACE, effects->x11RootWindow(), m_atom, XCB_ATOM_CARDINAL, 32, 1, &value); xcb_change_property(effects->xcbConnection(), XCB_PROP_MODE_REPLACE, effects->x11RootWindow(), m_atom, XCB_ATOM_CARDINAL, 32, 1, &value);
} }
#endif
} }
bool KscreenEffect::isActive() const bool KscreenEffect::isActive() const
{ {
return !m_waylandStates.isEmpty() || (!effects->waylandDisplay() && m_atom && m_xcbState.m_state != StateNormal); return !m_waylandStates.isEmpty()
#if KWIN_BUILD_X11
|| (!effects->waylandDisplay() && m_atom && m_xcbState.m_state != StateNormal)
#endif
;
} }
bool KscreenEffect::isScreenActive(Output *screen) const bool KscreenEffect::isScreenActive(Output *screen) const
{ {
return m_waylandStates.contains(screen) || (!effects->waylandDisplay() && m_atom && m_xcbState.m_state != StateNormal); return m_waylandStates.contains(screen)
#if KWIN_BUILD_X11
|| (!effects->waylandDisplay() && m_atom && m_xcbState.m_state != StateNormal)
#endif
;
} }
} // namespace KWin } // namespace KWin

View file

@ -37,8 +37,10 @@ public:
return 99; return 99;
} }
#if KWIN_BUILD_X11
private Q_SLOTS: private Q_SLOTS:
void propertyNotify(KWin::EffectWindow *window, long atom); void propertyNotify(KWin::EffectWindow *window, long atom);
#endif
private: private:
enum FadeOutState { enum FadeOutState {
@ -62,7 +64,9 @@ private:
QHash<Output *, ScreenState> m_waylandStates; QHash<Output *, ScreenState> m_waylandStates;
ScreenState m_xcbState; ScreenState m_xcbState;
Output *m_currentScreen = nullptr; Output *m_currentScreen = nullptr;
#if KWIN_BUILD_X11
xcb_atom_t m_atom; xcb_atom_t m_atom;
#endif
}; };
} // namespace KWin } // namespace KWin

View file

@ -53,14 +53,16 @@ SlidingPopupsEffect::SlidingPopupsEffect()
m_slideLength = QFontMetrics(QGuiApplication::font()).height() * 8; m_slideLength = QFontMetrics(QGuiApplication::font()).height() * 8;
#if KWIN_BUILD_X11
m_atom = effects->announceSupportProperty("_KDE_SLIDE", this); m_atom = effects->announceSupportProperty("_KDE_SLIDE", this);
connect(effects, &EffectsHandler::windowAdded, this, &SlidingPopupsEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &SlidingPopupsEffect::slotWindowClosed);
connect(effects, &EffectsHandler::windowDeleted, this, &SlidingPopupsEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::propertyNotify, this, &SlidingPopupsEffect::slotPropertyNotify);
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_SLIDE"), this); m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_SLIDE"), this);
}); });
connect(effects, &EffectsHandler::propertyNotify, this, &SlidingPopupsEffect::slotPropertyNotify);
#endif
connect(effects, &EffectsHandler::windowAdded, this, &SlidingPopupsEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &SlidingPopupsEffect::slotWindowClosed);
connect(effects, &EffectsHandler::windowDeleted, this, &SlidingPopupsEffect::slotWindowDeleted);
connect(effects, &EffectsHandler::desktopChanged, connect(effects, &EffectsHandler::desktopChanged,
this, &SlidingPopupsEffect::stopAnimations); this, &SlidingPopupsEffect::stopAnimations);
connect(effects, &EffectsHandler::activeFullScreenEffectChanged, connect(effects, &EffectsHandler::activeFullScreenEffectChanged,
@ -209,10 +211,12 @@ void SlidingPopupsEffect::setupSlideData(EffectWindow *w)
connect(w, &EffectWindow::windowFrameGeometryChanged, this, &SlidingPopupsEffect::slotWindowFrameGeometryChanged); connect(w, &EffectWindow::windowFrameGeometryChanged, this, &SlidingPopupsEffect::slotWindowFrameGeometryChanged);
connect(w, &EffectWindow::windowHiddenChanged, this, &SlidingPopupsEffect::slotWindowHiddenChanged); connect(w, &EffectWindow::windowHiddenChanged, this, &SlidingPopupsEffect::slotWindowHiddenChanged);
#if KWIN_BUILD_X11
// X11 // X11
if (m_atom != XCB_ATOM_NONE) { if (m_atom != XCB_ATOM_NONE) {
slotPropertyNotify(w, m_atom); slotPropertyNotify(w, m_atom);
} }
#endif
// Wayland // Wayland
if (auto surf = w->surface()) { if (auto surf = w->surface()) {
@ -257,6 +261,7 @@ void SlidingPopupsEffect::slotWindowHiddenChanged(EffectWindow *w)
} }
} }
#if KWIN_BUILD_X11
void SlidingPopupsEffect::slotPropertyNotify(EffectWindow *w, long atom) void SlidingPopupsEffect::slotPropertyNotify(EffectWindow *w, long atom)
{ {
if (!w || atom != m_atom || m_atom == XCB_ATOM_NONE) { if (!w || atom != m_atom || m_atom == XCB_ATOM_NONE) {
@ -333,6 +338,7 @@ void SlidingPopupsEffect::slotPropertyNotify(EffectWindow *w, long atom)
setupAnimData(w); setupAnimData(w);
} }
#endif
void SlidingPopupsEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const QRectF &) void SlidingPopupsEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const QRectF &)
{ {

View file

@ -11,6 +11,8 @@
#pragma once #pragma once
// Include with base class for effects. // Include with base class for effects.
#include "config-kwin.h"
#include "effect/effect.h" #include "effect/effect.h"
#include "effect/effectwindow.h" #include "effect/effectwindow.h"
#include "effect/timeline.h" #include "effect/timeline.h"
@ -52,7 +54,9 @@ private Q_SLOTS:
void slotWindowAdded(EffectWindow *w); void slotWindowAdded(EffectWindow *w);
void slotWindowClosed(EffectWindow *w); void slotWindowClosed(EffectWindow *w);
void slotWindowDeleted(EffectWindow *w); void slotWindowDeleted(EffectWindow *w);
#if KWIN_BUILD_X11
void slotPropertyNotify(EffectWindow *w, long atom); void slotPropertyNotify(EffectWindow *w, long atom);
#endif
void slotWaylandSlideOnShowChanged(EffectWindow *w); void slotWaylandSlideOnShowChanged(EffectWindow *w);
void slotWindowFrameGeometryChanged(EffectWindow *w, const QRectF &); void slotWindowFrameGeometryChanged(EffectWindow *w, const QRectF &);
void slotWindowHiddenChanged(EffectWindow *w); void slotWindowHiddenChanged(EffectWindow *w);
@ -69,7 +73,9 @@ private:
static SlideManagerInterface *s_slideManager; static SlideManagerInterface *s_slideManager;
static QTimer *s_slideManagerRemoveTimer; static QTimer *s_slideManagerRemoveTimer;
#if KWIN_BUILD_X11
long m_atom = 0; long m_atom = 0;
#endif
int m_slideLength; int m_slideLength;
std::chrono::milliseconds m_slideInDuration; std::chrono::milliseconds m_slideInDuration;

View file

@ -20,7 +20,9 @@
#include <QTimer> #include <QTimer>
// KDE // KDE
#include <KConfigGroup> #include <KConfigGroup>
#if KWIN_BUILD_X11
#include <KSelectionOwner> #include <KSelectionOwner>
#endif
#include <KSharedConfig> #include <KSharedConfig>
#include <KWindowSystem> #include <KWindowSystem>
// KWin // KWin
@ -72,8 +74,10 @@ static const int s_startupDefaultTimeout = 5;
StartupFeedbackEffect::StartupFeedbackEffect() StartupFeedbackEffect::StartupFeedbackEffect()
: m_bounceSizesRatio(1.0) : m_bounceSizesRatio(1.0)
#if KWIN_BUILD_X11
, m_startupInfo(new KStartupInfo(KStartupInfo::CleanOnCantDetect, this)) , m_startupInfo(new KStartupInfo(KStartupInfo::CleanOnCantDetect, this))
, m_selection(nullptr) , m_selection(nullptr)
#endif
, m_active(false) , m_active(false)
, m_frame(0) , m_frame(0)
, m_progress(0) , m_progress(0)
@ -83,6 +87,7 @@ StartupFeedbackEffect::StartupFeedbackEffect()
, m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("klaunchrc", KConfig::NoGlobals))) , m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("klaunchrc", KConfig::NoGlobals)))
, m_splashVisible(false) , m_splashVisible(false)
{ {
#if KWIN_BUILD_X11
// TODO: move somewhere that is x11-specific // TODO: move somewhere that is x11-specific
if (KWindowSystem::isPlatformX11()) { if (KWindowSystem::isPlatformX11()) {
m_selection = new KSelectionOwner("_KDE_STARTUP_FEEDBACK", effects->xcbConnection(), effects->x11RootWindow(), this); m_selection = new KSelectionOwner("_KDE_STARTUP_FEEDBACK", effects->xcbConnection(), effects->x11RootWindow(), this);
@ -99,6 +104,7 @@ StartupFeedbackEffect::StartupFeedbackEffect()
const auto icon = QIcon::fromTheme(data.findIcon(), QIcon::fromTheme(QStringLiteral("system-run"))); const auto icon = QIcon::fromTheme(data.findIcon(), QIcon::fromTheme(QStringLiteral("system-run")));
Q_EMIT effects->startupChanged(id.id(), icon); Q_EMIT effects->startupChanged(id.id(), icon);
}); });
#endif
connect(effects, &EffectsHandler::startupAdded, this, &StartupFeedbackEffect::gotNewStartup); connect(effects, &EffectsHandler::startupAdded, this, &StartupFeedbackEffect::gotNewStartup);
connect(effects, &EffectsHandler::startupRemoved, this, &StartupFeedbackEffect::gotRemoveStartup); connect(effects, &EffectsHandler::startupRemoved, this, &StartupFeedbackEffect::gotRemoveStartup);
@ -141,7 +147,9 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags)
c = m_configWatcher->config()->group(QStringLiteral("BusyCursorSettings")); c = m_configWatcher->config()->group(QStringLiteral("BusyCursorSettings"));
m_timeout = std::chrono::seconds(c.readEntry("Timeout", s_startupDefaultTimeout)); m_timeout = std::chrono::seconds(c.readEntry("Timeout", s_startupDefaultTimeout));
#if KWIN_BUILD_X11
m_startupInfo->setTimeout(m_timeout.count()); m_startupInfo->setTimeout(m_timeout.count());
#endif
const bool busyBlinking = c.readEntry("Blinking", false); const bool busyBlinking = c.readEntry("Blinking", false);
const bool busyBouncing = c.readEntry("Bouncing", true); const bool busyBouncing = c.readEntry("Bouncing", true);
if (!busyCursor) { if (!busyCursor) {

View file

@ -10,7 +10,11 @@
#pragma once #pragma once
#include "effect/effect.h" #include "effect/effect.h"
#include <KConfigWatcher> #include <KConfigWatcher>
#if KWIN_BUILD_X11
#include <KStartupInfo> #include <KStartupInfo>
#endif
#include <QIcon>
#include <QObject> #include <QObject>
#include <chrono> #include <chrono>
@ -77,8 +81,10 @@ private:
QSize feedbackIconSize() const; QSize feedbackIconSize() const;
qreal m_bounceSizesRatio; qreal m_bounceSizesRatio;
#if KWIN_BUILD_X11
KStartupInfo *m_startupInfo; KStartupInfo *m_startupInfo;
KSelectionOwner *m_selection; KSelectionOwner *m_selection;
#endif
QString m_currentStartup; QString m_currentStartup;
QMap<QString, Startup> m_startups; QMap<QString, Startup> m_startups;
bool m_active; bool m_active;

View file

@ -27,14 +27,17 @@
#include "wayland/seat.h" #include "wayland/seat.h"
#include "wayland/surface.h" #include "wayland/surface.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
// KDecoration // KDecoration
#include <KDecoration2/Decoration> #include <KDecoration2/Decoration>
// screenlocker // screenlocker
#if KWIN_BUILD_SCREENLOCKER #if KWIN_BUILD_SCREENLOCKER
#include <KScreenLocker/KsldApp> #include <KScreenLocker/KsldApp>
#endif #endif
#if KWIN_BUILD_X11
#include "x11window.h"
#endif
#include <KLocalizedString> #include <KLocalizedString>

View file

@ -7,6 +7,11 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include "x11eventfilter.h" #include "x11eventfilter.h"

View file

@ -11,7 +11,10 @@
#include "wayland/subcompositor.h" #include "wayland/subcompositor.h"
#include "wayland/surface.h" #include "wayland/surface.h"
#include "window.h" #include "window.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
namespace KWin namespace KWin
{ {
@ -208,6 +211,7 @@ bool SurfacePixmapWayland::isValid() const
return m_bufferRef; return m_bufferRef;
} }
#if KWIN_BUILD_X11
SurfaceItemXwayland::SurfaceItemXwayland(X11Window *window, Scene *scene, Item *parent) SurfaceItemXwayland::SurfaceItemXwayland(X11Window *window, Scene *scene, Item *parent)
: SurfaceItemWayland(window->surface(), scene, parent) : SurfaceItemWayland(window->surface(), scene, parent)
, m_window(window) , m_window(window)
@ -237,6 +241,7 @@ QRegion SurfaceItemXwayland::opaque() const
} }
return QRegion(); return QRegion();
} }
#endif
} // namespace KWin } // namespace KWin

View file

@ -74,6 +74,7 @@ private:
SurfaceItemWayland *m_item; SurfaceItemWayland *m_item;
}; };
#if KWIN_BUILD_X11
/** /**
* The SurfaceItemXwayland class represents an Xwayland surface in the scene. * The SurfaceItemXwayland class represents an Xwayland surface in the scene.
*/ */
@ -90,5 +91,6 @@ public:
private: private:
X11Window *m_window; X11Window *m_window;
}; };
#endif
} // namespace KWin } // namespace KWin

View file

@ -16,7 +16,9 @@
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h" #include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#include <KDecoration2/Decoration> #include <KDecoration2/Decoration>
@ -300,6 +302,7 @@ void WindowItem::freeze()
} }
} }
#if KWIN_BUILD_X11
WindowItemX11::WindowItemX11(X11Window *window, Scene *scene, Item *parent) WindowItemX11::WindowItemX11(X11Window *window, Scene *scene, Item *parent)
: WindowItem(window, scene, parent) : WindowItem(window, scene, parent)
{ {
@ -326,6 +329,7 @@ void WindowItemX11::initialize()
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
#endif
WindowItemWayland::WindowItemWayland(Window *window, Scene *scene, Item *parent) WindowItemWayland::WindowItemWayland(Window *window, Scene *scene, Item *parent)
: WindowItem(window, scene, parent) : WindowItem(window, scene, parent)

View file

@ -6,6 +6,8 @@
#pragma once #pragma once
#include "config-kwin.h"
#include "scene/item.h" #include "scene/item.h"
namespace KDecoration2 namespace KDecoration2
@ -88,6 +90,7 @@ private:
int m_forceVisibleByActivityCount = 0; int m_forceVisibleByActivityCount = 0;
}; };
#if KWIN_BUILD_X11
/** /**
* The WindowItemX11 class represents an X11 window (both on X11 and Wayland sessions). * The WindowItemX11 class represents an X11 window (both on X11 and Wayland sessions).
* *
@ -104,6 +107,7 @@ public:
private Q_SLOTS: private Q_SLOTS:
void initialize(); void initialize();
}; };
#endif
/** /**
* The WindowItemWayland class represents a Wayland window. * The WindowItemWayland class represents a Wayland window.

View file

@ -61,6 +61,7 @@
#include "core/renderviewport.h" #include "core/renderviewport.h"
#include "effect/effecthandler.h" #include "effect/effecthandler.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "scene/decorationitem.h"
#include "scene/dndiconitem.h" #include "scene/dndiconitem.h"
#include "scene/itemrenderer.h" #include "scene/itemrenderer.h"
#include "scene/shadowitem.h" #include "scene/shadowitem.h"
@ -71,8 +72,11 @@
#include "wayland/surface.h" #include "wayland/surface.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "waylandwindow.h" #include "waylandwindow.h"
#include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#include <QtMath> #include <QtMath>

View file

@ -30,8 +30,11 @@
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "wayland/seat.h" #include "wayland/seat.h"
#include "wayland_server.h" #include "wayland_server.h"
#include <window.h>
#include <workspace.h> #include <workspace.h>
#include <x11window.h> #if KWIN_BUILD_X11
#include "x11window.h"
#endif
// DBus generated // DBus generated
#if KWIN_BUILD_SCREENLOCKER #if KWIN_BUILD_SCREENLOCKER
#include "screenlocker_interface.h" #include "screenlocker_interface.h"
@ -49,6 +52,7 @@
#include <QTextStream> #include <QTextStream>
#include <QTimer> #include <QTimer>
#include <QWidget> #include <QWidget>
#include <span>
namespace KWin namespace KWin
{ {
@ -1463,6 +1467,7 @@ bool ScreenEdges::isEntered(QMouseEvent *event)
return activated; return activated;
} }
#if KWIN_BUILD_X11
bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp) bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp)
{ {
bool activated = false; bool activated = false;
@ -1501,7 +1506,16 @@ bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, c
} }
return activated; return activated;
} }
#endif
void ScreenEdges::ensureOnTop()
{
#if KWIN_BUILD_X11
Xcb::restackWindowsWithRaise(windows());
#endif
}
#if KWIN_BUILD_X11
bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point) bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point)
{ {
for (const auto &edge : m_edges) { for (const auto &edge : m_edges) {
@ -1517,11 +1531,6 @@ bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point)
return false; return false;
} }
void ScreenEdges::ensureOnTop()
{
Xcb::restackWindowsWithRaise(windows());
}
QList<xcb_window_t> ScreenEdges::windows() const QList<xcb_window_t> ScreenEdges::windows() const
{ {
QList<xcb_window_t> wins; QList<xcb_window_t> wins;
@ -1538,6 +1547,7 @@ QList<xcb_window_t> ScreenEdges::windows() const
} }
return wins; return wins;
} }
#endif
void ScreenEdges::setRemainActiveOnFullscreen(bool remainActive) void ScreenEdges::setRemainActiveOnFullscreen(bool remainActive)
{ {

View file

@ -331,11 +331,13 @@ public:
void ensureOnTop(); void ensureOnTop();
bool isEntered(QMouseEvent *event); bool isEntered(QMouseEvent *event);
#if KWIN_BUILD_X11
/** /**
* Returns a QList of all existing screen edge windows * Returns a QList of all existing screen edge windows
* @return all existing screen edge windows in a QList * @return all existing screen edge windows in a QList
*/ */
QList<xcb_window_t> windows() const; QList<xcb_window_t> windows() const;
#endif
bool isDesktopSwitching() const; bool isDesktopSwitching() const;
bool isDesktopSwitchingMovingClients() const; bool isDesktopSwitchingMovingClients() const;
@ -364,8 +366,10 @@ public:
return m_gestureRecognizer; return m_gestureRecognizer;
} }
#if KWIN_BUILD_X11
bool handleDndNotify(xcb_window_t window, const QPoint &point); bool handleDndNotify(xcb_window_t window, const QPoint &point);
bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp); bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp);
#endif
bool remainActiveOnFullscreen() const; bool remainActiveOnFullscreen() const;
const std::vector<std::unique_ptr<Edge>> &edges() const; const std::vector<std::unique_ptr<Edge>> &edges() const;

View file

@ -16,11 +16,14 @@
#include "outline.h" #include "outline.h"
#include "tiles/tilemanager.h" #include "tiles/tilemanager.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "window.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
#endif #endif
#if KWIN_BUILD_X11
#include "x11window.h"
#endif
#include <QQmlEngine> #include <QQmlEngine>
@ -292,12 +295,14 @@ void WorkspaceWrapper::raiseWindow(KWin::Window *window)
} }
} }
#if KWIN_BUILD_X11
Window *WorkspaceWrapper::getClient(qulonglong windowId) Window *WorkspaceWrapper::getClient(qulonglong windowId)
{ {
auto window = Workspace::self()->findClient(Predicate::WindowMatch, windowId); auto window = Workspace::self()->findClient(Predicate::WindowMatch, windowId);
QQmlEngine::setObjectOwnership(window, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(window, QQmlEngine::CppOwnership);
return window; return window;
} }
#endif
QList<KWin::Window *> WorkspaceWrapper::windowAt(const QPointF &pos, int count) const QList<KWin::Window *> WorkspaceWrapper::windowAt(const QPointF &pos, int count) const
{ {

View file

@ -240,12 +240,14 @@ public:
* @param window The Window to raise * @param window The Window to raise
*/ */
Q_INVOKABLE void raiseWindow(KWin::Window *window); Q_INVOKABLE void raiseWindow(KWin::Window *window);
#if KWIN_BUILD_X11
/** /**
* Finds the Client with the given @p windowId. * Finds the Client with the given @p windowId.
* @param windowId The window Id of the Client * @param windowId The window Id of the Client
* @return The found Client or @c null * @return The found Client or @c null
*/ */
Q_SCRIPTABLE KWin::Window *getClient(qulonglong windowId); Q_SCRIPTABLE KWin::Window *getClient(qulonglong windowId);
#endif
/** /**
* Finds up to count windows at a particular location, * Finds up to count windows at a particular location,
* prioritizing the topmost one first. A negative count * prioritizing the topmost one first. A negative count

View file

@ -9,13 +9,16 @@
*/ */
#include "shadow.h" #include "shadow.h"
// kwin // kwin
#include "atoms.h"
#include "core/graphicsbufferview.h" #include "core/graphicsbufferview.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "wayland/shadow.h" #include "wayland/shadow.h"
#include "wayland/surface.h" #include "wayland/surface.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h"
#if KWIN_BUILD_X11
#include "atoms.h"
#include "x11window.h" #include "x11window.h"
#endif
#include <KDecoration2/Decoration> #include <KDecoration2/Decoration>
#include <KDecoration2/DecorationShadow> #include <KDecoration2/DecorationShadow>
@ -45,15 +48,18 @@ std::unique_ptr<Shadow> Shadow::createShadow(Window *window)
if (!shadow && waylandServer()) { if (!shadow && waylandServer()) {
shadow = createShadowFromWayland(window); shadow = createShadowFromWayland(window);
} }
#if KWIN_BUILD_X11
if (!shadow && kwinApp()->x11Connection()) { if (!shadow && kwinApp()->x11Connection()) {
shadow = createShadowFromX11(window); shadow = createShadowFromX11(window);
} }
#endif
if (!shadow) { if (!shadow) {
shadow = createShadowFromInternalWindow(window); shadow = createShadowFromInternalWindow(window);
} }
return shadow; return shadow;
} }
#if KWIN_BUILD_X11
std::unique_ptr<Shadow> Shadow::createShadowFromX11(Window *window) std::unique_ptr<Shadow> Shadow::createShadowFromX11(Window *window)
{ {
X11Window *x11Window = qobject_cast<X11Window *>(window); X11Window *x11Window = qobject_cast<X11Window *>(window);
@ -71,6 +77,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromX11(Window *window)
return nullptr; return nullptr;
} }
} }
#endif
std::unique_ptr<Shadow> Shadow::createShadowFromDecoration(Window *window) std::unique_ptr<Shadow> Shadow::createShadowFromDecoration(Window *window)
{ {
@ -118,6 +125,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromInternalWindow(Window *window)
return shadow; return shadow;
} }
#if KWIN_BUILD_X11
QList<uint32_t> Shadow::readX11ShadowProperty(xcb_window_t id) QList<uint32_t> Shadow::readX11ShadowProperty(xcb_window_t id)
{ {
QList<uint32_t> ret; QList<uint32_t> ret;
@ -133,9 +141,11 @@ QList<uint32_t> Shadow::readX11ShadowProperty(xcb_window_t id)
} }
return ret; return ret;
} }
#endif
bool Shadow::init(const QList<uint32_t> &data) bool Shadow::init(const QList<uint32_t> &data)
{ {
#if KWIN_BUILD_X11
QList<Xcb::WindowGeometry> pixmapGeometries(ShadowElementsCount); QList<Xcb::WindowGeometry> pixmapGeometries(ShadowElementsCount);
QList<xcb_get_image_cookie_t> getImageCookies(ShadowElementsCount); QList<xcb_get_image_cookie_t> getImageCookies(ShadowElementsCount);
auto *c = kwinApp()->x11Connection(); auto *c = kwinApp()->x11Connection();
@ -167,6 +177,7 @@ bool Shadow::init(const QList<uint32_t> &data)
m_shadowElements[i] = image.copy(); m_shadowElements[i] = image.copy();
free(reply); free(reply);
} }
#endif
m_offset = QMargins(data[ShadowElementsCount + 3], m_offset = QMargins(data[ShadowElementsCount + 3],
data[ShadowElementsCount], data[ShadowElementsCount],
data[ShadowElementsCount + 1], data[ShadowElementsCount + 1],
@ -295,6 +306,7 @@ bool Shadow::updateShadow()
} }
} }
#if KWIN_BUILD_X11
if (X11Window *window = qobject_cast<X11Window *>(m_window)) { if (X11Window *window = qobject_cast<X11Window *>(m_window)) {
auto data = Shadow::readX11ShadowProperty(window->window()); auto data = Shadow::readX11ShadowProperty(window->window());
if (!data.isEmpty()) { if (!data.isEmpty()) {
@ -302,6 +314,7 @@ bool Shadow::updateShadow()
return true; return true;
} }
} }
#endif
return false; return false;
} }

View file

@ -18,9 +18,11 @@
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
#include "xdgshellwindow.h" #include "xdgshellwindow.h"
#include <QDebug> #include <QDebug>
#if KWIN_BUILD_X11
#include "x11window.h"
#endif
#include <QSessionManager> #include <QSessionManager>
#if KWIN_BUILD_NOTIFICATIONS #if KWIN_BUILD_NOTIFICATIONS
@ -95,6 +97,7 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase)
int count = 0; int count = 0;
int active_client = -1; int active_client = -1;
#if KWIN_BUILD_X11
const QList<Window *> windows = workspace()->windows(); const QList<Window *> windows = workspace()->windows();
for (auto it = windows.begin(); it != windows.end(); ++it) { for (auto it = windows.begin(); it != windows.end(); ++it) {
X11Window *c = qobject_cast<X11Window *>(*it); X11Window *c = qobject_cast<X11Window *>(*it);
@ -123,6 +126,7 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase)
storeClient(cg, count, c); storeClient(cg, count, c);
} }
} }
#endif
if (phase == SMSavePhase0) { if (phase == SMSavePhase0) {
// it would be much simpler to save these values to the config file, // it would be much simpler to save these values to the config file,
// but both Qt and KDE treat phase1 and phase2 separately, // but both Qt and KDE treat phase1 and phase2 separately,
@ -141,6 +145,7 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase)
config->sync(); // it previously did some "revert to defaults" stuff for phase1 I think config->sync(); // it previously did some "revert to defaults" stuff for phase1 I think
} }
#if KWIN_BUILD_X11
void SessionManager::storeClient(KConfigGroup &cg, int num, X11Window *c) void SessionManager::storeClient(KConfigGroup &cg, int num, X11Window *c)
{ {
c->setSessionActivityOverride(false); // make sure we get the real values c->setSessionActivityOverride(false); // make sure we get the real values
@ -176,7 +181,9 @@ void SessionManager::storeClient(KConfigGroup &cg, int num, X11Window *c)
cg.writeEntry(QLatin1String("stackingOrder") + n, workspace()->unconstrainedStackingOrder().indexOf(c)); cg.writeEntry(QLatin1String("stackingOrder") + n, workspace()->unconstrainedStackingOrder().indexOf(c));
cg.writeEntry(QLatin1String("activities") + n, c->activities()); cg.writeEntry(QLatin1String("activities") + n, c->activities());
} }
#endif
#if KWIN_BUILD_X11
void SessionManager::storeSubSession(const QString &name, QSet<QByteArray> sessionIds) void SessionManager::storeSubSession(const QString &name, QSet<QByteArray> sessionIds)
{ {
// TODO clear it first // TODO clear it first
@ -217,6 +224,7 @@ void SessionManager::storeSubSession(const QString &name, QSet<QByteArray> sessi
cg.writeEntry("active", active_client); cg.writeEntry("active", active_client);
// cg.writeEntry( "desktop", currentDesktop()); // cg.writeEntry( "desktop", currentDesktop());
} }
#endif
/** /**
* Loads the session information from the config file. * Loads the session information from the config file.
@ -275,6 +283,7 @@ void SessionManager::loadSubSessionInfo(const QString &name)
addSessionInfo(cg); addSessionInfo(cg);
} }
#if KWIN_BUILD_X11
static bool sessionInfoWindowTypeMatch(X11Window *c, SessionInfo *info) static bool sessionInfoWindowTypeMatch(X11Window *c, SessionInfo *info)
{ {
if (int(info->windowType) == -2) { if (int(info->windowType) == -2) {
@ -343,6 +352,7 @@ SessionInfo *SessionManager::takeSessionInfo(X11Window *c)
} }
return realInfo; return realInfo;
} }
#endif
SessionManager::SessionManager(QObject *parent) SessionManager::SessionManager(QObject *parent)
: QObject(parent) : QObject(parent)
@ -388,9 +398,11 @@ void SessionManager::setState(SessionState state)
// If we're ending a save session due to either completion or cancellation // If we're ending a save session due to either completion or cancellation
if (m_sessionState == SessionState::Saving) { if (m_sessionState == SessionState::Saving) {
workspace()->rulebook()->setUpdatesDisabled(false); workspace()->rulebook()->setUpdatesDisabled(false);
#if KWIN_BUILD_X11
Workspace::self()->forEachClient([](X11Window *client) { Workspace::self()->forEachClient([](X11Window *client) {
client->setSessionActivityOverride(false); client->setSessionActivityOverride(false);
}); });
#endif
} }
m_sessionState = state; m_sessionState = state;

View file

@ -43,9 +43,11 @@ public:
SessionState state() const; SessionState state() const;
void loadSubSessionInfo(const QString &name); void loadSubSessionInfo(const QString &name);
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
#if KWIN_BUILD_X11
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
SessionInfo *takeSessionInfo(X11Window *); SessionInfo *takeSessionInfo(X11Window *);
#endif
Q_SIGNALS: Q_SIGNALS:
void stateChanged(); void stateChanged();
@ -66,7 +68,9 @@ private:
void setState(SessionState state); void setState(SessionState state);
void storeSession(const QString &sessionName, SMSavePhase phase); void storeSession(const QString &sessionName, SMSavePhase phase);
#if KWIN_BUILD_X11
void storeClient(KConfigGroup &cg, int num, X11Window *c); void storeClient(KConfigGroup &cg, int num, X11Window *c);
#endif
void loadSessionInfo(const QString &sessionName); void loadSessionInfo(const QString &sessionName);
void addSessionInfo(KConfigGroup &cg); void addSessionInfo(KConfigGroup &cg);

View file

@ -16,7 +16,6 @@
#include "tabbox/clientmodel.h" #include "tabbox/clientmodel.h"
#include "tabbox/tabbox_logging.h" #include "tabbox/tabbox_logging.h"
#include "tabbox/tabboxconfig.h" #include "tabbox/tabboxconfig.h"
#include "tabbox/x11_filter.h"
// kwin // kwin
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
@ -28,10 +27,12 @@
#include "keyboard_input.h" #include "keyboard_input.h"
#include "pointer_input.h" #include "pointer_input.h"
#include "screenedge.h" #include "screenedge.h"
#include "utils/xcbutils.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
// Qt // Qt
#include <QAction> #include <QAction>
#include <QKeyEvent> #include <QKeyEvent>
@ -42,12 +43,15 @@
#include <KLazyLocalizedString> #include <KLazyLocalizedString>
#include <KLocalizedString> #include <KLocalizedString>
#include <kkeyserver.h> #include <kkeyserver.h>
#if KWIN_BUILD_X11
#include "tabbox/x11_filter.h"
#include "utils/xcbutils.h"
// X11 // X11
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/keysymdef.h> #include <X11/keysymdef.h>
// xcb // xcb
#include <xcb/xcb_keysyms.h> #include <xcb/xcb_keysyms.h>
#endif
// specify externals before namespace // specify externals before namespace
namespace KWin namespace KWin
@ -666,6 +670,7 @@ void TabBox::grabbedKeyEvent(QKeyEvent *event)
m_tabBox->grabbedKeyEvent(event); m_tabBox->grabbedKeyEvent(event);
} }
#if KWIN_BUILD_X11
struct KeySymbolsDeleter struct KeySymbolsDeleter
{ {
void operator()(xcb_key_symbols_t *symbols) void operator()(xcb_key_symbols_t *symbols)
@ -751,6 +756,7 @@ static bool areModKeysDepressedX11(const QKeySequence &seq)
return areKeySymXsDepressed(rgKeySyms, nKeySyms); return areKeySymXsDepressed(rgKeySyms, nKeySyms);
} }
#endif
static bool areModKeysDepressedWayland(const QKeySequence &seq) static bool areModKeysDepressedWayland(const QKeySequence &seq)
{ {
@ -776,11 +782,15 @@ static bool areModKeysDepressed(const QKeySequence &seq)
if (seq.isEmpty()) { if (seq.isEmpty()) {
return false; return false;
} }
#if KWIN_BUILD_X11
if (kwinApp()->shouldUseWaylandForCompositing()) { if (kwinApp()->shouldUseWaylandForCompositing()) {
return areModKeysDepressedWayland(seq); return areModKeysDepressedWayland(seq);
} else { } else {
return areModKeysDepressedX11(seq); return areModKeysDepressedX11(seq);
} }
#else
return areModKeysDepressedWayland(seq);
#endif
} }
void TabBox::navigatingThroughWindows(bool forward, const QKeySequence &shortcut, TabBoxMode mode) void TabBox::navigatingThroughWindows(bool forward, const QKeySequence &shortcut, TabBoxMode mode)
@ -1178,10 +1188,12 @@ bool TabBox::establishTabBoxGrab()
m_forcedGlobalMouseGrab = true; m_forcedGlobalMouseGrab = true;
return true; return true;
} }
#if KWIN_BUILD_X11
kwinApp()->updateXTime(); kwinApp()->updateXTime();
if (!grabXKeyboard()) { if (!grabXKeyboard()) {
return false; return false;
} }
#endif
// Don't try to establish a global mouse grab using XGrabPointer, as that would prevent // Don't try to establish a global mouse grab using XGrabPointer, as that would prevent
// using Alt+Tab while DND (#44972). However force passive grabs on all windows // using Alt+Tab while DND (#44972). However force passive grabs on all windows
// in order to catch MouseRelease events and close the tabbox (#67416). // in order to catch MouseRelease events and close the tabbox (#67416).
@ -1192,7 +1204,9 @@ bool TabBox::establishTabBoxGrab()
if (Workspace::self()->activeWindow() != nullptr) { if (Workspace::self()->activeWindow() != nullptr) {
Workspace::self()->activeWindow()->updateMouseGrab(); Workspace::self()->activeWindow()->updateMouseGrab();
} }
#if KWIN_BUILD_X11
m_x11EventFilter = std::make_unique<X11Filter>(); m_x11EventFilter = std::make_unique<X11Filter>();
#endif
return true; return true;
} }
@ -1202,14 +1216,19 @@ void TabBox::removeTabBoxGrab()
m_forcedGlobalMouseGrab = false; m_forcedGlobalMouseGrab = false;
return; return;
} }
#if KWIN_BUILD_X11
kwinApp()->updateXTime(); kwinApp()->updateXTime();
ungrabXKeyboard(); ungrabXKeyboard();
#endif
Q_ASSERT(m_forcedGlobalMouseGrab); Q_ASSERT(m_forcedGlobalMouseGrab);
m_forcedGlobalMouseGrab = false; m_forcedGlobalMouseGrab = false;
if (Workspace::self()->activeWindow() != nullptr) { if (Workspace::self()->activeWindow() != nullptr) {
Workspace::self()->activeWindow()->updateMouseGrab(); Workspace::self()->activeWindow()->updateMouseGrab();
} }
#if KWIN_BUILD_X11
m_x11EventFilter.reset(); m_x11EventFilter.reset();
#endif
} }
} // namespace TabBox } // namespace TabBox
} // namespace } // namespace

View file

@ -273,7 +273,10 @@ private:
QList<ElectricBorder> m_borderActivate, m_borderAlternativeActivate; QList<ElectricBorder> m_borderActivate, m_borderAlternativeActivate;
QHash<ElectricBorder, QAction *> m_touchActivate; QHash<ElectricBorder, QAction *> m_touchActivate;
QHash<ElectricBorder, QAction *> m_touchAlternativeActivate; QHash<ElectricBorder, QAction *> m_touchAlternativeActivate;
#if KWIN_BUILD_X11
std::unique_ptr<X11EventFilter> m_x11EventFilter; std::unique_ptr<X11EventFilter> m_x11EventFilter;
#endif
}; };
} // namespace TabBox } // namespace TabBox

View file

@ -32,8 +32,11 @@
#include "scripting/scripting.h" #include "scripting/scripting.h"
#include "useractions.h" #include "useractions.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "window.h"
#include "workspace.h" #include "workspace.h"
#if KWIN_BUILD_X11
#include "x11window.h" #include "x11window.h"
#endif
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
@ -46,6 +49,7 @@
#include <QAction> #include <QAction>
#include <QCheckBox> #include <QCheckBox>
#include <QPushButton> #include <QPushButton>
#include <QWindow>
#include <KGlobalAccel> #include <KGlobalAccel>
#include <KLazyLocalizedString> #include <KLazyLocalizedString>
@ -1819,19 +1823,6 @@ void Window::setShortcutInternal()
workspace()->windowShortcutUpdated(this); workspace()->windowShortcutUpdated(this);
} }
void X11Window::setShortcutInternal()
{
updateCaption();
#if 0
workspace()->windowShortcutUpdated(this);
#else
// Workaround for kwin<->kglobalaccel deadlock, when KWin has X grab and the kded
// kglobalaccel module tries to create the key grab. KWin should preferably grab
// they keys itself anyway :(.
QTimer::singleShot(0, this, std::bind(&Workspace::windowShortcutUpdated, workspace(), this));
#endif
}
bool Workspace::shortcutAvailable(const QKeySequence &cut, Window *ignore) const bool Workspace::shortcutAvailable(const QKeySequence &cut, Window *ignore) const
{ {
if (ignore && cut == ignore->shortcut()) { if (ignore && cut == ignore->shortcut()) {

View file

@ -10,9 +10,11 @@ target_sources(kwin PRIVATE
subsurfacemonitor.cpp subsurfacemonitor.cpp
udev.cpp udev.cpp
vsyncmonitor.cpp vsyncmonitor.cpp
xcbutils.cpp
xcursortheme.cpp xcursortheme.cpp
) )
if (KWIN_BUILD_X11)
target_sources(kwin PRIVATE xcbutils.cpp)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux") if(CMAKE_SYSTEM_NAME MATCHES "Linux")
target_sources(kwin PRIVATE executable_path_proc.cpp) target_sources(kwin PRIVATE executable_path_proc.cpp)

View file

@ -15,12 +15,15 @@
*/ */
#include "utils/common.h" #include "utils/common.h"
#include "effect/xcb.h"
#include "utils/c_ptr.h" #include "utils/c_ptr.h"
#if KWIN_BUILD_X11
#include "effect/xcb.h"
#include <kkeyserver.h>
#endif
#include <QPainter> #include <QPainter>
#include <QWidget> #include <QWidget>
#include <kkeyserver.h>
#ifndef KCMRULES #ifndef KCMRULES
#include <QApplication> #include <QApplication>
@ -67,6 +70,8 @@ StrutRect &StrutRect::operator=(const StrutRect &other)
return *this; return *this;
} }
#if KWIN_BUILD_X11
static int server_grab_count = 0; static int server_grab_count = 0;
void grabXServer() void grabXServer()
@ -128,8 +133,6 @@ void ungrabXKeyboard()
xcb_ungrab_keyboard(connection(), XCB_TIME_CURRENT_TIME); xcb_ungrab_keyboard(connection(), XCB_TIME_CURRENT_TIME);
} }
#endif
// converting between X11 mouse/keyboard state mask and Qt button/keyboard states // converting between X11 mouse/keyboard state mask and Qt button/keyboard states
Qt::MouseButton x11ToQtMouseButton(int button) Qt::MouseButton x11ToQtMouseButton(int button)
@ -191,6 +194,61 @@ Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state)
return ret; return ret;
} }
#endif
#endif
QPointF popupOffset(const QRectF &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSizeF popupSize)
{
QPointF anchorPoint;
switch (anchorEdge & (Qt::LeftEdge | Qt::RightEdge)) {
case Qt::LeftEdge:
anchorPoint.setX(anchorRect.x());
break;
case Qt::RightEdge:
anchorPoint.setX(anchorRect.x() + anchorRect.width());
break;
default:
anchorPoint.setX(qRound(anchorRect.x() + anchorRect.width() / 2.0));
}
switch (anchorEdge & (Qt::TopEdge | Qt::BottomEdge)) {
case Qt::TopEdge:
anchorPoint.setY(anchorRect.y());
break;
case Qt::BottomEdge:
anchorPoint.setY(anchorRect.y() + anchorRect.height());
break;
default:
anchorPoint.setY(qRound(anchorRect.y() + anchorRect.height() / 2.0));
}
// calculate where the top left point of the popup will end up with the applied gravity
// gravity indicates direction. i.e if gravitating towards the top the popup's bottom edge
// will next to the anchor point
QPointF popupPosAdjust;
switch (gravity & (Qt::LeftEdge | Qt::RightEdge)) {
case Qt::LeftEdge:
popupPosAdjust.setX(-popupSize.width());
break;
case Qt::RightEdge:
popupPosAdjust.setX(0);
break;
default:
popupPosAdjust.setX(qRound(-popupSize.width() / 2.0));
}
switch (gravity & (Qt::TopEdge | Qt::BottomEdge)) {
case Qt::TopEdge:
popupPosAdjust.setY(-popupSize.height());
break;
case Qt::BottomEdge:
popupPosAdjust.setY(0);
break;
default:
popupPosAdjust.setY(qRound(-popupSize.height() / 2.0));
}
return anchorPoint + popupPosAdjust;
}
QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity) QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity)
{ {
QRectF geometry = rect; QRectF geometry = rect;
@ -223,6 +281,3 @@ QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravi
} }
} // namespace } // namespace
#ifndef KCMRULES
#endif

View file

@ -84,11 +84,13 @@ inline MaximizeMode operator^(MaximizeMode m1, MaximizeMode m2)
return MaximizeMode(int(m1) ^ int(m2)); return MaximizeMode(int(m1) ^ int(m2));
} }
#if KWIN_BUILD_X11
// converting between X11 mouse/keyboard state mask and Qt button/keyboard states // converting between X11 mouse/keyboard state mask and Qt button/keyboard states
Qt::MouseButton x11ToQtMouseButton(int button); Qt::MouseButton x11ToQtMouseButton(int button);
Qt::MouseButton KWIN_EXPORT x11ToQtMouseButton(int button); Qt::MouseButton KWIN_EXPORT x11ToQtMouseButton(int button);
Qt::MouseButtons KWIN_EXPORT x11ToQtMouseButtons(int state); Qt::MouseButtons KWIN_EXPORT x11ToQtMouseButtons(int state);
Qt::KeyboardModifiers KWIN_EXPORT x11ToQtKeyboardModifiers(int state); Qt::KeyboardModifiers KWIN_EXPORT x11ToQtKeyboardModifiers(int state);
#endif
KWIN_EXPORT QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity); KWIN_EXPORT QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity);

View file

@ -8,6 +8,12 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include "effect/globals.h" #include "effect/globals.h"
#include "effect/xcb.h" #include "effect/xcb.h"
#include "main.h" #include "main.h"

View file

@ -14,7 +14,9 @@
#include <KConfigGroup> #include <KConfigGroup>
#include <KGlobalAccel> #include <KGlobalAccel>
#include <KLocalizedString> #include <KLocalizedString>
#if KWIN_BUILD_X11
#include <NETWM> #include <NETWM>
#endif
// Qt // Qt
#include <QAction> #include <QAction>
@ -196,7 +198,9 @@ KWIN_SINGLETON_FACTORY_VARIABLE(VirtualDesktopManager, s_manager)
VirtualDesktopManager::VirtualDesktopManager(QObject *parent) VirtualDesktopManager::VirtualDesktopManager(QObject *parent)
: QObject(parent) : QObject(parent)
, m_navigationWrapsAround(false) , m_navigationWrapsAround(false)
#if KWIN_BUILD_X11
, m_rootInfo(nullptr) , m_rootInfo(nullptr)
#endif
, m_swipeGestureReleasedY(new QAction(this)) , m_swipeGestureReleasedY(new QAction(this))
, m_swipeGestureReleasedX(new QAction(this)) , m_swipeGestureReleasedX(new QAction(this))
{ {
@ -209,6 +213,7 @@ VirtualDesktopManager::~VirtualDesktopManager()
void VirtualDesktopManager::setRootInfo(NETRootInfo *info) void VirtualDesktopManager::setRootInfo(NETRootInfo *info)
{ {
#if KWIN_BUILD_X11
m_rootInfo = info; m_rootInfo = info;
// Nothing will be connected to rootInfo // Nothing will be connected to rootInfo
@ -219,6 +224,7 @@ void VirtualDesktopManager::setRootInfo(NETRootInfo *info)
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
} }
} }
#endif
} }
VirtualDesktop *VirtualDesktopManager::inDirection(VirtualDesktop *desktop, Direction direction, bool wrap) VirtualDesktop *VirtualDesktopManager::inDirection(VirtualDesktop *desktop, Direction direction, bool wrap)
@ -428,6 +434,7 @@ VirtualDesktop *VirtualDesktopManager::createVirtualDesktop(uint position, const
vd->setId(generateDesktopId()); vd->setId(generateDesktopId());
vd->setName(desktopName); vd->setName(desktopName);
#if KWIN_BUILD_X11
connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() { connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() {
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
@ -437,15 +444,18 @@ VirtualDesktop *VirtualDesktopManager::createVirtualDesktop(uint position, const
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
} }
#endif
m_desktops.insert(position, vd); m_desktops.insert(position, vd);
// update the id of displaced desktops // update the id of displaced desktops
for (uint i = position + 1; i < (uint)m_desktops.count(); ++i) { for (uint i = position + 1; i < (uint)m_desktops.count(); ++i) {
m_desktops[i]->setX11DesktopNumber(i + 1); m_desktops[i]->setX11DesktopNumber(i + 1);
#if KWIN_BUILD_X11
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(i + 1, m_desktops[i]->name().toUtf8().data()); m_rootInfo->setDesktopName(i + 1, m_desktops[i]->name().toUtf8().data());
} }
#endif
} }
save(); save();
@ -477,9 +487,11 @@ void VirtualDesktopManager::removeVirtualDesktop(VirtualDesktop *desktop)
for (int j = i; j < m_desktops.count(); ++j) { for (int j = i; j < m_desktops.count(); ++j) {
m_desktops[j]->setX11DesktopNumber(j + 1); m_desktops[j]->setX11DesktopNumber(j + 1);
#if KWIN_BUILD_X11
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(j + 1, m_desktops[j]->name().toUtf8().data()); m_rootInfo->setDesktopName(j + 1, m_desktops[j]->name().toUtf8().data());
} }
#endif
} }
if (m_current == desktop) { if (m_current == desktop) {
@ -562,6 +574,7 @@ void VirtualDesktopManager::setCount(uint count)
} }
m_desktops << vd; m_desktops << vd;
newDesktops << vd; newDesktops << vd;
#if KWIN_BUILD_X11
connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() { connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() {
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
@ -570,6 +583,7 @@ void VirtualDesktopManager::setCount(uint count)
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data());
} }
#endif
} }
} }
@ -608,6 +622,7 @@ void VirtualDesktopManager::setRows(uint rows)
void VirtualDesktopManager::updateRootInfo() void VirtualDesktopManager::updateRootInfo()
{ {
#if KWIN_BUILD_X11
if (m_rootInfo) { if (m_rootInfo) {
const int n = count(); const int n = count();
m_rootInfo->setNumberOfDesktops(n); m_rootInfo->setNumberOfDesktops(n);
@ -616,6 +631,7 @@ void VirtualDesktopManager::updateRootInfo()
delete[] viewports; delete[] viewports;
m_rootInfo->setDesktopLayout(NET::OrientationHorizontal, m_grid.width(), m_grid.height(), NET::DesktopLayoutCornerTopLeft); m_rootInfo->setDesktopLayout(NET::OrientationHorizontal, m_grid.width(), m_grid.height(), NET::DesktopLayoutCornerTopLeft);
} }
#endif
} }
void VirtualDesktopManager::updateLayout() void VirtualDesktopManager::updateLayout()
@ -646,9 +662,11 @@ void VirtualDesktopManager::load()
for (int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i)); QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i));
#if KWIN_BUILD_X11
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(i, s.toUtf8().data()); m_rootInfo->setDesktopName(i, s.toUtf8().data());
} }
#endif
m_desktops[i - 1]->setName(s); m_desktops[i - 1]->setName(s);
const QString sId = group.readEntry(QStringLiteral("Id_%1").arg(i), QString()); const QString sId = group.readEntry(QStringLiteral("Id_%1").arg(i), QString());
@ -692,9 +710,11 @@ void VirtualDesktopManager::save()
const QString defaultvalue = defaultName(position); const QString defaultvalue = defaultName(position);
if (s.isEmpty()) { if (s.isEmpty()) {
s = defaultvalue; s = defaultvalue;
#if KWIN_BUILD_X11
if (m_rootInfo) { if (m_rootInfo) {
m_rootInfo->setDesktopName(position, s.toUtf8().data()); m_rootInfo->setDesktopName(position, s.toUtf8().data());
} }
#endif
} }
if (s != defaultvalue) { if (s != defaultvalue) {

View file

@ -481,7 +481,9 @@ private:
bool m_navigationWrapsAround; bool m_navigationWrapsAround;
VirtualDesktopGrid m_grid; VirtualDesktopGrid m_grid;
// TODO: QPointer // TODO: QPointer
#if KWIN_BUILD_X11
NETRootInfo *m_rootInfo; NETRootInfo *m_rootInfo;
#endif
PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr; PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr;
KSharedConfig::Ptr m_config; KSharedConfig::Ptr m_config;

View file

@ -71,14 +71,16 @@
#include "wayland/xdgoutput_v1.h" #include "wayland/xdgoutput_v1.h"
#include "wayland/xdgshell.h" #include "wayland/xdgshell.h"
#include "wayland/xdgtopleveldrag_v1.h" #include "wayland/xdgtopleveldrag_v1.h"
#include "wayland/xwaylandkeyboardgrab_v1.h"
#include "wayland/xwaylandshell_v1.h"
#include "wayland/xx_colormanagement_v2.h" #include "wayland/xx_colormanagement_v2.h"
#include "workspace.h" #include "workspace.h"
#include "x11window.h"
#include "xdgactivationv1.h" #include "xdgactivationv1.h"
#include "xdgshellintegration.h" #include "xdgshellintegration.h"
#include "xdgshellwindow.h" #include "xdgshellwindow.h"
#if KWIN_BUILD_X11
#include "wayland/xwaylandkeyboardgrab_v1.h"
#include "wayland/xwaylandshell_v1.h"
#include "x11window.h"
#endif
// Qt // Qt
#include <QDir> #include <QDir>
@ -310,6 +312,7 @@ bool WaylandServer::init(InitializationFlags flags)
{ {
m_initFlags = flags; m_initFlags = flags;
m_compositor = new CompositorInterface(m_display, m_display); m_compositor = new CompositorInterface(m_display, m_display);
#if KWIN_BUILD_X11
connect(m_compositor, &CompositorInterface::surfaceCreated, this, [this](SurfaceInterface *surface) { connect(m_compositor, &CompositorInterface::surfaceCreated, this, [this](SurfaceInterface *surface) {
// check whether we have a Window with the Surface's id // check whether we have a Window with the Surface's id
Workspace *ws = Workspace::self(); Workspace *ws = Workspace::self();
@ -359,6 +362,7 @@ bool WaylandServer::init(InitializationFlags flags)
return; return;
} }
}); });
#endif
m_tabletManagerV2 = new TabletManagerV2Interface(m_display, m_display); m_tabletManagerV2 = new TabletManagerV2Interface(m_display, m_display);
m_keyboardShortcutsInhibitManager = new KeyboardShortcutsInhibitManagerV1Interface(m_display, m_display); m_keyboardShortcutsInhibitManager = new KeyboardShortcutsInhibitManagerV1Interface(m_display, m_display);
@ -455,7 +459,9 @@ bool WaylandServer::init(InitializationFlags flags)
new SubCompositorInterface(m_display, m_display); new SubCompositorInterface(m_display, m_display);
m_XdgForeign = new XdgForeignV2Interface(m_display, m_display); m_XdgForeign = new XdgForeignV2Interface(m_display, m_display);
m_inputMethod = new InputMethodV1Interface(m_display, m_display); m_inputMethod = new InputMethodV1Interface(m_display, m_display);
#if KWIN_BUILD_X11
m_xWaylandKeyboardGrabManager = new XWaylandKeyboardGrabManagerV1Interface(m_display, m_display); m_xWaylandKeyboardGrabManager = new XWaylandKeyboardGrabManagerV1Interface(m_display, m_display);
#endif
auto activation = new XdgActivationV1Interface(m_display, this); auto activation = new XdgActivationV1Interface(m_display, this);
auto init = [this, activation] { auto init = [this, activation] {
@ -677,6 +683,7 @@ int WaylandServer::createScreenLockerConnection()
return socket.fd; return socket.fd;
} }
#if KWIN_BUILD_X11
int WaylandServer::createXWaylandConnection() int WaylandServer::createXWaylandConnection()
{ {
const auto socket = createConnection(); const auto socket = createConnection();
@ -701,6 +708,7 @@ void WaylandServer::destroyXWaylandConnection()
m_xwaylandConnection->destroy(); m_xwaylandConnection->destroy();
m_xwaylandConnection = nullptr; m_xwaylandConnection = nullptr;
} }
#endif
int WaylandServer::createInputMethodConnection() int WaylandServer::createInputMethodConnection()
{ {
@ -795,9 +803,11 @@ bool WaylandServer::isKeyboardShortcutsInhibited() const
if (inhibitor && inhibitor->isActive()) { if (inhibitor && inhibitor->isActive()) {
return true; return true;
} }
#if KWIN_BUILD_X11
if (m_xWaylandKeyboardGrabManager->hasGrab(surface, seat())) { if (m_xWaylandKeyboardGrabManager->hasGrab(surface, seat())) {
return true; return true;
} }
#endif
} }
return false; return false;
} }

View file

@ -123,10 +123,12 @@ public:
{ {
return m_keyboardShortcutsInhibitManager; return m_keyboardShortcutsInhibitManager;
} }
#if KWIN_BUILD_X11
XwaylandShellV1Interface *xwaylandShell() const XwaylandShellV1Interface *xwaylandShell() const
{ {
return m_xwaylandShell; return m_xwaylandShell;
} }
#endif
bool isKeyboardShortcutsInhibited() const; bool isKeyboardShortcutsInhibited() const;
@ -160,11 +162,13 @@ public:
*/ */
XdgExportedSurface *exportAsForeign(SurfaceInterface *surface); XdgExportedSurface *exportAsForeign(SurfaceInterface *surface);
#if KWIN_BUILD_X11
/** /**
* @returns file descriptor for Xwayland to connect to. * @returns file descriptor for Xwayland to connect to.
*/ */
int createXWaylandConnection(); int createXWaylandConnection();
void destroyXWaylandConnection(); void destroyXWaylandConnection();
#endif
/** /**
* @returns file descriptor to the input method server's socket. * @returns file descriptor to the input method server's socket.
@ -279,7 +283,9 @@ private:
ClientConnection *m_screenLockerClientConnection = nullptr; ClientConnection *m_screenLockerClientConnection = nullptr;
XdgForeignV2Interface *m_XdgForeign = nullptr; XdgForeignV2Interface *m_XdgForeign = nullptr;
XdgActivationV1Integration *m_xdgActivationIntegration = nullptr; XdgActivationV1Integration *m_xdgActivationIntegration = nullptr;
#if KWIN_BUILD_X11
XWaylandKeyboardGrabManagerV1Interface *m_xWaylandKeyboardGrabManager = nullptr; XWaylandKeyboardGrabManagerV1Interface *m_xWaylandKeyboardGrabManager = nullptr;
#endif
ContentTypeManagerV1Interface *m_contentTypeManager = nullptr; ContentTypeManagerV1Interface *m_contentTypeManager = nullptr;
TearingControlManagerV1Interface *m_tearingControlInterface = nullptr; TearingControlManagerV1Interface *m_tearingControlInterface = nullptr;
XwaylandShellV1Interface *m_xwaylandShell = nullptr; XwaylandShellV1Interface *m_xwaylandShell = nullptr;

View file

@ -19,19 +19,16 @@
#include "activities.h" #include "activities.h"
#endif #endif
#include "appmenu.h" #include "appmenu.h"
#include "atoms.h"
#include "core/outputbackend.h" #include "core/outputbackend.h"
#include "core/outputconfiguration.h" #include "core/outputconfiguration.h"
#include "cursor.h" #include "cursor.h"
#include "dbusinterface.h" #include "dbusinterface.h"
#include "effect/effecthandler.h" #include "effect/effecthandler.h"
#include "focuschain.h" #include "focuschain.h"
#include "group.h"
#include "input.h" #include "input.h"
#include "internalwindow.h" #include "internalwindow.h"
#include "killwindow.h" #include "killwindow.h"
#include "moving_client_x11_filter.h" #include "moving_client_x11_filter.h"
#include "netinfo.h"
#include "outline.h" #include "outline.h"
#include "placement.h" #include "placement.h"
#include "pluginmanager.h" #include "pluginmanager.h"
@ -40,7 +37,7 @@
#include "scripting/scripting.h" #include "scripting/scripting.h"
#include "syncalarmx11filter.h" #include "syncalarmx11filter.h"
#include "tiles/tilemanager.h" #include "tiles/tilemanager.h"
#include "x11window.h" #include "window.h"
#if KWIN_BUILD_TABBOX #if KWIN_BUILD_TABBOX
#include "tabbox/tabbox.h" #include "tabbox/tabbox.h"
#endif #endif
@ -57,15 +54,21 @@
#include "useractions.h" #include "useractions.h"
#include "utils/kernel.h" #include "utils/kernel.h"
#include "utils/orientationsensor.h" #include "utils/orientationsensor.h"
#include "utils/xcbutils.h"
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "was_user_interaction_x11_filter.h" #include "was_user_interaction_x11_filter.h"
#include "wayland_server.h" #include "wayland_server.h"
#if KWIN_BUILD_X11
#include "atoms.h"
#include "group.h"
#include "netinfo.h"
#include "utils/xcbutils.h"
#include "x11window.h"
#include <KStartupInfo>
#endif
// KDE // KDE
#include <KConfig> #include <KConfig>
#include <KConfigGroup> #include <KConfigGroup>
#include <KLocalizedString> #include <KLocalizedString>
#include <KStartupInfo>
// Qt // Qt
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QDBusConnection> #include <QDBusConnection>
@ -217,11 +220,13 @@ void Workspace::init()
m_activeWindow = nullptr; m_activeWindow = nullptr;
#if KWIN_BUILD_X11
// We want to have some xcb connection while tearing down X11 components. We don't really // We want to have some xcb connection while tearing down X11 components. We don't really
// care if the xcb connection is broken or has an error. // care if the xcb connection is broken or has an error.
connect(kwinApp(), &Application::x11ConnectionChanged, this, &Workspace::initializeX11); connect(kwinApp(), &Application::x11ConnectionChanged, this, &Workspace::initializeX11);
connect(kwinApp(), &Application::x11ConnectionAboutToBeDestroyed, this, &Workspace::cleanupX11); connect(kwinApp(), &Application::x11ConnectionAboutToBeDestroyed, this, &Workspace::cleanupX11);
initializeX11(); initializeX11();
#endif
Scripting::create(this); Scripting::create(this);
@ -272,6 +277,7 @@ QString Workspace::getPlacementTrackerHash()
return QString::fromLatin1(hash.toHex()); return QString::fromLatin1(hash.toHex());
} }
#if KWIN_BUILD_X11
void Workspace::initializeX11() void Workspace::initializeX11()
{ {
if (!kwinApp()->x11Connection()) { if (!kwinApp()->x11Connection()) {
@ -437,12 +443,15 @@ void Workspace::cleanupX11()
m_syncAlarmFilter.reset(); m_syncAlarmFilter.reset();
m_wasUserInteractionFilter.reset(); m_wasUserInteractionFilter.reset();
} }
#endif
Workspace::~Workspace() Workspace::~Workspace()
{ {
blockStackingUpdates(true); blockStackingUpdates(true);
#if KWIN_BUILD_X11
cleanupX11(); cleanupX11();
#endif
if (waylandServer()) { if (waylandServer()) {
const QList<Window *> waylandWindows = waylandServer()->windows(); const QList<Window *> waylandWindows = waylandServer()->windows();
@ -660,6 +669,7 @@ void Workspace::removeFromStack(Window *window)
} }
} }
#if KWIN_BUILD_X11
X11Window *Workspace::createX11Window(xcb_window_t windowId, bool is_mapped) X11Window *Workspace::createX11Window(xcb_window_t windowId, bool is_mapped)
{ {
StackingUpdatesBlocker blocker(this); StackingUpdatesBlocker blocker(this);
@ -722,7 +732,7 @@ void Workspace::addX11Window(X11Window *window)
} }
window->checkActiveModal(); window->checkActiveModal();
checkTransients(window->window()); // SELI TODO: Does this really belong here? checkTransients(window->window()); // SELI TODO: Does this really belong here?
updateStackingOrder(true); // Propagate new window updateStackingOrder(true); // Propagatem new window
if (window->isUtility() || window->isMenu() || window->isToolbar()) { if (window->isUtility() || window->isMenu() || window->isToolbar()) {
updateToolWindows(true); updateToolWindows(true);
} }
@ -759,6 +769,7 @@ void Workspace::removeUnmanaged(X11Window *window)
updateStackingOrder(); updateStackingOrder();
Q_EMIT windowRemoved(window); Q_EMIT windowRemoved(window);
} }
#endif
void Workspace::addDeleted(Window *c) void Workspace::addDeleted(Window *c)
{ {
@ -861,11 +872,13 @@ void Workspace::updateToolWindows(bool also_hide)
{ {
// TODO: What if Client's transiency/group changes? should this be called too? (I'm paranoid, am I not?) // TODO: What if Client's transiency/group changes? should this be called too? (I'm paranoid, am I not?)
if (!options->isHideUtilityWindowsForInactive()) { if (!options->isHideUtilityWindowsForInactive()) {
#if KWIN_BUILD_X11
for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) { for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) {
if (X11Window *x11Window = qobject_cast<X11Window *>(*it)) { if (X11Window *x11Window = qobject_cast<X11Window *>(*it)) {
x11Window->setHidden(false); x11Window->setHidden(false);
} }
} }
#endif
return; return;
} }
const Group *group = nullptr; const Group *group = nullptr;
@ -895,11 +908,14 @@ void Workspace::updateToolWindows(bool also_hide)
if (c->isUtility() || c->isMenu() || c->isToolbar()) { if (c->isUtility() || c->isMenu() || c->isToolbar()) {
bool show = true; bool show = true;
if (!c->isTransient()) { if (!c->isTransient()) {
#if KWIN_BUILD_X11
if (!c->group() || c->group()->members().count() == 1) { // Has its own group, keep always visible if (!c->group() || c->group()->members().count() == 1) { // Has its own group, keep always visible
show = true; show = true;
} else if (window != nullptr && c->group() == window->group()) { } else if (window != nullptr && c->group() == window->group()) {
show = true; show = true;
} else { } else
#endif
{
show = false; show = false;
} }
} else { } else {
@ -1030,6 +1046,7 @@ void Workspace::slotCurrentDesktopChangingCancelled()
void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop) void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop)
{ {
#if KWIN_BUILD_X11
for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) { for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) {
X11Window *c = qobject_cast<X11Window *>(*it); X11Window *c = qobject_cast<X11Window *>(*it);
if (!c) { if (!c) {
@ -1043,11 +1060,13 @@ void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop
if (rootInfo()) { if (rootInfo()) {
rootInfo()->setCurrentDesktop(VirtualDesktopManager::self()->current()); rootInfo()->setCurrentDesktop(VirtualDesktopManager::self()->current());
} }
#endif
if (m_moveResizeWindow && !m_moveResizeWindow->isOnDesktop(newDesktop)) { if (m_moveResizeWindow && !m_moveResizeWindow->isOnDesktop(newDesktop)) {
m_moveResizeWindow->setDesktops({newDesktop}); m_moveResizeWindow->setDesktops({newDesktop});
} }
#if KWIN_BUILD_X11
for (int i = stacking_order.size() - 1; i >= 0; --i) { for (int i = stacking_order.size() - 1; i >= 0; --i) {
X11Window *c = qobject_cast<X11Window *>(stacking_order.at(i)); X11Window *c = qobject_cast<X11Window *>(stacking_order.at(i));
if (!c) { if (!c) {
@ -1057,6 +1076,7 @@ void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop
c->updateVisibility(); c->updateVisibility();
} }
} }
#endif
if (showingDesktop()) { // Do this only after desktop change to avoid flicker if (showingDesktop()) { // Do this only after desktop change to avoid flicker
setShowingDesktop(false); setShowingDesktop(false);
} }
@ -1142,6 +1162,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
// mapping done from front to back => less exposure events // mapping done from front to back => less exposure events
// Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop)); // Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop));
#if KWIN_BUILD_X11
for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) { for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) {
X11Window *window = qobject_cast<X11Window *>(*it); X11Window *window = qobject_cast<X11Window *>(*it);
if (!window) { if (!window) {
@ -1170,6 +1191,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
window->updateVisibility(); window->updateVisibility();
} }
} }
#endif
// FIXME not sure if I should do this either // FIXME not sure if I should do this either
if (showingDesktop()) { // Do this only after desktop change to avoid flicker if (showingDesktop()) { // Do this only after desktop change to avoid flicker
@ -1458,6 +1480,7 @@ void Workspace::slotDesktopRemoved(VirtualDesktop *desktop)
m_focusChain->removeDesktop(desktop); m_focusChain->removeDesktop(desktop);
} }
#if KWIN_BUILD_X11
void Workspace::selectWmInputEventMask() void Workspace::selectWmInputEventMask()
{ {
uint32_t presentMask = 0; uint32_t presentMask = 0;
@ -1476,6 +1499,7 @@ void Workspace::selectWmInputEventMask()
Xcb::selectInput(kwinApp()->x11RootWindow(), presentMask | wmMask); Xcb::selectInput(kwinApp()->x11RootWindow(), presentMask | wmMask);
} }
#endif
/** /**
* Sends window \a window to desktop \a desk. * Sends window \a window to desktop \a desk.
@ -1542,10 +1566,12 @@ void Workspace::cancelDelayFocus()
m_delayFocusWindow = nullptr; m_delayFocusWindow = nullptr;
} }
#if KWIN_BUILD_X11
bool Workspace::checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data) bool Workspace::checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data)
{ {
return m_startup->checkStartup(w, id, data) == KStartupInfo::Match; return m_startup->checkStartup(w, id, data) == KStartupInfo::Match;
} }
#endif
/** /**
* Puts the focus on a dummy window * Puts the focus on a dummy window
@ -1553,10 +1579,12 @@ bool Workspace::checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KSt
*/ */
void Workspace::focusToNull() void Workspace::focusToNull()
{ {
#if KWIN_BUILD_X11
if (m_nullFocus) { if (m_nullFocus) {
should_get_focus.clear(); should_get_focus.clear();
m_nullFocus->focus(); m_nullFocus->focus();
} }
#endif
} }
bool Workspace::breaksShowingDesktop(Window *window) const bool Workspace::breaksShowingDesktop(Window *window) const
@ -1567,9 +1595,12 @@ bool Workspace::breaksShowingDesktop(Window *window) const
void Workspace::setShowingDesktop(bool showing, bool animated) void Workspace::setShowingDesktop(bool showing, bool animated)
{ {
const bool changed = showing != showing_desktop; const bool changed = showing != showing_desktop;
#if KWIN_BUILD_X11
if (rootInfo() && changed) { if (rootInfo() && changed) {
rootInfo()->setShowingDesktop(showing); rootInfo()->setShowingDesktop(showing);
} }
#endif
showing_desktop = showing; showing_desktop = showing;
for (int i = stacking_order.count() - 1; i > -1; --i) { for (int i = stacking_order.count() - 1; i > -1; --i) {
@ -1674,6 +1705,7 @@ QString Workspace::supportInformation() const
support.append(HAVE_GLX ? yes : no); support.append(HAVE_GLX ? yes : no);
support.append(QStringLiteral("\n")); support.append(QStringLiteral("\n"));
#if KWIN_BUILD_X11
if (auto c = kwinApp()->x11Connection()) { if (auto c = kwinApp()->x11Connection()) {
support.append(QStringLiteral("X11\n")); support.append(QStringLiteral("X11\n"));
support.append(QStringLiteral("===\n")); support.append(QStringLiteral("===\n"));
@ -1688,6 +1720,7 @@ QString Workspace::supportInformation() const
} }
support.append(QStringLiteral("\n")); support.append(QStringLiteral("\n"));
} }
#endif
if (m_decorationBridge) { if (m_decorationBridge) {
support.append(QStringLiteral("Decoration\n")); support.append(QStringLiteral("Decoration\n"));
@ -1823,9 +1856,11 @@ QString Workspace::supportInformation() const
if (platform->isMesaDriver()) { if (platform->isMesaDriver()) {
support.append(QStringLiteral("Mesa version: ") + platform->mesaVersion().toString() + QStringLiteral("\n")); support.append(QStringLiteral("Mesa version: ") + platform->mesaVersion().toString() + QStringLiteral("\n"));
} }
#if KWIN_BUILD_X11
if (auto xVersion = Xcb::xServerVersion(); xVersion.isValid()) { if (auto xVersion = Xcb::xServerVersion(); xVersion.isValid()) {
support.append(QStringLiteral("X server version: ") + xVersion.toString() + QStringLiteral("\n")); support.append(QStringLiteral("X server version: ") + xVersion.toString() + QStringLiteral("\n"));
} }
#endif
if (auto kernelVersion = linuxKernelVersion(); kernelVersion.isValid()) { if (auto kernelVersion = linuxKernelVersion(); kernelVersion.isValid()) {
support.append(QStringLiteral("Linux kernel version: ") + kernelVersion.toString() + QStringLiteral("\n")); support.append(QStringLiteral("Linux kernel version: ") + kernelVersion.toString() + QStringLiteral("\n"));
} }
@ -1892,6 +1927,7 @@ QString Workspace::supportInformation() const
return support; return support;
} }
#if KWIN_BUILD_X11
void Workspace::forEachClient(std::function<void(X11Window *)> func) void Workspace::forEachClient(std::function<void(X11Window *)> func)
{ {
for (Window *window : std::as_const(m_windows)) { for (Window *window : std::as_const(m_windows)) {
@ -1953,6 +1989,7 @@ X11Window *Workspace::findClient(Predicate predicate, xcb_window_t w) const
} }
return nullptr; return nullptr;
} }
#endif
Window *Workspace::findWindow(std::function<bool(const Window *)> func) const Window *Workspace::findWindow(std::function<bool(const Window *)> func) const
{ {
@ -1984,9 +2021,11 @@ Window *Workspace::findInternal(QWindow *w) const
if (!w) { if (!w) {
return nullptr; return nullptr;
} }
#if KWIN_BUILD_X11
if (kwinApp()->operationMode() == Application::OperationModeX11) { if (kwinApp()->operationMode() == Application::OperationModeX11) {
return findUnmanaged(w->winId()); return findUnmanaged(w->winId());
} }
#endif
for (Window *window : m_windows) { for (Window *window : m_windows) {
if (InternalWindow *internal = qobject_cast<InternalWindow *>(window)) { if (InternalWindow *internal = qobject_cast<InternalWindow *>(window)) {
if (internal->handle() == w) { if (internal->handle() == w) {
@ -2004,10 +2043,12 @@ void Workspace::setWasUserInteraction()
} }
was_user_interaction = true; was_user_interaction = true;
// might be called from within the filter, so delay till we now the filter returned // might be called from within the filter, so delay till we now the filter returned
#if KWIN_BUILD_X11
QTimer::singleShot(0, this, QTimer::singleShot(0, this,
[this] { [this] {
m_wasUserInteractionFilter.reset(); m_wasUserInteractionFilter.reset();
}); });
#endif
} }
void Workspace::updateTabbox() void Workspace::updateTabbox()
@ -2050,6 +2091,7 @@ void Workspace::setInitialDesktop(int desktop)
m_initialDesktop = desktop; m_initialDesktop = desktop;
} }
#if KWIN_BUILD_X11
Group *Workspace::findGroup(xcb_window_t leader) const Group *Workspace::findGroup(xcb_window_t leader) const
{ {
Q_ASSERT(leader != XCB_WINDOW_NONE); Q_ASSERT(leader != XCB_WINDOW_NONE);
@ -2092,6 +2134,7 @@ Group *Workspace::findClientLeaderGroup(const X11Window *window) const
} }
return ret; return ret;
} }
#endif
void Workspace::updateMinimizedOfTransients(Window *window) void Workspace::updateMinimizedOfTransients(Window *window)
{ {
@ -2142,6 +2185,7 @@ void Workspace::updateOnAllDesktopsOfTransients(Window *window)
} }
} }
#if KWIN_BUILD_X11
// A new window has been mapped. Check if it's not a mainwindow for some already existing transient window. // A new window has been mapped. Check if it's not a mainwindow for some already existing transient window.
void Workspace::checkTransients(xcb_window_t w) void Workspace::checkTransients(xcb_window_t w)
{ {
@ -2151,6 +2195,7 @@ void Workspace::checkTransients(xcb_window_t w)
} }
} }
} }
#endif
/** /**
* Resizes the workspace after an XRANDR screen size change * Resizes the workspace after an XRANDR screen size change
@ -2165,12 +2210,14 @@ void Workspace::desktopResized()
m_geometry = m_geometry.united(output->geometry()); m_geometry = m_geometry.united(output->geometry());
} }
#if KWIN_BUILD_X11
if (rootInfo()) { if (rootInfo()) {
NETSize desktop_geometry; NETSize desktop_geometry;
desktop_geometry.width = Xcb::toXNative(m_geometry.width()); desktop_geometry.width = Xcb::toXNative(m_geometry.width());
desktop_geometry.height = Xcb::toXNative(m_geometry.height()); desktop_geometry.height = Xcb::toXNative(m_geometry.height());
rootInfo()->setDesktopGeometry(desktop_geometry); rootInfo()->setDesktopGeometry(desktop_geometry);
} }
#endif
updateClientArea(); updateClientArea();
@ -2215,6 +2262,7 @@ void Workspace::saveOldScreenSizes()
} }
} }
#if KWIN_BUILD_X11
/** /**
* Whether or not the window has a strut that expands through the invisible area of * Whether or not the window has a strut that expands through the invisible area of
* an xinerama setup where the monitors are not the same resolution. * an xinerama setup where the monitors are not the same resolution.
@ -2241,6 +2289,7 @@ static bool hasOffscreenXineramaStrut(Window *window)
return false; return false;
} }
#endif
QRectF Workspace::adjustClientArea(Window *window, const QRectF &area) const QRectF Workspace::adjustClientArea(Window *window, const QRectF &area) const
{ {
@ -2252,6 +2301,7 @@ QRectF Workspace::adjustClientArea(Window *window, const QRectF &area) const
QRectF strutBottom = window->strutRect(StrutAreaBottom); QRectF strutBottom = window->strutRect(StrutAreaBottom);
QRectF screenArea = clientArea(ScreenArea, window); QRectF screenArea = clientArea(ScreenArea, window);
#if KWIN_BUILD_X11
if (qobject_cast<X11Window *>(window)) { if (qobject_cast<X11Window *>(window)) {
// HACK: workarea handling is not xinerama aware, so if this strut // HACK: workarea handling is not xinerama aware, so if this strut
// reserves place at a xinerama edge that's inside the virtual screen, // reserves place at a xinerama edge that's inside the virtual screen,
@ -2271,6 +2321,7 @@ QRectF Workspace::adjustClientArea(Window *window, const QRectF &area) const
} }
} }
} }
#endif
// Handle struts at xinerama edges that are inside the virtual screen. // Handle struts at xinerama edges that are inside the virtual screen.
// They're given in virtual screen coordinates, make them affect only // They're given in virtual screen coordinates, make them affect only
@ -2358,7 +2409,10 @@ void Workspace::updateClientArea()
// This goes against the EWMH description of the work area but it is a toss up between // This goes against the EWMH description of the work area but it is a toss up between
// having unusable sections of the screen (Which can be quite large with newer monitors) // having unusable sections of the screen (Which can be quite large with newer monitors)
// or having some content appear offscreen (Relatively rare compared to other). // or having some content appear offscreen (Relatively rare compared to other).
bool hasOffscreenStrut = hasOffscreenXineramaStrut(window); bool hasOffscreenStrut = false;
#if KWIN_BUILD_X11
hasOffscreenStrut = hasOffscreenXineramaStrut(window);
#endif
const auto vds = window->isOnAllDesktops() ? desktops : window->desktops(); const auto vds = window->isOnAllDesktops() ? desktops : window->desktops();
for (VirtualDesktop *vd : vds) { for (VirtualDesktop *vd : vds) {
@ -2384,6 +2438,7 @@ void Workspace::updateClientArea()
m_oldRestrictedAreas = m_restrictedAreas; m_oldRestrictedAreas = m_restrictedAreas;
m_restrictedAreas = restrictedAreas; m_restrictedAreas = restrictedAreas;
#if KWIN_BUILD_X11
if (rootInfo()) { if (rootInfo()) {
for (VirtualDesktop *desktop : desktops) { for (VirtualDesktop *desktop : desktops) {
const QRectF &workArea = m_workAreas[desktop]; const QRectF &workArea = m_workAreas[desktop];
@ -2391,6 +2446,7 @@ void Workspace::updateClientArea()
rootInfo()->setWorkArea(desktop->x11DesktopNumber(), r); rootInfo()->setWorkArea(desktop->x11DesktopNumber(), r);
} }
} }
#endif
for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) { for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) {
if ((*it)->isClient()) { if ((*it)->isClient()) {
@ -2503,6 +2559,7 @@ QHash<const Output *, QRect> Workspace::previousScreenSizes() const
return m_oldScreenGeometries; return m_oldScreenGeometries;
} }
#if KWIN_BUILD_X11
Output *Workspace::xineramaIndexToOutput(int index) const Output *Workspace::xineramaIndexToOutput(int index) const
{ {
xcb_connection_t *connection = kwinApp()->x11Connection(); xcb_connection_t *connection = kwinApp()->x11Connection();
@ -2536,6 +2593,7 @@ Output *Workspace::xineramaIndexToOutput(int index) const
return nullptr; return nullptr;
} }
#endif
void Workspace::setOutputOrder(const QList<Output *> &order) void Workspace::setOutputOrder(const QList<Output *> &order)
{ {
@ -3013,6 +3071,7 @@ void Workspace::setMoveResizeWindow(Window *window)
} }
} }
#if KWIN_BUILD_X11
// When kwin crashes, windows will not be gravitated back to their original position // When kwin crashes, windows will not be gravitated back to their original position
// and will remain offset by the size of the decoration. So when restarting, fix this // and will remain offset by the size of the decoration. So when restarting, fix this
// (the property with the size of the frame remains on the window after the crash). // (the property with the size of the frame remains on the window after the crash).
@ -3029,6 +3088,7 @@ void Workspace::fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_rep
xcb_configure_window(kwinApp()->x11Connection(), w, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values); xcb_configure_window(kwinApp()->x11Connection(), w, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
} }
} }
#endif
FocusChain *Workspace::focusChain() const FocusChain *Workspace::focusChain() const
{ {

View file

@ -95,10 +95,11 @@ public:
return _self; return _self;
} }
bool workspaceEvent(xcb_generic_event_t *);
bool hasWindow(const Window *); bool hasWindow(const Window *);
#if KWIN_BUILD_X11
bool workspaceEvent(xcb_generic_event_t *);
/** /**
* @brief Finds the first Client matching the condition expressed by passed in @p func. * @brief Finds the first Client matching the condition expressed by passed in @p func.
* *
@ -146,6 +147,7 @@ public:
* @return KWin::Unmanaged* Found Unmanaged or @c null if there is no Unmanaged with given Id. * @return KWin::Unmanaged* Found Unmanaged or @c null if there is no Unmanaged with given Id.
*/ */
X11Window *findUnmanaged(xcb_window_t w) const; X11Window *findUnmanaged(xcb_window_t w) const;
#endif
Window *findWindow(const QUuid &internalId) const; Window *findWindow(const QUuid &internalId) const;
Window *findWindow(std::function<bool(const Window *)> func) const; Window *findWindow(std::function<bool(const Window *)> func) const;
@ -227,14 +229,16 @@ public:
QRectF adjustWindowSize(const Window *window, QRectF moveResizeGeom, Gravity gravity) const; QRectF adjustWindowSize(const Window *window, QRectF moveResizeGeom, Gravity gravity) const;
void raiseWindow(Window *window, bool nogroup = false); void raiseWindow(Window *window, bool nogroup = false);
void lowerWindow(Window *window, bool nogroup = false); void lowerWindow(Window *window, bool nogroup = false);
void raiseWindowRequest(Window *window, NET::RequestSource src = NET::FromApplication, xcb_timestamp_t timestamp = 0); void raiseWindowRequest(Window *window, NET::RequestSource src = NET::FromApplication, uint32_t timestamp = 0);
#if KWIN_BUILD_X11
void lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t timestamp); void lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t timestamp);
void restoreSessionStackingOrder(X11Window *window);
#endif
void lowerWindowRequest(Window *window); void lowerWindowRequest(Window *window);
void restackWindowUnderActive(Window *window); void restackWindowUnderActive(Window *window);
void restack(Window *window, Window *under, bool force = false); void restack(Window *window, Window *under, bool force = false);
void raiseOrLowerWindow(Window *window); void raiseOrLowerWindow(Window *window);
void resetUpdateToolWindowsTimer(); void resetUpdateToolWindowsTimer();
void restoreSessionStackingOrder(X11Window *window);
void updateStackingOrder(bool propagate_new_windows = false); void updateStackingOrder(bool propagate_new_windows = false);
void forceRestacking(); void forceRestacking();
@ -251,7 +255,9 @@ public:
return m_windows; return m_windows;
} }
#if KWIN_BUILD_X11
void stackScreenEdgesUnderOverrideRedirect(); void stackScreenEdgesUnderOverrideRedirect();
#endif
SessionManager *sessionManager() const; SessionManager *sessionManager() const;
@ -283,7 +289,6 @@ public:
*/ */
const QList<Window *> &stackingOrder() const; const QList<Window *> &stackingOrder() const;
QList<Window *> unconstrainedStackingOrder() const; QList<Window *> unconstrainedStackingOrder() const;
QList<X11Window *> ensureStackingOrder(const QList<X11Window *> &windows) const;
QList<Window *> ensureStackingOrder(const QList<Window *> &windows) const; QList<Window *> ensureStackingOrder(const QList<Window *> &windows) const;
Window *topWindowOnDesktop(VirtualDesktop *desktop, Output *output = nullptr, bool unconstrained = false, Window *topWindowOnDesktop(VirtualDesktop *desktop, Output *output = nullptr, bool unconstrained = false,
@ -294,6 +299,9 @@ public:
void windowToNextDesktop(Window *window); void windowToNextDesktop(Window *window);
void sendWindowToOutput(Window *window, Output *output); void sendWindowToOutput(Window *window, Output *output);
#if KWIN_BUILD_X11
QList<X11Window *> ensureStackingOrder(const QList<X11Window *> &windows) const;
void addManualOverlay(xcb_window_t id) void addManualOverlay(xcb_window_t id)
{ {
manual_overlays << id; manual_overlays << id;
@ -302,6 +310,7 @@ public:
{ {
manual_overlays.removeOne(id); manual_overlays.removeOne(id);
} }
#endif
/** /**
* Shows the menu operations menu for the window and makes it active if * Shows the menu operations menu for the window and makes it active if
@ -317,9 +326,11 @@ public:
void updateMinimizedOfTransients(Window *); void updateMinimizedOfTransients(Window *);
void updateOnAllDesktopsOfTransients(Window *); void updateOnAllDesktopsOfTransients(Window *);
void checkTransients(xcb_window_t w);
#if KWIN_BUILD_X11
void checkTransients(xcb_window_t w);
SessionInfo *takeSessionInfo(X11Window *); SessionInfo *takeSessionInfo(X11Window *);
#endif
// D-Bus interface // D-Bus interface
QString supportInformation() const; QString supportInformation() const;
@ -347,8 +358,9 @@ public:
void setShowingDesktop(bool showing, bool animated = true); void setShowingDesktop(bool showing, bool animated = true);
bool showingDesktop() const; bool showingDesktop() const;
void removeX11Window(X11Window *); // Only called from X11Window::destroyWindow() or X11Window::releaseWindow()
void setActiveWindow(Window *window); void setActiveWindow(Window *window);
#if KWIN_BUILD_X11
void removeX11Window(X11Window *); // Only called from X11Window::destroyWindow() or X11Window::releaseWindow()
Group *findGroup(xcb_window_t leader) const; Group *findGroup(xcb_window_t leader) const;
void addGroup(Group *group); void addGroup(Group *group);
void removeGroup(Group *group); void removeGroup(Group *group);
@ -356,11 +368,11 @@ public:
int unconstainedStackingOrderIndex(const X11Window *c) const; int unconstainedStackingOrderIndex(const X11Window *c) const;
void removeUnmanaged(X11Window *); void removeUnmanaged(X11Window *);
bool checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data);
#endif
void removeDeleted(Window *); void removeDeleted(Window *);
void addDeleted(Window *); void addDeleted(Window *);
bool checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data);
void focusToNull(); // SELI TODO: Public? void focusToNull(); // SELI TODO: Public?
void windowShortcutUpdated(Window *window); void windowShortcutUpdated(Window *window);
@ -521,7 +533,9 @@ public Q_SLOTS:
private Q_SLOTS: private Q_SLOTS:
void desktopResized(); void desktopResized();
#if KWIN_BUILD_X11
void selectWmInputEventMask(); void selectWmInputEventMask();
#endif
void slotUpdateToolWindows(); void slotUpdateToolWindows();
void delayFocus(); void delayFocus();
void slotReloadConfig(); void slotReloadConfig();
@ -551,7 +565,9 @@ Q_SIGNALS:
void windowRemoved(KWin::Window *); void windowRemoved(KWin::Window *);
void windowActivated(KWin::Window *); void windowActivated(KWin::Window *);
void windowMinimizedChanged(KWin::Window *); void windowMinimizedChanged(KWin::Window *);
#if KWIN_BUILD_X11
void groupAdded(KWin::Group *); void groupAdded(KWin::Group *);
#endif
void deletedRemoved(KWin::Window *); void deletedRemoved(KWin::Window *);
void configChanged(); void configChanged();
void showingDesktopChanged(bool showing, bool animated); void showingDesktopChanged(bool showing, bool animated);
@ -567,8 +583,6 @@ Q_SIGNALS:
private: private:
void init(); void init();
void initializeX11();
void cleanupX11();
void initShortcuts(); void initShortcuts();
template<typename Slot> template<typename Slot>
void initShortcut(const QString &actionName, const QString &description, const QKeySequence &shortcut, Slot slot); void initShortcut(const QString &actionName, const QString &description, const QKeySequence &shortcut, Slot slot);
@ -577,24 +591,30 @@ private:
void setupWindowShortcut(Window *window); void setupWindowShortcut(Window *window);
bool switchWindow(Window *window, Direction direction, QPoint curPos, VirtualDesktop *desktop); bool switchWindow(Window *window, Direction direction, QPoint curPos, VirtualDesktop *desktop);
void propagateWindows(bool propagate_new_windows); // Called only from updateStackingOrder
QList<Window *> constrainedStackingOrder(); QList<Window *> constrainedStackingOrder();
void raiseWindowWithinApplication(Window *window); void raiseWindowWithinApplication(Window *window);
void lowerWindowWithinApplication(Window *window); void lowerWindowWithinApplication(Window *window);
bool allowFullClientRaising(const Window *window, xcb_timestamp_t timestamp); bool allowFullClientRaising(const Window *window, uint32_t timestamp);
void blockStackingUpdates(bool block); void blockStackingUpdates(bool block);
void updateToolWindows(bool also_hide); void updateToolWindows(bool also_hide);
void fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geom);
void saveOldScreenSizes(); void saveOldScreenSizes();
void addToStack(Window *window); void addToStack(Window *window);
void removeFromStack(Window *window); void removeFromStack(Window *window);
#if KWIN_BUILD_X11
void initializeX11();
void cleanupX11();
void propagateWindows(bool propagate_new_windows); // Called only from updateStackingOrder
void fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geom);
/// This is the right way to create a new X11 window /// This is the right way to create a new X11 window
X11Window *createX11Window(xcb_window_t windowId, bool is_mapped); X11Window *createX11Window(xcb_window_t windowId, bool is_mapped);
void addX11Window(X11Window *c); void addX11Window(X11Window *c);
void setupWindowConnections(Window *window);
X11Window *createUnmanaged(xcb_window_t windowId); X11Window *createUnmanaged(xcb_window_t windowId);
void addUnmanaged(X11Window *c); void addUnmanaged(X11Window *c);
void updateXStackingOrder();
#endif
void setupWindowConnections(Window *window);
void addWaylandWindow(Window *window); void addWaylandWindow(Window *window);
void removeWaylandWindow(Window *window); void removeWaylandWindow(Window *window);
@ -632,7 +652,6 @@ private:
Window *m_activePopupWindow; Window *m_activePopupWindow;
int m_initialDesktop; int m_initialDesktop;
void updateXStackingOrder();
void updateTabbox(); void updateTabbox();
QList<Output *> m_outputs; QList<Output *> m_outputs;
@ -654,7 +673,6 @@ private:
QList<Window *> unconstrained_stacking_order; // Topmost last QList<Window *> unconstrained_stacking_order; // Topmost last
QList<Window *> stacking_order; // Topmost last QList<Window *> stacking_order; // Topmost last
QList<xcb_window_t> manual_overlays; // Topmost last
bool force_restacking; bool force_restacking;
QList<Window *> should_get_focus; // Last is most recent QList<Window *> should_get_focus; // Last is most recent
QList<Window *> attention_chain; QList<Window *> attention_chain;
@ -664,7 +682,13 @@ private:
QList<Group *> groups; QList<Group *> groups;
bool was_user_interaction; bool was_user_interaction;
#if KWIN_BUILD_X11
QList<xcb_window_t> manual_overlays; // Topmost last
std::unique_ptr<X11EventFilter> m_wasUserInteractionFilter; std::unique_ptr<X11EventFilter> m_wasUserInteractionFilter;
std::unique_ptr<Xcb::Window> m_nullFocus;
std::unique_ptr<X11EventFilter> m_movingClientFilter;
std::unique_ptr<X11EventFilter> m_syncAlarmFilter;
#endif
int block_focus; int block_focus;
@ -686,9 +710,9 @@ private:
QTimer updateToolWindowsTimer; QTimer updateToolWindowsTimer;
static Workspace *_self; static Workspace *_self;
#if KWIN_BUILD_X11
std::unique_ptr<KStartupInfo> m_startup; std::unique_ptr<KStartupInfo> m_startup;
#endif
QHash<const VirtualDesktop *, QRectF> m_workAreas; QHash<const VirtualDesktop *, QRectF> m_workAreas;
QHash<const VirtualDesktop *, StrutRects> m_restrictedAreas; QHash<const VirtualDesktop *, StrutRects> m_restrictedAreas;
QHash<const VirtualDesktop *, QHash<const Output *, QRectF>> m_screenAreas; QHash<const VirtualDesktop *, QHash<const Output *, QRectF>> m_screenAreas;
@ -701,12 +725,9 @@ private:
int m_setActiveWindowRecursion = 0; int m_setActiveWindowRecursion = 0;
int m_blockStackingUpdates = 0; // When > 0, stacking updates are temporarily disabled int m_blockStackingUpdates = 0; // When > 0, stacking updates are temporarily disabled
bool m_blockedPropagatingNewWindows; // Propagate also new windows after enabling stacking updates? bool m_blockedPropagatingNewWindows; // Propagate also new windows after enabling stacking updates?
std::unique_ptr<Xcb::Window> m_nullFocus;
friend class StackingUpdatesBlocker; friend class StackingUpdatesBlocker;
std::unique_ptr<KillWindow> m_windowKiller; std::unique_ptr<KillWindow> m_windowKiller;
std::unique_ptr<X11EventFilter> m_movingClientFilter;
std::unique_ptr<X11EventFilter> m_syncAlarmFilter;
SessionManager *m_sessionManager; SessionManager *m_sessionManager;
std::unique_ptr<FocusChain> m_focusChain; std::unique_ptr<FocusChain> m_focusChain;
@ -775,6 +796,7 @@ inline Window *Workspace::mostRecentlyActivatedWindow() const
return should_get_focus.count() > 0 ? should_get_focus.last() : m_activeWindow; return should_get_focus.count() > 0 ? should_get_focus.last() : m_activeWindow;
} }
#if KWIN_BUILD_X11
inline void Workspace::addGroup(Group *group) inline void Workspace::addGroup(Group *group)
{ {
Q_EMIT groupAdded(group); Q_EMIT groupAdded(group);
@ -785,6 +807,7 @@ inline void Workspace::removeGroup(Group *group)
{ {
groups.removeAll(group); groups.removeAll(group);
} }
#endif
inline const QList<Window *> &Workspace::stackingOrder() const inline const QList<Window *> &Workspace::stackingOrder() const
{ {

View file

@ -5182,6 +5182,388 @@ void X11Window::getSkipCloseAnimation()
readSkipCloseAnimation(property); readSkipCloseAnimation(property);
} }
//********************************************
// Client
//********************************************
/**
* Updates the user time (time of last action in the active window).
* This is called inside kwin for every action with the window
* that qualifies for user interaction (clicking on it, activate it
* externally, etc.).
*/
void X11Window::updateUserTime(xcb_timestamp_t time)
{
// copied in Group::updateUserTime
if (time == XCB_TIME_CURRENT_TIME) {
kwinApp()->updateXTime();
time = xTime();
}
if (time != -1U
&& (m_userTime == XCB_TIME_CURRENT_TIME
|| NET::timestampCompare(time, m_userTime) > 0)) { // time > user_time
m_userTime = time;
shade_below = nullptr; // do not hover re-shade a window after it got interaction
}
group()->updateUserTime(m_userTime);
}
xcb_timestamp_t X11Window::readUserCreationTime() const
{
Xcb::Property prop(false, window(), atoms->kde_net_wm_user_creation_time, XCB_ATOM_CARDINAL, 0, 1);
return prop.value<xcb_timestamp_t>(-1);
}
xcb_timestamp_t X11Window::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data,
bool session) const
{
xcb_timestamp_t time = info->userTime();
// qDebug() << "User timestamp, initial:" << time;
//^^ this deadlocks kwin --replace sometimes.
// newer ASN timestamp always replaces user timestamp, unless user timestamp is 0
// helps e.g. with konqy reusing
if (asn_data != nullptr && time != 0) {
if (asn_id->timestamp() != 0
&& (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) {
time = asn_id->timestamp();
}
}
qCDebug(KWIN_CORE) << "User timestamp, ASN:" << time;
if (time == -1U) {
// The window doesn't have any timestamp.
// If it's the first window for its application
// (i.e. there's no other window from the same app),
// use the _KDE_NET_WM_USER_CREATION_TIME trick.
// Otherwise, refuse activation of a window
// from already running application if this application
// is not the active one (unless focus stealing prevention is turned off).
X11Window *act = dynamic_cast<X11Window *>(workspace()->mostRecentlyActivatedWindow());
if (act != nullptr && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) {
bool first_window = true;
auto sameApplicationActiveHackPredicate = [this](const X11Window *cl) {
// ignore already existing splashes, toolbars, utilities and menus,
// as the app may show those before the main window
return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
&& cl != this && X11Window::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive);
};
if (isTransient()) {
auto clientMainClients = [this]() {
QList<X11Window *> ret;
const auto mcs = mainWindows();
for (auto mc : mcs) {
if (X11Window *c = dynamic_cast<X11Window *>(mc)) {
ret << c;
}
}
return ret;
};
if (act->hasTransient(this, true)) {
; // is transient for currently active window, even though it's not
// the same app (e.g. kcookiejar dialog) -> allow activation
} else if (groupTransient() && findInList<X11Window, X11Window>(clientMainClients(), sameApplicationActiveHackPredicate) == nullptr) {
; // standalone transient
} else {
first_window = false;
}
} else {
#if KWIN_BUILD_X11
if (workspace()->findClient(sameApplicationActiveHackPredicate)) {
first_window = false;
}
#endif
}
// don't refuse if focus stealing prevention is turned off
if (!first_window && rules()->checkFSP(options->focusStealingPreventionLevel()) > 0) {
qCDebug(KWIN_CORE) << "User timestamp, already exists:" << 0;
return 0; // refuse activation
}
}
// Creation time would just mess things up during session startup,
// as possibly many apps are started up at the same time.
// If there's no active window yet, no timestamp will be needed,
// as plain Workspace::allowWindowActivation() will return true
// in such case. And if there's already active window,
// it's better not to activate the new one.
// Unless it was the active window at the time
// of session saving and there was no user interaction yet,
// this check will be done in manage().
if (session) {
return -1U;
}
time = readUserCreationTime();
}
qCDebug(KWIN_CORE) << "User timestamp, final:" << this << ":" << time;
return time;
}
xcb_timestamp_t X11Window::userTime() const
{
xcb_timestamp_t time = m_userTime;
if (time == 0) { // doesn't want focus after showing
return 0;
}
Q_ASSERT(group() != nullptr);
if (time == -1U
|| (group()->userTime() != -1U
&& NET::timestampCompare(group()->userTime(), time) > 0)) {
time = group()->userTime();
}
return time;
}
void X11Window::doSetActive()
{
updateUrgency(); // demand attention again if it's still urgent
info->setState(isActive() ? NET::Focused : NET::States(), NET::Focused);
}
void X11Window::startupIdChanged()
{
KStartupInfoId asn_id;
KStartupInfoData asn_data;
bool asn_valid = workspace()->checkStartupNotification(window(), asn_id, asn_data);
if (!asn_valid) {
return;
}
// If the ASN contains desktop, move it to the desktop, otherwise move it to the current
// desktop (since the new ASN should make the window act like if it's a new application
// launched). However don't affect the window's desktop if it's set to be on all desktops.
if (asn_data.desktop() != 0 && !isOnAllDesktops()) {
if (asn_data.desktop() == -1) {
workspace()->sendWindowToDesktops(this, {}, true);
} else {
if (VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(asn_data.desktop())) {
workspace()->sendWindowToDesktops(this, {desktop}, true);
}
}
}
if (asn_data.xinerama() != -1) {
Output *output = workspace()->xineramaIndexToOutput(asn_data.xinerama());
if (output) {
workspace()->sendWindowToOutput(this, output);
}
}
const xcb_timestamp_t timestamp = asn_id.timestamp();
if (timestamp != 0) {
bool activate = allowWindowActivation(timestamp);
if (activate) {
workspace()->activateWindow(this);
} else {
demandAttention();
}
}
}
void X11Window::updateUrgency()
{
if (info->urgency()) {
demandAttention();
}
}
namespace FSP
{
enum Level {
None = 0,
Low,
Medium,
High,
Extreme,
};
}
// focus_in -> the window got FocusIn event
bool X11Window::allowWindowActivation(xcb_timestamp_t time, bool focus_in)
{
auto window = this;
// options->focusStealingPreventionLevel :
// 0 - none - old KWin behaviour, new windows always get focus
// 1 - low - focus stealing prevention is applied normally, when unsure, activation is allowed
// 2 - normal - focus stealing prevention is applied normally, when unsure, activation is not allowed,
// this is the default
// 3 - high - new window gets focus only if it belongs to the active application,
// or when no window is currently active
// 4 - extreme - no window gets focus without user intervention
if (time == -1U) {
time = window->userTime();
}
const FSP::Level level = (FSP::Level)window->rules()->checkFSP(options->focusStealingPreventionLevel());
if (workspace()->sessionManager()->state() == SessionState::Saving && level <= FSP::Medium) { // <= normal
return true;
}
Window *ac = workspace()->mostRecentlyActivatedWindow();
if (focus_in) {
if (workspace()->inShouldGetFocus(window)) {
return true; // FocusIn was result of KWin's action
}
// Before getting FocusIn, the active Client already
// got FocusOut, and therefore got deactivated.
ac = workspace()->lastActiveWindow();
}
if (time == 0) { // explicitly asked not to get focus
if (!window->rules()->checkAcceptFocus(false)) {
return false;
}
}
const FSP::Level protection = (FSP::Level)(ac ? ac->rules()->checkFPP(2) : FSP::None);
// stealing is unconditionally allowed (NETWM behavior)
if (level == FSP::None || protection == FSP::None) {
return true;
}
// The active window "grabs" the focus or stealing is generally forbidden
if (level == FSP::Extreme || protection == FSP::Extreme) {
return false;
}
// No active window, it's ok to pass focus
// NOTICE that extreme protection needs to be handled before to allow protection on unmanged windows
if (ac == nullptr || ac->isDesktop()) {
qCDebug(KWIN_CORE) << "Activation: No window active, allowing";
return true; // no active window -> always allow
}
// TODO window urgency -> return true?
// Unconditionally allow intra-window passing around for lower stealing protections
// unless the active window has High interest
if (Window::belongToSameApplication(window, ac, Window::SameApplicationCheck::RelaxedForActive) && protection < FSP::High) {
qCDebug(KWIN_CORE) << "Activation: Belongs to active application";
return true;
}
// High FPS, not intr-window change. Only allow if the active window has only minor interest
if (level > FSP::Medium && protection > FSP::Low) {
return false;
}
if (time == -1U) { // no time known
qCDebug(KWIN_CORE) << "Activation: No timestamp at all";
// Only allow for Low protection unless active window has High interest in focus
if (level < FSP::Medium && protection < FSP::High) {
return true;
}
// no timestamp at all, don't activate - because there's also creation timestamp
// done on CreateNotify, this case should happen only in case application
// maps again already used window, i.e. this won't happen after app startup
return false;
}
// Low or medium FSP, usertime comparism is possible
const xcb_timestamp_t user_time = ac->userTime();
qCDebug(KWIN_CORE) << "Activation, compared:" << window << ":" << time << ":" << user_time
<< ":" << (NET::timestampCompare(time, user_time) >= 0);
return NET::timestampCompare(time, user_time) >= 0; // time >= user_time
}
void X11Window::restackWindow(xcb_window_t above, int detail, NET::RequestSource src, xcb_timestamp_t timestamp, bool send_event)
{
X11Window *other = nullptr;
if (detail == XCB_STACK_MODE_OPPOSITE) {
other = workspace()->findClient(Predicate::WindowMatch, above);
if (!other) {
workspace()->raiseOrLowerWindow(this);
return;
}
auto it = workspace()->stackingOrder().constBegin(),
end = workspace()->stackingOrder().constEnd();
while (it != end) {
if (*it == this) {
detail = XCB_STACK_MODE_ABOVE;
break;
} else if (*it == other) {
detail = XCB_STACK_MODE_BELOW;
break;
}
++it;
}
} else if (detail == XCB_STACK_MODE_TOP_IF) {
other = workspace()->findClient(Predicate::WindowMatch, above);
if (other && other->frameGeometry().intersects(frameGeometry())) {
workspace()->raiseWindowRequest(this, src, timestamp);
}
return;
} else if (detail == XCB_STACK_MODE_BOTTOM_IF) {
other = workspace()->findClient(Predicate::WindowMatch, above);
if (other && other->frameGeometry().intersects(frameGeometry())) {
workspace()->lowerWindowRequest(this, src, timestamp);
}
return;
}
if (!other) {
other = workspace()->findClient(Predicate::WindowMatch, above);
}
if (other && detail == XCB_STACK_MODE_ABOVE) {
auto it = workspace()->stackingOrder().constEnd(),
begin = workspace()->stackingOrder().constBegin();
while (--it != begin) {
if (*it == other) { // the other one is top on stack
it = begin; // invalidate
src = NET::FromTool; // force
break;
}
X11Window *window = qobject_cast<X11Window *>(*it);
if (!window || !((*it)->isNormalWindow() && window->isShown() && (*it)->isOnCurrentDesktop() && (*it)->isOnCurrentActivity() && (*it)->isOnOutput(output()))) {
continue; // irrelevant windows
}
if (*(it - 1) == other) {
break; // "it" is the one above the target one, stack below "it"
}
}
if (it != begin && (*(it - 1) == other)) {
other = qobject_cast<X11Window *>(*it);
} else {
other = nullptr;
}
}
if (other) {
workspace()->restack(this, other);
} else if (detail == XCB_STACK_MODE_BELOW) {
workspace()->lowerWindowRequest(this, src, timestamp);
} else if (detail == XCB_STACK_MODE_ABOVE) {
workspace()->raiseWindowRequest(this, src, timestamp);
}
if (send_event) {
sendSyntheticConfigureNotify();
}
}
bool X11Window::belongsToDesktop() const
{
const auto members = group()->members();
for (const X11Window *window : members) {
if (window->isDesktop()) {
return true;
}
}
return false;
}
void X11Window::setShortcutInternal()
{
updateCaption();
#if 0
workspace()->windowShortcutUpdated(this);
#else
// Workaround for kwin<->kglobalaccel deadlock, when KWin has X grab and the kded
// kglobalaccel module tries to create the key grab. KWin should preferably grab
// they keys itself anyway :(.
QTimer::singleShot(0, this, std::bind(&Workspace::windowShortcutUpdated, workspace(), this));
#endif
}
} // namespace } // namespace
#include "moc_x11window.cpp" #include "moc_x11window.cpp"

View file

@ -9,6 +9,11 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
// kwin // kwin
#include "scene/decorationitem.h" #include "scene/decorationitem.h"

View file

@ -9,6 +9,12 @@
*/ */
#pragma once #pragma once
#include "config-kwin.h"
#if !KWIN_BUILD_X11
#error Do not include on non-X11 builds
#endif
#include <memory> #include <memory>
#include "xwayland_interface.h" #include "xwayland_interface.h"

View file

@ -1,18 +1,20 @@
set(normalhintsbasesizetest_SRCS normalhintsbasesizetest.cpp) if(KWIN_BUILD_X11)
add_executable(normalhintsbasesizetest ${normalhintsbasesizetest_SRCS}) set(normalhintsbasesizetest_SRCS normalhintsbasesizetest.cpp)
target_link_libraries(normalhintsbasesizetest XCB::XCB XCB::ICCCM KF6::WindowSystem) add_executable(normalhintsbasesizetest ${normalhintsbasesizetest_SRCS})
target_link_libraries(normalhintsbasesizetest XCB::XCB XCB::ICCCM KF6::WindowSystem)
# next target # next target
set(screenedgeshowtest_SRCS screenedgeshowtest.cpp) set(screenedgeshowtest_SRCS screenedgeshowtest.cpp)
add_executable(screenedgeshowtest ${screenedgeshowtest_SRCS}) add_executable(screenedgeshowtest ${screenedgeshowtest_SRCS})
target_link_libraries(screenedgeshowtest Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem Plasma::KWaylandClient ${XCB_XCB_LIBRARY}) target_link_libraries(screenedgeshowtest Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem Plasma::KWaylandClient ${XCB_XCB_LIBRARY})
add_executable(x11shadowreader x11shadowreader.cpp) add_executable(x11shadowreader x11shadowreader.cpp)
target_link_libraries(x11shadowreader XCB::XCB Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem) target_link_libraries(x11shadowreader XCB::XCB Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem)
add_executable(pointerconstraints pointerconstraintstest.cpp) add_executable(pointerconstraints pointerconstraintstest.cpp)
add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}") add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(pointerconstraints XCB::XCB Qt::Gui Qt::Quick Plasma::KWaylandClient) target_link_libraries(pointerconstraints XCB::XCB Qt::Gui Qt::Quick Plasma::KWaylandClient)
endif()
add_executable(pointergestures pointergesturestest.cpp) add_executable(pointergestures pointergesturestest.cpp)
add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}") add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}")