Skip to content

fix: hide banner on search focus with animation - #842

Draft
pppanghu77 wants to merge 37 commits into
linuxdeepin:masterfrom
pppanghu77:fix/bug-256045-hide-banner-on-focus
Draft

pppanghu77 wants to merge 37 commits into
linuxdeepin:masterfrom
pppanghu77:fix/bug-256045-hide-banner-on-focus

Conversation

@pppanghu77

Copy link
Copy Markdown
Contributor

Root Cause Analysis

CooperationSearchEdit's eventFilter handles FocusIn/FocusOut events for placeholder switching but emits no signals, so WorkspaceWidgetPrivate::initConnect() (workspacewidget.cpp:93-106) has no way to link search focus to banner (FirstTipWidget) visibility. Additionally, FirstTipWidget::setVisible() calls QWidget::setVisible() directly with no animation. The root cause is a missing signal/connection chain: focus events are consumed internally but never propagated to the banner visibility controller.

Fix

Added focusIn()/focusOut() signals to CooperationSearchEdit and emit them in the eventFilter FocusIn/FocusOut branches. Connected these signals in initConnect() to tipWidget->setVisibleAnimated(false) on focus-in and tipWidget->setVisibleAnimated(true) on focus-out (guarded by empty-text + onlyTransfer + tipConfPath checks). Added setVisibleAnimated() to FirstTipWidget using QGraphicsOpacityEffect + QPropertyAnimation (300ms fade). This matches the analysis report section 10 recommended approach (root-cause layer fix + symptom layer patch, both required). No deviation from the plan.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • All changes are additive: new signal declarations, new Q_EMIT statements, new connect calls, and a new setVisibleAnimated() method — no existing function signatures or call paths are modified
  • Historical commits on these files (PMS 256007, PMS 256019) were UI visual fixes that do not touch focus→banner linkage or animation logic; this change does not revert any historical fix
  • setVisible() override adds one opacity-reset line when visible=true to ensure compatibility with switchWidget's direct-call path

Business Impact Scope

  • Cross-device cooperation main window: search box focus ↔ banner (first-use tip) interaction behavior
  • Affected callers: WorkspaceWidgetPrivate::initConnect() (new focus signal connections), WorkspaceWidgetPrivate::switchWidget() (existing setVisible path, now compatible with opacity reset)
  • User scenarios: clicking search box hides banner with fade-out; blurring search box with empty text restores banner with fade-in; page switching still controls banner visibility normally

Verification Suggestion

Focus on regression: verify search box focus hides banner with fade animation, search box blur with empty text restores banner, and page switching (switchWidget) still controls banner visibility correctly. Also verify onlyTransfer mode banner behavior is unaffected.


根因分析

CooperationSearchEdit 的 eventFilter 处理了 FocusIn/FocusOut 事件但仅切换占位文本,未对外暴露焦点信号,WorkspaceWidgetPrivate::initConnect()(workspacewidget.cpp:93-106)无法将搜索框焦点联动到 banner(FirstTipWidget)的显隐。此外,FirstTipWidget::setVisible() 直接调用 QWidget::setVisible(),无动画。根因为缺失型:焦点事件在内部被消费但未传播到 banner 可见性控制器。

修复方案

在 CooperationSearchEdit 新增 focusIn()/focusOut() 信号并在 eventFilter 中 emit;在 initConnect() 中连接到 tipWidget->setVisibleAnimated(false)(获焦)和 setVisibleAnimated(true)(失焦,受空文本 + onlyTransfer + tipConfPath 守卫);在 FirstTipWidget 新增 setVisibleAnimated() 方法,使用 QGraphicsOpacityEffect + QPropertyAnimation 实现 300ms 淡入淡出。与分析报告第十节推荐方案一致(根因层修复 + 症状层补丁,两层均需),无偏离。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 所有改动均为增量:新增信号声明、新增 Q_EMIT 语句、新增 connect 连接、新增 setVisibleAnimated() 方法——不修改任何现有函数签名或调用路径
  • 涉及文件的历史 commit(PMS 256007、PMS 256019)均为 UI 视觉修复,不涉及焦点→banner 联动或动画逻辑;本次改动不撤销任何历史修复
  • setVisible() override 仅在 visible=true 时新增一行 opacity 重置,确保与 switchWidget 直接调用路径兼容

业务影响范围

  • 跨端协同-主界面:搜索框焦点 ↔ banner(首次提示)的交互行为
  • 涉及调用者:WorkspaceWidgetPrivate::initConnect()(新增焦点信号连接)、WorkspaceWidgetPrivate::switchWidget()(现有 setVisible 路径,现已兼容 opacity 重置)
  • 用户场景:点击搜索框时 banner 带淡出动画隐藏;搜索框失焦且为空时 banner 带淡入动画恢复;页面切换时 banner 显隐行为正常

验证建议

回归重点:验证搜索框获焦时 banner 带动画隐藏、搜索框失焦且为空时 banner 恢复显示、页面切换(switchWidget)时 banner 显隐正常。同时验证 onlyTransfer 模式下 banner 行为不受影响。

pppanghu77 and others added 30 commits June 25, 2024 14:03
 [build] fix build

Log: [build] fix build
Task: https://pms.uniontech.com/task-view-354339.html
new tag v0.8.5, fix frontend launch issue for win.

Log: v0.8.5 override other incompatible version.
fix Multi user startup test

Log: fix Multi user startup test
Bug: https://pms.uniontech.com/bug-view-256723.html
[start] Change the startup sequence of the front-end and back-end

Log: [start] Change the startup sequence of the front-end and back-end
Bug: https://pms.uniontech.com/bug-view-261983.html
new tag v0.8.6

Log: new tag v0.8.6
[translation] add bo ug translation

Log: [translation] add bo ug translation
Fix title icon issue which caused by DTK updated.

Log: Fix title icon issue.
Bug: https://pms.uniontech.com/bug-view-264627.html
v0.8.7 release.

Log: v0.8.7 release.
…offline

Avoiding the impact of network fluctuations

Log: Added the option to manually disconnect the other party offline
Task: https://pms.uniontech.com/task-view-357177.html
Fix List Status and move the log location to/etc

Log: Fix List Status and move the log location to/et
Task: https://pms.uniontech.com/task-view-357177.html
v0.8.8 release.

Log: v0.8.8 release.
Modify the storage location of log level files

Log: Modify the storage location of log level files
Task: https://pms.uniontech.com/story-view-36529.html
Fix translation and UI issues

Log: Fix translation and UI issues
Bug: https://pms.uniontech.com/bug-view-250549.html
libcoost creates persistent static resources for each thread, which can cause memory leaks when threads are frequently created and released
using a thread pool to avoid frequent creation and destruction of threads
Log: Fix memory leaks
Bug: https://pms.uniontech.com/bug-view-266935.html
The daemon is renamed dde operation daemon

Log: The daemon is renamed dde operation daemon
Bug: https://pms.uniontech.com/bug-view-266935.html
v0.8.9 release.

Log: v0.8.9 release.
The default number of thread pools is too low, resulting in communication failure

Log: [thread] Increase the initial number of threads in threadpool
Bug: https://pms.uniontech.com/bug-view-273695.html
…nnection

Fix the issue of disconnection after network disconnection

Log: Fix the issue of disconnection after network disconnection
Bug: https://pms.uniontech.com/bug-view-273833.html
Record the searched devices and provide the option to minimize pallets

Log: [optimization] Optimize user experience
Bug: https://pms.uniontech.com/bug-view-250143.html
fix the password for the connection page is not complete in tibetan

Log: fix the password display is incomplete
Bug: https://pms.uniontech.com/bug-view-250623.html
Probability crash upon awakening

Log: Probability crash upon awakening
Bug: no
Unable to open from launcher after closing

Log: fix some ui bug
Bug: https://pms.uniontech.com/bug-view-282501.html
Implement a check in the setFile function to ensure that file paths do not exceed two directory levels. This change modifies the filename to retain only the last two directories and the file name itself, enhancing path management.

Log: Filter file paths to limit depth to two directories.
…P retrieval

Replace direct usage of QNetworkInterface::allAddresses() with
deepin_cross::CommonUitls::getFirstIp() to get the first available IP
address.
Log: fix: (data-transfer) replace QNetworkInterface with CommonUtils for IP retrieval
Bug: https://pms.uniontech.com/bug-view-341249.html
…rm transfer mechanism

- Add security checks in `getSaveFullpath` to prevent path traversal attacks by validating
  filenames and ensuring they are within allowed directories using realpath resolution.
- Introduce transfer confirmation mechanism in `JobManager` to require user approval before
  accepting incoming file transfers.
- Add methods to confirm, remove, and check transfer confirmation status for apps.
- Update `SendRpcService` to handle transfer confirmation and refusal messages.
- Include cleanup of confirmation status when jobs finish, cancel, or fail.

Log: fix(security): add path traversal protection in TransferJob and confirm transfer mechanism
Bug: https://pms.uniontech.com/bug-view-343709.html
Replace the library's dependencies with a method that displays the calling dynamic library.

Log: Remove displayjack kvm depend.
- Add file transfer confirmation status when password authentication succeeds
- Allow subsequent file transfers by calling JobManager::confirmTransfer
- This enables file operations after remote login is authenticated

Log: fix(rpc): add file transfer confirmation after successful authentication
Bug: https://pms.uniontech.com/bug-view-354299.html
pppanghu77 and others added 6 commits April 7, 2026 12:38
- Remove the transfer confirmation cleanup on job finished/canceled/failed
- Keep the confirmation state alive for the entire session to allow
  subsequent transfers without re-authentication
- This fixes the network error when transferring files again after
  returning from a completed transfer

Log: fix(transfer): 传输完成后点击返回再次传输提示网络错误
Bug: https://pms.uniontech.com/bug-view-355819.html
…emove transfer.json

- Fix storage directory for data-transfer: place target subdirectory under ~/Downloads
  instead of directly under home directory
- Change cleanup behavior to only remove transfer.json instead of the entire directory

Log: fix(data-transfer): save files to ~/Downloads subdirectory and only remove transfer.json
Bug: https://pms.uniontech.com/bug-view-356089.html
sync by github workflow

Log: none
Influence: none
… prompt on app installation

- Add initSecurityLoaderReport() in main.cpp: when started by deepin-security-loader (--fd1/--fd2 passed), report the system bus unique name and the com.deepin.lastore service list to the loader in JSON so it registers the lastore allow-caller whitelist on our behalf, making InstallPackage free of polkit authentication
- Call the report before any early-exit branch (including single-instance failure), otherwise the loader times out and kills the process, which shows up as a crash on startup
- Add launcher script /usr/bin/deepin-data-transfer: start the real binary /usr/libexec/deepin/deepin-data-transfer through deepin-security-loader with the deepin-daemon group when available (dbus >= 1.12.20.17-deepin1), otherwise fall back to direct launch with the historical polkit behavior
- Enable Qt DBus component/linking and install the real binary to libexec/deepin with the launcher taking over /usr/bin
- Update debian packaging: install the libexec binary and add Recommends: deepin-security-loader

修复(data-transfer): 经 deepin-security-loader 启动以避免安装应用时弹出 polkit 鉴权框

- main.cpp 新增 initSecurityLoaderReport():经 deepin-security-loader 启动(带 --fd1/--fd2 参数)时,将 system bus 唯一连接名和 com.deepin.lastore 服务列表以 JSON 回报给 loader,由其代为注册 lastore 的 allow-caller 白名单,使 InstallPackage 等接口免 polkit 鉴权
- 回报调用置于任何提前退出分支(含单例失败)之前,否则 loader 会超时结束子进程,表现为启动闪退
- 新增启动脚本 /usr/bin/deepin-data-transfer:环境满足(dbus >= 1.12.20.17-deepin1)时经 deepin-security-loader 附加 deepin-daemon 组启动真实二进制 /usr/libexec/deepin/deepin-data-transfer,否则回退直接启动,鉴权行为与历史一致
- 启用 Qt DBus 组件与链接,真实二进制安装至 libexec/deepin,/usr/bin 由启动脚本接管
- 更新 debian 打包:安装 libexec 二进制并增加 Recommends: deepin-security-loader

Log: 数据迁移工具经 deepin-security-loader 附加 deepin-daemon 组启动并回报 bus 连接名,实现 lastore 安装接口免鉴权,修复迁移三方应用时弹出密码认证框的问题
Bug: https://pms.uniontech.com/bug-view-375325.html
…n different filesystems

- Move directories with QDir::rename instead of QFile::rename, which fails with EISDIR on directories
- Fall back to recursive copy plus source removal when rename fails with EXDEV across filesystems: copyDirectory() for directories and QFile::copy for single files
- Fix rename-collision handling: dst.remove(fileName) deleted every occurrence of the name and corrupted paths with repeated segments; only the trailing segment is cut now
- Ensure the destination parent directory exists before moving, for targets such as ~/D:/ derived from Windows drive letters

修复(数据迁移): 修复源和目标位于不同文件系统时 moveFile 搬运失败的问题

- 目录改用 QDir::rename 移动,避免 QFile::rename 移动目录时报 EISDIR 错误
- rename 跨文件系统失败(EXDEV)时退化为复制后删除源:目录走 copyDirectory() 递归复制,单文件走 QFile::copy
- 修复重名避让逻辑: dst.remove(fileName) 会误删路径中所有同名段导致路径破坏,改为只截取结尾段
- 移动前确保目标父目录存在,兼容 ~/D:/ 这类源自 Windows 盘符的目标路径

Log: 修复数据迁移搬运阶段接收目录与主目录不在同一文件系统时 rename 跨设备失败(EXDEV)导致搬运失败的问题
Bug: https://pms.uniontech.com/bug-view-375881.html
- In domain-account environments the loginctl session username may differ
  from the home directory name (e.g. "@xxx"), and the name comparison
  failed, making the daemon exit right after startup (inactive desktop session)
- isActiveUser() now compares the active desktop session UID against getuid(),
  decoupled from the user naming scheme; when multiple desktop sessions are
  active, only the one belonging to the current user is taken as the active session
- KEY_CURRENT_ACTIVE_USER now stores the active session UID and the
  ServiceManager runtime check compares UIDs accordingly
- Guard the loginctl/getuid() based session check with _WIN32 so the daemon
  still compiles on Windows, where the check is not applicable
- Update SPDX copyright year to 2023-2026 for the modified files

修复(daemon): 改用 UID 而非用户名判定活动桌面会话

- 域账号场景下 loginctl 会话用户名与家目录名可能不一致(如 "@xxx"),
  名字比对失败导致 daemon 启动即退出(exit, inactive desktop session)
- isActiveUser 改为比对活动桌面会话 UID 与 getuid(), 与命名体系解耦;
  存在多个活跃桌面会话时, 以属于当前用户的会话为准
- KEY_CURRENT_ACTIVE_USER 改存活动会话 UID, ServiceManager 运行时检查同步按 UID 判定
- 活动会话检查增加 _WIN32 平台守卫, 修复 Windows 构建下 getuid() 编译失败的问题
- 更新所改文件的 SPDX 版权年份为 2023-2026

Log: 修复域账号环境下跨端协同 daemon 无法启动的问题

@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, we are unable to review this pull request

The GitHub API does not allow us to fetch diffs exceeding 20000 lines

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: pppanghu77

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

@github-actions

Copy link
Copy Markdown

TAG Bot

TAG: 0.8.9
EXISTED: no
DISTRIBUTION: unstable

@pppanghu77
pppanghu77 marked this pull request as draft October 29, 2026 19:36
1. Root cause: CooperationSearchEdit handled FocusIn/FocusOut events
   internally for placeholder switching but emitted no signals, so
   WorkspaceWidget had no way to link search focus to banner visibility
2. Fix: add focusIn/focusOut signals to CooperationSearchEdit, emit them
   in eventFilter, connect them in initConnect to hide/show banner via
   setVisibleAnimated with QPropertyAnimation fade effect
3. Guard conditions in focusIn/focusOut now match switchWidget logic:
   onlyTransfer || !tipConfPath.exists(), preventing banner from being
   wrongly shown/hidden when tip config exists in non-transfer mode
4. setVisibleAnimated stores animation pointer as member, stops and
   deletes previous animation before starting new one to prevent race
   between concurrent hide/show animations
5. setVisible(true) cancels any running hide animation to prevent
   finished callback from hiding a widget that was just shown
6. Impact: banner hides on search focus and shows on focus-out with
   empty text; respects onlyTransfer/tipConfPath flags; animation races
   eliminated; existing switchWidget path unaffected

Log: Banner now hides with fade animation when search box is focused

Influence:
1. Test search box focus hides banner with fade-out animation
2. Test search box blur with empty text shows banner with fade-in
3. Test search box blur with text keeps banner hidden
4. Test page switching still controls banner visibility correctly
5. Test onlyTransfer mode banner behavior unchanged
6. Test rapid focus/blur cycles do not leave banner in wrong state

fix: 激活搜索框时隐藏banner并添加动画

1. 根因:CooperationSearchEdit 的 eventFilter 处理了 FocusIn/FocusOut
   事件但仅切换占位文本,未对外暴露焦点信号,WorkspaceWidget 无法将
   搜索框焦点联动到 banner 显隐
2. 方案:在 CooperationSearchEdit 新增 focusIn/focusOut 信号并在
   eventFilter 中 emit,在 initConnect 中连接到 banner 的
   setVisibleAnimated 实现淡入淡出动画
3. focusIn/focusOut 守卫条件与 switchWidget 逻辑一致:onlyTransfer ||
   !tipConfPath.exists(),避免在非传输模式且提示配置存在时错误显隐
4. setVisibleAnimated 将动画指针存为成员变量,启动新动画前停止并删除
   旧动画,防止并发 hide/show 动画竞态
5. setVisible(true) 取消正在运行的 hide 动画,防止 finished 回调隐藏
   刚显示的 widget
6. 影响:搜索框获焦时 banner 淡出隐藏、失焦且文本为空时 banner 淡入
   显示;尊重 onlyTransfer/tipConfPath 标志位;消除动画竞态;
   switchWidget 路径不受影响

Log: 激活搜索框时banner带动画消失

Influence:
1. 测试搜索框获焦时banner带淡出动画隐藏
2. 测试搜索框失焦且为空时banner带淡入动画显示
3. 测试搜索框失焦且有内容时banner保持隐藏
4. 测试页面切换时banner显隐行为正常
5. 测试onlyTransfer模式下banner行为不受影响
6. 测试快速获焦/失焦循环不会导致banner状态错误

PMS: BUG-256045
@pppanghu77
pppanghu77 force-pushed the fix/bug-256045-hide-banner-on-focus branch from 357e09f to 194eb72 Compare October 29, 2026 21:03
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.

4 participants