winui-svelte 0.0.7 → 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.
- package/API.md +565 -19
- package/README.md +21 -5
- package/dist/app/activate.d.ts.map +1 -1
- package/dist/app/activate.js +3 -0
- package/dist/app/activate.js.map +1 -1
- package/dist/app/activation/index.d.ts +3 -0
- package/dist/app/activation/index.d.ts.map +1 -1
- package/dist/app/activation/index.js +2 -0
- package/dist/app/activation/index.js.map +1 -1
- package/dist/app/activation/login.d.ts +2 -1
- package/dist/app/activation/login.d.ts.map +1 -1
- package/dist/app/activation/login.js +2 -1
- package/dist/app/activation/login.js.map +1 -1
- package/dist/app/activation/native.js +1 -2
- package/dist/app/activation/native.js.map +1 -1
- package/dist/app/activation/packaged.d.ts +49 -0
- package/dist/app/activation/packaged.d.ts.map +1 -0
- package/dist/app/activation/packaged.js +90 -0
- package/dist/app/activation/packaged.js.map +1 -0
- package/dist/app/activation/receive.d.ts +11 -2
- package/dist/app/activation/receive.d.ts.map +1 -1
- package/dist/app/activation/receive.js +11 -4
- package/dist/app/activation/receive.js.map +1 -1
- package/dist/app/activation/registration.d.ts +3 -3
- package/dist/app/activation/registration.js +7 -7
- package/dist/app/activation/registration.js.map +1 -1
- package/dist/app/activation/scheme.d.ts +10 -0
- package/dist/app/activation/scheme.d.ts.map +1 -1
- package/dist/app/activation/scheme.js +17 -0
- package/dist/app/activation/scheme.js.map +1 -1
- package/dist/app/index.d.ts +4 -2
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +3 -1
- package/dist/app/index.js.map +1 -1
- package/dist/app/instance-running.d.ts +15 -0
- package/dist/app/instance-running.d.ts.map +1 -0
- package/dist/app/instance-running.js +20 -0
- package/dist/app/instance-running.js.map +1 -0
- package/dist/app/jump-list/native.d.ts.map +1 -1
- package/dist/app/jump-list/native.js +1 -2
- package/dist/app/jump-list/native.js.map +1 -1
- package/dist/app/native-messaging/browsers.d.ts +19 -0
- package/dist/app/native-messaging/browsers.d.ts.map +1 -0
- package/dist/app/native-messaging/browsers.js +17 -0
- package/dist/app/native-messaging/browsers.js.map +1 -0
- package/dist/app/native-messaging/index.d.ts +41 -0
- package/dist/app/native-messaging/index.d.ts.map +1 -0
- package/dist/app/native-messaging/index.js +84 -0
- package/dist/app/native-messaging/index.js.map +1 -0
- package/dist/app/native.d.ts +0 -6
- package/dist/app/native.d.ts.map +1 -1
- package/dist/app/native.js +1 -24
- package/dist/app/native.js.map +1 -1
- package/dist/app/notification-source.d.ts.map +1 -1
- package/dist/app/notification-source.js +1 -2
- package/dist/app/notification-source.js.map +1 -1
- package/dist/app/shell/native.js +1 -2
- package/dist/app/shell/native.js.map +1 -1
- package/dist/app/single-instance.d.ts +27 -1
- package/dist/app/single-instance.d.ts.map +1 -1
- package/dist/app/single-instance.js +32 -10
- package/dist/app/single-instance.js.map +1 -1
- package/dist/automation/native.d.ts.map +1 -1
- package/dist/automation/native.js +1 -2
- package/dist/automation/native.js.map +1 -1
- package/dist/bindings/.dynwinrt-js-types +198 -0
- package/dist/bindings/.dynwinrt-managed +1 -1
- package/dist/bindings/index.d.ts +15 -0
- package/dist/bindings/index.js +20 -0
- package/dist/bindings/index.mjs +2902 -2882
- package/dist/bindings/index.proxy.js +10 -0
- package/dist/bindings/windows/application-model/activation/ActivationKind.d.ts +49 -0
- package/dist/bindings/windows/application-model/activation/ActivationKind.js +50 -0
- package/dist/bindings/windows/application-model/activation/ApplicationExecutionState.d.ts +9 -0
- package/dist/bindings/windows/application-model/activation/ApplicationExecutionState.js +10 -0
- package/dist/bindings/windows/application-model/activation/IActivatedEventArgs.d.ts +36 -0
- package/dist/bindings/windows/application-model/activation/IActivatedEventArgs.js +149 -0
- package/dist/bindings/windows/application-model/activation/IActivatedEventArgsWithUser.d.ts +28 -0
- package/dist/bindings/windows/application-model/activation/IActivatedEventArgsWithUser.js +119 -0
- package/dist/bindings/windows/application-model/activation/IApplicationViewActivatedEventArgs.d.ts +27 -0
- package/dist/bindings/windows/application-model/activation/IApplicationViewActivatedEventArgs.js +116 -0
- package/dist/bindings/windows/application-model/activation/IProtocolActivatedEventArgsWithCallerPackageFamilyNameAndData.d.ts +31 -0
- package/dist/bindings/windows/application-model/activation/IProtocolActivatedEventArgsWithCallerPackageFamilyNameAndData.js +131 -0
- package/dist/bindings/windows/application-model/activation/IViewSwitcherProvider.d.ts +28 -0
- package/dist/bindings/windows/application-model/activation/IViewSwitcherProvider.js +119 -0
- package/dist/bindings/windows/application-model/activation/ProtocolActivatedEventArgs.d.ts +25 -0
- package/dist/bindings/windows/application-model/activation/ProtocolActivatedEventArgs.js +166 -0
- package/dist/bindings/windows/application-model/activation/SplashScreen.d.ts +35 -0
- package/dist/bindings/windows/application-model/activation/SplashScreen.js +105 -0
- package/dist/bindings/windows/foundation/TypedEventHandler_WindowsApplicationModelActivationSplashScreen_Object_g7a7dbfa699cd28ff.d.ts +7 -0
- package/dist/bindings/windows/foundation/TypedEventHandler_WindowsApplicationModelActivationSplashScreen_Object_g7a7dbfa699cd28ff.js +7 -0
- package/dist/bindings/windows/ui/view-management/ActivationViewSwitcher.d.ts +12 -0
- package/dist/bindings/windows/ui/view-management/ActivationViewSwitcher.js +96 -0
- package/dist/chrome/context-menus/context-menu-schema.d.ts.map +1 -1
- package/dist/chrome/context-menus/context-menu-schema.js +1 -7
- package/dist/chrome/context-menus/context-menu-schema.js.map +1 -1
- package/dist/chrome/parse-or-throw.d.ts +7 -0
- package/dist/chrome/parse-or-throw.d.ts.map +1 -0
- package/dist/chrome/parse-or-throw.js +9 -0
- package/dist/chrome/parse-or-throw.js.map +1 -0
- package/dist/chrome/permissions/permission-schema.d.ts.map +1 -1
- package/dist/chrome/permissions/permission-schema.js +1 -7
- package/dist/chrome/permissions/permission-schema.js.map +1 -1
- package/dist/chrome/windows/chrome-windows.d.ts.map +1 -1
- package/dist/chrome/windows/chrome-windows.js +1 -7
- package/dist/chrome/windows/chrome-windows.js.map +1 -1
- package/dist/components/hand-written/items/keyed-rows.svelte.d.ts.map +1 -1
- package/dist/components/hand-written/items/keyed-rows.svelte.js +6 -0
- package/dist/components/hand-written/items/keyed-rows.svelte.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/runtime.svelte.d.ts.map +1 -1
- package/dist/components/runtime.svelte.js +7 -0
- package/dist/components/runtime.svelte.js.map +1 -1
- package/dist/composition/expression.d.ts +1 -1
- package/dist/css/runtime/containers.d.ts.map +1 -1
- package/dist/css/runtime/containers.js +1 -17
- package/dist/css/runtime/containers.js.map +1 -1
- package/dist/css/runtime/native.d.ts.map +1 -1
- package/dist/css/runtime/native.js +40 -20
- package/dist/css/runtime/native.js.map +1 -1
- package/dist/css/translate/property-kit.d.ts +9 -0
- package/dist/css/translate/property-kit.d.ts.map +1 -1
- package/dist/css/translate/property-kit.js.map +1 -1
- package/dist/css/translate/transition-properties.d.ts +1 -1
- package/dist/css/translate/transition-properties.d.ts.map +1 -1
- package/dist/css/translate/transition-properties.js +32 -5
- package/dist/css/translate/transition-properties.js.map +1 -1
- package/dist/data-transfer/data-transfer.d.ts +3 -3
- package/dist/data-transfer/data-transfer.d.ts.map +1 -1
- package/dist/data-transfer/data-transfer.js.map +1 -1
- package/dist/data-transfer/drag-effects.d.ts +25 -2
- package/dist/data-transfer/drag-effects.d.ts.map +1 -1
- package/dist/data-transfer/drag-effects.js +27 -2
- package/dist/data-transfer/drag-effects.js.map +1 -1
- package/dist/data-transfer/drag-helper.d.ts +50 -0
- package/dist/data-transfer/drag-helper.d.ts.map +1 -0
- package/dist/data-transfer/drag-helper.js +156 -0
- package/dist/data-transfer/drag-helper.js.map +1 -0
- package/dist/data-transfer/drop-target.d.ts +6 -5
- package/dist/data-transfer/drop-target.d.ts.map +1 -1
- package/dist/data-transfer/drop-target.js +68 -20
- package/dist/data-transfer/drop-target.js.map +1 -1
- package/dist/data-transfer/index.d.ts +1 -0
- package/dist/data-transfer/index.d.ts.map +1 -1
- package/dist/data-transfer/index.js.map +1 -1
- package/dist/data-transfer/launcher.d.ts +4 -3
- package/dist/data-transfer/launcher.d.ts.map +1 -1
- package/dist/data-transfer/launcher.js +58 -9
- package/dist/data-transfer/launcher.js.map +1 -1
- package/dist/data-transfer/native.d.ts +66 -0
- package/dist/data-transfer/native.d.ts.map +1 -0
- package/dist/data-transfer/native.js +148 -0
- package/dist/data-transfer/native.js.map +1 -0
- package/dist/data-transfer/ole-data-object.d.ts +62 -0
- package/dist/data-transfer/ole-data-object.d.ts.map +1 -0
- package/dist/data-transfer/ole-data-object.js +162 -0
- package/dist/data-transfer/ole-data-object.js.map +1 -0
- package/dist/data-transfer/ole-drop-target.d.ts +54 -0
- package/dist/data-transfer/ole-drop-target.d.ts.map +1 -0
- package/dist/data-transfer/ole-drop-target.js +192 -0
- package/dist/data-transfer/ole-drop-target.js.map +1 -0
- package/dist/data-transfer/share-interop.d.ts.map +1 -1
- package/dist/data-transfer/share-interop.js +1 -1
- package/dist/data-transfer/share-interop.js.map +1 -1
- package/dist/data-transfer/shell-items.d.ts +10 -0
- package/dist/data-transfer/shell-items.d.ts.map +1 -0
- package/dist/data-transfer/shell-items.js +67 -0
- package/dist/data-transfer/shell-items.js.map +1 -0
- package/dist/data-transfer/window-drop.d.ts +35 -0
- package/dist/data-transfer/window-drop.d.ts.map +1 -0
- package/dist/data-transfer/window-drop.js +311 -0
- package/dist/data-transfer/window-drop.js.map +1 -0
- package/dist/devices/native.js +1 -2
- package/dist/devices/native.js.map +1 -1
- package/dist/enums.d.ts +3 -0
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +3 -0
- package/dist/enums.js.map +1 -1
- package/dist/input/index.d.ts +2 -0
- package/dist/input/index.d.ts.map +1 -1
- package/dist/input/index.js +1 -0
- package/dist/input/index.js.map +1 -1
- package/dist/input/modifier-keys.d.ts +24 -0
- package/dist/input/modifier-keys.d.ts.map +1 -0
- package/dist/input/modifier-keys.js +20 -0
- package/dist/input/modifier-keys.js.map +1 -0
- package/dist/media/pixel-buffer.d.ts.map +1 -1
- package/dist/media/pixel-buffer.js +1 -1
- package/dist/media/pixel-buffer.js.map +1 -1
- package/dist/messaging/web-view2/core.d.ts +56 -0
- package/dist/messaging/web-view2/core.d.ts.map +1 -1
- package/dist/messaging/web-view2/core.js +6 -0
- package/dist/messaging/web-view2/core.js.map +1 -1
- package/dist/messaging/web-view2/environment.d.ts +41 -0
- package/dist/messaging/web-view2/environment.d.ts.map +1 -0
- package/dist/messaging/web-view2/environment.js +91 -0
- package/dist/messaging/web-view2/environment.js.map +1 -0
- package/dist/messaging/web-view2/index.d.ts +9 -1
- package/dist/messaging/web-view2/index.d.ts.map +1 -1
- package/dist/messaging/web-view2/index.js +5 -0
- package/dist/messaging/web-view2/index.js.map +1 -1
- package/dist/messaging/web-view2/input.d.ts +68 -0
- package/dist/messaging/web-view2/input.d.ts.map +1 -0
- package/dist/messaging/web-view2/input.js +108 -0
- package/dist/messaging/web-view2/input.js.map +1 -0
- package/dist/messaging/web-view2/protocol.d.ts +24 -0
- package/dist/messaging/web-view2/protocol.d.ts.map +1 -0
- package/dist/messaging/web-view2/protocol.js +31 -0
- package/dist/messaging/web-view2/protocol.js.map +1 -0
- package/dist/messaging/web-view2/recovery.d.ts +65 -0
- package/dist/messaging/web-view2/recovery.d.ts.map +1 -0
- package/dist/messaging/web-view2/recovery.js +138 -0
- package/dist/messaging/web-view2/recovery.js.map +1 -0
- package/dist/messaging/web-view2/requests.d.ts +88 -0
- package/dist/messaging/web-view2/requests.d.ts.map +1 -0
- package/dist/messaging/web-view2/requests.js +169 -0
- package/dist/messaging/web-view2/requests.js.map +1 -0
- package/dist/messaging/web-view2/transport.d.ts.map +1 -1
- package/dist/messaging/web-view2/transport.js +1 -4
- package/dist/messaging/web-view2/transport.js.map +1 -1
- package/dist/native-identity.d.ts +10 -0
- package/dist/native-identity.d.ts.map +1 -0
- package/dist/native-identity.js +20 -0
- package/dist/native-identity.js.map +1 -0
- package/dist/renderer/host/host.d.ts.map +1 -1
- package/dist/renderer/host/host.js +33 -16
- package/dist/renderer/host/host.js.map +1 -1
- package/dist/renderer/host/structure-sync.d.ts +9 -0
- package/dist/renderer/host/structure-sync.d.ts.map +1 -0
- package/dist/renderer/host/structure-sync.js +24 -0
- package/dist/renderer/host/structure-sync.js.map +1 -0
- package/dist/security/data-protection-error.d.ts +14 -0
- package/dist/security/data-protection-error.d.ts.map +1 -0
- package/dist/security/data-protection-error.js +15 -0
- package/dist/security/data-protection-error.js.map +1 -0
- package/dist/security/index.d.ts +48 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +32 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/native.d.ts +43 -0
- package/dist/security/native.d.ts.map +1 -0
- package/dist/security/native.js +170 -0
- package/dist/security/native.js.map +1 -0
- package/dist/security/protection-scope.d.ts +13 -0
- package/dist/security/protection-scope.d.ts.map +1 -0
- package/dist/security/protection-scope.js +11 -0
- package/dist/security/protection-scope.js.map +1 -0
- package/dist/store/states.d.ts +2 -2
- package/dist/store/windows-identity.d.ts +2 -6
- package/dist/store/windows-identity.d.ts.map +1 -1
- package/dist/store/windows-identity.js +2 -29
- package/dist/store/windows-identity.js.map +1 -1
- package/dist/store/windows-packages.d.ts +2 -2
- package/dist/store/windows-store.d.ts +2 -2
- package/dist/tray/click-detector.d.ts.map +1 -1
- package/dist/tray/click-detector.js.map +1 -1
- package/dist/tray/flyout-model.d.ts +4 -3
- package/dist/tray/flyout-model.d.ts.map +1 -1
- package/dist/tray/flyout-model.js +12 -2
- package/dist/tray/flyout-model.js.map +1 -1
- package/dist/tray/menu/icon.d.ts +17 -0
- package/dist/tray/menu/icon.d.ts.map +1 -0
- package/dist/tray/menu/icon.js +31 -0
- package/dist/tray/menu/icon.js.map +1 -0
- package/dist/tray/menu/index.d.ts +1 -1
- package/dist/tray/menu/index.d.ts.map +1 -1
- package/dist/tray/menu/index.js.map +1 -1
- package/dist/tray/menu/types.d.ts +23 -6
- package/dist/tray/menu/types.d.ts.map +1 -1
- package/dist/tray/menu/types.js.map +1 -1
- package/dist/tray/menu-svelte/menu-node.d.ts +4 -4
- package/dist/tray/native.d.ts +9 -4
- package/dist/tray/native.d.ts.map +1 -1
- package/dist/tray/native.js +10 -18
- package/dist/tray/native.js.map +1 -1
- package/dist/tray/personalize.d.ts +18 -0
- package/dist/tray/personalize.d.ts.map +1 -0
- package/dist/tray/personalize.js +42 -0
- package/dist/tray/personalize.js.map +1 -0
- package/dist/tray/standalone/icon-raster.d.ts +72 -0
- package/dist/tray/standalone/icon-raster.d.ts.map +1 -0
- package/dist/tray/standalone/icon-raster.js +161 -0
- package/dist/tray/standalone/icon-raster.js.map +1 -0
- package/dist/tray/standalone/index.d.ts +3 -2
- package/dist/tray/standalone/index.d.ts.map +1 -1
- package/dist/tray/standalone/index.js +1 -0
- package/dist/tray/standalone/index.js.map +1 -1
- package/dist/tray/standalone/menu-icons.d.ts +9 -0
- package/dist/tray/standalone/menu-icons.d.ts.map +1 -0
- package/dist/tray/standalone/menu-icons.js +280 -0
- package/dist/tray/standalone/menu-icons.js.map +1 -0
- package/dist/tray/standalone/native.d.ts +19 -6
- package/dist/tray/standalone/native.d.ts.map +1 -1
- package/dist/tray/standalone/native.js +58 -15
- package/dist/tray/standalone/native.js.map +1 -1
- package/dist/tray/standalone/standalone-tray.d.ts +4 -2
- package/dist/tray/standalone/standalone-tray.d.ts.map +1 -1
- package/dist/tray/standalone/standalone-tray.js +12 -2
- package/dist/tray/standalone/standalone-tray.js.map +1 -1
- package/dist/tray/themed-icon.d.ts.map +1 -1
- package/dist/tray/themed-icon.js +4 -28
- package/dist/tray/themed-icon.js.map +1 -1
- package/dist/tray/tray-core.d.ts.map +1 -1
- package/dist/tray/tray-core.js +5 -1
- package/dist/tray/tray-core.js.map +1 -1
- package/dist/tray/tray-extras.d.ts +26 -2
- package/dist/tray/tray-extras.d.ts.map +1 -1
- package/dist/web-apis/eye-dropper.d.ts.map +1 -1
- package/dist/web-apis/eye-dropper.js +8 -5
- package/dist/web-apis/eye-dropper.js.map +1 -1
- package/dist/web-apis/media-devices-source.d.ts +1 -1
- package/dist/web-apis/native.d.ts +0 -7
- package/dist/web-apis/native.d.ts.map +1 -1
- package/dist/web-apis/native.js +0 -19
- package/dist/web-apis/native.js.map +1 -1
- package/dist/win2d/activation-failure.d.ts +10 -0
- package/dist/win2d/activation-failure.d.ts.map +1 -0
- package/dist/win2d/activation-failure.js +30 -0
- package/dist/win2d/activation-failure.js.map +1 -0
- package/dist/win2d/element-lifecycle.d.ts.map +1 -1
- package/dist/win2d/element-lifecycle.js +6 -1
- package/dist/win2d/element-lifecycle.js.map +1 -1
- package/dist/win2d/manifest.d.ts +29 -0
- package/dist/win2d/manifest.d.ts.map +1 -0
- package/dist/win2d/manifest.js +67 -0
- package/dist/win2d/manifest.js.map +1 -0
- package/dist/win32/index.d.ts +3 -0
- package/dist/win32/index.d.ts.map +1 -0
- package/dist/win32/index.js +11 -0
- package/dist/win32/index.js.map +1 -0
- package/dist/win32-calls.d.ts +6 -0
- package/dist/win32-calls.d.ts.map +1 -1
- package/dist/win32-calls.js +6 -1
- package/dist/win32-calls.js.map +1 -1
- package/dist/win32-foreground.d.ts +20 -0
- package/dist/win32-foreground.d.ts.map +1 -1
- package/dist/win32-foreground.js +24 -4
- package/dist/win32-foreground.js.map +1 -1
- package/dist/win32-icons.d.ts.map +1 -1
- package/dist/win32-icons.js +1 -2
- package/dist/win32-icons.js.map +1 -1
- package/dist/win32-key-state.d.ts +31 -0
- package/dist/win32-key-state.d.ts.map +1 -0
- package/dist/win32-key-state.js +41 -0
- package/dist/win32-key-state.js.map +1 -0
- package/dist/window/anchor.d.ts +15 -0
- package/dist/window/anchor.d.ts.map +1 -1
- package/dist/window/anchor.js +23 -0
- package/dist/window/anchor.js.map +1 -1
- package/dist/window/apply-frame.d.ts +4 -2
- package/dist/window/apply-frame.d.ts.map +1 -1
- package/dist/window/apply-frame.js +2 -3
- package/dist/window/apply-frame.js.map +1 -1
- package/dist/window/bootstrap-core.d.ts +69 -0
- package/dist/window/bootstrap-core.d.ts.map +1 -0
- package/dist/window/bootstrap-core.js +93 -0
- package/dist/window/bootstrap-core.js.map +1 -0
- package/dist/window/bootstrap-mode.d.ts +21 -0
- package/dist/window/bootstrap-mode.d.ts.map +1 -0
- package/dist/window/bootstrap-mode.js +17 -0
- package/dist/window/bootstrap-mode.js.map +1 -0
- package/dist/window/bootstrap.d.ts +12 -28
- package/dist/window/bootstrap.d.ts.map +1 -1
- package/dist/window/bootstrap.js +18 -66
- package/dist/window/bootstrap.js.map +1 -1
- package/dist/window/cover.d.ts +43 -0
- package/dist/window/cover.d.ts.map +1 -0
- package/dist/window/cover.js +64 -0
- package/dist/window/cover.js.map +1 -0
- package/dist/window/create-window.d.ts +1 -1
- package/dist/window/create-window.d.ts.map +1 -1
- package/dist/window/create-window.js +1 -0
- package/dist/window/create-window.js.map +1 -1
- package/dist/window/dpi-awareness.d.ts +71 -0
- package/dist/window/dpi-awareness.d.ts.map +1 -0
- package/dist/window/dpi-awareness.js +127 -0
- package/dist/window/dpi-awareness.js.map +1 -0
- package/dist/window/foreground-native.d.ts.map +1 -1
- package/dist/window/foreground-native.js +3 -5
- package/dist/window/foreground-native.js.map +1 -1
- package/dist/window/index.d.ts +2 -0
- package/dist/window/index.d.ts.map +1 -1
- package/dist/window/index.js +1 -0
- package/dist/window/index.js.map +1 -1
- package/dist/window/native.d.ts.map +1 -1
- package/dist/window/native.js +1 -2
- package/dist/window/native.js.map +1 -1
- package/dist/window/package-identity.d.ts +17 -0
- package/dist/window/package-identity.d.ts.map +1 -0
- package/dist/window/package-identity.js +97 -0
- package/dist/window/package-identity.js.map +1 -0
- package/dist/window/system-dispatcher-queue.d.ts.map +1 -1
- package/dist/window/system-dispatcher-queue.js +1 -2
- package/dist/window/system-dispatcher-queue.js.map +1 -1
- package/dist/window/taskbar-calls.d.ts +1 -1
- package/dist/window/taskbar-native.d.ts.map +1 -1
- package/dist/window/taskbar-native.js +1 -2
- package/dist/window/taskbar-native.js.map +1 -1
- package/dist/window/window-handle.d.ts +25 -1
- package/dist/window/window-handle.d.ts.map +1 -1
- package/dist/window/window-handle.js +27 -1
- package/dist/window/window-handle.js.map +1 -1
- package/dist/window/window-host.svelte.d.ts +10 -1
- package/dist/window/window-host.svelte.d.ts.map +1 -1
- package/dist/window/window-host.svelte.js +38 -4
- package/dist/window/window-host.svelte.js.map +1 -1
- package/package.json +26 -4
- package/src/app/activate.ts +3 -0
- package/src/app/activation/index.ts +3 -0
- package/src/app/activation/login.ts +2 -1
- package/src/app/activation/native.ts +1 -1
- package/src/app/activation/packaged.ts +118 -0
- package/src/app/activation/receive.ts +24 -4
- package/src/app/activation/registration.ts +7 -7
- package/src/app/activation/scheme.ts +19 -0
- package/src/app/index.ts +4 -2
- package/src/app/instance-running.ts +22 -0
- package/src/app/jump-list/native.ts +1 -2
- package/src/app/native-messaging/browsers.ts +21 -0
- package/src/app/native-messaging/index.ts +124 -0
- package/src/app/native.ts +1 -32
- package/src/app/notification-source.ts +1 -3
- package/src/app/shell/native.ts +1 -1
- package/src/app/single-instance.ts +34 -10
- package/src/automation/native.ts +1 -2
- package/src/chrome/context-menus/context-menu-schema.ts +1 -12
- package/src/chrome/parse-or-throw.ts +14 -0
- package/src/chrome/permissions/permission-schema.ts +1 -12
- package/src/chrome/windows/chrome-windows.ts +1 -13
- package/src/components/hand-written/items/keyed-rows.svelte.ts +6 -0
- package/src/components/index.ts +1 -0
- package/src/components/runtime.svelte.ts +8 -0
- package/src/css/runtime/containers.ts +1 -20
- package/src/css/runtime/native.ts +46 -21
- package/src/css/translate/property-kit.ts +9 -0
- package/src/css/translate/transition-properties.ts +44 -10
- package/src/data-transfer/data-transfer.ts +3 -3
- package/src/data-transfer/drag-effects.ts +48 -4
- package/src/data-transfer/drag-helper.ts +216 -0
- package/src/data-transfer/drop-target.ts +90 -26
- package/src/data-transfer/index.ts +1 -0
- package/src/data-transfer/launcher.ts +65 -9
- package/src/data-transfer/native.ts +184 -0
- package/src/data-transfer/ole-data-object.ts +200 -0
- package/src/data-transfer/ole-drop-target.ts +263 -0
- package/src/data-transfer/share-interop.ts +1 -1
- package/src/data-transfer/shell-items.ts +81 -0
- package/src/data-transfer/window-drop.ts +411 -0
- package/src/devices/native.ts +1 -1
- package/src/enums.ts +3 -0
- package/src/input/index.ts +2 -0
- package/src/input/modifier-keys.ts +30 -0
- package/src/media/pixel-buffer.ts +1 -1
- package/src/messaging/web-view2/core.ts +64 -0
- package/src/messaging/web-view2/environment.ts +131 -0
- package/src/messaging/web-view2/index.ts +11 -0
- package/src/messaging/web-view2/input.ts +154 -0
- package/src/messaging/web-view2/protocol.ts +41 -0
- package/src/messaging/web-view2/recovery.ts +177 -0
- package/src/messaging/web-view2/requests.ts +238 -0
- package/src/messaging/web-view2/transport.ts +1 -5
- package/src/native-identity.ts +22 -0
- package/src/renderer/host/host.ts +39 -17
- package/src/renderer/host/structure-sync.ts +25 -0
- package/src/security/data-protection-error.ts +18 -0
- package/src/security/index.ts +57 -0
- package/src/security/native.ts +234 -0
- package/src/security/protection-scope.ts +13 -0
- package/src/store/windows-identity.ts +3 -35
- package/src/tray/click-detector.ts +6 -7
- package/src/tray/flyout-model.ts +14 -3
- package/src/tray/menu/icon.ts +40 -0
- package/src/tray/menu/index.ts +3 -0
- package/src/tray/menu/types.ts +27 -6
- package/src/tray/native.ts +20 -21
- package/src/tray/personalize.ts +57 -0
- package/src/tray/pointer-share.ts +3 -3
- package/src/tray/standalone/icon-raster.ts +208 -0
- package/src/tray/standalone/index.ts +4 -1
- package/src/tray/standalone/menu-icons.ts +317 -0
- package/src/tray/standalone/native.ts +78 -15
- package/src/tray/standalone/standalone-tray.ts +26 -5
- package/src/tray/themed-icon.ts +4 -36
- package/src/tray/tray-core.ts +6 -1
- package/src/tray/tray-extras.ts +31 -2
- package/src/web-apis/eye-dropper.ts +9 -5
- package/src/web-apis/native.ts +0 -20
- package/src/win2d/activation-failure.ts +35 -0
- package/src/win2d/element-lifecycle.ts +6 -1
- package/src/win2d/manifest.ts +78 -0
- package/src/win32/index.ts +19 -0
- package/src/win32-calls.ts +8 -1
- package/src/win32-foreground.ts +28 -4
- package/src/win32-icons.ts +7 -2
- package/src/win32-key-state.ts +48 -0
- package/src/window/anchor.ts +28 -0
- package/src/window/apply-frame.ts +6 -4
- package/src/window/bootstrap-core.ts +165 -0
- package/src/window/bootstrap-mode.ts +23 -0
- package/src/window/bootstrap.ts +20 -103
- package/src/window/cover.ts +100 -0
- package/src/window/create-window.ts +2 -0
- package/src/window/dpi-awareness.ts +162 -0
- package/src/window/foreground-native.ts +3 -5
- package/src/window/index.ts +2 -0
- package/src/window/native.ts +1 -1
- package/src/window/package-identity.ts +112 -0
- package/src/window/system-dispatcher-queue.ts +7 -2
- package/src/window/taskbar-native.ts +1 -2
- package/src/window/window-handle.ts +29 -1
- package/src/window/window-host.svelte.ts +58 -5
- package/web-types.json +11 -3
package/API.md
CHANGED
|
@@ -35,17 +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
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()`, `notify()`, `activateInstance()`, `activateOrLaunch()`, `launchApp()`, `startTray()`, `relaunch()`, `restartAfterCrash()` (opt-in; see App lifecycle) |
|
|
42
|
+
| `winui-svelte/app` | `src/app/index.ts` | `ensureSingleInstance()`, `claimInstance()`, `isInstanceRunning()`, `notify()`, `activateInstance()`, `activateOrLaunch()`, `launchApp()`, `startTray()`, `relaunch()`, `restartAfterCrash()` (opt-in; see App lifecycle) |
|
|
43
43
|
| `winui-svelte/app/shell` | `src/app/shell/index.ts` | `trash()`, `openWith()`, `createShortcut()`, `readShortcut()`, `registerAppPath()`, `ShellFailure` (opt-in; see Shell verbs) |
|
|
44
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) |
|
|
45
47
|
| `winui-svelte/app/jump-list` | `src/app/jump-list/index.ts` | `setJumpListTasks()`, `clearJumpList()` (opt-in; see Jump list tasks) |
|
|
46
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) |
|
|
47
49
|
| `winui-svelte/incremental` | `src/incremental/index.ts` | `createIncrementalSource()`, `IncrementalSource`, `IncrementalStatus`, `IncrementalState` (opt-in; see Incremental loading) |
|
|
48
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) |
|
|
49
52
|
| `winui-svelte/chrome/runtime` | `src/chrome/runtime/index.ts` | `Runtime` (`chrome.runtime`), `Port`, `InstallReason`, the native messaging codec (opt-in; see Chrome runtime) |
|
|
50
53
|
| `winui-svelte/chrome/notifications` | `src/chrome/notifications/index.ts` | `ChromeNotifications` (`chrome.notifications`), `NotificationTemplateType`, `NotificationPermissionLevel` (opt-in; see Chrome notifications) |
|
|
51
54
|
|
|
@@ -53,10 +56,11 @@ monorepo needs no build step (the repository is a pnpm workspace, see
|
|
|
53
56
|
| `winui-svelte/chrome/action` | `src/chrome/action/index.ts` | `ChromeAction` (`chrome.action`), `createChromeAction()` (opt-in; see Chrome action) |
|
|
54
57
|
| `winui-svelte/chrome/i18n` | `src/chrome/i18n/index.ts` | `ChromeI18n` (`chrome.i18n`), `installLanguageDefaults()` (opt-in; see Chrome i18n) |
|
|
55
58
|
| `winui-svelte/chrome/install` | `src/chrome/install.ts` | `installChromeApis()`, `ChromeGlobal`, `ChromeAlarms`, `ChromeSystem` (opt-in; see Chrome global) |
|
|
56
|
-
| `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) |
|
|
57
60
|
| `winui-svelte/media` | `src/media/index.ts` | `bitmapImageOf()`, `svgImageSourceOf()`, `decodeDataUri()`, `createMediaPlayer()`, `mediaSourceOfBytes()`, `observePlayback()`, `PlaybackState` (opt-in; see Media) |
|
|
58
61
|
| `winui-svelte/win2d` | `src/win2d/index.ts` | `Canvas`, the Win2D controls, the drawing helpers and Win2D classes, `applyEffect` (opt-in; see Win2D) |
|
|
59
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) |
|
|
60
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) |
|
|
61
65
|
| `winui-svelte/tray` | `src/tray/index.ts` | `TrayIcon` (with its `menu`), `createTrayIcon()`, `placeMenuWindow()`, `hideToTray()`, `restoreFromTray()`, `toggleInTray()`, `removeAllTrayIcons()`, `TrayGesture` (opt-in; see System tray) |
|
|
62
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) |
|
|
@@ -709,14 +713,75 @@ for tools; `compileSvelte()` throws an `Error` with that message
|
|
|
709
713
|
// match wins), sets WINAPPSDK_BOOTSTRAP_DLL_PATH, puts the folder it was found
|
|
710
714
|
// in on PATH (WebView2's native libraries are there) and initialises the
|
|
711
715
|
// Windows App SDK. Sets WEBVIEW2_USER_DATA_FOLDER to `webViewUserDataFolder`
|
|
712
|
-
// unless it is already set
|
|
713
|
-
//
|
|
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.
|
|
714
722
|
function initWindowsAppSdk(options?: {
|
|
715
723
|
major?: number;
|
|
716
724
|
minor?: number;
|
|
717
725
|
folders?: string[];
|
|
718
|
-
webViewUserDataFolder?: string;
|
|
719
|
-
|
|
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
|
|
720
785
|
|
|
721
786
|
// thread (in the worker that owns the UI thread; WinUI's loop never gives its
|
|
722
787
|
// thread back): enters the single-threaded apartment first, so everything
|
|
@@ -1191,6 +1256,8 @@ Items come in two forms
|
|
|
1191
1256
|
keep a row only for each item the control has realized; a `TreeView` also takes
|
|
1192
1257
|
`children` (the items under an item) and `bind:expandedKeys`, and a `ListView`
|
|
1193
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
|
|
1194
1261
|
A
|
|
1195
1262
|
control whose items are controls takes them as Svelte's own blocks: `{#each}`
|
|
1196
1263
|
in the children of `ComboBox`, `FlipView` and `ListBox`, or in the snippet of
|
|
@@ -1688,13 +1755,152 @@ const bridge = defineMessaging<AppProtocol>({ transport: createPageTransport() }
|
|
|
1688
1755
|
| `executeScript({ control, code })` | runs script in the page and resolves with its JSON value, checked |
|
|
1689
1756
|
| `addDocumentCreatedScript({ control, code })` | runs script before every page script; resolves with the function that removes it |
|
|
1690
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()` |
|
|
1691
1761
|
| `getCookies`, `setCookie`, `deleteCookie` | the profile's cookies as plain data (`CookieSameSite`) |
|
|
1692
1762
|
| `onPermissionRequested({ control, decide })` | answers permission requests with a `PermissionState` (`default`, `allow`, `deny`) for a `PermissionKind` |
|
|
1693
1763
|
| `onDownloadStarting({ control, pathFor })` | sends a download to a path with no dialog, or cancels it with `null` |
|
|
1694
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` |
|
|
1695
1900
|
|
|
1696
1901
|
`examples/web-bridge` is an app talking to a hosted page, and
|
|
1697
|
-
`test/web-bridge.test.ts` runs it in a real window;
|
|
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
|
|
1698
1904
|
desktop session (a sandboxed process cannot launch the browser, 0x8007139F)
|
|
1699
1905
|
|
|
1700
1906
|
### ListView and GridView
|
|
@@ -1887,6 +2093,15 @@ exists on Windows 11 only
|
|
|
1887
2093
|
A window on a desktop of its own (a hidden desktop) is never composed by
|
|
1888
2094
|
Windows, so there is nothing to see through to: `test/transparent-window.test.ts`
|
|
1889
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)
|
|
1890
2105
|
Not checked: a filter or a drop shadow (`filter: drop-shadow()`) on content
|
|
1891
2106
|
over a transparent window
|
|
1892
2107
|
The window's own `cornerRadius` clips with an edge that is not anti-aliased, so
|
|
@@ -1974,11 +2189,40 @@ along the top, until `isResizable={false}` takes it away),
|
|
|
1974
2189
|
`isShownInSwitchers` and `isToolWindow` (no taskbar button or Alt+Tab entry),
|
|
1975
2190
|
`isActivatable={false}` (a click never takes focus), `isClickThrough`,
|
|
1976
2191
|
`isExcludedFromCapture` (black in screenshots and screen sharing),
|
|
1977
|
-
`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
|
|
1978
2193
|
window to a rounded rectangle; the edge is not anti-aliased, so on a
|
|
1979
2194
|
transparent window round the card's own `corner-radius` instead, which is)
|
|
1980
2195
|
A prop left out leaves the window as it is, and dropped again it puts the
|
|
1981
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
|
+
```
|
|
1982
2226
|
`createWindow` takes them too
|
|
1983
2227
|
`handle.setShownInSwitchers(isShown)` does not throw for a window that has no
|
|
1984
2228
|
taskbar button (WinUI answers 0x80004001 there); `hideToTray` uses it
|
|
@@ -2037,6 +2281,46 @@ at the size it has after Windows rescaled it
|
|
|
2037
2281
|
The arithmetic is plain functions (`anchoredBounds`, `dockedBounds`,
|
|
2038
2282
|
`fittedBounds` in `src/window/anchor.ts`) over device pixels
|
|
2039
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
|
+
|
|
2040
2324
|
`handle.geometry` is the window's own `window.outerWidth`, `outerHeight`,
|
|
2041
2325
|
`screenX`, `screenY`, `devicePixelRatio`, `resizeTo(width, height)`,
|
|
2042
2326
|
`resizeBy`, `moveTo(x, y)` and `moveBy`, in CSS pixels (WinUI's
|
|
@@ -2564,9 +2848,22 @@ An opt-in subpath: an app that does not import it does not bundle it
|
|
|
2564
2848
|
The running copy's `onRedirect` receives `activation`
|
|
2565
2849
|
- `launchApp({ command, arguments, workingDirectory })` starts a program
|
|
2566
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)
|
|
2567
2857
|
- `activateOrLaunch({ key, activation, launch })` is the two together: it
|
|
2568
2858
|
activates the running copy, or else starts the app with `launch`, and
|
|
2569
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
|
|
2570
2867
|
- `relaunch({ arguments })` starts the same Node with the same flags, entry
|
|
2571
2868
|
script (`process.argv[1]`) and then `arguments`, detached, and calls
|
|
2572
2869
|
`exitApplication`, so the new copy outlives this one
|
|
@@ -2603,10 +2900,12 @@ import {
|
|
|
2603
2900
|
ActivationKind,
|
|
2604
2901
|
installProtocolHandlers,
|
|
2605
2902
|
launchAtLogin,
|
|
2903
|
+
packagedActivation,
|
|
2606
2904
|
registerFileTypes,
|
|
2607
2905
|
startActivation,
|
|
2608
2906
|
} from "winui-svelte/app/activation";
|
|
2609
2907
|
|
|
2908
|
+
const packaged = packagedActivation(); // { kind: "protocol", uri } or { kind: "startup" }
|
|
2610
2909
|
installProtocolHandlers();
|
|
2611
2910
|
navigator.registerProtocolHandler("note", "https://notes.example/open?uri=%s");
|
|
2612
2911
|
registerFileTypes({ id: "com.example.notes", extensions: [".note"] });
|
|
@@ -2634,6 +2933,7 @@ if (!single.isPrimary) {
|
|
|
2634
2933
|
| `unregisterFileTypes({ id, extensions })` | deletes both and the empty keys left | returns the extensions removed |
|
|
2635
2934
|
| `launchAtLogin({ id, isEnabled, arguments })` | `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` value `id` | listed in Settings, Apps, Startup; the start arrives as `startup` |
|
|
2636
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 |
|
|
2637
2937
|
| `startActivation({ key, onActivation })` | `ensureSingleInstance` and the command line | one `ActivationEvent` per start or redirect |
|
|
2638
2938
|
|
|
2639
2939
|
- `ActivationEvent` is a union on `kind` (`ActivationKind`, also from
|
|
@@ -2673,18 +2973,116 @@ if (!single.isPrimary) {
|
|
|
2673
2973
|
characters at most) and handed to your code, never run
|
|
2674
2974
|
Windows can pass a quote in a link through `"%1"` unescaped, so treat the
|
|
2675
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=""%1"" />
|
|
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`)
|
|
2676
3010
|
- Needs packaging for: the share target and a default-app claim (a package
|
|
2677
3011
|
manifest declares them); unpackaged, the app is offered in Open with and the
|
|
2678
3012
|
user picks the default
|
|
2679
3013
|
- `installProtocolHandlers()` returns the function that removes the two
|
|
2680
3014
|
navigator methods; the registrations stay until you unregister them
|
|
2681
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
|
|
2682
3018
|
- `src/app/activation/native.test.ts` registers a protocol, a file type and a
|
|
2683
3019
|
startup entry under HKCU with a unique name, reads them with `reg query`,
|
|
2684
3020
|
removes them and checks nothing is left, even when it fails;
|
|
2685
3021
|
`test/activation.test.ts` starts real second copies with a link, a file and
|
|
2686
3022
|
nothing, and checks the first hears each as one event
|
|
2687
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
|
+
|
|
2688
3086
|
### Jump list tasks (`winui-svelte/app/jump-list`)
|
|
2689
3087
|
|
|
2690
3088
|
Entries in the Tasks section of the taskbar button's right-click menu
|
|
@@ -3194,8 +3592,13 @@ const lines = resolveMenu({
|
|
|
3194
3592
|
labels and ticks only); `closeThenRun` (true unless set to false) runs
|
|
3195
3593
|
`onselect` after the menu has closed, so that a dialog can open
|
|
3196
3594
|
- A submenu may have its own `onselect` and `autoExpand`
|
|
3197
|
-
- `icon` is a path, a glyph
|
|
3198
|
-
|
|
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
|
|
3199
3602
|
- `MenuProfile` is plain JSON: `level`, `hidden` (ids the level shows that
|
|
3200
3603
|
the user hid), `shown` (ids above the level that the user turned on) and
|
|
3201
3604
|
`order` (child ids in the user order, keyed by parent id, `""` for the root)
|
|
@@ -3399,11 +3802,11 @@ createStandaloneTray({
|
|
|
3399
3802
|
native menus too
|
|
3400
3803
|
- The default is the smallest tray: an icon from one `.ico` path, clicks,
|
|
3401
3804
|
`update`, `remove` and the menu
|
|
3402
|
-
|
|
3805
|
+
Four parts are opt-in, each one import from the same entry, passed in
|
|
3403
3806
|
`extras`, and none of their code is in the bundle unless passed:
|
|
3404
|
-
`balloons` adds `notify`, `bounds` adds `bounds()`,
|
|
3807
|
+
`balloons` adds `notify`, `bounds` adds `bounds()`, `themedIcon` lets
|
|
3405
3808
|
`icon` be `{ forLightTaskbar, forDarkTaskbar }`, swapped as the taskbar theme
|
|
3406
|
-
changes
|
|
3809
|
+
changes, and `menuIcons` draws the icons of the menu's lines (below)
|
|
3407
3810
|
The handle has `notify` or `bounds` only when its extra is passed, and a
|
|
3408
3811
|
theme pair is accepted only with `themedIcon`; otherwise it fails to compile
|
|
3409
3812
|
`createTrayIcon` and `TrayIcon` of `winui-svelte/tray` include all three
|
|
@@ -3442,9 +3845,26 @@ tray.notify({ title: "Ready" });
|
|
|
3442
3845
|
labels and ticks, right after the line runs; `onselect` otherwise runs on
|
|
3443
3846
|
the next turn after the menu is gone (`closeThenRun: false` runs it as the
|
|
3444
3847
|
menu closes)
|
|
3445
|
-
A submenu's own `onselect` and `autoExpand
|
|
3446
|
-
|
|
3447
|
-
|
|
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
|
|
3448
3868
|
The menu is modal: the thread runs its own message loop until it closes
|
|
3449
3869
|
`colorScheme` makes it follow the system theme through an undocumented
|
|
3450
3870
|
uxtheme call; a menu that must be drawn in WinUI belongs in
|
|
@@ -3924,6 +4344,46 @@ const lines = menus.menu(ContextMenuSurface.TRAY);
|
|
|
3924
4344
|
`ContextMenuSurface`, `ContextType`, `ChromeEvent`, and the types
|
|
3925
4345
|
`CreateProperties`, `OnClickData` and `UpdateProperties`
|
|
3926
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
|
+
|
|
3927
4387
|
## Downloads (`winui-svelte/downloads`)
|
|
3928
4388
|
|
|
3929
4389
|
Downloads on the two APIs an app already knows: the web's `fetch` with the File
|
|
@@ -4598,8 +5058,12 @@ pixels), `offsetX`/`offsetY` (the control), `altKey`, `ctrlKey`, `shiftKey`,
|
|
|
4598
5058
|
`DataTransfer` has `types`, `files`, `items` (`DataTransferItemList`: `length`,
|
|
4599
5059
|
`at`, `add`, iteration; items have `kind`, `type`, `getAsString`, `getAsFile`),
|
|
4600
5060
|
`getData(type)`, `setData(type, value)`, `clearData(type?)`, `effectAllowed`
|
|
4601
|
-
(`
|
|
4602
|
-
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`
|
|
4603
5067
|
The standard formats are `text/plain` (Text), `text/html` (the fragment of the
|
|
4604
5068
|
HTML format), `text/uri-list` (Uri), `Files` (StorageItems) and, for a picture,
|
|
4605
5069
|
a `NativeFile` in `files`; any other format id is a custom text format, listed
|
|
@@ -4636,6 +5100,36 @@ window's content to take drops anywhere on the window
|
|
|
4636
5100
|
`onDragEnter`, `onDragOver`, `onDragLeave` and `onDrop` take the same
|
|
4637
5101
|
`DragEvent` as the web names
|
|
4638
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
|
+
|
|
4639
5133
|
`draggable(options)`: `text`, `html`, `uri`, `files`, `bitmap`, `effectAllowed`,
|
|
4640
5134
|
and `onDragStart` / `onDrag` / `onDragEnd`
|
|
4641
5135
|
Drag out to Explorer works with `files` (paths become `StorageFile` and
|
|
@@ -4981,6 +5475,10 @@ Everything runs on the UI thread
|
|
|
4981
5475
|
</border>
|
|
4982
5476
|
```
|
|
4983
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
|
+
|
|
4984
5482
|
`enableInputEvents()` adds the eleven names to the renderer's event-alias table
|
|
4985
5483
|
(`src/renderer/host/event-adapters.ts`, the one `enableDragEvents()` fills), so a
|
|
4986
5484
|
raw element takes them
|
|
@@ -6525,6 +7023,54 @@ The effect graph is checked on pixels without a window
|
|
|
6525
7023
|
(`src/win2d/effect-graph.test.ts`), and the effects in a real window through
|
|
6526
7024
|
`PrintWindow` (`test/effects.test.ts`, with `examples/effects`)
|
|
6527
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
|
+
|
|
6528
7074
|
### Canvas 2D (`winui-svelte/win2d/context-2d`)
|
|
6529
7075
|
|
|
6530
7076
|
Opt-in, and a separate subpath: an app that imports only `winui-svelte/win2d`
|