Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow creation of new window to be customizable. #41432

Merged
merged 1 commit into from Feb 29, 2024

Conversation

khalwa
Copy link
Contributor

@khalwa khalwa commented Feb 25, 2024

Description of Change

This PR adds a way to manually control the creation of a guest window in webContents.setWindowOpenHandler. My main motivation for this change is to have the possibility to properly handle new windows in form of BrowserView (in order to support window.opener I need to pass appropriate WebContents when creating an instance of it).

I am not an expert so I don't know what important things I could've missed introducing this change but I am hoping that with your guidance we'll be able to work on this PR and make such functionality possible in Electron.

This is a copy of #33134 but this time set up from my private fork.

Checklist

Release Notes

Notes: Extended webContents.setWindowOpenHandler to support manual creation of BrowserWindow.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened in the last 24 hours label Feb 25, 2024
@khalwa khalwa force-pushed the override-window-open-function-2 branch 2 times, most recently from cd39cc1 to e8c6988 Compare February 25, 2024 19:01
@samuelmaddock samuelmaddock added semver/minor backwards-compatible functionality no-backport labels Feb 26, 2024
Copy link
Member

@samuelmaddock samuelmaddock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API LGTM

Copy link
Member

@nornagon nornagon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API LGTM

@samuelmaddock
Copy link
Member

Linux build failure is a known flaky test

@khalwa khalwa force-pushed the override-window-open-function-2 branch from e8c6988 to 2af7bb0 Compare February 29, 2024 07:37
@jkleinsc jkleinsc merged commit a0dad83 into electron:main Feb 29, 2024
14 checks passed
Copy link

welcome bot commented Feb 29, 2024

Congrats on merging your first pull request! 🎉🎉🎉

Copy link

release-clerk bot commented Feb 29, 2024

Release Notes Persisted

Extended webContents.setWindowOpenHandler to support manual creation of BrowserWindow.

@PalmerAL
Copy link
Contributor

@khalwa Sorry if I'm not understanding something, but how is this API supposed to work with WebContentsView (which is replacing BrowserView)?

With a BrowserView, the options.webContents can be passed in, but WebContentsView doesn't have an equivalent option. If I do this:

return {
        action: 'allow',
        createWindow: function (options) {
          const view = new WebContentsView(options)
          return view.webContents
        }
      }

I get:

Error: Invalid webContents. Created window should be connected to webContents passed with options object.

@khalwa
Copy link
Contributor Author

khalwa commented Apr 26, 2024

@PalmerAL Hi! This PR was started two years ago (see reference in description) when WebContentsView was not introduced yet so I was creating it with mainly BrowserView in mind. I was checking what you have said and I was not able to make this work with WebContentsView either. I am not sure if it allows setting webContents by the constructor. If we take a look at the implementation of BrowserView it is now using internally WebContentsView and in the constructor we see that it actually sets the webContents as a "hidden field" of webPreferences object: https://github.com/electron/electron/blob/main/lib/browser/api/browser-view.ts#L15-L17. So in order for it to work with WebContentsView I think there needs to be a way to pass webContents to it programatically, but its not documented anywhere and I do not know how/if it is possible in the current implementation to do it.

Edit:
Here is a code that I tried out in Electron Fiddle and it made this work with WebContentsView. It uses Electron internals and should not be used but kind of proves that there is a problem with setting webContents for that type.

mainWindow.webContents.setWindowOpenHandler((details) => {
    return {
      action: 'allow',
      createWindow: (options) => {
        const webPreferences = {
          ...options.webPreferences,
        }
        webPreferences.type = "browserView";
        
        const v8Util = process._linkedBinding('electron_common_v8_util');
        v8Util.setHiddenValue(webPreferences, "webContents", options.webContents);

        const webContentsView = new WebContentsView({
          webPreferences
        })
        webContentsView.setBounds({x: 0, y: 0, width: 300, height: 300})
        mainWindow.contentView.addChildView(webContentsView)
        return webContentsView.webContents
      }
    }
  })

@PalmerAL
Copy link
Contributor

@khalwa Thanks! That matches my investigation too.

@nornagon Since it looks like you wrote the WebContentsView implementation and also reviewed this previously:

  1. Is there a reason that WebContentsView doesn't expose a public option to create a view with a pre-existing contents like BrowserView did?
  2. What would be the process for proposing an API change to make these two things work together?

@PalmerAL
Copy link
Contributor

PalmerAL commented May 6, 2024

#42054

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-review/requested 🗳 new-pr 🌱 PR opened in the last 24 hours no-backport semver/minor backwards-compatible functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants