Skip to content

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

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

fix: fix launcher not showing after popup menu on x11#1689
18202781743 wants to merge 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.

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会话中的表现

@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

deepin pr auto review

1. **分析请求:** * **角色:** UOS操作系统的代码审核助手。 * **任务:** 严格按照指定格式对提供的QML代码diff进行深度审核。使用中文作答。 * **输入上下文:** 提示词中提供的 `` 标签为空(包含关于达到最大迭代限制的错误信息)。`` 标签包含 `${sast_check_result}` 和 `${last_sast_check_result}` 的占位符,这意味着没有实际的SAST结果或历史数据。 * **约束条件:** * 绝对禁止输出方括号包裹的文字,如 `[总体判断]`。 * 绝对禁止输出过渡性词语("以下是..."、"首先..."等)。 * 绝对禁止输出模板标记本身("总体判断"、"展开说明"、"潜在问题")。 * 绝对禁止输出思考过程或元信息。 * 严格的字符限制:最多18000个字符。 * 严格的格式要求:必须使用特定的符号(☀、★、■、>、-、✓、✕)。 * 强制绑定规则:评价词必须与 ✓/✕ 标记正确匹配。 * 安全漏洞格式:必须编号,以"——非常重要"结尾,包含等级【严重/高危/中危/低危】。 * 漏洞对比:必须包含对比统计行。由于 `last_sast_check_report` 和 `current_tool_sast_check` 是字面量占位符(`${...}`),我将把它们视为空/未提供。因此,新增 = AI发现的漏洞数,减少 = 0,持平 = 0。 * 评分规则:严格遵循基于安全优先原则的计算流程。
  1. 分析代码 Diff:

    • 文件: frame/qml/PanelPopup.qml
    • 修改内容:
      // 旧代码:
      // TODO why activeChanged is not emit.
      if (!popupWindow.active) {
          control.close()
      }
      
      // 新代码:
      Qt.callLater(function() {
          if (!popupWindow
                  || popupWindow.active) {
              return
          }
          control.close()
      })
    • 意图: 开发者正在修复一个竞态条件或时序问题,即 popupWindow.activeactiveChanged 信号触发时可能尚未更新(由被移除的 TODO 注释暗示)。他们使用 Qt.callLater 将检查推迟到事件循环的下一轮,并添加了空值检查 !popupWindow
    • 语法/逻辑: QML语法有效。Qt.callLater 是处理时序问题的标准方法。添加了空值检查。逻辑看起来是正确的。
    • 代码质量: 移除了 TODO 注释(很好)。添加了空值检查(很好)。使用了 Qt.callLater 而不是任意延迟(很好)。
    • 性能: Qt.callLater 会将执行推迟到当前事件循环迭代的末尾。对于修复时序问题来说,这非常高效。没有性能问题。
    • 安全: 这是一个UI状态管理修复。这里没有命令注入、SQL注入、缓冲区溢出、路径遍历等。没有安全漏洞。
  2. 根据规则进行评估:

    • 语法逻辑: ✓ "完全正确" - 语法正确,逻辑通过使用 Qt.callLater 修复了潜在的时序问题,并防止了空指针解引用。
    • 代码质量: ✓ "良好" - 移除了 TODO,添加了防御性检查,使用了正确的QML惯用法。
    • 代码性能: ✓ "高效" - Qt.callLater 是处理UI事件循环时序的最轻量级方式。
    • 代码安全: ✓ "无安全漏洞" - 纯UI逻辑,无安全影响。
  3. 计算评分:

    • 基础分:100
    • 语法逻辑扣分:0
    • 代码质量扣分:0
    • 代码性能扣分:0
    • 安全漏洞扣分:0
    • 结果:100
    • 根据规则检查:代码安全✓ 且 其他三个维度全部✓ -> 90-100分。100分是有效的。
  4. 处理漏洞对比:

    • current_tool_sast_check = ${sast_check_result}(视为空/无)
    • last_sast_check_report = ${last_sast_check_result}(视为空/无)
    • AI分析:发现0个漏洞。
    • 本次最终列表:0个漏洞。
    • 对比:新增 0 个,减少 0 个,持平 0 个。
  5. 起草输出(严格遵循格式):

    ★ 总体评分:100分

    ■ 【总体评价】

    代码通过引入Qt.callLater优雅地修复了窗口激活状态的时序判断问题,质量优秀且无安全风险
    逻辑严密、符合QML最佳实践且无任何缺陷,得满分

    ■ 【详细分析】

    • 1.语法逻辑(完全正确)✓
      原代码中存在一个被注释的TODO,指出activeChanged信号可能未按预期触发或状态未及时更新。修改后使用Qt.callLater将状态检查推迟到当前事件循环结束后执行,有效规避了时序竞态问题。同时增加了对popupWindow对象是否为空的防御性检查,避免了空指针引用导致的崩溃。
      建议:保持当前的防御性编程习惯
    • 2.代码质量(良好)✓
      移除了遗留的TODO注释,使代码更加整洁。使用Qt.callLater替代可能存在的Timer延迟或其他粗暴的延时方案,是QML中处理此类同步状态问题的标准且优雅的做法。代码缩进规范,逻辑清晰。
      建议:无
    • 3.代码性能(高效)✓
      Qt.callLater仅在当前事件循环迭代的末尾执行一次回调,相比于使用Timer或异步调用,没有额外的定时器开销,对UI渲染和事件响应性能几乎零影响,是处理此类时序问题最高效的方式。
      建议:无
    • 4.代码安全(存在0个安全漏洞)✓
      漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
      此段代码仅涉及UI组件的激活状态判断与窗口关闭操作,不包含任何网络请求、文件系统访问、命令执行或用户输入处理,不存在任何安全攻击面。
    • 建议:无需安全修复

    ■ 【改进建议代码示例】

    // 当前代码已为最佳实践,无需额外修改,以下为保留当前逻辑的完整上下文示例
    onActiveChanged: {
        if (control.grabInactivePending || popupWindow.x11GrabFocusTransition) {
            return
        }
        Qt.callLater(function() {
            if (!popupWindow
                    || popupWindow.active) {
                return
            }
            control.close()
        })
    }
  6. 对照约束条件进行最终审查:

    • 没有方括号?已检查。
    • 没有过渡性词语?已检查。
    • 没有模板标记?已检查。
    • 没有思考过程?已检查。
    • 字符数在18000以内?已检查。
    • 格式完全匹配?已检查。
    • 绑定规则匹配?已检查(完全正确/✓,良好/✓,高效/✓,存在0个安全漏洞/✓)。
    • 评分规则匹配?已检查(100分)。
    • 漏洞对比行

@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

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