experiments in a post-browser web
10
fork

Configure Feed

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

fix(page): make Cmd+L navbar auto-hide on mouseleave like hover

Previously, navbar opened via Cmd+L (source: 'shortcut') stayed visible
forever because scheduleHide() only ran for 'hover' source. Now both
'hover' and 'shortcut' sources auto-hide when the mouse leaves the
navbar area, with the same 300ms delay and re-enter cancellation.
The 'loading' source still only hides when loading completes.

Add test verifying Cmd+L navbar auto-hides after mouseleave.

+60 -3
+3 -3
app/page/page.js
··· 934 934 function scheduleHide() { 935 935 if (hideTimer) clearTimeout(hideTimer); 936 936 hideTimer = setTimeout(() => { 937 - if (showSource !== 'hover') return; 937 + if (showSource !== 'hover' && showSource !== 'shortcut') return; 938 938 // If cursor is still in the navbar+trigger area, don't hide. 939 939 // This prevents the hide→contract→re-trigger→show bounce when cursor 940 940 // crosses the boundary between navbar and webview. ··· 967 967 }); 968 968 969 969 triggerZone.addEventListener('mouseleave', () => { 970 - if (showSource === 'hover') scheduleHide(); 970 + if (showSource === 'hover' || showSource === 'shortcut') scheduleHide(); 971 971 }); 972 972 973 973 navbar.addEventListener('mouseenter', () => { ··· 975 975 }); 976 976 977 977 navbar.addEventListener('mouseleave', () => { 978 - if (showSource === 'hover') scheduleHide(); 978 + if (showSource === 'hover' || showSource === 'shortcut') scheduleHide(); 979 979 }); 980 980 981 981 // Cmd+L: show navbar with URL focus
+57
tests/desktop/page-navbar.spec.ts
··· 152 152 }, windowId); 153 153 }); 154 154 155 + test('Cmd+L navbar auto-hides on mouseleave like hover', async () => { 156 + const { pageWindow, windowId } = await openCanvasPage( 157 + sharedBgWindow, 158 + 'https://example.com' 159 + ); 160 + 161 + // Wait for page.js to fully initialize and loading to complete 162 + await pageWindow.waitForFunction( 163 + () => document.getElementById('navbar') !== null, 164 + undefined, 165 + { timeout: 10000 } 166 + ); 167 + await waitForPageLoaded(pageWindow); 168 + 169 + // Wait for navbar to be hidden after loading 170 + await waitForNavbarVisible(pageWindow, false, 10000); 171 + 172 + // Simulate Cmd+L via pubsub 173 + await sharedBgWindow.evaluate(async (wid: number) => { 174 + (window as any).app.publish( 175 + 'page:show-navbar', 176 + { windowId: wid }, 177 + (window as any).app.scopes.GLOBAL 178 + ); 179 + }, windowId); 180 + 181 + // Navbar should become visible with source 'shortcut' 182 + await waitForNavbarVisible(pageWindow, true, 5000); 183 + 184 + // Simulate mouse entering then leaving the navbar area 185 + // First enter the navbar (cancels any pending hide) 186 + await pageWindow.evaluate(() => { 187 + const navbar = document.getElementById('navbar'); 188 + if (navbar) { 189 + navbar.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); 190 + } 191 + }); 192 + 193 + // Then leave the navbar — should schedule auto-hide 194 + await pageWindow.evaluate(() => { 195 + const navbar = document.getElementById('navbar'); 196 + if (navbar) { 197 + navbar.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true, clientY: 200 })); 198 + } 199 + // Update lastMouseY to simulate cursor being below navbar area 200 + document.dispatchEvent(new MouseEvent('mousemove', { bubbles: true, clientY: 200 })); 201 + }); 202 + 203 + // Navbar should auto-hide after the 300ms delay 204 + await waitForNavbarVisible(pageWindow, false, 5000); 205 + 206 + // Clean up 207 + await sharedBgWindow.evaluate(async (id: number) => { 208 + return await (window as any).app.window.close(id); 209 + }, windowId); 210 + }); 211 + 155 212 test('trigger zone hover shows navbar', async () => { 156 213 const { pageWindow, windowId } = await openCanvasPage( 157 214 sharedBgWindow,