mac: views: Add customization point for acceptsFirstMouse (fixes #3680)

This commit is contained in:
Nik Pavlov
2024-04-12 15:49:31 +00:00
committed by Marshall Greenblatt
parent 96dc172980
commit 744a194a6e
15 changed files with 160 additions and 12 deletions

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=b292cdf6e293dfd42c30ea9189b2a8a2ed77ba7a$ // $hash=e6bbc33db1b5ed3832982f8799e14557204f4028$
// //
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_ #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
@ -182,6 +182,20 @@ typedef struct _cef_window_delegate_t {
struct _cef_window_t* window, struct _cef_window_t* window,
float* titlebar_height); float* titlebar_height);
///
/// Return whether the view should accept the initial mouse-down event,
/// allowing it to respond to click-through behavior. If STATE_ENABLED is
/// returned, the view will be sent a mouseDown: message for an initial mouse-
/// down event, activating the view with one click, instead of clicking first
/// to make the window active and then clicking the view.
///
/// This function is only supported on macOS. For more details, refer to the
/// documentation of acceptsFirstMouse.
///
cef_state_t(CEF_CALLBACK* accepts_first_mouse)(
struct _cef_window_delegate_t* self,
struct _cef_window_t* window);
/// ///
/// Return true (1) if |window| can be resized. /// Return true (1) if |window| can be resized.
/// ///

View File

@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal // way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash // hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected. // values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "ed9b17c85e769cb4d087390a77bed6613fed9166" #define CEF_API_HASH_UNIVERSAL "de72aee0623e568ded52b7075c7fda576844e8b3"
#if defined(OS_WIN) #if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "5f47de7bf681782160a81ee201cef71f82ac9d69" #define CEF_API_HASH_PLATFORM "46bb69fe7038d7e9f8d4ee86e4a0825bb2d289b7"
#elif defined(OS_MAC) #elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "d4ca78dc9bc6357c4a05679b2da0863b543f96fa" #define CEF_API_HASH_PLATFORM "e3ef47d5541f5260eba70030386d692138315900"
#elif defined(OS_LINUX) #elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "2dfd768af8ca7aa0474a2014b05cec33f64d83b0" #define CEF_API_HASH_PLATFORM "579ef9c5282456c7de906cf055aed0ff4ba0a5a3"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -176,6 +176,21 @@ class CefWindowDelegate : public CefPanelDelegate {
return false; return false;
} }
///
/// Return whether the view should accept the initial mouse-down event,
/// allowing it to respond to click-through behavior. If STATE_ENABLED is
/// returned, the view will be sent a mouseDown: message for an initial
/// mouse-down event, activating the view with one click, instead of clicking
/// first to make the window active and then clicking the view.
///
/// This method is only supported on macOS. For more details, refer to the
/// documentation of acceptsFirstMouse.
///
/*--cef(default_retval=STATE_DEFAULT)--*/
virtual cef_state_t AcceptsFirstMouse(CefRefPtr<CefWindow> window) {
return STATE_DEFAULT;
}
/// ///
/// Return true if |window| can be resized. /// Return true if |window| can be resized.
/// ///

View File

@ -87,10 +87,12 @@ NativeWidgetMacNSWindow* CefNativeWidgetMac::CreateNSWindow(
NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable |
NSWindowStyleMaskTexturedBackground; NSWindowStyleMaskTexturedBackground;
bool is_frameless = window_delegate_->IsFrameless(window_); const bool is_frameless = window_delegate_->IsFrameless(window_);
const auto accepts_first_mouse = window_delegate_->AcceptsFirstMouse(window_);
auto window = [[CefNSWindow alloc] initWithStyle:style_mask auto window = [[CefNSWindow alloc] initWithStyle:style_mask
isFrameless:is_frameless]; isFrameless:is_frameless
acceptsFirstMouse:accepts_first_mouse];
if (is_frameless) { if (is_frameless) {
[window setTitlebarAppearsTransparent:YES]; [window setTitlebarAppearsTransparent:YES];

View File

@ -6,15 +6,22 @@
#define CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_ #define CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_
#pragma once #pragma once
#include "include/internal/cef_types.h"
#include "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h" #include "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h"
@interface CefNSWindow : NativeWidgetMacNSWindow { @interface CefNSWindow : NativeWidgetMacNSWindow {
@private @private
bool is_frameless_; bool is_frameless_;
cef_state_t accepts_first_mouse_;
} }
- (id)initWithStyle:(NSUInteger)style_mask isFrameless:(bool)is_frameless;
- (id)initWithStyle:(NSUInteger)style_mask
isFrameless:(bool)is_frameless
acceptsFirstMouse:(cef_state_t)accepts_first_mouse;
- (BOOL)shouldCenterTrafficLights; - (BOOL)shouldCenterTrafficLights;
- (int)acceptsFirstMouse;
@end @end
#endif // CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_ #endif // CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_

View File

@ -64,12 +64,15 @@
@implementation CefNSWindow @implementation CefNSWindow
- (id)initWithStyle:(NSUInteger)style_mask isFrameless:(bool)is_frameless { - (id)initWithStyle:(NSUInteger)style_mask
isFrameless:(bool)is_frameless
acceptsFirstMouse:(cef_state_t)accepts_first_mouse {
if ((self = [super initWithContentRect:ui::kWindowSizeDeterminedLater if ((self = [super initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:style_mask styleMask:style_mask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO])) { defer:NO])) {
is_frameless_ = is_frameless; is_frameless_ = is_frameless;
accepts_first_mouse_ = accepts_first_mouse;
} }
return self; return self;
} }
@ -102,4 +105,8 @@
return [super frameViewClassForStyleMask:windowStyle]; return [super frameViewClassForStyleMask:windowStyle];
} }
- (int)acceptsFirstMouse {
return accepts_first_mouse_;
}
@end @end

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=4350cb3f26c9b2a56bac5a0368eab19dff8659ae$ // $hash=4d171663d78dd204b321d77248f44ed7f0d752b8$
// //
#include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h" #include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h"
@ -374,6 +374,31 @@ window_delegate_get_titlebar_height(struct _cef_window_delegate_t* self,
return _retval; return _retval;
} }
cef_state_t CEF_CALLBACK
window_delegate_accepts_first_mouse(struct _cef_window_delegate_t* self,
cef_window_t* window) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self) {
return STATE_DEFAULT;
}
// Verify param: window; type: refptr_diff
DCHECK(window);
if (!window) {
return STATE_DEFAULT;
}
// Execute
cef_state_t _retval = CefWindowDelegateCppToC::Get(self)->AcceptsFirstMouse(
CefWindowCToCpp::Wrap(window));
// Return type: simple
return _retval;
}
int CEF_CALLBACK window_delegate_can_resize(struct _cef_window_delegate_t* self, int CEF_CALLBACK window_delegate_can_resize(struct _cef_window_delegate_t* self,
cef_window_t* window) { cef_window_t* window) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();
@ -860,6 +885,7 @@ CefWindowDelegateCppToC::CefWindowDelegateCppToC() {
GetStruct()->with_standard_window_buttons = GetStruct()->with_standard_window_buttons =
window_delegate_with_standard_window_buttons; window_delegate_with_standard_window_buttons;
GetStruct()->get_titlebar_height = window_delegate_get_titlebar_height; GetStruct()->get_titlebar_height = window_delegate_get_titlebar_height;
GetStruct()->accepts_first_mouse = window_delegate_accepts_first_mouse;
GetStruct()->can_resize = window_delegate_can_resize; GetStruct()->can_resize = window_delegate_can_resize;
GetStruct()->can_maximize = window_delegate_can_maximize; GetStruct()->can_maximize = window_delegate_can_maximize;
GetStruct()->can_minimize = window_delegate_can_minimize; GetStruct()->can_minimize = window_delegate_can_minimize;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=18fd259f012c67956bda267a62d0e30971c696ca$ // $hash=e7548cf2202aa3827f45c56a706f735606db1f83$
// //
#include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h" #include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h"
@ -363,6 +363,32 @@ bool CefWindowDelegateCToCpp::GetTitlebarHeight(CefRefPtr<CefWindow> window,
return _retval ? true : false; return _retval ? true : false;
} }
NO_SANITIZE("cfi-icall")
cef_state_t CefWindowDelegateCToCpp::AcceptsFirstMouse(
CefRefPtr<CefWindow> window) {
shutdown_checker::AssertNotShutdown();
cef_window_delegate_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, accepts_first_mouse)) {
return STATE_DEFAULT;
}
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: window; type: refptr_diff
DCHECK(window.get());
if (!window.get()) {
return STATE_DEFAULT;
}
// Execute
cef_state_t _retval =
_struct->accepts_first_mouse(_struct, CefWindowCppToC::Wrap(window));
// Return type: simple
return _retval;
}
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
bool CefWindowDelegateCToCpp::CanResize(CefRefPtr<CefWindow> window) { bool CefWindowDelegateCToCpp::CanResize(CefRefPtr<CefWindow> window) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=a67a7b010e34bdda6ad0ecdf8da9bd6402689a6b$ // $hash=c829c66e21b16f72c4af8421de518eaa89b5e8eb$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_
@ -56,6 +56,7 @@ class CefWindowDelegateCToCpp
bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) override; bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) override;
bool GetTitlebarHeight(CefRefPtr<CefWindow> window, bool GetTitlebarHeight(CefRefPtr<CefWindow> window,
float* titlebar_height) override; float* titlebar_height) override;
cef_state_t AcceptsFirstMouse(CefRefPtr<CefWindow> window) override;
bool CanResize(CefRefPtr<CefWindow> window) override; bool CanResize(CefRefPtr<CefWindow> window) override;
bool CanMaximize(CefRefPtr<CefWindow> window) override; bool CanMaximize(CefRefPtr<CefWindow> window) override;
bool CanMinimize(CefRefPtr<CefWindow> window) override; bool CanMinimize(CefRefPtr<CefWindow> window) override;

View File

@ -752,5 +752,10 @@ patches = [
# https://github.com/chromiumembedded/cef/issues/3610 # https://github.com/chromiumembedded/cef/issues/3610
# https://issues.chromium.org/issues/40280130#comment7 # https://issues.chromium.org/issues/40280130#comment7
'name': 'linux_gtk_theme_3610' 'name': 'linux_gtk_theme_3610'
},
{
# views: mac: Add customization point to acceptsFirstMouse.
# https://github.com/chromiumembedded/cef/issues/3680
'name': 'mac_render_widget_3680'
} }
] ]

View File

@ -0,0 +1,33 @@
diff --git content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
index 5649f120ccefa..c6c1a676a24cf 100644
--- content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
+++ content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -164,6 +164,13 @@ void ExtractUnderlines(NSAttributedString* string,
// RenderWidgetHostViewCocoa ---------------------------------------------------
+@interface NSWindow (CefCustomMethods)
+- (int)acceptsFirstMouse;
+@end
+
+constexpr int kStateEnabled = 1;
+constexpr int kStateDisabled = 2;
+
// Private methods:
@interface RenderWidgetHostViewCocoa ()
@@ -744,6 +751,14 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
+ if ([self.window respondsToSelector:@selector(acceptsFirstMouse)]) {
+ const auto mode = [self.window acceptsFirstMouse];
+ if (mode == kStateEnabled) {
+ return YES;
+ } else if (mode == kStateDisabled) {
+ return NO;
+ }
+ }
return [self acceptsMouseEventsWhenInactive];
}

View File

@ -905,6 +905,13 @@ bool ViewsWindow::GetTitlebarHeight(CefRefPtr<CefWindow> window,
return false; return false;
} }
cef_state_t ViewsWindow::AcceptsFirstMouse(CefRefPtr<CefWindow> window) {
if (accepts_first_mouse_) {
return STATE_ENABLED;
}
return STATE_DEFAULT;
}
bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) { bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD(); CEF_REQUIRE_UI_THREAD();
// Only allow resize of normal and DevTools windows. // Only allow resize of normal and DevTools windows.
@ -1110,6 +1117,7 @@ ViewsWindow::ViewsWindow(WindowType type,
const bool hide_toolbar = hide_overlays && !with_controls_; const bool hide_toolbar = hide_overlays && !with_controls_;
const bool show_window_buttons = const bool show_window_buttons =
command_line->HasSwitch(switches::kShowWindowButtons); command_line->HasSwitch(switches::kShowWindowButtons);
accepts_first_mouse_ = command_line->HasSwitch(switches::kAcceptsFirstMouse);
// Without a window frame. // Without a window frame.
frameless_ = hide_frame || type_ == WindowType::EXTENSION; frameless_ = hide_frame || type_ == WindowType::EXTENSION;

View File

@ -184,6 +184,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) override; bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) override;
bool GetTitlebarHeight(CefRefPtr<CefWindow> window, bool GetTitlebarHeight(CefRefPtr<CefWindow> window,
float* titlebar_height) override; float* titlebar_height) override;
cef_state_t AcceptsFirstMouse(CefRefPtr<CefWindow> window) override;
bool CanResize(CefRefPtr<CefWindow> window) override; bool CanResize(CefRefPtr<CefWindow> window) override;
bool CanMaximize(CefRefPtr<CefWindow> window) override; bool CanMaximize(CefRefPtr<CefWindow> window) override;
bool CanMinimize(CefRefPtr<CefWindow> window) override; bool CanMinimize(CefRefPtr<CefWindow> window) override;
@ -268,6 +269,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
bool use_window_modal_dialog_; bool use_window_modal_dialog_;
bool use_bottom_controls_; bool use_bottom_controls_;
bool hide_pip_frame_; bool hide_pip_frame_;
bool accepts_first_mouse_;
CefRefPtr<CefWindow> window_; CefRefPtr<CefWindow> window_;
CefRefPtr<CefMenuModel> button_menu_model_; CefRefPtr<CefMenuModel> button_menu_model_;

View File

@ -57,5 +57,6 @@ const char kUseBottomControls[] = "use-bottom-controls";
const char kHidePipFrame[] = "hide-pip-frame"; const char kHidePipFrame[] = "hide-pip-frame";
const char kHideChromeBubbles[] = "hide-chrome-bubbles"; const char kHideChromeBubbles[] = "hide-chrome-bubbles";
const char kHideWindowOnClose[] = "hide-window-on-close"; const char kHideWindowOnClose[] = "hide-window-on-close";
const char kAcceptsFirstMouse[] = "accepts-first-mouse";
} // namespace client::switches } // namespace client::switches

View File

@ -51,6 +51,7 @@ extern const char kUseBottomControls[];
extern const char kHidePipFrame[]; extern const char kHidePipFrame[];
extern const char kHideChromeBubbles[]; extern const char kHideChromeBubbles[];
extern const char kHideWindowOnClose[]; extern const char kHideWindowOnClose[];
extern const char kAcceptsFirstMouse[];
} // namespace client::switches } // namespace client::switches