From 6e947d20ea07f5edd09859803599989370f894d9 Mon Sep 17 00:00:00 2001 From: zhangkun Date: Wed, 3 Dec 2025 11:39:38 +0800 Subject: [PATCH] fix: add cursor size listener and optimize cursor theme handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Added cursor theme size property listener alongside existing cursor theme name listener 2. Modified cursorThemePropertyChanged function to directly handle cursor updates instead of queued invocation 3. Added explicit cursor cache clearing and context reinitialization for all screens 4. Removed queued connection to ensure immediate cursor updates when theme properties change The changes address the need for real-time cursor updates when both cursor theme name and size change. Previously, only theme name changes were monitored, and cursor updates were queued which could cause delays. Now the function directly clears cursor caches, reinitializes cursor contexts, and updates all window cursors immediately. This ensures consistent cursor appearance across all windows when theme properties are modified. Log: Added cursor theme size change listener for real-time cursor updates Influence: 1. Test cursor theme changes by modifying both theme name and size settings 2. Verify cursor updates immediately across all application windows 3. Test with multiple screens to ensure proper cursor context reinitialization 4. Verify cursor cache is properly cleared when theme properties change 5. Test application behavior during theme property changes to ensure no crashes or memory leaks fix: 增加光标大小监听并优化光标主题处理 1. 在现有光标主题名称监听的基础上,新增光标主题大小属性监听 2. 修改cursorThemePropertyChanged函数,直接处理光标更新而非排队调用 3. 为所有屏幕添加显式的光标缓存清理和上下文重新初始化 4. 移除排队连接,确保主题属性变化时立即更新光标 这些更改解决了光标主题名称和大小变化时需要实时更新光标的问题。之前仅监听 了主题名称变化,且光标更新被排队处理可能导致延迟。现在函数直接清理光标缓 存、重新初始化光标上下文并立即更新所有窗口光标。这确保了主题属性修改时所 有窗口的光标外观保持一致。 Log: 新增光标主题大小变化监听,实现实时光标更新 Influence: 1. 测试修改主题名称和大小设置时的光标变化 2. 验证所有应用程序窗口的光标立即更新 3. 使用多屏幕测试,确保正确重新初始化光标上下文 4. 验证主题属性变化时正确清理光标缓存 5. 测试主题属性变化期间的应用程序行为,确保无崩溃或内存泄漏 pms: STORY-39797 --- xcb/dplatformintegration.cpp | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/xcb/dplatformintegration.cpp b/xcb/dplatformintegration.cpp index e4fef040..314181c7 100644 --- a/xcb/dplatformintegration.cpp +++ b/xcb/dplatformintegration.cpp @@ -1064,13 +1064,35 @@ static void cursorThemePropertyChanged(xcb_connection_t *connection, const QByte Q_UNUSED(property); Q_UNUSED(handle) - QMetaObject::invokeMethod(qApp, [](){ - for (const auto window : qApp->allWindows()) { - auto cursor = window->cursor(); - if (window->screen() && window->screen()->handle() && window->screen()->handle()->cursor()) - overrideChangeCursor(window->screen()->handle()->cursor(), &cursor, window); + // TODO: https://qt-project.atlassian.net/browse/QTBUG-142329 这个BUG解决之后可将这里的代码删除 + for (QScreen *screen : qApp->screens()) { + if (screen && screen->handle() && screen->handle()->cursor()) { + QXcbCursor *xcb_cursor = static_cast(screen->handle()->cursor()); + + if (xcb_cursor == nullptr) { + continue; + } + xcb_cursor->m_cursorHash.clear(); + + // source from: QXCBCursor::updateContext() + if (xcb_cursor->m_cursorContext) { + xcb_cursor_context_free(xcb_cursor->m_cursorContext); + } + xcb_cursor->m_cursorContext = nullptr; + xcb_connection_t *conn = xcb_cursor->xcb_connection(); + + if (xcb_cursor_context_new(conn, xcb_cursor->m_screen->screen(), &xcb_cursor->m_cursorContext) < 0) { + xcb_cursor->m_cursorContext = nullptr; + } + } + } + + for (const auto window : qApp->allWindows()) { + auto cursor = window->cursor(); + if (window->screen() && window->screen()->handle() && window->screen()->handle()->cursor()) { + overrideChangeCursor(window->screen()->handle()->cursor(), &cursor, window); } - }, Qt::QueuedConnection); + } } void DPlatformIntegration::initialize() @@ -1196,6 +1218,7 @@ void DPlatformIntegration::initialize() // Qt中同样监听了这个属性的变化,但是只刷新了光标上下文却没有更新当前窗口的光标,无法做到光标的实时变化,所以加了该逻辑额外处理 xSettings()->registerCallbackForProperty("Gtk/CursorThemeName", cursorThemePropertyChanged, nullptr); + xSettings()->registerCallbackForProperty("Gtk/CursorThemeSize", cursorThemePropertyChanged, nullptr); } #ifdef Q_OS_LINUX