Skip to content

Conversation

@BLumia
Copy link
Member

@BLumia BLumia commented Jan 26, 2026

修正自由排序的列表视图在启动时和从其他模式切换到自由排序模式时,视图
位置不在最顶端的问题.有下面的原因:

  1. ListView.contentY 实际是 Flickable.contentY, ListView 的 contentY 不一定是 0 为起点.
  2. 目前,小窗口启动器的视图位置重置只会在隐藏时进行, 会导致首次启动后 启动器的自由排序模式视图位置不对(因为没变为隐藏过,所以没被重置).

关联:

Summary by Sourcery

Ensure the free-sort app list view is reset to the top on initial launch and when entering free-sort mode so that the list starts at the beginning.

Bug Fixes:

  • Fix the free-sort ListView sometimes not starting at the top due to relying on contentY being zero.
  • Reset the windowed launcher app list view state on component completion to correctly initialize the scroll position.

修正自由排序的列表视图在启动时和从其他模式切换到自由排序模式时,视图
位置不在最顶端的问题.有下面的原因:

1. ListView.contentY 实际是 Flickable.contentY, ListView 的 contentY
   不一定是 0 为起点.
2. 目前,小窗口启动器的视图位置重置只会在隐藏时进行, 会导致首次启动后
   启动器的自由排序模式视图位置不对(因为没变为隐藏过,所以没被重置).

PMS: BUG-348311
Log:
@BLumia BLumia requested a review from robertkill January 26, 2026 07:32
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 26, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Ensures the free-sort app list view is reset to the top both on initial creation and when resetting its state by using ListView’s positioning API correctly and triggering a view state reset when the windowed launcher frame is completed.

Sequence diagram for windowed launcher startup and list view reset

sequenceDiagram
    participant WindowedFrame
    participant LauncherController
    participant appList as FreeSortListView

    rect rgb(230,230,255)
        WindowedFrame->>WindowedFrame: Component.onCompleted
        WindowedFrame->>appList: resetViewState()
        activate appList
        appList->>appList: set currentIndex = 0
        appList->>appList: set highlightFollowsCurrentItem = false
        appList->>appList: positionViewAtBeginning()
        appList->>appList: restore highlightFollowsCurrentItem
        deactivate appList
    end

    rect rgb(230,255,230)
        LauncherController->>LauncherController: onVisibleChanged(visible = false)
        LauncherController->>appList: resetViewState()
        activate appList
        appList->>appList: set currentIndex = 0
        appList->>appList: set highlightFollowsCurrentItem = false
        appList->>appList: positionViewAtBeginning()
        appList->>appList: restore highlightFollowsCurrentItem
        deactivate appList
    end
Loading

Class diagram for updated windowed launcher view reset behavior

classDiagram
    class WindowedFrame {
        +Component_onCompleted()
        +Connections_onVisibleChanged()
    }

    class LauncherController {
        +visible : bool
        +onVisibleChanged(visible)
    }

    class FreeSortListView {
        +listView_currentIndex : int
        +listView_highlightFollowsCurrentItem : bool
        +resetViewState()
        +listView_positionViewAtBeginning()
    }

    WindowedFrame --> LauncherController : observes visible
    WindowedFrame --> FreeSortListView : appList
    LauncherController --> FreeSortListView : calls resetViewState()

    FreeSortListView : resetViewState() sets listView_currentIndex = 0
    FreeSortListView : resetViewState() disables listView_highlightFollowsCurrentItem
    FreeSortListView : resetViewState() calls listView_positionViewAtBeginning()
    FreeSortListView : resetViewState() restores listView_highlightFollowsCurrentItem
Loading

File-Level Changes

Change Details Files
Ensure windowed launcher app list view state is reset on initial creation so the free-sort list starts at the top.
  • Invoke appList.resetViewState() when the WindowedFrame component finishes creation.
  • Rely on existing LauncherController visibility handling to continue resetting view state on hide while covering the initial-show gap.
qml/windowed/WindowedFrame.qml
Use ListView’s positioning API to scroll to the top instead of directly manipulating contentY.
  • Replace direct contentY assignment with positionViewAtBeginning() when resetting the free-sort ListView state.
  • Preserve and restore highlightFollowsCurrentItem around the reset to avoid side effects while changing currentIndex and position.
qml/windowed/FreeSortListView.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

deepin pr auto review

这段代码变更主要涉及 QML (Qt Modeling Language) 中列表视图的状态重置逻辑。以下是对这段 diff 的详细审查和改进意见:

1. 语法逻辑审查

变更点 1:FreeSortListView.qml

  • 原代码listView.contentY = 0
  • 新代码listView.positionViewAtBeginning()
  • 分析:这是一个很好的改进。
    • contentY = 0 强制将视口的垂直位置设置为绝对坐标 0。这存在潜在风险:如果列表视图有 header(表头)或 topMargin(顶部边距),直接设置为 0 可能会导致表头被遮挡或布局错位。
    • positionViewAtBeginning() 是 ListView 提供的 API,它会自动处理边距和表头,确保视图正确地定位到第一个可见项。这更符合 QML 的组件化封装思想。
  • 结论:逻辑正确,且优于原实现。

变更点 2:WindowedFrame.qml

  • 新增代码
    Component.onCompleted: {
        appList.resetViewState()
    }
  • 分析
    • 注释解释得很清楚:因为 LauncherControlleronVisibleChanged 只在隐藏时重置状态,所以需要在组件初始化完成时(onCompleted)手动调用一次重置,以确保初始状态的一致性。
    • 这是一个合理的生命周期管理补丁,避免了应用启动时列表位置可能残留上一次状态的问题。
  • 结论:逻辑正确,解决了潜在的初始化状态不一致问题。

2. 代码质量

  • 注释质量WindowedFrame.qml 中的注释清晰地解释了"为什么"需要这段代码,而不仅仅是描述代码做了"什么"。这是优秀的代码注释实践。
  • API 使用:在 FreeSortListView.qml 中,使用标准 API (positionViewAtBeginning) 替代直接属性赋值,提高了代码的可读性和可维护性。

3. 代码性能

  • positionViewAtBeginning() vs contentY = 0
    • 两者在性能上差异极小,通常都可以忽略不计。
    • positionViewAtBeginning() 内部可能包含更多的边界检查和动画计算(如果开启了动画),但在重置列表这种低频操作场景下,这种开销完全是可以接受的。
  • Component.onCompleted
    • 在组件加载时执行一次函数调用,对启动性能的影响微乎其微,属于必要的初始化开销。

4. 代码安全

  • 空指针风险
    • WindowedFrame.qml 中,appList.resetViewState() 假设 appList 对象在 Component.onCompleted 触发时已经存在并且可用。
    • 在 QML 的对象树构建过程中,子组件通常在父组件之前完成构造。如果 appListWindowedFrame 的直接子属性或子对象,这通常是安全的。
    • 潜在风险:如果 appList 是通过动态加载(如 Loader)或者异步加载的,这里可能会抛出 "TypeError: Cannot read property 'resetViewState' of undefined"。
  • 改进建议:为了增强健壮性,可以增加一个简单的存在性检查(虽然 QML 中不常见,但在复杂依赖下很有用):
    Component.onCompleted: {
        if (appList && typeof appList.resetViewState === "function") {
            appList.resetViewState()
        }
    }

总结与改进建议

这段 diff 整体上是高质量的修复,主要提升了代码的健壮性和逻辑正确性。

建议:

  1. 确认依赖关系:请确保 WindowedFrame.qml 中的 appListComponent.onCompleted 执行时确实已经准备好。如果 appList 是通过 ID 引用的兄弟组件,通常没问题;如果是动态加载的,建议改为在 appListComponent.onCompleted 中触发,或者使用 Connections 监听加载完成信号。
  2. 保持现状:如果 appList 是静态定义的,当前代码已经足够好,无需过度防御性编程,以免增加代码复杂度。

Copy link

@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 left some high level feedback:

  • Consider guarding appList.resetViewState() in Component.onCompleted with a null/ready check (or appList && appList.resetViewState) to avoid issues if appList is not yet initialized when the frame completes.
  • If resetViewState() affects modes other than free-sort, it might be worth tightening the condition under which it's called on startup so that only the relevant view/mode is reset.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider guarding `appList.resetViewState()` in `Component.onCompleted` with a null/ready check (or `appList && appList.resetViewState`) to avoid issues if `appList` is not yet initialized when the frame completes.
- If `resetViewState()` affects modes other than free-sort, it might be worth tightening the condition under which it's called on startup so that only the relevant view/mode is reset.

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.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

@BLumia BLumia merged commit 2dc6b7d into linuxdeepin:master Jan 26, 2026
10 checks passed
@BLumia BLumia deleted the pms-BUG-348311 branch January 26, 2026 07:53
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