Skip to content

fix: close popups before showing launchpad - #790

Open
18202781743 wants to merge 1 commit into
linuxdeepin:masterfrom
18202781743:master
Open

fix: close popups before showing launchpad#790
18202781743 wants to merge 1 commit into
linuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743

@18202781743 18202781743 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Bug Fixes:

  • Prevent the launcher from becoming visible while other Qt popups are still active by deferring its display until popups are closed.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @18202781743, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@sourcery-ai

sourcery-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements deferred launcher visibility changes to ensure all Qt popups are closed and their Wayland grabs released before showing the launchpad, using a pending-show flag and a zero-timeout timer callback.

Sequence diagram for deferred launcher visibility when popups are open

sequenceDiagram
    participant Caller
    participant LauncherController
    participant QGuiApplicationPrivate
    participant QTimer

    Caller->>LauncherController: setVisible(true)
    LauncherController->>QGuiApplicationPrivate: popupCount()
    QGuiApplicationPrivate-->>LauncherController: popupCount > 0
    LauncherController->>LauncherController: m_showPending = true
    LauncherController->>LauncherController: closeAllPopups()
    LauncherController->>QTimer: singleShot(0, this, lambda)

    QTimer-->>LauncherController: lambda callback
    alt m_showPending is true
        LauncherController->>LauncherController: m_showPending = false
        LauncherController->>LauncherController: setVisible(true)
    else m_showPending is false
        LauncherController->>LauncherController: [return]
    end
Loading

File-Level Changes

Change Details Files
Guard launcher visibility changes with a pending-show flag and defer showing until after popups are closed.
  • Return early when hiding while a pending show is scheduled, cancelling the pending show instead
  • Avoid redundant visibility changes by returning when the requested visibility matches the current state or when a show is already pending
  • When a show is requested while any Qt popups are open, mark the show as pending, close all popups, and schedule a deferred visibility change using QTimer::singleShot
  • In the deferred callback, re-check the pending flag, clear it, and call setVisible(true) to actually show the launcher
launchercontroller.cpp
Extend launcher controller state to track pending show requests and update copyright metadata.
  • Add a new m_showPending boolean member, initialized to false, to track deferred show operations
  • Update the SPDX-FileCopyrightText year range to 2023 - 2026
launchercontroller.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@18202781743

Copy link
Copy Markdown
Contributor Author

在x11和wayland下,任务栏上的右键菜单弹出后,再用快捷键启动小启动器,菜单不消失,
在treeland下,小启动器位置还会错误,

1. Add m_showPending flag to track deferred launcher show requests
2. When a show request arrives while popups are open, close all popups
first and defer the launcher display
3. Use a QTimer::singleShot(0) to let Qt properly finish hiding popups
and release the Wayland popup grab before mapping the launcher window
4. On hide requests, clear the pending show flag to avoid conflicts with
the deferred show operation
5. Prevent redundant show calls while a show is already pending
6. Update SPDX copyright year to 2026 in the header file

Log: Fixed the issue where the taskbar right-click context menu would
not disappear when launching the launcher via keyboard shortcut on X11
and Wayland

Influence:
1. On X11: open taskbar context menu via right-click, then press the
launcher shortcut key, verify the menu closes and the launcher opens
2. On Wayland: repeat the same test and verify smooth transition from
menu to launcher
3. Test repeatedly triggering the shortcut key while popups are open,
verify no stale launcher state occurs
4. Test hiding the launcher immediately after showing it (rapid show/
hide), verify no pending-show state inconsistency
5. Test launching the launcher when no popup is open, verify normal
behavior remains unchanged
6. Test in both single and multi-screen display configurations

fix: 修复隐藏任务栏菜单时启动器弹窗阻塞问题

1. 添加 m_showPending 标志用于跟踪延迟的启动器显示请求
2. 当弹出菜单打开时收到显示请求,先关闭所有弹出菜单并延迟启动器显示
3. 使用 QTimer::singleShot(0) 让 Qt 先完成弹出窗口的隐藏和释放 Wayland
弹出抓取,然后才映射启动器窗口
4. 收到隐藏请求时清除待显示标志,避免与延迟显示操作冲突
5. 防止已有待显示操作时重复触发显示调用
6. 将头文件中的 SPDX 版权年份更新为 2026

Log: 修复在 X11 和 Wayland 下通过快捷键启动小启动器时任务栏右键菜单不消
失的问题

Influence:
1. 在 X11 下:右键打开任务栏上下文菜单,然后按下启动器快捷键,验证菜单关
闭且启动器正常打开
2. 在 Wayland 下:重复相同测试,验证菜单到启动器的切换过程流畅无异常
3. 在弹出菜单打开时反复触发快捷键,验证不产生启动器状态残留
4. 显示启动器后立即隐藏(快速显示/隐藏),验证无待显示状态不一致
5. 在没有弹出菜单打开时启动启动器,验证正常行为不受影响
6. 测试单屏和多屏显示配置下的表现
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:85分

■ 【总体评价】

代码实现了Wayland下弹出窗口抓取释放的延迟显示逻辑,但使用了Qt私有API
逻辑正确但因依赖私有接口导致兼容性风险扣15分

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

在LauncherController::setVisible函数中,通过m_showPending标志位和QTimer::singleShot(0)实现了状态机的正确流转,有效处理了在延迟显示期间取消显示的边界情况
潜在问题:若在QTimer::singleShot(0)触发瞬间有新的弹出窗口产生,popupCount可能仍大于0,但概率极低
建议:在QTimer::singleShot(0)的回调中增加二次检查弹出窗口数量的逻辑,若仍大于0则继续延迟

  • 2.代码质量(一般)✕

代码引入了m_showPending状态变量且注释清晰,但直接调用了QGuiApplicationPrivate::popupCount(),该接口属于Qt的私有API,未在官方公共头文件中导出
潜在问题:依赖私有API会导致在Qt版本升级(如从Qt5升级到Qt6)时面临编译失败或运行时符号找不到的风险
建议:尽量避免直接使用私有API,可通过遍历QGuiApplication::topLevelWidgets()检测带Qt::Popup标志的窗口数量,或向Qt官方提需求暴露公共接口

  • 3.代码性能(无性能问题)✓

使用QTimer::singleShot(0)将显示操作推迟到当前事件循环结束后,仅增加极小的事件队列开销,closeAllPopups()为必要的清理操作,整体无性能损耗
建议:保持现状即可

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码仅涉及UI状态控制和事件循环调度,未涉及内存越界、命令注入、权限提升等安全风险面

  • 建议:保持现有的安全编码水平,注意后续迭代中的内存管理

■ 【改进建议代码示例】

void LauncherController::setVisible(bool visible)
{
    if (!visible && m_showPending) {
        m_showPending = false;
        return;
    }

    if (visible == m_visible || (visible && m_showPending)) return;

    // 替换私有API调用,通过遍历顶层窗口检测Popup
    auto getPopupCount = []() {
        int count = 0;
        const auto topWidgets = QGuiApplication::topLevelWidgets();
        for (QWidget *w : topWidgets) {
            if (w->windowType() == Qt::Popup && w->isVisible()) {
                ++count;
            }
        }
        return count;
    };

    if (visible && getPopupCount() > 0) {
        m_showPending = true;
        closeAllPopups();

        // Let Qt finish hiding the current popup and release the Wayland
        // popup grab before the launcher window is mapped.
        QTimer::singleShot(0, this, [this, getPopupCount] {
            if (!m_showPending) {
                return;
            }

            // 增加二次检查,防止极端情况下新的Popup产生
            if (getPopupCount() > 0) {
                QTimer::singleShot(0, this, [this] {
                    if (!m_showPending) return;
                    m_showPending = false;
                    setVisible(true);
                });
                return;
            }

            m_showPending = false;
            setVisible(true);
        });
        return;
    }

    m_visible = visible;
    // ... (后续原有逻辑)
}

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, yixinshark

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants