Repository navigation
Electron 对标全线 + arco 组件库完成(#71–#92,22 提交) - #71
Merged
Merged
Conversation
复核 7-24/7-25 成果(#55–#70)全绿后,推进报告 29 事件面第 2 优先级: 把 sv-ui 本已有的 on_pointer_down/up(原只内部接 :active)在 codegen 暴露为 `onpointerdown`/`onpointerup` 模板属性。sv-ui 存储/setter/getter/shell 派发全 就绪,零内核改动、ViewNode 不增重。 - 与 :active 共存靠**合成一次设入**(照 :hover↔onpointerenter/leave 的 __ue/__ul 范式):同元素既有 :active 又有 onpointerdown 时,set_on_pointer_down 只发一次, 闭包先记按压态 __ac 再调用户回调 __ud;纯 :active(无用户回调)保持原简形。 - 禁用门同点击(pointer_down/up_handler getter 收口,disabled 节点取不到)。 - 白名单/错误串补 onpointerdown/onpointerup/onkeyup(onkeyup 有真 arm、原串漏列)。 **修一处方法论坑 + 孪生 bug**:合成路径首版 syn::parse 金样全绿,却被 multiclosure-check 真编译逮出 E0382——合成块里 __ud/__uu 各 move 同一非 Copy plain,只一份块级克隆份不够。修法每侧单独套 with_captured_plain。**同构的 :hover↔onpointerenter/leave 也有同款潜伏 bug**(:hover+捕 String 在真实代码更常见), 一并改为逐侧捕获。纯伪类退简形 move || __hv.set(..),wide 金样 -36/+4(等价简化)。 守卫:onpointerdown_onpointerup_compile + onpointerdown_composes_with_active_pseudo (sv-compiler);multiclosure-check(Check.svelte)加 :active/:hover × down/up/enter/leave × 捕 label 的真编译守卫。全仓 595 测试绿、clippy 净。 顺带复核发现回填报告 29:§2.1/§2.2 pointerdown/up 转 ✅;§3 #2 标完成;并订正 #1「OS 文件拖入」——winit DroppedFile **不带光标坐标**,非"转发即可",是清单里 唯一有平台能力坑的一项(下一步优先转 #3 onwheel/ondblclick,无平台坑更顺手)。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
对 7-24/7-25 全部 17 个提交(#55–#71,+10429/−1243)逐行复核。结论:16 个干净 (#55 span 契约、#56 金样对拍、#58 对称修复、#59 门控、#60/#62 捕获份、#64 拆分 路由、#66/#67/#68 事件面等均核实无误);#65(disabled)查获两处真实缺口,本提交修: - **① Tab 环落在禁用节点上**:`focus_next/prev` 走的内部 `focusables()` 遍历读 **裸** `focusable` 字段,没过公开 getter `focusable()` 的禁用门——两个读取口、 门只装了一个。已改为同门过滤(`n.focusable && !n.disabled`)。 - **② 获焦期间被禁用不清焦点**:焦点环留在禁用控件上、TextInput 的 IME 会话 不关、键盘事件(key_handler 无禁用门)继续派发——可向禁用输入框打字。 `set_disabled(true)` 对当前焦点节点现自动 `blur()`(失焦回调照发,浏览器同款)。 - 顺带 ③ `focus(禁用节点)` 改 no-op(浏览器同款;shell 点击设焦/a11y Focus 动作 本已设门,这是纵深防御)。 守卫:disabled_focus_surface_tab_skip_blur_and_focus_noop(sv-ui,三缺口各钉一段)。 方法论点(已记 open-issues):加交互门时应 grep 全部字段读取点,而不只改 getter。 复核中另核销一个疑点:空体 {#each} 早退路径绕过 list_cl 内层捕获,疑 E0382—— 实证不复现(语句级外层捕获份挡住,空体语句内仅一个闭包),往 multiclosure-check 的 Check.svelte 加两行空体 each 共享 plain 的真编译守卫钉住该防线。 全仓 596 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
推进报告 29 §3 Electron 面 #1(最低成本最高回报项)+ 事件面 #1,整面落地: - **创建时**:WindowOptions(标题/尺寸/最小最大约束/位置/resizable/无边框/ 透明/置顶/全屏/最大化/RGBA 图标)→ to_attributes 纯映射(单测钉死;恒 visible:false 保 AccessKit 前置,建好再翻开)。新入口 run_app_with/ run_multi_with,旧 run_app/run_multi 语义不变(= 只设 title)。 - **运行期**:window_of(doc) → WindowCtl(Electron BrowserWindow 实例方法 对标):set_title/set_inner_size/约束/set_outer_position/resizable/ decorations/always_on_top/fullscreen/最大最小化/set_visible/图标/focus/ request_user_attention/close。逻辑坐标口径与模板层一致。close 走标记 + 事件批末尾兑现(回调里不能拆正在派发的 Pane)。 - **OS 文件拖入**(报告 29 §3 事件面 #1):set_on_file_drop(doc) → FileDropEvent::{Hovered,Dropped,HoveredCancelled}。窗口级回调——winit DroppedFile 不带光标坐标,按报告订正落实为 API 形态,不做假坐标。 - **系统主题**:WindowCtl::theme() + set_on_theme_change(ThemeChanged 转发)。 - **多显示器**:monitors/current_monitor/primary_monitor → MonitorInfo。 实现全是 winit 薄转发,注册表 thread_local 按 Doc::key()(sv-ui 新增身份键) 挂靠,Pane 建时登记/关时注销(防指针复用串台);离屏路径 window_of 恒 None, 窗口代码自然短路,离屏测试零影响。 报告 29 §1.1/§1.4 十一行 ❌→✅ 回填;§1.1 剩余缺口只有运行期动态开窗与原生 模态子窗。守卫:选项映射 + 畸形图标忽略 + 回调注册表串台/注销 4 测(sv-shell); examples/window-ctl 演示全部能力(离屏 --png 已验)。全仓 600 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
推进报告 29 §3 Electron 面 #2 与 #4:新增 sv_shell::native 模块,三个独立 feature(默认全关,依赖卫生同 lottie/pag): - **dialogs**(rfd 0.15,default-features=false + gtk3——xdg-portal 后端会拖 async-std 整个运行时,gtk3 只影响 linux,win/mac 恒系统原生): pick_file/pick_files/pick_folder/save_file(FileDialogOptions:标题/起始 目录/预填名/扩展过滤)+ message(Info/Warning/Error)/confirm(OK/Cancel)。 - **notifications**(notify-rust,版本上限 <4.12——4.18 要 rustc 1.89 破 MSRV 1.88):notify(summary, body)。 - **opener**(带 reveal):open_external(URL/路径)+ reveal_in_folder (= Electron shell.showItemInFolder)。 设计:同步阻塞薄门面(对话框挡事件循环 = Electron showOpenDialogSync 语义); 失败一律不 panic(None/false + log::warn——无 dbus/无通知中心不该带崩应用); 稳定门面类型不漏 rfd/notify-rust(与 ColorTheme 不漏 winit 同一纪律)。 CI:test 矩阵 + clippy 补 "dialogs,notifications,opener" 道(ubuntu 用镜像 预装 libgtk-3-dev)。示例:window-ctl 加 feature `native` 演示段(打开文件/ 发通知/开外链/消息框,--png 离屏已验)。报告 29 §1.3/§1.4 四行 ❌→✅。 全仓 600 测试绿(含 --features 道 116)、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
推进报告 29 §3 Electron 面 #3(常驻类应用刚需): - **menu**(muda 0.17):声明式 MenuEntry(Action/Separator/Submenu,加速键 muda 语法、坏串降级 warn 不炸)→ set_app_menu(win 经 HWND 挂窗口菜单栏 / mac init_for_nsapp 应用级)+ show_context_menu(原生右键弹出,逻辑坐标, 与 oncontextmenu 事件配套;win)。**linux 明确不支持**(muda 菜单栏只接 gtk 窗,winit 非 gtk):warn + false 优雅降级,指路自绘 overlay 菜单。 - **tray**(tray-icon 0.21,依赖 menu):set_tray(RGBA 图标 + tooltip + 托盘菜单,左键弹菜单平台惯例)+ remove_tray;linux v0 不支持同上。 - **事件路由**:菜单栏/右键/托盘共用一条 muda 通道,about_to_wait 统一泵出 (菜单点击发生在消息泵内,本轮批末必达,无需额外唤醒),按 id 归属集路由 到各注册回调;回调 clone 出借用再调(防回调内改注册表 RefCell panic)。 菜单注册与窗口同生命周期(close_window 自动摘)。 - 已知限制(文档已记):win 加速键按键触发需 TranslateAccelerator 未接 (显示正常,应用内快捷键层可承接);mac 原生右键需 NSView 接线暂 warn。 守卫:collect_ids 嵌套归属 + 坏加速键容错(sv-shell,118 测全绿);CI test 矩阵/clippy 道扩为 dialogs,notifications,opener,menu,tray。示例:window-ctl --features native 增菜单栏/托盘/原生右键演示段(离屏 --png 已验,降级路径 无窗自然跳过)。报告 29 §1.2 三行 ❌→✅,§3 Electron 面 1-4 全落。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
推进报告 29 §3 Electron 面 #5 与 #6 首项: - **global-hotkey**(feature,global-hotkey 0.7):hotkey::register_global_hotkey (加速键语法同菜单)/unregister——窗口无焦点也触发(区别于应用内 shortcuts 层,两者并存);win/mac/x11,wayland 平台不支持(false+warn)。管理器懒建、 同键重复注册 = 替换;事件与菜单同模式(OS 热键消息唤醒循环,about_to_wait 批末泵出,clone 出借用再调)。 - **open_window(options, build)**(无 feature,核心能力):运行期动态开窗, 报告 29 §1.1 的最后一个 ❌、multi-window.md 预记方案的兑现——thread_local BuildFn 队列(!Send 不走 proxy 载荷)+ 无载荷 Wake 唤醒,批末兑现成 Pane; 新窗共享线程内响应式运行时,跨窗联动照旧零样板。离屏/循环未运行时 false+warn。 守卫:坏加速键/未注册注销容错(sv-shell);CI 特性道扩 global-hotkey。 示例:window-ctl「开新窗」按钮(核心路径)+ Ctrl+Shift+K 全局唤回(native 段)。 报告 29 §1.1「动态开窗」/§1.4「全局快捷键」❌→✅——**§3 Electron 面清单 只剩深链/自动更新/代码签名三项**(各有外部前置)。全仓 600 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
推进报告 29 §3 事件面 #3(前三项至此全落): - **ondblclick={|x, y| …}**:shell 连击计数 click_streak() 上提到每次左键 按下算一次(有副作用只能算一次;此前只在输入框分支算,4px 位移窗天然排除 跨控件连击,输入框选词/全选行为不变),第二击命中最上层带回调节点派发, 逻辑坐标、DOM 序在 click 之后;禁用门同点击(handler getter 收口)。 - **onwheel={|dx, dy| -> bool}**:原始滚轮先于滚动链派发,逻辑像素、DOM deltaY 口径(正 = 向下/右滚);**返回 true = 消费**该次滚轮、整条默认滚动 链跳过(preventDefault 心智,Ctrl+滚轮缩放类手势);false 时默认滚动照走, 与 onscroll 共存。禁用节点仍触发(滚轮掠过禁用控件照样滚,DOM 同款)。 - sv-ui:RareHandlers 加两槽(Box 内,ViewNode 不增重)+ setter/getter; codegen 两个 arm + 白名单/错误串;模板事件 14 → 16 个。 守卫:dbl_click_gates_and_wheel_consumes(sv-ui:坐标/消费语义/禁用门差异)、 ondblclick_and_onwheel_compile(sv-compiler);multiclosure-check 补两处存储型 move 处理器捕获份真编译守卫。全仓 602 测试绿、clippy 净、golden 逐字节不变。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
鼠标事件族最后一个同形缺口:MouseButton::Middle 命中派发,签名 |x, y| 逻辑 坐标、禁用门(动作类)与 contextmenu 完全同构。RareHandlers 加槽(Box 内, ViewNode 不增重)、codegen arm + 白名单、守卫并入既有双击/滚轮测试。 模板事件 16 → 17 个;鼠标族仅剩 mouseover/out(enter/leave 已覆盖其桌面用途)。 全仓 602 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
对 #73–#78 六轮做对抗复核,三处修正 + 一处守卫: - **rustdoc 链接红灯(会挂 CI docs 门禁)**:menu/hotkey/window 模块文档里 ①`pub mod` 外层 /// 与内层 //! 合并后链接解析域错乱(set_app_menu/ show_context_menu/pump_* 解析失败),②中文说明括号紧跟 [`X`] 被 markdown 当链接目标(`](可单测)`)。模块头改纯代码字体 + 断开 ](,本地全仓 --all-features 文档门禁清零。教训已记 open-issues:新增带文档的模块后 本地过一遍 doc 门禁,别等 CI。 - **菜单事件路由次序**:右键菜单(刚弹出的那个)必须先于应用菜单路由, 否则与菜单栏共用 id(如都叫 "copy")时被截胡。改为 CONTEXT → APP → TRAY。 - **多窗菜单同 id 限制警示**:muda 通道只带 item id 不带窗口,同 id 路由到 先注册窗——set_app_menu 文档 + open-issues 记账(结构性解法上游不提供), 建议各窗前缀 id。 - **public_api.rs 补窗口面守卫**:WindowOptions/FileDropEvent/ColorTheme/ window_of/open_window 外部 crate 可命名可构造 + 离屏 no-op(防"pub 类型 困在私有模块"重演)。 核实无虞项:同窗二次 set_app_menu = 整体替换(SetMenu 语义,新 Menu 实例无 AlreadyInitialized 路径);WindowCtl::close 的唤醒依赖(close 必发生在事件 回调内,批末 about_to_wait 必达);连击上提/滚轮消费/中键派发行为边界。 默认 602 + 全 native 特性 119 测试绿,双特性道 clippy 净,离屏渲染通过。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
推进剩余项(筛选无外部前置、本机可验证的三件):
- **app 模块**(无 feature,std-only 零新依赖;Electron `app` 对标):
- `ensure_single_instance(app_id)` + `set_on_second_instance`:
= requestSingleInstanceLock + 'second-instance'。127.0.0.1 确定端口
(FNV-1a → 49152–65535)会合:绑定成功即主实例(后台线程 accept,
魔数+app id 校验后 argv 入队,about_to_wait 批末泵出回调);绑定失败
握手转发本进程 argv(应答 ok 则调用方退出);端口被无关程序占 →
**降级无锁运行**(warn,宁可双开不可拒启)。
- `set_as_default_protocol_client(scheme)`(深链):Windows 运行时写
HKCU\Software\Classes(经系统 reg.exe,无注册表依赖库;与 Electron
同层,无需管理员)。深链接收闭环 = OS 二启带 URL argv → 单实例转发
→ 回调。scheme 白名单校验防注入;mac/linux 是安装期产物(warn+false)。
- `install_panic_hook(dir)`:panic 载荷/位置/回溯写 crash-{ts}.log,
链式不吞原输出(crashReporter 本地最小面;上传需服务端,不半吊子)。
- **图片剪贴板**(feature `clipboard-image` = arboard/image-data):
`native::clipboard_image()`/`set_clipboard_image(rgba, w, h)`(RGBA8 直通;
坏长度先于 OS 拒绝);独立懒建实例,不动编辑内核的文本剪贴板。
守卫 5 测:真 TCP 回环(合法二启转发 + 无关连接不应答不入队)、端口哈希
确定性、非法 scheme 拒绝、panic 真落盘(链式验证)、坏图长度拒绝——全部
headless 安全。CI 特性道扩 clipboard-image;文档门禁全仓清零(先过后提交)。
报告 29:剪贴板行补图片、深链/崩溃上报 ❌→✅,**§3 清单只剩自动更新与
代码签名**(更新服务器/证书是外部前置)。全仓 607 测试绿、双道 clippy 净。
Co-authored-by: Psyche <review@local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
对 #80(R7–R9)逐行对抗复核,两处真缺陷修复 + 一处文档失实订正 + 一处
伪缺陷实证排除:
- **二启派发 LIFO → FIFO**:pump 原逐条 Vec::pop(栈序),连续两次深链
点击回调顺序颠倒。改整批 mem::take 后按到达序派发(出锁再调,回调里可
再挂回调)。守卫 second_instance_pump_is_fifo(修前必红:得「第二,第一」)。
- **主实例重复 ensure_single_instance 自杀**:已是主实例再调,bind 必失败
→ 连到自己的 listener 把自家 argv 当"二启"转发 + 返回 false → 调用方
误判"已有实例"而退出。IS_PRIMARY(原为死状态,只写不读)改为幂等护栏
先查先短路。守卫 ensure_single_instance_is_idempotent_for_primary
(修前必红 + 验证不产生伪二启)。
- **崩溃钩子文档失实**:「重复调用后设胜」不实——实际链式叠加(每层各写
一份报告)。订正为「只装一次,重复会叠加」。
- **reg.exe 空值/引号疑点实证排除**:PowerShell 直测显示空 /d 被吞
("URL Protocol"值成 /f)、命令行引号被剥——但那是 PowerShell 5.1 自己
的空参丢弃;用**真 Rust Command 探针**复测:空值正确落空 REG_SZ、内嵌
引号完整保留("C:\fake path\app.exe" "%1")。现实现无缺陷,免于一次
"把正确代码修坏"。已知限制补记模块文档(argv 含换行拆散/慢连接串行,
均 localhost 面)。
测试间共享全局队列加串行锁(mem::take 会互偷条目,防 flaky)。
全仓 609 测试绿(app 模块 6 测)、clippy 净、文档门禁净。
Co-authored-by: Psyche <review@local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
遗留项归档(open-issues「Electron 对标遗留」全清单)后,D 轨道 A2 波次落地:
- **Checkbox**:bind:checked 双向,行/框皆可点(单点派发天然不双触发),
选中 primary-6 白勾,禁用 fill-2/light-3 + 短路。
- **Radio / RadioGroup**:受控单枚 + 互斥组(selected: $bindable(i32)),
14px 正圆 gray-3 圈、选中 primary-6 + 白点。
- **Switch**:circle 形态两尺寸(40×24/28×16),padding+justify-content
两态滑(无动效版);开 primary-6 / 关 fill-4 / 禁用 light-3/fill-2。
- **Input**:fill-2 → hover fill-3 → 聚焦白底 + primary-6 描边(A2 验收
条款 :focus 接线);error/warning 换 danger/warning 系;四尺寸;禁用不可焦。
- **InputNumber**:button 形态 [−][框][+],i32 步进钳制 min..=max;手输
oninput 解析回流(不回显文本,光标不跳),非法输入 danger-6 红字。
全部 vendored 上游 token(web-react 2.66.16 经 npmmirror,github raw 不稳)、
出处逐行注释;17 项离屏行为测试(含键盘编辑段真键入回流);gallery A2 展区
离屏视觉验收通过。
**框架级修复(A2 撞出)**:
- `{#each}` 中间容器恒默认竖排且 .svelte 够不着——Radio.Group 横排组竖排。
sv-ui 容器创建时镜像父节点 flex 上下文(direction/gap/align/justify 快照;
keyed 变体同修;运行期父方向再变不跟随,记为已知限制)。守卫
each_container_mirrors_parent_flex_context。
- `.svelte` placeholder={表达式}(建树求值一次,组件 String prop 透传);
静态串路径不变,golden 不动。
全仓 626 测试绿(sv-arco 52)、clippy 净。
Co-authored-by: Psyche <review@local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
D 轨道 A4 波次落地(Card/GridRow/GridCol/List/Menu/Tabs/Progress/Pagination/ Steps/Skeleton,全部 vendored 上游 token 2.66.16 + 出处注释): - Card:46px 标题栏 + extra + 1px 分隔线 + children 插槽;bordered 开关。 - Grid:span 比例列(无百分比宽度 → flex-grow 降级,@Attach 写入;列内容 align stretch)。 - List:头 + 行间分隔线(末行不画,count 比对)+ hover fill-1。 - Menu:vertical 平铺,选中 fill-2 底 + primary-6 文,hover 同底。 - Tabs:line 形态,墨条 2px 占位恒在(切换不跳动),active 双向。 - Progress:line 四状态(primary/success/danger/warning-6),条宽 @Attach 按 percent 钳算;右侧百分比文字。 - Pagination:全量页码 + 前后翻,active bg primary-1 文 primary-6,越界钳。 - Steps:circle 三态(finish primary-1/process primary-6/wait fill-2)+ 连线按进度变色。 - Skeleton:行占位 fill-2,末行 60% 短行。 **框架级修复(Grid 竖排撞出,离屏探针实证)**:`{@render}` 编译为 key_block, 其中间容器不在 #82 的 each 镜像范围 → Grid 列被竖排容器隔断。修复: 「镜像父 flex 上下文」推广到 **if/key/await/mount 全部块原语**(sv-ui; virtual_list 刻意除外——虚拟化偏移按竖排算);镜像方向为 Row 时容器 flex-grow=1 填主轴(否则子列 grow 无余量,比例失效)。 复核记事:gallery 缩略图里 Menu/Tabs 选中文字"发红"经全分辨率单渲探针证伪 (3.1× 下采样的 CJK 细笔画抗锯齿伪影,实为 #165DFF 正蓝)。 11 项 A4 行为测试(含离屏布局冒烟);gallery A1+A2+A4 全景 --png 验收。 全仓 637 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
D 轨道 A5 波次落地(Tooltip/Dropdown/Select/Modal/Message/Popconfirm, vendored token 2.66.16 + 出处注释),弹层原语的组件化验收: - Tooltip:sv_ui::tooltip 原语代付 400ms 延时/防抖/不可命中/a11y 描述, 组件只给 arco 视觉(深底白字气泡)。 - Dropdown:点击下拉,选项 36 高 hover fill-2,on_select(i) + 自动收合。 - Select:单选 selected 双向(-1=placeholder),弹开白底 primary 描边 (与 Input 聚焦同构);选中项 primary-6。 - Modal:居中模态——焦点陷阱/Esc LIFO/点外关闭全由 overlay 原语代付; 48px 头 + children 插槽 + 右对齐 取消/确定。 - Message + show_message 编排:await_block 计时、完成回调主线程写信号 (线程内响应式约束下的合规定时路径),duration 后自动消失;**锚点降级** 已记 README(overlay 无窗口顶部锚,居中显示)。 - Popconfirm:确认气泡 mini 钮 OK/Cancel。 守卫 6 测:开合树增删、选择回流、回调触发、tooltip hover 接线、 show_message 定时消失(真 tasks 泵)。gallery A5 展区(窗口化可交互, Modal/Message 真开)。**sv-arco 至此 A1(7)+A2(6)+A4(10)+A5(6)=29 组件, 调研 26 计划内组件波次全部完结**(A3 图标/阴影是渲染基建按降级口径先行, A6 数据重件按调研口径「另计」)。全仓 643 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
对 #82–#84 三波逐行对抗复核,查获并修复: - **框架级 panic(高危)**:销毁**焦点所在**且带 :focus 接线的子树(点选 下拉选项关弹层的标准路径)→ Doc::remove 照发失焦回调 → 回调写的 __fc 信号已随行作用域销毁 → panic「signal 已随作用域销毁」。真实用户点一下 即崩,由本轮键盘可达性改造(选项转 focusable)暴露。修:对齐浏览器语义 ——移除聚焦元素**静默清焦、不发 blur 事件**(节点已亡,样式复原无意义; DOM 同款)。旧测试钉着旧行为,按新语义改写并注明缘由。 - **键盘可达性五处**:Modal 确定/取消、Popconfirm 触发/OK/Cancel、 Dropdown 触发/选项、Select 选框/选项 从 <view> 改真 <button>(Tab 可达 + Enter/Space 激活 + 弹层开自动落焦第一项的 #49 框架行为要求 focusable); InputNumber 步进钮补 disabled 属性(此前禁用仍可聚焦)。 - **show_message 累积泄漏(两版修到零)**:v1 直接 await_block 每次 toast 永久留下包装 + 计时容器;v2 mount + 作用域内自拆(裸 drop 不拆节点且有 自毁风险)。终版:mount 气泡 + tasks::spawn 计时(完成回调主线程、 不挂树、不属挂载作用域)→ 关 overlay 再 unmount,**节点数回落基线**。 守卫:overlay_controls_are_keyboard_reachable(触发器 focusable + 开即落焦)、 show_message_reclaims_nodes(基线回落)、remove_focused_subtree_clears_focus (改钉静默清焦);既有 dropdown/select 选择测试即 panic 修复的回归守卫 (修前必崩)。全仓 645 测试绿、clippy 净、gallery 重渲无回归。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
继 #85 复核轮后推进 arco 收尾,A6 落地(vendored token 2.66.16):
- **Table**:字符串单元格 + 等分列(flex-grow=1/格)+ 表头 gray-2 底 +
行分隔线(末行不画)+ 行 hover fill-1;无排序/筛选/固定列(各是独立
交互件,按需另加)。
- **Tree**:两级降级版(组件不能自引用,无任意深度递归)——组展开态
u64 位掩码(组数上限 64,超出恒展开,降级注明)、叶选中 primary-1 底
primary-6 文 + (组,叶) 回调;无勾选/拖拽/连接线。
- **DatePicker**:内联月面板——纯算术历法($derived 蔡勒公式,无系统
时钟依赖)+ 月导航跨年进位 + 选日 on_pick(y,m,d);无输入框触发/范围/
时间。测试钉历法:2026-07 = 31 天且 1 日落周三、6 月 30 天、连翻跨年。
**框架级修复(日历折行撞出,两步定位)**:块容器镜像补 `flex_wrap`
(wrap 父里的 {#each} 容器此前不折行);仍不折 → 根因本仓 Style 缺省
flex_shrink=0(CSS 是 1),max-content basis 的镜像容器压不回父约束,
Row 镜像补 shrink=1。gallery 全景(8000px,32 组件)验收通过。
sv-arco 至此 **A1–A6 组件波次全完结:32 组件,组件面无遗留**;A3(SVG
图标管线 + box-shadow)是 sv-shell 渲染基建轨道(调研 26 估 4–7 人周、
"隐形深坑"),边界与降级口径已记 README。3 项 A6 行为测试;全仓 648
测试绿、clippy 净。
Co-authored-by: Psyche <review@local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
调研 26 A3 的阴影项按预划形状落地(Painter trait 加法 + Recording 金样保底): - **sv-ui**:Style.shadow: Option<Box<BoxShadow>>(冷字段 Box 化,+8B 过 预算探针);三道穷尽解构闸门(Style::eq / dirty::layout_relevant / render::to_taffy)+ 数据面 StyleDecl::Shadow 全数过账。 - **Painter 动词 blurred_rounded_rect**:带默认降级实现(σ 归零实心矩形 ——阴影是装饰性动词,与 fill_path"禁止默认"的纪律相反而互补,注释成文)。 三后端:RecordingPainter 记 PaintCmd::Shadow(金样);**tiny-skia 解析式** (圆角矩形 SDF × 高斯 CDF〔A&S erf 近似〕,直边与真高斯逐点相等、角部 亚像素近似,免掉 CPU 栈没有的模糊滤镜与整幅中间缓冲);**vello 原生** draw_blurred_rounded_rect(caps.blur 早已预留位,今补实)。 - **σ 口径**:CSS blur-radius ≈ 2σ(Chrome 同款),换算在 render 调用方; 阴影画在背景之下,几何 = 矩形平移 (dx,dy)。 - **脏矩形出血**:node_ink 并入阴影足迹(平移 + 3σ 羽化)——不并的话带 阴影节点动一下就在增量重绘里留鬼影。 - **CSS 解析**:box-shadow: x y blur 颜色(px 可省、rgba 内含空格 OK、 无 spread/inset——arco 令牌全集)+ none;坏形态报错不静默。 - **arco 回填**:Dropdown/Select/Popconfirm 弹层与 Message 挂 shadow2-down (0 4 10 rgba(0,0,0,.1),tokens 金样值);README 降级口径「无阴影」勾销。 守卫:命令流序(阴影先于背景、dy/σ 量化)+ CPU 像素实证(阴影带变暗且 随距离衰减、本体纯白)+ 损伤出血下沿 + 编译器四态解析。CSS-SUPPORT box-shadow ⏳→✅。全仓 651 测试绿、双后端构建过、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
调研 26 标注"隐形深坑"的图标管线正面攻下(自研,无 usvg 依赖): - **sv-ui `parse_svg_path`**:SVG path `d` 全集(M/L/H/V/C/S/Q/T/A/Z、 隐式命令重复、SVG 数字词法怪癖——负号分隔/`.5.5`/弧标志位粘连); **弧转贝塞尔**按 SVG 1.1 附录 F.6(端点→中心参数化、半径不足等比放大、 拆 ≤90° 段);Q/T 二次升三次。契约测试:arco 六枚真实图标 `d` 原文全 解析且坐标有界(飞点现形)、两段弧拼整圆包围盒 0.5px 内、病态词法四例。 - **ElementKind::Icon 内容节点**:载荷 `IconData`(段/viewBox/描边宽/ evenodd)场景树自持不走注册表(与 Animation 的注册表句柄语义相反,注释 成文);fg 继承上色、固有尺寸 1em;dump 印段数不印坐标(防金样浮点漂)。 ViewNode 400→408 记账(kind 门控内容载荷 anim/input/icon 各 8B,下个 载荷前先合并 payload enum)。 - **sv-shell 渲染臂**:内容盒等比缩放居中,线性系 stroke_path(圆帽圆角, 宽随缩放)、填充系 fill_path(evenodd)——正是调研 26 预划的"矢量走 既有动词"形状;不预光栅,HiDPI 天然无损。a11y Role::Image。 - **sv-arco::icons 八枚**(vendored 2.66.16 `d` 原文,与 token 同版本 pin):check/close/down/loading 线性系 + info/check/close/exclamation 实心圆填充系;mount_icon 便捷挂载。**回填**:Alert 四态状态图标 (状态-6 上色)、Modal ✕ 关闭钮(可点真关);button 是文本叶子不能含 子节点 → Select/Dropdown ▾ 仍字形,README 记限制。 守卫:像素落墨实证(填充圆大面积着色 + 描边勾成线)、Alert 树上图标 + 状态色、Modal ✕ 点击关闭。gallery 图标展区(4400px 处八枚两系)。 **D 轨道至此 A0–A6 全完结**:令牌 + 32 组件 + 阴影 + 图标,调研 26 计划面 清空。全仓 658 测试绿、clippy 净、双后端构建过。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- **`:disabled` 伪类样式**(open-issues「Phase 2」按预记方案落地):
- style.rs:ClassStyle 加 disabled 槽,规则头 `.x:disabled` 与嵌套
`&:disabled` 两形态都认(报错文案随更新);
- codegen:元素级镜像信号 `__dis`(声明在样式块外——attrs 循环里的
disabled 属性 arm 要写它),`disabled={expr}` 的 effect **同一趟**写
节点禁用位与镜像(节点 bool 不是信号,不镜像样式追不上切换);裸
disabled 建树置 true。样式重算尾追 `:disabled` 块,**垫最后盖过
hover/active/focus**(浏览器直觉:禁用态最强);
- Input.svelte 从 `.inp-off` 条件类迁 `&:disabled`(首个真组件验收,
既有 disabled 测试即行为守卫);CSS-SUPPORT 伪类行订正(:active/
:focus 也早落地,合并行一并勾账)。守卫
disabled_pseudo_class_tracks_attr(镜像联动 + 依赖断言)。
- **Message 顶部锚**:overlay `Anchor::WindowTop`(顶部居中距顶 24,arco
message 口径)+ codegen `anchor="top"` + Message.svelte 迁顶部——A5 的
「锚点降级:居中显示」清账。
全仓 659 测试绿、clippy 净。arco 文档面的降级清单至此:字重(fontique
接线,R3 框架轨道)与过渡动效(transition C2,框架轨道)为仅存两项,
均为既定框架路线项而非组件库缺口。
Co-authored-by: Psyche <review@local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
对阴影/图标/:disabled/顶锚四提交逐行对抗复核:
- **高危:parse_svg_path 对 `Z5` 类病态输入死循环**——Z 无参,隐式重复
分支落进 Z 臂时零消费 token,`M0 0Z5` 永不推进(一条坏 path 字符串即可
挂死调用线程)。修:隐式重复遇 Z/z 立即报错「Z 后不应有参数」;守卫四例
(Z5/z-1z 报错,正常 Z 收尾与 Z 接新子路径不受影响)。顺手清掉同段的
死代码(尾部 no-op continue 与 has_more_coords)。
- **伪类规则头嵌套防线统一**:`.x:hover { &:hover {} }` 的拒绝守卫原来
只装在 hover 头上——`.x:disabled { &:hover {} }` 会把 hover 悄悄并进类
的 hover 槽(语义污染,:disabled 新增后暴露面变大)。四个伪类头统一
前置检查,报错同文案。
- **核实无虞项**(逐条过审):阴影 blend 的 cov×alpha 双因子/裁剪交集/
绘制序/量化/damage 出血时序;弧转换退化早退(den=0 不可达)、S/s 反射
基准清理、词法三怪癖;__dis 与 has_state 分支恒配对、兄弟 shadowing
安全、golden 零扰动;WindowTop clamp 兜底。
全仓 659 测试绿、clippy 净。
Co-authored-by: Psyche <review@local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
仓库实证复盘:两条冲刺线(Electron 对标 #71–#81、D 轨道 arco #82–#91) 的落地表、六处组件撞出的框架级修复、复核方法论沉淀、余账明界。 索引同步:docs/README 两语 + 根 README 两语 + CLAUDE.md 计数 29→30。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…acOS muda 断言 - rustfmt:sv-arco/sv-compiler/sv-shell 等 20 文件补平格式账(唯一改动是排版) - examples/window-ctl:补漏掉的 license.workspace(cargo-deny unlicensed 拦下) - deny.toml:GTK3 绑定家族 7 条 + proc-macro-error 的 unmaintained 通告登记放行 (非漏洞;muda/tray-icon/rfd 上游整体钉 GTK3;复查期 2026-10-25) - ci.yml:ubuntu-24.04 镜像不再预装 libgtk-3-dev——msrv/docs/lint 三道 --all-features 与 features 原生道全在 glib-sys 构建期红;四道补装 gtk/xdo/appindicator -dev 包(features 道按矩阵行条件装) - ci.yml:features 道 rust-cache key 直接用特性串,actions/cache key 不准含 逗号,lottie,pag/原生道缓存自始静默失效——矩阵改 flags/key 双字段 - menu.rs:build_menu_tolerates_bad_accelerator 在 macOS cfg 掉——muda 的 NSMenu 主线程断言在测试线程必炸,且经崩溃钩子串进 app::tests 的目录连坐; 运行期构建菜单都在主线程,生产路径不受影响 - CHANGELOG:修复段记账 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
首轮 CI 的 fmt 红把 clippy 挡在了后面,这条 collapsible_if 是第二轮才首次 暴露的存量(let 链正是 MSRV 1.88 的由来,写法本就该如此)。四条 clippy 道 (默认/vello/lottie,pag/原生)本地已全数复跑清零。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
build_menu_for_tray/set_tray_menu_route 的唯一调用方是 tray.rs 的 win/mac 分支(linux 整块运行时降级),不带平台门时 ubuntu 原生道 clippy 按 dead_code/unused_imports 红。cfg 与调用方对齐:tray + win/mac。 build_menu 本体不动——set_app_menu/show_context_menu 在 linux 也无条件 调它(构建后才降级),不受影响。 前两轮该步没跑到(fmt→默认道 clippy 依次挡在前面),属存量首暴露; 本机 Windows 照不到 linux 视角的 dead_code,故直到 CI 才现形。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cyaim
added a commit
that referenced
this pull request
Jul 26, 2026
复核 7-24/7-25 成果(#55–#70)全绿后,推进报告 29 事件面第 2 优先级: 把 sv-ui 本已有的 on_pointer_down/up(原只内部接 :active)在 codegen 暴露为 `onpointerdown`/`onpointerup` 模板属性。sv-ui 存储/setter/getter/shell 派发全 就绪,零内核改动、ViewNode 不增重。 - 与 :active 共存靠**合成一次设入**(照 :hover↔onpointerenter/leave 的 __ue/__ul 范式):同元素既有 :active 又有 onpointerdown 时,set_on_pointer_down 只发一次, 闭包先记按压态 __ac 再调用户回调 __ud;纯 :active(无用户回调)保持原简形。 - 禁用门同点击(pointer_down/up_handler getter 收口,disabled 节点取不到)。 - 白名单/错误串补 onpointerdown/onpointerup/onkeyup(onkeyup 有真 arm、原串漏列)。 **修一处方法论坑 + 孪生 bug**:合成路径首版 syn::parse 金样全绿,却被 multiclosure-check 真编译逮出 E0382——合成块里 __ud/__uu 各 move 同一非 Copy plain,只一份块级克隆份不够。修法每侧单独套 with_captured_plain。**同构的 :hover↔onpointerenter/leave 也有同款潜伏 bug**(:hover+捕 String 在真实代码更常见), 一并改为逐侧捕获。纯伪类退简形 move || __hv.set(..),wide 金样 -36/+4(等价简化)。 守卫:onpointerdown_onpointerup_compile + onpointerdown_composes_with_active_pseudo (sv-compiler);multiclosure-check(Check.svelte)加 :active/:hover × down/up/enter/leave × 捕 label 的真编译守卫。全仓 595 测试绿、clippy 净。 顺带复核发现回填报告 29:§2.1/§2.2 pointerdown/up 转 ✅;§3 #2 标完成;并订正 #1「OS 文件拖入」——winit DroppedFile **不带光标坐标**,非"转发即可",是清单里 唯一有平台能力坑的一项(下一步优先转 #3 onwheel/ondblclick,无平台坑更顺手)。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cyaim
added a commit
that referenced
this pull request
Jul 26, 2026
对 7-24/7-25 全部 17 个提交(#55–#71,+10429/−1243)逐行复核。结论:16 个干净 (#55 span 契约、#56 金样对拍、#58 对称修复、#59 门控、#60/#62 捕获份、#64 拆分 路由、#66/#67/#68 事件面等均核实无误);#65(disabled)查获两处真实缺口,本提交修: - **① Tab 环落在禁用节点上**:`focus_next/prev` 走的内部 `focusables()` 遍历读 **裸** `focusable` 字段,没过公开 getter `focusable()` 的禁用门——两个读取口、 门只装了一个。已改为同门过滤(`n.focusable && !n.disabled`)。 - **② 获焦期间被禁用不清焦点**:焦点环留在禁用控件上、TextInput 的 IME 会话 不关、键盘事件(key_handler 无禁用门)继续派发——可向禁用输入框打字。 `set_disabled(true)` 对当前焦点节点现自动 `blur()`(失焦回调照发,浏览器同款)。 - 顺带 ③ `focus(禁用节点)` 改 no-op(浏览器同款;shell 点击设焦/a11y Focus 动作 本已设门,这是纵深防御)。 守卫:disabled_focus_surface_tab_skip_blur_and_focus_noop(sv-ui,三缺口各钉一段)。 方法论点(已记 open-issues):加交互门时应 grep 全部字段读取点,而不只改 getter。 复核中另核销一个疑点:空体 {#each} 早退路径绕过 list_cl 内层捕获,疑 E0382—— 实证不复现(语句级外层捕获份挡住,空体语句内仅一个闭包),往 multiclosure-check 的 Check.svelte 加两行空体 each 共享 plain 的真编译守卫钉住该防线。 全仓 596 测试绿、clippy 净。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cyaim
added a commit
that referenced
this pull request
Jul 26, 2026
仓库实证复盘:两条冲刺线(Electron 对标 #71–#81、D 轨道 arco #82–#91) 的落地表、六处组件撞出的框架级修复、复核方法论沉淀、余账明界。 索引同步:docs/README 两语 + 根 README 两语 + CLAUDE.md 计数 29→30。 Co-authored-by: Psyche <review@local> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cyaim
added a commit
that referenced
this pull request
Jul 26, 2026
…acOS muda 断言 - rustfmt:sv-arco/sv-compiler/sv-shell 等 20 文件补平格式账(唯一改动是排版) - examples/window-ctl:补漏掉的 license.workspace(cargo-deny unlicensed 拦下) - deny.toml:GTK3 绑定家族 7 条 + proc-macro-error 的 unmaintained 通告登记放行 (非漏洞;muda/tray-icon/rfd 上游整体钉 GTK3;复查期 2026-10-25) - ci.yml:ubuntu-24.04 镜像不再预装 libgtk-3-dev——msrv/docs/lint 三道 --all-features 与 features 原生道全在 glib-sys 构建期红;四道补装 gtk/xdo/appindicator -dev 包(features 道按矩阵行条件装) - ci.yml:features 道 rust-cache key 直接用特性串,actions/cache key 不准含 逗号,lottie,pag/原生道缓存自始静默失效——矩阵改 flags/key 双字段 - menu.rs:build_menu_tolerates_bad_accelerator 在 macOS cfg 掉——muda 的 NSMenu 主线程断言在测试线程必炸,且经崩溃钩子串进 app::tests 的目录连坐; 运行期构建菜单都在主线程,生产路径不受影响 - CHANGELOG:修复段记账 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cyaim
added a commit
that referenced
this pull request
Jul 26, 2026
功能复核:570 单测全绿 + 三平台 CI 矩阵(含四条特性道/门禁/bench)+ arco-gallery 离屏 32 组件落墨目检;bench 3k p99=16.76ms、100k 虚拟 p99=2.84ms。 距离更新(对照调研 27):九项交集仍 8✅+1 卡 ADR-10 裁决;档 B 特性面 比 27 时厚一整层(32 组件 + Electron API 面),信心面(真机 IME/读屏/ 真 PAG 素材)未动。余账按距离重分类为五档:决策/发布尾巴/验证盲区/ 外部前置/生态打磨,给出人日~人周~人月的三档量化与三条并行关键路径。 顺带:docs/README 两语索引 + CLAUDE.md/根 README 计数 30→31。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
报告 29 发布后同日的两条冲刺线,一次 PR 交付(复盘全文见新增的
调研 30):
Electron 对标(#71–#81)
WindowOptions/window_of(doc) → WindowCtl(标题/尺寸/约束/无边框/置顶/全屏/图标/close/focus/flash)dialogs(rfd)、通知notifications、外链opener、菜单栏/原生右键menu(muda)、托盘tray、全局快捷键global-hotkey、图片剪贴板clipboard-imageapp(std-only 零新依赖):单实例(TCP 会合 + 魔数握手)+ 深链(win 运行时 HKCU + 二启 argv 转发闭环)+ panic 崩溃落盘open_window(thread_local BuildFn 队列 + Wake,!Send约束下的预记方案)onpointerdown/up(与:active合成)、ondblclick、onauxclick、onwheel(->bool消费语义)+ OS 文件拖入/系统主题/多显示器arco 组件库(#82–#91)——调研 26 计划面清空
:disabled伪类样式(镜像信号)+ Message 顶部锚(Anchor::WindowTop)组件当磨刀石:撞出并修复 6 处框架级缺陷
块容器镜像父 flex 上下文(each/if/key/await/mount)、
flex_shrink=0缺省分歧、销毁焦点子树 panic(→浏览器同款静默清焦)、合成闭包捕获份 E0382、path 解析 Z 死循环、placeholder={表达式}。复核纪律
五轮逐行复核(#72/#79/#81/#85/#91)全部带"修前必红"回归守卫;方法论沉淀(验证语义一致性/缩略图伪影/门装一半等于没装)记入调研 30 §4。
验证
cargo test:659 通过 0 失败(全特性道另 119);clippy 双道净;rustdoc 门禁净cargo run -p arco-gallery -- --png:32 组件全景(8000px)视觉验收cargo run -p window-ctl --features native:桌面集成可交互演示🤖 Generated with Claude Code