experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(pubsub): broadcaster now reaches webview guests, not just BrowserWindows

The pubsub broadcaster in main.ts iterates getAllTileWindows() which
only returns top-level BrowserWindows tracked in the tile-launcher
registry. HUD widget webviews (peek://ext/hud/widgets/*.html) and
page-canvas child webviews are webContents GUESTS of their host
BrowserWindow — not themselves in the registry — so global pubsub
events (context:changed, izui:state-changed, window:focused, etc.)
never reach their subscribers. The widget subscribes, the cap check
passes, the publish happens, but delivery silently misses.

Extended the broadcaster with a second pass over
webContents.getAllWebContents() filtered by getType()==='webview'
and peek:// URLs. Same source-origin echo-prevention as the
BrowserWindow pass.

Fixes the remaining 3 HUD mode-reactivity tests (displays mode
information, updates reactively on mode changes, displays group
mode with name) — all were blocked because the mode widget's
api.context.watchMode subscription never received context:changed
events from setMode() calls on bgWindow.

Cluster 1 now 11/11 passing (10 HUD + 1 groups-context HUD test).

+27 -1
+27 -1
backend/electron/main.ts
··· 5 5 * a unified API for managing the Electron application. 6 6 */ 7 7 8 - import { app, BrowserWindow, ipcMain, Menu, nativeImage, nativeTheme } from 'electron'; 8 + import { app, BrowserWindow, ipcMain, Menu, nativeImage, nativeTheme, webContents } from 'electron'; 9 9 import path from 'node:path'; 10 10 import fs from 'node:fs'; 11 11 import { pathToFileURL } from 'node:url'; ··· 226 226 } 227 227 } catch { 228 228 // Window may have been destroyed between check and send 229 + } 230 + } 231 + 232 + // Broadcast to webview guests that are themselves peek:// tiles (HUD 233 + // widgets, page-canvas webviews, etc.). These guest webContents each 234 + // run a tile-preload with a capability token and subscribe to pubsub, 235 + // but they are NOT returned by `getAllTileWindows()` (that registry 236 + // only tracks top-level BrowserWindows), so without this second pass 237 + // their subscribers never fire. Filter by `getType() === 'webview'` 238 + // and peek:// URLs to avoid broadcasting into arbitrary http(s) 239 + // content webviews. 240 + for (const wc of webContents.getAllWebContents()) { 241 + try { 242 + if (wc.isDestroyed()) continue; 243 + if (wc.getType() !== 'webview') continue; 244 + const url = wc.getURL(); 245 + if (!url.startsWith('peek://')) continue; 246 + const wcHost = peekHost(url); 247 + if (wcHost !== sourceOrigin) { 248 + wc.send(`pubsub:${topic}`, { 249 + ...(msg as object), 250 + source 251 + }); 252 + } 253 + } catch { 254 + // WebContents may have been destroyed mid-iteration 229 255 } 230 256 } 231 257 });