| 2357 | }, |
| 2358 | |
| 2359 | async syncViewport(force = false, options = {}) { |
| 2360 | const restartStream = Boolean(options.restartStream); |
| 2361 | const contextId = this.normalizeContextId(this.activeBrowserContextId || this.contextId); |
| 2362 | if (!contextId || !this.activeBrowserId) { |
| 2363 | return; |
| 2364 | } |
| 2365 | const viewport = this.currentViewportSize(); |
| 2366 | if (!viewport) { |
| 2367 | return; |
| 2368 | } |
| 2369 | const key = `${contextId}:${this.activeBrowserId}:${viewport.width}x${viewport.height}`; |
| 2370 | if ( |
| 2371 | (!restartStream && this._lastViewportKey === key) |
| 2372 | || ( |
| 2373 | !force |
| 2374 | && !restartStream |
| 2375 | && this._lastViewport |
| 2376 | && this.sameBrowserTab(this._lastViewport.browserId, this._lastViewport.contextId, this.activeBrowserId, contextId) |
| 2377 | && Math.abs(this._lastViewport.width - viewport.width) <= VIEWPORT_SYNC_SIZE_TOLERANCE |
| 2378 | && Math.abs(this._lastViewport.height - viewport.height) <= VIEWPORT_SYNC_SIZE_TOLERANCE |
| 2379 | ) |
| 2380 | ) { |
| 2381 | return; |
| 2382 | } |
| 2383 | try { |
| 2384 | await websocket.emit("browser_viewer_input", { |
| 2385 | context_id: contextId, |
| 2386 | browser_id: this.activeBrowserId, |
| 2387 | viewer_id: this._viewerToken, |
| 2388 | input_type: "viewport", |
| 2389 | width: viewport.width, |
| 2390 | height: viewport.height, |
| 2391 | restart_stream: restartStream && this.usesScreencastTransport(), |
| 2392 | }); |
| 2393 | this._lastViewportKey = key; |
| 2394 | this._lastViewport = { |
| 2395 | browserId: this.activeBrowserId, |
| 2396 | contextId, |
| 2397 | width: viewport.width, |
| 2398 | height: viewport.height, |
| 2399 | }; |
| 2400 | } catch (error) { |
| 2401 | this._lastViewportKey = ""; |
| 2402 | this._lastViewport = null; |
| 2403 | console.warn("Browser viewport sync failed", error); |
| 2404 | } |
| 2405 | }, |
| 2406 | |
| 2407 | async sendMouse(eventType, event) { |
| 2408 | if (this.annotating) return; |