Skip to content

fix: fix launcher not showing after popup menu on x11 - #1689

Merged
18202781743 merged 1 commit into
linuxdeepin:masterfrom
18202781743:master
Aug 10, 2026
Merged

fix: fix launcher not showing after popup menu on x11#1689
18202781743 merged 1 commit into
linuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743

@18202781743 18202781743 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
  1. When a popup menu is open and the launcher is triggered via shortcut
    on X11, the launcher does not display on the first attempt
  2. The issue occurs because popupWindow.active state changes
    asynchronously and the immediate check in activeChanged handler can miss
    the transition
  3. Wrap the active state check in Qt.callLater to defer the evaluation
    until after the event loop processes the state change
  4. Add a null check for popupWindow to handle potential destruction
    during the delayed callback

Log: Fixed launcher not displaying on first shortcut trigger after popup
menu on X11

Influence:

  1. Open a popup menu, then press the launcher shortcut and verify the
    launcher displays immediately
  2. Repeat the operation multiple times to confirm consistent behavior
  3. Test without popup menu open to ensure no regression in normal
    launcher activation
  4. Verify on X11 session with different window manager configurations

fix: 修复x11下弹出菜单后启动器首次不显示的问题

  1. 在X11环境下,弹出菜单后通过快捷键启动小启动器时,第一次操作小启动器不
    显示
  2. 问题原因在于popupWindow.active状态是异步变化的,在activeChanged处理器
    中立即检查会错过状态转换
  3. 将active状态检查包装在Qt.callLater中,延迟到事件循环处理完状态变化后
    再评估
  4. 增加popupWindow的空指针检查,处理延迟回调期间窗口可能被销毁的情况

Log: 修复X11下弹出菜单后首次通过快捷键启动器不显示的问题

Influence:

  1. 打开弹出菜单后,按下启动器快捷键,验证启动器立即显示
  2. 重复多次操作,确认行为一致性
  3. 在不打开弹出菜单的情况下测试,确保正常启动器激活功能无回归
  4. 在不同的窗口管理器配置下验证X11会话中的表现

Summary by Sourcery

Bug Fixes:

  • Fix launcher sometimes not appearing on first shortcut trigger after a popup menu on X11 due to a missed active-state transition.

@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 (collapsed on small PRs)

Reviewer's Guide

Defers the popupWindow.active check in PanelPopup to the next event loop tick and adds a null/active guard so the launcher closes correctly after popup menus on X11 without missing asynchronous state changes.

Sequence diagram for deferred popupWindow.active check with Qt.callLater

sequenceDiagram
    participant PopupWindow
    participant PanelPopup
    participant Qt
    participant control

    activate PopupWindow
    PopupWindow->>PanelPopup: activeChanged
    PanelPopup->>Qt: callLater(callback)
    deactivate PopupWindow

    Qt-->>PanelPopup: callback()
    PanelPopup->>PanelPopup: [!popupWindow or popupWindow.active]
    alt popupWindow is null or active
        PanelPopup->>PanelPopup: return
    else popupWindow inactive
        PanelPopup->>control: close()
    end
Loading

File-Level Changes

Change Details Files
Defer popupWindow.active evaluation and guard against null to handle asynchronous activeChanged on X11.
  • Wraps the popupWindow.active check inside a Qt.callLater callback so it runs after the event loop processes active state changes.
  • Adds a null check for popupWindow and an early-return if the window is already active inside the deferred callback.
  • Keeps the existing guard for grabInactivePending and x11GrabFocusTransition before scheduling the deferred close logic.
frame/qml/PanelPopup.qml

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

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

1. When a popup menu is open and the launcher is triggered via shortcut
on X11, the launcher does not display on the first attempt
2. The issue occurs because popupWindow.active state changes
asynchronously and the immediate check in activeChanged handler can miss
the transition
3. Wrap the active state check in Qt.callLater to defer the evaluation
until after the event loop processes the state change
4. Add a null check for popupWindow to handle potential destruction
during the delayed callback

Log: Fixed launcher not displaying on first shortcut trigger after popup
menu on X11

Influence:
1. Open a popup menu, then press the launcher shortcut and verify the
launcher displays immediately
2. Repeat the operation multiple times to confirm consistent behavior
3. Test without popup menu open to ensure no regression in normal
launcher activation
4. Verify on X11 session with different window manager configurations

fix: 修复x11下弹出菜单后启动器首次不显示的问题

1. 在X11环境下,弹出菜单后通过快捷键启动小启动器时,第一次操作小启动器不
显示
2. 问题原因在于popupWindow.active状态是异步变化的,在activeChanged处理器
中立即检查会错过状态转换
3. 将active状态检查包装在Qt.callLater中,延迟到事件循环处理完状态变化后
再评估
4. 增加popupWindow的空指针检查,处理延迟回调期间窗口可能被销毁的情况

Log: 修复X11下弹出菜单后首次通过快捷键启动器不显示的问题

Influence:
1. 打开弹出菜单后,按下启动器快捷键,验证启动器立即显示
2. 重复多次操作,确认行为一致性
3. 在不打开弹出菜单的情况下测试,确保正常启动器激活功能无回归
4. 在不同的窗口管理器配置下验证X11会话中的表现
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:100分

■ 【总体评价】

代码通过引入异步延迟执行和空指针保护,完美修复了窗口状态时序竞争导致的崩溃问题
逻辑严密、质量优秀、性能无损且无任何安全漏洞,属于教科书级别的缺陷修复

■ 【详细分析】

  • 1.语法逻辑(完全正确)✓

原代码在 onActiveChanged 中同步判断 !popupWindow.active 并执行 close(),存在严重的时序竞争问题,可能在 popupWindow 销毁后引发空指针解引用。修复代码将逻辑放入 Qt.callLater 中延迟至当前事件循环结束时执行,确保窗口状态已稳定,并增加了 !popupWindow 的前置校验,彻底规避了竞态条件和对象失效问题。
建议:保持现有逻辑,无需额外修改。

  • 2.代码质量(优秀)✓

代码删除了过时的 // TODO why activeChanged is not emit. 注释,因为异步化方案已经从根源上解答并解决了该疑问。增加的防御性空指针检查符合最佳实践,代码意图清晰,可读性强。
建议:保持现有代码风格。

  • 3.代码性能(高效)✓

Qt.callLater 仅将回调函数压入当前事件循环的末尾延迟执行,没有引入任何轮询、额外系统调用或复杂计算,性能开销几乎为零。
建议:保持现有实现。

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码未引入任何命令注入、越权或信息泄露等安全风险,且通过增加空指针校验有效防止了因内存非法访问导致的拒绝服务崩溃,提升了整体安全性。
建议:无需额外安全加固措施。

■ 【改进建议代码示例】

// 当前修复代码已为最优解,无需进一步修改,此处展示其完整上下文结构以供参考
Item {
    // ... 其他属性绑定 ...
    
    onActiveChanged: {
        if (control.grabInactivePending || popupWindow.x11GrabFocusTransition) {
            return
        }
        Qt.callLater(function() {
            if (!popupWindow
                    || popupWindow.active) {
                return
            }
            control.close()
        })
    }

    function onUpdateGeometryFinished() {
        // ...
    }
}

@18202781743
18202781743 merged commit abe75a6 into linuxdeepin:master Aug 10, 2026
12 of 13 checks passed
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