From 2b868edb9eb81e6c6ce6164e189beefd8759a9d2 Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Thu, 23 Nov 2023 14:48:04 +0100 Subject: [PATCH] xdgshell: Use killPingTimeout option This makes it consistent with the timeout used on X11. The current ping timeout was also generally quite short, causing apps to desaturate for brief moments when they were busy e.g. starting up or loading large files. --- autotests/integration/xdgshellwindow_test.cpp | 5 +++-- src/wayland/xdgshell.cpp | 13 ++++++++++++- src/wayland/xdgshell.h | 12 ++++++++++++ src/wayland/xdgshell_p.h | 1 + src/wayland_server.cpp | 7 +++++++ src/xdgshellintegration.cpp | 17 +++++++++++++---- src/xdgshellintegration.h | 8 ++++++++ 7 files changed, 56 insertions(+), 7 deletions(-) diff --git a/autotests/integration/xdgshellwindow_test.cpp b/autotests/integration/xdgshellwindow_test.cpp index ee16edb79d..7f9d657f36 100644 --- a/autotests/integration/xdgshellwindow_test.cpp +++ b/autotests/integration/xdgshellwindow_test.cpp @@ -822,7 +822,8 @@ void TestXdgShellWindow::testUnresponsiveWindow() QVERIFY(unresponsiveSpy.wait()); // window should be marked unresponsive but not killed auto elapsed1 = QDateTime::currentMSecsSinceEpoch() - startTime; - QVERIFY(elapsed1 > 900 && elapsed1 < 1200); // ping timer is 1s, but coarse timers on a test across two processes means we need a fuzzy compare + const int timeout = options->killPingTimeout() / 2; + QVERIFY(elapsed1 > timeout - 200 && elapsed1 < timeout + 200); // coarse timers on a test across two processes means we need a fuzzy compare QVERIFY(killWindow->unresponsive()); QVERIFY(killedSpy.isEmpty()); @@ -833,7 +834,7 @@ void TestXdgShellWindow::testUnresponsiveWindow() } auto elapsed2 = QDateTime::currentMSecsSinceEpoch() - startTime; - QVERIFY(elapsed2 > 1800); // second ping comes in a second later + QVERIFY(elapsed2 > timeout * 2 - 200); // second ping comes in later } void TestXdgShellWindow::testAppMenu() diff --git a/src/wayland/xdgshell.cpp b/src/wayland/xdgshell.cpp index 3a587692a0..a371f4db1b 100644 --- a/src/wayland/xdgshell.cpp +++ b/src/wayland/xdgshell.cpp @@ -41,7 +41,8 @@ void XdgShellInterfacePrivate::unregisterXdgSurface(XdgSurfaceInterface *surface void XdgShellInterfacePrivate::registerPing(quint32 serial) { QTimer *timer = new QTimer(q); - timer->setInterval(1000); + // we'll run the timer twice. + timer->setInterval(pingTimeout / 2); QObject::connect(timer, &QTimer::timeout, q, [this, serial, attempt = 0]() mutable { ++attempt; if (attempt == 1) { @@ -134,6 +135,16 @@ quint32 XdgShellInterface::ping(XdgSurfaceInterface *surface) return serial; } +std::chrono::milliseconds XdgShellInterface::pingTimeoutInterval() const +{ + return d->pingTimeout; +} + +void XdgShellInterface::setPingTimeoutInterval(std::chrono::milliseconds pingTimeout) +{ + d->pingTimeout = pingTimeout; +} + XdgSurfaceInterfacePrivate::XdgSurfaceInterfacePrivate(XdgSurfaceInterface *xdgSurface) : q(xdgSurface) { diff --git a/src/wayland/xdgshell.h b/src/wayland/xdgshell.h index c4822f8f5c..72e6536190 100644 --- a/src/wayland/xdgshell.h +++ b/src/wayland/xdgshell.h @@ -10,6 +10,8 @@ #include #include + +#include #include struct wl_resource; @@ -65,6 +67,16 @@ public: */ quint32 ping(XdgSurfaceInterface *surface); + /** + * Returns the ping timeout. + */ + std::chrono::milliseconds pingTimeoutInterval() const; + + /** + * Set the ping timeout. + */ + void setPingTimeoutInterval(std::chrono::milliseconds pingTimeout); + Q_SIGNALS: /** * This signal is emitted when a new XdgToplevelInterface object is created. diff --git a/src/wayland/xdgshell_p.h b/src/wayland/xdgshell_p.h index 8b79d3f9b5..8e9329ae0a 100644 --- a/src/wayland/xdgshell_p.h +++ b/src/wayland/xdgshell_p.h @@ -31,6 +31,7 @@ public: XdgShellInterface *q; Display *display = nullptr; QMap pings; + std::chrono::milliseconds pingTimeout = std::chrono::milliseconds(1000); protected: void xdg_wm_base_destroy_resource(Resource *resource) override; diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 3feb35f121..aa8790c7ae 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -18,6 +18,7 @@ #include "layershellv1integration.h" #include "layershellv1window.h" #include "main.h" +#include "options.h" #include "utils/serviceutils.h" #include "virtualdesktops.h" #include "wayland/appmenu.h" @@ -519,6 +520,12 @@ void WaylandServer::initWorkspace() connect(xdgShellIntegration, &XdgShellIntegration::windowCreated, this, &WaylandServer::registerXdgGenericWindow); + auto setPingTimeout = [xdgShellIntegration] { + xdgShellIntegration->setPingTimeout(std::chrono::milliseconds(options->killPingTimeout())); + }; + connect(options, &Options::killPingTimeoutChanged, xdgShellIntegration, setPingTimeout); + setPingTimeout(); + auto layerShellV1Integration = new LayerShellV1Integration(this); connect(layerShellV1Integration, &LayerShellV1Integration::windowCreated, this, &WaylandServer::registerWindow); diff --git a/src/xdgshellintegration.cpp b/src/xdgshellintegration.cpp index 205163294e..6791de402f 100644 --- a/src/xdgshellintegration.cpp +++ b/src/xdgshellintegration.cpp @@ -28,15 +28,24 @@ namespace KWin XdgShellIntegration::XdgShellIntegration(QObject *parent) : WaylandShellIntegration(parent) + , m_shell(new XdgShellInterface(waylandServer()->display(), this)) { - XdgShellInterface *shell = new XdgShellInterface(waylandServer()->display(), this); - - connect(shell, &XdgShellInterface::toplevelCreated, + connect(m_shell, &XdgShellInterface::toplevelCreated, this, &XdgShellIntegration::registerXdgToplevel); - connect(shell, &XdgShellInterface::popupCreated, + connect(m_shell, &XdgShellInterface::popupCreated, this, &XdgShellIntegration::registerXdgPopup); } +std::chrono::milliseconds XdgShellIntegration::pingTimeout() const +{ + return m_shell->pingTimeoutInterval(); +} + +void XdgShellIntegration::setPingTimeout(std::chrono::milliseconds pingTimeout) +{ + m_shell->setPingTimeoutInterval(pingTimeout); +} + void XdgShellIntegration::registerXdgToplevel(XdgToplevelInterface *toplevel) { // Note that the window is going to be destroyed and immediately re-created when the diff --git a/src/xdgshellintegration.h b/src/xdgshellintegration.h index 78c9a4fe62..50db9baf8d 100644 --- a/src/xdgshellintegration.h +++ b/src/xdgshellintegration.h @@ -8,9 +8,12 @@ #include "waylandshellintegration.h" +#include + namespace KWin { +class XdgShellInterface; class XdgToplevelInterface; class XdgPopupInterface; @@ -21,10 +24,15 @@ class XdgShellIntegration : public WaylandShellIntegration public: explicit XdgShellIntegration(QObject *parent = nullptr); + std::chrono::milliseconds pingTimeout() const; + void setPingTimeout(std::chrono::milliseconds pingTimeout); + private: void registerXdgToplevel(XdgToplevelInterface *toplevel); void registerXdgPopup(XdgPopupInterface *popup); void createXdgToplevelWindow(XdgToplevelInterface *surface); + + XdgShellInterface *m_shell; }; } // namespace KWin