fest:重构悬浮窗#87
Conversation
悬浮窗重构
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
- Actions/ShowFloatingWindowAction.cs: 保留 HEAD 的空悬浮窗组件检查与 main 的 IsRevertable 状态快照 - Services/FloatingWindowService.cs: 保留 HEAD 基于 FloatingWindowProfile 的行规则集方案 Co-Authored-By: TRAE Agent <agent@trae.local>
重构悬浮窗
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
- 去除悬浮窗设置页中的“组件库”区域 - 在“添加行”旁新增“添加按钮” Flyout,用于从可用按钮池中选择添加 - 为每个悬浮窗按钮项增加“设置”与“从行中移除”按钮,可在按钮单独设置中调整规则集 - 调整按钮项 Grid 列为 Auto,*,Auto,Auto,确保设置/移除按钮完整显示 - 修复 ToggleFloatingWindowLayer 的 TargetLayer 语义:0=置底,1=置顶(与 FloatingWindowProfile 内部语义一致) - 修正 ShowFloatingWindowAction 恢复逻辑中 MainConfig 为 null 的潜在空引用 Co-Authored-By: TRAE Agent <agent@trae.local>
- 删除悬浮窗设置页中的“组件库”及“添加按钮” Flyout - 新注册的按钮自动追加到第一行;被用户移除的按钮配置保留为 IsVisible=false,避免自动重新出现 - 按钮项内采用 inline 规则集/移除按钮,避免设置按钮被截断 - 行标题右侧增加行规则集、在下方插入一行、删除行三个操作按钮(参照 oSq 分支布局) - 新增 OnRowRulesetClick / OnInsertRowBelowClick 事件处理 - ViewModel 移除 AvailableFloatingTriggerItems 集合,AddTriggerFromPool 改为直接从 Entries 重建 Co-Authored-By: TRAE Agent <agent@trae.local>
Remove the per-button remove button from floating window layout editor; button removal is now handled via row settings only.
- ShowFloatingWindowAction: keep existing snapshot with null-safe revert - ToggleFloatingWindowLayerAction: save/restore layer via ActionSet.Guid - SwitchFloatingWindowThemeAction: save/restore theme via ActionSet.Guid - ToggleFloatingWindowProfileAction: save/restore profile via ActionSet.Guid Aligns with ClassIsland's revert pattern of keying snapshots by ActionSet.Guid.
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
保留 trae/solo-agent-VuGEdC 上的悬浮窗改进: - 4 个悬浮窗 Action 的可恢复快照(OnRevert 机制) - 智能悬浮窗显隐(HasAnyVisibleButton) - 一直显示拖拽把手功能(FloatingWindowDragHandleAlwaysVisible) - 行/按钮规则集 Drawer、属性实时监听 与 origin/main 的差异保留: - 切换悬浮窗层级方向 0=置底 1=置顶(与 Action 一致) - 移除组件库,使用 axaml 中重做的"按钮行+按钮"布局
-完全移除组件库 - 行标题右侧增加行规则集、在下方插入一行、删除行三个操作按钮 -优化规则集触发后的现实逻辑 -修复三个行动的恢复逻辑
悬浮窗配置方案管理 - 移除"方案切换"按钮及对应 OnToggleFloatingWindowProfileClick - 新增"打开悬浮窗配置文件夹"按钮,参照 ClassIsland 自动化设置页 - "新建"按钮改为 ContentDialog 输入方案名,避免静默重名失败 - 修复删除当前方案后被自动复活的 BUG: * FloatingWindowProfileManager.LoadProfile 不再为缺失文件回写默认方案 * FloatingWindowService.SwitchToProfile 仅在当前方案文件存在时 SaveProfile 定时器统一 - 移除 LayerRecheck50MsTimer / LayerRecheck1MsTimer 两个 DispatcherTimer - 层级巡检(mode 2/3)与规则集隐藏(整窗/按钮/行)统一迁移到 ILessonsService.PostMainTimerTicked(50ms) - 移除 IRulesetService.StatusUpdated 事件订阅及三个 handler 附带 - 模式 3(每 1ms)受 50ms 节流限制无法再保留,并入 50ms 行为; XAML 标签同步更新为"每 50ms(高占用)"
悬浮窗层级巡检的 mode 2(50ms 轮询)与 mode 3(1ms 轮询)之前 被改走 ILessonsService.PostMainTimerTicked,会受 50ms 节流限制 且不能完整保留 1ms 高频巡检能力。现改回各自的 DispatcherTimer Tick 事件触发: - 恢复 LayerRecheck50MsTimer / LayerRecheck1MsTimer 字段 - EnsureLayerRecheckHooks 改为订阅 timer Tick - RemoveLayerRecheckHooks 取消 timer Tick 订阅 - RefreshLayerRecheckMode 重新控制两个 timer.IsEnabled - Stop() 增加 LayerRecheck50MsTimer.Stop() / LayerRecheck1MsTimer.Stop() - 新增 OnLayerRecheck50MsTimerTick / OnLayerRecheck1MsTimerTick 各自仅在对应 mode 触发 RecheckWindowLayer - XAML 模式 3 标签恢复为"每 1ms(高占用)" OnPostMainTimerTicked 仍保留 ILessonsService 订阅,仅用于驱动 规则集巡检(整窗/按钮/行)与兜底 ApplyVisibility。
包含以下两次提交: 1. feat: 优化悬浮窗配置管理与定时器使用 - 移除"方案切换"按钮及对应 OnToggleFloatingWindowProfileClick - 新增"打开悬浮窗配置文件夹"按钮 - "新建"按钮改为 ContentDialog 输入方案名 - 修复删除当前方案后被自动复活的 BUG - 统一 ILessonsService.PostMainTimerTicked 驱动规则集巡检 2. fix(floating): mode 2/3 改回 DispatcherTimer 事件触发 - 模式 2/3 改回各自 DispatcherTimer.Tick 事件触发 - 恢复 LayerRecheck50MsTimer / LayerRecheck1MsTimer - OnPostMainTimerTicked 仅用于规则集巡检 - XAML 模式 3 标签恢复为"每 1ms(高占用)" 冲突解决:丢弃 main 上遗留的 SubscribeRulesetStatusChanged/ UnsubscribeRulesetStatusChanged/OnRulesetStatusUpdated 方法, trae 分支的最终方案已统一走 ILessonsService.PostMainTimerTicked 驱动规则集巡检,不再需要 StatusUpdated 事件订阅。
修复 main 工作流构建错误(CS0103): 1. FloatingWindowService.cs 恢复 private ILessonsService? _lessonsService; 字段, 合并冲突解决时与 DispatcherTimer 字段一并被丢弃, 导致 EnsureLayerRecheckHooks / RemoveLayerRecheckHooks 中的 PostMainTimerTicked 订阅无法编译。 2. FloatingWindowEditorSettingsPage.axaml.cs OnAddFloatingWindowProfileClick / OnOpenFloatingWindowProfileFolderClick 中错误引用了不存在的 _floatingWindowService 字段; 改为通过 ViewModel 暴露的 FloatingWindowProfilesDirectory 访问 ProfileManager.ProfilesDirectory,与现有 ViewModel 访问方式保持一致。 3. SystemToolsSettingsViewModel.cs 新增 public string FloatingWindowProfilesDirectory => _floatingWindowService.ProfileManager.ProfilesDirectory; 供 SettingsPage 在创建/打开方案文件夹时使用。
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd20cd3d90
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| var rows = new List<List<FloatingWindowEntry>>(); | ||
|
|
||
| foreach (var row in profile.FloatingWindowButtonRows ?? []) |
There was a problem hiding this comment.
Preserve unconfigured floating triggers
When a profile has no FloatingWindowButtonRows yet (fresh install, a newly migrated config that only had FloatingWindowButtonOrder, or a trigger registered while the editor is closed), this method now returns no rows instead of appending the missing registered entries like the previous implementation did. Start()/NotifyEntriesChanged() only call the service, not RefreshFloatingTriggers(), so the floating window can hide all available trigger buttons until the user opens the editor; keep the missing-ID fallback in both row rendering and the visibility check.
Useful? React with 👍 / 👎.
| _floatingWindowService.SwitchToProfile(profileName); | ||
| SelectedFloatingWindowProfile = profileName; | ||
| RefreshFloatingTriggers(); |
There was a problem hiding this comment.
Notify bindings after switching profiles
After selecting another profile, SwitchToProfile() replaces ProfileManager.CurrentProfile, but CurrentFloatingWindowProfile is a computed property and this code never raises OnPropertyChanged(nameof(CurrentFloatingWindowProfile)). The editor binds sliders/toggles to ViewModel.CurrentFloatingWindowProfile.*, so after a profile switch those controls can remain bound to the old profile object and subsequent edits update the wrong profile; raise the property change when the current profile object changes.
Useful? React with 👍 / 👎.
| NotifyRulesetStatusChanged(); | ||
| IAppHost.TryGetService<FloatingWindowService>()?.UpdateWindowState(); |
There was a problem hiding this comment.
Persist ruleset edits from the drawer
When a user edits the actual rules inside the drawer (for a button, row, or the global window ruleset), this handler only refreshes status/window state and never saves the owning profile or main config. Toggle changes are saved elsewhere, but rule/group property edits and collection edits handled here and below are lost on restart; save ProfileManager or MainConfig according to _currentRulesetTarget before returning.
Useful? React with 👍 / 👎.
| [JsonPropertyName("floatingWindowPositionX")] | ||
| private int _floatingWindowPositionX = 100; | ||
|
|
||
| [ObservableProperty] | ||
| [JsonPropertyName("floatingWindowPositionY")] |
There was a problem hiding this comment.
Use profile positions for window placement
These per-profile position fields are migrated and saved in the profile JSON, but the window placement code still reads and writes only MainConfigData.FloatingWindowPositionX/Y in FloatingWindowService.EnsureWindowPositionVisibleOnStartup() and SavePosition(). Dragging the window therefore updates a global legacy setting and profile switches ignore each profile's stored coordinates, so position is not actually part of a floating-window profile.
Useful? React with 👍 / 👎.
重构悬浮窗