fix: context-menu emitted twice (#44978)

* fix: context-menu emitted twice

* refactor: simplify disabling draggable regions

* cleanup
This commit is contained in:
Sam Maddock 2024-12-11 11:42:48 -05:00 committed by GitHub
parent cf5a4640f5
commit 2c698d3f75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 51 additions and 65 deletions

View file

@ -49,8 +49,6 @@ using electron::InspectableWebContentsViewMac;
- (void)setTitle:(NSString*)title;
- (NSString*)getTitle;
- (void)redispatchContextMenuEvent:(base::apple::OwnedNSEvent)theEvent;
@end
#endif // ELECTRON_SHELL_BROWSER_UI_COCOA_ELECTRON_INSPECTABLE_WEB_CONTENTS_VIEW_H_

View file

@ -298,29 +298,6 @@
[self notifyDevToolsFocused];
}
- (void)redispatchContextMenuEvent:(base::apple::OwnedNSEvent)event {
DCHECK(event.Get().type == NSEventTypeRightMouseDown ||
(event.Get().type == NSEventTypeLeftMouseDown &&
(event.Get().modifierFlags & NSEventModifierFlagControl)));
content::WebContents* contents =
inspectableWebContentsView_->inspectable_web_contents()->GetWebContents();
electron::api::WebContents* api_contents =
electron::api::WebContents::From(contents);
if (api_contents) {
// Temporarily pretend that the WebContents is fully non-draggable while we
// re-send the mouse event. This allows the re-dispatched event to "land"
// on the WebContents, instead of "falling through" back to the window.
auto* rwhv = contents->GetRenderWidgetHostView();
if (rwhv) {
api_contents->SetForceNonDraggable(true);
BaseView* contentsView =
(BaseView*)rwhv->GetNativeView().GetNativeNSView();
[contentsView mouseEvent:event.Get()];
api_contents->SetForceNonDraggable(false);
}
}
}
#pragma mark - NSWindowDelegate
- (void)windowWillClose:(NSNotification*)notification {

View file

@ -6,6 +6,7 @@
#include "base/strings/sys_string_conversions.h"
#include "electron/mas.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/native_window_mac.h"
#include "shell/browser/ui/cocoa/delayed_native_view_host.h"
#include "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h"
@ -193,41 +194,23 @@ void SwizzleSwipeWithEvent(NSView* view, SEL swiz_selector) {
- (void)sendEvent:(NSEvent*)event {
// Draggable regions only respond to left-click dragging, but the system will
// still suppress right-clicks in a draggable region. Forwarding right-clicks
// and ctrl+left-clicks allows the underlying views to respond to right-click
// to potentially bring up a frame context menu. WebContentsView is now a
// sibling view of the NSWindow contentView, so we need to intercept the event
// here as NativeWidgetMacNSWindow won't forward it to the WebContentsView
// anymore.
if (event.type == NSEventTypeRightMouseDown ||
(event.type == NSEventTypeLeftMouseDown &&
([event modifierFlags] & NSEventModifierFlagControl))) {
// We're looking for the NativeViewHost that contains the WebContentsView.
// There can be two possible NativeViewHosts - one containing the
// 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 it = std::ranges::find_if(children, [&](views::View* child) {
if (std::strcmp(child->GetClassName(), "NativeViewHost") == 0) {
auto* nvh = static_cast<views::NativeViewHost*>(child);
return nvh->native_view().GetNativeNSView() != [self vibrantView];
}
return false;
});
// still suppress right-clicks in a draggable region. Temporarily disabling
// draggable regions allows the underlying views to respond to right-click
// to potentially bring up a frame context menu.
BOOL shouldDisableDraggable =
(event.type == NSEventTypeRightMouseDown ||
(event.type == NSEventTypeLeftMouseDown &&
([event modifierFlags] & NSEventModifierFlagControl)));
if (it != children.end()) {
auto ns_view = static_cast<electron::DelayedNativeViewHost*>(*it)
->native_view()
.GetNativeNSView();
if (ns_view) {
[static_cast<ElectronInspectableWebContentsView*>(ns_view)
redispatchContextMenuEvent:base::apple::OwnedNSEvent(event)];
}
}
if (shouldDisableDraggable) {
electron::api::WebContents::SetDisableDraggableRegions(true);
}
[super sendEvent:event];
if (shouldDisableDraggable) {
electron::api::WebContents::SetDisableDraggableRegions(false);
}
}
- (void)rotateWithEvent:(NSEvent*)event {