experiments in a post-browser web
10
fork

Configure Feed

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

fix(drag): unify hold-to-drag default to 1s, fix webview drag reliability

+22 -12
+2 -2
app/config.js
··· 91 91 "dragHoldDelay": { 92 92 "description": "How long (in seconds) to hold the mouse still before a window becomes draggable. Click and hold without moving — the cursor changes to a hand when ready, then drag to move. This allows normal text selection and clicking without accidental window drags. Set to 0 for instant drag. Takes effect on new windows.", 93 93 "type": "number", 94 - "default": 2 94 + "default": 1 95 95 }, 96 96 }, 97 97 "required": [ "shortcutKey", "startupFeature", "enableTrayIcon", "showInDockAndSwitcher", "quitShortcut" ] ··· 168 168 sessionAutosaveInterval: 5, 169 169 pageWidth: 800, 170 170 pageHeight: 600, 171 - dragHoldDelay: 2 171 + dragHoldDelay: 1 172 172 }, 173 173 items: [ 174 174 { id: '82de735f-a4b7-4fe6-a458-ec29939ae00d',
+15 -5
app/page/page.js
··· 10 10 * The URL params (x, y, width, height) store screen coordinates of the webview 11 11 * for session save/restore. Internally, elements use window-relative positions. 12 12 * 13 - * - Custom drag: instant on navbar background, hold-150ms-to-drag anywhere else 13 + * - Custom drag: instant on navbar background, hold-to-drag anywhere else (configurable via dragHoldDelay pref, default 1s) 14 14 * - Custom resize: pointer-captured resize handle (robust even if cursor leaves window) 15 15 * - Hover trigger zone above webview reveals/hides navbar 16 16 * - Cmd+L shows navbar with URL focus ··· 392 392 // --- Custom drag --- 393 393 // Two modes: 394 394 // 1. Navbar background: instant drag (no hold delay) 395 - // 2. Anywhere else: hold ~150ms then drag 395 + // 2. Anywhere else: hold for dragHoldDelay (default 1s) then drag 396 396 // Drag now moves the BrowserWindow itself via setBounds() IPC. 397 397 398 398 let isDragging = false; ··· 404 404 405 405 // Hold-to-drag state (configurable, read from prefs at init) 406 406 const JITTER_TOLERANCE = 3; // px of movement allowed during hold without cancelling 407 - let DRAG_HOLD_THRESHOLD = 2000; // ms, updated from prefs 407 + let DRAG_HOLD_THRESHOLD = 1000; // ms, updated from prefs 408 408 let holdDragTimer = null; 409 409 let holdDragPending = false; 410 410 let holdDragReady = false; // true when hold fires, cursor is 'grab', waiting for movement ··· 672 672 let mouseBridgeTimer = null; 673 673 674 674 function injectMouseBridge() { 675 - webview.executeJavaScript(WEBVIEW_MOUSE_BRIDGE_JS).catch(() => {}); 675 + webview.executeJavaScript(WEBVIEW_MOUSE_BRIDGE_JS) 676 + .then(() => { DEBUG && console.log('[page] Mouse bridge injected'); }) 677 + .catch((err) => { console.warn('[page] Mouse bridge injection failed:', err.message); }); 676 678 } 677 679 678 680 // Inject on dom-ready (fires on each full navigation) 679 681 webview.addEventListener('dom-ready', injectMouseBridge); 680 682 681 - // Also inject on did-navigate for robustness (some navigations may not fire dom-ready). 683 + // Also inject on did-navigate and did-finish-load for robustness. 684 + // Some navigations skip dom-ready; some sites run scripts that reset global state. 682 685 // Cancel any pending injection from a previous navigation to avoid listener buildup. 683 686 webview.addEventListener('did-navigate', () => { 684 687 if (mouseBridgeTimer) clearTimeout(mouseBridgeTimer); ··· 686 689 mouseBridgeTimer = null; 687 690 injectMouseBridge(); 688 691 }, 50); 692 + }); 693 + 694 + webview.addEventListener('did-finish-load', () => { 695 + // Re-inject after full load — catches cases where dom-ready injection was too early 696 + // or the page's own scripts cleared global state. The bridge's __peekMouseBridgeInstalled 697 + // guard prevents duplicate listeners if the bridge is already active. 698 + injectMouseBridge(); 689 699 }); 690 700 691 701 dragOverlay.addEventListener('mouseup', () => {
+2 -2
docs/feature-tour.md
··· 139 139 140 140 **How to try it:** 141 141 1. Open a page (`open example.com` in the command palette). 142 - 2. The page appears as a floating window. Hold the mouse still on the page body for 2 seconds (configurable "drag hold delay" in Settings) -- the cursor changes to a hand, then drag to move the window. 142 + 2. The page appears as a floating window. Hold the mouse still on the page body for 1 second (configurable "drag hold delay" in Settings) -- the cursor changes to a hand, then drag to move the window. 143 143 3. Use the corner resize handle to change dimensions. 144 144 145 145 ### Navbar ··· 173 173 **Where in UI:** Settings > Core > "Window drag hold delay". 174 174 175 175 **How to try it:** 176 - 1. Open Settings and set "Window drag hold delay" (default: 2 seconds). 176 + 1. Open Settings and set "Window drag hold delay" (default: 1 second). 177 177 2. On a page, click and hold without moving. After the delay, the cursor changes to a hand. 178 178 3. Now move the mouse to drag the window. 179 179 4. On the navbar background, drag is instant with no delay.
+3 -3
preload.js
··· 2207 2207 // Design (v3 rewrite): 2208 2208 // - Window ID is fetched once at init (it never changes). 2209 2209 // - Window position is fetched eagerly on mousedown (overlaps with hold timer). 2210 - // - Hold delay is 120ms. Short enough to feel responsive. 2210 + // - Hold delay is configurable via dragHoldDelay pref (default 1s). 2211 2211 // - NO movement threshold during hold period. Mouse can move freely while 2212 2212 // waiting for the hold timer to fire. When it fires, the CURRENT mouse 2213 2213 // position becomes the drag origin (no jump from early movement). ··· 2229 2229 const MOVE_THRESHOLD = 3; // px of movement required to engage drag after hold fires 2230 2230 const JITTER_TOLERANCE = 3; // px of movement allowed during hold without cancelling 2231 2231 2232 - // Configurable hold delay (read from prefs at init, default 2s) 2233 - let HOLD_DELAY = 2000; 2232 + // Configurable hold delay (read from prefs at init, default 1s) 2233 + let HOLD_DELAY = 1000; 2234 2234 2235 2235 // State 2236 2236 let isDragging = false;