Merge XwaylandWindow with X11Window

This commit is contained in:
Vlad Zahorodnii 2023-03-28 22:08:11 +03:00
parent c395afde9b
commit 2d275e16ec
6 changed files with 35 additions and 101 deletions

View file

@ -181,7 +181,6 @@ target_sources(kwin PRIVATE
xdgshellintegration.cpp xdgshellintegration.cpp
xdgshellwindow.cpp xdgshellwindow.cpp
xkb.cpp xkb.cpp
xwaylandwindow.cpp
) )
target_link_libraries(kwin target_link_libraries(kwin

View file

@ -57,7 +57,6 @@
#include "virtualdesktops.h" #include "virtualdesktops.h"
#include "was_user_interaction_x11_filter.h" #include "was_user_interaction_x11_filter.h"
#include "wayland_server.h" #include "wayland_server.h"
#include "xwaylandwindow.h"
// KDE // KDE
#include <KConfig> #include <KConfig>
#include <KConfigGroup> #include <KConfigGroup>
@ -653,12 +652,7 @@ void Workspace::removeFromStack(Window *window)
X11Window *Workspace::createX11Window(xcb_window_t windowId, bool is_mapped) X11Window *Workspace::createX11Window(xcb_window_t windowId, bool is_mapped)
{ {
StackingUpdatesBlocker blocker(this); StackingUpdatesBlocker blocker(this);
X11Window *window = nullptr; X11Window *window = new X11Window();
if (kwinApp()->operationMode() == Application::OperationModeX11) {
window = new X11Window();
} else {
window = new XwaylandWindow();
}
setupWindowConnections(window); setupWindowConnections(window);
if (X11Compositor *compositor = X11Compositor::self()) { if (X11Compositor *compositor = X11Compositor::self()) {
connect(window, &X11Window::blockingCompositingChanged, compositor, &X11Compositor::updateClientCompositeBlocking); connect(window, &X11Window::blockingCompositingChanged, compositor, &X11Compositor::updateClientCompositeBlocking);

View file

@ -1169,6 +1169,21 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
info.setOpacityF(opacity()); 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; return true;
} }
@ -2466,7 +2481,16 @@ void X11Window::getIcons()
*/ */
bool X11Window::wantsSyncCounter() const 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() void X11Window::getSyncCounter()
@ -4987,12 +5011,18 @@ void X11Window::updateWindowPixmap()
void X11Window::associate() void X11Window::associate()
{ {
auto handleMapped = [this]() {
if (syncRequest().counter == XCB_NONE) { // cannot detect complete redraw, consider done now
setReadyForPainting();
}
};
if (surface()->isMapped()) { if (surface()->isMapped()) {
setReadyForPainting(); handleMapped();
} else { } else {
// Queued connection because we want to mark the window ready for painting after // Queued connection because we want to mark the window ready for painting after
// the associated surface item has processed the new surface state. // 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);
} }
} }

View file

@ -285,7 +285,7 @@ public:
{ {
return m_syncRequest; return m_syncRequest;
} }
virtual bool wantsSyncCounter() const; bool wantsSyncCounter() const;
void handleSync(); void handleSync();
void handleSyncTimeout(); void handleSyncTimeout();

View file

@ -1,55 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
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

View file

@ -1,34 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
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