experiments in a post-browser web
10
fork

Configure Feed

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

feat(window): add overlay mode for transient full-screen views

New `overlay: true` option for window.open():
- Backend hides other visible windows after overlay opens
- When overlay closes, hidden windows are automatically restored
- Tracks hidden window IDs in the window's params

This provides a proper system-level pattern for window switcher,
mission control, and similar transient overlay UIs.

Windows extension now uses overlay mode instead of manual hide/restore.

+44 -56
+25
backend/electron/ipc.ts
··· 1906 1906 win.setBounds({ x: 0, y: 0, width, height }); 1907 1907 } 1908 1908 1909 + // Handle overlay mode: hide other windows after this one is ready 1910 + // When overlay window closes, the hidden windows will be restored (see main.ts) 1911 + if (options.overlay === true) { 1912 + const hiddenWindowIds: number[] = []; 1913 + const allWindows = BrowserWindow.getAllWindows(); 1914 + for (const otherWin of allWindows) { 1915 + if (otherWin.id === win.id) continue; 1916 + if (otherWin.isDestroyed()) continue; 1917 + if (!otherWin.isVisible()) continue; 1918 + // Don't hide background windows (check by URL or params) 1919 + const otherInfo = getWindowInfo(otherWin.id); 1920 + if (otherInfo?.params?.address?.includes('background.html')) continue; 1921 + if (otherInfo?.params?.address?.includes('extension-host.html')) continue; 1922 + // Hide and track 1923 + otherWin.hide(); 1924 + hiddenWindowIds.push(otherWin.id); 1925 + } 1926 + DEBUG && console.log('Overlay mode: hidden', hiddenWindowIds.length, 'windows'); 1927 + // Store hidden window IDs in the window's params for restore on close 1928 + const winInfo = getWindowInfo(win.id); 1929 + if (winInfo) { 1930 + winInfo.params.overlayHiddenWindows = hiddenWindowIds; 1931 + } 1932 + } 1933 + 1909 1934 // Show dock when window opens 1910 1935 updateDockVisibility(); 1911 1936
+12
backend/electron/main.ts
··· 137 137 const windowData = windowRegistry.get(windowId); 138 138 139 139 if (windowData) { 140 + // If this was an overlay window, restore the windows that were hidden 141 + const hiddenWindowIds = windowData.params.overlayHiddenWindows as number[] | undefined; 142 + if (hiddenWindowIds && hiddenWindowIds.length > 0) { 143 + DEBUG && console.log('Overlay closed, restoring', hiddenWindowIds.length, 'windows'); 144 + for (const hiddenId of hiddenWindowIds) { 145 + const hiddenWin = BrowserWindow.fromId(hiddenId); 146 + if (hiddenWin && !hiddenWin.isDestroyed()) { 147 + hiddenWin.show(); 148 + } 149 + } 150 + } 151 + 140 152 publish(windowData.source, scopes.GLOBAL, 'window:closed', { 141 153 id: windowId, 142 154 source: windowData.source
+5 -50
extensions/windows/background.js
··· 34 34 return { prefs: defaults.prefs }; 35 35 }; 36 36 37 - // Track windows we've hidden so we can restore them 38 - let hiddenWindowIds = []; 39 - 40 37 /** 41 - * Hide all other app windows before showing windows view 42 - */ 43 - const hideOtherWindows = async () => { 44 - const result = await api.window.list({ includeInternal: true }); 45 - if (!result.success) return; 46 - 47 - hiddenWindowIds = []; 48 - for (const win of result.windows) { 49 - // Skip background pages and extension host 50 - if (win.url.includes('background.html')) continue; 51 - if (win.url.includes('extension-host.html')) continue; 52 - if (win.url.includes('windows.html')) continue; 53 - 54 - // Hide this window 55 - await api.window.hide(win.id); 56 - hiddenWindowIds.push(win.id); 57 - } 58 - debug && console.log('[ext:windows] Hidden windows:', hiddenWindowIds.length); 59 - }; 60 - 61 - /** 62 - * Restore windows that were hidden 63 - */ 64 - const restoreHiddenWindows = async () => { 65 - for (const id of hiddenWindowIds) { 66 - await api.window.show(id); 67 - } 68 - debug && console.log('[ext:windows] Restored windows:', hiddenWindowIds.length); 69 - hiddenWindowIds = []; 70 - }; 71 - 72 - /** 73 - * Open the Windows view (maximized, transparent) 38 + * Open the Windows view (maximized, transparent overlay) 74 39 */ 75 40 const openWindowsView = async () => { 76 41 const params = { ··· 79 44 alwaysOnTop: true, 80 45 skipTaskbar: true, 81 46 resizable: false, 82 - // Maximize to fill screen without OS fullscreen 83 47 maximize: true, 84 - // Don't use modal - we want windows view to stay open until ESC or selection 85 48 type: 'panel', 86 - // Use default 'auto' escapeMode - IZUI will handle transient detection 87 - // (window switcher invoked via global hotkey will be transient, closing on ESC) 49 + // Overlay mode: backend hides other windows when this opens, 50 + // and restores them when this closes 51 + overlay: true, 88 52 trackingSource: 'windows', 89 53 trackingSourceId: 'main' 90 54 }; 91 55 92 56 api.window.open(address, params) 93 - .then(async (window) => { 57 + .then(window => { 94 58 debug && console.log('[ext:windows] Windows view opened:', window); 95 - // Hide other windows AFTER the windows view is open and focused 96 - // This prevents macOS from switching focus to another app 97 - await hideOtherWindows(); 98 59 }) 99 60 .catch(error => { 100 61 console.error('[ext:windows] Failed to open windows view:', error); ··· 157 118 158 119 // Query in case cmd is already ready 159 120 api.publish('cmd:query', {}, api.scopes.GLOBAL); 160 - 161 - // Listen for windows view closing to restore hidden windows 162 - api.subscribe('windows:closing', () => { 163 - console.log('[ext:windows] Received closing signal, restoring windows'); 164 - restoreHiddenWindows(); 165 - }, api.scopes.GLOBAL); 166 121 }; 167 122 168 123 const uninit = () => {
+2 -6
extensions/windows/windows.js
··· 24 24 renderWindows(); 25 25 return { handled: true }; 26 26 } 27 - // Notify background to restore windows, then close 28 - api.publish('windows:closing', {}, api.scopes.GLOBAL); 29 - // Let window close 27 + // Let window close - backend handles restoring hidden windows (overlay mode) 30 28 return { handled: false }; 31 29 }); 32 30 ··· 54 52 }; 55 53 56 54 /** 57 - * Close windows view and restore hidden windows 55 + * Close windows view (backend handles restoring hidden windows via overlay mode) 58 56 */ 59 57 const closeWindowsView = () => { 60 - // Notify background to restore hidden windows 61 - api.publish('windows:closing', {}, api.scopes.GLOBAL); 62 58 window.close(); 63 59 }; 64 60