dsh-builtin-browser 0.1.19 → 0.1.21
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/README.en.md +22 -8
- package/README.md +22 -8
- package/docs/architecture.md +2 -2
- package/docs/user-guide.md +3 -3
- package/lib/browser-electron/host-main.js +38 -7
- package/lib/browser-electron/remote-host.d.ts +76 -1
- package/lib/browser-electron/remote-host.js +294 -123
- package/package.json +1 -1
- package/src/browser-electron/host-main.ts +35 -7
- package/src/browser-electron/remote-host.ts +315 -115
|
@@ -327,8 +327,11 @@ function windowFor(windowId: string | undefined): HostWindow {
|
|
|
327
327
|
// regaining focus (alt-tab, click) does not automatically refocus any view
|
|
328
328
|
// (electron#28163) — the last addChildView keeps the focus. Restore the view
|
|
329
329
|
// the human was last using (click steering via wireFocusRouting), falling
|
|
330
|
-
// back to the visible page view.
|
|
330
|
+
// back to the visible page view. Windows-only: on macOS/Linux the OS routes
|
|
331
|
+
// keyboard input to the clicked view natively, and forcing focus() on window
|
|
332
|
+
// focus fights the platform — it can leave page inputs untypeable (issue #7).
|
|
331
333
|
w.on('focus', () => {
|
|
334
|
+
if (process.platform !== 'win32') return
|
|
332
335
|
const last = win.lastFocusedViewId
|
|
333
336
|
const wc = last === TOOLBAR_FOCUS ? win.toolbarView?.webContents
|
|
334
337
|
: last !== undefined ? win.views.get(last)?.webContentsView.webContents
|
|
@@ -361,8 +364,14 @@ function layoutWindow(win: HostWindow): void {
|
|
|
361
364
|
* regaining focus does not refocus any view, electron#28163). Focusing the
|
|
362
365
|
* clicked view on mousedown makes the toolbar and pages behave like a real
|
|
363
366
|
* browser: click the URL bar and type, click the page and type/scroll.
|
|
367
|
+
*
|
|
368
|
+
* Windows-only by design (issue #7): macOS/Linux already route keyboard input
|
|
369
|
+
* to the clicked view natively; calling webContents.focus() from inside the
|
|
370
|
+
* mousedown input-event there interferes with native click-to-focus and can
|
|
371
|
+
* leave login/page inputs unable to receive typed characters.
|
|
364
372
|
*/
|
|
365
373
|
function wireFocusRouting(win: HostWindow, view: WebContentsView, focusKey: string): void {
|
|
374
|
+
if (process.platform !== 'win32') return
|
|
366
375
|
view.webContents.on('input-event', (_event, input) => {
|
|
367
376
|
if (input.type !== 'mouseDown') return
|
|
368
377
|
win.lastFocusedViewId = focusKey
|
|
@@ -498,17 +507,36 @@ async function handle(op: string, msg: { id: number; viewId?: string; windowId?:
|
|
|
498
507
|
case 'createView': {
|
|
499
508
|
const viewId = msg.viewId
|
|
500
509
|
if (viewId === undefined) throw new Error('createView missing viewId')
|
|
510
|
+
// Idempotent against a duplicate createView for the same id (e.g. two
|
|
511
|
+
// concurrent parent-side recoveries after a host death): re-creating
|
|
512
|
+
// would stack a second WebContentsView in the window and leak the
|
|
513
|
+
// first — the duplicate call simply confirms the existing view.
|
|
514
|
+
if (windowOfView(viewId) !== undefined) {
|
|
515
|
+
reply(msg.id, { ok: true })
|
|
516
|
+
return
|
|
517
|
+
}
|
|
501
518
|
const assignment = assignments.get(viewId)
|
|
502
519
|
const win = windowFor(assignment?.windowId)
|
|
503
520
|
const view = new WebContentsView()
|
|
504
|
-
// Route popups (window.open / target=_blank)
|
|
505
|
-
// instead of letting Electron open untracked native windows
|
|
506
|
-
// diverge from the session/tab model.
|
|
521
|
+
// Route popups (window.open / target=_blank) into the session/tab
|
|
522
|
+
// model instead of letting Electron open untracked native windows.
|
|
507
523
|
view.webContents.setWindowOpenHandler(({ url }) => {
|
|
508
|
-
// HTTP(S) popups
|
|
509
|
-
//
|
|
524
|
+
// HTTP(S) popups open as a NEW TAB of this view's session: the
|
|
525
|
+
// parent (provider) owns the session model and its newTab action
|
|
526
|
+
// creates the tab in the same window, navigates it, and records it
|
|
527
|
+
// in the session history. Overriding THIS view with loadURL()
|
|
528
|
+
// destroyed the opener page — pages that need their opener context
|
|
529
|
+
// (portal dashboards carrying token/referer to the new window)
|
|
530
|
+
// lost it and the target page then 403'd (issue #8); the tab strip
|
|
531
|
+
// now keeps the original page alive like a real browser.
|
|
510
532
|
if (/^https?:/i.test(url)) {
|
|
511
|
-
|
|
533
|
+
if (win.windowId !== SHARED_WINDOW_ID) {
|
|
534
|
+
sendUserAction({ type: 'newTab', windowId: win.windowId, url })
|
|
535
|
+
} else {
|
|
536
|
+
// Ungrouped view (no live session to attach a tab to,
|
|
537
|
+
// defensive only): fall back to navigating this view.
|
|
538
|
+
void view.webContents.loadURL(url).catch(() => { /* navigation failures surface on the next snapshot */ })
|
|
539
|
+
}
|
|
512
540
|
return { action: 'deny' }
|
|
513
541
|
}
|
|
514
542
|
// Non-HTTP popups (OAuth redirects, mailto:, custom schemes):
|