Ariver
2026-05-29 279b3a07eb06f86b8825aa0a53e71cd3137e43a7
Reduce app grid scroll churn
3 files modified
25 ■■■■■ changed files
Apptag/AppGridCollectionView.swift 11 ●●●● patch | view | raw | blame | history
Apptag/ContentView.swift 4 ●●● patch | view | raw | blame | history
TODO.md 10 ●●●●● patch | view | raw | blame | history
Apptag/AppGridCollectionView.swift
@@ -272,6 +272,7 @@
    private var lastLayoutSize: NSSize = .zero
    private var lastReportedBoundsOrigin: NSPoint?
    private var scrollUnfreezeWorkItem: DispatchWorkItem?
    private var scrollActivityIsActive = false
    override var isFlipped: Bool { true }
@@ -385,14 +386,18 @@
    }
    private func handleScrollActivity() {
        if coordinator?.setScrollBubbleDisabled(true) == true {
            refreshVisibleRuntimeState()
        if !scrollActivityIsActive {
            scrollActivityIsActive = true
            if coordinator?.setScrollBubbleDisabled(true) == true {
                refreshVisibleRuntimeState()
            }
            coordinator?.onScrollActivity()
        }
        coordinator?.onScrollActivity()
        scrollUnfreezeWorkItem?.cancel()
        let workItem = DispatchWorkItem { [weak self] in
            guard let self else { return }
            self.scrollActivityIsActive = false
            self.replayPointerHover()
            if self.coordinator?.setScrollBubbleDisabled(false) == true {
                self.refreshVisibleRuntimeState()
Apptag/ContentView.swift
@@ -1732,7 +1732,9 @@
    }
    private func handleAppGridScrollActivity() {
        appGridInteraction.hoveredBubble = nil
        if appGridInteraction.hoveredBubble != nil {
            appGridInteraction.hoveredBubble = nil
        }
    }
    private func handleBubbleHover(app: AppInfo, frame: CGRect, event: AppBubbleHoverEvent) {
TODO.md
@@ -13,12 +13,14 @@
## Todo
- [2026-05-29] 第二批:AppGrid 滚动流畅性优化。
  - 目标: 降低滚动期间 SwiftUI 状态写入和 visible item 刷新频率,改善偶发卡顿/抖动。
  - 验收: 滚动手感稳定;hover 气泡不在滚动中闪现;不影响标签 hover 定位和拖拽。
## Done
- [2026-05-29] 第二批:AppGrid 滚动流畅性优化。
  - 提交: 本次提交
  - 结果: AppGrid 滚动期间只在滚动 burst 开始时通知 SwiftUI 清理 hover 气泡,不再每次 bounds 变化重复写状态;滚动停止后再恢复 hover replay 和 visible item runtime state。
  - 范围: 不改布局算法、不改拖拽、不改 hover 气泡展示规则,只降低滚动期间的刷新频率。
  - 验证: `bash build.sh`、`codesign --verify --deep --strict`、`Scripts/window_logic_qa.sh` 全部通过;滚动后 Space/Esc 连续循环 QA 保持通过。
- [2026-05-29] 第一批:未分类拖拽确认记忆 + 滚动后键盘兜底。
  - 提交: 本次提交
  - 结果: “拖到未分类”弹窗新增独立“不再提醒”checkbox 和 `skipUncategorizedDropConfirm` 持久化;overlay 键盘处理增加 AppKit `sendEvent` 兜底;AppGrid 滚轮进入时重新声明 key/front,避免滚动后 Space/Esc 偶发丢失。