Skip to content

refactor: restructure search item event handling and loader#315

Merged
deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
Kakueeen:master
Jun 4, 2026
Merged

refactor: restructure search item event handling and loader#315
deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
Kakueeen:master

Conversation

@Kakueeen
Copy link
Copy Markdown
Contributor

@Kakueeen Kakueeen commented Jun 3, 2026

  1. Move Timer, HoverHandler, and MouseArea from inside Image to direct
    children of AppletItem for better component hierarchy
  2. Merge TapHandler (left click) and MouseArea (right click) into a
    single MouseArea handling both buttons via onPressed and onClicked
  3. Change platformMenuLoader active from false to true to load context
    menu eagerly (previously lazy loaded)
  4. Remove TapHandler and right-click MouseArea, simplifying event
    handling logic

Log: Changed context menu loading strategy from lazy to eager; combined
left and right click handlers

Influence:

  1. Test left click on search icon triggers Grand Search toggle
  2. Test right click on search icon opens context menu
  3. Verify tooltip appears on hover and disappears on unhover
  4. Verify context menu items (if any) function correctly
  5. Test quick successive clicks (left/right) do not cause unexpected
    behavior
  6. Verify search icon still displays correctly and scales as expected

refactor: 重构搜索项事件处理和加载器

  1. 将Timer、HoverHandler和MouseArea从Image内部移至AppletItem的直接子级,
    优化组件层次结构
  2. 将左键点击的TapHandler和右键点击的MouseArea合并为单个MouseArea,通过
    onPressed和onClicked处理两种按钮
  3. 将platformMenuLoader的active从false改为true,使上下文菜单从惰性加载变
    为主动加载
  4. 移除TapHandler和独立的右键MouseArea,简化事件处理逻辑

Log: 将菜单加载策略从惰性改为主动;合并左右键点击处理器

Influence:

  1. 测试左键点击搜索图标触发全局搜索切换
  2. 测试右键点击搜索图标弹出上下文菜单
  3. 验证悬停时显示提示,移出后提示消失
  4. 验证上下文菜单项(如果有)功能正常
  5. 测试快速连续点击(左/右键)不导致意外行为
  6. 验证搜索图标正常显示且缩放符合预期

BUG: https://pms.uniontech.com/bug-view-328025.html

Summary by Sourcery

Simplify search item event handling and adjust context menu loading behavior.

Enhancements:

  • Unify left- and right-click handling for the search item into a single MouseArea while preserving existing behaviors.
  • Move tooltip timer and hover handling out of the image into AppletItem-level components for a cleaner hierarchy.
  • Change the context menu loader to be eagerly active so the platform menu is available immediately on right-click.

1. Move Timer, HoverHandler, and MouseArea from inside Image to direct
children of AppletItem for better component hierarchy
2. Merge TapHandler (left click) and MouseArea (right click) into a
single MouseArea handling both buttons via onPressed and onClicked
3. Change platformMenuLoader active from false to true to load context
menu eagerly (previously lazy loaded)
4. Remove TapHandler and right-click MouseArea, simplifying event
handling logic

Log: Changed context menu loading strategy from lazy to eager; combined
left and right click handlers

Influence:
1. Test left click on search icon triggers Grand Search toggle
2. Test right click on search icon opens context menu
3. Verify tooltip appears on hover and disappears on unhover
4. Verify context menu items (if any) function correctly
5. Test quick successive clicks (left/right) do not cause unexpected
behavior
6. Verify search icon still displays correctly and scales as expected

refactor: 重构搜索项事件处理和加载器

1. 将Timer、HoverHandler和MouseArea从Image内部移至AppletItem的直接子级,
优化组件层次结构
2. 将左键点击的TapHandler和右键点击的MouseArea合并为单个MouseArea,通过
onPressed和onClicked处理两种按钮
3. 将platformMenuLoader的active从false改为true,使上下文菜单从惰性加载变
为主动加载
4. 移除TapHandler和独立的右键MouseArea,简化事件处理逻辑

Log: 将菜单加载策略从惰性改为主动;合并左右键点击处理器

Influence:
1. 测试左键点击搜索图标触发全局搜索切换
2. 测试右键点击搜索图标弹出上下文菜单
3. 验证悬停时显示提示,移出后提示消失
4. 验证上下文菜单项(如果有)功能正常
5. 测试快速连续点击(左/右键)不导致意外行为
6. 验证搜索图标正常显示且缩放符合预期

BUG: https://pms.uniontech.com/bug-view-328025.html
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Jun 3, 2026

Reviewer's Guide

Refactors the search item QML to move interaction handlers out of the Image into the AppletItem, merge left/right click handling into a single MouseArea, and eagerly load the context menu via an always-active Loader, while preserving tooltip and search toggle behavior.

Sequence diagram for unified search item mouse interactions

sequenceDiagram
    actor User
    participant MouseArea
    participant Applet
    participant platformMenuLoader
    participant toolTipShowTimer
    participant toolTip

    rect rgb(230,230,255)
    User->>MouseArea: hover enter
    MouseArea->>toolTipShowTimer: start()
    toolTipShowTimer->>toolTip: open()
    end

    rect rgb(230,255,230)
    User->>MouseArea: hover leave
    MouseArea->>toolTipShowTimer: stop()
    MouseArea->>toolTip: close()
    end

    rect rgb(255,230,230)
    alt left click
        User->>MouseArea: onClicked(Qt.LeftButton)
        MouseArea->>Applet: toggleGrandSearch()
        MouseArea->>toolTip: close()
    else right click
        User->>MouseArea: onPressed(Qt.RightButton)
        MouseArea->>platformMenuLoader: item.open()
    end
    end
Loading

File-Level Changes

Change Details Files
Restructured tooltip timer and hover handling to live at the AppletItem level instead of inside the Image.
  • Moved the tooltip Timer object definition out of the Image into a sibling of the Image under AppletItem
  • Kept the 50ms interval and tooltip positioning logic unchanged when opening the tooltip
  • Retained the hover state logic to start/stop the timer and close the tooltip on unhover, but now using a HoverHandler attached to AppletItem instead of the Image
src/grand-search-shell-plugin/package/searchitem.qml
Simplified click handling by replacing separate TapHandler and right-click MouseArea with a single MouseArea managing both left and right mouse buttons.
  • Removed the TapHandler that previously handled left-button taps to toggle Grand Search and close the tooltip
  • Removed the MouseArea that was restricted to right-button clicks for opening the context menu
  • Introduced a new MouseArea anchored to fill the AppletItem, accepting both left and right buttons via acceptedButtons
  • Implemented onPressed to intercept right-button presses, mark the event as accepted, and open the context menu from the platformMenuLoader
  • Implemented onClicked to handle left-button clicks, toggling Grand Search and closing the tooltip
src/grand-search-shell-plugin/package/searchitem.qml
Changed platformMenuLoader to eagerly load the platform menu component and adjusted how it is used when opening the context menu.
  • Set platformMenuLoader.active from false to true so the LP.Menu component is instantiated eagerly instead of lazily at first use
  • Updated context menu opening logic to assume platformMenuLoader.item is always available when the right button is pressed
  • Removed the previous activation step that set active to true immediately before opening the menu
src/grand-search-shell-plugin/package/searchitem.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

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • By moving MouseArea and HoverHandler from the Image to the AppletItem and using anchors.fill: parent, left/right clicks and hover now apply to the entire applet instead of just the icon; if this wider hit area is not intentional, consider anchoring to the Image or a dedicated wrapper.
  • When calling platformMenuLoader.item.open() in onPressed, consider guarding with a platformMenuLoader.status === Loader.Ready (or a null check on item) to avoid potential issues if the loader isn’t fully initialized at the moment of the first right-click.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- By moving MouseArea and HoverHandler from the Image to the AppletItem and using `anchors.fill: parent`, left/right clicks and hover now apply to the entire applet instead of just the icon; if this wider hit area is not intentional, consider anchoring to the Image or a dedicated wrapper.
- When calling `platformMenuLoader.item.open()` in `onPressed`, consider guarding with a `platformMenuLoader.status === Loader.Ready` (or a null check on `item`) to avoid potential issues if the loader isn’t fully initialized at the moment of the first right-click.

## Individual Comments

### Comment 1
<location path="src/grand-search-shell-plugin/package/searchitem.qml" line_range="79-70" />
<code_context>
+        acceptedButtons: Qt.LeftButton | Qt.RightButton
+        onPressed: function(mouse) {
+            if (mouse.button === Qt.RightButton) {
+                mouse.accepted = true
+                platformMenuLoader.item.open()
+            }
+        }
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against `platformMenuLoader.item` being null before calling `open()`.

`active: true` doesn’t fully guarantee `platformMenuLoader.item` is available or that the load succeeded. Please guard the call with a null/status check (e.g. `if (platformMenuLoader.item)` or `platformMenuLoader.status === Loader.Ready`) before calling `open()` to avoid potential runtime errors.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

toolTipShowTimer.stop()
}

toolTip.close()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Guard against platformMenuLoader.item being null before calling open().

active: true doesn’t fully guarantee platformMenuLoader.item is available or that the load succeeded. Please guard the call with a null/status check (e.g. if (platformMenuLoader.item) or platformMenuLoader.status === Loader.Ready) before calling open() to avoid potential runtime errors.

Johnson-zs
Johnson-zs previously approved these changes Jun 4, 2026
Fix the toggleGrandSearch function to switch visibility based on current
state instead of always setting it to true. Add D-Bus signal connection
for VisibleChanged to keep internal state synchronized with external
events.

Log: Changed Grand Search toggle behavior from always open to switchable

Influence:
1. Test clicking the Grand Search toggle button repeatedly and verify
visibility toggles correctly
2. Verify the D-Bus VisibleChanged signal is received and updates
internal state
3. Test with other components that control Grand Search visibility to
ensure consistency
4. Check that no regression occurs for the config toggle function

fix: toggleGrandSearch 现在切换可见性

修复 toggleGrandSearch 函数,使其基于当前状态切换可见性,而不是始终设置
为 true。添加对 D-Bus VisibleChanged 信号的连接,确保内部状态与外部事件
同步。

Log: 修改 Grand Search 切换行为,从始终打开变为可切换

Influence:
1. 反复点击 Grand Search 切换按钮,验证可见性正确切换
2. 验证 D-Bus VisibleChanged 信号被接收并更新内部状态
3. 与其他控制 Grand Search 可见性的组件协同测试,确保一致性
4. 检查配置切换功能没有出现回归问题

BUG: https://pms.uniontech.com/bug-view-303917.html
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX,你的智能编程助手。我已经仔细审查了你提供的 Git Diff。

这次代码变更主要对 DDE Dock 上的全局搜索插件进行了重构和功能增强,包括:版权年份更新、QML 事件处理逻辑的合并与重构、右键菜单加载策略的更改、C++ 端 D-Bus 信号监听的引入,以及搜索显隐逻辑的修复。

以下是针对语法逻辑、代码质量、代码性能和代码安全四个方面的详细审查意见及改进建议:

一、 语法与逻辑

  1. QML 鼠标事件逻辑冲突(严重)

    • 问题:在新的 MouseArea 中,同时重写了 onPressedonClicked。在 Qt Quick 中,onClicked 只有在 onPressed 随后发生 onReleased 且事件未被吞没时才会触发。当前代码在 onPressed 中对右键做了 mouse.accepted = true,这是正确的;但对左键没有处理。更严重的是,onClicked 中的逻辑依赖按钮判断,这种将逻辑拆分到两个回调中的写法容易引起逻辑混乱和潜在的响应时序问题。
    • 建议:统一在一个回调中处理即可。由于 TapHandler 被移除,直接在 onClicked 中处理左右键逻辑更清晰:
      MouseArea {
          anchors.fill: parent
          acceptedButtons: Qt.LeftButton | Qt.RightButton
          onClicked: function(mouse) {
              if (mouse.button === Qt.RightButton) {
                  platformMenuLoader.item.open()
              } else if (mouse.button === Qt.LeftButton) {
                  Applet.toggleGrandSearch()
                  toolTip.close()
              }
          }
      }
  2. C++ D-Bus 信号匹配与槽函数签名(潜在隐患)

    • 问题:在 SearchItem 构造函数中,直接连接了 D-Bus 信号 "VisibleChanged" 到槽 onGrandSearchVisibleChanged(bool)必须确保 D-Bus 服务端发出的 VisibleChanged 信号签名确实是 bool 类型,且参数个数为 1。如果服务端信号签名不匹配(例如是 int 或无参数),该连接将静默失败,导致状态不同步。
    • 建议:如果不确定服务端信号签名,建议使用 QDBusConnection::connect 的完整重载形式指定参数签名,或者在 onGrandSearchVisibleChanged 中增加 qCDebug 打印以确保被触发。
  3. toggleGrandSearch 逻辑竞态条件(中风险)

    • 问题searchDbus().method("SetVisible").arg(!m_grandSearchVisible).call(); 依赖本地缓存的状态 m_grandSearchVisible 取反来决定是否显示。如果由于某种原因(如 D-Bus 信号丢失、外部程序修改了搜索显隐状态),本地状态与服务端状态不一致,点击该按钮将执行与预期相反的操作。
    • 建议
      • 方案A:如果是 Toggle 语义,且 D-Bus 服务端支持,建议直接调用服务端的 Toggle 方法,由服务端维护状态机。
      • 方案B:如果必须传值,建议在 onGrandSearchVisibleChanged 槽函数中做好容错处理,并在初始化时主动获取一次服务端真实状态。

二、 代码质量

  1. QML 组件层级与事件冒泡

    • 问题:原本 TapHandlerHoverHandler 作为 Image 的子组件,而 MouseAreaImage 平级。重构后,HoverHandler 依然是 Image 的子组件,但 MouseArea 跑到了外层 AppletItem 中,且使用了 anchors.fill: parent
    • 影响MouseArea 会覆盖在 HoverHandler 之上。在 Qt Quick 中,MouseArea 默认会拦截鼠标事件,这可能会导致 HoverHandler 无法接收到 Hover 事件,使得 Tooltip 失效。
    • 建议:将 HoverHandlerMouseArea 放在同一个父级层级中,或者确保 MouseArea 不阻止 Hover 事件的传递。如果 MouseAreaHoverHandler 同级,建议测试 Hover 是否仍然生效;若失效,需在 MouseArea 设置 hoverEnabled: true 并考虑移除独立的 HoverHandler,直接利用 MouseAreacontainsMouse 属性来控制 Timer。
  2. 代码格式化一致性

    • 问题:C++ 文件中,构造函数初始化列表从换行形式改为了单行形式 DApplet(parent), m_visible(true), m_grandSearchVisible(false),同时命名空间的括号风格也改变了。虽然这是个人偏好,但在同一个项目中应保持与现有代码库风格一致。
    • 建议:遵循项目原有的 .clang-format 配置或团队代码规范。

三、 代码性能

  1. Loader 的 active: true 导致资源常驻
    • 问题:将右键菜单的 Loaderactive: false 改为 active: true,意味着该 Menu 组件在插件加载时就被实例化并常驻内存,而右键菜单其实是一个低频操作。
    • 建议:恢复为 active: false。在需要打开菜单时,再动态激活并打开。为了防止异步加载导致的延迟,可以在右键点击时先设置 active = true,然后在 onLoaded 回调中调用 open()
      Loader {
          id: platformMenuLoader
          active: false
          // ... sourceComponent ...
          onLoaded: {
              if (pendingOpen) {
                  item.open()
                  pendingOpen = false
              }
          }
      }
      
      // 触发打开的逻辑中:
      property bool pendingOpen: false
      
      function showMenu() {
          if (!platformMenuLoader.active) {
              platformMenuLoader.active = true
              pendingOpen = true
          } else {
              platformMenuLoader.item.open()
          }
      }
      这样既保证了首帧性能,又避免了不必要的内存占用。

四、 代码安全

  1. D-Bus 权限与调用失败处理
    • 问题searchDbus().method("SetVisible").arg(!m_grandSearchVisible).call(); 使用了同步调用(call()),如果 D-Bus 服务端无响应或崩溃,会导致当前线程阻塞,可能导致 Dock 卡顿。此外,未对调用返回值进行检查。
    • 建议
      • 使用异步调用 callAsync()callWithCallback() 代替 call(),避免阻塞主线程(UI线程)。
      • 虽然是前端插件,但也应考虑 D-Bus 调用失败的情况,至少在 Debug 模式下输出错误日志:
        QDBusPendingCall async = searchDbus().method("SetVisible").arg(!m_grandSearchVisible).callAsync();
        QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
        QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [](QDBusPendingCallWatcher *watcher) {
            QDBusPendingReply<void> reply = *watcher;
            if (reply.isError()) {
                qCWarning(logShell) << "Failed to toggle Grand Search:" << reply.error().message();
            }
            watcher->deleteLater();
        });

总结

最核心需要修改的是:

  1. 验证 MouseArea 是否遮挡了 HoverHandler,避免 Tooltip 功能失效。
  2. 恢复 Loader 的懒加载 active: false,优化内存占用。
  3. 合并 onPressedonClicked 逻辑,简化事件处理。
  4. 考虑将 D-Bus 的同步调用 call() 改为异步调用,防止 UI 阻塞。

希望这些审查意见对你有所帮助!如果有任何疑问,欢迎随时提问。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Johnson-zs, Kakueeen

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

@Kakueeen
Copy link
Copy Markdown
Contributor Author

Kakueeen commented Jun 4, 2026

/forcemerge

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Jun 4, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit fa2bdb8 into linuxdeepin:master Jun 4, 2026
9 of 11 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