winui-svelte 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (737) hide show
  1. package/API.md +955 -22
  2. package/README.md +25 -5
  3. package/dist/app/activate.d.ts.map +1 -1
  4. package/dist/app/activate.js +3 -0
  5. package/dist/app/activate.js.map +1 -1
  6. package/dist/app/activation/index.d.ts +3 -0
  7. package/dist/app/activation/index.d.ts.map +1 -1
  8. package/dist/app/activation/index.js +2 -0
  9. package/dist/app/activation/index.js.map +1 -1
  10. package/dist/app/activation/login.d.ts +2 -1
  11. package/dist/app/activation/login.d.ts.map +1 -1
  12. package/dist/app/activation/login.js +2 -1
  13. package/dist/app/activation/login.js.map +1 -1
  14. package/dist/app/activation/native.js +1 -2
  15. package/dist/app/activation/native.js.map +1 -1
  16. package/dist/app/activation/packaged.d.ts +49 -0
  17. package/dist/app/activation/packaged.d.ts.map +1 -0
  18. package/dist/app/activation/packaged.js +90 -0
  19. package/dist/app/activation/packaged.js.map +1 -0
  20. package/dist/app/activation/receive.d.ts +11 -2
  21. package/dist/app/activation/receive.d.ts.map +1 -1
  22. package/dist/app/activation/receive.js +11 -4
  23. package/dist/app/activation/receive.js.map +1 -1
  24. package/dist/app/activation/registration.d.ts +3 -3
  25. package/dist/app/activation/registration.js +7 -7
  26. package/dist/app/activation/registration.js.map +1 -1
  27. package/dist/app/activation/scheme.d.ts +10 -0
  28. package/dist/app/activation/scheme.d.ts.map +1 -1
  29. package/dist/app/activation/scheme.js +17 -0
  30. package/dist/app/activation/scheme.js.map +1 -1
  31. package/dist/app/index.d.ts +4 -2
  32. package/dist/app/index.d.ts.map +1 -1
  33. package/dist/app/index.js +3 -1
  34. package/dist/app/index.js.map +1 -1
  35. package/dist/app/instance-running.d.ts +15 -0
  36. package/dist/app/instance-running.d.ts.map +1 -0
  37. package/dist/app/instance-running.js +20 -0
  38. package/dist/app/instance-running.js.map +1 -0
  39. package/dist/app/jump-list/native.d.ts.map +1 -1
  40. package/dist/app/jump-list/native.js +1 -2
  41. package/dist/app/jump-list/native.js.map +1 -1
  42. package/dist/app/launch-command.d.ts +11 -6
  43. package/dist/app/launch-command.d.ts.map +1 -1
  44. package/dist/app/launch-command.js +16 -5
  45. package/dist/app/launch-command.js.map +1 -1
  46. package/dist/app/native-messaging/browsers.d.ts +19 -0
  47. package/dist/app/native-messaging/browsers.d.ts.map +1 -0
  48. package/dist/app/native-messaging/browsers.js +17 -0
  49. package/dist/app/native-messaging/browsers.js.map +1 -0
  50. package/dist/app/native-messaging/index.d.ts +41 -0
  51. package/dist/app/native-messaging/index.d.ts.map +1 -0
  52. package/dist/app/native-messaging/index.js +84 -0
  53. package/dist/app/native-messaging/index.js.map +1 -0
  54. package/dist/app/native.d.ts +0 -6
  55. package/dist/app/native.d.ts.map +1 -1
  56. package/dist/app/native.js +1 -24
  57. package/dist/app/native.js.map +1 -1
  58. package/dist/app/notification-source.d.ts.map +1 -1
  59. package/dist/app/notification-source.js +1 -2
  60. package/dist/app/notification-source.js.map +1 -1
  61. package/dist/app/shell/native.js +1 -2
  62. package/dist/app/shell/native.js.map +1 -1
  63. package/dist/app/single-instance.d.ts +27 -1
  64. package/dist/app/single-instance.d.ts.map +1 -1
  65. package/dist/app/single-instance.js +32 -10
  66. package/dist/app/single-instance.js.map +1 -1
  67. package/dist/app/tray-instance.d.ts +4 -3
  68. package/dist/app/tray-instance.d.ts.map +1 -1
  69. package/dist/app/tray-instance.js +7 -5
  70. package/dist/app/tray-instance.js.map +1 -1
  71. package/dist/automation/backend.d.ts +51 -0
  72. package/dist/automation/backend.d.ts.map +1 -0
  73. package/dist/automation/backend.js +5 -0
  74. package/dist/automation/backend.js.map +1 -0
  75. package/dist/automation/client.d.ts +97 -0
  76. package/dist/automation/client.d.ts.map +1 -0
  77. package/dist/automation/client.js +203 -0
  78. package/dist/automation/client.js.map +1 -0
  79. package/dist/automation/ids.d.ts +90 -0
  80. package/dist/automation/ids.d.ts.map +1 -0
  81. package/dist/automation/ids.js +84 -0
  82. package/dist/automation/ids.js.map +1 -0
  83. package/dist/automation/index.d.ts +13 -0
  84. package/dist/automation/index.d.ts.map +1 -0
  85. package/dist/automation/index.js +8 -0
  86. package/dist/automation/index.js.map +1 -0
  87. package/dist/automation/native.d.ts +11 -0
  88. package/dist/automation/native.d.ts.map +1 -0
  89. package/dist/automation/native.js +594 -0
  90. package/dist/automation/native.js.map +1 -0
  91. package/dist/automation/text.d.ts +50 -0
  92. package/dist/automation/text.d.ts.map +1 -0
  93. package/dist/automation/text.js +110 -0
  94. package/dist/automation/text.js.map +1 -0
  95. package/dist/automation/with-client.d.ts +13 -0
  96. package/dist/automation/with-client.d.ts.map +1 -0
  97. package/dist/automation/with-client.js +19 -0
  98. package/dist/automation/with-client.js.map +1 -0
  99. package/dist/automation/worker-job.d.ts +32 -0
  100. package/dist/automation/worker-job.d.ts.map +1 -0
  101. package/dist/automation/worker-job.js +69 -0
  102. package/dist/automation/worker-job.js.map +1 -0
  103. package/dist/automation/worker.d.ts +44 -0
  104. package/dist/automation/worker.d.ts.map +1 -0
  105. package/dist/automation/worker.js +70 -0
  106. package/dist/automation/worker.js.map +1 -0
  107. package/dist/bindings/.dynwinrt-js-types +198 -0
  108. package/dist/bindings/.dynwinrt-managed +1 -1
  109. package/dist/bindings/index.d.ts +15 -0
  110. package/dist/bindings/index.js +20 -0
  111. package/dist/bindings/index.mjs +2902 -2882
  112. package/dist/bindings/index.proxy.js +10 -0
  113. package/dist/bindings/windows/application-model/activation/ActivationKind.d.ts +49 -0
  114. package/dist/bindings/windows/application-model/activation/ActivationKind.js +50 -0
  115. package/dist/bindings/windows/application-model/activation/ApplicationExecutionState.d.ts +9 -0
  116. package/dist/bindings/windows/application-model/activation/ApplicationExecutionState.js +10 -0
  117. package/dist/bindings/windows/application-model/activation/IActivatedEventArgs.d.ts +36 -0
  118. package/dist/bindings/windows/application-model/activation/IActivatedEventArgs.js +149 -0
  119. package/dist/bindings/windows/application-model/activation/IActivatedEventArgsWithUser.d.ts +28 -0
  120. package/dist/bindings/windows/application-model/activation/IActivatedEventArgsWithUser.js +119 -0
  121. package/dist/bindings/windows/application-model/activation/IApplicationViewActivatedEventArgs.d.ts +27 -0
  122. package/dist/bindings/windows/application-model/activation/IApplicationViewActivatedEventArgs.js +116 -0
  123. package/dist/bindings/windows/application-model/activation/IProtocolActivatedEventArgsWithCallerPackageFamilyNameAndData.d.ts +31 -0
  124. package/dist/bindings/windows/application-model/activation/IProtocolActivatedEventArgsWithCallerPackageFamilyNameAndData.js +131 -0
  125. package/dist/bindings/windows/application-model/activation/IViewSwitcherProvider.d.ts +28 -0
  126. package/dist/bindings/windows/application-model/activation/IViewSwitcherProvider.js +119 -0
  127. package/dist/bindings/windows/application-model/activation/ProtocolActivatedEventArgs.d.ts +25 -0
  128. package/dist/bindings/windows/application-model/activation/ProtocolActivatedEventArgs.js +166 -0
  129. package/dist/bindings/windows/application-model/activation/SplashScreen.d.ts +35 -0
  130. package/dist/bindings/windows/application-model/activation/SplashScreen.js +105 -0
  131. package/dist/bindings/windows/foundation/TypedEventHandler_WindowsApplicationModelActivationSplashScreen_Object_g7a7dbfa699cd28ff.d.ts +7 -0
  132. package/dist/bindings/windows/foundation/TypedEventHandler_WindowsApplicationModelActivationSplashScreen_Object_g7a7dbfa699cd28ff.js +7 -0
  133. package/dist/bindings/windows/ui/view-management/ActivationViewSwitcher.d.ts +12 -0
  134. package/dist/bindings/windows/ui/view-management/ActivationViewSwitcher.js +96 -0
  135. package/dist/chrome/context-menus/context-menu-schema.d.ts +4 -4
  136. package/dist/chrome/context-menus/context-menu-schema.d.ts.map +1 -1
  137. package/dist/chrome/context-menus/context-menu-schema.js +1 -7
  138. package/dist/chrome/context-menus/context-menu-schema.js.map +1 -1
  139. package/dist/chrome/notifications/notification-schema.d.ts +2 -2
  140. package/dist/chrome/parse-or-throw.d.ts +7 -0
  141. package/dist/chrome/parse-or-throw.d.ts.map +1 -0
  142. package/dist/chrome/parse-or-throw.js +9 -0
  143. package/dist/chrome/parse-or-throw.js.map +1 -0
  144. package/dist/chrome/permissions/permission-schema.d.ts.map +1 -1
  145. package/dist/chrome/permissions/permission-schema.js +1 -7
  146. package/dist/chrome/permissions/permission-schema.js.map +1 -1
  147. package/dist/chrome/windows/chrome-windows.d.ts.map +1 -1
  148. package/dist/chrome/windows/chrome-windows.js +1 -7
  149. package/dist/chrome/windows/chrome-windows.js.map +1 -1
  150. package/dist/components/hand-written/Window.svelte +2 -0
  151. package/dist/components/hand-written/items/keyed-rows.svelte.d.ts.map +1 -1
  152. package/dist/components/hand-written/items/keyed-rows.svelte.js +6 -0
  153. package/dist/components/hand-written/items/keyed-rows.svelte.js.map +1 -1
  154. package/dist/components/index.d.ts +1 -0
  155. package/dist/components/index.d.ts.map +1 -1
  156. package/dist/components/runtime.svelte.d.ts.map +1 -1
  157. package/dist/components/runtime.svelte.js +7 -0
  158. package/dist/components/runtime.svelte.js.map +1 -1
  159. package/dist/components/window-context.d.ts +14 -0
  160. package/dist/components/window-context.d.ts.map +1 -0
  161. package/dist/components/window-context.js +20 -0
  162. package/dist/components/window-context.js.map +1 -0
  163. package/dist/composition/expression.d.ts +1 -1
  164. package/dist/css/runtime/containers.d.ts.map +1 -1
  165. package/dist/css/runtime/containers.js +1 -17
  166. package/dist/css/runtime/containers.js.map +1 -1
  167. package/dist/css/runtime/native.d.ts.map +1 -1
  168. package/dist/css/runtime/native.js +40 -20
  169. package/dist/css/runtime/native.js.map +1 -1
  170. package/dist/css/translate/property-kit.d.ts +9 -0
  171. package/dist/css/translate/property-kit.d.ts.map +1 -1
  172. package/dist/css/translate/property-kit.js.map +1 -1
  173. package/dist/css/translate/transition-properties.d.ts +1 -1
  174. package/dist/css/translate/transition-properties.d.ts.map +1 -1
  175. package/dist/css/translate/transition-properties.js +32 -5
  176. package/dist/css/translate/transition-properties.js.map +1 -1
  177. package/dist/data-transfer/data-transfer.d.ts +3 -3
  178. package/dist/data-transfer/data-transfer.d.ts.map +1 -1
  179. package/dist/data-transfer/data-transfer.js.map +1 -1
  180. package/dist/data-transfer/drag-effects.d.ts +25 -2
  181. package/dist/data-transfer/drag-effects.d.ts.map +1 -1
  182. package/dist/data-transfer/drag-effects.js +27 -2
  183. package/dist/data-transfer/drag-effects.js.map +1 -1
  184. package/dist/data-transfer/drag-helper.d.ts +50 -0
  185. package/dist/data-transfer/drag-helper.d.ts.map +1 -0
  186. package/dist/data-transfer/drag-helper.js +156 -0
  187. package/dist/data-transfer/drag-helper.js.map +1 -0
  188. package/dist/data-transfer/drop-target.d.ts +6 -5
  189. package/dist/data-transfer/drop-target.d.ts.map +1 -1
  190. package/dist/data-transfer/drop-target.js +68 -20
  191. package/dist/data-transfer/drop-target.js.map +1 -1
  192. package/dist/data-transfer/index.d.ts +1 -0
  193. package/dist/data-transfer/index.d.ts.map +1 -1
  194. package/dist/data-transfer/index.js.map +1 -1
  195. package/dist/data-transfer/launcher.d.ts +4 -3
  196. package/dist/data-transfer/launcher.d.ts.map +1 -1
  197. package/dist/data-transfer/launcher.js +58 -9
  198. package/dist/data-transfer/launcher.js.map +1 -1
  199. package/dist/data-transfer/native.d.ts +66 -0
  200. package/dist/data-transfer/native.d.ts.map +1 -0
  201. package/dist/data-transfer/native.js +148 -0
  202. package/dist/data-transfer/native.js.map +1 -0
  203. package/dist/data-transfer/ole-data-object.d.ts +62 -0
  204. package/dist/data-transfer/ole-data-object.d.ts.map +1 -0
  205. package/dist/data-transfer/ole-data-object.js +162 -0
  206. package/dist/data-transfer/ole-data-object.js.map +1 -0
  207. package/dist/data-transfer/ole-drop-target.d.ts +54 -0
  208. package/dist/data-transfer/ole-drop-target.d.ts.map +1 -0
  209. package/dist/data-transfer/ole-drop-target.js +192 -0
  210. package/dist/data-transfer/ole-drop-target.js.map +1 -0
  211. package/dist/data-transfer/share-interop.d.ts.map +1 -1
  212. package/dist/data-transfer/share-interop.js +1 -1
  213. package/dist/data-transfer/share-interop.js.map +1 -1
  214. package/dist/data-transfer/shell-items.d.ts +10 -0
  215. package/dist/data-transfer/shell-items.d.ts.map +1 -0
  216. package/dist/data-transfer/shell-items.js +67 -0
  217. package/dist/data-transfer/shell-items.js.map +1 -0
  218. package/dist/data-transfer/window-drop.d.ts +35 -0
  219. package/dist/data-transfer/window-drop.d.ts.map +1 -0
  220. package/dist/data-transfer/window-drop.js +311 -0
  221. package/dist/data-transfer/window-drop.js.map +1 -0
  222. package/dist/devices/native.js +1 -2
  223. package/dist/devices/native.js.map +1 -1
  224. package/dist/downloads/chrome-downloads.d.ts +8 -0
  225. package/dist/downloads/chrome-downloads.d.ts.map +1 -1
  226. package/dist/downloads/chrome-downloads.js +35 -6
  227. package/dist/downloads/chrome-downloads.js.map +1 -1
  228. package/dist/downloads/download-record.d.ts +3 -2
  229. package/dist/downloads/download-record.d.ts.map +1 -1
  230. package/dist/downloads/download-record.js.map +1 -1
  231. package/dist/downloads/download-transfer.d.ts.map +1 -1
  232. package/dist/downloads/download-transfer.js +3 -3
  233. package/dist/downloads/download-transfer.js.map +1 -1
  234. package/dist/downloads/download-types.d.ts +3 -1
  235. package/dist/downloads/download-types.d.ts.map +1 -1
  236. package/dist/downloads/download-types.js.map +1 -1
  237. package/dist/downloads/fetch-to-file.d.ts +11 -6
  238. package/dist/downloads/fetch-to-file.d.ts.map +1 -1
  239. package/dist/downloads/fetch-to-file.js +45 -16
  240. package/dist/downloads/fetch-to-file.js.map +1 -1
  241. package/dist/downloads/taskbar-progress.d.ts +3 -18
  242. package/dist/downloads/taskbar-progress.d.ts.map +1 -1
  243. package/dist/downloads/taskbar-progress.js +1 -38
  244. package/dist/downloads/taskbar-progress.js.map +1 -1
  245. package/dist/enums.d.ts +4 -0
  246. package/dist/enums.d.ts.map +1 -1
  247. package/dist/enums.js +4 -0
  248. package/dist/enums.js.map +1 -1
  249. package/dist/forms/form-field-props.d.ts +2 -2
  250. package/dist/input/index.d.ts +2 -0
  251. package/dist/input/index.d.ts.map +1 -1
  252. package/dist/input/index.js +1 -0
  253. package/dist/input/index.js.map +1 -1
  254. package/dist/input/modifier-keys.d.ts +24 -0
  255. package/dist/input/modifier-keys.d.ts.map +1 -0
  256. package/dist/input/modifier-keys.js +20 -0
  257. package/dist/input/modifier-keys.js.map +1 -0
  258. package/dist/media/pixel-buffer.d.ts.map +1 -1
  259. package/dist/media/pixel-buffer.js +1 -1
  260. package/dist/media/pixel-buffer.js.map +1 -1
  261. package/dist/messaging/web-view2/core.d.ts +56 -0
  262. package/dist/messaging/web-view2/core.d.ts.map +1 -1
  263. package/dist/messaging/web-view2/core.js +6 -0
  264. package/dist/messaging/web-view2/core.js.map +1 -1
  265. package/dist/messaging/web-view2/environment.d.ts +41 -0
  266. package/dist/messaging/web-view2/environment.d.ts.map +1 -0
  267. package/dist/messaging/web-view2/environment.js +91 -0
  268. package/dist/messaging/web-view2/environment.js.map +1 -0
  269. package/dist/messaging/web-view2/index.d.ts +9 -1
  270. package/dist/messaging/web-view2/index.d.ts.map +1 -1
  271. package/dist/messaging/web-view2/index.js +5 -0
  272. package/dist/messaging/web-view2/index.js.map +1 -1
  273. package/dist/messaging/web-view2/input.d.ts +68 -0
  274. package/dist/messaging/web-view2/input.d.ts.map +1 -0
  275. package/dist/messaging/web-view2/input.js +108 -0
  276. package/dist/messaging/web-view2/input.js.map +1 -0
  277. package/dist/messaging/web-view2/protocol.d.ts +24 -0
  278. package/dist/messaging/web-view2/protocol.d.ts.map +1 -0
  279. package/dist/messaging/web-view2/protocol.js +31 -0
  280. package/dist/messaging/web-view2/protocol.js.map +1 -0
  281. package/dist/messaging/web-view2/recovery.d.ts +65 -0
  282. package/dist/messaging/web-view2/recovery.d.ts.map +1 -0
  283. package/dist/messaging/web-view2/recovery.js +138 -0
  284. package/dist/messaging/web-view2/recovery.js.map +1 -0
  285. package/dist/messaging/web-view2/requests.d.ts +88 -0
  286. package/dist/messaging/web-view2/requests.d.ts.map +1 -0
  287. package/dist/messaging/web-view2/requests.js +169 -0
  288. package/dist/messaging/web-view2/requests.js.map +1 -0
  289. package/dist/messaging/web-view2/transport.d.ts.map +1 -1
  290. package/dist/messaging/web-view2/transport.js +1 -4
  291. package/dist/messaging/web-view2/transport.js.map +1 -1
  292. package/dist/native-identity.d.ts +10 -0
  293. package/dist/native-identity.d.ts.map +1 -0
  294. package/dist/native-identity.js +20 -0
  295. package/dist/native-identity.js.map +1 -0
  296. package/dist/progress/TaskbarProgress.d.svelte.ts +6 -0
  297. package/dist/progress/TaskbarProgress.svelte +32 -0
  298. package/dist/progress/aggregate.d.ts +23 -0
  299. package/dist/progress/aggregate.d.ts.map +1 -0
  300. package/dist/progress/aggregate.js +59 -0
  301. package/dist/progress/aggregate.js.map +1 -0
  302. package/dist/progress/core.d.ts +14 -0
  303. package/dist/progress/core.d.ts.map +1 -0
  304. package/dist/progress/core.js +8 -0
  305. package/dist/progress/core.js.map +1 -0
  306. package/dist/progress/index.d.ts +5 -0
  307. package/dist/progress/index.d.ts.map +1 -0
  308. package/dist/progress/index.js +4 -0
  309. package/dist/progress/index.js.map +1 -0
  310. package/dist/progress/progress-event.d.ts +18 -0
  311. package/dist/progress/progress-event.d.ts.map +1 -0
  312. package/dist/progress/progress-event.js +19 -0
  313. package/dist/progress/progress-event.js.map +1 -0
  314. package/dist/progress/progress-operation.d.ts +163 -0
  315. package/dist/progress/progress-operation.d.ts.map +1 -0
  316. package/dist/progress/progress-operation.js +356 -0
  317. package/dist/progress/progress-operation.js.map +1 -0
  318. package/dist/progress/progress-registry.d.ts +89 -0
  319. package/dist/progress/progress-registry.d.ts.map +1 -0
  320. package/dist/progress/progress-registry.js +187 -0
  321. package/dist/progress/progress-registry.js.map +1 -0
  322. package/dist/progress/progress-source.d.ts +46 -0
  323. package/dist/progress/progress-source.d.ts.map +1 -0
  324. package/dist/progress/progress-source.js +31 -0
  325. package/dist/progress/progress-source.js.map +1 -0
  326. package/dist/progress/progress-state.d.ts +54 -0
  327. package/dist/progress/progress-state.d.ts.map +1 -0
  328. package/dist/progress/progress-state.js +35 -0
  329. package/dist/progress/progress-state.js.map +1 -0
  330. package/dist/progress/progress-text.d.ts +10 -0
  331. package/dist/progress/progress-text.d.ts.map +1 -0
  332. package/dist/progress/progress-text.js +23 -0
  333. package/dist/progress/progress-text.js.map +1 -0
  334. package/dist/progress/scoped-source.d.ts +31 -0
  335. package/dist/progress/scoped-source.d.ts.map +1 -0
  336. package/dist/progress/scoped-source.js +46 -0
  337. package/dist/progress/scoped-source.js.map +1 -0
  338. package/dist/progress/taskbar-progress-props.d.ts +15 -0
  339. package/dist/progress/taskbar-progress-props.d.ts.map +1 -0
  340. package/dist/progress/taskbar-progress-props.js +2 -0
  341. package/dist/progress/taskbar-progress-props.js.map +1 -0
  342. package/dist/progress/taskbar-progress.d.ts +44 -0
  343. package/dist/progress/taskbar-progress.d.ts.map +1 -0
  344. package/dist/progress/taskbar-progress.js +62 -0
  345. package/dist/progress/taskbar-progress.js.map +1 -0
  346. package/dist/progress/track-operation.d.ts +36 -0
  347. package/dist/progress/track-operation.d.ts.map +1 -0
  348. package/dist/progress/track-operation.js +53 -0
  349. package/dist/progress/track-operation.js.map +1 -0
  350. package/dist/renderer/host/host.d.ts.map +1 -1
  351. package/dist/renderer/host/host.js +33 -16
  352. package/dist/renderer/host/host.js.map +1 -1
  353. package/dist/renderer/host/structure-sync.d.ts +9 -0
  354. package/dist/renderer/host/structure-sync.d.ts.map +1 -0
  355. package/dist/renderer/host/structure-sync.js +24 -0
  356. package/dist/renderer/host/structure-sync.js.map +1 -0
  357. package/dist/security/data-protection-error.d.ts +14 -0
  358. package/dist/security/data-protection-error.d.ts.map +1 -0
  359. package/dist/security/data-protection-error.js +15 -0
  360. package/dist/security/data-protection-error.js.map +1 -0
  361. package/dist/security/index.d.ts +48 -0
  362. package/dist/security/index.d.ts.map +1 -0
  363. package/dist/security/index.js +32 -0
  364. package/dist/security/index.js.map +1 -0
  365. package/dist/security/native.d.ts +43 -0
  366. package/dist/security/native.d.ts.map +1 -0
  367. package/dist/security/native.js +170 -0
  368. package/dist/security/native.js.map +1 -0
  369. package/dist/security/protection-scope.d.ts +13 -0
  370. package/dist/security/protection-scope.d.ts.map +1 -0
  371. package/dist/security/protection-scope.js +11 -0
  372. package/dist/security/protection-scope.js.map +1 -0
  373. package/dist/store/states.d.ts +2 -2
  374. package/dist/store/windows-identity.d.ts +2 -6
  375. package/dist/store/windows-identity.d.ts.map +1 -1
  376. package/dist/store/windows-identity.js +2 -29
  377. package/dist/store/windows-identity.js.map +1 -1
  378. package/dist/store/windows-packages.d.ts +2 -2
  379. package/dist/store/windows-store.d.ts +2 -2
  380. package/dist/tray/click-detector.d.ts.map +1 -1
  381. package/dist/tray/click-detector.js.map +1 -1
  382. package/dist/tray/flyout-model.d.ts +4 -3
  383. package/dist/tray/flyout-model.d.ts.map +1 -1
  384. package/dist/tray/flyout-model.js +12 -2
  385. package/dist/tray/flyout-model.js.map +1 -1
  386. package/dist/tray/menu/icon.d.ts +17 -0
  387. package/dist/tray/menu/icon.d.ts.map +1 -0
  388. package/dist/tray/menu/icon.js +31 -0
  389. package/dist/tray/menu/icon.js.map +1 -0
  390. package/dist/tray/menu/index.d.ts +1 -1
  391. package/dist/tray/menu/index.d.ts.map +1 -1
  392. package/dist/tray/menu/index.js.map +1 -1
  393. package/dist/tray/menu/types.d.ts +23 -6
  394. package/dist/tray/menu/types.d.ts.map +1 -1
  395. package/dist/tray/menu/types.js.map +1 -1
  396. package/dist/tray/menu-svelte/TrayMenuOperations.d.svelte.ts +6 -0
  397. package/dist/tray/menu-svelte/TrayMenuOperations.svelte +33 -0
  398. package/dist/tray/menu-svelte/TrayMenuProgress.d.svelte.ts +6 -0
  399. package/dist/tray/menu-svelte/TrayMenuProgress.svelte +28 -0
  400. package/dist/tray/menu-svelte/index.d.ts +3 -1
  401. package/dist/tray/menu-svelte/index.d.ts.map +1 -1
  402. package/dist/tray/menu-svelte/index.js +2 -0
  403. package/dist/tray/menu-svelte/index.js.map +1 -1
  404. package/dist/tray/menu-svelte/menu-node.d.ts +9 -9
  405. package/dist/tray/menu-svelte/menu-props.d.ts +16 -0
  406. package/dist/tray/menu-svelte/menu-props.d.ts.map +1 -1
  407. package/dist/tray/menu-svelte/operation-ids.d.ts +8 -0
  408. package/dist/tray/menu-svelte/operation-ids.d.ts.map +1 -0
  409. package/dist/tray/menu-svelte/operation-ids.js +20 -0
  410. package/dist/tray/menu-svelte/operation-ids.js.map +1 -0
  411. package/dist/tray/native.d.ts +15 -5
  412. package/dist/tray/native.d.ts.map +1 -1
  413. package/dist/tray/native.js +27 -45
  414. package/dist/tray/native.js.map +1 -1
  415. package/dist/tray/personalize.d.ts +18 -0
  416. package/dist/tray/personalize.d.ts.map +1 -0
  417. package/dist/tray/personalize.js +42 -0
  418. package/dist/tray/personalize.js.map +1 -0
  419. package/dist/tray/pointer-share.d.ts +27 -0
  420. package/dist/tray/pointer-share.d.ts.map +1 -0
  421. package/dist/tray/pointer-share.js +61 -0
  422. package/dist/tray/pointer-share.js.map +1 -0
  423. package/dist/tray/standalone/icon-raster.d.ts +72 -0
  424. package/dist/tray/standalone/icon-raster.d.ts.map +1 -0
  425. package/dist/tray/standalone/icon-raster.js +161 -0
  426. package/dist/tray/standalone/icon-raster.js.map +1 -0
  427. package/dist/tray/standalone/index.d.ts +4 -2
  428. package/dist/tray/standalone/index.d.ts.map +1 -1
  429. package/dist/tray/standalone/index.js +2 -0
  430. package/dist/tray/standalone/index.js.map +1 -1
  431. package/dist/tray/standalone/menu-icons.d.ts +9 -0
  432. package/dist/tray/standalone/menu-icons.d.ts.map +1 -0
  433. package/dist/tray/standalone/menu-icons.js +280 -0
  434. package/dist/tray/standalone/menu-icons.js.map +1 -0
  435. package/dist/tray/standalone/menu-theme.d.ts +38 -0
  436. package/dist/tray/standalone/menu-theme.d.ts.map +1 -0
  437. package/dist/tray/standalone/menu-theme.js +74 -0
  438. package/dist/tray/standalone/menu-theme.js.map +1 -0
  439. package/dist/tray/standalone/native.d.ts +24 -7
  440. package/dist/tray/standalone/native.d.ts.map +1 -1
  441. package/dist/tray/standalone/native.js +63 -16
  442. package/dist/tray/standalone/native.js.map +1 -1
  443. package/dist/tray/standalone/standalone-tray.d.ts +17 -2
  444. package/dist/tray/standalone/standalone-tray.d.ts.map +1 -1
  445. package/dist/tray/standalone/standalone-tray.js +34 -2
  446. package/dist/tray/standalone/standalone-tray.js.map +1 -1
  447. package/dist/tray/themed-icon.d.ts.map +1 -1
  448. package/dist/tray/themed-icon.js +4 -28
  449. package/dist/tray/themed-icon.js.map +1 -1
  450. package/dist/tray/tray-core.d.ts.map +1 -1
  451. package/dist/tray/tray-core.js +6 -1
  452. package/dist/tray/tray-core.js.map +1 -1
  453. package/dist/tray/tray-extras.d.ts +26 -2
  454. package/dist/tray/tray-extras.d.ts.map +1 -1
  455. package/dist/tray/tray-manifest.d.ts +44 -4
  456. package/dist/tray/tray-manifest.d.ts.map +1 -1
  457. package/dist/tray/tray-manifest.js +48 -4
  458. package/dist/tray/tray-manifest.js.map +1 -1
  459. package/dist/vite/entrypoints/build-tray.d.ts +3 -1
  460. package/dist/vite/entrypoints/build-tray.d.ts.map +1 -1
  461. package/dist/vite/entrypoints/build-tray.js +22 -16
  462. package/dist/vite/entrypoints/build-tray.js.map +1 -1
  463. package/dist/vite/entrypoints/extract-tray.d.ts +7 -6
  464. package/dist/vite/entrypoints/extract-tray.d.ts.map +1 -1
  465. package/dist/vite/entrypoints/extract-tray.js +35 -15
  466. package/dist/vite/entrypoints/extract-tray.js.map +1 -1
  467. package/dist/vite/entrypoints/tray-module.d.ts +2 -1
  468. package/dist/vite/entrypoints/tray-module.d.ts.map +1 -1
  469. package/dist/vite/entrypoints/tray-module.js +8 -4
  470. package/dist/vite/entrypoints/tray-module.js.map +1 -1
  471. package/dist/web-apis/eye-dropper.d.ts.map +1 -1
  472. package/dist/web-apis/eye-dropper.js +8 -5
  473. package/dist/web-apis/eye-dropper.js.map +1 -1
  474. package/dist/web-apis/file-read.d.ts +14 -0
  475. package/dist/web-apis/file-read.d.ts.map +1 -0
  476. package/dist/web-apis/file-read.js +37 -0
  477. package/dist/web-apis/file-read.js.map +1 -0
  478. package/dist/web-apis/file-system.d.ts +9 -0
  479. package/dist/web-apis/file-system.d.ts.map +1 -1
  480. package/dist/web-apis/file-system.js +24 -0
  481. package/dist/web-apis/file-system.js.map +1 -1
  482. package/dist/web-apis/media-devices-source.d.ts +1 -1
  483. package/dist/web-apis/native.d.ts +0 -7
  484. package/dist/web-apis/native.d.ts.map +1 -1
  485. package/dist/web-apis/native.js +0 -19
  486. package/dist/web-apis/native.js.map +1 -1
  487. package/dist/win2d/activation-failure.d.ts +10 -0
  488. package/dist/win2d/activation-failure.d.ts.map +1 -0
  489. package/dist/win2d/activation-failure.js +30 -0
  490. package/dist/win2d/activation-failure.js.map +1 -0
  491. package/dist/win2d/element-lifecycle.d.ts.map +1 -1
  492. package/dist/win2d/element-lifecycle.js +6 -1
  493. package/dist/win2d/element-lifecycle.js.map +1 -1
  494. package/dist/win2d/manifest.d.ts +29 -0
  495. package/dist/win2d/manifest.d.ts.map +1 -0
  496. package/dist/win2d/manifest.js +67 -0
  497. package/dist/win2d/manifest.js.map +1 -0
  498. package/dist/win32/index.d.ts +3 -0
  499. package/dist/win32/index.d.ts.map +1 -0
  500. package/dist/win32/index.js +11 -0
  501. package/dist/win32/index.js.map +1 -0
  502. package/dist/win32-calls.d.ts +6 -0
  503. package/dist/win32-calls.d.ts.map +1 -1
  504. package/dist/win32-calls.js +6 -1
  505. package/dist/win32-calls.js.map +1 -1
  506. package/dist/win32-foreground.d.ts +34 -0
  507. package/dist/win32-foreground.d.ts.map +1 -0
  508. package/dist/win32-foreground.js +91 -0
  509. package/dist/win32-foreground.js.map +1 -0
  510. package/dist/win32-icons.d.ts.map +1 -1
  511. package/dist/win32-icons.js +1 -2
  512. package/dist/win32-icons.js.map +1 -1
  513. package/dist/win32-key-state.d.ts +31 -0
  514. package/dist/win32-key-state.d.ts.map +1 -0
  515. package/dist/win32-key-state.js +41 -0
  516. package/dist/win32-key-state.js.map +1 -0
  517. package/dist/window/anchor.d.ts +15 -0
  518. package/dist/window/anchor.d.ts.map +1 -1
  519. package/dist/window/anchor.js +23 -0
  520. package/dist/window/anchor.js.map +1 -1
  521. package/dist/window/apply-frame.d.ts +4 -2
  522. package/dist/window/apply-frame.d.ts.map +1 -1
  523. package/dist/window/apply-frame.js +2 -3
  524. package/dist/window/apply-frame.js.map +1 -1
  525. package/dist/window/bootstrap-core.d.ts +69 -0
  526. package/dist/window/bootstrap-core.d.ts.map +1 -0
  527. package/dist/window/bootstrap-core.js +93 -0
  528. package/dist/window/bootstrap-core.js.map +1 -0
  529. package/dist/window/bootstrap-mode.d.ts +21 -0
  530. package/dist/window/bootstrap-mode.d.ts.map +1 -0
  531. package/dist/window/bootstrap-mode.js +17 -0
  532. package/dist/window/bootstrap-mode.js.map +1 -0
  533. package/dist/window/bootstrap.d.ts +12 -28
  534. package/dist/window/bootstrap.d.ts.map +1 -1
  535. package/dist/window/bootstrap.js +18 -66
  536. package/dist/window/bootstrap.js.map +1 -1
  537. package/dist/window/cover.d.ts +43 -0
  538. package/dist/window/cover.d.ts.map +1 -0
  539. package/dist/window/cover.js +64 -0
  540. package/dist/window/cover.js.map +1 -0
  541. package/dist/window/create-window.d.ts +1 -1
  542. package/dist/window/create-window.d.ts.map +1 -1
  543. package/dist/window/create-window.js +2 -0
  544. package/dist/window/create-window.js.map +1 -1
  545. package/dist/window/dpi-awareness.d.ts +71 -0
  546. package/dist/window/dpi-awareness.d.ts.map +1 -0
  547. package/dist/window/dpi-awareness.js +127 -0
  548. package/dist/window/dpi-awareness.js.map +1 -0
  549. package/dist/window/foreground-filter.d.ts +71 -0
  550. package/dist/window/foreground-filter.d.ts.map +1 -0
  551. package/dist/window/foreground-filter.js +108 -0
  552. package/dist/window/foreground-filter.js.map +1 -0
  553. package/dist/window/foreground-native.d.ts +25 -0
  554. package/dist/window/foreground-native.d.ts.map +1 -0
  555. package/dist/window/foreground-native.js +86 -0
  556. package/dist/window/foreground-native.js.map +1 -0
  557. package/dist/window/foreground.d.ts +49 -0
  558. package/dist/window/foreground.d.ts.map +1 -0
  559. package/dist/window/foreground.js +78 -0
  560. package/dist/window/foreground.js.map +1 -0
  561. package/dist/window/index.d.ts +2 -0
  562. package/dist/window/index.d.ts.map +1 -1
  563. package/dist/window/index.js +1 -0
  564. package/dist/window/index.js.map +1 -1
  565. package/dist/window/native.d.ts.map +1 -1
  566. package/dist/window/native.js +1 -2
  567. package/dist/window/native.js.map +1 -1
  568. package/dist/window/package-identity.d.ts +17 -0
  569. package/dist/window/package-identity.d.ts.map +1 -0
  570. package/dist/window/package-identity.js +97 -0
  571. package/dist/window/package-identity.js.map +1 -0
  572. package/dist/window/system-dispatcher-queue.d.ts.map +1 -1
  573. package/dist/window/system-dispatcher-queue.js +1 -2
  574. package/dist/window/system-dispatcher-queue.js.map +1 -1
  575. package/dist/window/taskbar-calls.d.ts +1 -1
  576. package/dist/window/taskbar-native.d.ts.map +1 -1
  577. package/dist/window/taskbar-native.js +1 -2
  578. package/dist/window/taskbar-native.js.map +1 -1
  579. package/dist/window/window-handle.d.ts +25 -1
  580. package/dist/window/window-handle.d.ts.map +1 -1
  581. package/dist/window/window-handle.js +27 -1
  582. package/dist/window/window-handle.js.map +1 -1
  583. package/dist/window/window-host.svelte.d.ts +11 -2
  584. package/dist/window/window-host.svelte.d.ts.map +1 -1
  585. package/dist/window/window-host.svelte.js +38 -4
  586. package/dist/window/window-host.svelte.js.map +1 -1
  587. package/package.json +43 -4
  588. package/src/app/activate.ts +3 -0
  589. package/src/app/activation/index.ts +3 -0
  590. package/src/app/activation/login.ts +2 -1
  591. package/src/app/activation/native.ts +1 -1
  592. package/src/app/activation/packaged.ts +118 -0
  593. package/src/app/activation/receive.ts +24 -4
  594. package/src/app/activation/registration.ts +7 -7
  595. package/src/app/activation/scheme.ts +19 -0
  596. package/src/app/index.ts +4 -2
  597. package/src/app/instance-running.ts +22 -0
  598. package/src/app/jump-list/native.ts +1 -2
  599. package/src/app/launch-command.ts +19 -5
  600. package/src/app/native-messaging/browsers.ts +21 -0
  601. package/src/app/native-messaging/index.ts +124 -0
  602. package/src/app/native.ts +1 -32
  603. package/src/app/notification-source.ts +1 -3
  604. package/src/app/shell/native.ts +1 -1
  605. package/src/app/single-instance.ts +34 -10
  606. package/src/app/tray-instance.ts +7 -5
  607. package/src/automation/backend.ts +56 -0
  608. package/src/automation/client.ts +327 -0
  609. package/src/automation/ids.ts +97 -0
  610. package/src/automation/index.ts +23 -0
  611. package/src/automation/native.ts +688 -0
  612. package/src/automation/text.ts +174 -0
  613. package/src/automation/with-client.ts +20 -0
  614. package/src/automation/worker-job.ts +97 -0
  615. package/src/automation/worker.ts +116 -0
  616. package/src/chrome/context-menus/context-menu-schema.ts +1 -12
  617. package/src/chrome/parse-or-throw.ts +14 -0
  618. package/src/chrome/permissions/permission-schema.ts +1 -12
  619. package/src/chrome/windows/chrome-windows.ts +1 -13
  620. package/src/components/hand-written/items/keyed-rows.svelte.ts +6 -0
  621. package/src/components/index.ts +1 -0
  622. package/src/components/runtime.svelte.ts +8 -0
  623. package/src/components/window-context.ts +23 -0
  624. package/src/css/runtime/containers.ts +1 -20
  625. package/src/css/runtime/native.ts +46 -21
  626. package/src/css/translate/property-kit.ts +9 -0
  627. package/src/css/translate/transition-properties.ts +44 -10
  628. package/src/data-transfer/data-transfer.ts +3 -3
  629. package/src/data-transfer/drag-effects.ts +48 -4
  630. package/src/data-transfer/drag-helper.ts +216 -0
  631. package/src/data-transfer/drop-target.ts +90 -26
  632. package/src/data-transfer/index.ts +1 -0
  633. package/src/data-transfer/launcher.ts +65 -9
  634. package/src/data-transfer/native.ts +184 -0
  635. package/src/data-transfer/ole-data-object.ts +200 -0
  636. package/src/data-transfer/ole-drop-target.ts +263 -0
  637. package/src/data-transfer/share-interop.ts +1 -1
  638. package/src/data-transfer/shell-items.ts +81 -0
  639. package/src/data-transfer/window-drop.ts +411 -0
  640. package/src/devices/native.ts +1 -1
  641. package/src/downloads/chrome-downloads.ts +46 -6
  642. package/src/downloads/download-record.ts +3 -2
  643. package/src/downloads/download-transfer.ts +3 -3
  644. package/src/downloads/download-types.ts +3 -0
  645. package/src/downloads/fetch-to-file.ts +47 -17
  646. package/src/downloads/taskbar-progress.ts +3 -49
  647. package/src/enums.ts +4 -0
  648. package/src/input/index.ts +2 -0
  649. package/src/input/modifier-keys.ts +30 -0
  650. package/src/media/pixel-buffer.ts +1 -1
  651. package/src/messaging/web-view2/core.ts +64 -0
  652. package/src/messaging/web-view2/environment.ts +131 -0
  653. package/src/messaging/web-view2/index.ts +11 -0
  654. package/src/messaging/web-view2/input.ts +154 -0
  655. package/src/messaging/web-view2/protocol.ts +41 -0
  656. package/src/messaging/web-view2/recovery.ts +177 -0
  657. package/src/messaging/web-view2/requests.ts +238 -0
  658. package/src/messaging/web-view2/transport.ts +1 -5
  659. package/src/native-identity.ts +22 -0
  660. package/src/progress/TaskbarProgress.d.svelte.ts +6 -0
  661. package/src/progress/aggregate.ts +68 -0
  662. package/src/progress/core.ts +13 -0
  663. package/src/progress/index.ts +4 -0
  664. package/src/progress/progress-event.ts +25 -0
  665. package/src/progress/progress-operation.ts +469 -0
  666. package/src/progress/progress-registry.ts +224 -0
  667. package/src/progress/progress-source.ts +66 -0
  668. package/src/progress/progress-state.ts +72 -0
  669. package/src/progress/progress-text.ts +27 -0
  670. package/src/progress/scoped-source.ts +56 -0
  671. package/src/progress/taskbar-progress-props.ts +18 -0
  672. package/src/progress/taskbar-progress.ts +80 -0
  673. package/src/progress/track-operation.ts +81 -0
  674. package/src/renderer/host/host.ts +39 -17
  675. package/src/renderer/host/structure-sync.ts +25 -0
  676. package/src/security/data-protection-error.ts +18 -0
  677. package/src/security/index.ts +57 -0
  678. package/src/security/native.ts +234 -0
  679. package/src/security/protection-scope.ts +13 -0
  680. package/src/store/windows-identity.ts +3 -35
  681. package/src/tray/click-detector.ts +6 -7
  682. package/src/tray/flyout-model.ts +14 -3
  683. package/src/tray/menu/icon.ts +40 -0
  684. package/src/tray/menu/index.ts +3 -0
  685. package/src/tray/menu/types.ts +27 -6
  686. package/src/tray/menu-svelte/TrayMenuOperations.d.svelte.ts +6 -0
  687. package/src/tray/menu-svelte/TrayMenuProgress.d.svelte.ts +6 -0
  688. package/src/tray/menu-svelte/index.ts +4 -0
  689. package/src/tray/menu-svelte/menu-props.ts +20 -0
  690. package/src/tray/menu-svelte/operation-ids.ts +21 -0
  691. package/src/tray/native.ts +44 -49
  692. package/src/tray/personalize.ts +57 -0
  693. package/src/tray/pointer-share.ts +71 -0
  694. package/src/tray/standalone/icon-raster.ts +208 -0
  695. package/src/tray/standalone/index.ts +5 -1
  696. package/src/tray/standalone/menu-icons.ts +317 -0
  697. package/src/tray/standalone/menu-theme.ts +90 -0
  698. package/src/tray/standalone/native.ts +83 -16
  699. package/src/tray/standalone/standalone-tray.ts +68 -5
  700. package/src/tray/themed-icon.ts +4 -36
  701. package/src/tray/tray-core.ts +7 -1
  702. package/src/tray/tray-extras.ts +31 -2
  703. package/src/tray/tray-manifest.ts +53 -4
  704. package/src/vite/entrypoints/build-tray.ts +23 -16
  705. package/src/vite/entrypoints/extract-tray.ts +41 -15
  706. package/src/vite/entrypoints/tray-module.ts +8 -4
  707. package/src/web-apis/eye-dropper.ts +9 -5
  708. package/src/web-apis/file-read.ts +43 -0
  709. package/src/web-apis/file-system.ts +33 -0
  710. package/src/web-apis/native.ts +0 -20
  711. package/src/win2d/activation-failure.ts +35 -0
  712. package/src/win2d/element-lifecycle.ts +6 -1
  713. package/src/win2d/manifest.ts +78 -0
  714. package/src/win32/index.ts +19 -0
  715. package/src/win32-calls.ts +8 -1
  716. package/src/win32-foreground.ts +100 -0
  717. package/src/win32-icons.ts +7 -2
  718. package/src/win32-key-state.ts +48 -0
  719. package/src/window/anchor.ts +28 -0
  720. package/src/window/apply-frame.ts +6 -4
  721. package/src/window/bootstrap-core.ts +165 -0
  722. package/src/window/bootstrap-mode.ts +23 -0
  723. package/src/window/bootstrap.ts +20 -103
  724. package/src/window/cover.ts +100 -0
  725. package/src/window/create-window.ts +4 -0
  726. package/src/window/dpi-awareness.ts +162 -0
  727. package/src/window/foreground-filter.ts +167 -0
  728. package/src/window/foreground-native.ts +91 -0
  729. package/src/window/foreground.ts +106 -0
  730. package/src/window/index.ts +2 -0
  731. package/src/window/native.ts +1 -1
  732. package/src/window/package-identity.ts +112 -0
  733. package/src/window/system-dispatcher-queue.ts +7 -2
  734. package/src/window/taskbar-native.ts +1 -2
  735. package/src/window/window-handle.ts +29 -1
  736. package/src/window/window-host.svelte.ts +59 -6
  737. package/web-types.json +11 -3
package/API.md CHANGED
@@ -35,16 +35,20 @@ monorepo needs no build step (the repository is a pnpm workspace, see
35
35
  | `winui-svelte/runner` | `src/vite/runner.ts` | `createWindowModuleRunner()`, the window thread's side of the module server |
36
36
  | `winui-svelte/compile` | `src/vite/compile.ts` | `compileSvelte()` for bundlers (esbuild) and tests, `WINUI_COMPILE_OPTIONS`, `withElementAnimation()` |
37
37
  | `winui-svelte/testing` | `src/vite/loader.ts` | `svelteHooks()`: Node module hooks that run `.svelte` files, with Svelte's runtime read through the package's edits (pure tests) |
38
- | `winui-svelte/bootstrap` | `src/window/bootstrap.ts` | `initWindowsAppSdk()`; imports nothing of WinRT, safe on the host's main thread |
38
+ | `winui-svelte/bootstrap` | `src/window/bootstrap.ts` | `initWindowsAppSdk()`, `hasPackageIdentity()`, `processDpiAwareness()`, `BootstrapMode`, `DpiAwareness`; imports nothing of WinRT, safe on the host's main thread |
39
39
  | `winui-svelte/thread` | `src/window/thread.ts` | `runOnUiThread()`; imports only dynwinrt, so the apartment comes first |
40
40
  | `winui-svelte/window` | `src/window/index.ts` | `runWindow()`, `exitApplication()`, `createWindow()`, `startTimer()`, `systemSettings()`, the picker options (see App services) |
41
- | `winui-svelte/app` | `src/app/index.ts` | `ensureSingleInstance()`, `notify()`, `activateInstance()`, `activateOrLaunch()`, `launchApp()`, `startTray()`, `relaunch()`, `restartAfterCrash()` (opt-in; see App lifecycle) |
41
+ | `winui-svelte/window/foreground` | `src/window/foreground.ts` | `trackForeground()`, `bringWindowToFront()`, `shouldRestore()` (opt-in; see Following the foreground app) |
42
+ | `winui-svelte/app` | `src/app/index.ts` | `ensureSingleInstance()`, `claimInstance()`, `isInstanceRunning()`, `notify()`, `activateInstance()`, `activateOrLaunch()`, `launchApp()`, `startTray()`, `relaunch()`, `restartAfterCrash()` (opt-in; see App lifecycle) |
42
43
  | `winui-svelte/app/shell` | `src/app/shell/index.ts` | `trash()`, `openWith()`, `createShortcut()`, `readShortcut()`, `registerAppPath()`, `ShellFailure` (opt-in; see Shell verbs) |
43
44
  | `winui-svelte/app/activation` | `src/app/activation/index.ts` | `installProtocolHandlers()`, `registerFileTypes()`, `launchAtLogin()`, `startActivation()`, `ActivationKind` (opt-in; see Activation) |
45
+ | `winui-svelte/app/native-messaging` | `src/app/native-messaging/index.ts` | `registerNativeMessagingHost()`, `unregisterNativeMessagingHost()`, `NativeMessagingBrowser` (opt-in; see Native messaging host) |
46
+ | `winui-svelte/win32` | `src/win32/index.ts` | `bindDll()`, `bind()`, `hasPackageIdentity()` and the memory helpers (opt-in escape hatch; see Win32 seam) |
44
47
  | `winui-svelte/app/jump-list` | `src/app/jump-list/index.ts` | `setJumpListTasks()`, `clearJumpList()` (opt-in; see Jump list tasks) |
45
48
  | `winui-svelte/data-transfer` | `src/data-transfer/index.ts` | `enableDragEvents()`, `dropzone`, `draggable`, `filePicker`, `pickFiles`, `pickSaveFile`, `clipboard`, `launchUri` / `launchFile` / `openFolder` / `revealInExplorer`, `share`, `NativeFile`, `DataTransfer`, `DragEvent` (opt-in; see Data transfer) |
46
49
  | `winui-svelte/incremental` | `src/incremental/index.ts` | `createIncrementalSource()`, `IncrementalSource`, `IncrementalStatus`, `IncrementalState` (opt-in; see Incremental loading) |
47
50
  | `winui-svelte/downloads` | `src/downloads/index.ts` | `Downloads` (`chrome.downloads`), `fetchToFile()`, `markOfTheWeb()`, `DownloadError` (opt-in; see Downloads) |
51
+ | `winui-svelte/security` | `src/security/index.ts` | `protectData()`, `unprotectData()`, `wipe()`, `ProtectionScope`, `DataProtectionError`: Windows DPAPI, compatible with .NET `ProtectedData` (opt-in; see Security) |
48
52
  | `winui-svelte/chrome/runtime` | `src/chrome/runtime/index.ts` | `Runtime` (`chrome.runtime`), `Port`, `InstallReason`, the native messaging codec (opt-in; see Chrome runtime) |
49
53
  | `winui-svelte/chrome/notifications` | `src/chrome/notifications/index.ts` | `ChromeNotifications` (`chrome.notifications`), `NotificationTemplateType`, `NotificationPermissionLevel` (opt-in; see Chrome notifications) |
50
54
 
@@ -52,17 +56,20 @@ monorepo needs no build step (the repository is a pnpm workspace, see
52
56
  | `winui-svelte/chrome/action` | `src/chrome/action/index.ts` | `ChromeAction` (`chrome.action`), `createChromeAction()` (opt-in; see Chrome action) |
53
57
  | `winui-svelte/chrome/i18n` | `src/chrome/i18n/index.ts` | `ChromeI18n` (`chrome.i18n`), `installLanguageDefaults()` (opt-in; see Chrome i18n) |
54
58
  | `winui-svelte/chrome/install` | `src/chrome/install.ts` | `installChromeApis()`, `ChromeGlobal`, `ChromeAlarms`, `ChromeSystem` (opt-in; see Chrome global) |
55
- | `winui-svelte/input` | `src/input/index.ts` | `enableInputEvents()`, `setPointerCapture` / `releasePointerCapture` / `hasPointerCapture`, `activeElement()`, `moveFocus()`, `trapFocus()`, `PointerType`, `PointerEvent` / `WheelEvent` / `KeyboardEvent` / `FocusEvent` (opt-in; see Input events and focus) |
59
+ | `winui-svelte/input` | `src/input/index.ts` | `enableInputEvents()`, `setPointerCapture` / `releasePointerCapture` / `hasPointerCapture`, `activeElement()`, `modifierKeysHeld()`, `moveFocus()`, `trapFocus()`, `PointerType`, `PointerEvent` / `WheelEvent` / `KeyboardEvent` / `FocusEvent` (opt-in; see Input events and focus) |
56
60
  | `winui-svelte/media` | `src/media/index.ts` | `bitmapImageOf()`, `svgImageSourceOf()`, `decodeDataUri()`, `createMediaPlayer()`, `mediaSourceOfBytes()`, `observePlayback()`, `PlaybackState` (opt-in; see Media) |
57
61
  | `winui-svelte/win2d` | `src/win2d/index.ts` | `Canvas`, the Win2D controls, the drawing helpers and Win2D classes, `applyEffect` (opt-in; see Win2D) |
58
62
  | `winui-svelte/enums` | `src/enums.ts` | every closed set a prop or option takes: WinUI's enums, `ThemeBrush`, `ColorKeyword`, `Backdrop`, `WindowTheme`, `TrayBalloonIcon` and the rest (see Closed sets) |
63
+ | `winui-svelte/win2d/manifest` | `src/win2d/manifest.ts` | `win2dActivatableClasses`, `win2dClassNames`: the manifest fragment a packaged app needs for Win2D (see Packaged apps) |
59
64
  | `winui-svelte/win2d/context-2d` | `src/win2d/context-2d/index.ts` | `Canvas2D`, `createCanvas2D`, `CanvasElement`, `Context2D`, `Path2D` and the rest of the HTML Canvas 2D API over Win2D (opt-in; see Canvas 2D) |
60
65
  | `winui-svelte/tray` | `src/tray/index.ts` | `TrayIcon` (with its `menu`), `createTrayIcon()`, `placeMenuWindow()`, `hideToTray()`, `restoreFromTray()`, `toggleInTray()`, `removeAllTrayIcons()`, `TrayGesture` (opt-in; see System tray) |
66
+ | `winui-svelte/progress/core` | `src/progress/core.ts` | `ProgressRegistry`, `defaultProgressRegistry()`, `ProgressOperation`, `trackOperation()`, `progressText()` and the types, with no Svelte component and no taskbar code, for a process with no window (opt-in; see Progress) |
61
67
  | `winui-svelte/tray/standalone` | `src/tray/standalone/index.ts` | `createStandaloneTray()`, `defineTray()`, its opt-in parts `balloons`, `bounds` and `themedIcon`, `MenuItemKind`, `MenuLevel`, and the `winui-svelte/app` calls that start or signal the app: a tray with no window, no WinUI and no components (opt-in; see Tray with no window) |
62
68
  | `winui-svelte/notice` | `src/notice/index.ts` | `showNotice()`, `NoticeIcon`, `NoticeButtons`, `NoticeButton`: a message box with no window or app (opt-in; see Notice with no app) |
63
69
  | `winui-svelte/forms` | `src/forms/index.ts` | `Form`, `FormField`, `textField`, `numberField`, `selectField` and the other field attachments, `formButton`, `FormValues`, `validityOf` (opt-in; see Forms) |
64
70
  | `winui-svelte/store` | `src/store/index.ts` | `getAppLicense`, `watchLicense`, `checkForUpdates`, `watchPackages`, `getStartupTask`, `getPackageInfo`: the Store and package APIs, answering `hasPackage: false` outside a package (opt-in) |
65
71
  | `winui-svelte/accessibility`, `/accessibility/audit` | `src/accessibility/index.ts`, `src/accessibility/audit/index.ts` | `announce`, `liveRegion`, `LivePriority`; `auditAccessibility`, `accessibilityRules` (opt-in; see Accessibility) |
72
+ | `winui-svelte/automation` | `src/automation/index.ts` | `withUiaClient`, `createUiaWorker`, `readWindowText`, `UiaControlType`: a UI Automation client that reads the text of another window (opt-in; see UI Automation client) |
66
73
  | `winui-svelte/devices` | `src/devices/index.ts` | device enumeration, input devices, Bluetooth, printers, power, network, display, audio, gamepads and sensors, each also at `winui-svelte/devices/<area>` (opt-in; see Windows devices) |
67
74
 
68
75
  The table is the source layout: `exports` point at `.ts` files so the monorepo
@@ -706,14 +713,75 @@ for tools; `compileSvelte()` throws an `Error` with that message
706
713
  // match wins), sets WINAPPSDK_BOOTSTRAP_DLL_PATH, puts the folder it was found
707
714
  // in on PATH (WebView2's native libraries are there) and initialises the
708
715
  // Windows App SDK. Sets WEBVIEW2_USER_DATA_FOLDER to `webViewUserDataFolder`
709
- // unless it is already set. Throws WindowsAppRuntimeMissing when the runtime is
710
- // not installed.
716
+ // unless it is already set; `false` leaves it alone (the variable overrides the
717
+ // folder of a createWebView2Environment). Throws WindowsAppRuntimeMissing when the runtime is
718
+ // not installed. In a process whose package graph holds the Windows App SDK
719
+ // (an MSIX whose manifest declares the PackageDependency) it skips the
720
+ // bootstrapper, which refuses to run there with 0x80070032; the environment
721
+ // and PATH steps still run, and the bootstrapper need not be found.
711
722
  function initWindowsAppSdk(options?: {
712
723
  major?: number;
713
724
  minor?: number;
714
725
  folders?: string[];
715
- webViewUserDataFolder?: string;
716
- }): void;
726
+ webViewUserDataFolder?: string | false;
727
+ dpiAwareness?: DpiAwareness | undefined; // default "per-monitor-v2"; undefined leaves the process as it is
728
+ bootstrap?: BootstrapMode; // default "auto"
729
+ }): { runtime: RuntimeSource }; // "package" or "bootstrapper", for a log line
730
+
731
+ // auto: skip the bootstrapper when the package graph holds a Microsoft.WindowsAppRuntime
732
+ // framework package, call it otherwise; always: call it (an error surfaces as
733
+ // WindowsAppRuntimeMissing with the original in `cause`); never: skip it
734
+ const BootstrapMode = { auto: "auto", always: "always", never: "never" } as const;
735
+ const RuntimeSource = { bootstrapper: "bootstrapper", package: "package" } as const;
736
+
737
+ // Whether this process has a package identity (MSIX or sparse package); cheap,
738
+ // kernel32 only, no WinRT
739
+ function hasPackageIdentity(): boolean;
740
+
741
+ // The process's DPI awareness. node.exe is unaware, so every window reads 96
742
+ // DPI (`scaleOf` 1) and screen captures and monitor rectangles are virtualized
743
+ // on a display above 100%. `initWindowsAppSdk` asks for per-monitor v2 first,
744
+ // before WinUI starts: Windows allows it once per process and only before the
745
+ // first window exists, so a library that creates a window before the call
746
+ // keeps an unaware process. A refusal is success when the process already has
747
+ // at least that awareness (a manifest set it); otherwise it throws
748
+ // DpiAwarenessTooLow, naming both values.
749
+ const DpiAwareness = {
750
+ unaware: "unaware", system: "system", perMonitor: "per-monitor", perMonitorV2: "per-monitor-v2"
751
+ } as const;
752
+ type DpiAwareness = (typeof DpiAwareness)[keyof typeof DpiAwareness];
753
+ function processDpiAwareness(): DpiAwareness; // from GetThreadDpiAwarenessContext
754
+
755
+ const { runtime } = initWindowsAppSdk(); // per-monitor v2; "package" when packaged
756
+ initWindowsAppSdk({ bootstrap: BootstrapMode.always });
757
+ initWindowsAppSdk({ dpiAwareness: undefined }); // leave the process alone
758
+ processDpiAwareness(); // "per-monitor-v2"
759
+ ```
760
+
761
+ ### Packaged apps
762
+
763
+ An MSIX app whose manifest declares
764
+ `<PackageDependency Name="Microsoft.WindowsAppRuntime.2" .../>` runs with the
765
+ runtime already in its package graph, so WinRT and WinUI activate with no
766
+ bootstrapper; `initWindowsAppSdk` sees that and skips it (`runtime: "package"`)
767
+ A child process has the identity only when the packaged parent started it
768
+ A package that has an identity but no such dependency (a sparse package) still
769
+ calls the bootstrapper, which Windows refuses with `0x80070032` in any packaged
770
+ process; declare the dependency
771
+ `test/packaged-bootstrap.test.ts` proves it with a throwaway package
772
+ (`WINUI_SVELTE_PACKAGED_TEST=1 pnpm test:windows test/packaged-bootstrap.test.ts`),
773
+ and `test/support/test-package.ts` is the harness for any test that needs an
774
+ identity: register a loose layout package, run a script under it, remove it
775
+
776
+ An application manifest is the static route for a single executable: embed it
777
+ as the `RT_MANIFEST` resource (id 1, type 24) with `<dpiAware>true/pm</dpiAware>`
778
+ and `<dpiAwareness>PerMonitorV2,PerMonitor</dpiAwareness>` after the injection
779
+ and before signing, with a PE resource editor (`postject` cannot write it);
780
+ the call is then a no-op that reports success, and stays as the safety net for
781
+ `pnpm dev` under plain `node.exe`; the repository has no single-executable
782
+ build yet, so the embedding step belongs to that work
783
+
784
+ ```ts
717
785
 
718
786
  // thread (in the worker that owns the UI thread; WinUI's loop never gives its
719
787
  // thread back): enters the single-threaded apartment first, so everything
@@ -752,6 +820,7 @@ type WindowOptions<Props> = {
752
820
  size?: { width: number; height: number }; // device pixels
753
821
  backdrop?: Backdrop; // "acrylic" | "acrylicBase" | "acrylicThin" | "mica" | "micaAlt" | "none" | "transparent"
754
822
  extendsIntoTitleBar?: boolean;
823
+ onclosing?: () => boolean | void; // AppWindow.Closing: return true to keep the window open
755
824
  isBackground?: boolean; // shown without activating (tests, captures)
756
825
  } & ({ component: Component<Props>; props: Props } | { control: FrameworkElement });
757
826
 
@@ -1187,6 +1256,8 @@ Items come in two forms
1187
1256
  keep a row only for each item the control has realized; a `TreeView` also takes
1188
1257
  `children` (the items under an item) and `bind:expandedKeys`, and a `ListView`
1189
1258
  or `GridView` can show its items in groups (`groupBy`, `groupHeader`)
1259
+ A hot update of a component an `item` snippet uses shows in the rows already
1260
+ realized, with no restart
1190
1261
  A
1191
1262
  control whose items are controls takes them as Svelte's own blocks: `{#each}`
1192
1263
  in the children of `ComboBox`, `FlipView` and `ListBox`, or in the snippet of
@@ -1684,13 +1755,152 @@ const bridge = defineMessaging<AppProtocol>({ transport: createPageTransport() }
1684
1755
  | `executeScript({ control, code })` | runs script in the page and resolves with its JSON value, checked |
1685
1756
  | `addDocumentCreatedScript({ control, code })` | runs script before every page script; resolves with the function that removes it |
1686
1757
  | `openDevTools(control)` | opens the developer tools window |
1758
+ | `createWebView2Environment({ browserExecutableFolder, userDataFolder, additionalBrowserArguments, language })` | builds an environment: a profile folder and Chromium switches (an array, joined with spaces) |
1759
+ | `startWebView2({ control, environment, profileName, isInPrivateMode })` | starts the control's browser in that environment and resolves with its `CoreWebView2`; a second call on the control resolves with the same core |
1760
+ | `keepWebView2Alive({ control, setup, rebuild, maxCrashes, windowMilliseconds, onRecovering, onGaveUp })` | brings a control back after a browser crash (see below); resolves with a guard that has `retry()` and `dispose()` |
1687
1761
  | `getCookies`, `setCookie`, `deleteCookie` | the profile's cookies as plain data (`CookieSameSite`) |
1688
1762
  | `onPermissionRequested({ control, decide })` | answers permission requests with a `PermissionState` (`default`, `allow`, `deny`) for a `PermissionKind` |
1689
1763
  | `onDownloadStarting({ control, pathFor })` | sends a download to a path with no dialog, or cancels it with `null` |
1690
1764
  | `onNavigationStarting({ control, isAllowed })` | cancels the navigations `isAllowed` refuses |
1765
+ | `blockRequests({ control, uri, context, statusCode })` | answers every request to a URI pattern (`*` and `?` wildcards) with an empty `204` until the returned function is called |
1766
+ | `onWebResourceRequested({ control, filters, respond })` | `respond(request)` returns `null` to let a request through or `{ statusCode, reasonPhrase, headers, body }` to answer it; `filters` are `{ uri, context }` with a `ResourceContext` |
1767
+ | `callDevToolsMethod({ control, method, parameters })` | calls a DevTools protocol method, resolves with its result as checked JSON, rejects with the protocol's error |
1768
+ | `onDevToolsEvent({ control, event, handler })` | hands the parsed parameters of a protocol event to `handler`; the domain must be enabled first (`Network.enable`) |
1769
+ | `dispatchKey`, `dispatchMouseClick`, `typeText`, `keyEventParameters`, `KeyEventType`, `MouseButton` | trusted input through `Input.dispatchKeyEvent` and `Input.dispatchMouseEvent`; `typeText` takes a `TypeMode` (`keys`, or `insertAfterFirst`) |
1770
+
1771
+ #### Crash recovery
1772
+
1773
+ When Chromium's browser process dies the control is dead: every later call
1774
+ throws, and starting it again in place is not something to rely on
1775
+ `keepWebView2Alive` follows `CoreProcessFailed` and applies one policy
1776
+
1777
+ ```ts
1778
+ import { keepWebView2Alive } from "winui-svelte/messaging/web-view2";
1779
+
1780
+ const guard = keepWebView2Alive({
1781
+ control,
1782
+ maxCrashes: 3,
1783
+ windowMilliseconds: 30_000,
1784
+ async setup(core) {
1785
+ // runs for the first core and after every rebuild
1786
+ await core.addScriptToExecuteOnDocumentCreatedAsync(bridgeScript);
1787
+ },
1788
+ onRecovering: ({ kind }) => status("reconnecting"),
1789
+ onGaveUp: ({ reason }) => status("down"),
1790
+ rebuild: async () => remount()
1791
+ });
1792
+ guard.dispose();
1793
+ ```
1794
+
1795
+ - `ProcessFailureKind` (`winui-svelte/enums`) is `BROWSER_EXITED`,
1796
+ `RENDER_EXITED`, `UNRESPONSIVE` or `OTHER`, mapped from
1797
+ `CoreWebView2ProcessFailedKind`
1798
+ - `BROWSER_EXITED` calls `rebuild`, which resolves with a new control that is
1799
+ already started (`startWebView2`), then runs `setup` with its core; any other
1800
+ kind calls `core.reload()` and keeps the core
1801
+ - More than `maxCrashes` failures within `windowMilliseconds` (3 within 30
1802
+ seconds by default) call `onGaveUp` once and stop; `retry()` forgets the
1803
+ failures and rebuilds
1804
+ - A failure while a recovery is running is ignored; a `rebuild` or `setup` that
1805
+ throws gives up with the error's text as the reason
1806
+ - After a rebuild, redo in `setup` whatever is bound to the old core: scripts
1807
+ from `addDocumentCreatedScript`, `onNavigationStarting`,
1808
+ `onPermissionRequested`, `onWebResourceRequested`, the DevTools subscriptions
1809
+ and a `webView2Transport` with its messaging; cookies and storage live in
1810
+ the profile folder and survive; after a reload only the page's own state is
1811
+ lost
1812
+ - In a Svelte app, key the component on a `$state` counter: `rebuild` bumps
1813
+ it and resolves with the control that the new `WebView2` hands to
1814
+ `oncorewebview2initialized`; `examples/web-recovery` shows it, and
1815
+ `test/web-recovery.test.ts` kills its browser process and sees the page come
1816
+ back
1817
+ - Several controls on one profile folder share a browser process, so one kill
1818
+ fails all of them; each control has its own guard, and each rebuilds itself
1819
+ - Resuming what a page was doing (a live conversation) is the app's job;
1820
+ `onRecovering` is its hook
1821
+
1822
+ A profile folder and Chromium switches per control
1823
+
1824
+ ```ts
1825
+ import { createWebView2Environment, startWebView2 } from "winui-svelte/messaging/web-view2";
1826
+
1827
+ const environment = await createWebView2Environment({
1828
+ userDataFolder: path.join(process.env.LOCALAPPDATA, "MyApp", "WebView2Home"),
1829
+ additionalBrowserArguments: ["--autoplay-policy=no-user-gesture-required"],
1830
+ language: "en-US"
1831
+ });
1832
+ // control is the WebView2 (the sender of onloaded), already in a window
1833
+ const core = await startWebView2({ control, environment, profileName: "home" });
1834
+ ```
1835
+
1836
+ - The first start of a control wins: call `startWebView2` before anything that
1837
+ starts it with the default environment (`waitForCoreWebView2` and every
1838
+ helper that calls it); a second call resolves with the same core
1839
+ - `WEBVIEW2_USER_DATA_FOLDER` overrides the folder of an environment (measured:
1840
+ with it set, two environments with two folders both ran in the variable's
1841
+ folder), so the app starts with `initWindowsAppSdk({ webViewUserDataFolder: false })`
1842
+ and the variable unset
1843
+ - One browser process runs per folder; two controls in one folder with different
1844
+ options, or a process that cannot launch the browser, fail with 0x8007139F,
1845
+ and a folder another browser has open with 0x800700AA; the rejection's message
1846
+ names the causes
1847
+ - `additionalBrowserArguments` reach the browser process (the test reads its
1848
+ command line); profiles of different folders share no cookies
1849
+ - `core.browserProcessId` and `core.environment.userDataFolder` are on
1850
+ `CoreWebView2Like`
1851
+ - `examples/web-profiles` and `test/web-profiles.test.ts` run two controls in
1852
+ one window with two folders; it needs an ordinary desktop session
1853
+
1854
+ Request filters and the protocol
1855
+
1856
+ ```ts
1857
+ import {
1858
+ blockRequests,
1859
+ callDevToolsMethod,
1860
+ ResourceContext,
1861
+ typeText
1862
+ } from "winui-svelte/messaging/web-view2";
1863
+
1864
+ const unblock = await blockRequests({
1865
+ control,
1866
+ uri: "https://accounts.google.com/RotateCookies*",
1867
+ context: ResourceContext.ALL
1868
+ });
1869
+ await callDevToolsMethod({ control, method: "Runtime.evaluate", parameters: { expression: "document.title" } });
1870
+ await typeText({ control, text: "hello" });
1871
+ unblock();
1872
+ ```
1873
+
1874
+ - A filter added before the first navigation applies to it; one added later
1875
+ does not apply to requests already in flight
1876
+ - Every handler hears the requests of every filter of the control, so each
1877
+ checks its own filters; `respond` is a plain function (the answer is given
1878
+ before the event's handler returns), and a body holds the request until it
1879
+ is written to a stream
1880
+ - The empty answer uses an empty `InMemoryRandomAccessStream`; a `null` stream
1881
+ for `createWebResourceResponse` was not tried
1882
+ - Typing 300 characters with `typeText` takes 5 to 7.5 seconds in a window on
1883
+ this machine (two protocol calls per character, sent in order: sending them
1884
+ all at once reorders the keys); `TypeMode.INSERT_AFTER_FIRST` takes about
1885
+ 0.1 second, but whether a page enables its Submit button from inserted text
1886
+ is the page's
1887
+ - `coreWebView2` is not set yet inside `oncorewebview2initialized`; the helpers
1888
+ that wait for it need a turn of the event loop first (`setTimeout`)
1889
+
1890
+ Porting a C# WebView2 host
1891
+
1892
+ | C# | Here |
1893
+ |---|---|
1894
+ | `CookieManager` | `getCookies`, `setCookie`, `deleteCookie` |
1895
+ | `PermissionRequested` | `onPermissionRequested` |
1896
+ | `NavigationStarting` | `onNavigationStarting` |
1897
+ | `AddWebResourceRequestedFilter` and `WebResourceRequested` | `StatusCode`, `blockRequests`, `onWebResourceRequested` |
1898
+ | `CallDevToolsProtocolMethodAsync` | `callDevToolsMethod`, `dispatchKey`, `dispatchMouseClick` |
1899
+ | `GetDevToolsProtocolEventReceiver` | `onDevToolsEvent` |
1691
1900
 
1692
1901
  `examples/web-bridge` is an app talking to a hosted page, and
1693
- `test/web-bridge.test.ts` runs it in a real window; it needs an ordinary
1902
+ `test/web-bridge.test.ts` runs it in a real window; `examples/web-requests` and
1903
+ `test/web-requests.test.ts` do the same for a blocked request and typed input; it needs an ordinary
1694
1904
  desktop session (a sandboxed process cannot launch the browser, 0x8007139F)
1695
1905
 
1696
1906
  ### ListView and GridView
@@ -1883,6 +2093,15 @@ exists on Windows 11 only
1883
2093
  A window on a desktop of its own (a hidden desktop) is never composed by
1884
2094
  Windows, so there is nothing to see through to: `test/transparent-window.test.ts`
1885
2095
  reads the screen of the ordinary desktop for that reason
2096
+ `isClickThrough` with `backdrop="transparent"` works on build 26300, measured
2097
+ by `test/click-through.test.ts` (examples/click-through, a 3 px ring drawn by
2098
+ content): the window stays clear (the hole reads the desktop, the ring its
2099
+ color, not black), and a click on the ring and one in the hole reach the window
2100
+ below, as Windows hit-tests it (`WindowFromPoint`, the root's owner); the same
2101
+ ring without `isClickThrough` answers itself, which is the control
2102
+ No region (`clipToRing`) is needed, and the host's own order of the frame and
2103
+ the backdrop is the one that was measured
2104
+ The test sends no click, so a person still confirms it in Notepad (CONTRIBUTING)
1886
2105
  Not checked: a filter or a drop shadow (`filter: drop-shadow()`) on content
1887
2106
  over a transparent window
1888
2107
  The window's own `cornerRadius` clips with an edge that is not anti-aliased, so
@@ -1970,11 +2189,40 @@ along the top, until `isResizable={false}` takes it away),
1970
2189
  `isShownInSwitchers` and `isToolWindow` (no taskbar button or Alt+Tab entry),
1971
2190
  `isActivatable={false}` (a click never takes focus), `isClickThrough`,
1972
2191
  `isExcludedFromCapture` (black in screenshots and screen sharing),
1973
- `isHidden` (opens hidden, hides and shows later) and `cornerRadius` (clips the
2192
+ `isHidden` (opens hidden, hides and shows later), `isParked` (see below) and `cornerRadius` (clips the
1974
2193
  window to a rounded rectangle; the edge is not anti-aliased, so on a
1975
2194
  transparent window round the card's own `corner-radius` instead, which is)
1976
2195
  A prop left out leaves the window as it is, and dropped again it puts the
1977
2196
  window back
2197
+
2198
+ A window that must run but never be seen (a host for a page with no UI) is
2199
+ `isParked`: shown, so that Chromium keeps its page at full speed, but a tool
2200
+ window that is not activatable, opened without taking focus, and placed left of
2201
+ the virtual screen, clear of every display
2202
+ `placement` and `width`/`height` give only its size; dropping the prop moves it
2203
+ back
2204
+ It is the per-window form of the `WINUI_SVELTE_BACKGROUND` run, and uses the
2205
+ same code
2206
+ `isHidden` is not a substitute: a hidden window is a hidden page
2207
+ (`document.visibilityState` is `hidden`, timers are throttled)
2208
+ `test/parked-window.test.ts` measures it: the page of a parked window reports
2209
+ `visible`, a heartbeat of 100 milliseconds keeps its pace and
2210
+ `requestAnimationFrame` keeps firing, where the same window with `isHidden`
2211
+ reports `hidden`
2212
+ Measured over 5 seconds, no Chromium flags set (the default WebView2
2213
+ environment):
2214
+
2215
+ | Window | `visibilityState` | Heartbeat gap (100 ms timer) | Frames |
2216
+ |---|---|---|---|
2217
+ | `isParked` | `visible` | under 150 ms on average | above 10 a second |
2218
+ | `isHidden` | `hidden` | slower, throttled | not measured |
2219
+
2220
+ So the three Chromium flags the C# host sets are not needed for a parked window
2221
+ ```svelte
2222
+ <Window isParked width={900} height={720}>
2223
+ <WebView2 source="about:blank" />
2224
+ </Window>
2225
+ ```
1978
2226
  `createWindow` takes them too
1979
2227
  `handle.setShownInSwitchers(isShown)` does not throw for a window that has no
1980
2228
  taskbar button (WinUI answers 0x80004001 there); `hideToTray` uses it
@@ -2033,6 +2281,46 @@ at the size it has after Windows rescaled it
2033
2281
  The arithmetic is plain functions (`anchoredBounds`, `dockedBounds`,
2034
2282
  `fittedBounds` in `src/window/anchor.ts`) over device pixels
2035
2283
 
2284
+ ### Covering a display
2285
+
2286
+ ```ts
2287
+ // the whole display the user is on, in physical pixels
2288
+ handle.cover({ display: DockDisplay.active })
2289
+ // a rectangle of the display, from its top left
2290
+ handle.cover({ display: DockDisplay.current, region: { x: 240, y: 120, width: 800, height: 600 } })
2291
+ // one display by the id that displays() lists
2292
+ handle.cover({ display: displayId })
2293
+ ```
2294
+
2295
+ A covering window needs `isBorderless` and `isResizable={false}`: without the
2296
+ second, the 8 device pixel resize frame stays, shrinks the client area and
2297
+ paints a strip along the top; `cover` does not set either, because a prop left
2298
+ out leaves the window as it is
2299
+ `dock` is a corner of the **work area** at the window's own size; `cover` is
2300
+ the **whole display** (or a part of it) at the display's size;
2301
+ `handle.geometry` is in CSS pixels at the window's scale and can do neither
2302
+ exactly
2303
+ `display` is a `DockDisplay` or a display id (a `bigint`); the active display by
2304
+ default
2305
+ `region` is in the target display's own physical pixels, relative to its top
2306
+ left, and is not clipped to it, so a frame drawn 4 pixels outside a region at
2307
+ the display's edge stays where it was asked for; a region measured on another
2308
+ display has to be mapped by the caller
2309
+ It returns the bounds it applied (`WindowBounds`), so a frame or a canvas can
2310
+ follow them
2311
+ A window sent to a display with another scale first goes to that display's
2312
+ origin, so Windows rescales it there, and is then placed once at the bounds in
2313
+ that display's pixels; a rescale that changed the size anyway is placed again
2314
+ (at most twice)
2315
+ `coverWindow({ appWindow, display, region })` (`winui-svelte/window`) does the
2316
+ same for a bare `AppWindow`, and `coveredBounds` in `src/window/anchor.ts` is
2317
+ the plain arithmetic
2318
+ `outerBounds` and `appWindow` are physical pixels only in a PerMonitorV2
2319
+ process
2320
+ Not verified: whether a topmost window that equals a monitor's bounds changes
2321
+ the taskbar for that monitor, and whether a `backdrop="transparent"` cover is
2322
+ see-through at its edge pixels; try both before shipping an overlay on them
2323
+
2036
2324
  `handle.geometry` is the window's own `window.outerWidth`, `outerHeight`,
2037
2325
  `screenX`, `screenY`, `devicePixelRatio`, `resizeTo(width, height)`,
2038
2326
  `resizeBy`, `moveTo(x, y)` and `moveBy`, in CSS pixels (WinUI's
@@ -2560,9 +2848,22 @@ An opt-in subpath: an app that does not import it does not bundle it
2560
2848
  The running copy's `onRedirect` receives `activation`
2561
2849
  - `launchApp({ command, arguments, workingDirectory })` starts a program
2562
2850
  that outlives the caller: detached, no console window, no shared handles
2851
+ - `claimInstance({ key, source, activation, runOnUiThread, onRedirect })` is `ensureSingleInstance` over any source of the link
2852
+ Pass `createPipeSource()` to claim the pipe early on a plain main thread,
2853
+ before any WinUI loads, so a second copy exits in about 50 ms; it needs no
2854
+ dispatcher queue, and `runOnUiThread` relays `onRedirect` to the thread that
2855
+ owns the windows (`pipeNameFor` and `currentUserSid` are the pipe's name
2856
+ and its user)
2563
2857
  - `activateOrLaunch({ key, activation, launch })` is the two together: it
2564
2858
  activates the running copy, or else starts the app with `launch`, and
2565
2859
  resolves with true for the first and false for the second
2860
+ - `activateInstance` and `launchApp` first call `AllowSetForegroundWindow` for
2861
+ any process, as does the standalone tray after a menu pick and before a
2862
+ click's handler: Windows' foreground lock refuses the window of another
2863
+ process, and only the process that received the user's input can lift it
2864
+ `handle.bringToFront()` also joins the foreground thread's input (the same
2865
+ call as `bringWindowToFront`), so a window asked from another process comes
2866
+ to the front instead of flashing on the taskbar
2566
2867
  - `relaunch({ arguments })` starts the same Node with the same flags, entry
2567
2868
  script (`process.argv[1]`) and then `arguments`, detached, and calls
2568
2869
  `exitApplication`, so the new copy outlives this one
@@ -2571,9 +2872,13 @@ An opt-in subpath: an app that does not import it does not bundle it
2571
2872
  redirects to it
2572
2873
  An app whose windows run in a worker thread passes `entryScript`, the script
2573
2874
  that starts the process, because `process.argv[1]` there is the worker's
2875
+ A single executable application (a Node `node:sea` build, where
2876
+ `process.execPath` is the app's own exe) is relaunched as the exe and
2877
+ `arguments`, with no script and no Node flags
2574
2878
  - `restartAfterCrash({ arguments, conditions })` is
2575
2879
  `RegisterApplicationRestart`: Windows starts the same Node and entry
2576
- script with `arguments` after a crash, a hang, an update that closes the
2880
+ script (a single executable: its own exe) with `arguments` after a crash,
2881
+ a hang, an update that closes the
2577
2882
  app or a reboot for one; `conditions` is a subset of `RestartCondition`
2578
2883
  (`crash`, `hang`, `update`, `reboot`; all by default)
2579
2884
  Limits: no callback (a crashed Node cannot run code, so
@@ -2595,10 +2900,12 @@ import {
2595
2900
  ActivationKind,
2596
2901
  installProtocolHandlers,
2597
2902
  launchAtLogin,
2903
+ packagedActivation,
2598
2904
  registerFileTypes,
2599
2905
  startActivation,
2600
2906
  } from "winui-svelte/app/activation";
2601
2907
 
2908
+ const packaged = packagedActivation(); // { kind: "protocol", uri } or { kind: "startup" }
2602
2909
  installProtocolHandlers();
2603
2910
  navigator.registerProtocolHandler("note", "https://notes.example/open?uri=%s");
2604
2911
  registerFileTypes({ id: "com.example.notes", extensions: [".note"] });
@@ -2626,6 +2933,7 @@ if (!single.isPrimary) {
2626
2933
  | `unregisterFileTypes({ id, extensions })` | deletes both and the empty keys left | returns the extensions removed |
2627
2934
  | `launchAtLogin({ id, isEnabled, arguments })` | `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` value `id` | listed in Settings, Apps, Startup; the start arrives as `startup` |
2628
2935
  | `getLaunchAtLogin({ id })` | reads that value | `{ isEnabled, commandLine }`; the user's switch in Settings is not read |
2936
+ | `packagedActivation()` | `AppInstance.getActivatedEventArgs()` | how a packaged process was started; `undefined` outside a package |
2629
2937
  | `startActivation({ key, onActivation })` | `ensureSingleInstance` and the command line | one `ActivationEvent` per start or redirect |
2630
2938
 
2631
2939
  - `ActivationEvent` is a union on `kind` (`ActivationKind`, also from
@@ -2665,18 +2973,116 @@ if (!single.isPrimary) {
2665
2973
  characters at most) and handed to your code, never run
2666
2974
  Windows can pass a quote in a link through `"%1"` unescaped, so treat the
2667
2975
  whole of `uri` as untrusted
2976
+ - Packaged apps: a package declares its scheme in the manifest, so
2977
+ `installProtocolHandlers` is not needed; `startActivation` reads the start
2978
+ from two places and merges them, the command line first
2979
+ 1. Route A, the command line: give the protocol `Parameters`, and Windows
2980
+ passes the address as an argument, for a cold start
2981
+
2982
+ ```xml
2983
+ <Extensions>
2984
+ <uap3:Extension Category="windows.protocol" Executable="my-app.exe"
2985
+ EntryPoint="Windows.FullTrustApplication">
2986
+ <uap3:Protocol Name="my-scheme" Parameters="&quot;%1&quot;" />
2987
+ </uap3:Extension>
2988
+ </Extensions>
2989
+ ```
2990
+
2991
+ 2. Route B, the Windows App SDK: `packagedActivation()` reads
2992
+ `AppInstance.getCurrent().getActivatedEventArgs()`; a `Protocol`
2993
+ activation gives its address and a `StartupTask` activation is a
2994
+ `startup` event, which Route A cannot say (a startup task takes no
2995
+ `Parameters`)
2996
+
2997
+ ```xml
2998
+ <desktop:Extension Category="windows.startupTask" Executable="my-app.exe"
2999
+ EntryPoint="Windows.FullTrustApplication">
3000
+ <desktop:StartupTask TaskId="Startup" Enabled="false" DisplayName="My app" />
3001
+ </desktop:Extension>
3002
+ ```
3003
+
3004
+ An address the command line holds wins over the activation's; a later
3005
+ copy's address arrives through the single instance link as a redirect, as
3006
+ everywhere, so never call `redirectActivationToAsync`
3007
+ `packagedActivation()` answers `undefined` outside a package, for a plain
3008
+ launch and for any failure; it never throws
3009
+ Call `startActivation` after `initWindowsAppSdk` (`initWindowsAppSdk`)
2668
3010
  - Needs packaging for: the share target and a default-app claim (a package
2669
3011
  manifest declares them); unpackaged, the app is offered in Open with and the
2670
3012
  user picks the default
2671
3013
  - `installProtocolHandlers()` returns the function that removes the two
2672
3014
  navigator methods; the registrations stay until you unregister them
2673
3015
  Each registration function takes `registry` (a fake in tests) and `command`
3016
+ - `test/packaged-activation.test.ts` (opt in with `WINUI_SVELTE_PACKAGED_TEST=1`)
3017
+ registers a throwaway package with both routes and starts it with a link
2674
3018
  - `src/app/activation/native.test.ts` registers a protocol, a file type and a
2675
3019
  startup entry under HKCU with a unique name, reads them with `reg query`,
2676
3020
  removes them and checks nothing is left, even when it fails;
2677
3021
  `test/activation.test.ts` starts real second copies with a link, a file and
2678
3022
  nothing, and checks the first hears each as one event
2679
3023
 
3024
+ ### Native messaging host (`winui-svelte/app/native-messaging`)
3025
+
3026
+ Telling the browsers where a native messaging host lives, for the current user
3027
+
3028
+ ```ts
3029
+ import { registerNativeMessagingHost } from "winui-svelte/app/native-messaging";
3030
+ import { isInstanceRunning } from "winui-svelte/app";
3031
+
3032
+ registerNativeMessagingHost({
3033
+ name: "com.example.notes",
3034
+ manifestPath: "C:\Users\me\AppData\Local\Notes\host.json",
3035
+ });
3036
+
3037
+ const isAppUp = isInstanceRunning({ key: "com.example.notes" });
3038
+ ```
3039
+
3040
+ - `registerNativeMessagingHost({ name, manifestPath, browsers, registry })`
3041
+ writes the manifest's path as the default value of
3042
+ `HKCU\Software\<browser>\NativeMessagingHosts\<name>` for Chrome, Edge,
3043
+ Brave and Chromium (`NativeMessagingBrowser`; pass `browsers` for fewer)
3044
+ It writes the registry only: the JSON manifest is the caller's file
3045
+ Calling it again rewrites the same values; a name other than lowercase
3046
+ letters, digits, `_` and `.` between them, or a relative path, is a
3047
+ `TypeError`
3048
+ - `unregisterNativeMessagingHost({ name, browsers, registry })` deletes the
3049
+ host's own keys and each parent left empty; a key that holds anything else
3050
+ stays
3051
+ - Under a package identity the write is virtualized unless the manifest
3052
+ declares `desktop6:RegistryWriteVirtualization` as disabled and the
3053
+ `unvirtualizedResources` capability; browsers read the real registry
3054
+ - `isInstanceRunning({ key })` is true while a copy serves `key`
3055
+ (`ensureSingleInstance` or `claimInstance`); it asks the pipe's existence,
3056
+ sends nothing and never starts or claims anything, so a host can ask
3057
+ before it starts the app
3058
+
3059
+ ### Win32 seam (`winui-svelte/win32`)
3060
+
3061
+ An escape hatch for a Win32 function that WinRT has no equivalent for, over
3062
+ the binder the package uses itself
3063
+
3064
+ ```ts
3065
+ import { bindDll, hasPackageIdentity } from "winui-svelte/win32";
3066
+
3067
+ const user32 = bindDll({
3068
+ dll: "user32.dll",
3069
+ functions: { foreground: ["GetForegroundWindow", [], "pointer"] },
3070
+ });
3071
+ const hwnd = user32.foreground();
3072
+ ```
3073
+
3074
+ - `bindDll({ dll, functions })` takes one `[entryPoint, parameters,
3075
+ returnType]` row per name and calls with plain values (numbers, bigints,
3076
+ strings as wide text, memory, null) and gives back a number or an address
3077
+ - `bind(...)` is the lower level one, over `DynWin32` values
3078
+ `pointerOf`, `wideMemory`, `numberOf`, `addressOf`, `withMemory` and
3079
+ `WIDE_CHAR_BYTES` are its helpers; the caller owns the memory it allocates
3080
+ - `hasPackageIdentity()` tells a packaged process from plain Node
3081
+ - Types are strings and `@microsoft/dynwinrt` is a preview, so this entry may
3082
+ change with it; the registry has its own typed entry
3083
+ (`createWindowsRegistry` in `winui-svelte/app/activation`, string values of
3084
+ the current user only)
3085
+
2680
3086
  ### Jump list tasks (`winui-svelte/app/jump-list`)
2681
3087
 
2682
3088
  Entries in the Tasks section of the taskbar button's right-click menu
@@ -2926,6 +3332,65 @@ const hotkey = registerHotkey({
2926
3332
  posts `WM_HOTKEY` to the thread itself with `PostThreadMessageW`; no key is
2927
3333
  pressed
2928
3334
 
3335
+ ### Following the foreground app (`winui-svelte/window/foreground`)
3336
+
3337
+ Opt-in; nothing runs at import
3338
+
3339
+ ```ts
3340
+ import {
3341
+ bringWindowToFront,
3342
+ shouldRestore,
3343
+ trackForeground
3344
+ } from "winui-svelte/window/foreground";
3345
+
3346
+ const tracker = trackForeground({
3347
+ ownWindows: () => [pillHwnd],
3348
+ onChanged: ({ hwnd, isRealApp }) => {}
3349
+ });
3350
+ tracker.lastRealApp; // bigint | null, the last real app that was in front
3351
+ tracker.current; // bigint | null
3352
+ tracker.stop(); // idempotent
3353
+
3354
+ const isBack = shouldRestore({
3355
+ lastRealApp: tracker.lastRealApp,
3356
+ foreground: tracker.foreground
3357
+ });
3358
+ if (isBack && tracker.lastRealApp !== null) {
3359
+ bringWindowToFront(tracker.lastRealApp); // true when Windows took it
3360
+ }
3361
+ ```
3362
+
3363
+ - `trackForeground({ onChanged, ownWindows, ignoredClasses, tracking,
3364
+ intervalMilliseconds })` runs on the UI thread of a `runWindow` app
3365
+ - `tracking: "events"` (default, `ForegroundTracking.events`): the shell posts
3366
+ a message to a hidden window of the app on each change
3367
+ (`RegisterShellHookWindow` and `SHELLHOOK`), the message pump reads it, and
3368
+ `GetForegroundWindow` is read once; an idle foreground costs nothing
3369
+ dynwinrt delivers no native callbacks, so `SetWinEventHook` cannot be used
3370
+ If Windows refuses the registration, use `tracking: "polling"`
3371
+ - `tracking: "polling"`: one `GetForegroundWindow` per `intervalMilliseconds`
3372
+ (100 by default, 16 at least); latency is one tick
3373
+ The class and the process of a window are read once, when it is first seen
3374
+ - The filter: a real app is not the desktop, not a shell class
3375
+ (`ForegroundShellClass`: `Progman`, `WorkerW`, `Shell_TrayWnd`,
3376
+ `Shell_SecondaryTrayWnd`, `CopilotKeyPressFocusFrame`), not a window of
3377
+ this process, and not in `ownWindows()` or `ignoredClasses`
3378
+ `lastRealApp` changes only on a real app
3379
+ - `bringWindowToFront(hwnd)` joins this thread to the foreground thread's
3380
+ input for `BringWindowToTop` and `SetForegroundWindow`, then detaches,
3381
+ because a hotkey's key releases went to the app in front and Windows'
3382
+ foreground lock refuses a plain call; it restores a minimized window first,
3383
+ sends no input and returns whether the window ended in front
3384
+ It is best effort: a foreground window of a higher integrity level or a hung
3385
+ one still refuses; the tray menu window takes the foreground through it
3386
+ - Not measured yet: the idle cost of each mode (the tray's 30 Hz timer costs
3387
+ about 2 percent of a core in an idle window)
3388
+
3389
+ Manual checklist: press the app's hotkey from Notepad, then from the desktop,
3390
+ then from a browser on a second monitor; each time the key goes back to where
3391
+ it was; then Alt+Tab to another app while the overlay is up and confirm it is
3392
+ not pulled back
3393
+
2929
3394
  ### System tray (`winui-svelte/tray`)
2930
3395
 
2931
3396
  WinUI and the Windows App SDK have no notification-area API (apps call
@@ -3127,8 +3592,13 @@ const lines = resolveMenu({
3127
3592
  labels and ticks only); `closeThenRun` (true unless set to false) runs
3128
3593
  `onselect` after the menu has closed, so that a dialog can open
3129
3594
  - A submenu may have its own `onselect` and `autoExpand`
3130
- - `icon` is a path, a glyph or `IconPixels`; `shortcut` is display text only,
3131
- the menu does not bind the key
3595
+ - `icon` is a path, a glyph, `IconPixels`, `{ forLightMenu, forDarkMenu }` (one
3596
+ picture for each menu theme) or `{ tinted }` (a single-color glyph that the
3597
+ menu paints in its text color, so one picture serves both themes); each
3598
+ renderer draws what it can (the popup menu of `winui-svelte/tray/standalone`
3599
+ draws files and pixels, a flyout draws paths and glyphs, and takes the light
3600
+ member of a pair)
3601
+ `shortcut` is display text only, the menu does not bind the key
3132
3602
  - `MenuProfile` is plain JSON: `level`, `hidden` (ids the level shows that
3133
3603
  the user hid), `shown` (ids above the level that the user turned on) and
3134
3604
  `order` (child ids in the user order, keyed by parent id, `""` for the root)
@@ -3324,13 +3794,19 @@ createStandaloneTray({
3324
3794
  `bounds` when their extras are passed
3325
3795
  The icon keeps the process alive; `remove()` or the process ending takes it
3326
3796
  out of the tray
3797
+ - `colorScheme` is the menu's `color-scheme` as the web says it: `"light dark"`
3798
+ (the default) makes the popup dark when Windows' app theme is, `"light"` and
3799
+ `"dark"` force one; `MenuColorScheme` names the three values
3800
+ It uses uxtheme's `SetPreferredAppMode` and `FlushMenuThemes` (ordinals 135
3801
+ and 136), applied before each menu opens, so it affects the process's other
3802
+ native menus too
3327
3803
  - The default is the smallest tray: an icon from one `.ico` path, clicks,
3328
3804
  `update`, `remove` and the menu
3329
- Three parts are opt-in, each one import from the same entry, passed in
3805
+ Four parts are opt-in, each one import from the same entry, passed in
3330
3806
  `extras`, and none of their code is in the bundle unless passed:
3331
- `balloons` adds `notify`, `bounds` adds `bounds()`, and `themedIcon` lets
3807
+ `balloons` adds `notify`, `bounds` adds `bounds()`, `themedIcon` lets
3332
3808
  `icon` be `{ forLightTaskbar, forDarkTaskbar }`, swapped as the taskbar theme
3333
- changes
3809
+ changes, and `menuIcons` draws the icons of the menu's lines (below)
3334
3810
  The handle has `notify` or `bounds` only when its extra is passed, and a
3335
3811
  theme pair is accepted only with `themedIcon`; otherwise it fails to compile
3336
3812
  `createTrayIcon` and `TrayIcon` of `winui-svelte/tray` include all three
@@ -3369,12 +3845,29 @@ tray.notify({ title: "Ready" });
3369
3845
  labels and ticks, right after the line runs; `onselect` otherwise runs on
3370
3846
  the next turn after the menu is gone (`closeThenRun: false` runs it as the
3371
3847
  menu closes)
3372
- A submenu's own `onselect` and `autoExpand`, and every `icon`, do nothing
3373
- here: Windows opens a submenu row without reporting a pick, and no pixel
3374
- or file icon is drawn
3848
+ A submenu's own `onselect` and `autoExpand` do nothing here: Windows opens a
3849
+ submenu row without reporting a pick
3850
+ Without `menuIcons` in `extras` no line shows an icon, and the roughly 6 KB
3851
+ of the decoder and the bitmap code stay out of the bundle
3852
+ With it, every `icon` is drawn as a bitmap beside the label, on commands,
3853
+ checks, radios and submenu rows at any depth: a path to a png, ico, bmp, jpeg, gif
3854
+ or tiff (decoded by GDI+, kept by path and modification time, so a menu that
3855
+ opens again does not decode again), `IconPixels`, a `{ forLightMenu,
3856
+ forDarkMenu }` pair, or `{ tinted }` for a monochrome glyph (only its alpha is
3857
+ used, and it takes the menu's text color)
3858
+ The theme is read each time the menu opens, by the rule `colorScheme` sets
3859
+ (the system's app mode for `"light dark"`), so a pair and a tinted glyph
3860
+ follow a theme change; the bitmap is a 32-bit premultiplied DIB section, the
3861
+ size of the menu's check mark at the screen's scale (at least the small icon
3862
+ size), and is freed with the menu
3863
+ A disabled line gets a grey, fainter icon (Windows does not dim a bitmap),
3864
+ and a ticked line or radio gets a frame around its icon, because Windows
3865
+ draws the icon where the tick would be
3866
+ A path that cannot be read leaves the line without an icon; the rest of the
3867
+ menu opens as usual
3375
3868
  The menu is modal: the thread runs its own message loop until it closes
3376
- It does not follow a dark system theme, which a native popup menu does not
3377
- without an undocumented call; a menu that must match the theme belongs in
3869
+ `colorScheme` makes it follow the system theme through an undocumented
3870
+ uxtheme call; a menu that must be drawn in WinUI belongs in
3378
3871
  `winui-svelte/tray` with `TrayIcon`'s `menu` snippet
3379
3872
  - The same entry re-exports `activateInstance`, `activateOrLaunch` and
3380
3873
  `launchApp` from `winui-svelte/app` (App lifecycle), so a tray imports from
@@ -3385,6 +3878,76 @@ tray.notify({ title: "Ready" });
3385
3878
  component, window or renderer module, or a component's name, is in the
3386
3879
  output, or if it grows past its budget
3387
3880
 
3881
+ ### Trays and windows are independent
3882
+
3883
+ Neither needs the other
3884
+ A process can have zero windows and several tray icons, or windows and
3885
+ taskbar buttons and no tray; nothing is created for the part you leave out
3886
+
3887
+ ```ts
3888
+ // Zero windows, two icons, one Node process
3889
+ import { createStandaloneTray, MenuColorScheme, MenuItemKind } from "winui-svelte/tray/standalone";
3890
+ import { defaultProgressRegistry, progressText } from "winui-svelte/progress/core";
3891
+
3892
+ createStandaloneTray({
3893
+ icon: "recorder.ico",
3894
+ tooltip: "Recorder",
3895
+ colorScheme: MenuColorScheme.DARK,
3896
+ menu: () => [{
3897
+ kind: MenuItemKind.COMMAND,
3898
+ id: "status",
3899
+ label: progressText(defaultProgressRegistry().snapshot),
3900
+ onselect() {}
3901
+ }]
3902
+ });
3903
+
3904
+ createStandaloneTray({
3905
+ icon: "uploads.ico",
3906
+ tooltip: "Uploads",
3907
+ colorScheme: MenuColorScheme.LIGHT,
3908
+ menu: [{ kind: MenuItemKind.COMMAND, id: "quit", label: "Quit", onselect: () => process.exit(0) }]
3909
+ });
3910
+ ```
3911
+
3912
+ ```svelte
3913
+ <!-- Windows and a taskbar button, no tray -->
3914
+ <script lang="ts">
3915
+ import { Window } from "winui-svelte/components";
3916
+ import { TaskbarProgress } from "winui-svelte/progress";
3917
+ </script>
3918
+
3919
+ <Window>
3920
+ <TaskbarProgress />
3921
+ </Window>
3922
+ ```
3923
+
3924
+ - Each `createStandaloneTray` has an identity of its own (its own hidden owner
3925
+ window and a unique id, and its own `guid` when you pass one), its own
3926
+ timer, its own menu and its own state; `remove()` takes out that icon only
3927
+ and the exit hook takes out all of them
3928
+ - Clicks are polled, and Windows keeps one "pressed since the last read"
3929
+ flag for the whole process, which the first read clears; the trays of a
3930
+ process share that read, so each icon hears a click shorter than its
3931
+ polling interval (the flag can still be cleared by another process or by
3932
+ other code of yours that calls `GetAsyncKeyState`)
3933
+ - The menu theme is one setting per process (uxtheme's preferred app mode);
3934
+ a tray sets its own `colorScheme` right before each of its menus opens, so
3935
+ two trays with different schemes each get theirs, because only one menu is
3936
+ open at a time
3937
+ The setting then stays until the next menu opens, so another popup menu in
3938
+ the same process (a window's) shows in the scheme of the tray that spoke
3939
+ last
3940
+ - `winui-svelte/progress/core` is the progress registry, operations and
3941
+ `progressText` with no Svelte component and no taskbar code, so a
3942
+ tray-only process can show progress; `winui-svelte/progress` adds
3943
+ `TaskbarProgress` and `bindTaskbarProgress`, which are the only part that
3944
+ needs a window
3945
+ - `scripts/pack/independence.test.ts` walks the imports and fails if the
3946
+ standalone tray reaches a component, the renderer, the window runtime or
3947
+ taskbar code, if the taskbar progress reaches a tray, or if a window
3948
+ reaches a tray; `scripts/pack/tray-only.test.ts` bundles two trays with the
3949
+ registry and fails on the same, or on a growing size
3950
+
3388
3951
  ### Tray as an entrypoint (`entrypoints/tray.ts`)
3389
3952
 
3390
3953
  The app does not have to know it has a tray; the tray is its own file, found
@@ -3425,6 +3988,14 @@ export default defineTray({
3425
3988
  - `guid` is required: it keeps the icon's place in the tray and names the one
3426
3989
  tray process, so a second `tray.js` exits at once
3427
3990
  - `onactivate` runs on a left click when `onclick` is not given
3991
+ - `export default [defineTray({ ... }), defineTray({ ... })]` defines several
3992
+ trays in one entrypoint: one `tray.js`, one process, each tray with its own
3993
+ `guid`, icon, tooltip, menu and `colorScheme` (every `guid` must differ)
3994
+ The first tray's `guid` names the process, so keep the order; `tray.json` is
3995
+ the single manifest for one tray and `{ "trays": [ ... ] }` for several, and
3996
+ `startTray()` reads the first `guid` from either
3997
+ The markup form (`tray.svelte`) is one tray; use `tray.ts` for several
3998
+ `examples/tray-multiple` is a two-icon entrypoint with no window
3428
3999
  - The build reads `icon`, `tooltip` and `guid` from the syntax tree, never by
3429
4000
  running the file, so a top-level import of WinRT in `tray.ts` does not
3430
4001
  execute at build; `icon` and `guid` must be string literals, and the icon a
@@ -3773,6 +4344,46 @@ const lines = menus.menu(ContextMenuSurface.TRAY);
3773
4344
  `ContextMenuSurface`, `ContextType`, `ChromeEvent`, and the types
3774
4345
  `CreateProperties`, `OnClickData` and `UpdateProperties`
3775
4346
 
4347
+ ## Security (`winui-svelte/security`)
4348
+
4349
+ Windows DPAPI for secrets an app keeps on disk, with nothing to install: no
4350
+ native addon, no WinRT, only the Win32 calls through the package's own binder
4351
+ Opt-in: nothing is bundled until an app imports it (about 3 KB), and importing
4352
+ does no work
4353
+
4354
+ The blob is the one .NET's `ProtectedData.Protect` makes, so a TypeScript app
4355
+ reads the files a .NET app wrote with `CurrentUser` scope, and the other way
4356
+ round; `ProtectionScope` is `DataProtectionScope`'s two values
4357
+
4358
+ ```ts
4359
+ import { ProtectionScope, protectData, unprotectData, wipe } from "winui-svelte/security";
4360
+
4361
+ const sealed = protectData({
4362
+ data: new TextEncoder().encode(apiKey),
4363
+ scope: ProtectionScope.CURRENT_USER
4364
+ });
4365
+ await writeFile("settings.bin", sealed);
4366
+
4367
+ const plain = unprotectData({ data: await readFile("settings.bin") });
4368
+ useKey(new TextDecoder().decode(plain));
4369
+ wipe(plain);
4370
+ ```
4371
+
4372
+ - `protectData({ data, entropy?, scope?, description? })` returns the sealed
4373
+ bytes; `entropy` is mixed into the key and needed again to unseal
4374
+ - `unprotectData({ data, entropy?, scope? })` returns the plain bytes
4375
+ - `wipe(buffer)` zeroes a buffer; the native buffers the helper used are zeroed
4376
+ before release, the copies you hold are yours to wipe, and a string cannot be
4377
+ wiped, so keep secrets as bytes
4378
+ - `DataProtectionError` carries the Win32 `code` (87 for bytes that are no
4379
+ blob, 13 for a corrupted blob or the wrong entropy); the message never holds
4380
+ the data
4381
+ - `MAX_DATA_BYTES` (64 MiB) is the limit of one call; more throws `RangeError`
4382
+ - A UI prompt can never appear (`CRYPTPROTECT_UI_FORBIDDEN`)
4383
+ - DPAPI offers no recovery: keys follow the user's logon secret, so an
4384
+ administrator's password reset can make old blobs unreadable; a packaged app
4385
+ keeps the same user keys as an unpackaged one
4386
+
3776
4387
  ## Downloads (`winui-svelte/downloads`)
3777
4388
 
3778
4389
  Downloads on the two APIs an app already knows: the web's `fetch` with the File
@@ -4447,8 +5058,12 @@ pixels), `offsetX`/`offsetY` (the control), `altKey`, `ctrlKey`, `shiftKey`,
4447
5058
  `DataTransfer` has `types`, `files`, `items` (`DataTransferItemList`: `length`,
4448
5059
  `at`, `add`, iteration; items have `kind`, `type`, `getAsString`, `getAsFile`),
4449
5060
  `getData(type)`, `setData(type, value)`, `clearData(type?)`, `effectAllowed`
4450
- (`EffectAllowed`), `dropEffect` (`DropEffect`), `setDragImage` (accepted, WinUI
4451
- draws its own preview) and `bitmap` (a picture to drag)
5061
+ (`EffectAllowedName`), `dropEffect` (`DropEffectName`), `setDragImage` (accepted,
5062
+ WinUI draws its own preview) and `bitmap` (a picture to drag)
5063
+ `DropEffect` and `EffectAllowed` hold the names, so an editor suggests
5064
+ `DropEffect.link`; `DropEffectName` and `EffectAllowedName` are those names or
5065
+ any other string, and an unknown string counts as `none` for a drop effect and
5066
+ as `uninitialized` (everything allowed) for `effectAllowed`
4452
5067
  The standard formats are `text/plain` (Text), `text/html` (the fragment of the
4453
5068
  HTML format), `text/uri-list` (Uri), `Files` (StorageItems) and, for a picture,
4454
5069
  a `NativeFile` in `files`; any other format id is a custom text format, listed
@@ -4485,6 +5100,36 @@ window's content to take drops anywhere on the window
4485
5100
  `onDragEnter`, `onDragOver`, `onDragLeave` and `onDrop` take the same
4486
5101
  `DragEvent` as the web names
4487
5102
 
5103
+ Which part of the window takes a drag (accepting selectively):
5104
+
5105
+ - only a zone takes a drag; a point outside every zone shows the forbidden sign,
5106
+ so a section of the window is the only place that accepts when it alone has
5107
+ `dropzone`
5108
+ - the zone under the cursor answers; with nested zones the innermost one
5109
+ decides, and a zone that refuses (its `accept` takes nothing the drag
5110
+ carries) refuses for its whole area even when an outer zone would accept
5111
+ - a zone on the root element of the window is the window-wide default; put a
5112
+ zone with a narrower `accept` (or one that refuses) on a section to
5113
+ override it there
5114
+ - `accept` is judged per zone, so one window can have a folder-only zone and a
5115
+ text-only zone side by side
5116
+ - a drag that started inside the window (a list reordering its own items)
5117
+ carries no files, so a zone with `accept: ["directory", ".zip"]` leaves it to
5118
+ the control
5119
+
5120
+ A drag from another app (Explorer, a browser) reaches a WinUI 3 window as an OLE
5121
+ drag, and WinUI 3 registers no OLE drop target on its window: without one,
5122
+ Windows shows the forbidden sign over the whole window and no `dragenter` ever
5123
+ fires
5124
+ The first zone of a window registers one (`RegisterDragDrop` on the top-level
5125
+ window, `src/data-transfer/ole-drop-target.ts`), and it is revoked with the
5126
+ last zone or when the window is destroyed; each call is routed to the zone under
5127
+ the cursor by a hit test of the visual tree (`src/data-transfer/window-drop.ts`)
5128
+ The data object is read through the classic formats (files and folders as
5129
+ `CF_HDROP`, text, a link, HTML); a dragged picture from another app is not read
5130
+ yet
5131
+ `simulateDrop` stays the way to test a zone without any OLE call
5132
+
4488
5133
  `draggable(options)`: `text`, `html`, `uri`, `files`, `bitmap`, `effectAllowed`,
4489
5134
  and `onDragStart` / `onDrag` / `onDragEnd`
4490
5135
  Drag out to Explorer works with `files` (paths become `StorageFile` and
@@ -4556,6 +5201,170 @@ takes drops, through the handlers a real drop reaches, and resolves with the
4556
5201
  operation the control accepted (`0` when it refused); it sends no input, so an
4557
5202
  app can test its drop handling in a real window
4558
5203
 
5204
+ ## Progress (`winui-svelte/progress`)
5205
+
5206
+ One progress object for any long work: a download, a file read, a copy, an OCR
5207
+ pass; it is a promise, an `EventTarget` with the platform events, and
5208
+ reactive state, in one value
5209
+ Operations list themselves in an app-wide registry, so the taskbar button and
5210
+ the tray show them with no setup
5211
+ Opt-in: nothing is bundled until an app imports it, and importing does no work
5212
+
5213
+ ### Five call sites
5214
+
5215
+ ```svelte
5216
+ <script lang="ts">
5217
+ import { Button, ProgressBar, TextBlock, Window } from "winui-svelte/components";
5218
+ import { fetchToFile } from "winui-svelte/downloads";
5219
+ import { TaskbarProgress } from "winui-svelte/progress";
5220
+
5221
+ // 1. A download with a bar: fetchToFile returns the operation at once
5222
+ const download = fetchToFile({ url, handle });
5223
+ download.then(size => console.log("saved", size)); // or: await download
5224
+ </script>
5225
+
5226
+ <Window>
5227
+ <TaskbarProgress /> <!-- 4. the taskbar shows every running operation -->
5228
+ <ProgressBar {...download.barProps} /> <!-- value, isIndeterminate, showPaused, showError -->
5229
+ <TextBlock>{download.loaded} of {download.total ?? "?"}</TextBlock>
5230
+ <Button onclick={() => download.cancel()}>Cancel</Button>
5231
+ </Window>
5232
+ ```
5233
+
5234
+ ```ts
5235
+ // 2. Reading a file from disk, with progress and cancel
5236
+ const read = handle.read({ onprogress: event => console.log(event.loaded, event.total) });
5237
+ const file = await read; // a File, like getFile()
5238
+ read.cancel(); // or abort the signal given in the options
5239
+
5240
+ // 3. Any other long work: one call, no lifecycle code
5241
+ const copy = trackOperation({
5242
+ label: "Copying photos",
5243
+ group: "sync",
5244
+ async run(operation) {
5245
+ for await (const chunk of source) {
5246
+ await write(chunk);
5247
+ operation.update({ loaded: (written += chunk.byteLength), total });
5248
+ operation.signal.throwIfAborted();
5249
+ }
5250
+ }
5251
+ });
5252
+
5253
+ // 5. Retry: a failed fetchToFile continues where it stopped
5254
+ await fetchToFile({ url, handle, resume: true });
5255
+ ```
5256
+
5257
+ ```svelte
5258
+ <!-- Tray menu, in tray.svelte markup -->
5259
+ <TrayMenu>
5260
+ <TrayMenuProgress id="progress" /> <!-- "setup.exe - 45%", hidden when idle -->
5261
+ <TrayMenuOperations id="operations" label="Running" emptyLabel="Nothing running" />
5262
+ </TrayMenu>
5263
+ ```
5264
+
5265
+ `{...download.barProps}` spreads onto a `ProgressBar`; Svelte then cannot tell
5266
+ at build time whether a scoped class selector matches that bar, so write the
5267
+ five props out when the same component has a `<style>` rule for its siblings
5268
+
5269
+ ### Several windows and tray icons
5270
+
5271
+ The registry is app-wide; what a taskbar button or a tray line shows is scoped
5272
+ by `group` (a name an operation is given) or by an operation or registry given
5273
+ as `of`
5274
+ A `<TaskbarProgress />` drives the taskbar button of the window it sits in;
5275
+ `window={handle}` picks another
5276
+
5277
+ ```svelte
5278
+ <script lang="ts">
5279
+ const upload = trackOperation({ group: "uploads", run });
5280
+ const download = fetchToFile({ url, handle, group: "downloads" });
5281
+ </script>
5282
+
5283
+ <!-- Window A: its taskbar button shows the downloads only -->
5284
+ <Window bind:handle={windowA}>
5285
+ <TaskbarProgress group="downloads" />
5286
+ </Window>
5287
+
5288
+ <!-- Window B: its own button shows one upload; window A is not touched -->
5289
+ <Window>
5290
+ <TaskbarProgress of={upload} />
5291
+ </Window>
5292
+
5293
+ <!-- The main window drives window A from outside -->
5294
+ <TaskbarProgress window={windowA} group="downloads" />
5295
+
5296
+ <!-- Two tray icons, each with its own menu and its own scope -->
5297
+ <TrayIcon>
5298
+ <TrayMenu>
5299
+ <TrayMenuProgress id="downloads" group="downloads" />
5300
+ </TrayMenu>
5301
+ </TrayIcon>
5302
+ <TrayIcon>
5303
+ <TrayMenu>
5304
+ <TrayMenuOperations id="uploads" label="Uploads" group="uploads" />
5305
+ </TrayMenu>
5306
+ </TrayIcon>
5307
+ ```
5308
+
5309
+ ### `ProgressOperation`
5310
+
5311
+ - It is `PromiseLike`: `await operation` gives the value passed to `complete`
5312
+ and throws the reason of `fail` or `cancel` (an `AbortError` by default); an
5313
+ operation nobody awaits raises no unhandled rejection
5314
+ - It is an `EventTarget` that fires `loadstart`, `progress`, `load`, `error`,
5315
+ `abort` and `loadend` as `OperationProgressEvent` (`lengthComputable`,
5316
+ `loaded`, `total`), in the order `XMLHttpRequest` and `FileReader` use, plus
5317
+ `pause`, `resume` and `change`; `onprogress` and its kin work as properties
5318
+ and as options
5319
+ - `value` (0 to 1), `loaded`, `total`, `state`, `isIndeterminate`,
5320
+ `showPaused`, `showError`, `label` and `barProps` are reactive in markup and
5321
+ in `$effect`, with the meaning `ProgressBar` gives them: a total that is
5322
+ unknown is indeterminate
5323
+ - `$operation` works too: it has `subscribe` and so is a Svelte store
5324
+ - `signal` is an `AbortSignal` that aborts on `cancel()`; a `signal` given to
5325
+ the constructor cancels the operation when it aborts
5326
+ - `start`, `update({ loaded, total })`, `pause`, `resume`, `complete(value)`
5327
+ and `fail(reason)` are for the code doing the work; `resume` also retries an
5328
+ errored operation (the other final states are final)
5329
+ - `ProgressState` is the closed set of states: `idle`, `running`, `paused`,
5330
+ `complete`, `error`, `canceled`
5331
+
5332
+ ### Registry and scopes
5333
+
5334
+ - `defaultProgressRegistry()` is the app-wide registry; an operation lists
5335
+ itself there unless it gets `registry: otherRegistry` or `registry: false`
5336
+ - A finished or canceled operation leaves; a failed one stays so a red bar
5337
+ is not lost, until `clearFailed()` or `remove(operation)`
5338
+ - `registry.where("sync")` or `registry.where(operation => ...)` is a scoped
5339
+ registry that follows the first (call `dispose()` when done);
5340
+ `<TaskbarProgress group>` and the tray components do this for you
5341
+ - `snapshot`, `value`, `count`, `state`, `isIndeterminate`, `showPaused` and
5342
+ `showError` are the aggregate: the bar covers the operations that know their
5343
+ total, and is indeterminate only when none does; `paused` when all that are
5344
+ left are paused; `error` when only failed ones are left; `count` is the
5345
+ number unfinished
5346
+ - `aggregateSnapshots` is that rule as a pure function
5347
+
5348
+ ### Taskbar and tray
5349
+
5350
+ - `<TaskbarProgress of group window taskbar />` draws nothing and keeps the
5351
+ taskbar button in step: a bar, a marquee when the total is unknown, paused
5352
+ yellow, error red, gone when nothing is left; the shell is told only when the
5353
+ bar moves by a thousandth
5354
+ - `bindTaskbarProgress({ source, taskbar })` is the same without markup (the
5355
+ `taskbar` option of `Downloads.download` uses it); `taskbarOptionsOf` is the
5356
+ mapping
5357
+ - `<TrayMenuProgress id of group />` is a command line with the text of
5358
+ `progressText(snapshot)`, hidden while nothing runs; `onselect` is yours
5359
+ - `<TrayMenuOperations id label of group />` is a submenu with a line per
5360
+ running operation; picking a line cancels it
5361
+ - `Downloads` gives each download an operation (`progress: registry` in its
5362
+ options picks the registry, `group` in `download({ ... })` the group), and
5363
+ `fetchToFile` returns one; `FileSystemFileHandle.read` is the extra (WinUI
5364
+ only) that reads a file in 1 MiB chunks
5365
+ - `trackStream({ stream, operation })` passes a `ReadableStream` through and
5366
+ reports the bytes; `trackOperation` is the whole lifecycle for any async work
5367
+
4559
5368
  ## Incremental loading (`winui-svelte/incremental`)
4560
5369
 
4561
5370
  A list that loads its next batch as the user scrolls near the end, for
@@ -4666,6 +5475,10 @@ Everything runs on the UI thread
4666
5475
  </border>
4667
5476
  ```
4668
5477
 
5478
+ `modifierKeysHeld()` reads which of Shift, Control and Alt are held right now, as
5479
+ `{ shiftKey, ctrlKey, altKey }`, for an action that carries no key state of its
5480
+ own (a form submitted with the keyboard, a file picker's result)
5481
+
4669
5482
  `enableInputEvents()` adds the eleven names to the renderer's event-alias table
4670
5483
  (`src/renderer/host/event-adapters.ts`, the one `enableDragEvents()` fills), so a
4671
5484
  raw element takes them
@@ -6210,6 +7023,54 @@ The effect graph is checked on pixels without a window
6210
7023
  (`src/win2d/effect-graph.test.ts`), and the effects in a real window through
6211
7024
  `PrintWindow` (`test/effects.test.ts`, with `examples/effects`)
6212
7025
 
7026
+ ### Packaged apps
7027
+
7028
+ A process with a package identity (an MSIX, or a registered loose layout) finds
7029
+ a class through its package's registration catalogue, which lists the classes
7030
+ of its framework packages and the `ActivatableClass` entries of its own
7031
+ manifest; the `PATH` that `initWindowsAppSdk` sets is not consulted
7032
+ Win2D ships no framework package, so every Win2D class fails there with
7033
+ `0x80040154` (class not registered) until the manifest names it, and CSS
7034
+ `filter: blur()` and every Win2D effect do nothing
7035
+ The same app unpackaged (`pnpm dev`) is fine
7036
+
7037
+ `win2dActivatableClasses` writes the entries, one `ActivatableClass` of one
7038
+ `InProcessServer` per Win2D class the bindings hold; put the result in the
7039
+ package's own `<Extensions>` (a child of `<Package>`, after `<Capabilities>`,
7040
+ not the application's), with `Microsoft.Graphics.Canvas.dll` in the package at
7041
+ `libraryPath`, which `buildApp` writes to `bin/<architecture>`
7042
+
7043
+ ```ts
7044
+ import { win2dActivatableClasses } from "winui-svelte/win2d/manifest";
7045
+
7046
+ const fragment = win2dActivatableClasses({
7047
+ libraryPath: "bin/x64/Microsoft.Graphics.Canvas.dll"
7048
+ });
7049
+ ```
7050
+
7051
+ ```xml
7052
+ <Extensions>
7053
+ <Extension Category="windows.activatableClass.inProcessServer">
7054
+ <InProcessServer>
7055
+ <Path>bind\Microsoft.Graphics.Canvas.dll</Path>
7056
+ <ActivatableClass ActivatableClassId="Microsoft.Graphics.Canvas.Effects.GaussianBlurEffect" ThreadingModel="both" />
7057
+ </InProcessServer>
7058
+ </Extension>
7059
+ </Extensions>
7060
+ ```
7061
+
7062
+ - `classes` limits the list (an app that only blurs needs a few); by default it
7063
+ is every class the bindings activate by name (`win2dClassNames()`, which
7064
+ reads them from the bindings; `bindings` names another folder)
7065
+ - `libraryPath` is per architecture: an x64 and an arm64 package each have
7066
+ their own manifest, and the path is relative to the package root
7067
+ - Without the entries a packaged app writes one line to stderr that names this
7068
+ fragment, not one per class
7069
+ - `test/win2d-packaged.test.ts` proves it in a real registered package
7070
+ (`WINUI_SVELTE_PACKAGED_TEST=1`, `examples/win2d-packaged`): without the
7071
+ entries the canvas never draws and `0x80040154` is reported; with them it
7072
+ redraws and stderr is empty
7073
+
6213
7074
  ### Canvas 2D (`winui-svelte/win2d/context-2d`)
6214
7075
 
6215
7076
  Opt-in, and a separate subpath: an app that imports only `winui-svelte/win2d`
@@ -6331,6 +7192,78 @@ The working example is `examples/win2d` (`test/win2d.test.ts` runs it in a real
6331
7192
  window and checks the redraw; `src/win2d/win2d.test.ts` draws on a render
6332
7193
  target and checks the pixels)
6333
7194
 
7195
+ ## UI Automation client (`winui-svelte/automation`)
7196
+
7197
+ Read the exact text and headings of another window, instead of OCR; the
7198
+ counterpart of the Accessibility section, which provides automation to
7199
+ others, while this one consumes it; no web API reads another application's
7200
+ window, so this mirrors none; it is opt-in and bundles COM only when imported
7201
+
7202
+ ```ts
7203
+ import { createUiaWorker } from "winui-svelte/automation";
7204
+
7205
+ const worker = createUiaWorker();
7206
+ const text = await worker.readText({
7207
+ target: "foreground",
7208
+ excludeProcessId: process.pid,
7209
+ hardMilliseconds: 1500
7210
+ });
7211
+ // { title, blocks: [{ kind: "heading", level: 1, text }, ...], version, end }
7212
+ ```
7213
+
7214
+ `readText` runs in a worker thread in the multithreaded COM apartment; a target
7215
+ that hangs makes the call reject with `UiaTimeout` after `hardMilliseconds`,
7216
+ the worker is ended and the next call starts a new one (a blocked COM call
7217
+ cannot be cancelled); it resolves null when there is no window to read, the
7218
+ window is the excluded process's or an elevated one
7219
+
7220
+ For the lower level, `withUiaClient` gives a client on the calling thread
7221
+ (call it from a thread that joined a COM apartment) and releases every COM
7222
+ pointer it made when the callback ends:
7223
+
7224
+ ```ts
7225
+ import { UiaControlType, withUiaClient } from "winui-svelte/automation";
7226
+
7227
+ const lines = await withUiaClient(client => {
7228
+ const root = client.elementFromHandle(hwnd);
7229
+ if (root === null) {
7230
+ return [];
7231
+ }
7232
+
7233
+ const found: string[] = [];
7234
+ const walk = client.walk({
7235
+ root,
7236
+ maxElements: 400,
7237
+ maxMilliseconds: 400,
7238
+ shouldVisit: ({ controlType, isOffscreen }) => !isOffscreen && controlType !== UiaControlType.button
7239
+ });
7240
+ for (const node of walk) {
7241
+ const ranges = node.pattern("text")?.visibleRanges() ?? [];
7242
+ found.push(...ranges.map(range => range.getText(1000)));
7243
+ }
7244
+
7245
+ return found;
7246
+ });
7247
+ ```
7248
+
7249
+ | Call | What |
7250
+ |---|---|
7251
+ | `withUiaClient(use)` | creates `CUIAutomation`, runs `use(client)`, releases everything; an element used after that throws `UiaScopeEndedError` |
7252
+ | `client.elementFromHandle(hwnd)`, `client.focusedElement()` | an element, or null when it is gone or cannot be read |
7253
+ | `element.properties()` | `name`, `className`, `automationId`, `controlType`, `processId`, `isOffscreen`, `boundingRectangle`, `headingLevel` (0 for none, 1 to 9), `hasTextPattern`, `hasValuePattern` |
7254
+ | `client.walk({ root, maxElements, maxMilliseconds, shouldVisit })` | breadth first over the control view, one cached call per parent (`FindAllBuildCache`); `walk.end` is `complete`, `maxElements` or `deadline`; an element that went away is skipped; `node.skipSubtree()` prunes |
7255
+ | `element.pattern("text")` | `visibleRanges()`, `documentRange()`, and `range.getText(maxLength)` |
7256
+ | `element.pattern("value")` | `value` |
7257
+ | `readWindowText({ client, root })` | the headings and text of a window, skipping chrome and off screen elements (`UIA_CHROME_CONTROL_TYPES`); `version` changes when the text does |
7258
+ | `createUiaWorker()` | `readText({ target, excludeProcessId, hardMilliseconds, ... })` with the hard deadline; `close()` |
7259
+ | `UiaControlType`, `UiaPropertyId`, `UiaPatternName`, `HEADING_LEVEL_NONE`, `HEADING_LEVEL_FIRST` | the header's ids as `as const` sets and constants (the sets also under `winui-svelte/enums`) |
7260
+ | `UiaWalkEnd`, `TextBlockKind`, `UiaTarget` | the closed sets of a walk's end, a block's kind and a worker target (`foreground`, `focused`, or `{ hwnd }`) |
7261
+ | `UiaElementUnavailableError`, `UiaScopeEndedError`, `UiaTimeout` | the errors: an element went away, a client was used after its scope, a target did not answer in time |
7262
+
7263
+ Elements an app cannot read (elevated windows) come back as null, never an
7264
+ exception; browsers and Electron build their tree when the first client asks,
7265
+ so the first walk of such a window can be slower
7266
+
6334
7267
  ## Windows devices (`winui-svelte/devices`)
6335
7268
 
6336
7269
  Windows' own device APIs (`Windows.Devices.*`, `Windows.System.Power`,