Make it possible to build KWin without libxcb
Now that we have Wayland around, there's a whole branch of dependencies that shouldn't be necessary anymore. This allows to build KWin without all of it, allowing us to have a much more compact alignment for cases where all the legacy software isn't necessary anymore. Bundle KWindowSystem X11-specific headers into it too, since it's part of the same process. Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
This commit is contained in:
parent
94121c2a42
commit
bf1ce85474
94 changed files with 1484 additions and 740 deletions
|
@ -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
|
||||
|
|
|
@ -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,9 +233,59 @@ else()
|
|||
set(HAVE_XKBCOMMON_NO_SECURE_GETENV 0)
|
||||
endif()
|
||||
|
||||
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
|
||||
|
|
|
@ -45,6 +45,7 @@ ecm_mark_as_test(testVirtualDesktops)
|
|||
########################################################
|
||||
# Test ClientMachine
|
||||
########################################################
|
||||
if(KWIN_BUILD_X11)
|
||||
set(testClientMachine_SRCS
|
||||
../src/client_machine.cpp
|
||||
test_client_machine.cpp
|
||||
|
@ -122,6 +123,20 @@ target_link_libraries(testXcbWindow
|
|||
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
|
||||
|
|
|
@ -39,7 +39,6 @@ target_link_libraries(LibDrmTest
|
|||
KF6::WindowSystem
|
||||
KF6::CoreAddons
|
||||
KF6::I18n
|
||||
XCB::XCB
|
||||
PkgConfig::Libxcvt
|
||||
gbm::gbm
|
||||
Libdrm::Libdrm
|
||||
|
|
|
@ -14,7 +14,10 @@ kwineffects_unit_tests(
|
|||
timelinetest
|
||||
)
|
||||
|
||||
|
||||
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()
|
||||
|
|
|
@ -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()
|
||||
|
||||
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)
|
||||
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})
|
||||
|
|
|
@ -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 <KWayland/Client/compositor.h>
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/shm_pool.h>
|
||||
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#include "wayland_server.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
|
||||
#include <KDecoration2/Decoration>
|
||||
|
||||
|
|
|
@ -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 <KPluginMetaData>
|
||||
|
||||
|
@ -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<Xwl::Xwayland>(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()
|
||||
{
|
||||
|
|
|
@ -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<Xwl::Xwayland> m_xwayland;
|
||||
#endif
|
||||
QString m_inputMethodServerToStart;
|
||||
|
||||
std::unique_ptr<Test::VirtualInputDevice> 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<xcb_connection_t, XcbConnectionDeleter> XcbConnectionPtr;
|
||||
XcbConnectionPtr createX11Connection();
|
||||
#endif
|
||||
|
||||
MockInputMethod *inputMethod();
|
||||
KWayland::Client::Surface *inputPanelSurface();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 <KWayland/Client/surface.h>
|
||||
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -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,6 +246,41 @@ target_link_libraries(kwin
|
|||
KDecoration2::KDecoration
|
||||
KDecoration2::KDecoration2Private
|
||||
|
||||
UDev::UDev
|
||||
XKB::XKB
|
||||
EGL::EGL
|
||||
epoxy::epoxy
|
||||
|
||||
Threads::Threads
|
||||
lcms2::lcms2
|
||||
PkgConfig::libdisplayinfo
|
||||
)
|
||||
|
||||
if (TARGET K::KGlobalAccelD)
|
||||
target_sources(kwin PRIVATE globalshortcuts.cpp)
|
||||
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
|
||||
|
@ -274,20 +295,7 @@ target_link_libraries(kwin
|
|||
XCB::XCB
|
||||
XCB::XFIXES
|
||||
XCB::XINERAMA
|
||||
|
||||
UDev::UDev
|
||||
XKB::XKB
|
||||
EGL::EGL
|
||||
epoxy::epoxy
|
||||
|
||||
Threads::Threads
|
||||
lcms2::lcms2
|
||||
PkgConfig::libdisplayinfo
|
||||
)
|
||||
|
||||
if (TARGET K::KGlobalAccelD)
|
||||
target_sources(kwin PRIVATE globalshortcuts.cpp)
|
||||
target_link_libraries(kwin PRIVATE K::KGlobalAccelD)
|
||||
endif()
|
||||
|
||||
if (KWIN_BUILD_NOTIFICATIONS)
|
||||
|
@ -331,7 +339,10 @@ add_subdirectory(platformsupport)
|
|||
add_subdirectory(plugins)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(wayland)
|
||||
|
||||
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,6 +375,7 @@ qt_generate_dbus_interface(tabletmodemanager.h org.kde.KWin.TabletModeManager.xm
|
|||
|
||||
generate_export_header(kwin EXPORT_FILE_NAME kwin_export.h)
|
||||
|
||||
if (KWIN_BUILD_X11)
|
||||
add_executable(kwin_x11 main_x11.cpp)
|
||||
target_link_libraries(kwin_x11
|
||||
KWinX11Platform
|
||||
|
@ -371,9 +386,10 @@ 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
|
||||
|
|
|
@ -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 <KLocalizedString>
|
||||
#include <kstartupinfo.h>
|
||||
#include <kstringhandler.h>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
#include "atoms.h"
|
||||
#include "group.h"
|
||||
#include "netinfo.h"
|
||||
#include "x11window.h"
|
||||
#include <kstartupinfo.h>
|
||||
#endif
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <kstringhandler.h>
|
||||
|
||||
#include "rules.h"
|
||||
#include "useractions.h"
|
||||
#include "window.h"
|
||||
#include <QDebug>
|
||||
|
||||
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<xcb_timestamp_t>(-1);
|
||||
}
|
||||
|
||||
xcb_timestamp_t X11Window::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data,
|
||||
bool session) const
|
||||
{
|
||||
xcb_timestamp_t time = info->userTime();
|
||||
// qDebug() << "User timestamp, initial:" << time;
|
||||
//^^ this deadlocks kwin --replace sometimes.
|
||||
|
||||
// newer ASN timestamp always replaces user timestamp, unless user timestamp is 0
|
||||
// helps e.g. with konqy reusing
|
||||
if (asn_data != nullptr && time != 0) {
|
||||
if (asn_id->timestamp() != 0
|
||||
&& (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) {
|
||||
time = asn_id->timestamp();
|
||||
}
|
||||
}
|
||||
qCDebug(KWIN_CORE) << "User timestamp, ASN:" << time;
|
||||
if (time == -1U) {
|
||||
// The window doesn't have any timestamp.
|
||||
// If it's the first window for its application
|
||||
// (i.e. there's no other window from the same app),
|
||||
// use the _KDE_NET_WM_USER_CREATION_TIME trick.
|
||||
// Otherwise, refuse activation of a window
|
||||
// from already running application if this application
|
||||
// is not the active one (unless focus stealing prevention is turned off).
|
||||
X11Window *act = dynamic_cast<X11Window *>(workspace()->mostRecentlyActivatedWindow());
|
||||
if (act != nullptr && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) {
|
||||
bool first_window = true;
|
||||
auto sameApplicationActiveHackPredicate = [this](const X11Window *cl) {
|
||||
// ignore already existing splashes, toolbars, utilities and menus,
|
||||
// as the app may show those before the main window
|
||||
return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
|
||||
&& cl != this && X11Window::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive);
|
||||
};
|
||||
if (isTransient()) {
|
||||
auto clientMainClients = [this]() {
|
||||
QList<X11Window *> ret;
|
||||
const auto mcs = mainWindows();
|
||||
for (auto mc : mcs) {
|
||||
if (X11Window *c = dynamic_cast<X11Window *>(mc)) {
|
||||
ret << c;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
if (act->hasTransient(this, true)) {
|
||||
; // is transient for currently active window, even though it's not
|
||||
// the same app (e.g. kcookiejar dialog) -> allow activation
|
||||
} else if (groupTransient() && findInList<X11Window, X11Window>(clientMainClients(), sameApplicationActiveHackPredicate) == nullptr) {
|
||||
; // standalone transient
|
||||
} else {
|
||||
first_window = false;
|
||||
}
|
||||
} else {
|
||||
if (workspace()->findClient(sameApplicationActiveHackPredicate)) {
|
||||
first_window = false;
|
||||
}
|
||||
}
|
||||
// don't refuse if focus stealing prevention is turned off
|
||||
if (!first_window && rules()->checkFSP(options->focusStealingPreventionLevel()) > 0) {
|
||||
qCDebug(KWIN_CORE) << "User timestamp, already exists:" << 0;
|
||||
return 0; // refuse activation
|
||||
}
|
||||
}
|
||||
// Creation time would just mess things up during session startup,
|
||||
// as possibly many apps are started up at the same time.
|
||||
// If there's no active window yet, no timestamp will be needed,
|
||||
// as plain Workspace::allowWindowActivation() will return true
|
||||
// in such case. And if there's already active window,
|
||||
// it's better not to activate the new one.
|
||||
// Unless it was the active window at the time
|
||||
// of session saving and there was no user interaction yet,
|
||||
// this check will be done in manage().
|
||||
if (session) {
|
||||
return -1U;
|
||||
}
|
||||
time = readUserCreationTime();
|
||||
}
|
||||
qCDebug(KWIN_CORE) << "User timestamp, final:" << this << ":" << time;
|
||||
return time;
|
||||
}
|
||||
|
||||
xcb_timestamp_t X11Window::userTime() const
|
||||
{
|
||||
xcb_timestamp_t time = m_userTime;
|
||||
if (time == 0) { // doesn't want focus after showing
|
||||
return 0;
|
||||
}
|
||||
Q_ASSERT(group() != nullptr);
|
||||
if (time == -1U
|
||||
|| (group()->userTime() != -1U
|
||||
&& NET::timestampCompare(group()->userTime(), time) > 0)) {
|
||||
time = group()->userTime();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
void X11Window::doSetActive()
|
||||
{
|
||||
updateUrgency(); // demand attention again if it's still urgent
|
||||
info->setState(isActive() ? NET::Focused : NET::States(), NET::Focused);
|
||||
}
|
||||
|
||||
void X11Window::startupIdChanged()
|
||||
{
|
||||
KStartupInfoId asn_id;
|
||||
KStartupInfoData asn_data;
|
||||
bool asn_valid = workspace()->checkStartupNotification(window(), asn_id, asn_data);
|
||||
if (!asn_valid) {
|
||||
return;
|
||||
}
|
||||
// If the ASN contains desktop, move it to the desktop, otherwise move it to the current
|
||||
// desktop (since the new ASN should make the window act like if it's a new application
|
||||
// launched). However don't affect the window's desktop if it's set to be on all desktops.
|
||||
|
||||
if (asn_data.desktop() != 0 && !isOnAllDesktops()) {
|
||||
if (asn_data.desktop() == -1) {
|
||||
workspace()->sendWindowToDesktops(this, {}, true);
|
||||
} else {
|
||||
if (VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(asn_data.desktop())) {
|
||||
workspace()->sendWindowToDesktops(this, {desktop}, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (asn_data.xinerama() != -1) {
|
||||
Output *output = workspace()->xineramaIndexToOutput(asn_data.xinerama());
|
||||
if (output) {
|
||||
workspace()->sendWindowToOutput(this, output);
|
||||
}
|
||||
}
|
||||
const xcb_timestamp_t timestamp = asn_id.timestamp();
|
||||
if (timestamp != 0) {
|
||||
bool activate = allowWindowActivation(timestamp);
|
||||
if (activate) {
|
||||
workspace()->activateWindow(this);
|
||||
} else {
|
||||
demandAttention();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void X11Window::updateUrgency()
|
||||
{
|
||||
if (info->urgency()) {
|
||||
demandAttention();
|
||||
}
|
||||
}
|
||||
|
||||
namespace FSP
|
||||
{
|
||||
enum Level {
|
||||
None = 0,
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
Extreme,
|
||||
};
|
||||
}
|
||||
|
||||
// focus_in -> the window got FocusIn event
|
||||
bool X11Window::allowWindowActivation(xcb_timestamp_t time, bool focus_in)
|
||||
{
|
||||
auto window = this;
|
||||
// options->focusStealingPreventionLevel :
|
||||
// 0 - none - old KWin behaviour, new windows always get focus
|
||||
// 1 - low - focus stealing prevention is applied normally, when unsure, activation is allowed
|
||||
// 2 - normal - focus stealing prevention is applied normally, when unsure, activation is not allowed,
|
||||
// this is the default
|
||||
// 3 - high - new window gets focus only if it belongs to the active application,
|
||||
// or when no window is currently active
|
||||
// 4 - extreme - no window gets focus without user intervention
|
||||
if (time == -1U) {
|
||||
time = window->userTime();
|
||||
}
|
||||
const FSP::Level level = (FSP::Level)window->rules()->checkFSP(options->focusStealingPreventionLevel());
|
||||
if (workspace()->sessionManager()->state() == SessionState::Saving && level <= FSP::Medium) { // <= normal
|
||||
return true;
|
||||
}
|
||||
Window *ac = workspace()->mostRecentlyActivatedWindow();
|
||||
if (focus_in) {
|
||||
if (workspace()->inShouldGetFocus(window)) {
|
||||
return true; // FocusIn was result of KWin's action
|
||||
}
|
||||
// Before getting FocusIn, the active Client already
|
||||
// got FocusOut, and therefore got deactivated.
|
||||
ac = workspace()->lastActiveWindow();
|
||||
}
|
||||
if (time == 0) { // explicitly asked not to get focus
|
||||
if (!window->rules()->checkAcceptFocus(false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const FSP::Level protection = (FSP::Level)(ac ? ac->rules()->checkFPP(2) : FSP::None);
|
||||
|
||||
// stealing is unconditionally allowed (NETWM behavior)
|
||||
if (level == FSP::None || protection == FSP::None) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The active window "grabs" the focus or stealing is generally forbidden
|
||||
if (level == FSP::Extreme || protection == FSP::Extreme) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No active window, it's ok to pass focus
|
||||
// NOTICE that extreme protection needs to be handled before to allow protection on unmanged windows
|
||||
if (ac == nullptr || ac->isDesktop()) {
|
||||
qCDebug(KWIN_CORE) << "Activation: No window active, allowing";
|
||||
return true; // no active window -> always allow
|
||||
}
|
||||
|
||||
// TODO window urgency -> return true?
|
||||
|
||||
// Unconditionally allow intra-window passing around for lower stealing protections
|
||||
// unless the active window has High interest
|
||||
if (Window::belongToSameApplication(window, ac, Window::SameApplicationCheck::RelaxedForActive) && protection < FSP::High) {
|
||||
qCDebug(KWIN_CORE) << "Activation: Belongs to active application";
|
||||
return true;
|
||||
}
|
||||
|
||||
// High FPS, not intr-window change. Only allow if the active window has only minor interest
|
||||
if (level > FSP::Medium && protection > FSP::Low) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (time == -1U) { // no time known
|
||||
qCDebug(KWIN_CORE) << "Activation: No timestamp at all";
|
||||
// Only allow for Low protection unless active window has High interest in focus
|
||||
if (level < FSP::Medium && protection < FSP::High) {
|
||||
return true;
|
||||
}
|
||||
// no timestamp at all, don't activate - because there's also creation timestamp
|
||||
// done on CreateNotify, this case should happen only in case application
|
||||
// maps again already used window, i.e. this won't happen after app startup
|
||||
return false;
|
||||
}
|
||||
|
||||
// Low or medium FSP, usertime comparism is possible
|
||||
const xcb_timestamp_t user_time = ac->userTime();
|
||||
qCDebug(KWIN_CORE) << "Activation, compared:" << window << ":" << time << ":" << user_time
|
||||
<< ":" << (NET::timestampCompare(time, user_time) >= 0);
|
||||
return NET::timestampCompare(time, user_time) >= 0; // time >= user_time
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// Group
|
||||
//****************************************
|
||||
|
||||
void Group::startupIdChanged()
|
||||
{
|
||||
KStartupInfoId asn_id;
|
||||
KStartupInfoData asn_data;
|
||||
bool asn_valid = workspace()->checkStartupNotification(leader_wid, asn_id, asn_data);
|
||||
if (!asn_valid) {
|
||||
return;
|
||||
}
|
||||
if (asn_id.timestamp() != 0 && user_time != -1U
|
||||
&& NET::timestampCompare(asn_id.timestamp(), user_time) > 0) {
|
||||
user_time = asn_id.timestamp();
|
||||
}
|
||||
}
|
||||
|
||||
void Group::updateUserTime(xcb_timestamp_t time)
|
||||
{
|
||||
// copy of X11Window::updateUserTime
|
||||
if (time == XCB_CURRENT_TIME) {
|
||||
kwinApp()->updateXTime();
|
||||
time = xTime();
|
||||
}
|
||||
if (time != -1U
|
||||
&& (user_time == XCB_CURRENT_TIME
|
||||
|| NET::timestampCompare(time, user_time) > 0)) { // time > user_time
|
||||
user_time = time;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
*/
|
||||
#include "activities.h"
|
||||
// KWin
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
// KDE
|
||||
#include <KConfigGroup>
|
||||
// Qt
|
||||
|
@ -173,6 +176,7 @@ void Activities::reallyStop(const QString &id)
|
|||
|
||||
QSet<QByteArray> saveSessionIds;
|
||||
QSet<QByteArray> dontCloseSessionIds;
|
||||
#if KWIN_BUILD_X11
|
||||
const auto windows = ws->windows();
|
||||
for (auto *const window : windows) {
|
||||
auto x11Window = qobject_cast<X11Window *>(window);
|
||||
|
@ -206,8 +210,8 @@ void Activities::reallyStop(const QString &id)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ws->sessionManager()->storeSubSession(id, saveSessionIds);
|
||||
#endif
|
||||
|
||||
QStringList saveAndClose;
|
||||
QStringList saveOnly;
|
||||
|
|
|
@ -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 <appmenu_interface.h>
|
||||
|
||||
#include <QDBusObjectPath>
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#pragma once
|
||||
// Qt
|
||||
#include <QObject>
|
||||
// xcb
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
class QPoint;
|
||||
class OrgKdeKappmenuInterface;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,4 +3,7 @@ add_subdirectory(fakeinput)
|
|||
add_subdirectory(libinput)
|
||||
add_subdirectory(virtual)
|
||||
add_subdirectory(wayland)
|
||||
|
||||
if (KWIN_BUILD_X11)
|
||||
add_subdirectory(x11)
|
||||
endif()
|
||||
|
|
|
@ -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 <NETWM>
|
||||
#endif
|
||||
// Qt
|
||||
#include <QFutureWatcher>
|
||||
#include <QtConcurrentRun>
|
||||
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -8,9 +8,13 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "config-kwin.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
#if KWIN_BUILD_X11
|
||||
#include <xcb/xcb.h>
|
||||
#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();
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "config-kwin.h"
|
||||
#include <kwin_export.h>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
|
@ -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<xcb_atom_t> m_unusedSupportProperties;
|
||||
QTimer m_unusedSupportPropertyTimer;
|
||||
#endif
|
||||
std::unique_ptr<WorkspaceScene> m_scene;
|
||||
std::unique_ptr<CursorScene> m_cursorScene;
|
||||
std::unique_ptr<RenderBackend> m_backend;
|
||||
|
|
|
@ -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}");
|
||||
|
|
|
@ -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 <KConfig>
|
||||
#include <KConfigGroup>
|
||||
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -32,15 +32,16 @@
|
|||
#include "wayland_server.h"
|
||||
#include "waylandwindow.h"
|
||||
#include "workspace.h"
|
||||
#include "x11window.h"
|
||||
#include "xkb.h"
|
||||
#include <cerrno>
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
|
||||
#include "ui_debug_console.h"
|
||||
|
||||
// frameworks
|
||||
#include <KLocalizedString>
|
||||
#include <NETWM>
|
||||
// Qt
|
||||
#include <QFutureWatcher>
|
||||
#include <QMetaProperty>
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QScopeGuard>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QWindow>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
|
@ -932,6 +934,7 @@ DebugConsoleModel::DebugConsoleModel(QObject *parent)
|
|||
|
||||
void DebugConsoleModel::handleWindowAdded(Window *window)
|
||||
{
|
||||
#if KWIN_BUILD_X11
|
||||
if (auto x11 = qobject_cast<X11Window *>(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<WaylandWindow *>(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<X11Window *>(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<WaylandWindow *>(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<X11Window>(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:
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
#include "decorationpalette.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KDecoration2/Decoration>
|
||||
|
@ -136,17 +138,21 @@ DELEGATE(bool, isShaded, isShade)
|
|||
|
||||
WId DecoratedClientImpl::windowId() const
|
||||
{
|
||||
#if KWIN_BUILD_X11
|
||||
if (X11Window *x11Window = qobject_cast<X11Window *>(m_window)) {
|
||||
return x11Window->window();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
WId DecoratedClientImpl::decorationId() const
|
||||
{
|
||||
#if KWIN_BUILD_X11
|
||||
if (X11Window *x11Window = qobject_cast<X11Window *>(m_window)) {
|
||||
return x11Window->frameId();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<WindowPropertyNotifyX11Filter>(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<QByteArray> properties = m_propertiesForEffects.keys();
|
||||
for (const QByteArray &property : properties) {
|
||||
removeSupportProperty(property, effect);
|
||||
}
|
||||
#endif
|
||||
|
||||
delete effect;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "config-kwin.h"
|
||||
#include "effect/effect.h"
|
||||
#include "effect/effectwindow.h"
|
||||
|
||||
|
@ -29,7 +30,9 @@
|
|||
|
||||
#include <functional>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
#include <xcb/xcb.h>
|
||||
#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<EffectWindow *> &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<int, EffectPair> effect_order;
|
||||
#if KWIN_BUILD_X11
|
||||
QHash<long, int> registered_atoms;
|
||||
#endif
|
||||
QList<EffectPair> loaded_effects;
|
||||
CompositingType compositing_type;
|
||||
EffectsList m_activeEffects;
|
||||
|
@ -1090,7 +1104,9 @@ protected:
|
|||
EffectsIterator m_currentPaintWindowIterator;
|
||||
EffectsIterator m_currentPaintScreenIterator;
|
||||
typedef QHash<QByteArray, QList<Effect *>> PropertyEffectMap;
|
||||
#if KWIN_BUILD_X11
|
||||
PropertyEffectMap m_propertiesForEffects;
|
||||
#endif
|
||||
QHash<QByteArray, qulonglong> m_managedProperties;
|
||||
Compositor *m_compositor;
|
||||
WorkspaceScene *m_scene;
|
||||
|
|
|
@ -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<KWin::WaylandWindow *>(d->m_window) != nullptr;
|
||||
#if KWIN_BUILD_X11
|
||||
d->m_x11Window = qobject_cast<KWin::X11Window *>(d->m_window) != nullptr;
|
||||
#else
|
||||
d->m_x11Window = false;
|
||||
#endif
|
||||
|
||||
connect(d->m_window, &Window::hiddenChanged, this, [this]() {
|
||||
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<X11Window *>(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<X11Window *>(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<X11Window *>(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<X11Window *>(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<EffectWindow *> EffectWindowGroup::members() const
|
||||
{
|
||||
const auto memberList = m_group->members();
|
||||
QList<EffectWindow *> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/output.h"
|
||||
#include "kwin_export.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QWindow>
|
||||
|
||||
class QWindow;
|
||||
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#include "config-kwin.h"
|
||||
|
||||
#if !KWIN_BUILD_X11
|
||||
#error Do not include on non-X11 builds
|
||||
#endif
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <kwin_export.h>
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "workspace.h"
|
||||
#include "x11window.h"
|
||||
|
||||
#include <KStartupInfo>
|
||||
#include <KX11Extras>
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -116,4 +117,32 @@ void Group::lostLeader()
|
|||
}
|
||||
}
|
||||
|
||||
void Group::startupIdChanged()
|
||||
{
|
||||
KStartupInfoId asn_id;
|
||||
KStartupInfoData asn_data;
|
||||
bool asn_valid = workspace()->checkStartupNotification(leader_wid, asn_id, asn_data);
|
||||
if (!asn_valid) {
|
||||
return;
|
||||
}
|
||||
if (asn_id.timestamp() != 0 && user_time != -1U
|
||||
&& NET::timestampCompare(asn_id.timestamp(), user_time) > 0) {
|
||||
user_time = asn_id.timestamp();
|
||||
}
|
||||
}
|
||||
|
||||
void Group::updateUserTime(xcb_timestamp_t time)
|
||||
{
|
||||
// copy of X11Window::updateUserTime
|
||||
if (time == XCB_CURRENT_TIME) {
|
||||
kwinApp()->updateXTime();
|
||||
time = xTime();
|
||||
}
|
||||
if (time != -1U
|
||||
&& (user_time == XCB_CURRENT_TIME
|
||||
|| NET::timestampCompare(time, user_time) > 0)) { // time > user_time
|
||||
user_time = time;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <config-kwin.h>
|
||||
#if !KWIN_BUILD_X11
|
||||
#error Do not include on non-X11 builds
|
||||
#endif
|
||||
|
||||
#include "utils/common.h"
|
||||
#include <netwm.h>
|
||||
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* Usage kwin_wayland_wrapper [argForKwin] [argForKwin] ...
|
||||
*/
|
||||
|
||||
#include "config-kwin.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDBusConnection>
|
||||
#include <QDebug>
|
||||
|
@ -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<KWin::XwaylandSocket> m_xwlSocket;
|
||||
QTemporaryFile m_xauthorityFile;
|
||||
const std::chrono::microseconds m_watchdogInterval;
|
||||
bool m_watchdogIntervalOk;
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
std::unique_ptr<KWin::XwaylandSocket> 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>(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
|
||||
|
|
|
@ -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<X11Window *>(window) && kwinApp()->xwayland()) {
|
||||
return kwinApp()->xwayland()->xwlDropHandler();
|
||||
}
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#include <KLocalizedString>
|
||||
#include <KShell>
|
||||
#include <KKeyServer>
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include <QMenu>
|
||||
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <private/qxkbcommon_p.h>
|
||||
#include <unistd.h>
|
||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||
|
||||
|
@ -60,13 +60,14 @@ static std::vector<quint32> textToKey(const QString &text)
|
|||
return {};
|
||||
}
|
||||
|
||||
const QList<int> syms(KKeyServer::keyQtToSymXs(sequence[0]));
|
||||
QKeyEvent ev(QEvent::KeyPress, sequence[0], Qt::NoModifier);
|
||||
const QList<xkb_keysym_t> syms(QXkbCommon::toKeysym(&ev));
|
||||
if (syms.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<int> keyCode;
|
||||
for (int sym : syms) {
|
||||
std::optional<xkb_keycode_t> keyCode;
|
||||
for (xkb_keysym_t sym : syms) {
|
||||
auto code = input()->keyboard()->xkb()->keycodeFromKeysym(sym);
|
||||
if (code) {
|
||||
keyCode = code;
|
||||
|
|
|
@ -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)
|
||||
|
||||
if (KWIN_BUILD_X11)
|
||||
set(kwin_kcm_rules_XCB_LIBS
|
||||
XCB::CURSOR
|
||||
XCB::XCB
|
||||
XCB::XFIXES
|
||||
)
|
||||
endif()
|
||||
|
||||
set(kcm_libs
|
||||
Qt::Quick
|
||||
|
|
|
@ -27,8 +27,12 @@ target_link_libraries(kcm_kwintabbox
|
|||
KF6::Package
|
||||
KF6::Service
|
||||
KF6::XmlGui # For kkeysequencewidget
|
||||
)
|
||||
if (KWIN_BUILD_X11)
|
||||
target_link_libraries(kcm_kwintabbox
|
||||
XCB::XCB
|
||||
)
|
||||
endif()
|
||||
|
||||
########### install files ###############
|
||||
install(FILES thumbnails/falkon.png
|
||||
|
|
|
@ -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 <QDir>
|
||||
#include <QFileInfo>
|
||||
|
@ -25,7 +27,11 @@ namespace KWin
|
|||
KillPrompt::KillPrompt(Window *window)
|
||||
: m_window(window)
|
||||
{
|
||||
#if KWIN_BUILD_X11
|
||||
Q_ASSERT(qobject_cast<X11Window *>(window) || qobject_cast<XdgToplevelWindow *>(window));
|
||||
#else
|
||||
Q_ASSERT(qobject_cast<XdgToplevelWindow *>(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<X11Window *>(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<XdgToplevelWindow *>(m_window)) {
|
||||
} else
|
||||
#endif
|
||||
if (auto *xdgToplevel = qobject_cast<XdgToplevelWindow *>(m_window)) {
|
||||
platform = QStringLiteral("wayland");
|
||||
auto *exported = waylandServer()->exportAsForeign(xdgToplevel->surface());
|
||||
wid = exported->handle();
|
||||
|
|
121
src/layers.cpp
121
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 <array>
|
||||
|
||||
|
@ -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<X11Window *> 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<const X11Window *>(window)) {
|
||||
return layerForWindow(x11Window);
|
||||
} else {
|
||||
return window->layer();
|
||||
}
|
||||
#endif
|
||||
return window->layer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -635,11 +649,13 @@ QList<T *> ensureStackingOrderInList(const QList<Window *> &stackingOrder, const
|
|||
}
|
||||
}
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
// Ensure list is in stacking order
|
||||
QList<X11Window *> Workspace::ensureStackingOrder(const QList<X11Window *> &list) const
|
||||
{
|
||||
return ensureStackingOrderInList(stacking_order, list);
|
||||
}
|
||||
#endif
|
||||
|
||||
QList<Window *> Workspace::ensureStackingOrder(const QList<Window *> &list) const
|
||||
{
|
||||
|
@ -651,6 +667,7 @@ QList<Window *> 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<X11Window *>(*it);
|
||||
|
||||
if (!window || !((*it)->isNormalWindow() && window->isShown() && (*it)->isOnCurrentDesktop() && (*it)->isOnCurrentActivity() && (*it)->isOnOutput(output()))) {
|
||||
continue; // irrelevant windows
|
||||
}
|
||||
|
||||
if (*(it - 1) == other) {
|
||||
break; // "it" is the one above the target one, stack below "it"
|
||||
}
|
||||
}
|
||||
|
||||
if (it != begin && (*(it - 1) == other)) {
|
||||
other = qobject_cast<X11Window *>(*it);
|
||||
} else {
|
||||
other = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (other) {
|
||||
workspace()->restack(this, other);
|
||||
} else if (detail == XCB_STACK_MODE_BELOW) {
|
||||
workspace()->lowerWindowRequest(this, src, timestamp);
|
||||
} else if (detail == XCB_STACK_MODE_ABOVE) {
|
||||
workspace()->raiseWindowRequest(this, src, timestamp);
|
||||
}
|
||||
|
||||
if (send_event) {
|
||||
sendSyntheticConfigureNotify();
|
||||
}
|
||||
}
|
||||
|
||||
bool X11Window::belongsToDesktop() const
|
||||
{
|
||||
const auto members = group()->members();
|
||||
for (const X11Window *window : members) {
|
||||
if (window->isDesktop()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
|
26
src/main.cpp
26
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 <unistd.h>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
// xcb
|
||||
#include <xcb/damage.h>
|
||||
#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;
|
||||
|
|
13
src/main.h
13
src/main.h
|
@ -21,7 +21,9 @@
|
|||
#include <QApplication>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
#include <xcb/xcb.h>
|
||||
#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<QPointer<X11EventFilterContainer>> m_eventFilters;
|
||||
QList<QPointer<X11EventFilterContainer>> m_genericEventFilters;
|
||||
std::unique_ptr<XcbEventFilter> 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
|
||||
|
|
|
@ -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 <KCrash>
|
||||
|
@ -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<Xwl::Xwayland>(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));
|
||||
|
|
|
@ -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<Xwl::Xwayland> m_xwayland;
|
||||
QList<int> m_xwaylandListenFds;
|
||||
QString m_xwaylandDisplay;
|
||||
QString m_xwaylandXauthority;
|
||||
#endif
|
||||
KConfigWatcher::Ptr m_settingsWatcher;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "config-kwin.h"
|
||||
|
||||
#if !KWIN_BUILD_X11
|
||||
#error Do not include on non-X11 builds
|
||||
#endif
|
||||
|
||||
#include <NETWM>
|
||||
|
||||
#include <memory>
|
||||
|
|
|
@ -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 <epoxy/gl.h>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
#include "effect/xcb.h"
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QOpenGLContext>
|
||||
#include <QRegularExpression>
|
||||
|
|
|
@ -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 <QTextStream>
|
||||
#include <QTimer>
|
||||
|
||||
|
|
|
@ -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 <QCoreApplication>
|
||||
#include <QMatrix4x4>
|
||||
#include <QTimer>
|
||||
|
@ -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<EffectWindow *> 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)
|
||||
{
|
||||
|
|
|
@ -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<ContrastShader> m_shader;
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
long m_net_wm_contrast_region = 0;
|
||||
#endif
|
||||
QHash<const EffectWindow *, QMetaObject::Connection> m_contrastChangedConnections; // used only in Wayland to keep track of effect changed
|
||||
struct Data
|
||||
{
|
||||
|
|
|
@ -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 <QGuiApplication>
|
||||
#include <QMatrix4x4>
|
||||
#include <QScreen>
|
||||
|
@ -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<QRegion> content;
|
||||
std::optional<QRegion> 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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#include "keyboard_input.h"
|
||||
#include "xkb.h"
|
||||
|
||||
#include <KKeyServer>
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include <linux/input-event-codes.h>
|
||||
|
@ -23,6 +21,8 @@
|
|||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include <private/qxkbcommon_p.h>
|
||||
|
||||
// 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<int> syms(KKeyServer::keyQtToSymXs(keys[0]));
|
||||
QKeyEvent ev(QEvent::KeyPress, keys[0], Qt::NoModifier);
|
||||
const QList<xkb_keysym_t> syms(QXkbCommon::toKeysym(&ev));
|
||||
if (syms.empty()) {
|
||||
qCWarning(KWIN_BUTTONREBINDS) << "Could not convert" << keys << "to keysym";
|
||||
return false;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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<KWin::EffectWindow *> &windows);
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
long m_atom;
|
||||
#endif
|
||||
QList<EffectWindow *> m_highlightedWindows;
|
||||
QHash<EffectWindow *, quint64> m_animations;
|
||||
QEasingCurve m_easingCurve;
|
||||
|
|
|
@ -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<Output *> 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
|
||||
|
|
|
@ -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<Output *, ScreenState> m_waylandStates;
|
||||
ScreenState m_xcbState;
|
||||
Output *m_currentScreen = nullptr;
|
||||
#if KWIN_BUILD_X11
|
||||
xcb_atom_t m_atom;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -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 &)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
#include <QTimer>
|
||||
// KDE
|
||||
#include <KConfigGroup>
|
||||
#if KWIN_BUILD_X11
|
||||
#include <KSelectionOwner>
|
||||
#endif
|
||||
#include <KSharedConfig>
|
||||
#include <KWindowSystem>
|
||||
// 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) {
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
#pragma once
|
||||
#include "effect/effect.h"
|
||||
#include <KConfigWatcher>
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
#include <KStartupInfo>
|
||||
#endif
|
||||
#include <QIcon>
|
||||
#include <QObject>
|
||||
|
||||
#include <chrono>
|
||||
|
@ -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<QString, Startup> m_startups;
|
||||
bool m_active;
|
||||
|
|
|
@ -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 <KDecoration2/Decoration>
|
||||
// screenlocker
|
||||
#if KWIN_BUILD_SCREENLOCKER
|
||||
#include <KScreenLocker/KsldApp>
|
||||
#endif
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
#include "wayland_server.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
|
||||
#include <KDecoration2/Decoration>
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 <QtMath>
|
||||
|
||||
|
|
|
@ -30,8 +30,11 @@
|
|||
#include "virtualdesktops.h"
|
||||
#include "wayland/seat.h"
|
||||
#include "wayland_server.h"
|
||||
#include <window.h>
|
||||
#include <workspace.h>
|
||||
#include <x11window.h>
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
// DBus generated
|
||||
#if KWIN_BUILD_SCREENLOCKER
|
||||
#include "screenlocker_interface.h"
|
||||
|
@ -49,6 +52,7 @@
|
|||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
#include <span>
|
||||
|
||||
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<xcb_window_t> ScreenEdges::windows() const
|
||||
{
|
||||
QList<xcb_window_t> wins;
|
||||
|
@ -1538,6 +1547,7 @@ QList<xcb_window_t> ScreenEdges::windows() const
|
|||
}
|
||||
return wins;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ScreenEdges::setRemainActiveOnFullscreen(bool remainActive)
|
||||
{
|
||||
|
|
|
@ -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<xcb_window_t> 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<std::unique_ptr<Edge>> &edges() const;
|
||||
|
||||
|
|
|
@ -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 <QQmlEngine>
|
||||
|
||||
|
@ -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<KWin::Window *> WorkspaceWrapper::windowAt(const QPointF &pos, int count) const
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <KDecoration2/Decoration>
|
||||
#include <KDecoration2/DecorationShadow>
|
||||
|
@ -45,15 +48,18 @@ std::unique_ptr<Shadow> 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> Shadow::createShadowFromX11(Window *window)
|
||||
{
|
||||
X11Window *x11Window = qobject_cast<X11Window *>(window);
|
||||
|
@ -71,6 +77,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromX11(Window *window)
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Shadow> Shadow::createShadowFromDecoration(Window *window)
|
||||
{
|
||||
|
@ -118,6 +125,7 @@ std::unique_ptr<Shadow> Shadow::createShadowFromInternalWindow(Window *window)
|
|||
return shadow;
|
||||
}
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
QList<uint32_t> Shadow::readX11ShadowProperty(xcb_window_t id)
|
||||
{
|
||||
QList<uint32_t> ret;
|
||||
|
@ -133,9 +141,11 @@ QList<uint32_t> Shadow::readX11ShadowProperty(xcb_window_t id)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Shadow::init(const QList<uint32_t> &data)
|
||||
{
|
||||
#if KWIN_BUILD_X11
|
||||
QList<Xcb::WindowGeometry> pixmapGeometries(ShadowElementsCount);
|
||||
QList<xcb_get_image_cookie_t> getImageCookies(ShadowElementsCount);
|
||||
auto *c = kwinApp()->x11Connection();
|
||||
|
@ -167,6 +177,7 @@ bool Shadow::init(const QList<uint32_t> &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<X11Window *>(m_window)) {
|
||||
auto data = Shadow::readX11ShadowProperty(window->window());
|
||||
if (!data.isEmpty()) {
|
||||
|
@ -302,6 +314,7 @@ bool Shadow::updateShadow()
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
14
src/sm.cpp
14
src/sm.cpp
|
@ -18,9 +18,11 @@
|
|||
#include "virtualdesktops.h"
|
||||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
#include "x11window.h"
|
||||
#include "xdgshellwindow.h"
|
||||
#include <QDebug>
|
||||
#if KWIN_BUILD_X11
|
||||
#include "x11window.h"
|
||||
#endif
|
||||
|
||||
#include <QSessionManager>
|
||||
#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<Window *> windows = workspace()->windows();
|
||||
for (auto it = windows.begin(); it != windows.end(); ++it) {
|
||||
X11Window *c = qobject_cast<X11Window *>(*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<QByteArray> sessionIds)
|
||||
{
|
||||
// TODO clear it first
|
||||
|
@ -217,6 +224,7 @@ void SessionManager::storeSubSession(const QString &name, QSet<QByteArray> 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;
|
||||
|
|
6
src/sm.h
6
src/sm.h
|
@ -43,9 +43,11 @@ public:
|
|||
SessionState state() const;
|
||||
|
||||
void loadSubSessionInfo(const QString &name);
|
||||
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
void storeSubSession(const QString &name, QSet<QByteArray> sessionIds);
|
||||
SessionInfo *takeSessionInfo(X11Window *);
|
||||
#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);
|
||||
|
||||
|
|
|
@ -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 <QAction>
|
||||
#include <QKeyEvent>
|
||||
|
@ -42,12 +43,15 @@
|
|||
#include <KLazyLocalizedString>
|
||||
#include <KLocalizedString>
|
||||
#include <kkeyserver.h>
|
||||
#if KWIN_BUILD_X11
|
||||
#include "tabbox/x11_filter.h"
|
||||
#include "utils/xcbutils.h"
|
||||
// X11
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/keysymdef.h>
|
||||
// xcb
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
|
||||
#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<X11Filter>();
|
||||
#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
|
||||
|
|
|
@ -273,7 +273,10 @@ private:
|
|||
QList<ElectricBorder> m_borderActivate, m_borderAlternativeActivate;
|
||||
QHash<ElectricBorder, QAction *> m_touchActivate;
|
||||
QHash<ElectricBorder, QAction *> m_touchAlternativeActivate;
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
std::unique_ptr<X11EventFilter> m_x11EventFilter;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace TabBox
|
||||
|
|
|
@ -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 <QAction>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QWindow>
|
||||
|
||||
#include <KGlobalAccel>
|
||||
#include <KLazyLocalizedString>
|
||||
|
@ -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()) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 <kkeyserver.h>
|
||||
#endif
|
||||
|
||||
#include <QPainter>
|
||||
#include <QWidget>
|
||||
#include <kkeyserver.h>
|
||||
|
||||
#ifndef KCMRULES
|
||||
#include <QApplication>
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
#include <KConfigGroup>
|
||||
#include <KGlobalAccel>
|
||||
#include <KLocalizedString>
|
||||
#if KWIN_BUILD_X11
|
||||
#include <NETWM>
|
||||
#endif
|
||||
|
||||
// Qt
|
||||
#include <QAction>
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 <QDir>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <KStartupInfo>
|
||||
#endif
|
||||
// KDE
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KLocalizedString>
|
||||
#include <KStartupInfo>
|
||||
// Qt
|
||||
#include <QCryptographicHash>
|
||||
#include <QDBusConnection>
|
||||
|
@ -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<Window *> waylandWindows = waylandServer()->windows();
|
||||
|
@ -660,6 +669,7 @@ void Workspace::removeFromStack(Window *window)
|
|||
}
|
||||
}
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
X11Window *Workspace::createX11Window(xcb_window_t windowId, bool is_mapped)
|
||||
{
|
||||
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<X11Window *>(*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<X11Window *>(*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<X11Window *>(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<X11Window *>(*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<void(X11Window *)> 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<bool(const Window *)> 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<InternalWindow *>(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<X11Window *>(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<const Output *, QRect> 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<Output *> &order)
|
||||
{
|
||||
|
@ -3013,6 +3071,7 @@ void Workspace::setMoveResizeWindow(Window *window)
|
|||
}
|
||||
}
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
// When kwin crashes, windows will not be gravitated back to their original position
|
||||
// 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
|
||||
{
|
||||
|
|
|
@ -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<bool(const Window *)> 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<Window *> &stackingOrder() const;
|
||||
QList<Window *> unconstrainedStackingOrder() const;
|
||||
QList<X11Window *> ensureStackingOrder(const QList<X11Window *> &windows) const;
|
||||
QList<Window *> ensureStackingOrder(const QList<Window *> &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<X11Window *> ensureStackingOrder(const QList<X11Window *> &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<typename Slot>
|
||||
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<Window *> 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<Output *> m_outputs;
|
||||
|
@ -654,7 +673,6 @@ private:
|
|||
|
||||
QList<Window *> unconstrained_stacking_order; // Topmost last
|
||||
QList<Window *> stacking_order; // Topmost last
|
||||
QList<xcb_window_t> manual_overlays; // Topmost last
|
||||
bool force_restacking;
|
||||
QList<Window *> should_get_focus; // Last is most recent
|
||||
QList<Window *> attention_chain;
|
||||
|
@ -664,7 +682,13 @@ private:
|
|||
QList<Group *> groups;
|
||||
|
||||
bool was_user_interaction;
|
||||
#if KWIN_BUILD_X11
|
||||
QList<xcb_window_t> manual_overlays; // Topmost last
|
||||
std::unique_ptr<X11EventFilter> m_wasUserInteractionFilter;
|
||||
std::unique_ptr<Xcb::Window> m_nullFocus;
|
||||
std::unique_ptr<X11EventFilter> m_movingClientFilter;
|
||||
std::unique_ptr<X11EventFilter> m_syncAlarmFilter;
|
||||
#endif
|
||||
|
||||
int block_focus;
|
||||
|
||||
|
@ -686,9 +710,9 @@ private:
|
|||
QTimer updateToolWindowsTimer;
|
||||
|
||||
static Workspace *_self;
|
||||
|
||||
#if KWIN_BUILD_X11
|
||||
std::unique_ptr<KStartupInfo> m_startup;
|
||||
|
||||
#endif
|
||||
QHash<const VirtualDesktop *, QRectF> m_workAreas;
|
||||
QHash<const VirtualDesktop *, StrutRects> m_restrictedAreas;
|
||||
QHash<const VirtualDesktop *, QHash<const Output *, QRectF>> 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<Xcb::Window> m_nullFocus;
|
||||
friend class StackingUpdatesBlocker;
|
||||
|
||||
std::unique_ptr<KillWindow> m_windowKiller;
|
||||
std::unique_ptr<X11EventFilter> m_movingClientFilter;
|
||||
std::unique_ptr<X11EventFilter> m_syncAlarmFilter;
|
||||
|
||||
SessionManager *m_sessionManager;
|
||||
std::unique_ptr<FocusChain> m_focusChain;
|
||||
|
@ -775,6 +796,7 @@ inline Window *Workspace::mostRecentlyActivatedWindow() const
|
|||
return should_get_focus.count() > 0 ? should_get_focus.last() : m_activeWindow;
|
||||
}
|
||||
|
||||
#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<Window *> &Workspace::stackingOrder() const
|
||||
{
|
||||
|
|
|
@ -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<xcb_timestamp_t>(-1);
|
||||
}
|
||||
|
||||
xcb_timestamp_t X11Window::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data,
|
||||
bool session) const
|
||||
{
|
||||
xcb_timestamp_t time = info->userTime();
|
||||
// qDebug() << "User timestamp, initial:" << time;
|
||||
//^^ this deadlocks kwin --replace sometimes.
|
||||
|
||||
// newer ASN timestamp always replaces user timestamp, unless user timestamp is 0
|
||||
// helps e.g. with konqy reusing
|
||||
if (asn_data != nullptr && time != 0) {
|
||||
if (asn_id->timestamp() != 0
|
||||
&& (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) {
|
||||
time = asn_id->timestamp();
|
||||
}
|
||||
}
|
||||
qCDebug(KWIN_CORE) << "User timestamp, ASN:" << time;
|
||||
if (time == -1U) {
|
||||
// The window doesn't have any timestamp.
|
||||
// If it's the first window for its application
|
||||
// (i.e. there's no other window from the same app),
|
||||
// use the _KDE_NET_WM_USER_CREATION_TIME trick.
|
||||
// Otherwise, refuse activation of a window
|
||||
// from already running application if this application
|
||||
// is not the active one (unless focus stealing prevention is turned off).
|
||||
X11Window *act = dynamic_cast<X11Window *>(workspace()->mostRecentlyActivatedWindow());
|
||||
if (act != nullptr && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) {
|
||||
bool first_window = true;
|
||||
auto sameApplicationActiveHackPredicate = [this](const X11Window *cl) {
|
||||
// ignore already existing splashes, toolbars, utilities and menus,
|
||||
// as the app may show those before the main window
|
||||
return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
|
||||
&& cl != this && X11Window::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive);
|
||||
};
|
||||
if (isTransient()) {
|
||||
auto clientMainClients = [this]() {
|
||||
QList<X11Window *> ret;
|
||||
const auto mcs = mainWindows();
|
||||
for (auto mc : mcs) {
|
||||
if (X11Window *c = dynamic_cast<X11Window *>(mc)) {
|
||||
ret << c;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
if (act->hasTransient(this, true)) {
|
||||
; // is transient for currently active window, even though it's not
|
||||
// the same app (e.g. kcookiejar dialog) -> allow activation
|
||||
} else if (groupTransient() && findInList<X11Window, X11Window>(clientMainClients(), sameApplicationActiveHackPredicate) == nullptr) {
|
||||
; // standalone transient
|
||||
} else {
|
||||
first_window = false;
|
||||
}
|
||||
} else {
|
||||
#if KWIN_BUILD_X11
|
||||
if (workspace()->findClient(sameApplicationActiveHackPredicate)) {
|
||||
first_window = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// don't refuse if focus stealing prevention is turned off
|
||||
if (!first_window && rules()->checkFSP(options->focusStealingPreventionLevel()) > 0) {
|
||||
qCDebug(KWIN_CORE) << "User timestamp, already exists:" << 0;
|
||||
return 0; // refuse activation
|
||||
}
|
||||
}
|
||||
// Creation time would just mess things up during session startup,
|
||||
// as possibly many apps are started up at the same time.
|
||||
// If there's no active window yet, no timestamp will be needed,
|
||||
// as plain Workspace::allowWindowActivation() will return true
|
||||
// in such case. And if there's already active window,
|
||||
// it's better not to activate the new one.
|
||||
// Unless it was the active window at the time
|
||||
// of session saving and there was no user interaction yet,
|
||||
// this check will be done in manage().
|
||||
if (session) {
|
||||
return -1U;
|
||||
}
|
||||
time = readUserCreationTime();
|
||||
}
|
||||
qCDebug(KWIN_CORE) << "User timestamp, final:" << this << ":" << time;
|
||||
return time;
|
||||
}
|
||||
|
||||
xcb_timestamp_t X11Window::userTime() const
|
||||
{
|
||||
xcb_timestamp_t time = m_userTime;
|
||||
if (time == 0) { // doesn't want focus after showing
|
||||
return 0;
|
||||
}
|
||||
Q_ASSERT(group() != nullptr);
|
||||
if (time == -1U
|
||||
|| (group()->userTime() != -1U
|
||||
&& NET::timestampCompare(group()->userTime(), time) > 0)) {
|
||||
time = group()->userTime();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
void X11Window::doSetActive()
|
||||
{
|
||||
updateUrgency(); // demand attention again if it's still urgent
|
||||
info->setState(isActive() ? NET::Focused : NET::States(), NET::Focused);
|
||||
}
|
||||
|
||||
void X11Window::startupIdChanged()
|
||||
{
|
||||
KStartupInfoId asn_id;
|
||||
KStartupInfoData asn_data;
|
||||
bool asn_valid = workspace()->checkStartupNotification(window(), asn_id, asn_data);
|
||||
if (!asn_valid) {
|
||||
return;
|
||||
}
|
||||
// If the ASN contains desktop, move it to the desktop, otherwise move it to the current
|
||||
// desktop (since the new ASN should make the window act like if it's a new application
|
||||
// launched). However don't affect the window's desktop if it's set to be on all desktops.
|
||||
|
||||
if (asn_data.desktop() != 0 && !isOnAllDesktops()) {
|
||||
if (asn_data.desktop() == -1) {
|
||||
workspace()->sendWindowToDesktops(this, {}, true);
|
||||
} else {
|
||||
if (VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(asn_data.desktop())) {
|
||||
workspace()->sendWindowToDesktops(this, {desktop}, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (asn_data.xinerama() != -1) {
|
||||
Output *output = workspace()->xineramaIndexToOutput(asn_data.xinerama());
|
||||
if (output) {
|
||||
workspace()->sendWindowToOutput(this, output);
|
||||
}
|
||||
}
|
||||
const xcb_timestamp_t timestamp = asn_id.timestamp();
|
||||
if (timestamp != 0) {
|
||||
bool activate = allowWindowActivation(timestamp);
|
||||
if (activate) {
|
||||
workspace()->activateWindow(this);
|
||||
} else {
|
||||
demandAttention();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void X11Window::updateUrgency()
|
||||
{
|
||||
if (info->urgency()) {
|
||||
demandAttention();
|
||||
}
|
||||
}
|
||||
|
||||
namespace FSP
|
||||
{
|
||||
enum Level {
|
||||
None = 0,
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
Extreme,
|
||||
};
|
||||
}
|
||||
|
||||
// focus_in -> the window got FocusIn event
|
||||
bool X11Window::allowWindowActivation(xcb_timestamp_t time, bool focus_in)
|
||||
{
|
||||
auto window = this;
|
||||
// options->focusStealingPreventionLevel :
|
||||
// 0 - none - old KWin behaviour, new windows always get focus
|
||||
// 1 - low - focus stealing prevention is applied normally, when unsure, activation is allowed
|
||||
// 2 - normal - focus stealing prevention is applied normally, when unsure, activation is not allowed,
|
||||
// this is the default
|
||||
// 3 - high - new window gets focus only if it belongs to the active application,
|
||||
// or when no window is currently active
|
||||
// 4 - extreme - no window gets focus without user intervention
|
||||
if (time == -1U) {
|
||||
time = window->userTime();
|
||||
}
|
||||
const FSP::Level level = (FSP::Level)window->rules()->checkFSP(options->focusStealingPreventionLevel());
|
||||
if (workspace()->sessionManager()->state() == SessionState::Saving && level <= FSP::Medium) { // <= normal
|
||||
return true;
|
||||
}
|
||||
Window *ac = workspace()->mostRecentlyActivatedWindow();
|
||||
if (focus_in) {
|
||||
if (workspace()->inShouldGetFocus(window)) {
|
||||
return true; // FocusIn was result of KWin's action
|
||||
}
|
||||
// Before getting FocusIn, the active Client already
|
||||
// got FocusOut, and therefore got deactivated.
|
||||
ac = workspace()->lastActiveWindow();
|
||||
}
|
||||
if (time == 0) { // explicitly asked not to get focus
|
||||
if (!window->rules()->checkAcceptFocus(false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const FSP::Level protection = (FSP::Level)(ac ? ac->rules()->checkFPP(2) : FSP::None);
|
||||
|
||||
// stealing is unconditionally allowed (NETWM behavior)
|
||||
if (level == FSP::None || protection == FSP::None) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The active window "grabs" the focus or stealing is generally forbidden
|
||||
if (level == FSP::Extreme || protection == FSP::Extreme) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No active window, it's ok to pass focus
|
||||
// NOTICE that extreme protection needs to be handled before to allow protection on unmanged windows
|
||||
if (ac == nullptr || ac->isDesktop()) {
|
||||
qCDebug(KWIN_CORE) << "Activation: No window active, allowing";
|
||||
return true; // no active window -> always allow
|
||||
}
|
||||
|
||||
// TODO window urgency -> return true?
|
||||
|
||||
// Unconditionally allow intra-window passing around for lower stealing protections
|
||||
// unless the active window has High interest
|
||||
if (Window::belongToSameApplication(window, ac, Window::SameApplicationCheck::RelaxedForActive) && protection < FSP::High) {
|
||||
qCDebug(KWIN_CORE) << "Activation: Belongs to active application";
|
||||
return true;
|
||||
}
|
||||
|
||||
// High FPS, not intr-window change. Only allow if the active window has only minor interest
|
||||
if (level > FSP::Medium && protection > FSP::Low) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (time == -1U) { // no time known
|
||||
qCDebug(KWIN_CORE) << "Activation: No timestamp at all";
|
||||
// Only allow for Low protection unless active window has High interest in focus
|
||||
if (level < FSP::Medium && protection < FSP::High) {
|
||||
return true;
|
||||
}
|
||||
// no timestamp at all, don't activate - because there's also creation timestamp
|
||||
// done on CreateNotify, this case should happen only in case application
|
||||
// maps again already used window, i.e. this won't happen after app startup
|
||||
return false;
|
||||
}
|
||||
|
||||
// Low or medium FSP, usertime comparism is possible
|
||||
const xcb_timestamp_t user_time = ac->userTime();
|
||||
qCDebug(KWIN_CORE) << "Activation, compared:" << window << ":" << time << ":" << user_time
|
||||
<< ":" << (NET::timestampCompare(time, user_time) >= 0);
|
||||
return NET::timestampCompare(time, user_time) >= 0; // time >= user_time
|
||||
}
|
||||
|
||||
void X11Window::restackWindow(xcb_window_t above, int detail, NET::RequestSource src, xcb_timestamp_t timestamp, bool send_event)
|
||||
{
|
||||
X11Window *other = nullptr;
|
||||
if (detail == XCB_STACK_MODE_OPPOSITE) {
|
||||
other = workspace()->findClient(Predicate::WindowMatch, above);
|
||||
if (!other) {
|
||||
workspace()->raiseOrLowerWindow(this);
|
||||
return;
|
||||
}
|
||||
auto it = workspace()->stackingOrder().constBegin(),
|
||||
end = workspace()->stackingOrder().constEnd();
|
||||
while (it != end) {
|
||||
if (*it == this) {
|
||||
detail = XCB_STACK_MODE_ABOVE;
|
||||
break;
|
||||
} else if (*it == other) {
|
||||
detail = XCB_STACK_MODE_BELOW;
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
} else if (detail == XCB_STACK_MODE_TOP_IF) {
|
||||
other = workspace()->findClient(Predicate::WindowMatch, above);
|
||||
if (other && other->frameGeometry().intersects(frameGeometry())) {
|
||||
workspace()->raiseWindowRequest(this, src, timestamp);
|
||||
}
|
||||
return;
|
||||
} else if (detail == XCB_STACK_MODE_BOTTOM_IF) {
|
||||
other = workspace()->findClient(Predicate::WindowMatch, above);
|
||||
if (other && other->frameGeometry().intersects(frameGeometry())) {
|
||||
workspace()->lowerWindowRequest(this, src, timestamp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!other) {
|
||||
other = workspace()->findClient(Predicate::WindowMatch, above);
|
||||
}
|
||||
|
||||
if (other && detail == XCB_STACK_MODE_ABOVE) {
|
||||
auto it = workspace()->stackingOrder().constEnd(),
|
||||
begin = workspace()->stackingOrder().constBegin();
|
||||
while (--it != begin) {
|
||||
|
||||
if (*it == other) { // the other one is top on stack
|
||||
it = begin; // invalidate
|
||||
src = NET::FromTool; // force
|
||||
break;
|
||||
}
|
||||
X11Window *window = qobject_cast<X11Window *>(*it);
|
||||
|
||||
if (!window || !((*it)->isNormalWindow() && window->isShown() && (*it)->isOnCurrentDesktop() && (*it)->isOnCurrentActivity() && (*it)->isOnOutput(output()))) {
|
||||
continue; // irrelevant windows
|
||||
}
|
||||
|
||||
if (*(it - 1) == other) {
|
||||
break; // "it" is the one above the target one, stack below "it"
|
||||
}
|
||||
}
|
||||
|
||||
if (it != begin && (*(it - 1) == other)) {
|
||||
other = qobject_cast<X11Window *>(*it);
|
||||
} else {
|
||||
other = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (other) {
|
||||
workspace()->restack(this, other);
|
||||
} else if (detail == XCB_STACK_MODE_BELOW) {
|
||||
workspace()->lowerWindowRequest(this, src, timestamp);
|
||||
} else if (detail == XCB_STACK_MODE_ABOVE) {
|
||||
workspace()->raiseWindowRequest(this, src, timestamp);
|
||||
}
|
||||
|
||||
if (send_event) {
|
||||
sendSyntheticConfigureNotify();
|
||||
}
|
||||
}
|
||||
|
||||
bool X11Window::belongsToDesktop() const
|
||||
{
|
||||
const auto members = group()->members();
|
||||
for (const X11Window *window : members) {
|
||||
if (window->isDesktop()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void X11Window::setShortcutInternal()
|
||||
{
|
||||
updateCaption();
|
||||
#if 0
|
||||
workspace()->windowShortcutUpdated(this);
|
||||
#else
|
||||
// Workaround for kwin<->kglobalaccel deadlock, when KWin has X grab and the kded
|
||||
// kglobalaccel module tries to create the key grab. KWin should preferably grab
|
||||
// they keys itself anyway :(.
|
||||
QTimer::singleShot(0, this, std::bind(&Workspace::windowShortcutUpdated, workspace(), this));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "moc_x11window.cpp"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "config-kwin.h"
|
||||
|
||||
#if !KWIN_BUILD_X11
|
||||
#error Do not include on non-X11 builds
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "xwayland_interface.h"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
if(KWIN_BUILD_X11)
|
||||
set(normalhintsbasesizetest_SRCS normalhintsbasesizetest.cpp)
|
||||
add_executable(normalhintsbasesizetest ${normalhintsbasesizetest_SRCS})
|
||||
target_link_libraries(normalhintsbasesizetest XCB::XCB XCB::ICCCM KF6::WindowSystem)
|
||||
|
@ -13,6 +14,7 @@ target_link_libraries(x11shadowreader XCB::XCB Qt::GuiPrivate Qt::Widgets KF6::C
|
|||
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}")
|
||||
|
|
Loading…
Reference in a new issue