diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3e2d8b1b21..83ce1d07ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -181,7 +181,6 @@ target_sources(kwin PRIVATE xdgshellintegration.cpp xdgshellwindow.cpp xkb.cpp - xwaylandwindow.cpp ) target_link_libraries(kwin diff --git a/src/workspace.cpp b/src/workspace.cpp index 3c02e13b7f..891000ce94 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -57,7 +57,6 @@ #include "virtualdesktops.h" #include "was_user_interaction_x11_filter.h" #include "wayland_server.h" -#include "xwaylandwindow.h" // KDE #include #include @@ -653,12 +652,7 @@ void Workspace::removeFromStack(Window *window) X11Window *Workspace::createX11Window(xcb_window_t windowId, bool is_mapped) { StackingUpdatesBlocker blocker(this); - X11Window *window = nullptr; - if (kwinApp()->operationMode() == Application::OperationModeX11) { - window = new X11Window(); - } else { - window = new XwaylandWindow(); - } + X11Window *window = new X11Window(); setupWindowConnections(window); if (X11Compositor *compositor = X11Compositor::self()) { connect(window, &X11Window::blockingCompositingChanged, compositor, &X11Compositor::updateClientCompositeBlocking); diff --git a/src/x11window.cpp b/src/x11window.cpp index 0ed0569e22..de8b5fa621 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -1169,6 +1169,21 @@ bool X11Window::manage(xcb_window_t w, bool isMapped) info.setOpacityF(opacity()); }); + switch (kwinApp()->operationMode()) { + case Application::OperationModeXwayland: + // The wayland surface is associated with the window asynchronously. + if (surface()) { + associate(); + } else { + connect(this, &Window::surfaceChanged, this, &X11Window::associate); + } + break; + case Application::OperationModeX11: + break; + case Application::OperationModeWaylandOnly: + Q_UNREACHABLE(); + } + return true; } @@ -2466,7 +2481,16 @@ void X11Window::getIcons() */ bool X11Window::wantsSyncCounter() const { - return true; + if (!waylandServer()) { + return true; + } + // When the frame window is resized, the attached buffer will be destroyed by + // Xwayland, causing unexpected invalid previous and current window pixmaps. + // With the addition of multiple window buffers in Xwayland 1.21, X11 clients + // are no longer able to destroy the buffer after it's been committed and not + // released by the compositor yet. + static const quint32 xwaylandVersion = xcb_get_setup(kwinApp()->x11Connection())->release_number; + return xwaylandVersion >= 12100000; } void X11Window::getSyncCounter() @@ -4987,12 +5011,18 @@ void X11Window::updateWindowPixmap() void X11Window::associate() { + auto handleMapped = [this]() { + if (syncRequest().counter == XCB_NONE) { // cannot detect complete redraw, consider done now + setReadyForPainting(); + } + }; + if (surface()->isMapped()) { - setReadyForPainting(); + handleMapped(); } else { // Queued connection because we want to mark the window ready for painting after // the associated surface item has processed the new surface state. - connect(surface(), &KWaylandServer::SurfaceInterface::mapped, this, &X11Window::setReadyForPainting, Qt::QueuedConnection); + connect(surface(), &KWaylandServer::SurfaceInterface::mapped, this, handleMapped, Qt::QueuedConnection); } } diff --git a/src/x11window.h b/src/x11window.h index f6e77e9c62..3bc77ac7c9 100644 --- a/src/x11window.h +++ b/src/x11window.h @@ -285,7 +285,7 @@ public: { return m_syncRequest; } - virtual bool wantsSyncCounter() const; + bool wantsSyncCounter() const; void handleSync(); void handleSyncTimeout(); diff --git a/src/xwaylandwindow.cpp b/src/xwaylandwindow.cpp deleted file mode 100644 index 32fac66ec8..0000000000 --- a/src/xwaylandwindow.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2020 Vlad Zahorodnii - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include "xwaylandwindow.h" -#include "wayland/surface_interface.h" - -using namespace KWaylandServer; - -namespace KWin -{ - -XwaylandWindow::XwaylandWindow() -{ - // The wayland surface is associated with the Xwayland window asynchronously. - connect(this, &Window::surfaceChanged, this, &XwaylandWindow::associate); -} - -void XwaylandWindow::associate() -{ - if (surface()->isMapped()) { - initialize(); - } else { - // Queued connection because we want to mark the window ready for painting after - // the associated surface item has processed the new surface state. - connect(surface(), &SurfaceInterface::mapped, this, &XwaylandWindow::initialize, Qt::QueuedConnection); - } -} - -void XwaylandWindow::initialize() -{ - if (!readyForPainting()) { // avoid "setReadyForPainting()" function calling overhead - if (syncRequest().counter == XCB_NONE) { // cannot detect complete redraw, consider done now - setReadyForPainting(); - } - } -} - -bool XwaylandWindow::wantsSyncCounter() const -{ - // When the frame window is resized, the attached buffer will be destroyed by - // Xwayland, causing unexpected invalid previous and current window pixmaps. - // With the addition of multiple window buffers in Xwayland 1.21, X11 clients - // are no longer able to destroy the buffer after it's been committed and not - // released by the compositor yet. - static const quint32 xwaylandVersion = xcb_get_setup(kwinApp()->x11Connection())->release_number; - return xwaylandVersion >= 12100000; -} - -} // namespace KWin diff --git a/src/xwaylandwindow.h b/src/xwaylandwindow.h deleted file mode 100644 index bb1929e8b6..0000000000 --- a/src/xwaylandwindow.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2020 Vlad Zahorodnii - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#pragma once - -#include "x11window.h" - -namespace KWin -{ - -/** - * The XwaylandWindow class represents a managed Xwayland window. - */ -class XwaylandWindow : public X11Window -{ - Q_OBJECT - -public: - explicit XwaylandWindow(); - - bool wantsSyncCounter() const override; - -private: - void associate(); - void initialize(); -}; - -} // namespace KWin