[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1117893: High CPU usage in kwin_x11 when locking the screen while an external display is connected



Source: qt6-base
Version: 6.8.2+dfsg-9
Severity: normal
Tags: patch

Dear Maintainers,

When I lock the screen while an external display is connected, CPU usage
increases a lot by kwin_x11. After investigating, I found a KDE bug report about this issue. The bug was fixed in newer versions of QT. I applied the specific patch to Debian's qt6-base package and I can confirm that the fix works as intended.
Can you please include the patch in trixie's QT 6 build?

Original KDE bug report: https://bugs.kde.org/show_bug.cgi?id=484323
QT patch: https://codereview.qt-project.org/c/qt/qtbase/+/663811

Thank you


-- System Information:
Debian Release: 13.1
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.12.48+deb13-amd64 (SMP w/16 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

From e2b88612e5c8dfc3f4bf416dff7b1af3e1e4f0f6 Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Sun, 27 Jul 2025 15:58:31 +0300
Subject: [PATCH] XCB: Remove extra xcb_randr_select_input() calls

This fixes high CPU usage in kwin.

If there is a ConfigureNotify event for the root window, QtXCB will
call xcb_randr_select_input(). The problem is that the X server may send
an output change event in response to xcb_randr_select_input().

When kwin sees that output change event, it will process the event and
it can update its override redirect windows, which can produce a few
ConfigureNotify events for the root window and make kwin get stuck in an
update loop.

Since the QXcbConnection constructor already subscribes to the RandR
events, these xcb_randr_select_input() function calls can be removed.
Also, `true` is not a valid argument for xcb_randr_select_input(). It
expects a mask of events to listen. For what it's worth, `true`
corresponds to XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE = 1, which
xrandrSelectEvents() already subscribes to.

Pick-to: 6.10 6.9 6.8
Change-Id: I950a0a6e2e34822ac3da8cd69b96670e4bf4b07d
Reviewed-by: Liang Qi <liang.qi@qt.io>
---

diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 2f00615..c1b8f84 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -499,7 +499,6 @@
     , m_cursor(std::make_unique<QXcbCursor>(connection, this))
 {
     if (connection->isAtLeastXRandR12()) {
-        xcb_randr_select_input(xcb_connection(), screen()->root, true);
         auto crtc = Q_XCB_REPLY_UNCHECKED(xcb_randr_get_crtc_info, xcb_connection(),
                                           m_crtc, output ? output->timestamp : 0);
         if (crtc) {
@@ -605,8 +604,6 @@
         return;
     }
 
-    xcb_randr_select_input(xcb_connection(), screen()->root, true);
-
     m_monitor = monitorInfo;
     qCDebug(lcQpaScreen) << "xcb_randr_monitor_info_t: primary=" << m_monitor->primary << ", x=" << m_monitor->x << ", y=" << m_monitor->y
         << ", width=" << m_monitor->width << ", height=" << m_monitor->height

Reply to: