← Commit history

v0.0.36/0.0.20: focus-emulation fixes background clicking on occluded windows (was silently landing nowhere) + select readback polish

John Lauer ·2deb08e6ca ·4mo ago ·parent 50eae0a
6 files changed +20−10
bridge/BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.0.35\ No newline at end of file+0.0.36\ No newline at end of file
bridge/bridge.json+2−2
@@ -2,8 +2,8 @@   "manifest_version": 1,   "name": "native-browser",   "displayName": "Adom Native Browser (Chrome + Edge)",-  "version": "0.0.35",-  "expectedExtensionVersion": "0.0.19",+  "version": "0.0.36",+  "expectedExtensionVersion": "0.0.20",   "description": "Drives the user's REAL signed-in Chrome/Edge via an installed extension (native-messaging transport). Mirrors the puppeteer bridge's verb surface as nbrowser_* but runs inside the actual logged-in profile, so cookies/SSO/saved-logins/captcha human-trust all work. The bridge binds an ephemeral loopback port (PORTS.md compliant) and writes a discovery file; the native-messaging host pumps stdio <-> this bridge; the extension never touches a TCP port.",   "homepage": "https://wiki.adom.inc/adom/adom-browser-extension",   "author": "Adom Inc.",
bridge/package.json+1−1
@@ -1,6 +1,6 @@ {   "name": "adom-native-browser-bridge",-  "version": "0.0.35",+  "version": "0.0.36",   "private": true,   "description": "adom-desktop bridge for the Adom native-browser extension (Chrome + Edge)",   "main": "server.js",
extension/manifest.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 3,   "name": "Adom for Chrome & Edge",   "short_name": "Adom",-  "version": "0.0.19",+  "version": "0.0.20",   "description": "Drive your real, logged-in Chrome/Edge from the Adom ecosystem \u2014 the native-browser counterpart to pup.",   "minimum_chrome_version": "116",   "background": {
extension/src/cdp.js+12−2
@@ -42,6 +42,12 @@ async function attach(tabId) {   await send(tabId, 'Page.enable').catch(() => {});   await send(tabId, 'Runtime.enable').catch(() => {});   await send(tabId, 'Log.enable').catch(() => {});+  // CRITICAL for BACKGROUND clicking: a window fully occluded by another (e.g. the user's maximized+  // window over our background one) is marked hidden by Chrome's native-occlusion tracking, so+  // Input.dispatchMouseEvent stops hit-testing and clicks silently land NOWHERE (eval/screenshot still+  // work - they don't need a hit-testable frame). Emulating focus makes the page behave as focused+visible+  // so isTrusted CDP input lands, WITHOUT ever raising the window (stays background, no focus theft).+  await send(tabId, 'Emulation.setFocusEmulationEnabled', { enabled: true }).catch(() => {});   bumpIdle(tabId); } @@ -388,7 +394,10 @@ function selectTriggerFn(label, near) {   }   if (!cand) return { found: false };   var r = cand.getBoundingClientRect();-  return { found: true, x: Math.round(r.left + r.width / 2), y: Math.round(r.top + r.height / 2), tag: cand.tagName.toLowerCase(), isNativeSelect: cand.tagName.toLowerCase() === 'select', current: txt(cand).slice(0, 120) };+  // `display` = the trigger's now-VISIBLE text (what a human sees selected), preferred for the readback.+  // `current` = its accessible name (aria-label/title/placeholder, used for finding) - kept as fallback.+  var disp = ((cand.innerText || cand.textContent || '') + '').replace(/\s+/g, ' ').trim();+  return { found: true, x: Math.round(r.left + r.width / 2), y: Math.round(r.top + r.height / 2), tag: cand.tagName.toLowerCase(), isNativeSelect: cand.tagName.toLowerCase() === 'select', current: txt(cand).slice(0, 120), display: disp.slice(0, 120) }; } function nativeSetFn(x, y, optionText) {   var el = document.elementFromPoint(x, y); while (el && el.tagName !== 'SELECT') el = el.parentElement;@@ -433,7 +442,8 @@ export async function selectOption(tabId, args) {   await mouseClick(tabId, opt.x, opt.y);   // pick (isTrusted)   await new Promise((r) => setTimeout(r, 220));   const after = await inj(selectTriggerFn, [args.label || '', args.near || '']);-  const selected = (after && after.found && after.current) ? after.current : opt.text;+  // Prefer the trigger's now-visible display text; fall back to the option we clicked.+  const selected = (after && after.found && (after.display || after.current)) || opt.text;   return { ok: true, selected, matchedExact: opt.exact, clickedText: opt.text, via: 'custom-dropdown', _hint: `selected "${selected}". Verify it matches what you intended before continuing.` }; } 
native-browser-bridge-manifest.json+3−3
@@ -1,8 +1,8 @@ {   "manifest_version": 1,-  "version": "0.0.35",-  "url": "native-browser-bridge-v0.0.35.bin",-  "sha256": "d8bb45d1c1932f028ce8a304258cbb713a4b25c25dc74088391ae5e5c58538a5",+  "version": "0.0.36",+  "url": "native-browser-bridge-v0.0.36.bin",+  "sha256": "df7c7006b6de9efedbd4409df3767306d2c971b3717515e9dfc999c44005946e",   "size": 43378,   "released_at": "2026-07-06T00:00:00Z" }\ No newline at end of file