Extract DontShowPopupMenus and expose via content API
This allows Headless to explicitly tell content what it's trying to do rather than patch out the platform underneath content, which frees content to do reimplementation of popup menus. Bug: 389067059 Change-Id: If9996c55f5c5313f1abe54731c08c8585a04a3f5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6187262 Reviewed-by: Leonard Grey <lgrey@chromium.org> Commit-Queue: Avi Drissman <avi@chromium.org> Reviewed-by: Dmitry Gozman <dgozman@chromium.org> Cr-Commit-Position: refs/heads/main@{#1409664}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
476fef20ed
commit
5984e7ea2a
content
browser
renderer_host
public
browser
web_test
headless/lib/browser
@ -56,9 +56,6 @@ class PopupMenuHelper : public RenderWidgetHostObserver,
|
||||
void OnMenuItemSelected(int idx) override;
|
||||
void OnMenuCanceled() override;
|
||||
|
||||
// Immediately return from ShowPopupMenu.
|
||||
CONTENT_EXPORT static void DontShowPopupMenuForTesting();
|
||||
|
||||
private:
|
||||
// RenderWidgetHostObserver implementation:
|
||||
void RenderWidgetHostVisibilityChanged(RenderWidgetHost* widget_host,
|
||||
|
@ -8,12 +8,13 @@
|
||||
#include "content/browser/renderer_host/render_view_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_ios.h"
|
||||
#include "content/browser/renderer_host/web_menu_runner_ios.h"
|
||||
#include "content/common/content_export.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
namespace {
|
||||
|
||||
bool g_allow_showing_popup_menus_on_ios = true;
|
||||
bool g_allow_showing_popup_menus = true;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -44,7 +45,7 @@ void PopupMenuHelper::ShowPopupMenu(
|
||||
std::vector<blink::mojom::MenuItemPtr> items,
|
||||
bool right_aligned,
|
||||
bool allow_multiple_selection) {
|
||||
if (!g_allow_showing_popup_menus_on_ios) {
|
||||
if (!g_allow_showing_popup_menus) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -92,9 +93,9 @@ void PopupMenuHelper::RenderWidgetHostDestroyed(RenderWidgetHost* widget_host) {
|
||||
observation_.Reset();
|
||||
}
|
||||
|
||||
// static
|
||||
void PopupMenuHelper::DontShowPopupMenuForTesting() {
|
||||
g_allow_showing_popup_menus_on_ios = false;
|
||||
// As declared in //content/public/browser/popup_menu.h.
|
||||
CONTENT_EXPORT void DontShowPopupMenus() {
|
||||
g_allow_showing_popup_menus = false;
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
|
@ -56,9 +56,6 @@ class PopupMenuHelper : public RenderWidgetHostObserver {
|
||||
bool right_aligned,
|
||||
bool allow_multiple_selection);
|
||||
|
||||
// Immediately return from ShowPopupMenu.
|
||||
CONTENT_EXPORT static void DontShowPopupMenuForTesting();
|
||||
|
||||
private:
|
||||
// RenderWidgetHostObserver implementation:
|
||||
void RenderWidgetHostVisibilityChanged(RenderWidgetHost* widget_host,
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "content/browser/renderer_host/render_frame_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_view_host_impl.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#import "ui/base/cocoa/base_view.h"
|
||||
|
||||
@ -93,11 +94,6 @@ void PopupMenuHelper::Hide() {
|
||||
popup_client_.reset();
|
||||
}
|
||||
|
||||
// static
|
||||
void PopupMenuHelper::DontShowPopupMenuForTesting() {
|
||||
g_allow_showing_popup_menus = false;
|
||||
}
|
||||
|
||||
RenderWidgetHostViewMac* PopupMenuHelper::GetRenderWidgetHostView() const {
|
||||
return static_cast<RenderWidgetHostViewMac*>(
|
||||
render_frame_host_->GetOutermostMainFrameOrEmbedder()->GetView());
|
||||
@ -130,4 +126,9 @@ void PopupMenuHelper::PopupMenuClosed(std::optional<uint32_t> selected_item) {
|
||||
delegate_->OnMenuClosed(); // May delete |this|.
|
||||
}
|
||||
|
||||
// As declared in //content/public/browser/popup_menu.h.
|
||||
CONTENT_EXPORT void DontShowPopupMenus() {
|
||||
g_allow_showing_popup_menus = false;
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
|
@ -325,6 +325,7 @@ source_set("browser_sources") {
|
||||
"picture_in_picture_window_controller.h",
|
||||
"platform_notification_context.h",
|
||||
"platform_notification_service.h",
|
||||
"popup_menu.h",
|
||||
"prefetch_metrics.h",
|
||||
"prefetch_request_status_listener.h",
|
||||
"prefetch_service_delegate.cc",
|
||||
|
25
content/public/browser/popup_menu.h
Normal file
25
content/public/browser/popup_menu.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CONTENT_PUBLIC_BROWSER_POPUP_MENU_H_
|
||||
#define CONTENT_PUBLIC_BROWSER_POPUP_MENU_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "content/common/content_export.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
#if BUILDFLAG(IS_APPLE)
|
||||
|
||||
// On the Mac/Blink iOS, the menus shown by <select> HTML elements are native
|
||||
// menus. This call allows the embedder to turn off those menus entirely, so
|
||||
// that attempting to invoke them will return immediately. This is a one-way
|
||||
// switch and is irrevocable.
|
||||
CONTENT_EXPORT void DontShowPopupMenus();
|
||||
|
||||
#endif // BUILDFLAG(IS_APPLE)
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_PUBLIC_BROWSER_POPUP_MENU_H_
|
@ -7,14 +7,12 @@
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#include "content/browser/sandbox_parameters_mac.h"
|
||||
#include "content/public/browser/popup_menu.h"
|
||||
#include "net/test/test_data_directory.h"
|
||||
|
||||
// This file is also used in iOS, so we skip including AppKit.h in the iOS port.
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include <AppKit/AppKit.h>
|
||||
#include "content/browser/renderer_host/popup_menu_helper_mac.h"
|
||||
#elif BUILDFLAG(IS_IOS)
|
||||
#include "content/browser/renderer_host/popup_menu_helper_ios.h"
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
@ -38,7 +36,7 @@ void SetDefaultsToWebTestValues() {
|
||||
forKey:@"AppleHighlightColor"];
|
||||
[defaults setObject:@"0.500000 0.500000 0.500000"
|
||||
forKey:@"AppleOtherHighlightColor"];
|
||||
[defaults setObject:[NSArray arrayWithObject:@"en"] forKey:@"AppleLanguages"];
|
||||
[defaults setObject:@[ @"en" ] forKey:@"AppleLanguages"];
|
||||
[defaults setBool:NO forKey:@"NSScrollAnimationEnabled"];
|
||||
[defaults setObject:@"Always" forKey:@"AppleShowScrollBars"];
|
||||
|
||||
@ -52,7 +50,7 @@ void SetDefaultsToWebTestValues() {
|
||||
void WebTestBrowserPlatformInitialize() {
|
||||
SetDefaultsToWebTestValues();
|
||||
|
||||
PopupMenuHelper::DontShowPopupMenuForTesting();
|
||||
DontShowPopupMenus();
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
// Expand the network service sandbox to allow reading the test TLS
|
||||
|
@ -4,11 +4,10 @@
|
||||
|
||||
#include "headless/lib/browser/headless_browser_impl.h"
|
||||
|
||||
#import "base/apple/scoped_objc_class_swizzler.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/popup_menu.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "headless/lib/browser/headless_screen.h"
|
||||
@ -18,49 +17,10 @@
|
||||
#include "ui/display/screen.h"
|
||||
#import "ui/gfx/mac/coordinate_conversion.h"
|
||||
|
||||
// Overrides events and actions for NSPopUpButtonCell.
|
||||
@interface FakeNSPopUpButtonCell : NSObject
|
||||
@end
|
||||
|
||||
@implementation FakeNSPopUpButtonCell
|
||||
|
||||
- (void)performClickWithFrame:(NSRect)frame inView:(NSView*)view {
|
||||
}
|
||||
|
||||
- (void)attachPopUpWithFrame:(NSRect)frame inView:(NSView*)view {
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace headless {
|
||||
|
||||
namespace {
|
||||
|
||||
// Swizzles all event and actions for NSPopUpButtonCell to avoid showing in
|
||||
// headless mode.
|
||||
class HeadlessPopUpMethods {
|
||||
public:
|
||||
HeadlessPopUpMethods(const HeadlessPopUpMethods&) = delete;
|
||||
HeadlessPopUpMethods& operator=(const HeadlessPopUpMethods&) = delete;
|
||||
|
||||
static void Init() {
|
||||
[[maybe_unused]] static base::NoDestructor<HeadlessPopUpMethods> swizzler;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class base::NoDestructor<HeadlessPopUpMethods>;
|
||||
HeadlessPopUpMethods()
|
||||
: popup_perform_click_swizzler_([NSPopUpButtonCell class],
|
||||
[FakeNSPopUpButtonCell class],
|
||||
@selector(performClickWithFrame:inView:)),
|
||||
popup_attach_swizzler_([NSPopUpButtonCell class],
|
||||
[FakeNSPopUpButtonCell class],
|
||||
@selector(attachPopUpWithFrame:inView:)) {}
|
||||
|
||||
base::apple::ScopedObjCClassSwizzler popup_perform_click_swizzler_;
|
||||
base::apple::ScopedObjCClassSwizzler popup_attach_swizzler_;
|
||||
};
|
||||
|
||||
NSString* const kActivityReason = @"Batch headless process";
|
||||
const NSActivityOptions kActivityOptions =
|
||||
(NSActivityUserInitiatedAllowingIdleSystemSleep |
|
||||
@ -81,7 +41,7 @@ void HeadlessBrowserImpl::PlatformInitialize() {
|
||||
options()->screen_info_spec);
|
||||
display::Screen::SetScreenInstance(screen);
|
||||
|
||||
HeadlessPopUpMethods::Init();
|
||||
content::DontShowPopupMenus();
|
||||
}
|
||||
|
||||
void HeadlessBrowserImpl::PlatformStart() {
|
||||
|
Reference in New Issue
Block a user