diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a991ec95d7..f01bfc78e3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,4 +11,4 @@ suse_tumbleweed_qt66_reduced_featureset: extends: suse_tumbleweed_qt66 script: - 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index f2d1c6b03c..a5198479a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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_SCREENLOCKER "Enable building of KWin lockscreen 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 Concurrent @@ -232,8 +233,58 @@ else() set(HAVE_XKBCOMMON_NO_SECURE_GETENV 0) endif() -pkg_check_modules(XKBX11 IMPORTED_TARGET xkbcommon-x11 REQUIRED) -add_feature_info(XKBX11 XKBX11_FOUND "Required for handling keyboard events in X11 backend") +if (KWIN_BUILD_X11) + 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) 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" ) -# 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) set_package_properties(Freetype PROPERTIES DESCRIPTION "A font rendering engine" @@ -324,15 +346,6 @@ set_package_properties(Fontconfig PROPERTIES 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) set_package_properties(Libcap PROPERTIES 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) 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) add_feature_info("SCHED_RESET_ON_FORK" HAVE_SCHED_RESET_ON_FORK diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index a171968333..2e8de476cc 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -45,82 +45,97 @@ ecm_mark_as_test(testVirtualDesktops) ######################################################## # Test ClientMachine ######################################################## -set(testClientMachine_SRCS - ../src/client_machine.cpp - test_client_machine.cpp - xcb_scaling_mock.cpp -) -add_executable(testClientMachine ${testClientMachine_SRCS}) -set_target_properties(testClientMachine PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") +if(KWIN_BUILD_X11) + set(testClientMachine_SRCS + ../src/client_machine.cpp + test_client_machine.cpp + xcb_scaling_mock.cpp + ) + add_executable(testClientMachine ${testClientMachine_SRCS}) + set_target_properties(testClientMachine PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") -target_link_libraries(testClientMachine - Qt::Concurrent - Qt::GuiPrivate - Qt::Test - Qt::Widgets + target_link_libraries(testClientMachine + Qt::Concurrent + Qt::GuiPrivate + Qt::Test + Qt::Widgets - KF6::ConfigCore - KF6::WindowSystem + KF6::ConfigCore + KF6::WindowSystem - XCB::XCB - XCB::XFIXES + XCB::XCB + XCB::XFIXES - ${X11_X11_LIB} # to make jenkins happy -) -add_test(NAME kwin-testClientMachine COMMAND testClientMachine) -ecm_mark_as_test(testClientMachine) + ${X11_X11_LIB} # to make jenkins happy + ) + add_test(NAME kwin-testClientMachine COMMAND testClientMachine) + ecm_mark_as_test(testClientMachine) -######################################################## -# Test XcbWrapper -######################################################## -add_executable(testXcbWrapper test_xcb_wrapper.cpp xcb_scaling_mock.cpp) + ######################################################## + # Test XcbWrapper + ######################################################## + add_executable(testXcbWrapper test_xcb_wrapper.cpp xcb_scaling_mock.cpp) -target_link_libraries(testXcbWrapper - Qt::GuiPrivate - Qt::Test - Qt::Widgets + target_link_libraries(testXcbWrapper + Qt::GuiPrivate + Qt::Test + Qt::Widgets - KF6::ConfigCore - KF6::WindowSystem + KF6::ConfigCore + KF6::WindowSystem - XCB::XCB -) -add_test(NAME kwin-testXcbWrapper COMMAND testXcbWrapper) -ecm_mark_as_test(testXcbWrapper) + XCB::XCB + ) + add_test(NAME kwin-testXcbWrapper COMMAND testXcbWrapper) + ecm_mark_as_test(testXcbWrapper) -add_executable(testXcbSizeHints test_xcb_size_hints.cpp xcb_scaling_mock.cpp) -set_target_properties(testXcbSizeHints PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") -target_link_libraries(testXcbSizeHints - Qt::GuiPrivate - Qt::Test - Qt::Widgets + add_executable(testXcbSizeHints test_xcb_size_hints.cpp xcb_scaling_mock.cpp) + set_target_properties(testXcbSizeHints PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WINDOW") + target_link_libraries(testXcbSizeHints + Qt::GuiPrivate + Qt::Test + Qt::Widgets - KF6::ConfigCore - KF6::WindowSystem + KF6::ConfigCore + KF6::WindowSystem - XCB::ICCCM - XCB::XCB -) -add_test(NAME kwin-testXcbSizeHints COMMAND testXcbSizeHints) -ecm_mark_as_test(testXcbSizeHints) + XCB::ICCCM + XCB::XCB + ) + add_test(NAME kwin-testXcbSizeHints COMMAND testXcbSizeHints) + ecm_mark_as_test(testXcbSizeHints) -######################################################## -# Test XcbWindow -######################################################## -add_executable(testXcbWindow test_xcb_window.cpp xcb_scaling_mock.cpp) + ######################################################## + # Test XcbWindow + ######################################################## + add_executable(testXcbWindow test_xcb_window.cpp xcb_scaling_mock.cpp) -target_link_libraries(testXcbWindow - Qt::GuiPrivate - Qt::Test - Qt::Widgets + target_link_libraries(testXcbWindow + Qt::GuiPrivate + Qt::Test + Qt::Widgets - KF6::ConfigCore - KF6::WindowSystem + KF6::ConfigCore + KF6::WindowSystem - XCB::XCB -) -add_test(NAME kwin-testXcbWindow COMMAND testXcbWindow) -ecm_mark_as_test(testXcbWindow) + XCB::XCB + ) + add_test(NAME kwin-testXcbWindow COMMAND 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 @@ -161,19 +176,6 @@ target_link_libraries(testGestures add_test(NAME kwin-testGestures COMMAND 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 ../src/opengl/abstract_opengl_context_attribute_builder.cpp ../src/opengl/egl_context_attribute_builder.cpp diff --git a/autotests/drm/CMakeLists.txt b/autotests/drm/CMakeLists.txt index 1772fa3b55..d1941fe90a 100644 --- a/autotests/drm/CMakeLists.txt +++ b/autotests/drm/CMakeLists.txt @@ -39,7 +39,6 @@ target_link_libraries(LibDrmTest KF6::WindowSystem KF6::CoreAddons KF6::I18n - XCB::XCB PkgConfig::Libxcvt gbm::gbm Libdrm::Libdrm diff --git a/autotests/effect/CMakeLists.txt b/autotests/effect/CMakeLists.txt index aa697d8fd5..b0e1e6181f 100644 --- a/autotests/effect/CMakeLists.txt +++ b/autotests/effect/CMakeLists.txt @@ -14,7 +14,10 @@ kwineffects_unit_tests( 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) -target_link_libraries(kwinglplatformtest Qt::Test Qt::Gui KF6::ConfigCore XCB::XCB) -ecm_mark_as_test(kwinglplatformtest) + +if (KWIN_BUILD_X11 AND ARGS_LIBS MATCHES .*XCB.*) + 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) + target_link_libraries(kwinglplatformtest Qt::Test Qt::Gui KF6::ConfigCore XCB::XCB) + ecm_mark_as_test(kwinglplatformtest) +endif() diff --git a/autotests/integration/CMakeLists.txt b/autotests/integration/CMakeLists.txt index 80255f6ef4..b31999f9f2 100644 --- a/autotests/integration/CMakeLists.txt +++ b/autotests/integration/CMakeLists.txt @@ -33,20 +33,21 @@ target_sources(KWinIntegrationTestFramework PRIVATE target_link_libraries(KWinIntegrationTestFramework PUBLIC Qt::Test + Qt::Concurrent Plasma::KWaylandClient Wayland::Client Libdrm::Libdrm kwin PRIVATE - # Own libraries - KWinXwaylandServerModule - # Static plugins KWinQpaPlugin KF6WindowSystemKWinPlugin KF6IdleTimeKWinPlugin ) +if(KWIN_BUILD_X11) + target_link_libraries(KWinIntegrationTestFramework PRIVATE KWinXwaylandServerModule) +endif() if(TARGET KF6GlobalAccelKWinPlugin) target_link_libraries(KWinIntegrationTestFramework PUBLIC KF6GlobalAccelKWinPlugin) endif() @@ -60,6 +61,9 @@ function(integrationTest) set(oneValueArgs NAME) set(multiValueArgs SRCS LIBS) 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}) target_link_libraries(${ARGS_NAME} KWinIntegrationTestFramework Qt::Test ${ARGS_LIBS}) if(${ARGS_BUILTIN_EFFECTS}) @@ -67,8 +71,9 @@ function(integrationTest) endif() add_test(NAME kwin-${ARGS_NAME} COMMAND dbus-run-session ${CMAKE_BINARY_DIR}/bin/${ARGS_NAME}) endfunction() - -integrationTest(NAME testDontCrashGlxgears SRCS dont_crash_glxgears.cpp LIBS KF6::I18n KDecoration2::KDecoration) +if(KWIN_BUILD_X11) + integrationTest(NAME testDontCrashGlxgears SRCS dont_crash_glxgears.cpp LIBS KF6::I18n KDecoration2::KDecoration) +endif() if (KWIN_BUILD_SCREENLOCKER) integrationTest(NAME testLockScreen SRCS lockscreen.cpp LIBS KF6::GlobalAccel) 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 testTransientPlacement SRCS transient_placement.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 testMaximized SRCS maximize_test.cpp LIBS KDecoration2::KDecoration KF6::Package) 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 testSceneOpenGLES SRCS scene_opengl_es_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 testSecurityContext SRCS security_context_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) integrationTest(NAME testVirtualKeyboardDBus SRCS test_virtualkeyboard_dbus.cpp ${DBUS_SRCS}) diff --git a/autotests/integration/debug_console_test.cpp b/autotests/integration/debug_console_test.cpp index 3e35b93c7f..a17b13b15a 100644 --- a/autotests/integration/debug_console_test.cpp +++ b/autotests/integration/debug_console_test.cpp @@ -11,11 +11,14 @@ #include "core/output.h" #include "debug_console.h" #include "internalwindow.h" -#include "utils/xcbutils.h" #include "wayland_server.h" #include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 +#include "utils/xcbutils.h" +#endif + #include #include #include @@ -38,8 +41,10 @@ private Q_SLOTS: void cleanup(); void topLevelTest_data(); void topLevelTest(); +#if KWIN_BUILD_X11 void testX11Window(); void testX11Unmanaged(); +#endif void testWaylandClient(); void testInternalWindow(); void testClosingDebugConsole(); @@ -109,6 +114,7 @@ void DebugConsoleTest::topLevelTest() } } +#if KWIN_BUILD_X11 void DebugConsoleTest::testX11Window() { DebugConsoleModel model; @@ -281,6 +287,7 @@ void DebugConsoleTest::testX11Unmanaged() QVERIFY(!model.hasChildren(unmanagedTopLevelIndex)); QVERIFY(!model2.hasChildren(model2.index(1, 0, QModelIndex()))); } +#endif void DebugConsoleTest::testWaylandClient() { diff --git a/autotests/integration/dont_crash_cancel_animation.cpp b/autotests/integration/dont_crash_cancel_animation.cpp index 14a0ee8822..dfe87c3e41 100644 --- a/autotests/integration/dont_crash_cancel_animation.cpp +++ b/autotests/integration/dont_crash_cancel_animation.cpp @@ -15,7 +15,9 @@ #include "wayland_server.h" #include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif #include diff --git a/autotests/integration/kwin_wayland_test.cpp b/autotests/integration/kwin_wayland_test.cpp index b3f6e65b93..aac04b0d3d 100644 --- a/autotests/integration/kwin_wayland_test.cpp +++ b/autotests/integration/kwin_wayland_test.cpp @@ -15,11 +15,14 @@ #include "inputmethod.h" #include "placement.h" #include "pluginmanager.h" -#include "utils/xcbutils.h" #include "wayland_server.h" #include "workspace.h" + +#if KWIN_BUILD_X11 +#include "utils/xcbutils.h" #include "xwayland/xwayland.h" #include "xwayland/xwaylandlauncher.h" +#endif #include @@ -99,7 +102,9 @@ WaylandTestApplication::~WaylandTestApplication() if (effects) { effects->unloadAllEffects(); } +#if KWIN_BUILD_X11 m_xwayland.reset(); +#endif destroyVirtualInputDevices(); destroyColorManager(); destroyWorkspace(); @@ -179,10 +184,12 @@ void WaylandTestApplication::continueStartupWithScene() qFatal("Failed to initialize the Wayland server, exiting now"); } +#if KWIN_BUILD_X11 if (operationMode() == OperationModeXwayland) { m_xwayland = std::make_unique(this); m_xwayland->init(); } +#endif notifyStarted(); } @@ -202,10 +209,12 @@ Test::VirtualInputDevice *WaylandTestApplication::virtualTouch() const return m_virtualTouch.get(); } +#if KWIN_BUILD_X11 XwaylandInterface *WaylandTestApplication::xwayland() const { return m_xwayland.get(); } +#endif Test::FractionalScaleManagerV1::~FractionalScaleManagerV1() { diff --git a/autotests/integration/kwin_wayland_test.h b/autotests/integration/kwin_wayland_test.h index 7588176638..199eea9ea7 100644 --- a/autotests/integration/kwin_wayland_test.h +++ b/autotests/integration/kwin_wayland_test.h @@ -68,10 +68,12 @@ class ScreencastingV1; namespace KWin { +#if KWIN_BUILD_X11 namespace Xwl { class Xwayland; } +#endif namespace Test { @@ -93,7 +95,9 @@ public: Test::VirtualInputDevice *virtualPointer() const; Test::VirtualInputDevice *virtualKeyboard() const; Test::VirtualInputDevice *virtualTouch() const; +#if KWIN_BUILD_X11 XwaylandInterface *xwayland() const override; +#endif protected: void performStartup() override; @@ -104,8 +108,9 @@ private: void createVirtualInputDevices(); void destroyVirtualInputDevices(); - +#if KWIN_BUILD_X11 std::unique_ptr m_xwayland; +#endif QString m_inputMethodServerToStart; std::unique_ptr m_virtualPointer; @@ -766,13 +771,14 @@ bool renderNodeAvailable(); * with X on demand */ +#if KWIN_BUILD_X11 struct XcbConnectionDeleter { void operator()(xcb_connection_t *pointer); }; - typedef std::unique_ptr XcbConnectionPtr; XcbConnectionPtr createX11Connection(); +#endif MockInputMethod *inputMethod(); KWayland::Client::Surface *inputPanelSurface(); diff --git a/autotests/integration/test_helpers.cpp b/autotests/integration/test_helpers.cpp index 9c6fff8736..7dd55f8592 100644 --- a/autotests/integration/test_helpers.cpp +++ b/autotests/integration/test_helpers.cpp @@ -1183,6 +1183,7 @@ bool renderNodeAvailable() }); } +#if KWIN_BUILD_X11 void XcbConnectionDeleter::operator()(xcb_connection_t *pointer) { xcb_disconnect(pointer); @@ -1200,6 +1201,7 @@ Test::XcbConnectionPtr createX11Connection() e.exec(); return Test::XcbConnectionPtr(future.result()); } +#endif WaylandOutputManagementV2::WaylandOutputManagementV2(struct ::wl_registry *registry, int id, int version) : QObject() diff --git a/autotests/integration/virtual_desktop_test.cpp b/autotests/integration/virtual_desktop_test.cpp index 1ea6457306..3a08fd191b 100644 --- a/autotests/integration/virtual_desktop_test.cpp +++ b/autotests/integration/virtual_desktop_test.cpp @@ -9,12 +9,15 @@ #include "kwin_wayland_test.h" #include "main.h" -#include "utils/xcbutils.h" #include "virtualdesktops.h" #include "wayland_server.h" #include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 +#include "utils/xcbutils.h" +#endif + #include using namespace KWin; @@ -28,8 +31,9 @@ private Q_SLOTS: void initTestCase(); void init(); void cleanup(); - +#if KWIN_BUILD_X11 void testNetCurrentDesktop(); +#endif void testLastDesktopRemoved(); void testWindowOnMultipleDesktops(); void testRemoveDesktopWithWindow(); @@ -52,6 +56,7 @@ void VirtualDesktopTest::initTestCase() kwinApp()->start(); QVERIFY(applicationStartedSpy.wait()); +#if KWIN_BUILD_X11 if (kwinApp()->x11Connection()) { // verify the current desktop x11 property on startup, see BUG: 391034 Xcb::Atom currentDesktopAtom("_NET_CURRENT_DESKTOP"); @@ -61,6 +66,7 @@ void VirtualDesktopTest::initTestCase() QCOMPARE(currentDesktop.value(0, &ok), 0); QVERIFY(ok); } +#endif } void VirtualDesktopTest::init() @@ -75,6 +81,7 @@ void VirtualDesktopTest::cleanup() Test::destroyWaylandConnection(); } +#if KWIN_BUILD_X11 void VirtualDesktopTest::testNetCurrentDesktop() { if (!kwinApp()->x11Connection()) { @@ -115,6 +122,7 @@ void VirtualDesktopTest::testNetCurrentDesktop() QCOMPARE(currentDesktop.value(0, &ok), 0); QVERIFY(ok); } +#endif void VirtualDesktopTest::testLastDesktopRemoved() { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb3d70105c..262973f7cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,13 +37,11 @@ target_sources(kwin PRIVATE 3rdparty/xcursor.c activation.cpp appmenu.cpp - atoms.cpp client_machine.cpp colors/colordevice.cpp colors/colormanager.cpp compositor.cpp compositor_wayland.cpp - compositor_x11.cpp core/colorlut.cpp core/colorlut3d.cpp core/colorpipelinestage.cpp @@ -96,11 +94,9 @@ target_sources(kwin PRIVATE effect/offscreenquickview.cpp effect/quickeffect.cpp effect/timeline.cpp - events.cpp focuschain.cpp ftrace.cpp gestures.cpp - group.cpp hide_cursor_spy.cpp idle_inhibition.cpp idledetector.cpp @@ -125,8 +121,6 @@ target_sources(kwin PRIVATE main.cpp modifier_only_shortcuts.cpp mousebuttons.cpp - moving_client_x11_filter.cpp - netinfo.cpp onscreennotification.cpp opengl/abstract_opengl_context_attribute_builder.cpp opengl/egl_context_attribute_builder.cpp @@ -160,7 +154,6 @@ target_sources(kwin PRIVATE pointer_input.cpp popup_input_filter.cpp resources.qrc - rootinfo_filter.cpp rulebooksettings.cpp rules.cpp scene/cursordelegate_opengl.cpp @@ -180,7 +173,6 @@ target_sources(kwin PRIVATE scene/surfaceitem.cpp scene/surfaceitem_internal.cpp scene/surfaceitem_wayland.cpp - scene/surfaceitem_x11.cpp scene/windowitem.cpp scene/workspacescene.cpp scene/workspacescene_opengl.cpp @@ -203,7 +195,6 @@ target_sources(kwin PRIVATE scripting/workspace_wrapper.cpp shadow.cpp sm.cpp - syncalarmx11filter.cpp tablet_input.cpp tabletmodemanager.cpp tiles/customtile.cpp @@ -216,16 +207,11 @@ target_sources(kwin PRIVATE virtualdesktops.cpp virtualdesktopsdbustypes.cpp virtualkeyboard_dbus.cpp - was_user_interaction_x11_filter.cpp wayland_server.cpp waylandshellintegration.cpp waylandwindow.cpp window.cpp - window_property_notify_x11_filter.cpp workspace.cpp - x11eventfilter.cpp - x11syncmanager.cpp - x11window.cpp xdgactivationv1.cpp xdgshellintegration.cpp xdgshellwindow.cpp @@ -260,21 +246,6 @@ target_link_libraries(kwin KDecoration2::KDecoration 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 XKB::XKB EGL::EGL @@ -290,6 +261,43 @@ if (TARGET K::KGlobalAccelD) target_link_libraries(kwin PRIVATE K::KGlobalAccelD) 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) target_link_libraries(kwin PRIVATE KF6::Notifications) endif() @@ -331,7 +339,10 @@ add_subdirectory(platformsupport) add_subdirectory(plugins) add_subdirectory(utils) add_subdirectory(wayland) -add_subdirectory(xwayland) + +if (KWIN_BUILD_X11) + add_subdirectory(xwayland) +endif() if (KWIN_BUILD_ACTIVITIES) target_sources(kwin PRIVATE activities.cpp) @@ -351,9 +362,12 @@ if (KWIN_BUILD_TABBOX) tabbox/tabbox_logging.cpp tabbox/tabboxconfig.cpp tabbox/tabboxhandler.cpp - tabbox/x11_filter.cpp ) add_subdirectory(tabbox/switchers) + + if (KWIN_BUILD_X11) + target_sources(kwin PRIVATE tabbox/x11_filter.cpp) + endif() endif() 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) -add_executable(kwin_x11 main_x11.cpp) -target_link_libraries(kwin_x11 - KWinX11Platform - kwin - KF6::GlobalAccel -) -target_compile_definitions(kwin_x11 PRIVATE - -DTRANSLATION_DOMAIN=\"kwin\" -) -kcoreaddons_target_static_plugins(kwin_x11 NAMESPACE "kwin/effects/plugins") +if (KWIN_BUILD_X11) + add_executable(kwin_x11 main_x11.cpp) + target_link_libraries(kwin_x11 + KWinX11Platform + kwin + KF6::GlobalAccel + ) + target_compile_definitions(kwin_x11 PRIVATE + -DTRANSLATION_DOMAIN=\"kwin\" + ) + 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_x11 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) add_executable(kwin_wayland main_wayland.cpp) @@ -391,9 +407,12 @@ endif() target_link_libraries(kwin_wayland kwin - KWinXwaylandServerModule KF6::Crash + KF6::I18n ) +if (KWIN_BUILD_X11) + target_link_libraries(kwin_wayland KWinXwaylandServerModule) +endif() target_compile_definitions(kwin_wayland PRIVATE -DTRANSLATION_DOMAIN=\"kwin\" ) @@ -446,12 +465,15 @@ install( 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 ${CMAKE_CURRENT_BINARY_DIR}/config-kwin.h ${CMAKE_CURRENT_BINARY_DIR}/kwin_export.h activities.h appmenu.h - atoms.h client_machine.h compositor.h cursor.h diff --git a/src/activation.cpp b/src/activation.cpp index 70e7b7595c..3cb138ef62 100644 --- a/src/activation.cpp +++ b/src/activation.cpp @@ -17,22 +17,26 @@ #include "cursor.h" #include "focuschain.h" -#include "netinfo.h" #include "workspace.h" -#include "x11window.h" #if KWIN_BUILD_ACTIVITIES #include "activities.h" #endif #include "virtualdesktops.h" -#include -#include -#include - +#if KWIN_BUILD_X11 #include "atoms.h" #include "group.h" +#include "netinfo.h" +#include "x11window.h" +#include +#endif + +#include +#include + #include "rules.h" #include "useractions.h" +#include "window.h" #include namespace KWin @@ -259,9 +263,11 @@ void Workspace::setActiveWindow(Window *window) updateStackingOrder(); // e.g. fullscreens have different layer when active/not-active +#if KWIN_BUILD_X11 if (rootInfo()) { rootInfo()->setActiveClient(m_activeWindow); } +#endif Q_EMIT windowActivated(m_activeWindow); --m_setActiveWindowRecursion; @@ -330,6 +336,7 @@ void Workspace::activateWindow(Window *window, bool force) requestFocus(window, force); } +#if KWIN_BUILD_X11 // 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 // 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 x11Window->updateUserTime(); } +#endif m_quickTileCombineTimer->stop(); } @@ -558,7 +566,7 @@ void Workspace::setShouldGetFocus(Window *window) // a window to be fully raised upon its own request (XRaiseWindow), // if refused, it will be raised only on top of windows belonging // 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()); 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 return false; } +#if KWIN_BUILD_X11 xcb_timestamp_t user_time = ac->userTime(); qCDebug(KWIN_CORE) << "Raising, compared:" << time << ":" << user_time << ":" << (NET::timestampCompare(time, user_time) >= 0); 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 // that was used by whoever caused the focus change, and therefore // the attempt to restore the focus would fail due to old timestamp +#if KWIN_BUILD_X11 kwinApp()->updateXTime(); +#endif if (should_get_focus.count() > 0) { return requestFocus(should_get_focus.last()); } 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(-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(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 ret; - const auto mcs = mainWindows(); - for (auto mc : mcs) { - if (X11Window *c = dynamic_cast(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(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 diff --git a/src/activities.cpp b/src/activities.cpp index 4ed8743392..59f4cbdae7 100644 --- a/src/activities.cpp +++ b/src/activities.cpp @@ -8,8 +8,11 @@ */ #include "activities.h" // KWin +#include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif // KDE #include // Qt @@ -173,6 +176,7 @@ void Activities::reallyStop(const QString &id) QSet saveSessionIds; QSet dontCloseSessionIds; +#if KWIN_BUILD_X11 const auto windows = ws->windows(); for (auto *const window : windows) { auto x11Window = qobject_cast(window); @@ -206,8 +210,8 @@ void Activities::reallyStop(const QString &id) } } } - ws->sessionManager()->storeSubSession(id, saveSessionIds); +#endif QStringList saveAndClose; QStringList saveOnly; diff --git a/src/appmenu.cpp b/src/appmenu.cpp index 5a5d7f3de1..5259d0d908 100644 --- a/src/appmenu.cpp +++ b/src/appmenu.cpp @@ -9,8 +9,8 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #include "appmenu.h" +#include "window.h" #include "workspace.h" -#include "x11window.h" #include #include diff --git a/src/appmenu.h b/src/appmenu.h index 55bdc149ae..3b81dfcfaa 100644 --- a/src/appmenu.h +++ b/src/appmenu.h @@ -11,8 +11,6 @@ #pragma once // Qt #include -// xcb -#include class QPoint; class OrgKdeKappmenuInterface; diff --git a/src/atoms.h b/src/atoms.h index 2f7e7bc59e..bef610afe3 100644 --- a/src/atoms.h +++ b/src/atoms.h @@ -11,6 +11,12 @@ #pragma once +#include "config-kwin.h" + +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif + #include "utils/xcbutils.h" namespace KWin diff --git a/src/backends/CMakeLists.txt b/src/backends/CMakeLists.txt index 93e19918db..e734828df5 100644 --- a/src/backends/CMakeLists.txt +++ b/src/backends/CMakeLists.txt @@ -3,4 +3,7 @@ add_subdirectory(fakeinput) add_subdirectory(libinput) add_subdirectory(virtual) add_subdirectory(wayland) -add_subdirectory(x11) + +if (KWIN_BUILD_X11) + add_subdirectory(x11) +endif() diff --git a/src/client_machine.cpp b/src/client_machine.cpp index 6f9bcda814..e75b659d08 100644 --- a/src/client_machine.cpp +++ b/src/client_machine.cpp @@ -8,11 +8,17 @@ */ // own #include "client_machine.h" -#include "effect/xcb.h" #include "main.h" #include "utils/common.h" + +#if KWIN_BUILD_X11 +#include "effect/xcb.h" +#endif + // KF5 +#if KWIN_BUILD_X11 #include +#endif // Qt #include #include @@ -167,6 +173,7 @@ ClientMachine::~ClientMachine() { } +#if KWIN_BUILD_X11 void ClientMachine::resolve(xcb_window_t window, xcb_window_t clientLeader) { if (m_resolved) { @@ -186,6 +193,7 @@ void ClientMachine::resolve(xcb_window_t window, xcb_window_t clientLeader) checkForLocalhost(); m_resolved = true; } +#endif void ClientMachine::checkForLocalhost() { diff --git a/src/client_machine.h b/src/client_machine.h index 55cca3d54e..a91dd7152d 100644 --- a/src/client_machine.h +++ b/src/client_machine.h @@ -8,9 +8,13 @@ */ #pragma once +#include "config-kwin.h" + #include #include +#if KWIN_BUILD_X11 #include +#endif // forward declaration struct addrinfo; @@ -57,7 +61,9 @@ public: explicit ClientMachine(QObject *parent = nullptr); ~ClientMachine() override; +#if KWIN_BUILD_X11 void resolve(xcb_window_t window, xcb_window_t clientLeader); +#endif const QString &hostName() const; bool isLocal() const; static QString localhost(); diff --git a/src/compositor.cpp b/src/compositor.cpp index 8d6bec576d..104e1206e6 100644 --- a/src/compositor.cpp +++ b/src/compositor.cpp @@ -45,14 +45,14 @@ Compositor *Compositor::self() Compositor::Compositor(QObject *workspace) : QObject(workspace) { +#if KWIN_BUILD_X11 // 2 sec which should be enough to restart the compositor. static const int compositorLostMessageDelay = 2000; - m_unusedSupportPropertyTimer.setInterval(compositorLostMessageDelay); m_unusedSupportPropertyTimer.setSingleShot(true); connect(&m_unusedSupportPropertyTimer, &QTimer::timeout, this, &Compositor::deleteUnusedSupportProperties); - +#endif // Delay the call to start by one event cycle. // The ctor of this class is invoked from the Workspace ctor, that means before // Workspace is completely constructed, so calling Workspace::self() would result @@ -66,7 +66,9 @@ Compositor::Compositor(QObject *workspace) Compositor::~Compositor() { +#if KWIN_BUILD_X11 deleteUnusedSupportProperties(); +#endif s_compositor = nullptr; } @@ -94,6 +96,7 @@ void Compositor::removeSuperLayer(RenderLayer *layer) delete layer; } +#if KWIN_BUILD_X11 void Compositor::keepSupportProperty(xcb_atom_t atom) { m_unusedSupportProperties.removeAll(atom); @@ -120,6 +123,7 @@ void Compositor::deleteUnusedSupportProperties() m_unusedSupportProperties.clear(); } } +#endif void Compositor::reinitialize() { diff --git a/src/compositor.h b/src/compositor.h index d5a0d0ddd6..c2fc1726a0 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -9,8 +9,12 @@ */ #pragma once +#include "config-kwin.h" #include + +#if KWIN_BUILD_X11 #include +#endif #include #include @@ -80,9 +84,11 @@ public: return s_compositor != nullptr && s_compositor->isActive(); } +#if KWIN_BUILD_X11 // for delayed supportproperty management of effects void keepSupportProperty(xcb_atom_t atom); void removeSupportProperty(xcb_atom_t atom); +#endif /** * Whether Compositing is possible in the Platform. @@ -134,7 +140,9 @@ private Q_SLOTS: void handleFrameRequested(RenderLoop *renderLoop); protected: +#if KWIN_BUILD_X11 void deleteUnusedSupportProperties(); +#endif Output *findOutput(RenderLoop *loop) const; @@ -147,8 +155,10 @@ protected: void framePass(RenderLayer *layer, OutputFrame *frame); State m_state = State::Off; +#if KWIN_BUILD_X11 QList m_unusedSupportProperties; QTimer m_unusedSupportPropertyTimer; +#endif std::unique_ptr m_scene; std::unique_ptr m_cursorScene; std::unique_ptr m_backend; diff --git a/src/config-kwin.h.cmake b/src/config-kwin.h.cmake index c68a3eae17..a4ad8a646c 100644 --- a/src/config-kwin.h.cmake +++ b/src/config-kwin.h.cmake @@ -10,6 +10,7 @@ #cmakedefine01 KWIN_BUILD_TABBOX #cmakedefine01 KWIN_BUILD_ACTIVITIES #cmakedefine01 KWIN_BUILD_GLOBALSHORTCUTS +#cmakedefine01 KWIN_BUILD_X11 constexpr QLatin1String KWIN_CONFIG("kwinrc"); constexpr QLatin1String KWIN_VERSION_STRING("${PROJECT_VERSION}"); constexpr QLatin1String XCB_VERSION_STRING("${XCB_VERSION}"); diff --git a/src/cursor.cpp b/src/cursor.cpp index 133d1c8ca8..cf8ed30525 100644 --- a/src/cursor.cpp +++ b/src/cursor.cpp @@ -17,7 +17,10 @@ #include "main.h" #include "scene/workspacescene.h" #include "utils/common.h" + +#if KWIN_BUILD_X11 #include "utils/xcbutils.h" +#endif // KDE #include #include @@ -222,6 +225,7 @@ void Cursor::markAsRendered(std::chrono::milliseconds timestamp) Q_EMIT rendered(timestamp); } +#if KWIN_BUILD_X11 xcb_cursor_t Cursor::x11Cursor(CursorShape shape) { return x11Cursor(shape.name()); @@ -261,6 +265,7 @@ xcb_cursor_t Cursor::x11Cursor(const QByteArray &name) xcb_cursor_context_free(ctx); return cursor; } +#endif void Cursor::doSetPos() { diff --git a/src/debug_console.cpp b/src/debug_console.cpp index 00043125d0..6246c7d858 100644 --- a/src/debug_console.cpp +++ b/src/debug_console.cpp @@ -32,15 +32,16 @@ #include "wayland_server.h" #include "waylandwindow.h" #include "workspace.h" -#include "x11window.h" #include "xkb.h" #include +#if KWIN_BUILD_X11 +#include "x11window.h" +#endif #include "ui_debug_console.h" // frameworks #include -#include // Qt #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include @@ -932,6 +934,7 @@ DebugConsoleModel::DebugConsoleModel(QObject *parent) void DebugConsoleModel::handleWindowAdded(Window *window) { +#if KWIN_BUILD_X11 if (auto x11 = qobject_cast(window)) { if (x11->isUnmanaged()) { add(s_x11UnmanagedId - 1, m_unmanageds, x11); @@ -940,6 +943,7 @@ void DebugConsoleModel::handleWindowAdded(Window *window) } return; } +#endif if (auto wayland = qobject_cast(window)) { add(s_waylandWindowId - 1, m_waylandWindows, wayland); @@ -954,6 +958,7 @@ void DebugConsoleModel::handleWindowAdded(Window *window) void DebugConsoleModel::handleWindowRemoved(Window *window) { +#if KWIN_BUILD_X11 if (auto x11 = qobject_cast(window)) { if (x11->isUnmanaged()) { remove(s_x11UnmanagedId - 1, m_unmanageds, x11); @@ -962,6 +967,7 @@ void DebugConsoleModel::handleWindowRemoved(Window *window) } return; } +#endif if (auto wayland = qobject_cast(window)) { 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 KWIN_BUILD_X11 return propertyCount(parent, &DebugConsoleModel::x11Window); +#else + return 0; +#endif } else if (parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) { +#if KWIN_BUILD_X11 return propertyCount(parent, &DebugConsoleModel::unmanaged); +#else + return 0; +#endif } else if (parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) { return propertyCount(parent, &DebugConsoleModel::waylandWindow); } 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) if (parent.internalId() < s_idDistance * (s_x11WindowId + 1)) { +#if KWIN_BUILD_X11 return indexForProperty(row, column, parent, &DebugConsoleModel::x11Window); +#else + return {}; +#endif } else if (parent.internalId() < s_idDistance * (s_x11UnmanagedId + 1)) { +#if KWIN_BUILD_X11 return indexForProperty(row, column, parent, &DebugConsoleModel::unmanaged); +#else + return {}; +#endif } else if (parent.internalId() < s_idDistance * (s_waylandWindowId + 1)) { return indexForProperty(row, column, parent, &DebugConsoleModel::waylandWindow); } 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); } else if (InternalWindow *w = internalWindow(index)) { return propertyData(w, index, role); +#if KWIN_BUILD_X11 } else if (X11Window *w = x11Window(index)) { return propertyData(w, index, role); } else if (X11Window *u = unmanaged(index)) { return propertyData(u, index, role); +#endif } } else { if (index.column() != 0) { @@ -1248,10 +1272,14 @@ QVariant DebugConsoleModel::data(const QModelIndex &index, int role) const }; switch (index.parent().internalId()) { case s_x11WindowId: +#if KWIN_BUILD_X11 return windowData(index, role, m_x11Windows, [](X11Window *c) -> QString { return QStringLiteral("0x%1: %2").arg(c->window(), 0, 16).arg(c->caption()); }); +#endif + break; case s_x11UnmanagedId: { +#if KWIN_BUILD_X11 if (index.row() >= m_unmanageds.count()) { return QVariant(); } @@ -1259,6 +1287,7 @@ QVariant DebugConsoleModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole) { return QStringLiteral("0x%1").arg(u->window(), 0, 16); } +#endif break; } case s_waylandWindowId: diff --git a/src/decorations/decoratedclient.cpp b/src/decorations/decoratedclient.cpp index 01b8122d58..3d2ab5a2b9 100644 --- a/src/decorations/decoratedclient.cpp +++ b/src/decorations/decoratedclient.cpp @@ -12,7 +12,9 @@ #include "decorationpalette.h" #include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif #include #include @@ -136,17 +138,21 @@ DELEGATE(bool, isShaded, isShade) WId DecoratedClientImpl::windowId() const { +#if KWIN_BUILD_X11 if (X11Window *x11Window = qobject_cast(m_window)) { return x11Window->window(); } +#endif return 0; } WId DecoratedClientImpl::decorationId() const { +#if KWIN_BUILD_X11 if (X11Window *x11Window = qobject_cast(m_window)) { return x11Window->frameId(); } +#endif return 0; } diff --git a/src/effect/effecthandler.cpp b/src/effect/effecthandler.cpp index 9d6e90a809..ab43c53189 100644 --- a/src/effect/effecthandler.cpp +++ b/src/effect/effecthandler.cpp @@ -42,8 +42,9 @@ #include "wayland_server.h" #include "window_property_notify_x11_filter.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" - +#endif #if KWIN_BUILD_ACTIVITIES #include "activities.h" #endif @@ -68,7 +69,7 @@ namespace KWin { - +#if KWIN_BUILD_X11 static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom_t type, int format) { if (win == XCB_WINDOW_NONE) { @@ -108,6 +109,7 @@ static xcb_atom_t registerSupportProperty(const QByteArray &propertyName) // TODO: add to _NET_SUPPORTED return atomReply->atom; } +#endif //**************************************** // EffectsHandler @@ -200,6 +202,7 @@ EffectsHandler::EffectsHandler(Compositor *compositor, WorkspaceScene *scene) connect(kwinApp()->screenLockerWatcher(), &ScreenLockerWatcher::aboutToLock, this, &EffectsHandler::screenAboutToLock); #endif +#if KWIN_BUILD_X11 connect(kwinApp(), &Application::x11ConnectionChanged, this, [this]() { registered_atoms.clear(); for (auto it = m_propertiesForEffects.keyBegin(); it != m_propertiesForEffects.keyEnd(); it++) { @@ -222,6 +225,7 @@ EffectsHandler::EffectsHandler(Compositor *compositor, WorkspaceScene *scene) if (kwinApp()->x11Connection()) { m_x11WindowPropertyNotify = std::make_unique(this); } +#endif // connect all clients for (Window *window : ws->windows()) { @@ -244,6 +248,7 @@ EffectsHandler::~EffectsHandler() KWin::effects = nullptr; } +#if KWIN_BUILD_X11 xcb_window_t EffectsHandler::x11RootWindow() const { return kwinApp()->x11RootWindow(); @@ -253,6 +258,7 @@ xcb_connection_t *EffectsHandler::xcbConnection() const { return kwinApp()->x11Connection(); } +#endif CompositingType EffectsHandler::compositingType() const { @@ -638,6 +644,7 @@ bool EffectsHandler::hasKeyboardGrab() const return keyboard_grab_effect != nullptr; } +#if KWIN_BUILD_X11 void EffectsHandler::registerPropertyType(long atom, bool reg) { if (reg) { @@ -692,13 +699,18 @@ void EffectsHandler::removeSupportProperty(const QByteArray &propertyName, Effec m_propertiesForEffects.remove(propertyName); m_compositor->removeSupportProperty(atom); // delayed removal } +#endif QByteArray EffectsHandler::readRootProperty(long atom, long type, int format) const { +#if KWIN_BUILD_X11 if (!kwinApp()->x11Connection()) { return QByteArray(); } return readWindowProperty(kwinApp()->x11RootWindow(), atom, type, format); +#else + return {}; +#endif } void EffectsHandler::activateWindow(EffectWindow *effectWindow) @@ -859,15 +871,16 @@ double EffectsHandler::animationTimeFactor() const EffectWindow *EffectsHandler::findWindow(WId id) const { +#if KWIN_BUILD_X11 if (X11Window *w = Workspace::self()->findClient(Predicate::WindowMatch, id)) { return w->effectWindow(); } if (X11Window *w = Workspace::self()->findUnmanaged(id)) { return w->effectWindow(); } +#endif return nullptr; } - EffectWindow *EffectsHandler::findWindow(SurfaceInterface *surf) const { if (waylandServer()) { @@ -1197,10 +1210,12 @@ void EffectsHandler::destroyEffect(Effect *effect) stopMouseInterception(effect); +#if KWIN_BUILD_X11 const QList properties = m_propertiesForEffects.keys(); for (const QByteArray &property : properties) { removeSupportProperty(property, effect); } +#endif delete effect; } diff --git a/src/effect/effecthandler.h b/src/effect/effecthandler.h index dc7a4483aa..2960ddf2a8 100644 --- a/src/effect/effecthandler.h +++ b/src/effect/effecthandler.h @@ -12,6 +12,7 @@ #pragma once +#include "config-kwin.h" #include "effect/effect.h" #include "effect/effectwindow.h" @@ -29,7 +30,9 @@ #include +#if KWIN_BUILD_X11 #include +#endif class KConfigGroup; class QFont; @@ -480,6 +483,8 @@ public: void reconfigure(); 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 * has announced support for this feature yet, an X11 property will be installed on @@ -511,6 +516,7 @@ public: * @since 4.11 */ void removeSupportProperty(const QByteArray &propertyName, Effect *effect); +#endif /** * Returns @a true if the active window decoration has shadow API hooks. @@ -570,8 +576,10 @@ public: */ void doneOpenGLContextCurrent(); +#if KWIN_BUILD_X11 xcb_connection_t *xcbConnection() const; xcb_window_t x11RootWindow() const; +#endif /** * Interface to the Wayland display: this is relevant only @@ -741,10 +749,12 @@ public: void highlightWindows(const QList &windows); +#if KWIN_BUILD_X11 bool isPropertyTypeRegistered(xcb_atom_t atom) const { return registered_atoms.contains(atom); } +#endif Q_SIGNALS: /** @@ -987,6 +997,7 @@ Q_SIGNALS: */ 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 * got destroyed. @@ -998,6 +1009,7 @@ Q_SIGNALS: * @since 5.11 */ void xcbConnectionChanged(); +#endif /** * This signal is emitted when active fullscreen effect changed. @@ -1082,7 +1094,9 @@ protected: Effect *keyboard_grab_effect; Effect *fullscreen_effect; QMultiMap effect_order; +#if KWIN_BUILD_X11 QHash registered_atoms; +#endif QList loaded_effects; CompositingType compositing_type; EffectsList m_activeEffects; @@ -1090,7 +1104,9 @@ protected: EffectsIterator m_currentPaintWindowIterator; EffectsIterator m_currentPaintScreenIterator; typedef QHash> PropertyEffectMap; +#if KWIN_BUILD_X11 PropertyEffectMap m_propertiesForEffects; +#endif QHash m_managedProperties; Compositor *m_compositor; WorkspaceScene *m_scene; diff --git a/src/effect/effectwindow.cpp b/src/effect/effectwindow.cpp index 1905dcbd5e..e7450fc55e 100644 --- a/src/effect/effectwindow.cpp +++ b/src/effect/effectwindow.cpp @@ -10,12 +10,15 @@ #include "effect/effectwindow.h" #include "core/output.h" #include "effect/effecthandler.h" -#include "group.h" #include "internalwindow.h" #include "scene/windowitem.h" #include "virtualdesktops.h" #include "waylandwindow.h" + +#if KWIN_BUILD_X11 +#include "group.h" #include "x11window.h" +#endif namespace KWin { @@ -54,7 +57,11 @@ EffectWindow::EffectWindow(WindowItem *windowItem) d->managed = d->m_window->isClient(); d->m_waylandWindow = qobject_cast(d->m_window) != nullptr; +#if KWIN_BUILD_X11 d->m_x11Window = qobject_cast(d->m_window) != nullptr; +#else + d->m_x11Window = false; +#endif connect(d->m_window, &Window::hiddenChanged, this, [this]() { Q_EMIT windowHiddenChanged(this); @@ -210,9 +217,11 @@ void EffectWindow::addLayerRepaint(const QRect &r) const EffectWindowGroup *EffectWindow::group() const { +#if KWIN_BUILD_X11 if (Group *group = d->m_window->group()) { return group->effectGroup(); } +#endif return nullptr; } @@ -302,9 +311,11 @@ WINDOW_HELPER(bool, isInputMethod, isInputMethod) qlonglong EffectWindow::windowId() const { +#if KWIN_BUILD_X11 if (X11Window *x11Window = qobject_cast(d->m_window)) { return x11Window->window(); } +#endif return 0; } @@ -325,9 +336,11 @@ WindowType EffectWindow::windowType() const QSizeF EffectWindow::basicUnit() const { +#if KWIN_BUILD_X11 if (auto window = qobject_cast(d->m_window)) { return window->basicUnit(); } +#endif return QSize(1, 1); } @@ -343,6 +356,7 @@ KDecoration2::Decoration *EffectWindow::decoration() const QByteArray EffectWindow::readProperty(long atom, long type, int format) const { +#if KWIN_BUILD_X11 auto x11Window = qobject_cast(d->m_window); if (!x11Window) { return QByteArray(); @@ -363,10 +377,13 @@ QByteArray EffectWindow::readProperty(long atom, long type, int format) const } return prop.toByteArray(format, type); } +#endif + return {}; } void EffectWindow::deleteProperty(long int atom) const { +#if KWIN_BUILD_X11 auto x11Window = qobject_cast(d->m_window); if (!x11Window) { return; @@ -375,6 +392,7 @@ void EffectWindow::deleteProperty(long int atom) const return; } xcb_delete_property(kwinApp()->x11Connection(), x11Window->window(), atom); +#endif } EffectWindow *EffectWindow::findModal() @@ -495,12 +513,14 @@ EffectWindowGroup::~EffectWindowGroup() QList EffectWindowGroup::members() const { - const auto memberList = m_group->members(); QList ret; +#if KWIN_BUILD_X11 + const auto memberList = m_group->members(); ret.reserve(memberList.size()); std::transform(std::cbegin(memberList), std::cend(memberList), std::back_inserter(ret), [](auto window) { return window->effectWindow(); }); +#endif return ret; } diff --git a/src/effect/effectwindow.h b/src/effect/effectwindow.h index 2a03ee994e..df36516fc3 100644 --- a/src/effect/effectwindow.h +++ b/src/effect/effectwindow.h @@ -9,11 +9,13 @@ #pragma once +#include "core/output.h" #include "kwin_export.h" #include "globals.h" #include +#include class QWindow; diff --git a/src/effect/xcb.h b/src/effect/xcb.h index 0993380b68..929a796475 100644 --- a/src/effect/xcb.h +++ b/src/effect/xcb.h @@ -8,6 +8,11 @@ */ #pragma once +#include "config-kwin.h" + +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif #include #include diff --git a/src/group.cpp b/src/group.cpp index 87a7ecc897..c5afd1e2e0 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -13,6 +13,7 @@ #include "workspace.h" #include "x11window.h" +#include #include #include @@ -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 diff --git a/src/group.h b/src/group.h index 5cae3c1083..55efba4ce9 100644 --- a/src/group.h +++ b/src/group.h @@ -10,6 +10,11 @@ #pragma once +#include +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif + #include "utils/common.h" #include diff --git a/src/helpers/wayland_wrapper/CMakeLists.txt b/src/helpers/wayland_wrapper/CMakeLists.txt index 005d4de4b8..49078fd1ca 100644 --- a/src/helpers/wayland_wrapper/CMakeLists.txt +++ b/src/helpers/wayland_wrapper/CMakeLists.txt @@ -15,6 +15,9 @@ ecm_qt_declare_logging_category(kwin_wayland_wrapper 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) install(TARGETS kwin_wayland_wrapper ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/helpers/wayland_wrapper/kwin_wrapper.cpp b/src/helpers/wayland_wrapper/kwin_wrapper.cpp index 1a88ad38af..55af30b21f 100644 --- a/src/helpers/wayland_wrapper/kwin_wrapper.cpp +++ b/src/helpers/wayland_wrapper/kwin_wrapper.cpp @@ -20,6 +20,8 @@ * Usage kwin_wayland_wrapper [argForKwin] [argForKwin] ... */ +#include "config-kwin.h" + #include #include #include @@ -33,8 +35,11 @@ #include "wl-socket.h" #include "wrapper_logging.h" + +#if KWIN_BUILD_X11 #include "xauthority.h" #include "xwaylandsocket.h" +#endif using namespace std::chrono_literals; @@ -55,10 +60,13 @@ private: int m_crashCount = 0; QProcess *m_kwinProcess = nullptr; - std::unique_ptr m_xwlSocket; - QTemporaryFile m_xauthorityFile; const std::chrono::microseconds m_watchdogInterval; bool m_watchdogIntervalOk; + +#if KWIN_BUILD_X11 + std::unique_ptr m_xwlSocket; + QTemporaryFile m_xauthorityFile; +#endif }; KWinWrapper::KWinWrapper(QObject *parent) @@ -71,6 +79,7 @@ KWinWrapper::KWinWrapper(QObject *parent) qFatal("Could not create wayland socket"); } +#if KWIN_BUILD_X11 if (qApp->arguments().contains(QLatin1String("--xwayland"))) { m_xwlSocket = std::make_unique(KWin::XwaylandSocket::OperationMode::TransferFdsOnExec); if (!m_xwlSocket->isValid()) { @@ -85,6 +94,7 @@ KWinWrapper::KWinWrapper(QObject *parent) } } } +#endif } KWinWrapper::~KWinWrapper() @@ -102,6 +112,7 @@ void KWinWrapper::run() args << "--wayland-fd" << QString::number(wl_socket_get_fd(m_socket)); args << "--socket" << QString::fromUtf8(wl_socket_get_display_name(m_socket)); +#if KWIN_BUILD_X11 if (m_xwlSocket) { const auto xwaylandFileDescriptors = m_xwlSocket->fileDescriptors(); for (const int &fileDescriptor : xwaylandFileDescriptors) { @@ -112,6 +123,7 @@ void KWinWrapper::run() args << "--xwayland-xauthority" << m_xauthorityFile.fileName(); } } +#endif // attach our main process arguments // the first entry is dropped as it will be our program name @@ -143,12 +155,14 @@ void KWinWrapper::run() QProcessEnvironment env; env.insert("WAYLAND_DISPLAY", QString::fromUtf8(wl_socket_get_display_name(m_socket))); +#if KWIN_BUILD_X11 if (m_xwlSocket) { env.insert("DISPLAY", m_xwlSocket->name()); if (m_xauthorityFile.open()) { env.insert("XAUTHORITY", m_xauthorityFile.fileName()); } } +#endif auto envSyncJob = new KUpdateLaunchEnvironmentJob(env); 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 diff --git a/src/input.cpp b/src/input.cpp index 25f944e779..a9dd43fe13 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -30,7 +30,9 @@ #include "tablet_input.h" #include "touch_input.h" #include "wayland/xdgtopleveldrag_v1.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif #if KWIN_BUILD_TABBOX #include "tabbox/tabbox.h" #endif @@ -2363,10 +2365,11 @@ static AbstractDropHandler *dropHandler(Window *window) if (dropTarget) { return dropTarget; } - +#if KWIN_BUILD_X11 if (qobject_cast(window) && kwinApp()->xwayland()) { return kwinApp()->xwayland()->xwlDropHandler(); } +#endif return nullptr; } diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 1eac69c40b..605566f684 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -34,7 +34,6 @@ #include #include -#include #include #include @@ -43,6 +42,7 @@ #include #include +#include #include #include @@ -60,13 +60,14 @@ static std::vector textToKey(const QString &text) return {}; } - const QList syms(KKeyServer::keyQtToSymXs(sequence[0])); + QKeyEvent ev(QEvent::KeyPress, sequence[0], Qt::NoModifier); + const QList syms(QXkbCommon::toKeysym(&ev)); if (syms.empty()) { return {}; } - std::optional keyCode; - for (int sym : syms) { + std::optional keyCode; + for (xkb_keysym_t sym : syms) { auto code = input()->keyboard()->xkb()->keycodeFromKeysym(sym); if (code) { keyCode = code; diff --git a/src/kcms/rules/CMakeLists.txt b/src/kcms/rules/CMakeLists.txt index 1cda29d7a4..b47d162441 100644 --- a/src/kcms/rules/CMakeLists.txt +++ b/src/kcms/rules/CMakeLists.txt @@ -20,11 +20,13 @@ kconfig_add_kcfg_files(kwinrules_SRCS ../../rulebooksettingsbase.kcfgc) add_library(KWinRulesObjects STATIC ${kwinrules_SRCS}) set_property(TARGET KWinRulesObjects PROPERTY POSITION_INDEPENDENT_CODE ON) -set(kwin_kcm_rules_XCB_LIBS - XCB::CURSOR - XCB::XCB - XCB::XFIXES -) +if (KWIN_BUILD_X11) + set(kwin_kcm_rules_XCB_LIBS + XCB::CURSOR + XCB::XCB + XCB::XFIXES + ) +endif() set(kcm_libs Qt::Quick diff --git a/src/kcms/tabbox/CMakeLists.txt b/src/kcms/tabbox/CMakeLists.txt index fc17c307a6..6d6aa1f759 100644 --- a/src/kcms/tabbox/CMakeLists.txt +++ b/src/kcms/tabbox/CMakeLists.txt @@ -27,8 +27,12 @@ target_link_libraries(kcm_kwintabbox KF6::Package KF6::Service KF6::XmlGui # For kkeysequencewidget - XCB::XCB ) +if (KWIN_BUILD_X11) + target_link_libraries(kcm_kwintabbox + XCB::XCB + ) +endif() ########### install files ############### install(FILES thumbnails/falkon.png diff --git a/src/killprompt.cpp b/src/killprompt.cpp index e1b4433108..28d77ae469 100644 --- a/src/killprompt.cpp +++ b/src/killprompt.cpp @@ -11,9 +11,11 @@ #include "wayland/seat.h" #include "wayland/xdgforeign_v2.h" #include "wayland_server.h" -#include "x11window.h" #include "xdgactivationv1.h" #include "xdgshellwindow.h" +#if KWIN_BUILD_X11 +#include "x11window.h" +#endif #include #include @@ -25,7 +27,11 @@ namespace KWin KillPrompt::KillPrompt(Window *window) : m_window(window) { +#if KWIN_BUILD_X11 Q_ASSERT(qobject_cast(window) || qobject_cast(window)); +#else + Q_ASSERT(qobject_cast(window)); +#endif 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 platform; +#if KWIN_BUILD_X11 if (auto *x11Window = qobject_cast(m_window)) { platform = QStringLiteral("xcb"); wid = QString::number(x11Window->window()); @@ -65,7 +72,9 @@ void KillPrompt::start(quint32 timestamp) if (!x11Window->clientMachine()->isLocal()) { hostname = x11Window->clientMachine()->hostName(); } - } else if (auto *xdgToplevel = qobject_cast(m_window)) { + } else +#endif + if (auto *xdgToplevel = qobject_cast(m_window)) { platform = QStringLiteral("wayland"); auto *exported = waylandServer()->exportAsForeign(xdgToplevel->surface()); wid = exported->handle(); diff --git a/src/layers.cpp b/src/layers.cpp index 91f567e6ab..45baa452d6 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -67,9 +67,7 @@ #include "compositor.h" #include "effect/effecthandler.h" #include "focuschain.h" -#include "group.h" #include "internalwindow.h" -#include "netinfo.h" #include "rules.h" #include "screenedge.h" #include "tabbox/tabbox.h" @@ -77,7 +75,11 @@ #include "virtualdesktops.h" #include "wayland_server.h" #include "workspace.h" +#if KWIN_BUILD_X11 +#include "group.h" +#include "netinfo.h" #include "x11window.h" +#endif #include @@ -103,7 +105,9 @@ void Workspace::updateStackingOrder(bool propagate_new_windows) force_restacking = false; stacking_order = new_stacking_order; if (changed || propagate_new_windows) { +#if KWIN_BUILD_X11 propagateWindows(propagate_new_windows); +#endif for (int i = 0; i < stacking_order.size(); ++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 * 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()); } +#endif /** * 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.prepend(window); + // TODO How X11-specific is this implementation? +#if KWIN_BUILD_X11 if (!nogroup && window->isTransient()) { // lower also all windows in the group, in their reversed stacking order QList wins; @@ -318,6 +326,7 @@ void Workspace::lowerWindow(Window *window, bool nogroup) } } } +#endif } 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*/) { // 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); } } +#endif void Workspace::lowerWindowRequest(Window *window) { @@ -470,6 +481,7 @@ void Workspace::restackWindowUnderActive(Window *window) restack(window, m_activeWindow); } +#if KWIN_BUILD_X11 void Workspace::restoreSessionStackingOrder(X11Window *window) { if (window->sessionStackingOrder() < 0) { @@ -515,14 +527,16 @@ static Layer layerForWindow(const X11Window *window) return layer; } +#endif static Layer computeLayer(const Window *window) { +#if KWIN_BUILD_X11 if (auto x11Window = qobject_cast(window)) { return layerForWindow(x11Window); - } else { - return window->layer(); } +#endif + return window->layer(); } /** @@ -635,11 +649,13 @@ QList ensureStackingOrderInList(const QList &stackingOrder, const } } +#if KWIN_BUILD_X11 // Ensure list is in stacking order QList Workspace::ensureStackingOrder(const QList &list) const { return ensureStackingOrderInList(stacking_order, list); } +#endif QList Workspace::ensureStackingOrder(const QList &list) const { @@ -651,6 +667,7 @@ QList Workspace::unconstrainedStackingOrder() const return unconstrained_stacking_order; } +#if KWIN_BUILD_X11 void Workspace::updateXStackingOrder() { // we use our stacking order for managed windows, but X's for override-redirect windows @@ -672,100 +689,6 @@ void Workspace::updateXStackingOrder() updateStackingOrder(); } } - -//******************************* -// 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(*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(*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; -} +#endif } // namespace diff --git a/src/main.cpp b/src/main.cpp index fbc21852de..1674612bf0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,9 @@ #include "config-kwin.h" +#if KWIN_BUILD_X11 #include "atoms.h" +#endif #include "colors/colormanager.h" #include "compositor.h" #include "core/outputbackend.h" @@ -32,10 +34,13 @@ #include "screenedge.h" #include "sm.h" #include "tabletmodemanager.h" -#include "utils/xcbutils.h" #include "wayland/surface.h" #include "workspace.h" + +#if KWIN_BUILD_X11 +#include "utils/xcbutils.h" #include "x11eventfilter.h" +#endif #if KWIN_BUILD_SCREENLOCKER #include "screenlockerwatcher.h" @@ -59,11 +64,13 @@ #endif #include +#if KWIN_BUILD_X11 // xcb #include #ifndef XCB_GE_GENERIC #define XCB_GE_GENERIC 35 #endif +#endif Q_DECLARE_METATYPE(KSharedConfigPtr) @@ -71,12 +78,16 @@ namespace KWin { Options *options; +#if KWIN_BUILD_X11 Atoms *atoms; +#endif int Application::crashes = 0; Application::Application(Application::OperationMode mode, int &argc, char **argv) : QApplication(argc, argv) +#if KWIN_BUILD_X11 , m_eventFilter(new XcbEventFilter()) +#endif , m_configLock(false) , m_config(KSharedConfig::openConfig(QStringLiteral("kwinrc"))) , m_kxkbConfig() @@ -150,8 +161,10 @@ void Application::notifyStarted() void Application::destroyAtoms() { +#if KWIN_BUILD_X11 delete atoms; atoms = nullptr; +#endif } void Application::destroyPlatform() @@ -262,7 +275,9 @@ void Application::createInput() void Application::createAtoms() { +#if KWIN_BUILD_X11 atoms = new Atoms; +#endif } void Application::createOptions() @@ -295,6 +310,7 @@ TabletModeManager *Application::tabletModeManager() const return m_tabletModeManager.get(); } +#if KWIN_BUILD_X11 void Application::installNativeX11EventFilter() { installNativeEventFilter(m_eventFilter.get()); @@ -304,6 +320,7 @@ void Application::removeNativeX11EventFilter() { removeNativeEventFilter(m_eventFilter.get()); } +#endif void Application::destroyInput() { @@ -358,6 +375,7 @@ void Application::createEffectsHandler(Compositor *compositor, WorkspaceScene *s new EffectsHandler(compositor, scene); } +#if KWIN_BUILD_X11 void Application::registerEventFilter(X11EventFilter *filter) { if (filter->isGenericEvent()) { @@ -378,6 +396,7 @@ static X11EventFilterContainer *takeEventFilter(X11EventFilter *eventFilter, } return nullptr; } +#endif void Application::setXwaylandScale(qreal scale) { @@ -403,12 +422,15 @@ void Application::applyXwaylandScale() } xwaylandGroup.sync(); +#if KWIN_BUILD_X11 if (x11Connection()) { // rerun the fonts kcm init that does the appropriate xrdb call with the new settings QProcess::startDetached("kcminit", {"kcm_fonts_init", "kcm_style_init"}); } +#endif } +#if KWIN_BUILD_X11 void Application::unregisterEventFilter(X11EventFilter *filter) { X11EventFilterContainer *container = nullptr; @@ -625,6 +647,8 @@ bool XcbEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag return false; } +#endif + QProcessEnvironment Application::processStartupEnvironment() const { return m_processEnvironment; diff --git a/src/main.h b/src/main.h index b28256bca6..a0b55dd5c9 100644 --- a/src/main.h +++ b/src/main.h @@ -21,7 +21,9 @@ #include #include +#if KWIN_BUILD_X11 #include +#endif class KPluginMetaData; class QCommandLineParser; @@ -69,9 +71,11 @@ private: class KWIN_EXPORT Application : public QApplication { Q_OBJECT +#if KWIN_BUILD_X11 Q_PROPERTY(quint32 x11Time READ x11Time WRITE setX11Time) Q_PROPERTY(quint32 x11RootWindow READ x11RootWindow CONSTANT) Q_PROPERTY(void *x11Connection READ x11Connection NOTIFY x11ConnectionChanged) +#endif Q_PROPERTY(KSharedConfigPtr config READ config WRITE setConfig) Q_PROPERTY(KSharedConfigPtr kxkbConfig READ kxkbConfig WRITE setKxkbConfig) public: @@ -140,6 +144,7 @@ public: void setupCommandLine(QCommandLineParser *parser); void processCommandLine(QCommandLineParser *parser); +#if KWIN_BUILD_X11 void registerEventFilter(X11EventFilter *filter); void unregisterEventFilter(X11EventFilter *filter); bool dispatchEvent(xcb_generic_event_t *event); @@ -163,6 +168,7 @@ public: */ void updateXTime(); void updateX11Time(xcb_generic_event_t *event); +#endif static void setCrashCount(int count); static bool wasCrash(); @@ -174,6 +180,7 @@ public: */ static void createAboutData(); +#if KWIN_BUILD_X11 /** * @returns the X11 root window. */ @@ -197,7 +204,6 @@ public: { return m_connection; } - /** * Inheriting classes should use this method to set the X11 root window * before accessing any X11 specific code pathes. @@ -218,6 +224,7 @@ public: { m_compositeWindow = window; } +#endif qreal xwaylandScale() const { @@ -372,19 +379,23 @@ protected: static int crashes; private: +#if KWIN_BUILD_X11 QList> m_eventFilters; QList> m_genericEventFilters; std::unique_ptr m_eventFilter; +#endif bool m_followLocale1 = false; bool m_configLock; KSharedConfigPtr m_config; KSharedConfigPtr m_kxkbConfig; KSharedConfigPtr m_inputConfig; OperationMode m_operationMode; +#if KWIN_BUILD_X11 xcb_timestamp_t m_x11Time = XCB_TIME_CURRENT_TIME; xcb_window_t m_rootWindow = XCB_WINDOW_NONE; xcb_window_t m_compositeWindow = XCB_WINDOW_NONE; xcb_connection_t *m_connection = nullptr; +#endif #if KWIN_BUILD_ACTIVITIES bool m_useKActivities = true; #endif diff --git a/src/main_wayland.cpp b/src/main_wayland.cpp index a82da86d5b..000178c59e 100644 --- a/src/main_wayland.cpp +++ b/src/main_wayland.cpp @@ -25,8 +25,11 @@ #include "wayland/seat.h" #include "wayland_server.h" #include "workspace.h" + +#if KWIN_BUILD_X11 #include "xwayland/xwayland.h" #include "xwayland/xwaylandlauncher.h" +#endif // KDE #include @@ -121,7 +124,9 @@ ApplicationWayland::~ApplicationWayland() if (effects) { effects->unloadAllEffects(); } +#if KWIN_BUILD_X11 m_xwayland.reset(); +#endif destroyColorManager(); destroyWorkspace(); @@ -132,10 +137,12 @@ ApplicationWayland::~ApplicationWayland() void ApplicationWayland::performStartup() { +#if KWIN_BUILD_X11 if (m_startXWayland) { setOperationMode(OperationModeXwayland); setXwaylandScale(config()->group(QStringLiteral("Xwayland")).readEntry("Scale", 1.0)); } +#endif createOptions(); if (!outputBackend()->initialize()) { @@ -162,6 +169,7 @@ void ApplicationWayland::continueStartupWithScene() qFatal("Failed to initialze the Wayland server, exiting now"); } +#if KWIN_BUILD_X11 if (operationMode() == OperationModeXwayland) { m_xwayland = std::make_unique(this); m_xwayland->xwaylandLauncher()->setListenFDs(m_xwaylandListenFds); @@ -170,6 +178,7 @@ void ApplicationWayland::continueStartupWithScene() m_xwayland->init(); connect(m_xwayland.get(), &Xwl::Xwayland::started, this, &ApplicationWayland::applyXwaylandScale); } +#endif startSession(); notifyStarted(); } @@ -247,10 +256,12 @@ void ApplicationWayland::startSession() } } +#if KWIN_BUILD_X11 XwaylandInterface *ApplicationWayland::xwayland() const { return m_xwayland.get(); } +#endif } // namespace @@ -287,14 +298,18 @@ int main(int argc, char *argv[]) KWin::Application::createAboutData(); +#if KWIN_BUILD_X11 QCommandLineOption xwaylandOption(QStringLiteral("xwayland"), i18n("Start a rootless Xwayland server.")); +#endif QCommandLineOption waylandSocketOption(QStringList{QStringLiteral("s"), QStringLiteral("socket")}, i18n("Name of the Wayland socket to listen on. If not set \"wayland-0\" is used."), QStringLiteral("socket")); +#if KWIN_BUILD_X11 QCommandLineOption x11DisplayOption(QStringLiteral("x11-display"), i18n("The X11 Display to use in windowed mode on platform X11."), QStringLiteral("display")); +#endif QCommandLineOption waylandDisplayOption(QStringLiteral("wayland-display"), i18n("The Wayland Display to use in windowed mode on platform Wayland."), QStringLiteral("display")); @@ -342,14 +357,18 @@ int main(int argc, char *argv[]) QCommandLineParser parser; a.setupCommandLine(&parser); +#if KWIN_BUILD_X11 parser.addOption(xwaylandOption); +#endif parser.addOption(waylandSocketOption); parser.addOption(waylandSocketFdOption); parser.addOption(xwaylandListenFdOption); parser.addOption(xwaylandDisplayOption); parser.addOption(xwaylandXAuthorityOption); parser.addOption(replaceOption); +#if KWIN_BUILD_X11 parser.addOption(x11DisplayOption); +#endif parser.addOption(waylandDisplayOption); parser.addOption(virtualFbOption); parser.addOption(widthOption); @@ -429,8 +448,10 @@ int main(int argc, char *argv[]) // Decide what backend to use. if (parser.isSet(drmOption)) { backendType = BackendType::Kms; +#if KWIN_BUILD_X11 } else if (parser.isSet(x11DisplayOption)) { backendType = BackendType::X11; +#endif } else if (parser.isSet(waylandDisplayOption)) { backendType = BackendType::Wayland; } else if (parser.isSet(virtualFbOption)) { @@ -539,6 +560,7 @@ int main(int argc, char *argv[]) a.setOutputBackend(std::move(outputBackend)); break; } +#if KWIN_BUILD_X11 case BackendType::X11: { QString display = parser.value(x11DisplayOption); if (display.isEmpty()) { @@ -553,6 +575,7 @@ int main(int argc, char *argv[]) })); break; } +#endif case BackendType::Wayland: { QString socketName = parser.value(waylandDisplayOption); if (socketName.isEmpty()) { @@ -576,6 +599,7 @@ int main(int argc, char *argv[]) } a.setProcessStartupEnvironment(environment); +#if KWIN_BUILD_X11 if (parser.isSet(xwaylandOption)) { a.setStartXwayland(true); @@ -601,6 +625,7 @@ int main(int argc, char *argv[]) } } } +#endif a.setApplicationsToStart(parser.positionalArguments()); a.setInputMethodServerToStart(parser.value(inputMethodOption)); diff --git a/src/main_wayland.h b/src/main_wayland.h index 3a387dda33..deb9ec7057 100644 --- a/src/main_wayland.h +++ b/src/main_wayland.h @@ -25,6 +25,7 @@ public: ApplicationWayland(int &argc, char **argv); ~ApplicationWayland() override; +#if KWIN_BUILD_X11 void setStartXwayland(bool start) { m_startXWayland = start; @@ -41,6 +42,8 @@ public: { m_xwaylandXauthority = xauthority; } + XwaylandInterface *xwayland() const override; +#endif void setApplicationsToStart(const QStringList &applications) { m_applicationsToStart = applications; @@ -54,8 +57,6 @@ public: m_sessionArgument = session; } - XwaylandInterface *xwayland() const override; - protected: void performStartup() override; @@ -64,15 +65,17 @@ private: void startSession(); void refreshSettings(const KConfigGroup &group, const QByteArrayList &names); - bool m_startXWayland = false; QStringList m_applicationsToStart; QString m_inputMethodServerToStart; QString m_sessionArgument; +#if KWIN_BUILD_X11 + bool m_startXWayland = false; std::unique_ptr m_xwayland; QList m_xwaylandListenFds; QString m_xwaylandDisplay; QString m_xwaylandXauthority; +#endif KConfigWatcher::Ptr m_settingsWatcher; }; diff --git a/src/netinfo.h b/src/netinfo.h index 4f85e8997d..47abde370f 100644 --- a/src/netinfo.h +++ b/src/netinfo.h @@ -11,6 +11,12 @@ */ #pragma once +#include "config-kwin.h" + +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif + #include #include diff --git a/src/opengl/glplatform.cpp b/src/opengl/glplatform.cpp index 00fd1223d8..83d6c6a36f 100644 --- a/src/opengl/glplatform.cpp +++ b/src/opengl/glplatform.cpp @@ -10,10 +10,13 @@ #include "opengl/glplatform.h" // include kwinglutils_funcs.h to avoid the redeclaration issues // between qopengl.h and epoxy/gl.h -#include "effect/xcb.h" #include "opengl/glutils_funcs.h" #include +#if KWIN_BUILD_X11 +#include "effect/xcb.h" +#endif + #include #include #include diff --git a/src/placement.cpp b/src/placement.cpp index 0f7b7c0e28..5379ab9797 100644 --- a/src/placement.cpp +++ b/src/placement.cpp @@ -18,9 +18,12 @@ #include "rules.h" #include "virtualdesktops.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" #endif +#endif +#include "window.h" #include #include diff --git a/src/plugins/backgroundcontrast/contrast.cpp b/src/plugins/backgroundcontrast/contrast.cpp index 409f033472..fff7389dea 100644 --- a/src/plugins/backgroundcontrast/contrast.cpp +++ b/src/plugins/backgroundcontrast/contrast.cpp @@ -13,11 +13,14 @@ #include "core/rendertarget.h" #include "core/renderviewport.h" #include "effect/effecthandler.h" -#include "utils/xcbutils.h" #include "wayland/contrast.h" #include "wayland/display.h" #include "wayland/surface.h" +#if KWIN_BUILD_X11 +#include "utils/xcbutils.h" +#endif + #include #include #include @@ -40,9 +43,11 @@ ContrastEffect::ContrastEffect() // ### Hackish way to announce support. // Should be included in _NET_SUPPORTED instead. if (m_shader && m_shader->isValid()) { +#if KWIN_BUILD_X11 if (effects->xcbConnection()) { m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this); } +#endif if (effects->waylandDisplay()) { if (!s_contrastManagerRemoveTimer) { s_contrastManagerRemoveTimer = new QTimer(QCoreApplication::instance()); @@ -61,13 +66,16 @@ ContrastEffect::ContrastEffect() connect(effects, &EffectsHandler::windowAdded, this, &ContrastEffect::slotWindowAdded); connect(effects, &EffectsHandler::windowDeleted, this, &ContrastEffect::slotWindowDeleted); - connect(effects, &EffectsHandler::propertyNotify, this, &ContrastEffect::slotPropertyNotify); connect(effects, &EffectsHandler::virtualScreenGeometryChanged, this, &ContrastEffect::slotScreenGeometryChanged); + +#if KWIN_BUILD_X11 + connect(effects, &EffectsHandler::propertyNotify, this, &ContrastEffect::slotPropertyNotify); connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { if (m_shader && m_shader->isValid()) { m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this); } }); +#endif // Fetch the contrast regions for all windows const QList windowList = effects->stackingOrder(); @@ -102,10 +110,11 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w) { QRegion region; QMatrix4x4 matrix; - float colorTransform[16]; bool valid = false; +#if KWIN_BUILD_X11 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); 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(); } +#endif SurfaceInterface *surf = w->surface(); @@ -217,12 +227,14 @@ void ContrastEffect::slotWindowDeleted(EffectWindow *w) } } +#if KWIN_BUILD_X11 void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom) { if (w && atom == m_net_wm_contrast_region && m_net_wm_contrast_region != XCB_ATOM_NONE) { updateContrastRegion(w); } } +#endif QMatrix4x4 ContrastEffect::colorMatrix(qreal contrast, qreal intensity, qreal saturation) { diff --git a/src/plugins/backgroundcontrast/contrast.h b/src/plugins/backgroundcontrast/contrast.h index 7d63d55317..6f5f639448 100644 --- a/src/plugins/backgroundcontrast/contrast.h +++ b/src/plugins/backgroundcontrast/contrast.h @@ -49,7 +49,9 @@ public: public Q_SLOTS: void slotWindowAdded(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w); +#if KWIN_BUILD_X11 void slotPropertyNotify(KWin::EffectWindow *w, long atom); +#endif void slotScreenGeometryChanged(); private: @@ -62,7 +64,10 @@ private: private: std::unique_ptr m_shader; + +#if KWIN_BUILD_X11 long m_net_wm_contrast_region = 0; +#endif QHash m_contrastChangedConnections; // used only in Wayland to keep track of effect changed struct Data { diff --git a/src/plugins/blur/blur.cpp b/src/plugins/blur/blur.cpp index a29e4710f0..f69f1b4eca 100644 --- a/src/plugins/blur/blur.cpp +++ b/src/plugins/blur/blur.cpp @@ -15,11 +15,14 @@ #include "core/renderviewport.h" #include "effect/effecthandler.h" #include "opengl/glplatform.h" -#include "utils/xcbutils.h" #include "wayland/blur.h" #include "wayland/display.h" #include "wayland/surface.h" +#if KWIN_BUILD_X11 +#include "utils/xcbutils.h" +#endif + #include #include #include @@ -94,9 +97,11 @@ BlurEffect::BlurEffect() initBlurStrengthValues(); reconfigure(ReconfigureAll); +#if KWIN_BUILD_X11 if (effects->xcbConnection()) { net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); } +#endif if (effects->waylandDisplay()) { if (!s_blurManagerRemoveTimer) { @@ -116,10 +121,12 @@ BlurEffect::BlurEffect() connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded); connect(effects, &EffectsHandler::windowDeleted, this, &BlurEffect::slotWindowDeleted); connect(effects, &EffectsHandler::screenRemoved, this, &BlurEffect::slotScreenRemoved); +#if KWIN_BUILD_X11 connect(effects, &EffectsHandler::propertyNotify, this, &BlurEffect::slotPropertyNotify); connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); }); +#endif // Fetch the blur regions for all windows const auto stackingOrder = effects->stackingOrder(); @@ -215,6 +222,7 @@ void BlurEffect::updateBlurRegion(EffectWindow *w) std::optional content; std::optional frame; +#if KWIN_BUILD_X11 if (net_wm_blur_region != XCB_ATOM_NONE) { const QByteArray value = w->readProperty(net_wm_blur_region, XCB_ATOM_CARDINAL, 32); QRegion region; @@ -232,6 +240,7 @@ void BlurEffect::updateBlurRegion(EffectWindow *w) content = region; } } +#endif 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) { if (w && atom == net_wm_blur_region && net_wm_blur_region != XCB_ATOM_NONE) { updateBlurRegion(w); } } +#endif void BlurEffect::setupDecorationConnections(EffectWindow *w) { diff --git a/src/plugins/blur/blur.h b/src/plugins/blur/blur.h index 880880757d..9e488b949a 100644 --- a/src/plugins/blur/blur.h +++ b/src/plugins/blur/blur.h @@ -71,7 +71,9 @@ public Q_SLOTS: void slotWindowAdded(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w); void slotScreenRemoved(KWin::Output *screen); +#if KWIN_BUILD_X11 void slotPropertyNotify(KWin::EffectWindow *w, long atom); +#endif void setupDecorationConnections(EffectWindow *w); private: @@ -114,7 +116,9 @@ private: } m_noisePass; bool m_valid = false; +#if KWIN_BUILD_X11 long net_wm_blur_region = 0; +#endif 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) Output *m_currentScreen = nullptr; diff --git a/src/plugins/buttonrebinds/CMakeLists.txt b/src/plugins/buttonrebinds/CMakeLists.txt index 0611e0b651..5a8e00e451 100644 --- a/src/plugins/buttonrebinds/CMakeLists.txt +++ b/src/plugins/buttonrebinds/CMakeLists.txt @@ -14,4 +14,4 @@ target_sources(buttonsrebind PRIVATE main.cpp buttonrebindsfilter.cpp ) -target_link_libraries(buttonsrebind PRIVATE kwin KF6::WindowSystem XKB::XKB) +target_link_libraries(buttonsrebind PRIVATE kwin Qt::GuiPrivate XKB::XKB) diff --git a/src/plugins/buttonrebinds/buttonrebindsfilter.cpp b/src/plugins/buttonrebinds/buttonrebindsfilter.cpp index 44424cc8fa..df54678060 100644 --- a/src/plugins/buttonrebinds/buttonrebindsfilter.cpp +++ b/src/plugins/buttonrebinds/buttonrebindsfilter.cpp @@ -13,8 +13,6 @@ #include "keyboard_input.h" #include "xkb.h" -#include - #include #include @@ -23,6 +21,8 @@ #include #include +#include + // Tells us that we are already in a binding event class RebindScope { @@ -300,7 +300,8 @@ bool ButtonRebindsFilter::sendKeySequence(const QKeySequence &keys, bool pressed } } - const QList syms(KKeyServer::keyQtToSymXs(keys[0])); + QKeyEvent ev(QEvent::KeyPress, keys[0], Qt::NoModifier); + const QList syms(QXkbCommon::toKeysym(&ev)); if (syms.empty()) { qCWarning(KWIN_BUTTONREBINDS) << "Could not convert" << keys << "to keysym"; return false; diff --git a/src/plugins/highlightwindow/highlightwindow.cpp b/src/plugins/highlightwindow/highlightwindow.cpp index f20929293c..a879ccca8a 100644 --- a/src/plugins/highlightwindow/highlightwindow.cpp +++ b/src/plugins/highlightwindow/highlightwindow.cpp @@ -23,17 +23,19 @@ HighlightWindowEffect::HighlightWindowEffect() , m_fadeDuration(animationTime(150)) , m_monitorWindow(nullptr) { +#if KWIN_BUILD_X11 // TODO KF6 remove atom support 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]() { 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"), QStringLiteral("org.kde.KWin.HighlightWindow"), @@ -93,7 +95,9 @@ void HighlightWindowEffect::slotWindowAdded(EffectWindow *w) complete(animationId); } } +#if KWIN_BUILD_X11 slotPropertyNotify(w, m_atom, w); // Check initial value +#endif } void HighlightWindowEffect::slotWindowClosed(EffectWindow *w) @@ -108,6 +112,7 @@ void HighlightWindowEffect::slotWindowDeleted(EffectWindow *w) m_animations.remove(w); } +#if KWIN_BUILD_X11 void HighlightWindowEffect::slotPropertyNotify(EffectWindow *w, long a, EffectWindow *addedWindow) { if (a != m_atom || m_atom == XCB_ATOM_NONE) { @@ -156,6 +161,7 @@ void HighlightWindowEffect::slotPropertyNotify(EffectWindow *w, long a, EffectWi } prepareHighlighting(); } +#endif void HighlightWindowEffect::prepareHighlighting() { diff --git a/src/plugins/highlightwindow/highlightwindow.h b/src/plugins/highlightwindow/highlightwindow.h index 516ec2b4ef..1388323578 100644 --- a/src/plugins/highlightwindow/highlightwindow.h +++ b/src/plugins/highlightwindow/highlightwindow.h @@ -9,6 +9,8 @@ #pragma once +#include "config-kwin.h" + #include "effect/animationeffect.h" namespace KWin @@ -35,7 +37,9 @@ public Q_SLOTS: void slotWindowAdded(KWin::EffectWindow *w); void slotWindowClosed(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w); +#if KWIN_BUILD_X11 void slotPropertyNotify(KWin::EffectWindow *w, long atom, EffectWindow *addedWindow = nullptr); +#endif private: quint64 startGhostAnimation(EffectWindow *window); @@ -48,7 +52,9 @@ private: void finishHighlighting(); void highlightWindows(const QList &windows); +#if KWIN_BUILD_X11 long m_atom; +#endif QList m_highlightedWindows; QHash m_animations; QEasingCurve m_easingCurve; diff --git a/src/plugins/kscreen/kscreen.cpp b/src/plugins/kscreen/kscreen.cpp index ea2c4bce17..26c44299a0 100644 --- a/src/plugins/kscreen/kscreen.cpp +++ b/src/plugins/kscreen/kscreen.cpp @@ -46,15 +46,19 @@ namespace KWin KscreenEffect::KscreenEffect() : Effect() +#if KWIN_BUILD_X11 , m_atom(effects->waylandDisplay() ? XCB_ATOM_NONE : effects->announceSupportProperty("_KDE_KWIN_KSCREEN_SUPPORT", this)) +#endif { KscreenConfig::instance(effects->config()); +#if KWIN_BUILD_X11 if (!effects->waylandDisplay()) { connect(effects, &EffectsHandler::propertyNotify, this, &KscreenEffect::propertyNotify); connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() { m_atom = effects->announceSupportProperty(QByteArrayLiteral("_KDE_KWIN_KSCREEN_SUPPORT"), this); }); } +#endif reconfigure(ReconfigureAll); const QList screens = effects->screens(); @@ -173,6 +177,7 @@ void KscreenEffect::setState(ScreenState &state, FadeOutState newState) effects->addRepaintFull(); } +#if KWIN_BUILD_X11 void KscreenEffect::propertyNotify(EffectWindow *window, long int atom) { 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])); } +#endif void KscreenEffect::switchState(ScreenState &state) { @@ -202,19 +208,29 @@ void KscreenEffect::switchState(ScreenState &state) state.m_state = StateNormal; value = 0l; } +#if KWIN_BUILD_X11 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); } +#endif } 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 { - 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 diff --git a/src/plugins/kscreen/kscreen.h b/src/plugins/kscreen/kscreen.h index ffd35da458..38d26e7ec0 100644 --- a/src/plugins/kscreen/kscreen.h +++ b/src/plugins/kscreen/kscreen.h @@ -37,8 +37,10 @@ public: return 99; } +#if KWIN_BUILD_X11 private Q_SLOTS: void propertyNotify(KWin::EffectWindow *window, long atom); +#endif private: enum FadeOutState { @@ -62,7 +64,9 @@ private: QHash m_waylandStates; ScreenState m_xcbState; Output *m_currentScreen = nullptr; +#if KWIN_BUILD_X11 xcb_atom_t m_atom; +#endif }; } // namespace KWin diff --git a/src/plugins/slidingpopups/slidingpopups.cpp b/src/plugins/slidingpopups/slidingpopups.cpp index ac3c2a2869..e156c9e69b 100644 --- a/src/plugins/slidingpopups/slidingpopups.cpp +++ b/src/plugins/slidingpopups/slidingpopups.cpp @@ -53,14 +53,16 @@ SlidingPopupsEffect::SlidingPopupsEffect() m_slideLength = QFontMetrics(QGuiApplication::font()).height() * 8; +#if KWIN_BUILD_X11 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]() { 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, this, &SlidingPopupsEffect::stopAnimations); connect(effects, &EffectsHandler::activeFullScreenEffectChanged, @@ -209,10 +211,12 @@ void SlidingPopupsEffect::setupSlideData(EffectWindow *w) connect(w, &EffectWindow::windowFrameGeometryChanged, this, &SlidingPopupsEffect::slotWindowFrameGeometryChanged); connect(w, &EffectWindow::windowHiddenChanged, this, &SlidingPopupsEffect::slotWindowHiddenChanged); +#if KWIN_BUILD_X11 // X11 if (m_atom != XCB_ATOM_NONE) { slotPropertyNotify(w, m_atom); } +#endif // Wayland 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) { if (!w || atom != m_atom || m_atom == XCB_ATOM_NONE) { @@ -333,6 +338,7 @@ void SlidingPopupsEffect::slotPropertyNotify(EffectWindow *w, long atom) setupAnimData(w); } +#endif void SlidingPopupsEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const QRectF &) { diff --git a/src/plugins/slidingpopups/slidingpopups.h b/src/plugins/slidingpopups/slidingpopups.h index c697b138e3..74a79efa5e 100644 --- a/src/plugins/slidingpopups/slidingpopups.h +++ b/src/plugins/slidingpopups/slidingpopups.h @@ -11,6 +11,8 @@ #pragma once // Include with base class for effects. +#include "config-kwin.h" + #include "effect/effect.h" #include "effect/effectwindow.h" #include "effect/timeline.h" @@ -52,7 +54,9 @@ private Q_SLOTS: void slotWindowAdded(EffectWindow *w); void slotWindowClosed(EffectWindow *w); void slotWindowDeleted(EffectWindow *w); +#if KWIN_BUILD_X11 void slotPropertyNotify(EffectWindow *w, long atom); +#endif void slotWaylandSlideOnShowChanged(EffectWindow *w); void slotWindowFrameGeometryChanged(EffectWindow *w, const QRectF &); void slotWindowHiddenChanged(EffectWindow *w); @@ -69,7 +73,9 @@ private: static SlideManagerInterface *s_slideManager; static QTimer *s_slideManagerRemoveTimer; +#if KWIN_BUILD_X11 long m_atom = 0; +#endif int m_slideLength; std::chrono::milliseconds m_slideInDuration; diff --git a/src/plugins/startupfeedback/startupfeedback.cpp b/src/plugins/startupfeedback/startupfeedback.cpp index abd3312248..36f94837fb 100644 --- a/src/plugins/startupfeedback/startupfeedback.cpp +++ b/src/plugins/startupfeedback/startupfeedback.cpp @@ -20,7 +20,9 @@ #include // KDE #include +#if KWIN_BUILD_X11 #include +#endif #include #include // KWin @@ -72,8 +74,10 @@ static const int s_startupDefaultTimeout = 5; StartupFeedbackEffect::StartupFeedbackEffect() : m_bounceSizesRatio(1.0) +#if KWIN_BUILD_X11 , m_startupInfo(new KStartupInfo(KStartupInfo::CleanOnCantDetect, this)) , m_selection(nullptr) +#endif , m_active(false) , m_frame(0) , m_progress(0) @@ -83,6 +87,7 @@ StartupFeedbackEffect::StartupFeedbackEffect() , m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("klaunchrc", KConfig::NoGlobals))) , m_splashVisible(false) { +#if KWIN_BUILD_X11 // TODO: move somewhere that is x11-specific if (KWindowSystem::isPlatformX11()) { 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"))); Q_EMIT effects->startupChanged(id.id(), icon); }); +#endif connect(effects, &EffectsHandler::startupAdded, this, &StartupFeedbackEffect::gotNewStartup); connect(effects, &EffectsHandler::startupRemoved, this, &StartupFeedbackEffect::gotRemoveStartup); @@ -141,7 +147,9 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags) c = m_configWatcher->config()->group(QStringLiteral("BusyCursorSettings")); m_timeout = std::chrono::seconds(c.readEntry("Timeout", s_startupDefaultTimeout)); +#if KWIN_BUILD_X11 m_startupInfo->setTimeout(m_timeout.count()); +#endif const bool busyBlinking = c.readEntry("Blinking", false); const bool busyBouncing = c.readEntry("Bouncing", true); if (!busyCursor) { diff --git a/src/plugins/startupfeedback/startupfeedback.h b/src/plugins/startupfeedback/startupfeedback.h index 1a5399c4e7..7a757d268d 100644 --- a/src/plugins/startupfeedback/startupfeedback.h +++ b/src/plugins/startupfeedback/startupfeedback.h @@ -10,7 +10,11 @@ #pragma once #include "effect/effect.h" #include + +#if KWIN_BUILD_X11 #include +#endif +#include #include #include @@ -77,8 +81,10 @@ private: QSize feedbackIconSize() const; qreal m_bounceSizesRatio; +#if KWIN_BUILD_X11 KStartupInfo *m_startupInfo; KSelectionOwner *m_selection; +#endif QString m_currentStartup; QMap m_startups; bool m_active; diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 60d1e9bcf1..cea3868ab3 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -27,14 +27,17 @@ #include "wayland/seat.h" #include "wayland/surface.h" #include "wayland_server.h" +#include "window.h" #include "workspace.h" -#include "x11window.h" // KDecoration #include // screenlocker #if KWIN_BUILD_SCREENLOCKER #include #endif +#if KWIN_BUILD_X11 +#include "x11window.h" +#endif #include diff --git a/src/rootinfo_filter.h b/src/rootinfo_filter.h index 8a53aec42a..3428c0ea61 100644 --- a/src/rootinfo_filter.h +++ b/src/rootinfo_filter.h @@ -7,6 +7,11 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once +#include "config-kwin.h" + +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif #include "x11eventfilter.h" diff --git a/src/scene/surfaceitem_wayland.cpp b/src/scene/surfaceitem_wayland.cpp index 82863c3a45..eabc4836cc 100644 --- a/src/scene/surfaceitem_wayland.cpp +++ b/src/scene/surfaceitem_wayland.cpp @@ -11,7 +11,10 @@ #include "wayland/subcompositor.h" #include "wayland/surface.h" #include "window.h" + +#if KWIN_BUILD_X11 #include "x11window.h" +#endif namespace KWin { @@ -208,6 +211,7 @@ bool SurfacePixmapWayland::isValid() const return m_bufferRef; } +#if KWIN_BUILD_X11 SurfaceItemXwayland::SurfaceItemXwayland(X11Window *window, Scene *scene, Item *parent) : SurfaceItemWayland(window->surface(), scene, parent) , m_window(window) @@ -237,6 +241,7 @@ QRegion SurfaceItemXwayland::opaque() const } return QRegion(); } +#endif } // namespace KWin diff --git a/src/scene/surfaceitem_wayland.h b/src/scene/surfaceitem_wayland.h index ab31192cb9..7e3c7a0980 100644 --- a/src/scene/surfaceitem_wayland.h +++ b/src/scene/surfaceitem_wayland.h @@ -74,6 +74,7 @@ private: SurfaceItemWayland *m_item; }; +#if KWIN_BUILD_X11 /** * The SurfaceItemXwayland class represents an Xwayland surface in the scene. */ @@ -90,5 +91,6 @@ public: private: X11Window *m_window; }; +#endif } // namespace KWin diff --git a/src/scene/windowitem.cpp b/src/scene/windowitem.cpp index ec1ce942bd..40cf80c6b0 100644 --- a/src/scene/windowitem.cpp +++ b/src/scene/windowitem.cpp @@ -16,7 +16,9 @@ #include "wayland_server.h" #include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif #include @@ -300,6 +302,7 @@ void WindowItem::freeze() } } +#if KWIN_BUILD_X11 WindowItemX11::WindowItemX11(X11Window *window, Scene *scene, Item *parent) : WindowItem(window, scene, parent) { @@ -326,6 +329,7 @@ void WindowItemX11::initialize() Q_UNREACHABLE(); } } +#endif WindowItemWayland::WindowItemWayland(Window *window, Scene *scene, Item *parent) : WindowItem(window, scene, parent) diff --git a/src/scene/windowitem.h b/src/scene/windowitem.h index 9774ad38e3..d49e895db7 100644 --- a/src/scene/windowitem.h +++ b/src/scene/windowitem.h @@ -6,6 +6,8 @@ #pragma once +#include "config-kwin.h" + #include "scene/item.h" namespace KDecoration2 @@ -88,6 +90,7 @@ private: int m_forceVisibleByActivityCount = 0; }; +#if KWIN_BUILD_X11 /** * The WindowItemX11 class represents an X11 window (both on X11 and Wayland sessions). * @@ -104,6 +107,7 @@ public: private Q_SLOTS: void initialize(); }; +#endif /** * The WindowItemWayland class represents a Wayland window. diff --git a/src/scene/workspacescene.cpp b/src/scene/workspacescene.cpp index 671ed747d7..5f5bcb972d 100644 --- a/src/scene/workspacescene.cpp +++ b/src/scene/workspacescene.cpp @@ -61,6 +61,7 @@ #include "core/renderviewport.h" #include "effect/effecthandler.h" #include "internalwindow.h" +#include "scene/decorationitem.h" #include "scene/dndiconitem.h" #include "scene/itemrenderer.h" #include "scene/shadowitem.h" @@ -71,8 +72,11 @@ #include "wayland/surface.h" #include "wayland_server.h" #include "waylandwindow.h" +#include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif #include diff --git a/src/screenedge.cpp b/src/screenedge.cpp index 7c7b1776fb..da0ea2f27d 100644 --- a/src/screenedge.cpp +++ b/src/screenedge.cpp @@ -30,8 +30,11 @@ #include "virtualdesktops.h" #include "wayland/seat.h" #include "wayland_server.h" +#include #include -#include +#if KWIN_BUILD_X11 +#include "x11window.h" +#endif // DBus generated #if KWIN_BUILD_SCREENLOCKER #include "screenlocker_interface.h" @@ -49,6 +52,7 @@ #include #include #include +#include namespace KWin { @@ -1463,6 +1467,7 @@ bool ScreenEdges::isEntered(QMouseEvent *event) return activated; } +#if KWIN_BUILD_X11 bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime ×tamp) { bool activated = false; @@ -1501,7 +1506,16 @@ bool ScreenEdges::handleEnterNotifiy(xcb_window_t window, const QPoint &point, c } 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) { for (const auto &edge : m_edges) { @@ -1517,11 +1531,6 @@ bool ScreenEdges::handleDndNotify(xcb_window_t window, const QPoint &point) return false; } -void ScreenEdges::ensureOnTop() -{ - Xcb::restackWindowsWithRaise(windows()); -} - QList ScreenEdges::windows() const { QList wins; @@ -1538,6 +1547,7 @@ QList ScreenEdges::windows() const } return wins; } +#endif void ScreenEdges::setRemainActiveOnFullscreen(bool remainActive) { diff --git a/src/screenedge.h b/src/screenedge.h index 208caeb1c1..6b7f5740f0 100644 --- a/src/screenedge.h +++ b/src/screenedge.h @@ -331,11 +331,13 @@ public: void ensureOnTop(); bool isEntered(QMouseEvent *event); +#if KWIN_BUILD_X11 /** * Returns a QList of all existing screen edge windows * @return all existing screen edge windows in a QList */ QList windows() const; +#endif bool isDesktopSwitching() const; bool isDesktopSwitchingMovingClients() const; @@ -364,8 +366,10 @@ public: return m_gestureRecognizer; } +#if KWIN_BUILD_X11 bool handleDndNotify(xcb_window_t window, const QPoint &point); bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime ×tamp); +#endif bool remainActiveOnFullscreen() const; const std::vector> &edges() const; diff --git a/src/scripting/workspace_wrapper.cpp b/src/scripting/workspace_wrapper.cpp index a966b35a25..aaf5fb1002 100644 --- a/src/scripting/workspace_wrapper.cpp +++ b/src/scripting/workspace_wrapper.cpp @@ -16,11 +16,14 @@ #include "outline.h" #include "tiles/tilemanager.h" #include "virtualdesktops.h" +#include "window.h" #include "workspace.h" -#include "x11window.h" #if KWIN_BUILD_ACTIVITIES #include "activities.h" #endif +#if KWIN_BUILD_X11 +#include "x11window.h" +#endif #include @@ -292,12 +295,14 @@ void WorkspaceWrapper::raiseWindow(KWin::Window *window) } } +#if KWIN_BUILD_X11 Window *WorkspaceWrapper::getClient(qulonglong windowId) { auto window = Workspace::self()->findClient(Predicate::WindowMatch, windowId); QQmlEngine::setObjectOwnership(window, QQmlEngine::CppOwnership); return window; } +#endif QList WorkspaceWrapper::windowAt(const QPointF &pos, int count) const { diff --git a/src/scripting/workspace_wrapper.h b/src/scripting/workspace_wrapper.h index d4edf62b8e..cc5edbe6cd 100644 --- a/src/scripting/workspace_wrapper.h +++ b/src/scripting/workspace_wrapper.h @@ -240,12 +240,14 @@ public: * @param window The Window to raise */ Q_INVOKABLE void raiseWindow(KWin::Window *window); +#if KWIN_BUILD_X11 /** * Finds the Client with the given @p windowId. * @param windowId The window Id of the Client * @return The found Client or @c null */ Q_SCRIPTABLE KWin::Window *getClient(qulonglong windowId); +#endif /** * Finds up to count windows at a particular location, * prioritizing the topmost one first. A negative count diff --git a/src/shadow.cpp b/src/shadow.cpp index 6afc3f1fe1..36b13a526d 100644 --- a/src/shadow.cpp +++ b/src/shadow.cpp @@ -9,13 +9,16 @@ */ #include "shadow.h" // kwin -#include "atoms.h" #include "core/graphicsbufferview.h" #include "internalwindow.h" #include "wayland/shadow.h" #include "wayland/surface.h" #include "wayland_server.h" +#include "window.h" +#if KWIN_BUILD_X11 +#include "atoms.h" #include "x11window.h" +#endif #include #include @@ -45,15 +48,18 @@ std::unique_ptr Shadow::createShadow(Window *window) if (!shadow && waylandServer()) { shadow = createShadowFromWayland(window); } +#if KWIN_BUILD_X11 if (!shadow && kwinApp()->x11Connection()) { shadow = createShadowFromX11(window); } +#endif if (!shadow) { shadow = createShadowFromInternalWindow(window); } return shadow; } +#if KWIN_BUILD_X11 std::unique_ptr Shadow::createShadowFromX11(Window *window) { X11Window *x11Window = qobject_cast(window); @@ -71,6 +77,7 @@ std::unique_ptr Shadow::createShadowFromX11(Window *window) return nullptr; } } +#endif std::unique_ptr Shadow::createShadowFromDecoration(Window *window) { @@ -118,6 +125,7 @@ std::unique_ptr Shadow::createShadowFromInternalWindow(Window *window) return shadow; } +#if KWIN_BUILD_X11 QList Shadow::readX11ShadowProperty(xcb_window_t id) { QList ret; @@ -133,9 +141,11 @@ QList Shadow::readX11ShadowProperty(xcb_window_t id) } return ret; } +#endif bool Shadow::init(const QList &data) { +#if KWIN_BUILD_X11 QList pixmapGeometries(ShadowElementsCount); QList getImageCookies(ShadowElementsCount); auto *c = kwinApp()->x11Connection(); @@ -167,6 +177,7 @@ bool Shadow::init(const QList &data) m_shadowElements[i] = image.copy(); free(reply); } +#endif m_offset = QMargins(data[ShadowElementsCount + 3], data[ShadowElementsCount], data[ShadowElementsCount + 1], @@ -295,6 +306,7 @@ bool Shadow::updateShadow() } } +#if KWIN_BUILD_X11 if (X11Window *window = qobject_cast(m_window)) { auto data = Shadow::readX11ShadowProperty(window->window()); if (!data.isEmpty()) { @@ -302,6 +314,7 @@ bool Shadow::updateShadow() return true; } } +#endif return false; } diff --git a/src/sm.cpp b/src/sm.cpp index 22ce33e0eb..e676793cf4 100644 --- a/src/sm.cpp +++ b/src/sm.cpp @@ -18,9 +18,11 @@ #include "virtualdesktops.h" #include "wayland_server.h" #include "workspace.h" -#include "x11window.h" #include "xdgshellwindow.h" #include +#if KWIN_BUILD_X11 +#include "x11window.h" +#endif #include #if KWIN_BUILD_NOTIFICATIONS @@ -95,6 +97,7 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase) int count = 0; int active_client = -1; +#if KWIN_BUILD_X11 const QList windows = workspace()->windows(); for (auto it = windows.begin(); it != windows.end(); ++it) { X11Window *c = qobject_cast(*it); @@ -123,6 +126,7 @@ void SessionManager::storeSession(const QString &sessionName, SMSavePhase phase) storeClient(cg, count, c); } } +#endif if (phase == SMSavePhase0) { // it would be much simpler to save these values to the config file, // 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 } +#if KWIN_BUILD_X11 void SessionManager::storeClient(KConfigGroup &cg, int num, X11Window *c) { 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("activities") + n, c->activities()); } +#endif +#if KWIN_BUILD_X11 void SessionManager::storeSubSession(const QString &name, QSet sessionIds) { // TODO clear it first @@ -217,6 +224,7 @@ void SessionManager::storeSubSession(const QString &name, QSet sessi cg.writeEntry("active", active_client); // cg.writeEntry( "desktop", currentDesktop()); } +#endif /** * Loads the session information from the config file. @@ -275,6 +283,7 @@ void SessionManager::loadSubSessionInfo(const QString &name) addSessionInfo(cg); } +#if KWIN_BUILD_X11 static bool sessionInfoWindowTypeMatch(X11Window *c, SessionInfo *info) { if (int(info->windowType) == -2) { @@ -343,6 +352,7 @@ SessionInfo *SessionManager::takeSessionInfo(X11Window *c) } return realInfo; } +#endif SessionManager::SessionManager(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 (m_sessionState == SessionState::Saving) { workspace()->rulebook()->setUpdatesDisabled(false); +#if KWIN_BUILD_X11 Workspace::self()->forEachClient([](X11Window *client) { client->setSessionActivityOverride(false); }); +#endif } m_sessionState = state; diff --git a/src/sm.h b/src/sm.h index d37e706e08..625b8f508b 100644 --- a/src/sm.h +++ b/src/sm.h @@ -43,9 +43,11 @@ public: SessionState state() const; void loadSubSessionInfo(const QString &name); - void storeSubSession(const QString &name, QSet sessionIds); +#if KWIN_BUILD_X11 + void storeSubSession(const QString &name, QSet sessionIds); SessionInfo *takeSessionInfo(X11Window *); +#endif Q_SIGNALS: void stateChanged(); @@ -66,7 +68,9 @@ private: void setState(SessionState state); void storeSession(const QString &sessionName, SMSavePhase phase); +#if KWIN_BUILD_X11 void storeClient(KConfigGroup &cg, int num, X11Window *c); +#endif void loadSessionInfo(const QString &sessionName); void addSessionInfo(KConfigGroup &cg); diff --git a/src/tabbox/tabbox.cpp b/src/tabbox/tabbox.cpp index 60b493cf3f..8e5cc30e53 100644 --- a/src/tabbox/tabbox.cpp +++ b/src/tabbox/tabbox.cpp @@ -16,7 +16,6 @@ #include "tabbox/clientmodel.h" #include "tabbox/tabbox_logging.h" #include "tabbox/tabboxconfig.h" -#include "tabbox/x11_filter.h" // kwin #if KWIN_BUILD_ACTIVITIES #include "activities.h" @@ -28,10 +27,12 @@ #include "keyboard_input.h" #include "pointer_input.h" #include "screenedge.h" -#include "utils/xcbutils.h" #include "virtualdesktops.h" +#include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif // Qt #include #include @@ -42,12 +43,15 @@ #include #include #include +#if KWIN_BUILD_X11 +#include "tabbox/x11_filter.h" +#include "utils/xcbutils.h" // X11 #include #include // xcb #include - +#endif // specify externals before namespace namespace KWin @@ -666,6 +670,7 @@ void TabBox::grabbedKeyEvent(QKeyEvent *event) m_tabBox->grabbedKeyEvent(event); } +#if KWIN_BUILD_X11 struct KeySymbolsDeleter { void operator()(xcb_key_symbols_t *symbols) @@ -751,6 +756,7 @@ static bool areModKeysDepressedX11(const QKeySequence &seq) return areKeySymXsDepressed(rgKeySyms, nKeySyms); } +#endif static bool areModKeysDepressedWayland(const QKeySequence &seq) { @@ -776,11 +782,15 @@ static bool areModKeysDepressed(const QKeySequence &seq) if (seq.isEmpty()) { return false; } +#if KWIN_BUILD_X11 if (kwinApp()->shouldUseWaylandForCompositing()) { return areModKeysDepressedWayland(seq); } else { return areModKeysDepressedX11(seq); } +#else + return areModKeysDepressedWayland(seq); +#endif } void TabBox::navigatingThroughWindows(bool forward, const QKeySequence &shortcut, TabBoxMode mode) @@ -1178,10 +1188,12 @@ bool TabBox::establishTabBoxGrab() m_forcedGlobalMouseGrab = true; return true; } +#if KWIN_BUILD_X11 kwinApp()->updateXTime(); if (!grabXKeyboard()) { return false; } +#endif // 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 // in order to catch MouseRelease events and close the tabbox (#67416). @@ -1192,7 +1204,9 @@ bool TabBox::establishTabBoxGrab() if (Workspace::self()->activeWindow() != nullptr) { Workspace::self()->activeWindow()->updateMouseGrab(); } +#if KWIN_BUILD_X11 m_x11EventFilter = std::make_unique(); +#endif return true; } @@ -1202,14 +1216,19 @@ void TabBox::removeTabBoxGrab() m_forcedGlobalMouseGrab = false; return; } +#if KWIN_BUILD_X11 kwinApp()->updateXTime(); ungrabXKeyboard(); +#endif Q_ASSERT(m_forcedGlobalMouseGrab); m_forcedGlobalMouseGrab = false; if (Workspace::self()->activeWindow() != nullptr) { Workspace::self()->activeWindow()->updateMouseGrab(); } + +#if KWIN_BUILD_X11 m_x11EventFilter.reset(); +#endif } } // namespace TabBox } // namespace diff --git a/src/tabbox/tabbox.h b/src/tabbox/tabbox.h index 6731eb003d..ec4ca2ba28 100644 --- a/src/tabbox/tabbox.h +++ b/src/tabbox/tabbox.h @@ -273,7 +273,10 @@ private: QList m_borderActivate, m_borderAlternativeActivate; QHash m_touchActivate; QHash m_touchAlternativeActivate; + +#if KWIN_BUILD_X11 std::unique_ptr m_x11EventFilter; +#endif }; } // namespace TabBox diff --git a/src/useractions.cpp b/src/useractions.cpp index 8f8cbe2b39..9b8fe2004c 100644 --- a/src/useractions.cpp +++ b/src/useractions.cpp @@ -32,8 +32,11 @@ #include "scripting/scripting.h" #include "useractions.h" #include "virtualdesktops.h" +#include "window.h" #include "workspace.h" +#if KWIN_BUILD_X11 #include "x11window.h" +#endif #if KWIN_BUILD_ACTIVITIES #include "activities.h" @@ -46,6 +49,7 @@ #include #include #include +#include #include #include @@ -1819,19 +1823,6 @@ void Window::setShortcutInternal() 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 { if (ignore && cut == ignore->shortcut()) { diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 629d17b869..e2ed52cf3d 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -10,9 +10,11 @@ target_sources(kwin PRIVATE subsurfacemonitor.cpp udev.cpp vsyncmonitor.cpp - xcbutils.cpp xcursortheme.cpp ) +if (KWIN_BUILD_X11) + target_sources(kwin PRIVATE xcbutils.cpp) +endif() if(CMAKE_SYSTEM_NAME MATCHES "Linux") target_sources(kwin PRIVATE executable_path_proc.cpp) diff --git a/src/utils/common.cpp b/src/utils/common.cpp index 3375fca4ee..547d7ce4e9 100644 --- a/src/utils/common.cpp +++ b/src/utils/common.cpp @@ -15,12 +15,15 @@ */ #include "utils/common.h" -#include "effect/xcb.h" #include "utils/c_ptr.h" +#if KWIN_BUILD_X11 +#include "effect/xcb.h" +#include +#endif + #include #include -#include #ifndef KCMRULES #include @@ -67,6 +70,8 @@ StrutRect &StrutRect::operator=(const StrutRect &other) return *this; } +#if KWIN_BUILD_X11 + static int server_grab_count = 0; void grabXServer() @@ -128,8 +133,6 @@ void ungrabXKeyboard() xcb_ungrab_keyboard(connection(), XCB_TIME_CURRENT_TIME); } -#endif - // converting between X11 mouse/keyboard state mask and Qt button/keyboard states Qt::MouseButton x11ToQtMouseButton(int button) @@ -191,6 +194,61 @@ Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state) 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 geometry = rect; @@ -223,6 +281,3 @@ QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravi } } // namespace - -#ifndef KCMRULES -#endif diff --git a/src/utils/common.h b/src/utils/common.h index 5250f4a159..cdfc75f635 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -84,11 +84,13 @@ inline MaximizeMode operator^(MaximizeMode m1, MaximizeMode m2) return MaximizeMode(int(m1) ^ int(m2)); } +#if KWIN_BUILD_X11 // converting between X11 mouse/keyboard state mask and Qt button/keyboard states Qt::MouseButton x11ToQtMouseButton(int button); Qt::MouseButton KWIN_EXPORT x11ToQtMouseButton(int button); Qt::MouseButtons KWIN_EXPORT x11ToQtMouseButtons(int state); Qt::KeyboardModifiers KWIN_EXPORT x11ToQtKeyboardModifiers(int state); +#endif KWIN_EXPORT QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity); diff --git a/src/utils/xcbutils.h b/src/utils/xcbutils.h index 98d19b1fe7..03ca03f098 100644 --- a/src/utils/xcbutils.h +++ b/src/utils/xcbutils.h @@ -8,6 +8,12 @@ */ #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/xcb.h" #include "main.h" diff --git a/src/virtualdesktops.cpp b/src/virtualdesktops.cpp index 0fb3986a64..a0a09040d4 100644 --- a/src/virtualdesktops.cpp +++ b/src/virtualdesktops.cpp @@ -14,7 +14,9 @@ #include #include #include +#if KWIN_BUILD_X11 #include +#endif // Qt #include @@ -196,7 +198,9 @@ KWIN_SINGLETON_FACTORY_VARIABLE(VirtualDesktopManager, s_manager) VirtualDesktopManager::VirtualDesktopManager(QObject *parent) : QObject(parent) , m_navigationWrapsAround(false) +#if KWIN_BUILD_X11 , m_rootInfo(nullptr) +#endif , m_swipeGestureReleasedY(new QAction(this)) , m_swipeGestureReleasedX(new QAction(this)) { @@ -209,6 +213,7 @@ VirtualDesktopManager::~VirtualDesktopManager() void VirtualDesktopManager::setRootInfo(NETRootInfo *info) { +#if KWIN_BUILD_X11 m_rootInfo = info; // Nothing will be connected to rootInfo @@ -219,6 +224,7 @@ void VirtualDesktopManager::setRootInfo(NETRootInfo *info) m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); } } +#endif } VirtualDesktop *VirtualDesktopManager::inDirection(VirtualDesktop *desktop, Direction direction, bool wrap) @@ -428,6 +434,7 @@ VirtualDesktop *VirtualDesktopManager::createVirtualDesktop(uint position, const vd->setId(generateDesktopId()); vd->setName(desktopName); +#if KWIN_BUILD_X11 connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() { if (m_rootInfo) { m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); @@ -437,15 +444,18 @@ VirtualDesktop *VirtualDesktopManager::createVirtualDesktop(uint position, const if (m_rootInfo) { m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); } +#endif m_desktops.insert(position, vd); // update the id of displaced desktops for (uint i = position + 1; i < (uint)m_desktops.count(); ++i) { m_desktops[i]->setX11DesktopNumber(i + 1); +#if KWIN_BUILD_X11 if (m_rootInfo) { m_rootInfo->setDesktopName(i + 1, m_desktops[i]->name().toUtf8().data()); } +#endif } save(); @@ -477,9 +487,11 @@ void VirtualDesktopManager::removeVirtualDesktop(VirtualDesktop *desktop) for (int j = i; j < m_desktops.count(); ++j) { m_desktops[j]->setX11DesktopNumber(j + 1); +#if KWIN_BUILD_X11 if (m_rootInfo) { m_rootInfo->setDesktopName(j + 1, m_desktops[j]->name().toUtf8().data()); } +#endif } if (m_current == desktop) { @@ -562,6 +574,7 @@ void VirtualDesktopManager::setCount(uint count) } m_desktops << vd; newDesktops << vd; +#if KWIN_BUILD_X11 connect(vd, &VirtualDesktop::nameChanged, this, [this, vd]() { if (m_rootInfo) { m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); @@ -570,6 +583,7 @@ void VirtualDesktopManager::setCount(uint count) if (m_rootInfo) { m_rootInfo->setDesktopName(vd->x11DesktopNumber(), vd->name().toUtf8().data()); } +#endif } } @@ -608,6 +622,7 @@ void VirtualDesktopManager::setRows(uint rows) void VirtualDesktopManager::updateRootInfo() { +#if KWIN_BUILD_X11 if (m_rootInfo) { const int n = count(); m_rootInfo->setNumberOfDesktops(n); @@ -616,6 +631,7 @@ void VirtualDesktopManager::updateRootInfo() delete[] viewports; m_rootInfo->setDesktopLayout(NET::OrientationHorizontal, m_grid.width(), m_grid.height(), NET::DesktopLayoutCornerTopLeft); } +#endif } void VirtualDesktopManager::updateLayout() @@ -646,9 +662,11 @@ void VirtualDesktopManager::load() for (int i = 1; i <= n; i++) { QString s = group.readEntry(QStringLiteral("Name_%1").arg(i), i18n("Desktop %1", i)); +#if KWIN_BUILD_X11 if (m_rootInfo) { m_rootInfo->setDesktopName(i, s.toUtf8().data()); } +#endif m_desktops[i - 1]->setName(s); const QString sId = group.readEntry(QStringLiteral("Id_%1").arg(i), QString()); @@ -692,9 +710,11 @@ void VirtualDesktopManager::save() const QString defaultvalue = defaultName(position); if (s.isEmpty()) { s = defaultvalue; +#if KWIN_BUILD_X11 if (m_rootInfo) { m_rootInfo->setDesktopName(position, s.toUtf8().data()); } +#endif } if (s != defaultvalue) { diff --git a/src/virtualdesktops.h b/src/virtualdesktops.h index c63d94fe78..9232369633 100644 --- a/src/virtualdesktops.h +++ b/src/virtualdesktops.h @@ -481,7 +481,9 @@ private: bool m_navigationWrapsAround; VirtualDesktopGrid m_grid; // TODO: QPointer +#if KWIN_BUILD_X11 NETRootInfo *m_rootInfo; +#endif PlasmaVirtualDesktopManagementInterface *m_virtualDesktopManagement = nullptr; KSharedConfig::Ptr m_config; diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 9b80d13575..416910b111 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -71,14 +71,16 @@ #include "wayland/xdgoutput_v1.h" #include "wayland/xdgshell.h" #include "wayland/xdgtopleveldrag_v1.h" -#include "wayland/xwaylandkeyboardgrab_v1.h" -#include "wayland/xwaylandshell_v1.h" #include "wayland/xx_colormanagement_v2.h" #include "workspace.h" -#include "x11window.h" #include "xdgactivationv1.h" #include "xdgshellintegration.h" #include "xdgshellwindow.h" +#if KWIN_BUILD_X11 +#include "wayland/xwaylandkeyboardgrab_v1.h" +#include "wayland/xwaylandshell_v1.h" +#include "x11window.h" +#endif // Qt #include @@ -310,6 +312,7 @@ bool WaylandServer::init(InitializationFlags flags) { m_initFlags = flags; m_compositor = new CompositorInterface(m_display, m_display); +#if KWIN_BUILD_X11 connect(m_compositor, &CompositorInterface::surfaceCreated, this, [this](SurfaceInterface *surface) { // check whether we have a Window with the Surface's id Workspace *ws = Workspace::self(); @@ -359,6 +362,7 @@ bool WaylandServer::init(InitializationFlags flags) return; } }); +#endif m_tabletManagerV2 = new TabletManagerV2Interface(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); m_XdgForeign = new XdgForeignV2Interface(m_display, m_display); m_inputMethod = new InputMethodV1Interface(m_display, m_display); +#if KWIN_BUILD_X11 m_xWaylandKeyboardGrabManager = new XWaylandKeyboardGrabManagerV1Interface(m_display, m_display); +#endif auto activation = new XdgActivationV1Interface(m_display, this); auto init = [this, activation] { @@ -677,6 +683,7 @@ int WaylandServer::createScreenLockerConnection() return socket.fd; } +#if KWIN_BUILD_X11 int WaylandServer::createXWaylandConnection() { const auto socket = createConnection(); @@ -701,6 +708,7 @@ void WaylandServer::destroyXWaylandConnection() m_xwaylandConnection->destroy(); m_xwaylandConnection = nullptr; } +#endif int WaylandServer::createInputMethodConnection() { @@ -795,9 +803,11 @@ bool WaylandServer::isKeyboardShortcutsInhibited() const if (inhibitor && inhibitor->isActive()) { return true; } +#if KWIN_BUILD_X11 if (m_xWaylandKeyboardGrabManager->hasGrab(surface, seat())) { return true; } +#endif } return false; } diff --git a/src/wayland_server.h b/src/wayland_server.h index 8eb6f31a17..d4dc7d1e41 100644 --- a/src/wayland_server.h +++ b/src/wayland_server.h @@ -123,10 +123,12 @@ public: { return m_keyboardShortcutsInhibitManager; } +#if KWIN_BUILD_X11 XwaylandShellV1Interface *xwaylandShell() const { return m_xwaylandShell; } +#endif bool isKeyboardShortcutsInhibited() const; @@ -160,11 +162,13 @@ public: */ XdgExportedSurface *exportAsForeign(SurfaceInterface *surface); +#if KWIN_BUILD_X11 /** * @returns file descriptor for Xwayland to connect to. */ int createXWaylandConnection(); void destroyXWaylandConnection(); +#endif /** * @returns file descriptor to the input method server's socket. @@ -279,7 +283,9 @@ private: ClientConnection *m_screenLockerClientConnection = nullptr; XdgForeignV2Interface *m_XdgForeign = nullptr; XdgActivationV1Integration *m_xdgActivationIntegration = nullptr; +#if KWIN_BUILD_X11 XWaylandKeyboardGrabManagerV1Interface *m_xWaylandKeyboardGrabManager = nullptr; +#endif ContentTypeManagerV1Interface *m_contentTypeManager = nullptr; TearingControlManagerV1Interface *m_tearingControlInterface = nullptr; XwaylandShellV1Interface *m_xwaylandShell = nullptr; diff --git a/src/workspace.cpp b/src/workspace.cpp index 8176c2afa5..55832c5337 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -19,19 +19,16 @@ #include "activities.h" #endif #include "appmenu.h" -#include "atoms.h" #include "core/outputbackend.h" #include "core/outputconfiguration.h" #include "cursor.h" #include "dbusinterface.h" #include "effect/effecthandler.h" #include "focuschain.h" -#include "group.h" #include "input.h" #include "internalwindow.h" #include "killwindow.h" #include "moving_client_x11_filter.h" -#include "netinfo.h" #include "outline.h" #include "placement.h" #include "pluginmanager.h" @@ -40,7 +37,7 @@ #include "scripting/scripting.h" #include "syncalarmx11filter.h" #include "tiles/tilemanager.h" -#include "x11window.h" +#include "window.h" #if KWIN_BUILD_TABBOX #include "tabbox/tabbox.h" #endif @@ -57,15 +54,21 @@ #include "useractions.h" #include "utils/kernel.h" #include "utils/orientationsensor.h" -#include "utils/xcbutils.h" #include "virtualdesktops.h" #include "was_user_interaction_x11_filter.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 +#endif // KDE #include #include #include -#include // Qt #include #include @@ -217,11 +220,13 @@ void Workspace::init() m_activeWindow = nullptr; +#if KWIN_BUILD_X11 // 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. connect(kwinApp(), &Application::x11ConnectionChanged, this, &Workspace::initializeX11); connect(kwinApp(), &Application::x11ConnectionAboutToBeDestroyed, this, &Workspace::cleanupX11); initializeX11(); +#endif Scripting::create(this); @@ -272,6 +277,7 @@ QString Workspace::getPlacementTrackerHash() return QString::fromLatin1(hash.toHex()); } +#if KWIN_BUILD_X11 void Workspace::initializeX11() { if (!kwinApp()->x11Connection()) { @@ -437,12 +443,15 @@ void Workspace::cleanupX11() m_syncAlarmFilter.reset(); m_wasUserInteractionFilter.reset(); } +#endif Workspace::~Workspace() { blockStackingUpdates(true); +#if KWIN_BUILD_X11 cleanupX11(); +#endif if (waylandServer()) { const QList 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) { StackingUpdatesBlocker blocker(this); @@ -722,7 +732,7 @@ void Workspace::addX11Window(X11Window *window) } window->checkActiveModal(); 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()) { updateToolWindows(true); } @@ -759,6 +769,7 @@ void Workspace::removeUnmanaged(X11Window *window) updateStackingOrder(); Q_EMIT windowRemoved(window); } +#endif 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?) if (!options->isHideUtilityWindowsForInactive()) { +#if KWIN_BUILD_X11 for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) { if (X11Window *x11Window = qobject_cast(*it)) { x11Window->setHidden(false); } } +#endif return; } const Group *group = nullptr; @@ -895,11 +908,14 @@ void Workspace::updateToolWindows(bool also_hide) if (c->isUtility() || c->isMenu() || c->isToolbar()) { bool show = true; if (!c->isTransient()) { +#if KWIN_BUILD_X11 if (!c->group() || c->group()->members().count() == 1) { // Has its own group, keep always visible show = true; } else if (window != nullptr && c->group() == window->group()) { show = true; - } else { + } else +#endif + { show = false; } } else { @@ -1030,6 +1046,7 @@ void Workspace::slotCurrentDesktopChangingCancelled() void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop) { +#if KWIN_BUILD_X11 for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) { X11Window *c = qobject_cast(*it); if (!c) { @@ -1043,11 +1060,13 @@ void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop if (rootInfo()) { rootInfo()->setCurrentDesktop(VirtualDesktopManager::self()->current()); } +#endif if (m_moveResizeWindow && !m_moveResizeWindow->isOnDesktop(newDesktop)) { m_moveResizeWindow->setDesktops({newDesktop}); } +#if KWIN_BUILD_X11 for (int i = stacking_order.size() - 1; i >= 0; --i) { X11Window *c = qobject_cast(stacking_order.at(i)); if (!c) { @@ -1057,6 +1076,7 @@ void Workspace::updateWindowVisibilityOnDesktopChange(VirtualDesktop *newDesktop c->updateVisibility(); } } +#endif if (showingDesktop()) { // Do this only after desktop change to avoid flicker setShowingDesktop(false); } @@ -1142,6 +1162,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity) // mapping done from front to back => less exposure events // Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop)); +#if KWIN_BUILD_X11 for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) { X11Window *window = qobject_cast(*it); if (!window) { @@ -1170,6 +1191,7 @@ void Workspace::updateCurrentActivity(const QString &new_activity) window->updateVisibility(); } } +#endif // FIXME not sure if I should do this either if (showingDesktop()) { // Do this only after desktop change to avoid flicker @@ -1458,6 +1480,7 @@ void Workspace::slotDesktopRemoved(VirtualDesktop *desktop) m_focusChain->removeDesktop(desktop); } +#if KWIN_BUILD_X11 void Workspace::selectWmInputEventMask() { uint32_t presentMask = 0; @@ -1476,6 +1499,7 @@ void Workspace::selectWmInputEventMask() Xcb::selectInput(kwinApp()->x11RootWindow(), presentMask | wmMask); } +#endif /** * Sends window \a window to desktop \a desk. @@ -1542,10 +1566,12 @@ void Workspace::cancelDelayFocus() m_delayFocusWindow = nullptr; } +#if KWIN_BUILD_X11 bool Workspace::checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data) { return m_startup->checkStartup(w, id, data) == KStartupInfo::Match; } +#endif /** * Puts the focus on a dummy window @@ -1553,10 +1579,12 @@ bool Workspace::checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KSt */ void Workspace::focusToNull() { +#if KWIN_BUILD_X11 if (m_nullFocus) { should_get_focus.clear(); m_nullFocus->focus(); } +#endif } bool Workspace::breaksShowingDesktop(Window *window) const @@ -1567,9 +1595,12 @@ bool Workspace::breaksShowingDesktop(Window *window) const void Workspace::setShowingDesktop(bool showing, bool animated) { const bool changed = showing != showing_desktop; + +#if KWIN_BUILD_X11 if (rootInfo() && changed) { rootInfo()->setShowingDesktop(showing); } +#endif showing_desktop = showing; 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(QStringLiteral("\n")); +#if KWIN_BUILD_X11 if (auto c = kwinApp()->x11Connection()) { support.append(QStringLiteral("X11\n")); support.append(QStringLiteral("===\n")); @@ -1688,6 +1720,7 @@ QString Workspace::supportInformation() const } support.append(QStringLiteral("\n")); } +#endif if (m_decorationBridge) { support.append(QStringLiteral("Decoration\n")); @@ -1823,9 +1856,11 @@ QString Workspace::supportInformation() const if (platform->isMesaDriver()) { support.append(QStringLiteral("Mesa version: ") + platform->mesaVersion().toString() + QStringLiteral("\n")); } +#if KWIN_BUILD_X11 if (auto xVersion = Xcb::xServerVersion(); xVersion.isValid()) { support.append(QStringLiteral("X server version: ") + xVersion.toString() + QStringLiteral("\n")); } +#endif if (auto kernelVersion = linuxKernelVersion(); kernelVersion.isValid()) { support.append(QStringLiteral("Linux kernel version: ") + kernelVersion.toString() + QStringLiteral("\n")); } @@ -1892,6 +1927,7 @@ QString Workspace::supportInformation() const return support; } +#if KWIN_BUILD_X11 void Workspace::forEachClient(std::function func) { for (Window *window : std::as_const(m_windows)) { @@ -1953,6 +1989,7 @@ X11Window *Workspace::findClient(Predicate predicate, xcb_window_t w) const } return nullptr; } +#endif Window *Workspace::findWindow(std::function func) const { @@ -1984,9 +2021,11 @@ Window *Workspace::findInternal(QWindow *w) const if (!w) { return nullptr; } +#if KWIN_BUILD_X11 if (kwinApp()->operationMode() == Application::OperationModeX11) { return findUnmanaged(w->winId()); } +#endif for (Window *window : m_windows) { if (InternalWindow *internal = qobject_cast(window)) { if (internal->handle() == w) { @@ -2004,10 +2043,12 @@ void Workspace::setWasUserInteraction() } was_user_interaction = true; // might be called from within the filter, so delay till we now the filter returned +#if KWIN_BUILD_X11 QTimer::singleShot(0, this, [this] { m_wasUserInteractionFilter.reset(); }); +#endif } void Workspace::updateTabbox() @@ -2050,6 +2091,7 @@ void Workspace::setInitialDesktop(int desktop) m_initialDesktop = desktop; } +#if KWIN_BUILD_X11 Group *Workspace::findGroup(xcb_window_t leader) const { Q_ASSERT(leader != XCB_WINDOW_NONE); @@ -2092,6 +2134,7 @@ Group *Workspace::findClientLeaderGroup(const X11Window *window) const } return ret; } +#endif 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. 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 @@ -2165,12 +2210,14 @@ void Workspace::desktopResized() m_geometry = m_geometry.united(output->geometry()); } +#if KWIN_BUILD_X11 if (rootInfo()) { NETSize desktop_geometry; desktop_geometry.width = Xcb::toXNative(m_geometry.width()); desktop_geometry.height = Xcb::toXNative(m_geometry.height()); rootInfo()->setDesktopGeometry(desktop_geometry); } +#endif 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 * an xinerama setup where the monitors are not the same resolution. @@ -2241,6 +2289,7 @@ static bool hasOffscreenXineramaStrut(Window *window) return false; } +#endif 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 screenArea = clientArea(ScreenArea, window); +#if KWIN_BUILD_X11 if (qobject_cast(window)) { // HACK: workarea handling is not xinerama aware, so if this strut // 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. // 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 // 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). - bool hasOffscreenStrut = hasOffscreenXineramaStrut(window); + bool hasOffscreenStrut = false; +#if KWIN_BUILD_X11 + hasOffscreenStrut = hasOffscreenXineramaStrut(window); +#endif const auto vds = window->isOnAllDesktops() ? desktops : window->desktops(); for (VirtualDesktop *vd : vds) { @@ -2384,6 +2438,7 @@ void Workspace::updateClientArea() m_oldRestrictedAreas = m_restrictedAreas; m_restrictedAreas = restrictedAreas; +#if KWIN_BUILD_X11 if (rootInfo()) { for (VirtualDesktop *desktop : desktops) { const QRectF &workArea = m_workAreas[desktop]; @@ -2391,6 +2446,7 @@ void Workspace::updateClientArea() rootInfo()->setWorkArea(desktop->x11DesktopNumber(), r); } } +#endif for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) { if ((*it)->isClient()) { @@ -2503,6 +2559,7 @@ QHash Workspace::previousScreenSizes() const return m_oldScreenGeometries; } +#if KWIN_BUILD_X11 Output *Workspace::xineramaIndexToOutput(int index) const { xcb_connection_t *connection = kwinApp()->x11Connection(); @@ -2536,6 +2593,7 @@ Output *Workspace::xineramaIndexToOutput(int index) const return nullptr; } +#endif void Workspace::setOutputOrder(const QList &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 // 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). @@ -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); } } +#endif FocusChain *Workspace::focusChain() const { diff --git a/src/workspace.h b/src/workspace.h index 7abbb2d28b..02a531c610 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -95,10 +95,11 @@ public: return _self; } - bool workspaceEvent(xcb_generic_event_t *); - 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. * @@ -146,6 +147,7 @@ public: * @return KWin::Unmanaged* Found Unmanaged or @c null if there is no Unmanaged with given Id. */ X11Window *findUnmanaged(xcb_window_t w) const; +#endif Window *findWindow(const QUuid &internalId) const; Window *findWindow(std::function func) const; @@ -227,14 +229,16 @@ public: QRectF adjustWindowSize(const Window *window, QRectF moveResizeGeom, Gravity gravity) const; void raiseWindow(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 restoreSessionStackingOrder(X11Window *window); +#endif void lowerWindowRequest(Window *window); void restackWindowUnderActive(Window *window); void restack(Window *window, Window *under, bool force = false); void raiseOrLowerWindow(Window *window); void resetUpdateToolWindowsTimer(); - void restoreSessionStackingOrder(X11Window *window); void updateStackingOrder(bool propagate_new_windows = false); void forceRestacking(); @@ -251,7 +255,9 @@ public: return m_windows; } +#if KWIN_BUILD_X11 void stackScreenEdgesUnderOverrideRedirect(); +#endif SessionManager *sessionManager() const; @@ -283,7 +289,6 @@ public: */ const QList &stackingOrder() const; QList unconstrainedStackingOrder() const; - QList ensureStackingOrder(const QList &windows) const; QList ensureStackingOrder(const QList &windows) const; Window *topWindowOnDesktop(VirtualDesktop *desktop, Output *output = nullptr, bool unconstrained = false, @@ -294,6 +299,9 @@ public: void windowToNextDesktop(Window *window); void sendWindowToOutput(Window *window, Output *output); +#if KWIN_BUILD_X11 + QList ensureStackingOrder(const QList &windows) const; + void addManualOverlay(xcb_window_t id) { manual_overlays << id; @@ -302,6 +310,7 @@ public: { manual_overlays.removeOne(id); } +#endif /** * Shows the menu operations menu for the window and makes it active if @@ -317,9 +326,11 @@ public: void updateMinimizedOfTransients(Window *); void updateOnAllDesktopsOfTransients(Window *); - void checkTransients(xcb_window_t w); +#if KWIN_BUILD_X11 + void checkTransients(xcb_window_t w); SessionInfo *takeSessionInfo(X11Window *); +#endif // D-Bus interface QString supportInformation() const; @@ -347,8 +358,9 @@ public: void setShowingDesktop(bool showing, bool animated = true); bool showingDesktop() const; - void removeX11Window(X11Window *); // Only called from X11Window::destroyWindow() or X11Window::releaseWindow() 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; void addGroup(Group *group); void removeGroup(Group *group); @@ -356,11 +368,11 @@ public: int unconstainedStackingOrderIndex(const X11Window *c) const; void removeUnmanaged(X11Window *); + bool checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data); +#endif void removeDeleted(Window *); void addDeleted(Window *); - bool checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data); - void focusToNull(); // SELI TODO: Public? void windowShortcutUpdated(Window *window); @@ -521,7 +533,9 @@ public Q_SLOTS: private Q_SLOTS: void desktopResized(); +#if KWIN_BUILD_X11 void selectWmInputEventMask(); +#endif void slotUpdateToolWindows(); void delayFocus(); void slotReloadConfig(); @@ -551,7 +565,9 @@ Q_SIGNALS: void windowRemoved(KWin::Window *); void windowActivated(KWin::Window *); void windowMinimizedChanged(KWin::Window *); +#if KWIN_BUILD_X11 void groupAdded(KWin::Group *); +#endif void deletedRemoved(KWin::Window *); void configChanged(); void showingDesktopChanged(bool showing, bool animated); @@ -567,8 +583,6 @@ Q_SIGNALS: private: void init(); - void initializeX11(); - void cleanupX11(); void initShortcuts(); template void initShortcut(const QString &actionName, const QString &description, const QKeySequence &shortcut, Slot slot); @@ -577,24 +591,30 @@ private: void setupWindowShortcut(Window *window); bool switchWindow(Window *window, Direction direction, QPoint curPos, VirtualDesktop *desktop); - void propagateWindows(bool propagate_new_windows); // Called only from updateStackingOrder QList constrainedStackingOrder(); void raiseWindowWithinApplication(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 updateToolWindows(bool also_hide); - void fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geom); void saveOldScreenSizes(); void addToStack(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 X11Window *createX11Window(xcb_window_t windowId, bool is_mapped); void addX11Window(X11Window *c); - void setupWindowConnections(Window *window); X11Window *createUnmanaged(xcb_window_t windowId); void addUnmanaged(X11Window *c); + void updateXStackingOrder(); +#endif + void setupWindowConnections(Window *window); void addWaylandWindow(Window *window); void removeWaylandWindow(Window *window); @@ -632,7 +652,6 @@ private: Window *m_activePopupWindow; int m_initialDesktop; - void updateXStackingOrder(); void updateTabbox(); QList m_outputs; @@ -654,7 +673,6 @@ private: QList unconstrained_stacking_order; // Topmost last QList stacking_order; // Topmost last - QList manual_overlays; // Topmost last bool force_restacking; QList should_get_focus; // Last is most recent QList attention_chain; @@ -664,7 +682,13 @@ private: QList groups; bool was_user_interaction; +#if KWIN_BUILD_X11 + QList manual_overlays; // Topmost last std::unique_ptr m_wasUserInteractionFilter; + std::unique_ptr m_nullFocus; + std::unique_ptr m_movingClientFilter; + std::unique_ptr m_syncAlarmFilter; +#endif int block_focus; @@ -686,9 +710,9 @@ private: QTimer updateToolWindowsTimer; static Workspace *_self; - +#if KWIN_BUILD_X11 std::unique_ptr m_startup; - +#endif QHash m_workAreas; QHash m_restrictedAreas; QHash> m_screenAreas; @@ -701,12 +725,9 @@ private: int m_setActiveWindowRecursion = 0; int m_blockStackingUpdates = 0; // When > 0, stacking updates are temporarily disabled bool m_blockedPropagatingNewWindows; // Propagate also new windows after enabling stacking updates? - std::unique_ptr m_nullFocus; friend class StackingUpdatesBlocker; std::unique_ptr m_windowKiller; - std::unique_ptr m_movingClientFilter; - std::unique_ptr m_syncAlarmFilter; SessionManager *m_sessionManager; std::unique_ptr m_focusChain; @@ -775,6 +796,7 @@ inline Window *Workspace::mostRecentlyActivatedWindow() const return should_get_focus.count() > 0 ? should_get_focus.last() : m_activeWindow; } +#if KWIN_BUILD_X11 inline void Workspace::addGroup(Group *group) { Q_EMIT groupAdded(group); @@ -785,6 +807,7 @@ inline void Workspace::removeGroup(Group *group) { groups.removeAll(group); } +#endif inline const QList &Workspace::stackingOrder() const { diff --git a/src/x11window.cpp b/src/x11window.cpp index 8ec10b374c..733a91b6a5 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -5182,6 +5182,388 @@ void X11Window::getSkipCloseAnimation() 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(-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(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 ret; + const auto mcs = mainWindows(); + for (auto mc : mcs) { + if (X11Window *c = dynamic_cast(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(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(*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(*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 #include "moc_x11window.cpp" diff --git a/src/x11window.h b/src/x11window.h index 1365f36048..a9ace5c131 100644 --- a/src/x11window.h +++ b/src/x11window.h @@ -9,6 +9,11 @@ */ #pragma once +#include "config-kwin.h" + +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif // kwin #include "scene/decorationitem.h" diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h index 73ceeff163..6e8e758c29 100644 --- a/src/xwayland/xwayland.h +++ b/src/xwayland/xwayland.h @@ -9,6 +9,12 @@ */ #pragma once +#include "config-kwin.h" + +#if !KWIN_BUILD_X11 +#error Do not include on non-X11 builds +#endif + #include #include "xwayland_interface.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 678a663149..a122145efb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,18 +1,20 @@ -set(normalhintsbasesizetest_SRCS normalhintsbasesizetest.cpp) -add_executable(normalhintsbasesizetest ${normalhintsbasesizetest_SRCS}) -target_link_libraries(normalhintsbasesizetest XCB::XCB XCB::ICCCM KF6::WindowSystem) +if(KWIN_BUILD_X11) + set(normalhintsbasesizetest_SRCS normalhintsbasesizetest.cpp) + add_executable(normalhintsbasesizetest ${normalhintsbasesizetest_SRCS}) + target_link_libraries(normalhintsbasesizetest XCB::XCB XCB::ICCCM KF6::WindowSystem) -# next target -set(screenedgeshowtest_SRCS screenedgeshowtest.cpp) -add_executable(screenedgeshowtest ${screenedgeshowtest_SRCS}) -target_link_libraries(screenedgeshowtest Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem Plasma::KWaylandClient ${XCB_XCB_LIBRARY}) + # next target + set(screenedgeshowtest_SRCS screenedgeshowtest.cpp) + add_executable(screenedgeshowtest ${screenedgeshowtest_SRCS}) + target_link_libraries(screenedgeshowtest Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem Plasma::KWaylandClient ${XCB_XCB_LIBRARY}) -add_executable(x11shadowreader x11shadowreader.cpp) -target_link_libraries(x11shadowreader XCB::XCB Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem) + add_executable(x11shadowreader x11shadowreader.cpp) + target_link_libraries(x11shadowreader XCB::XCB Qt::GuiPrivate Qt::Widgets KF6::ConfigCore KF6::WindowSystem) -add_executable(pointerconstraints pointerconstraintstest.cpp) -add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(pointerconstraints XCB::XCB Qt::Gui Qt::Quick Plasma::KWaylandClient) + add_executable(pointerconstraints pointerconstraintstest.cpp) + add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}") + target_link_libraries(pointerconstraints XCB::XCB Qt::Gui Qt::Quick Plasma::KWaylandClient) +endif() add_executable(pointergestures pointergesturestest.cpp) add_definitions(-DDIR="${CMAKE_CURRENT_SOURCE_DIR}")