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
xdgshellwindow.cpp
xkb.cpp
xwaylandwindow.cpp
)
target_link_libraries(kwin

View file

@ -57,7 +57,6 @@
#include "virtualdesktops.h"
#include "was_user_interaction_x11_filter.h"
#include "wayland_server.h"
#include "xwaylandwindow.h"
// KDE
#include <KConfig>
#include <KConfigGroup>
@ -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);

View file

@ -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
{
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()
{
if (surface()->isMapped()) {
auto handleMapped = [this]() {
if (syncRequest().counter == XCB_NONE) { // cannot detect complete redraw, consider done now
setReadyForPainting();
}
};
if (surface()->isMapped()) {
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);
}
}

View file

@ -285,7 +285,7 @@ public:
{
return m_syncRequest;
}
virtual bool wantsSyncCounter() const;
bool wantsSyncCounter() const;
void handleSync();
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