fix: context-menu
event with BaseWindows
(#44953)
fix: context-menu event with BaseWindows Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
parent
0af5ec3758
commit
4062d18270
4 changed files with 78 additions and 26 deletions
|
@ -72,7 +72,7 @@ The `menu` object has the following instance methods:
|
||||||
#### `menu.popup([options])`
|
#### `menu.popup([options])`
|
||||||
|
|
||||||
* `options` Object (optional)
|
* `options` Object (optional)
|
||||||
* `window` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
|
* `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
|
||||||
* `x` number (optional) - Default is the current mouse cursor position.
|
* `x` number (optional) - Default is the current mouse cursor position.
|
||||||
Must be declared if `y` is declared.
|
Must be declared if `y` is declared.
|
||||||
* `y` number (optional) - Default is the current mouse cursor position.
|
* `y` number (optional) - Default is the current mouse cursor position.
|
||||||
|
@ -86,13 +86,13 @@ The `menu` object has the following instance methods:
|
||||||
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
||||||
* `callback` Function (optional) - Called when menu is closed.
|
* `callback` Function (optional) - Called when menu is closed.
|
||||||
|
|
||||||
Pops up this menu as a context menu in the [`BrowserWindow`](browser-window.md).
|
Pops up this menu as a context menu in the [`BaseWindow`](base-window.md).
|
||||||
|
|
||||||
#### `menu.closePopup([browserWindow])`
|
#### `menu.closePopup([window])`
|
||||||
|
|
||||||
* `browserWindow` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
|
* `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
|
||||||
|
|
||||||
Closes the context menu in the `browserWindow`.
|
Closes the context menu in the `window`.
|
||||||
|
|
||||||
#### `menu.append(menuItem)`
|
#### `menu.append(menuItem)`
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@ class DelayedNativeViewHost : public views::NativeViewHost {
|
||||||
void ViewHierarchyChanged(
|
void ViewHierarchyChanged(
|
||||||
const views::ViewHierarchyChangedDetails& details) override;
|
const views::ViewHierarchyChangedDetails& details) override;
|
||||||
|
|
||||||
gfx::NativeView GetNativeView() { return native_view_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gfx::NativeView native_view_;
|
gfx::NativeView native_view_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -201,26 +201,29 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
|
||||||
if (event.type == NSEventTypeRightMouseDown ||
|
if (event.type == NSEventTypeRightMouseDown ||
|
||||||
(event.type == NSEventTypeLeftMouseDown &&
|
(event.type == NSEventTypeLeftMouseDown &&
|
||||||
([event modifierFlags] & NSEventModifierFlagControl))) {
|
([event modifierFlags] & NSEventModifierFlagControl))) {
|
||||||
// The WebContentsView is added a sibling of BaseWindow's contentView at
|
// We're looking for the NativeViewHost that contains the WebContentsView.
|
||||||
// index 0 before it in the paint order - see
|
// There can be two possible NativeViewHosts - one containing the
|
||||||
// https://github.com/electron/electron/pull/41256.
|
// WebContentsView (present for BrowserWindows) and the one containing the
|
||||||
|
// VibrantView (present when vibrancy is set). We want the one containing
|
||||||
|
// the WebContentsView if it exists.
|
||||||
const auto& children = shell_->GetContentsView()->children();
|
const auto& children = shell_->GetContentsView()->children();
|
||||||
if (children.empty())
|
const auto it = std::ranges::find_if(children, [&](views::View* child) {
|
||||||
return;
|
if (std::strcmp(child->GetClassName(), "NativeViewHost") == 0) {
|
||||||
|
auto* nvh = static_cast<views::NativeViewHost*>(child);
|
||||||
|
return nvh->native_view().GetNativeNSView() != [self vibrantView];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
auto* wcv = children.front().get();
|
if (it != children.end()) {
|
||||||
if (!wcv)
|
auto ns_view = static_cast<electron::DelayedNativeViewHost*>(*it)
|
||||||
return;
|
->native_view()
|
||||||
|
|
||||||
auto ns_view = static_cast<electron::DelayedNativeViewHost*>(wcv)
|
|
||||||
->GetNativeView()
|
|
||||||
.GetNativeNSView();
|
.GetNativeNSView();
|
||||||
if (!ns_view)
|
if (ns_view) {
|
||||||
return;
|
|
||||||
|
|
||||||
[static_cast<ElectronInspectableWebContentsView*>(ns_view)
|
[static_cast<ElectronInspectableWebContentsView*>(ns_view)
|
||||||
redispatchContextMenuEvent:base::apple::OwnedNSEvent(event)];
|
redispatchContextMenuEvent:base::apple::OwnedNSEvent(event)];
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[super sendEvent:event];
|
[super sendEvent:event];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BrowserWindow, ipcMain, webContents, session, app, BrowserView, WebContents } from 'electron/main';
|
import { BrowserWindow, ipcMain, webContents, session, app, BrowserView, WebContents, BaseWindow, WebContentsView } from 'electron/main';
|
||||||
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
|
|
||||||
|
@ -2734,6 +2734,57 @@ describe('webContents module', () => {
|
||||||
expect(params.x).to.be.a('number');
|
expect(params.x).to.be.a('number');
|
||||||
expect(params.y).to.be.a('number');
|
expect(params.y).to.be.a('number');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('emits when right clicked in a WebContentsView', async () => {
|
||||||
|
const w = new BaseWindow({ show: false });
|
||||||
|
|
||||||
|
const mainView = new WebContentsView({
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.js')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const draggablePage = path.join(fixturesPath, 'pages', 'draggable-page.html');
|
||||||
|
await mainView.webContents.loadFile(draggablePage);
|
||||||
|
|
||||||
|
w.contentView.addChildView(mainView);
|
||||||
|
|
||||||
|
const { width, height } = w.getContentBounds();
|
||||||
|
mainView.setBounds({ x: 0, y: 0, width, height });
|
||||||
|
|
||||||
|
const promise = once(mainView.webContents, 'context-menu') as Promise<[any, Electron.ContextMenuParams]>;
|
||||||
|
|
||||||
|
// Simulate right-click to create context-menu event.
|
||||||
|
const opts = { x: 0, y: 0, button: 'right' as const };
|
||||||
|
mainView.webContents.sendInputEvent({ ...opts, type: 'mouseDown' });
|
||||||
|
mainView.webContents.sendInputEvent({ ...opts, type: 'mouseUp' });
|
||||||
|
|
||||||
|
const [, params] = await promise;
|
||||||
|
|
||||||
|
expect(params.pageURL).to.equal(mainView.webContents.getURL());
|
||||||
|
expect(params.frame).to.be.an('object');
|
||||||
|
expect(params.x).to.be.a('number');
|
||||||
|
expect(params.y).to.be.a('number');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('emits when right clicked in a BrowserWindow with vibrancy', async () => {
|
||||||
|
const w = new BrowserWindow({ show: false, vibrancy: 'titlebar' });
|
||||||
|
await w.loadFile(path.join(fixturesPath, 'pages', 'draggable-page.html'));
|
||||||
|
|
||||||
|
const promise = once(w.webContents, 'context-menu') as Promise<[any, Electron.ContextMenuParams]>;
|
||||||
|
|
||||||
|
// Simulate right-click to create context-menu event.
|
||||||
|
const opts = { x: 0, y: 0, button: 'right' as const };
|
||||||
|
w.webContents.sendInputEvent({ ...opts, type: 'mouseDown' });
|
||||||
|
w.webContents.sendInputEvent({ ...opts, type: 'mouseUp' });
|
||||||
|
|
||||||
|
const [, params] = await promise;
|
||||||
|
|
||||||
|
expect(params.pageURL).to.equal(w.webContents.getURL());
|
||||||
|
expect(params.frame).to.be.an('object');
|
||||||
|
expect(params.x).to.be.a('number');
|
||||||
|
expect(params.y).to.be.a('number');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('close() method', () => {
|
describe('close() method', () => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue