@dimina-kit/devtools 0.4.0-dev.20260630123203 → 0.4.0-dev.20260701155140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main/app/app.js +17 -0
- package/dist/main/app/max-listeners-diagnostic.d.ts +32 -0
- package/dist/main/app/max-listeners-diagnostic.js +59 -0
- package/dist/main/index.bundle.js +426 -220
- package/dist/main/ipc/bridge-router.d.ts +5 -4
- package/dist/main/ipc/bridge-router.js +25 -1
- package/dist/main/ipc/simulator.js +1 -5
- package/dist/main/ipc/views.js +8 -19
- package/dist/main/services/automation/wait-active-page.d.ts +4 -2
- package/dist/main/services/render-inspect/index.d.ts +9 -0
- package/dist/main/services/render-inspect/index.js +13 -1
- package/dist/main/services/simulator-storage/index.d.ts +9 -0
- package/dist/main/services/simulator-storage/index.js +26 -1
- package/dist/main/services/simulator-wxml/index.js +117 -11
- package/dist/main/services/views/apply-view-ops.d.ts +11 -0
- package/dist/main/services/views/apply-view-ops.js +22 -0
- package/dist/main/services/views/placement-test-driver.d.ts +25 -0
- package/dist/main/services/views/placement-test-driver.js +48 -0
- package/dist/main/services/views/view-manager.d.ts +9 -55
- package/dist/main/services/views/view-manager.js +264 -233
- package/dist/main/services/workbench-context.d.ts +10 -0
- package/dist/preload/windows/host-toolbar-runtime.cjs +6 -13
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
- package/dist/preload/windows/simulator.cjs +0 -3
- package/dist/preload/windows/simulator.cjs.map +2 -2
- package/dist/preload/windows/simulator.js +0 -3
- package/dist/render-host/render-inspect.js +35 -1
- package/dist/renderer/assets/index-jDrNHghH.js +49 -0
- package/dist/renderer/assets/{input-BbWPVJlM.js → input-Djg2NR4U.js} +2 -2
- package/dist/renderer/assets/{ipc-transport-DTT-j7AD.js → ipc-transport-Be-AzCub.js} +2 -2
- package/dist/renderer/assets/ipc-transport-C6-KPMqw.css +1 -0
- package/dist/renderer/assets/{popover-CjAdKdAo.js → popover-eDUh4NYe.js} +2 -2
- package/dist/renderer/assets/{select-RyHeTVsc.js → select-DesFfkVV.js} +2 -2
- package/dist/renderer/assets/{settings-DaR5vif_.js → settings-CRmO7zUG.js} +2 -2
- package/dist/renderer/assets/{settings-api-DXYCjMQY.js → settings-api-HQ7ZFPWi.js} +2 -2
- package/dist/renderer/assets/{workbenchSettings-CwW0JEe6.js → workbenchSettings-CZBWsliT.js} +2 -2
- package/dist/renderer/entries/main/index.html +6 -6
- package/dist/renderer/entries/popover/index.html +5 -5
- package/dist/renderer/entries/settings/index.html +5 -5
- package/dist/renderer/entries/workbench-settings/index.html +4 -4
- package/dist/service-host/sync-api-patch.js +33 -3
- package/dist/shared/ipc-channels.d.ts +28 -14
- package/dist/shared/ipc-channels.js +10 -17
- package/dist/shared/ipc-schemas.d.ts +21 -19
- package/dist/shared/ipc-schemas.js +32 -26
- package/dist/shared/view-ids.d.ts +19 -0
- package/dist/shared/view-ids.js +25 -0
- package/dist/simulator/assets/device-shell-CT3LRnTB.js +2 -0
- package/dist/simulator/assets/{simulator-CYPhufF2.js → simulator-BizhGGE3.js} +3 -3
- package/dist/simulator/simulator.html +1 -1
- package/package.json +5 -5
- package/dist/renderer/assets/index-BMwmmaSp.js +0 -46
- package/dist/renderer/assets/ipc-transport-BZ4gxQ4_.css +0 -1
- package/dist/simulator/assets/device-shell-H3Bq5NgA.js +0 -2
|
@@ -17,6 +17,9 @@ import { acquireHostToolbarSessionRuntime, releaseHostToolbarSessionRuntime, } f
|
|
|
17
17
|
import { createHostToolbarPortChannel, } from './host-toolbar-port-channel.js';
|
|
18
18
|
import { parseRoute } from '../../../shared/simulator-route.js';
|
|
19
19
|
import { HEADER_H, HOST_TOOLBAR_RUNTIME_MARKER } from '../../../shared/constants.js';
|
|
20
|
+
import { reconcile, createInitialState } from '@dimina-kit/electron-deck/layout';
|
|
21
|
+
import { applyViewOps } from './apply-view-ops.js';
|
|
22
|
+
import { VIEW_ID, VIEW_LAYER } from '../../../shared/view-ids.js';
|
|
20
23
|
/**
|
|
21
24
|
* Resolve a DevTools source request against the service-host URL that created
|
|
22
25
|
* the inspected app. Its pkgRoot is authoritative; the workspace is only a
|
|
@@ -46,6 +49,32 @@ export function resolveProjectEditorTarget(serviceHostUrl, activeProjectRoot, re
|
|
|
46
49
|
column: typeof req.column === 'number' ? req.column + 1 : undefined,
|
|
47
50
|
};
|
|
48
51
|
}
|
|
52
|
+
// `webContents.executeJavaScript()` registers a transient `did-stop-loading`
|
|
53
|
+
// listener on the target wc whenever that wc is still loading (Electron's
|
|
54
|
+
// `waitTillCanExecuteJavaScript` defers the eval until load finishes, then
|
|
55
|
+
// removes the listener). The DevTools front-end host wc takes a burst of injects
|
|
56
|
+
// during its boot window — tab customization, default-panel selection, the 150ms
|
|
57
|
+
// Elements-forward reconcile, and Network-forward probing all call
|
|
58
|
+
// `executeJavaScript()` on it before the front-end has finished loading — so the
|
|
59
|
+
// pending listeners can transiently exceed Node's default EventEmitter ceiling
|
|
60
|
+
// of 10 and print a spurious `MaxListenersExceededWarning: 11 did-stop-loading
|
|
61
|
+
// listeners`. They drain once the wc stops loading; this is a boot-time
|
|
62
|
+
// concurrency spike, not a per-event leak. Raise the ceiling on the DevTools
|
|
63
|
+
// host wc, which we knowingly inject into repeatedly during its boot window, so
|
|
64
|
+
// the benign spike stays quiet. (Confirmed at runtime: the tripped emitter is
|
|
65
|
+
// this host wc's `did-stop-loading`, count 11 — see the `process.on('warning')`
|
|
66
|
+
// diagnostic in app bootstrap.)
|
|
67
|
+
const DEVTOOLS_HOST_EXEC_JS_MAX_LISTENERS = 50;
|
|
68
|
+
function raiseExecuteJavaScriptListenerCeiling(wc) {
|
|
69
|
+
try {
|
|
70
|
+
if (wc.isDestroyed())
|
|
71
|
+
return;
|
|
72
|
+
if (wc.getMaxListeners() >= DEVTOOLS_HOST_EXEC_JS_MAX_LISTENERS)
|
|
73
|
+
return;
|
|
74
|
+
wc.setMaxListeners(DEVTOOLS_HOST_EXEC_JS_MAX_LISTENERS);
|
|
75
|
+
}
|
|
76
|
+
catch { /* torn-down / stub wc — best effort, warning is non-fatal */ }
|
|
77
|
+
}
|
|
49
78
|
/**
|
|
50
79
|
* Build a ViewManager bound to the given context. The returned object is the
|
|
51
80
|
* only component allowed to instantiate or add/remove overlay WebContentsViews.
|
|
@@ -69,12 +98,6 @@ export function createViewManager(ctx) {
|
|
|
69
98
|
let nativeSimulatorViewAdded = false;
|
|
70
99
|
let nativeSimulatorProjectPath = null;
|
|
71
100
|
let settleNativeSimulatorReady = null;
|
|
72
|
-
// Model A: the renderer's measured inner-screen rect is the SOLE authority for
|
|
73
|
-
// the native simulator WCV bounds (see docs/simulator-render-architecture.md).
|
|
74
|
-
// Cache the last rect so a report that lands before attachNativeSimulator (the
|
|
75
|
-
// project-open ordering) is not lost — attach replays it instead of using a
|
|
76
|
-
// coarse panel-size fallback (which raced and caused the clip/surround flips).
|
|
77
|
-
let lastRendererRect = null;
|
|
78
101
|
// NATIVE-HOST ONLY. The `ipcMain.on` listener that services the
|
|
79
102
|
// `__diminaCustomApis` bridge for the current native simulator webContents
|
|
80
103
|
// (see `attachNativeCustomApiBridge`). Tracked so we can remove it before
|
|
@@ -87,7 +110,6 @@ export function createViewManager(ctx) {
|
|
|
87
110
|
// pick up the correct scale in `did-attach-webview`. Defaults to 1 (100%).
|
|
88
111
|
let currentZoomFactor = 1;
|
|
89
112
|
let settingsView = null;
|
|
90
|
-
let settingsViewAdded = false;
|
|
91
113
|
let popoverView = null;
|
|
92
114
|
let simulatorWebContentsId = null;
|
|
93
115
|
// NATIVE-HOST ONLY. The webContents the right-panel Chrome DevTools front-end
|
|
@@ -111,17 +133,11 @@ export function createViewManager(ctx) {
|
|
|
111
133
|
let stopServiceConsole = null;
|
|
112
134
|
let nativeDevtoolsRetryTimer = null;
|
|
113
135
|
let nativeDevtoolsRetryToken = 0;
|
|
114
|
-
// Renderer-driven overlay bounds for the simulator DevTools view — the SOLE
|
|
115
|
-
// mount/geometry authority (no static-layout fallback). A zero-area
|
|
116
|
-
// rectangle means "hide" — the overlay is removed from the contentView but
|
|
117
|
-
// its WebContents stays alive.
|
|
118
|
-
let simulatorBoundsOverride = null;
|
|
119
136
|
// ── Embedded workbench editor WebContentsView ────────────────────────
|
|
120
137
|
// The opt-in VS Code workbench hosting the 'editor' dock slot. Lazily created
|
|
121
138
|
// by `attachWorkbench` from the COI server URL; its bounds ride the renderer
|
|
122
139
|
// 'editor'-slot anchor (forward anchor, like the simulator DevTools overlay).
|
|
123
140
|
let workbenchView = null;
|
|
124
|
-
let workbenchViewAdded = false;
|
|
125
141
|
// Whether the devtools-theme → workbench-theme `nativeTheme` listener is live.
|
|
126
142
|
// Bound lazily on first workbench attach, removed on detach.
|
|
127
143
|
let workbenchThemeSyncBound = false;
|
|
@@ -178,37 +194,177 @@ export function createViewManager(ctx) {
|
|
|
178
194
|
}
|
|
179
195
|
catch { /* ignore */ }
|
|
180
196
|
}
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
197
|
+
// ── Placement reconciler ────────────────────────────────────────────────
|
|
198
|
+
// The main-process view tree is converged toward the renderer's declared
|
|
199
|
+
// placement by a level-triggered reconciler (docs/view-placement-reconciler.md).
|
|
200
|
+
// The renderer publishes a window-level snapshot into `baseDesired`;
|
|
201
|
+
// settings/popover are main-owned and live in `overlayDesired`. Any change
|
|
202
|
+
// merges the two, runs the pure reconcile core, and applies the ordered ops
|
|
203
|
+
// through `viewTarget`. `epochCounter` is a single monotonic tick — main is the
|
|
204
|
+
// only (serial) reconcile caller, so the core's stale guard passes by
|
|
205
|
+
// construction; `rendererGeneration` still drives the reset on renderer restart.
|
|
206
|
+
let placementState = createInitialState();
|
|
207
|
+
let epochCounter = 0;
|
|
208
|
+
let rendererGeneration = 0;
|
|
209
|
+
const baseDesired = new Map();
|
|
210
|
+
const overlayDesired = new Map();
|
|
211
|
+
// simulator / simulator-devtools WCVs are built by the project-open flow, not
|
|
212
|
+
// by an attach op; gate them hidden until they exist so the reconciler never
|
|
213
|
+
// records an attach that addChildView can't perform. The view-creation sites
|
|
214
|
+
// call reconcileNow() to re-open the gate. workbench is gated until it has a
|
|
215
|
+
// source or a live view (it lazy-creates from the URL in target.attach).
|
|
216
|
+
function gateReadiness(v) {
|
|
217
|
+
if (v.viewId === VIEW_ID.simulator && !nativeSimulatorView)
|
|
218
|
+
return { ...v, placement: { visible: false } };
|
|
219
|
+
if (v.viewId === VIEW_ID.simulatorDevtools && !simulatorView)
|
|
220
|
+
return { ...v, placement: { visible: false } };
|
|
221
|
+
if (v.viewId === VIEW_ID.workbench && !workbenchView && !workbenchUrl)
|
|
222
|
+
return { ...v, placement: { visible: false } };
|
|
223
|
+
return v;
|
|
187
224
|
}
|
|
188
|
-
function
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return;
|
|
192
|
-
|
|
193
|
-
return;
|
|
194
|
-
|
|
195
|
-
|
|
225
|
+
function resolveView(viewId) {
|
|
226
|
+
switch (viewId) {
|
|
227
|
+
case VIEW_ID.simulator: return nativeSimulatorView;
|
|
228
|
+
case VIEW_ID.simulatorDevtools: return simulatorView;
|
|
229
|
+
case VIEW_ID.workbench: return workbenchView;
|
|
230
|
+
case VIEW_ID.hostToolbar: return hostToolbarView;
|
|
231
|
+
case VIEW_ID.settings: return settingsView;
|
|
232
|
+
case VIEW_ID.popover: return popoverView;
|
|
233
|
+
default: return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function markAdded(viewId, added) {
|
|
237
|
+
switch (viewId) {
|
|
238
|
+
case VIEW_ID.simulator:
|
|
239
|
+
nativeSimulatorViewAdded = added;
|
|
240
|
+
break;
|
|
241
|
+
case VIEW_ID.simulatorDevtools:
|
|
242
|
+
simulatorViewAdded = added;
|
|
243
|
+
break;
|
|
244
|
+
case VIEW_ID.hostToolbar:
|
|
245
|
+
hostToolbarViewAdded = added;
|
|
246
|
+
break;
|
|
247
|
+
// popover has no added-flag (create == added).
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// simulator zoom rides in `extra`: setBounds also drives the WCV zoomFactor and
|
|
251
|
+
// propagates it to nested render-host guests (from the old
|
|
252
|
+
// setNativeSimulatorViewBounds body).
|
|
253
|
+
function applyNativeSimulatorBounds(view, bounds, zoom) {
|
|
254
|
+
const p = layout.computeNativeSimulatorViewParams(bounds, zoom);
|
|
255
|
+
currentZoomFactor = p.zoomFactor;
|
|
256
|
+
view.setBounds(p.bounds);
|
|
257
|
+
const simWc = view.webContents;
|
|
258
|
+
if (!simWc.isDestroyed())
|
|
259
|
+
simWc.setZoomFactor(p.zoomFactor);
|
|
260
|
+
try {
|
|
261
|
+
for (const wc of webContents.getAllWebContents()) {
|
|
262
|
+
if (wc.isDestroyed())
|
|
263
|
+
continue;
|
|
264
|
+
if (wc.hostWebContents === simWc)
|
|
265
|
+
wc.setZoomFactor(p.zoomFactor);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch { /* hostWebContents unavailable; guests get zoom on attach */ }
|
|
269
|
+
}
|
|
270
|
+
const viewTarget = {
|
|
271
|
+
attach(viewId) {
|
|
272
|
+
if (ctx.windows.mainWindow.isDestroyed())
|
|
273
|
+
return;
|
|
274
|
+
if (viewId === VIEW_ID.workbench && !workbenchView && workbenchUrl) {
|
|
275
|
+
// Lazy-load the workbench; attachWorkbench adds it + sets the flag.
|
|
276
|
+
void attachWorkbench(workbenchUrl);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (viewId === VIEW_ID.hostToolbar) {
|
|
280
|
+
const view = ensureHostToolbarView();
|
|
281
|
+
ctx.windows.mainWindow.contentView.addChildView(view);
|
|
282
|
+
hostToolbarViewAdded = true;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const view = resolveView(viewId);
|
|
286
|
+
if (!view)
|
|
287
|
+
return;
|
|
288
|
+
ctx.windows.mainWindow.contentView.addChildView(view);
|
|
289
|
+
markAdded(viewId, true);
|
|
290
|
+
},
|
|
291
|
+
detach(viewId) {
|
|
292
|
+
const view = resolveView(viewId);
|
|
293
|
+
if (view && !ctx.windows.mainWindow.isDestroyed()) {
|
|
196
294
|
try {
|
|
197
|
-
ctx.windows.mainWindow.contentView.removeChildView(
|
|
295
|
+
ctx.windows.mainWindow.contentView.removeChildView(view);
|
|
198
296
|
}
|
|
199
297
|
catch { /* already removed */ }
|
|
200
|
-
simulatorViewAdded = false;
|
|
201
298
|
}
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
299
|
+
markAdded(viewId, false);
|
|
300
|
+
},
|
|
301
|
+
setBounds(viewId, bounds, extra) {
|
|
302
|
+
const view = resolveView(viewId);
|
|
303
|
+
if (!view || view.webContents.isDestroyed())
|
|
304
|
+
return;
|
|
305
|
+
if (viewId === VIEW_ID.simulator) {
|
|
306
|
+
applyNativeSimulatorBounds(view, bounds, extra?.zoom ?? 1);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
view.setBounds(bounds);
|
|
310
|
+
},
|
|
311
|
+
setVisible(viewId, visible) {
|
|
312
|
+
const view = resolveView(viewId);
|
|
313
|
+
if (!view)
|
|
314
|
+
return;
|
|
315
|
+
try {
|
|
316
|
+
view.setVisible(visible);
|
|
317
|
+
}
|
|
318
|
+
catch { /* stub may lack setVisible */ }
|
|
319
|
+
},
|
|
320
|
+
reorder(order) {
|
|
321
|
+
// A single attached view is already in place — nothing to reorder.
|
|
322
|
+
if (order.length <= 1 || ctx.windows.mainWindow.isDestroyed())
|
|
323
|
+
return;
|
|
324
|
+
const cv = ctx.windows.mainWindow.contentView;
|
|
325
|
+
for (const viewId of order) {
|
|
326
|
+
const view = resolveView(viewId);
|
|
327
|
+
if (view) {
|
|
328
|
+
try {
|
|
329
|
+
cv.addChildView(view);
|
|
330
|
+
}
|
|
331
|
+
catch { /* already attached */ }
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
// Create the lazily-built views (host-toolbar, workbench) BEFORE reconcile so
|
|
337
|
+
// the setBounds op — which the core emits before attach — lands on a live view
|
|
338
|
+
// rather than a not-yet-created one.
|
|
339
|
+
function ensureLazyViews() {
|
|
340
|
+
const ht = baseDesired.get(VIEW_ID.hostToolbar);
|
|
341
|
+
if (ht?.placement.visible && !liveHostToolbarWebContents())
|
|
342
|
+
ensureHostToolbarView();
|
|
343
|
+
const wb = baseDesired.get(VIEW_ID.workbench);
|
|
344
|
+
if (wb?.placement.visible && !workbenchView && workbenchUrl)
|
|
345
|
+
void attachWorkbench(workbenchUrl);
|
|
346
|
+
}
|
|
347
|
+
function reconcileNow() {
|
|
348
|
+
ensureLazyViews();
|
|
349
|
+
const views = [];
|
|
350
|
+
for (const v of baseDesired.values())
|
|
351
|
+
views.push(gateReadiness(v));
|
|
352
|
+
for (const v of overlayDesired.values())
|
|
353
|
+
views.push(v);
|
|
354
|
+
const result = reconcile(placementState, {
|
|
355
|
+
generation: rendererGeneration,
|
|
356
|
+
epoch: ++epochCounter,
|
|
357
|
+
views,
|
|
358
|
+
});
|
|
359
|
+
placementState = result.state;
|
|
360
|
+
applyViewOps(result.ops, viewTarget);
|
|
361
|
+
}
|
|
362
|
+
function setPlacementSnapshot(snapshot) {
|
|
363
|
+
rendererGeneration = snapshot.generation;
|
|
364
|
+
baseDesired.clear();
|
|
365
|
+
for (const v of snapshot.views)
|
|
366
|
+
baseDesired.set(v.viewId, v);
|
|
367
|
+
reconcileNow();
|
|
212
368
|
}
|
|
213
369
|
// ── Embedded workbench editor WebContentsView ────────────────────────
|
|
214
370
|
/** Current devtools color scheme, mirrored into the workbench's theme. */
|
|
@@ -257,9 +413,6 @@ export function createViewManager(ctx) {
|
|
|
257
413
|
}
|
|
258
414
|
catch { /* stub may lack it */ }
|
|
259
415
|
ctx.windows.mainWindow.contentView.addChildView(view);
|
|
260
|
-
workbenchViewAdded = true;
|
|
261
|
-
// Keep settings/popover above the freshly-added base overlay.
|
|
262
|
-
raiseTopOverlays();
|
|
263
416
|
// Hand the workbench the current devtools scheme as a URL query so its very
|
|
264
417
|
// first paint already matches (the runtime setter only exists post-init).
|
|
265
418
|
const loadUrl = `${url}index.html?theme=${workbenchThemeScheme()}`;
|
|
@@ -271,40 +424,6 @@ export function createViewManager(ctx) {
|
|
|
271
424
|
function setWorkbenchSource(url) {
|
|
272
425
|
workbenchUrl = url;
|
|
273
426
|
}
|
|
274
|
-
function setWorkbenchBounds(bounds) {
|
|
275
|
-
if (ctx.windows.mainWindow.isDestroyed())
|
|
276
|
-
return;
|
|
277
|
-
// Zero-area rect means "hide" — remove the child view but keep its
|
|
278
|
-
// WebContents (and the workbench's loaded state) alive. Never triggers the
|
|
279
|
-
// lazy load: a hidden slot must not pull the workbench onto screen.
|
|
280
|
-
if (isHidden(bounds)) {
|
|
281
|
-
if (workbenchView && workbenchViewAdded && !workbenchView.webContents.isDestroyed()) {
|
|
282
|
-
try {
|
|
283
|
-
ctx.windows.mainWindow.contentView.removeChildView(workbenchView);
|
|
284
|
-
}
|
|
285
|
-
catch { /* already removed */ }
|
|
286
|
-
workbenchViewAdded = false;
|
|
287
|
-
}
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
// First time the 'editor' slot becomes visible: lazily create + load the
|
|
291
|
-
// workbench (off the boot critical path). attachWorkbench assigns
|
|
292
|
-
// workbenchView + addChildView synchronously, so bounds apply immediately
|
|
293
|
-
// while the bundle loads in the background.
|
|
294
|
-
if (!workbenchView && workbenchUrl) {
|
|
295
|
-
void attachWorkbench(workbenchUrl);
|
|
296
|
-
}
|
|
297
|
-
if (!workbenchView || workbenchView.webContents.isDestroyed())
|
|
298
|
-
return;
|
|
299
|
-
if (!workbenchViewAdded) {
|
|
300
|
-
ctx.windows.mainWindow.contentView.addChildView(workbenchView);
|
|
301
|
-
workbenchViewAdded = true;
|
|
302
|
-
// Re-attaching this base overlay moved it to the top of the z-stack; keep
|
|
303
|
-
// any open settings/popover above it.
|
|
304
|
-
raiseTopOverlays();
|
|
305
|
-
}
|
|
306
|
-
workbenchView.setBounds(bounds);
|
|
307
|
-
}
|
|
308
427
|
function detachWorkbench() {
|
|
309
428
|
if (workbenchThemeSyncBound) {
|
|
310
429
|
nativeTheme.removeListener('updated', pushWorkbenchTheme);
|
|
@@ -312,7 +431,8 @@ export function createViewManager(ctx) {
|
|
|
312
431
|
}
|
|
313
432
|
destroyViewInternal(workbenchView);
|
|
314
433
|
workbenchView = null;
|
|
315
|
-
|
|
434
|
+
baseDesired.delete(VIEW_ID.workbench);
|
|
435
|
+
reconcileNow();
|
|
316
436
|
}
|
|
317
437
|
// Build the `file:///workspace/<rel>` URI string with each path SEGMENT
|
|
318
438
|
// percent-encoded. A raw `rel` passed to `vscode.Uri.parse` mis-parses a
|
|
@@ -412,6 +532,9 @@ export function createViewManager(ctx) {
|
|
|
412
532
|
catch { /* already removed */ }
|
|
413
533
|
hostToolbarViewAdded = false;
|
|
414
534
|
}
|
|
535
|
+
// The instance is being replaced — forget its reconciled mount state so the
|
|
536
|
+
// rebuilt view is treated as a fresh attach (not skipped as already-attached).
|
|
537
|
+
placementState.actual.delete(VIEW_ID.hostToolbar);
|
|
415
538
|
// The framework's height-advertiser runtime is SESSION-resident: register
|
|
416
539
|
// it on session.defaultSession (ref-counted across coexisting managers)
|
|
417
540
|
// BEFORE the view exists, so the very first load already runs it. The
|
|
@@ -457,31 +580,6 @@ export function createViewManager(ctx) {
|
|
|
457
580
|
catch { /* stub may lack it */ }
|
|
458
581
|
return view;
|
|
459
582
|
}
|
|
460
|
-
function setHostToolbarBounds(bounds) {
|
|
461
|
-
if (ctx.windows.mainWindow.isDestroyed())
|
|
462
|
-
return;
|
|
463
|
-
// Zero-area rect means "hide" — remove the child view but keep its
|
|
464
|
-
// WebContents (and the host's loaded content) alive. Do NOT create the
|
|
465
|
-
// view just to immediately hide it.
|
|
466
|
-
if (isHidden(bounds)) {
|
|
467
|
-
if (hostToolbarView && hostToolbarViewAdded && liveHostToolbarWebContents()) {
|
|
468
|
-
try {
|
|
469
|
-
ctx.windows.mainWindow.contentView.removeChildView(hostToolbarView);
|
|
470
|
-
}
|
|
471
|
-
catch { /* already removed */ }
|
|
472
|
-
}
|
|
473
|
-
hostToolbarViewAdded = false;
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
const view = ensureHostToolbarView();
|
|
477
|
-
if (!hostToolbarViewAdded) {
|
|
478
|
-
// addChildView appends = topmost z-order, which is correct for a strip
|
|
479
|
-
// that sits above the devtools header.
|
|
480
|
-
ctx.windows.mainWindow.contentView.addChildView(view);
|
|
481
|
-
hostToolbarViewAdded = true;
|
|
482
|
-
}
|
|
483
|
-
view.setBounds(bounds);
|
|
484
|
-
}
|
|
485
583
|
// Single funnel for the height notify: retain-then-push, so the retained
|
|
486
584
|
// value is exactly the last value the renderer was told. Every height
|
|
487
585
|
// notify site MUST go through here — the renderer pulls the retained value
|
|
@@ -490,9 +588,9 @@ export function createViewManager(ctx) {
|
|
|
490
588
|
function notifyHostToolbarHeight(height) {
|
|
491
589
|
hostToolbarLastHeight = height;
|
|
492
590
|
ctx.notify.hostToolbarHeightChanged(height);
|
|
493
|
-
if (
|
|
591
|
+
if (overlayDesired.has(VIEW_ID.settings))
|
|
494
592
|
applySettingsBounds();
|
|
495
|
-
if (
|
|
593
|
+
if (overlayDesired.has(VIEW_ID.popover))
|
|
496
594
|
applyPopoverBounds();
|
|
497
595
|
}
|
|
498
596
|
function setHostToolbarHeight(extent) {
|
|
@@ -512,13 +610,12 @@ export function createViewManager(ctx) {
|
|
|
512
610
|
notifyHostToolbarHeight(extent);
|
|
513
611
|
}
|
|
514
612
|
function hideHostToolbar() {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
hostToolbarViewAdded = false;
|
|
613
|
+
baseDesired.set(VIEW_ID.hostToolbar, {
|
|
614
|
+
viewId: VIEW_ID.hostToolbar,
|
|
615
|
+
placement: { visible: false },
|
|
616
|
+
layer: VIEW_LAYER.hostToolbar,
|
|
617
|
+
});
|
|
618
|
+
reconcileNow();
|
|
522
619
|
// Collapse the renderer placeholder to 0 too. Otherwise its anchor keeps a
|
|
523
620
|
// non-zero reserved height and re-publishes bounds on the next window
|
|
524
621
|
// resize, silently re-adding the view we just hid (unstable hide). Zeroing
|
|
@@ -590,17 +687,36 @@ export function createViewManager(ctx) {
|
|
|
590
687
|
function overlayHeaderHeight() {
|
|
591
688
|
return HEADER_H + hostToolbarLastHeight;
|
|
592
689
|
}
|
|
690
|
+
// settings/popover bounds are main-computed; publish them into overlayDesired
|
|
691
|
+
// and let the reconciler place them (they are top-tier layers, so a reorder
|
|
692
|
+
// keeps them above every base overlay — the old raiseTopOverlays is gone).
|
|
593
693
|
function applySettingsBounds() {
|
|
594
694
|
if (!settingsView || ctx.windows.mainWindow.isDestroyed())
|
|
595
695
|
return;
|
|
596
696
|
const [w = 0, h = 0] = ctx.windows.mainWindow.getContentSize();
|
|
597
|
-
|
|
697
|
+
overlayDesired.set(VIEW_ID.settings, {
|
|
698
|
+
viewId: VIEW_ID.settings,
|
|
699
|
+
placement: {
|
|
700
|
+
visible: true,
|
|
701
|
+
bounds: layout.computeSettingsBounds(w, h, overlayHeaderHeight()),
|
|
702
|
+
},
|
|
703
|
+
layer: VIEW_LAYER.settings,
|
|
704
|
+
});
|
|
705
|
+
reconcileNow();
|
|
598
706
|
}
|
|
599
707
|
function applyPopoverBounds() {
|
|
600
708
|
if (!popoverView || ctx.windows.mainWindow.isDestroyed())
|
|
601
709
|
return;
|
|
602
710
|
const [w = 0, h = 0] = ctx.windows.mainWindow.getContentSize();
|
|
603
|
-
|
|
711
|
+
overlayDesired.set(VIEW_ID.popover, {
|
|
712
|
+
viewId: VIEW_ID.popover,
|
|
713
|
+
placement: {
|
|
714
|
+
visible: true,
|
|
715
|
+
bounds: layout.computePopoverBounds(w, h, overlayHeaderHeight()),
|
|
716
|
+
},
|
|
717
|
+
layer: VIEW_LAYER.popover,
|
|
718
|
+
});
|
|
719
|
+
reconcileNow();
|
|
604
720
|
}
|
|
605
721
|
function clearNativeDevtoolsRetry() {
|
|
606
722
|
nativeDevtoolsRetryToken++;
|
|
@@ -736,7 +852,7 @@ export function createViewManager(ctx) {
|
|
|
736
852
|
ctx.notify.editorOpenFile(target);
|
|
737
853
|
};
|
|
738
854
|
serviceWc.on('devtools-open-url', onOpenUrl);
|
|
739
|
-
// Consolidate teardown onto the connection layer
|
|
855
|
+
// Consolidate teardown onto the connection layer,
|
|
740
856
|
// but as a wc-LIFETIME resource: the open-in-editor wiring inspects this
|
|
741
857
|
// service-host wc and must SURVIVE pool reuse (`reset`) — the dedup set
|
|
742
858
|
// entry + listener stay valid across sessions reusing the same wc, and the
|
|
@@ -871,6 +987,11 @@ export function createViewManager(ctx) {
|
|
|
871
987
|
// request the `console` view, and also persist the choice via the
|
|
872
988
|
// `panel-selectedTab` localStorage key so subsequent reloads honor it.
|
|
873
989
|
const devtoolsWc = simulatorView.webContents;
|
|
990
|
+
// The boot-time burst of `executeJavaScript()` injects on this host wc (tab
|
|
991
|
+
// customization / console default / Elements+Network forwarding below) each
|
|
992
|
+
// queue a pending `did-stop-loading` waiter while the front-end is still
|
|
993
|
+
// loading (see raiseExecuteJavaScriptListenerCeiling).
|
|
994
|
+
raiseExecuteJavaScriptListenerCeiling(devtoolsWc);
|
|
874
995
|
// Hand the network forwarder THIS front-end host wc — it injects the
|
|
875
996
|
// simulator WCV's Network.* CDP events into `window.DevToolsAPI.dispatchMessage`
|
|
876
997
|
// here so the native Network tab renders them (falls back to the service-host
|
|
@@ -936,11 +1057,9 @@ export function createViewManager(ctx) {
|
|
|
936
1057
|
// unadded and unsized until the first publish arrives. No static-layout
|
|
937
1058
|
// fallback — an attach-time computed rect raced the precise anchor rect
|
|
938
1059
|
// and flashed the overlay at the wrong rectangle.
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
simulatorView.setBounds(simulatorBoundsOverride);
|
|
943
|
-
}
|
|
1060
|
+
// The view now exists: re-run the reconciler so a placement published before
|
|
1061
|
+
// this attach (project-open ordering) attaches it once the gate re-opens.
|
|
1062
|
+
reconcileNow();
|
|
944
1063
|
if (ctx.bridge?.isNativeHost()) {
|
|
945
1064
|
unsubscribeNativeRenderEvents = ctx.bridge.onRenderEvent(onNativeRenderEvent);
|
|
946
1065
|
followNativeDevtoolsServiceHost();
|
|
@@ -988,6 +1107,8 @@ export function createViewManager(ctx) {
|
|
|
988
1107
|
catch { /* ignore */ }
|
|
989
1108
|
nativeSimulatorView = null;
|
|
990
1109
|
nativeSimulatorViewAdded = false;
|
|
1110
|
+
// The view is gone: gateReadiness now hides it, so reconcile detaches it.
|
|
1111
|
+
reconcileNow();
|
|
991
1112
|
}
|
|
992
1113
|
/**
|
|
993
1114
|
* NATIVE-HOST ONLY. The native simulator is a top-level WebContentsView with
|
|
@@ -1033,8 +1154,8 @@ export function createViewManager(ctx) {
|
|
|
1033
1154
|
};
|
|
1034
1155
|
nativeCustomApiBridgeHandler = handler;
|
|
1035
1156
|
ipcMain.on(SimulatorCustomApiBridgeChannel.Request, handler);
|
|
1036
|
-
// Consolidate this per-webContents teardown onto the connection layer
|
|
1037
|
-
//
|
|
1157
|
+
// Consolidate this per-webContents teardown onto the connection layer:
|
|
1158
|
+
// acquiring the simWc connection makes the
|
|
1038
1159
|
// registry track this trusted webContents, and `own()`-ing the detach ties
|
|
1039
1160
|
// the ipcMain listener's lifetime to the connection so it's torn down
|
|
1040
1161
|
// deterministically when the wc is destroyed (or the connection is reset),
|
|
@@ -1063,8 +1184,8 @@ export function createViewManager(ctx) {
|
|
|
1063
1184
|
settleNativeSimulatorReady = resolve;
|
|
1064
1185
|
});
|
|
1065
1186
|
// Derive THIS project's session partition from the simulator URL's appId so
|
|
1066
|
-
// its cookies/localStorage/cache are isolated from every other project
|
|
1067
|
-
//
|
|
1187
|
+
// its cookies/localStorage/cache are isolated from every other project.
|
|
1188
|
+
// Same project → same partition (storage survives a relaunch);
|
|
1068
1189
|
// unknown appId → the shared fallback. Configure the partition's session
|
|
1069
1190
|
// (protocol handlers + CORS/referer policy) before any project content loads
|
|
1070
1191
|
// on it — idempotent per partition.
|
|
@@ -1233,13 +1354,11 @@ export function createViewManager(ctx) {
|
|
|
1233
1354
|
// embedded DevTools the right panel hosts. Attaches the CDP debugger; no-op
|
|
1234
1355
|
// if the forwarder is unwired (partial test ctx) or the debugger is claimed.
|
|
1235
1356
|
ctx.networkForward?.attachSimulator(simWc);
|
|
1236
|
-
// Model A: bounds come ONLY from the renderer's
|
|
1237
|
-
//
|
|
1238
|
-
//
|
|
1239
|
-
//
|
|
1240
|
-
|
|
1241
|
-
setNativeSimulatorViewBounds(lastRendererRect);
|
|
1242
|
-
}
|
|
1357
|
+
// Model A: bounds come ONLY from the renderer's window-level placement
|
|
1358
|
+
// snapshot. The view now exists, so re-reconcile: gateReadiness admits the
|
|
1359
|
+
// simulator (gated hidden while its WCV was absent) and the latest desired
|
|
1360
|
+
// placement attaches + sizes it. Until the next snapshot it stays unadded.
|
|
1361
|
+
reconcileNow();
|
|
1243
1362
|
// Native-host page code (console.log / wx.request / Sources) runs in the
|
|
1244
1363
|
// hidden SERVICE HOST window, not this DeviceShell host nor the render-host
|
|
1245
1364
|
// guests. Keep the right-panel DevTools host view stable and point it at the
|
|
@@ -1277,19 +1396,11 @@ export function createViewManager(ctx) {
|
|
|
1277
1396
|
// Drop the settings view too — the previous detachAllViews() did.
|
|
1278
1397
|
destroyViewInternal(settingsView);
|
|
1279
1398
|
settingsView = null;
|
|
1280
|
-
settingsViewAdded = false;
|
|
1281
1399
|
destroyViewInternal(simulatorView);
|
|
1282
1400
|
simulatorView = null;
|
|
1283
1401
|
simulatorViewAdded = false;
|
|
1284
1402
|
simulatorWebContentsId = null;
|
|
1285
1403
|
nativeSimulatorProjectPath = null;
|
|
1286
|
-
// Drop the renderer-published rect so a stale "hidden" override doesn't
|
|
1287
|
-
// suppress the next view before its renderer republishes.
|
|
1288
|
-
simulatorBoundsOverride = null;
|
|
1289
|
-
// Also drop the cached native-simulator rect: attachNativeSimulator replays
|
|
1290
|
-
// lastRendererRect on attach, so a leftover rect/offset from a torn-down
|
|
1291
|
-
// session must not be replayed onto a fresh re-attach (stale slice/offset).
|
|
1292
|
-
lastRendererRect = null;
|
|
1293
1404
|
}
|
|
1294
1405
|
// Remove (but do not destroy) the DevTools overlay from the contentView.
|
|
1295
1406
|
// Internal teardown helper for re-attach; user-facing visibility is the
|
|
@@ -1325,39 +1436,11 @@ export function createViewManager(ctx) {
|
|
|
1325
1436
|
settingsView.setBackgroundColor('#00000000');
|
|
1326
1437
|
await settingsView.webContents.loadFile(path.join(ctx.rendererDir, 'entries/settings/index.html'));
|
|
1327
1438
|
}
|
|
1328
|
-
if (!settingsViewAdded) {
|
|
1329
|
-
ctx.windows.mainWindow.contentView.addChildView(settingsView);
|
|
1330
|
-
settingsViewAdded = true;
|
|
1331
|
-
}
|
|
1332
1439
|
applySettingsBounds();
|
|
1333
1440
|
}
|
|
1334
1441
|
function hideSettings() {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
ctx.windows.mainWindow.contentView.removeChildView(settingsView);
|
|
1338
|
-
}
|
|
1339
|
-
catch { /* ignore */ }
|
|
1340
|
-
settingsViewAdded = false;
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
// Keep the TOP-tier overlays (settings, popover) above the BASE-tier native
|
|
1344
|
-
// overlays (the native simulator WCV + the console/DevTools WCV). Native
|
|
1345
|
-
// overlays are z-ordered by `addChildView` insertion order — the last-added
|
|
1346
|
-
// sits on top — so RE-attaching a base overlay while a top overlay is open
|
|
1347
|
-
// (e.g. the simulator re-shows on a tab switch, or the console bounds
|
|
1348
|
-
// republish re-adds it) would move the base ABOVE the open settings/popover
|
|
1349
|
-
// and occlude it. Whenever a base overlay is (re)added, re-append the open top
|
|
1350
|
-
// overlays so they stay on top. Settings is re-appended before popover so a
|
|
1351
|
-
// simultaneously-open popover ends up topmost. A no-op when neither is open
|
|
1352
|
-
// (pinned by the z-order guard test).
|
|
1353
|
-
function raiseTopOverlays() {
|
|
1354
|
-
if (ctx.windows.mainWindow.isDestroyed())
|
|
1355
|
-
return;
|
|
1356
|
-
const cv = ctx.windows.mainWindow.contentView;
|
|
1357
|
-
if (settingsView && settingsViewAdded)
|
|
1358
|
-
cv.addChildView(settingsView);
|
|
1359
|
-
if (popoverView)
|
|
1360
|
-
cv.addChildView(popoverView);
|
|
1442
|
+
overlayDesired.delete(VIEW_ID.settings);
|
|
1443
|
+
reconcileNow();
|
|
1361
1444
|
}
|
|
1362
1445
|
function showPopover(data) {
|
|
1363
1446
|
hidePopover();
|
|
@@ -1373,7 +1456,6 @@ export function createViewManager(ctx) {
|
|
|
1373
1456
|
applyNavigationHardening(popover.webContents, ctx.rendererDir);
|
|
1374
1457
|
popoverView = popover;
|
|
1375
1458
|
popover.setBackgroundColor('#00000000');
|
|
1376
|
-
ctx.windows.mainWindow.contentView.addChildView(popover);
|
|
1377
1459
|
applyPopoverBounds();
|
|
1378
1460
|
popover.webContents.once('did-finish-load', () => {
|
|
1379
1461
|
ctx.notify.popoverInit(popover, data);
|
|
@@ -1381,19 +1463,23 @@ export function createViewManager(ctx) {
|
|
|
1381
1463
|
popover.webContents.loadFile(path.join(ctx.rendererDir, 'entries/popover/index.html'));
|
|
1382
1464
|
}
|
|
1383
1465
|
function hidePopover() {
|
|
1384
|
-
if (popoverView)
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1466
|
+
if (!popoverView)
|
|
1467
|
+
return;
|
|
1468
|
+
overlayDesired.delete(VIEW_ID.popover);
|
|
1469
|
+
// Destroy the WCV first (removeChildView + close), THEN reconcile: the detach
|
|
1470
|
+
// op then finds the view already gone and does not double-removeChildView.
|
|
1471
|
+
destroyViewInternal(popoverView);
|
|
1472
|
+
popoverView = null;
|
|
1473
|
+
reconcileNow();
|
|
1474
|
+
ctx.notify.popoverClosed();
|
|
1389
1475
|
}
|
|
1390
1476
|
function repositionAll() {
|
|
1391
1477
|
// Simulator + DevTools overlay: bounds owned by the renderer's anchor
|
|
1392
1478
|
// publishes; their ResizeObserver/window-resize listeners re-measure, so
|
|
1393
1479
|
// no static re-apply here.
|
|
1394
|
-
if (
|
|
1480
|
+
if (overlayDesired.has(VIEW_ID.settings))
|
|
1395
1481
|
applySettingsBounds();
|
|
1396
|
-
if (
|
|
1482
|
+
if (overlayDesired.has(VIEW_ID.popover))
|
|
1397
1483
|
applyPopoverBounds();
|
|
1398
1484
|
}
|
|
1399
1485
|
function disposeAll() {
|
|
@@ -1420,63 +1506,11 @@ export function createViewManager(ctx) {
|
|
|
1420
1506
|
}
|
|
1421
1507
|
safeArea.dispose();
|
|
1422
1508
|
}
|
|
1423
|
-
function setNativeSimulatorViewBounds(params) {
|
|
1424
|
-
// Cache unconditionally so attachNativeSimulator can replay a report that
|
|
1425
|
-
// landed before the view existed (project-open ordering). This rect is the
|
|
1426
|
-
// ONLY authority for the native WCV bounds.
|
|
1427
|
-
lastRendererRect = params;
|
|
1428
|
-
if (ctx.windows.mainWindow.isDestroyed() || !nativeSimulatorView)
|
|
1429
|
-
return;
|
|
1430
|
-
const p = layout.computeNativeSimulatorViewParams(params, params.zoom);
|
|
1431
|
-
currentZoomFactor = p.zoomFactor;
|
|
1432
|
-
// A zero-area rect means "hide" — the renderer reports this when the
|
|
1433
|
-
// simulator panel/cell is toggled off or unmounts (toolbar toggle only
|
|
1434
|
-
// mutates renderer layout state, so without this the WCV would stay
|
|
1435
|
-
// painted over its old region). Mirror `setSimulatorDevtoolsBounds`:
|
|
1436
|
-
// remove the child view from the contentView but keep its WebContents
|
|
1437
|
-
// alive, so re-showing doesn't re-pay the simulator bootstrap.
|
|
1438
|
-
if (isHidden(p.bounds)) {
|
|
1439
|
-
if (nativeSimulatorViewAdded) {
|
|
1440
|
-
try {
|
|
1441
|
-
ctx.windows.mainWindow.contentView.removeChildView(nativeSimulatorView);
|
|
1442
|
-
}
|
|
1443
|
-
catch { /* already removed */ }
|
|
1444
|
-
nativeSimulatorViewAdded = false;
|
|
1445
|
-
}
|
|
1446
|
-
return;
|
|
1447
|
-
}
|
|
1448
|
-
if (!nativeSimulatorViewAdded) {
|
|
1449
|
-
ctx.windows.mainWindow.contentView.addChildView(nativeSimulatorView);
|
|
1450
|
-
nativeSimulatorViewAdded = true;
|
|
1451
|
-
// Re-attaching this base overlay moved it to the top of the z-stack; keep
|
|
1452
|
-
// any open settings/popover above it.
|
|
1453
|
-
raiseTopOverlays();
|
|
1454
|
-
}
|
|
1455
|
-
nativeSimulatorView.setBounds(p.bounds);
|
|
1456
|
-
const simWc = nativeSimulatorView.webContents;
|
|
1457
|
-
if (!simWc.isDestroyed()) {
|
|
1458
|
-
simWc.setZoomFactor(p.zoomFactor);
|
|
1459
|
-
}
|
|
1460
|
-
// Propagate zoom to any already-attached nested render-host guests so the
|
|
1461
|
-
// page rescales live on zoom change (newly-attached guests get it in
|
|
1462
|
-
// did-attach-webview). `webContents.getAllWebContents()` includes guests;
|
|
1463
|
-
// filter to those hosted by this simulator wc.
|
|
1464
|
-
try {
|
|
1465
|
-
for (const wc of webContents.getAllWebContents()) {
|
|
1466
|
-
if (wc.isDestroyed())
|
|
1467
|
-
continue;
|
|
1468
|
-
if (wc.hostWebContents === simWc) {
|
|
1469
|
-
wc.setZoomFactor(p.zoomFactor);
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
catch { /* hostWebContents unavailable; guests get zoom on attach */ }
|
|
1474
|
-
}
|
|
1475
1509
|
function resize(_simWidth) {
|
|
1476
1510
|
// Simulator + DevTools overlay bounds are owned solely by the renderer's
|
|
1477
1511
|
// anchor publishes — its ResizeObserver/window-resize listeners re-measure
|
|
1478
1512
|
// on this same resize. No static re-apply (it raced the precise rect).
|
|
1479
|
-
if (
|
|
1513
|
+
if (overlayDesired.has(VIEW_ID.settings))
|
|
1480
1514
|
applySettingsBounds();
|
|
1481
1515
|
}
|
|
1482
1516
|
return {
|
|
@@ -1520,15 +1554,12 @@ export function createViewManager(ctx) {
|
|
|
1520
1554
|
},
|
|
1521
1555
|
getHostToolbarWebContentsId: () => liveHostToolbarWebContents()?.id ?? null,
|
|
1522
1556
|
getHostToolbarHeight: () => hostToolbarLastHeight,
|
|
1523
|
-
setNativeSimulatorViewBounds,
|
|
1524
1557
|
resize,
|
|
1525
|
-
|
|
1558
|
+
setPlacementSnapshot,
|
|
1526
1559
|
attachWorkbench,
|
|
1527
1560
|
setWorkbenchSource,
|
|
1528
|
-
setWorkbenchBounds,
|
|
1529
1561
|
detachWorkbench,
|
|
1530
1562
|
openFileInWorkbench,
|
|
1531
|
-
setHostToolbarBounds,
|
|
1532
1563
|
setHostToolbarHeight,
|
|
1533
1564
|
hostToolbar,
|
|
1534
1565
|
};
|