[x11] Disable synchronized resizing for Xwayland < 1.21

In case Xwayland does not use multiple buffers, the currently attached
buffer is going to be destroyed if the frame window is resized. It may
render the previous and the current window pixmap invalid and thus result
in visual artifacts when an X11 client is being interactively resized.

In order to avoid the visual artifacts, this change disables support for
synchronized resizing for X11 clients if the version of Xwayland is less
than the version in which Xwayland started using multiple buffers, i.e.
1.21.

Differential Revision: https://phabricator.kde.org/D29250
This commit is contained in:
Vlad Zahorodnii 2020-04-27 21:44:12 +03:00
parent a9d2bad007
commit 76af96bcc9
6 changed files with 97 additions and 4 deletions

View file

@ -509,6 +509,7 @@ set(kwin_SRCS
xcbutils.cpp
xdgshellclient.cpp
xkb.cpp
xwaylandclient.cpp
xwl/xwayland_interface.cpp
)

View file

@ -62,6 +62,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "xcbutils.h"
#include "main.h"
#include "decorations/decorationbridge.h"
#include "xwaylandclient.h"
// KDE
#include <KConfig>
#include <KConfigGroup>
@ -528,7 +529,12 @@ void Workspace::setupClientConnections(AbstractClient *c)
X11Client *Workspace::createClient(xcb_window_t w, bool is_mapped)
{
StackingUpdatesBlocker blocker(this);
X11Client *c = new X11Client();
X11Client *c = nullptr;
if (kwinApp()->operationMode() == Application::OperationModeX11) {
c = new X11Client();
} else {
c = new XwaylandClient();
}
setupClientConnections(c);
if (X11Compositor *compositor = X11Compositor::self()) {
connect(c, &X11Client::blockingCompositingChanged, compositor, &X11Compositor::updateClientCompositeBlocking);

View file

@ -2342,10 +2342,20 @@ void X11Client::getIcons()
setIcon(icon);
}
/**
* Returns \c true if X11Client wants to throttle resizes; otherwise returns \c false.
*/
bool X11Client::wantsSyncCounter() const
{
return true;
}
void X11Client::getSyncCounter()
{
if (!Xcb::Extensions::self()->isSyncAvailable())
return;
if (!wantsSyncCounter())
return;
Xcb::Property syncProp(false, window(), atoms->net_wm_sync_request_counter, XCB_ATOM_CARDINAL, 0, 1);
const xcb_sync_counter_t counter = syncProp.value<xcb_sync_counter_t>(XCB_NONE);

View file

@ -85,6 +85,8 @@ class KWIN_EXPORT X11Client : public AbstractClient
Q_PROPERTY(bool clientSideDecorated READ isClientSideDecorated NOTIFY clientSideDecoratedChanged)
public:
explicit X11Client();
~X11Client() override; ///< Use destroyClient() or releaseWindow()
xcb_window_t wrapperId() const;
xcb_window_t inputId() const { return m_decoInputExtent; }
xcb_window_t frameId() const override;
@ -320,6 +322,7 @@ public:
const SyncRequest &syncRequest() const {
return m_syncRequest;
}
virtual bool wantsSyncCounter() const;
void handleSync();
static void cleanupX11();
@ -333,9 +336,6 @@ private Q_SLOTS:
void shadeUnhover();
private:
// Use Workspace::createClient()
~X11Client() override; ///< Use destroyClient() or releaseWindow()
// Handlers for X11 events
bool mapRequestEvent(xcb_map_request_event_t *e);
void unmapNotifyEvent(xcb_unmap_notify_event_t *e);

37
xwaylandclient.cpp Normal file
View file

@ -0,0 +1,37 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "xwaylandclient.h"
namespace KWin
{
bool XwaylandClient::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(connection())->release_number;
return xwaylandVersion >= 12100000;
}
} // namespace KWin

39
xwaylandclient.h Normal file
View file

@ -0,0 +1,39 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#pragma once
#include "x11client.h"
namespace KWin
{
/**
* The XwaylandClient class represents a managed Xwayland client.
*/
class XwaylandClient : public X11Client
{
Q_OBJECT
public:
bool wantsSyncCounter() const override;
};
} // namespace KWin