opentray 0.4.1 → 0.5.1

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/README.md CHANGED
@@ -56,6 +56,43 @@ Run the human-visible daemon tray example:
56
56
  pnpm --filter opentray example:daemon-tray
57
57
  ```
58
58
 
59
+ Run the direct webview control demo:
60
+
61
+ ```bash
62
+ pnpm --filter opentray example:webview-control
63
+ ```
64
+
65
+ That demo opens a native WebView window immediately and puts the controls inside the page itself, so you can exercise frameless, transparent, keep-on-top, title, icon, screen, and navigation behavior without going through the tray menu first.
66
+ Treat `example:webview-control` as the API exercise surface. It is useful for probing capabilities and events, but it is not the canonical recipe for a tray-anchored glass shell.
67
+
68
+ Run the dedicated tray-panel demo:
69
+
70
+ ```bash
71
+ cargo build -p opentray-bin -p opentray-ext-webview
72
+ pnpm --filter opentray example:tray-panel
73
+ ```
74
+
75
+ This demo is the canonical custom TrayPanel case: one `primaryEvent` tray item, backend `tray.getBounds()`, page `navigator.opentray.tray.getBounds()`, screen-aware repositioning, and a frameless glass panel with `keepOnTop`.
76
+ It also follows the native-glass rule strictly: transparent native window background, no root HTML shell styling, and content padding only inside the page.
77
+ It now also pins `style.platform.macos.materialState: "active"` so the tray-launched material surface does not immediately fall back to the inactive grey AppKit appearance.
78
+ For a step-by-step walkthrough of the examples and expected behavior, read [examples/EXAMPLE.md](./examples/EXAMPLE.md).
79
+
80
+ ## Release Channels And Maturity
81
+
82
+ OpenTray uses release channels and capability maturity together. Do not read a published platform package as proof that every visible runtime path is already stable.
83
+
84
+ - `latest`: the stable package line
85
+ - `alpha`: the prerelease/testing package line, installed as `npm i opentray@alpha`
86
+
87
+ Current WebView truth:
88
+
89
+ - macOS is the current `stable` human-visible acceptance path
90
+ - Windows and Linux are currently `alpha` for WebView runtime behavior, even though their platform packages are published
91
+ - some requests are `unsupported by design`, such as asking the macOS runtime to apply a Windows-only style family
92
+ - some results are `unavailable by context`, such as tray-bounds projection when the current session has no authoritative tray anchor
93
+
94
+ When run from the repo worktree, the example automatically discovers `target/debug` or `target/release` `libopentray_ext_webview` and wires it through `OPENTRAY_EXT_PATH` before starting the daemon. That keeps the example on the real `load-ext` path without requiring a manual staging step for routine source-level testing.
95
+
59
96
  After installing from npm, use the published CLI smoke path instead of workspace scripts:
60
97
 
61
98
  ```bash
@@ -73,14 +110,36 @@ pnpm --filter opentray cli -- daemon stop
73
110
  pnpm --filter opentray cli -- daemon restart
74
111
  ```
75
112
 
76
- The menu includes `WebView Commands` entries that call the `@opentray/ext-webview` facade. On macOS, `Show HTML` loads the platform WebView dynamic library and opens a real native WebView window owned by that library; `Navigate`, `Post Message`, `Evaluate JS`, and `Hide` operate on that window.
113
+ The menu intentionally declares only one plain item: `Open WebView` with `primaryEvent: true`. On macOS, that single primary item lets clicking the status item direct-trigger the normal `menuClick` event without opening a menu, so the example can behave like a one-action launcher for a WebView-built surface.
77
114
 
78
- The `Show HTML` demo also enables the injected page bridge so the rendered page can call `navigator.window` / `navigator.opentrayWindow` and, for the demo only, opt into `window.close()` / `window.moveTo()` / `window.resizeTo()` overrides. Use the in-page buttons to verify `getCapabilities`, `getStyle`, `setStyle({ frameless })`, move, resize, and close behavior visually instead of relying only on terminal logs.
115
+ On platforms that expose a direct tray activation gesture, the same item opens the WebView immediately while still remaining a normal native menu item on platforms or gestures that show a menu.
79
116
 
80
- The Lynx smoke path uses the same generic extension loader but launches a real `OpenTrayLynxRuntime.app.zip` sidecar from `@opentray/ext-lynx-darwin-*`. It starts the requested `.lynx.bundle` immediately in fit-content mode, enables `navigator.window`, enables global overrides for validation, and exposes `Show Fit Window`, `Show Fixed Window`, `Hide Window`, and `Quit Smoke` through tray-routed events. Inside the Lynx window, use the rendered controls to verify `getCapabilities`, `getStyle`, `resizeTo`, `moveTo`, frameless toggling, `window.resizeTo()`, and close behavior visually.
117
+ The host side of that example can call `await tray.getBounds()` to read the current tray geometry before opening the window. The rendered page can also opt into `navigator.opentray.tray.getBounds()` when it needs the same tray anchor for layout.
118
+
119
+ The opened WebView also enables the injected page bridge so the rendered page can call `navigator.window` / `navigator.opentrayWindow` and, for the demo only, opt into `window.close()` / `window.moveTo()` / `window.resizeTo()` overrides. Use the in-page buttons to verify `getCapabilities`, `getStyle`, `setStyle({ frameless })`, move, resize, close, and tray-bounds behavior visually instead of relying only on terminal logs.
120
+
121
+ The Lynx smoke path uses the same generic extension loader but launches a real `OpenTrayLynxRuntime.app.zip` sidecar from `@opentray/ext-lynx-darwin-*`. It starts the requested `.lynx.bundle` in a fixed host shell, sets an initial title and icon, applies an explicit startup feature expression, and exposes `Show Window`, `Hide Window`, and `Quit Smoke` through tray-routed events. Inside the Lynx window, use the rendered controls to verify `getCapabilities`, `getStyle`, `getTitle`, `setTitle`, `getIcon`, `setIcon`, `navigator.screen.getScreenDetails()`, `resizeTo`, `moveTo`, frameless toggling, `window.resizeTo()`, `window.getScreenDetails()`, and close behavior visually. On macOS, the runtime Dock icon should no longer appear blank.
122
+
123
+ For Lynx, `frameless` currently means borderless only. It does not imply a full-window drag region, because that would steal clicks from the page content. When isolating host-feature regressions, `--features "*,!frameless"` is the fastest way to keep the bridge on while removing the borderless shell from the test.
124
+
125
+ When you need to validate a GitHub-built macOS artifact before publish, use the workspace launcher instead of hand-written `/tmp` scripts:
126
+
127
+ ```bash
128
+ pnpm run smoke:lynx -- --run <github-actions-run-id> --bundle packages/cli/assets/lynx-review/main.lynx.bundle
129
+ pnpm run smoke:lynx -- --run <github-actions-run-id> --bundle packages/cli/assets/lynx-review/main.lynx.bundle --features "nativeWindowApi,bindWindowGlobals,nativeScreenApi,bindScreenGlobals"
130
+ pnpm run smoke:lynx -- --run <github-actions-run-id> --bundle packages/cli/assets/lynx-review/main.lynx.bundle --features "*,!nativeScreenApi"
131
+ ```
132
+
133
+ The package-owned review bundle is the full human acceptance surface. The separate `input-probe.lynx.bundle` is only a low-level diagnostic asset for isolating raw click/scroll/input delivery. The empty feature set is the baseline carrier check. Use it to validate the physical window baseline: click, scroll, input, red/yellow/green controls, and resize/move. Only after that baseline is healthy should you validate explicit startup feature sets on top of the same carrier.
81
134
 
82
135
  First-stage platform packages are published for macOS, Linux, and Windows. macOS is the current human-visual acceptance path. Linux and Windows artifacts are present for package topology validation, but unsupported broker/WebView capability must fail explicitly rather than pretending a visible UI exists. Lynx is intentionally macOS-first for now and should fail honestly on other platforms instead of pretending the runtime exists.
83
136
 
137
+ If you are validating the current prerelease branch before stable publication, install from the alpha channel and treat that as alpha evidence rather than stable evidence:
138
+
139
+ ```bash
140
+ npm i opentray@alpha
141
+ ```
142
+
84
143
  For local native smoke before npm publish, stage the current platform artifacts first:
85
144
 
86
145
  ```bash
@@ -94,6 +153,14 @@ OPENTRAY_EXAMPLE_WEBVIEW_SMOKE=1 pnpm --filter opentray cli -- smoke daemon-tray
94
153
  pnpm --filter opentray cli -- smoke daemon-lynx
95
154
  ```
96
155
 
156
+ During source-level daemon work, restart the daemon with the freshly built broker binary before testing tray behavior. Otherwise the CLI may reuse the already staged same-version daemon:
157
+
158
+ ```bash
159
+ cargo build -p opentray-bin
160
+ OPENTRAY_BROKER_BIN="$PWD/target/debug/opentray" pnpm --filter opentray cli -- daemon restart
161
+ OPENTRAY_BROKER_BIN="$PWD/target/debug/opentray" pnpm --filter opentray cli -- smoke daemon-tray
162
+ ```
163
+
97
164
  The daemon exits automatically after 30 seconds with no connected clients. Set `OPENTRAY_DAEMON_IDLE_TIMEOUT_MS=0` to keep it alive during debugging, or provide another millisecond value for a custom idle release window.
98
165
 
99
166
  `OPENTRAY_HOME` should point at a home root, not the `.opentray` state directory itself. OpenTray always stores versioned state under `"$OPENTRAY_HOME/.opentray/<package-version>"`.
Binary file
package/dist/cli.d.mts CHANGED
@@ -11,6 +11,7 @@ type CliCommand = {
11
11
  type: "smoke";
12
12
  name: "daemon-lynx";
13
13
  bundlePath?: string;
14
+ featureExpression?: string;
14
15
  } | {
15
16
  type: "help";
16
17
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";;;KAuBK,UAAA;EACC,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAe,IAAA;AAAA;EACf,IAAA;EAAe,IAAA;EAAqB,UAAA;AAAA;EACpC,IAAA;AAAA;AAAA,cAEO,eAAA,GAAmB,IAAA,eAAiB,UAwBhD;AAAA,cAEY,MAAA,GAAgB,IAAA,eAAiB,OAAO;AAAA,cAmGxC,wBAAA,GAA4B,MAAoB,EAAZ,YAAY;AAAA,cAoBhD,eAAA,GACX,aAAA,sBACA,UAAkB"}
1
+ {"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";;;KAuBK,UAAA;EACC,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAe,IAAA;AAAA;EAEf,IAAA;EACA,IAAA;EACA,UAAA;EACA,iBAAA;AAAA;EAEA,IAAA;AAAA;AAAA,cAEO,eAAA,GAAmB,IAAA,eAAiB,UA+BhD;AAAA,cAEY,MAAA,GAAgB,IAAA,eAAiB,OAAO;AAAA,cAwGxC,wBAAA,GAA4B,MAAoB,EAAZ,YAAY;AAAA,cAoBhD,eAAA,GACX,aAAA,sBACA,UAAkB"}