Compare commits

..

18 Commits
5005 ... 4951

Author SHA1 Message Date
Marshall Greenblatt
367b4a0f3f alloy: Disable ProxyErrorClient callbacks when extensions are disabled (fixes issue #2830) 2022-05-13 12:09:30 +03:00
Marshall Greenblatt
98411f72b3 Update to Chromium version 101.0.4951.67 2022-05-13 07:41:25 +00:00
Marshall Greenblatt
31bd2406f3 Update to Chromium version 101.0.4951.64 2022-05-12 07:35:44 +00:00
Marshall Greenblatt
ca159c57bd Update to Chromium version 101.0.4951.54 2022-05-02 23:02:43 +00:00
Marshall Greenblatt
0135887c4c Fix type conversion warning with GCC 10 (fixes issue #3324) 2022-05-02 11:58:45 -04:00
Marshall Greenblatt
485fa78362 Update to Chromium version 101.0.4951.41 2022-04-22 13:29:56 +00:00
Marshall Greenblatt
212303203b Don't override Accept-Language header if set by the client (fixes issue #3139) 2022-04-20 15:11:30 -04:00
Joshua Marler
0692cb0e80 views: Fix ConvertPointFromPixel for fractional scaling (fixes issue #3312) 2022-04-14 20:25:03 -04:00
Marshall Greenblatt
09a0606927 views: Fix crash when clicking a draggable region (fixes issue #3311) 2022-04-14 15:20:09 -04:00
Marshall Greenblatt
cc98c1d1f8 alloy: win: Fix range check for system cursors (fixes issue #3270) 2022-04-14 15:20:00 -04:00
Marshall Greenblatt
d56d7ab290 Update to Chromium version 101.0.4951.34 2022-04-14 16:00:37 +00:00
maikesiwu
1f02c709c8 Use Uint32::NewFromUnsigned for unsigned values 2022-04-13 15:48:45 -04:00
Marshall Greenblatt
e56440898e Fix unintentional state transfer in DetachToUserFree (fixes issue #3309)
Calling DetachToUserFree() on a CefString holding a reference should copy the
value instead of transferring ownership.

A new `StringTest.Ownership` test has been added for this behavior.
2022-04-13 14:55:09 -04:00
Marshall Greenblatt
c3a6788f6e Fix dismissal of select popups on NotifyMoveOrResizeStarted (see issue #3294)
This impacts both Alloy and Chrome runtimes when using a native parent window.
2022-04-12 12:19:53 -04:00
Marshall Greenblatt
93cf5b766a mac/linux: Use python3 for .sh scripts
Newer OS versions no longer ship with Python 2 by default.
2022-04-12 12:19:53 -04:00
Marshall Greenblatt
68a0a11815 Update to Chromium version 101.0.4951.26 2022-04-07 14:51:46 +00:00
Marshall Greenblatt
54dd34e19b chrome: Update expectations with same-site BFCache enabled (fixes issue #3301)
With same-site BFCache enabled every navigation can now potentially be served
via the BFCache. To support this internally a new top-level RenderFrame object
may be created for each new navigation. As a result, OnBrowserCreated may now
be called multiple times with the same browser ID in a given renderer process
(a behavior previously only seen with cross-site navigations and different
renderer processes).

BFCache navigations do not trigger the same Chromium notifications as a normal
load. To avoid breaking CEF API usage expectations we now synthetically
generate the load-related callbacks that would otherwise be missing
(OnLoadingStateChange with isLoading=true, OnLoadStart, OnLoadEnd). The
|httpStatusCode| argument to OnLoadEnd will be 0 in this case.

To test:
- Run `FrameHandlerTest.*:MessageRouterTest.*:NavigationTest.*`
- Run `NavigationTest.LoadSameOriginLoadURL` for OnBrowserCreated behavior.
- Run `NavigationTest.History` for load-related callback behavior.
2022-04-05 15:55:07 -04:00
Marshall Greenblatt
889823e082 Update to Chromium version 101.0.4951.15 2022-03-31 19:17:05 -04:00
212 changed files with 3731 additions and 3410 deletions

354
BUILD.gn
View File

@@ -257,9 +257,6 @@ assert(enable_print_preview)
# Enable support for Widevine CDM.
assert(enable_widevine)
# Enable Views UI framework.
assert(toolkit_views)
if (is_clang) {
# Don't use the chrome style plugin.
assert(!clang_use_chrome_plugins)
@@ -414,6 +411,8 @@ static_library("libcef_static") {
"libcef/browser/alloy/alloy_browser_main.h",
"libcef/browser/alloy/alloy_content_browser_client.cc",
"libcef/browser/alloy/alloy_content_browser_client.h",
"libcef/browser/alloy/alloy_dialog_util.cc",
"libcef/browser/alloy/alloy_dialog_util.h",
"libcef/browser/alloy/alloy_download_util.cc",
"libcef/browser/alloy/alloy_download_util.h",
"libcef/browser/alloy/browser_platform_delegate_alloy.cc",
@@ -470,22 +469,6 @@ static_library("libcef_static") {
"libcef/browser/chrome_crash_reporter_client_stub.cc",
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.cc",
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.h",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_child_window.cc",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_child_window.h",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_views.cc",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h",
"libcef/browser/chrome/views/chrome_browser_frame.cc",
"libcef/browser/chrome/views/chrome_browser_frame.h",
"libcef/browser/chrome/views/chrome_browser_view.cc",
"libcef/browser/chrome/views/chrome_browser_view.h",
"libcef/browser/chrome/views/chrome_child_window.cc",
"libcef/browser/chrome/views/chrome_child_window.h",
"libcef/browser/chrome/views/chrome_views_util.cc",
"libcef/browser/chrome/views/chrome_views_util.h",
"libcef/browser/chrome/views/toolbar_view_impl.cc",
"libcef/browser/chrome/views/toolbar_view_impl.h",
"libcef/browser/chrome/views/toolbar_view_view.cc",
"libcef/browser/chrome/views/toolbar_view_view.h",
"libcef/browser/context.cc",
"libcef/browser/context.h",
"libcef/browser/context_menu_params_impl.cc",
@@ -548,10 +531,9 @@ static_library("libcef_static") {
"libcef/browser/extensions/value_store/cef_value_store.h",
"libcef/browser/extensions/value_store/cef_value_store_factory.cc",
"libcef/browser/extensions/value_store/cef_value_store_factory.h",
"libcef/browser/file_dialog_runner.h",
"libcef/browser/file_dialog_manager.cc",
"libcef/browser/file_dialog_manager.h",
"libcef/browser/file_dialog_runner.cc",
"libcef/browser/file_dialog_runner.h",
"libcef/browser/frame_host_impl.cc",
"libcef/browser/frame_host_impl.h",
"libcef/browser/frame_service_base.h",
@@ -585,8 +567,6 @@ static_library("libcef_static") {
"libcef/browser/native/browser_platform_delegate_native.h",
"libcef/browser/native/cursor_util.h",
"libcef/browser/native/cursor_util.cc",
"libcef/browser/native/window_delegate_view.cc",
"libcef/browser/native/window_delegate_view.h",
"libcef/browser/navigation_entry_impl.cc",
"libcef/browser/navigation_entry_impl.h",
"libcef/browser/net/chrome_scheme_handler.cc",
@@ -677,63 +657,6 @@ static_library("libcef_static") {
"libcef/browser/trace_subscriber.cc",
"libcef/browser/trace_subscriber.h",
"libcef/browser/thread_util.h",
"libcef/browser/views/basic_label_button_impl.cc",
"libcef/browser/views/basic_label_button_impl.h",
"libcef/browser/views/basic_label_button_view.cc",
"libcef/browser/views/basic_label_button_view.h",
"libcef/browser/views/basic_panel_impl.cc",
"libcef/browser/views/basic_panel_impl.h",
"libcef/browser/views/basic_panel_view.cc",
"libcef/browser/views/basic_panel_view.h",
"libcef/browser/views/box_layout_impl.cc",
"libcef/browser/views/box_layout_impl.h",
"libcef/browser/views/browser_platform_delegate_views.cc",
"libcef/browser/views/browser_platform_delegate_views.h",
"libcef/browser/views/browser_view_impl.cc",
"libcef/browser/views/browser_view_impl.h",
"libcef/browser/views/browser_view_view.cc",
"libcef/browser/views/browser_view_view.h",
"libcef/browser/views/button_impl.h",
"libcef/browser/views/button_view.h",
"libcef/browser/views/display_impl.cc",
"libcef/browser/views/display_impl.h",
"libcef/browser/views/fill_layout_impl.cc",
"libcef/browser/views/fill_layout_impl.h",
"libcef/browser/views/label_button_impl.h",
"libcef/browser/views/label_button_view.h",
"libcef/browser/views/layout_impl.h",
"libcef/browser/views/layout_adapter.cc",
"libcef/browser/views/layout_adapter.h",
"libcef/browser/views/layout_util.cc",
"libcef/browser/views/layout_util.h",
"libcef/browser/views/menu_button_impl.cc",
"libcef/browser/views/menu_button_impl.h",
"libcef/browser/views/menu_button_view.cc",
"libcef/browser/views/menu_button_view.h",
"libcef/browser/views/menu_runner_views.cc",
"libcef/browser/views/menu_runner_views.h",
"libcef/browser/views/overlay_view_host.cc",
"libcef/browser/views/overlay_view_host.h",
"libcef/browser/views/panel_impl.h",
"libcef/browser/views/panel_view.h",
"libcef/browser/views/scroll_view_impl.cc",
"libcef/browser/views/scroll_view_impl.h",
"libcef/browser/views/scroll_view_view.cc",
"libcef/browser/views/scroll_view_view.h",
"libcef/browser/views/textfield_impl.cc",
"libcef/browser/views/textfield_impl.h",
"libcef/browser/views/textfield_view.cc",
"libcef/browser/views/textfield_view.h",
"libcef/browser/views/view_adapter.cc",
"libcef/browser/views/view_adapter.h",
"libcef/browser/views/view_impl.h",
"libcef/browser/views/view_util.cc",
"libcef/browser/views/view_util.h",
"libcef/browser/views/view_view.h",
"libcef/browser/views/window_impl.cc",
"libcef/browser/views/window_impl.h",
"libcef/browser/views/window_view.cc",
"libcef/browser/views/window_view.h",
"libcef/browser/web_contents_dialog_helper.cc",
"libcef/browser/web_contents_dialog_helper.h",
"libcef/browser/x509_certificate_impl.cc",
@@ -873,14 +796,6 @@ static_library("libcef_static") {
# For Chrome runtime support.
"//chrome/app/chrome_main_delegate.cc",
"//chrome/app/chrome_main_delegate.h",
# Part of //ui/views:test_support which is testingonly.
"//ui/views/test/desktop_test_views_delegate.h",
"//ui/views/test/test_views_delegate.h",
# Support for UI input events.
# Part of //ui/base:test_support which is testingonly.
"//ui/base/test/ui_controls.h",
]
configs += [
@@ -997,7 +912,6 @@ static_library("libcef_static") {
"//third_party/zlib:minizip",
"//ui/base",
"//ui/base/ime",
"//ui/events",
"//ui/events:events_base",
"//ui/gfx",
"//ui/gfx/geometry",
@@ -1005,9 +919,6 @@ static_library("libcef_static") {
"//ui/gfx/ipc/geometry",
"//ui/gfx/ipc/skia",
"//ui/gl",
"//ui/strings",
"//ui/views",
"//ui/views/controls/webview",
"//url",
"//v8",
]
@@ -1018,6 +929,8 @@ static_library("libcef_static") {
"libcef/browser/native/browser_platform_delegate_native_win.cc",
"libcef/browser/native/browser_platform_delegate_native_win.h",
"libcef/browser/native/cursor_util_win.cc",
"libcef/browser/native/file_dialog_runner_win.cc",
"libcef/browser/native/file_dialog_runner_win.h",
"libcef/browser/native/javascript_dialog_runner_win.cc",
"libcef/browser/native/javascript_dialog_runner_win.h",
"libcef/browser/native/menu_2.cc",
@@ -1089,29 +1002,20 @@ static_library("libcef_static") {
sources += includes_mac + [
"libcef/browser/native/browser_platform_delegate_native_mac.h",
"libcef/browser/native/browser_platform_delegate_native_mac.mm",
"libcef/browser/native/file_dialog_runner_mac.h",
"libcef/browser/native/file_dialog_runner_mac.mm",
"libcef/browser/native/javascript_dialog_runner_mac.h",
"libcef/browser/native/javascript_dialog_runner_mac.mm",
"libcef/browser/native/menu_runner_mac.h",
"libcef/browser/native/menu_runner_mac.mm",
"libcef/browser/osr/browser_platform_delegate_osr_mac.h",
"libcef/browser/osr/browser_platform_delegate_osr_mac.mm",
"libcef/browser/views/view_util_mac.mm",
"libcef/common/util_mac.h",
"libcef/common/util_mac.mm",
# For Chrome runtime support.
"//chrome/app/chrome_main_mac.h",
"//chrome/app/chrome_main_mac.mm",
# Part of //ui/views:test_support which is testingonly.
"//ui/views/test/desktop_test_views_delegate_mac.mm",
"//ui/views/test/test_views_delegate_mac.mm",
# Support for UI input events.
# Part of //ui/base:test_support which is testingonly.
"//ui/base/test/ui_controls_mac.mm",
# Part of //ui//events:test_support which is testingonly.
"//ui/events/test/cocoa_test_event_utils.mm",
]
}
@@ -1123,92 +1027,204 @@ static_library("libcef_static") {
deps += [ "//tools/v8_context_snapshot" ]
}
if (use_aura) {
if (toolkit_views) {
sources += [
"libcef/browser/native/browser_platform_delegate_native_aura.cc",
"libcef/browser/native/browser_platform_delegate_native_aura.h",
"libcef/browser/views/view_util_aura.cc",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_views.cc",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h",
"libcef/browser/chrome/views/chrome_browser_frame.cc",
"libcef/browser/chrome/views/chrome_browser_frame.h",
"libcef/browser/chrome/views/chrome_browser_view.cc",
"libcef/browser/chrome/views/chrome_browser_view.h",
"libcef/browser/chrome/views/chrome_views_util.cc",
"libcef/browser/chrome/views/chrome_views_util.h",
"libcef/browser/chrome/views/toolbar_view_impl.cc",
"libcef/browser/chrome/views/toolbar_view_impl.h",
"libcef/browser/chrome/views/toolbar_view_view.cc",
"libcef/browser/chrome/views/toolbar_view_view.h",
"libcef/browser/native/window_delegate_view.cc",
"libcef/browser/native/window_delegate_view.h",
"libcef/browser/views/basic_label_button_impl.cc",
"libcef/browser/views/basic_label_button_impl.h",
"libcef/browser/views/basic_label_button_view.cc",
"libcef/browser/views/basic_label_button_view.h",
"libcef/browser/views/basic_panel_impl.cc",
"libcef/browser/views/basic_panel_impl.h",
"libcef/browser/views/basic_panel_view.cc",
"libcef/browser/views/basic_panel_view.h",
"libcef/browser/views/box_layout_impl.cc",
"libcef/browser/views/box_layout_impl.h",
"libcef/browser/views/browser_platform_delegate_views.cc",
"libcef/browser/views/browser_platform_delegate_views.h",
"libcef/browser/views/browser_view_impl.cc",
"libcef/browser/views/browser_view_impl.h",
"libcef/browser/views/browser_view_view.cc",
"libcef/browser/views/browser_view_view.h",
"libcef/browser/views/button_impl.h",
"libcef/browser/views/button_view.h",
"libcef/browser/views/display_impl.cc",
"libcef/browser/views/display_impl.h",
"libcef/browser/views/fill_layout_impl.cc",
"libcef/browser/views/fill_layout_impl.h",
"libcef/browser/views/label_button_impl.h",
"libcef/browser/views/label_button_view.h",
"libcef/browser/views/layout_impl.h",
"libcef/browser/views/layout_adapter.cc",
"libcef/browser/views/layout_adapter.h",
"libcef/browser/views/layout_util.cc",
"libcef/browser/views/layout_util.h",
"libcef/browser/views/menu_button_impl.cc",
"libcef/browser/views/menu_button_impl.h",
"libcef/browser/views/menu_button_view.cc",
"libcef/browser/views/menu_button_view.h",
"libcef/browser/views/menu_runner_views.cc",
"libcef/browser/views/menu_runner_views.h",
"libcef/browser/views/overlay_view_host.cc",
"libcef/browser/views/overlay_view_host.h",
"libcef/browser/views/panel_impl.h",
"libcef/browser/views/panel_view.h",
"libcef/browser/views/scroll_view_impl.cc",
"libcef/browser/views/scroll_view_impl.h",
"libcef/browser/views/scroll_view_view.cc",
"libcef/browser/views/scroll_view_view.h",
"libcef/browser/views/textfield_impl.cc",
"libcef/browser/views/textfield_impl.h",
"libcef/browser/views/textfield_view.cc",
"libcef/browser/views/textfield_view.h",
"libcef/browser/views/view_adapter.cc",
"libcef/browser/views/view_adapter.h",
"libcef/browser/views/view_impl.h",
"libcef/browser/views/view_util.cc",
"libcef/browser/views/view_util.h",
"libcef/browser/views/view_view.h",
"libcef/browser/views/window_impl.cc",
"libcef/browser/views/window_impl.h",
"libcef/browser/views/window_view.cc",
"libcef/browser/views/window_view.h",
# Part of //ui/views:test_support which is testingonly.
"//ui/views/test/desktop_test_views_delegate_aura.cc",
"//ui/views/test/test_views_delegate_aura.cc",
"//ui/views/test/desktop_test_views_delegate.h",
"//ui/views/test/test_views_delegate.h",
# Support for UI input events.
# Part of //ui/base:test_support which is testingonly.
"//ui/base/test/ui_controls_aura.cc",
"//ui/aura/test/ui_controls_factory_aura.h",
"//ui/base/test/ui_controls.h",
]
deps += [
"//ui/aura",
"//ui/wm",
"//ui/wm/public",
"//ui/events",
"//ui/strings",
"//ui/views",
"//ui/views/controls/webview",
]
if (is_win) {
if (use_aura) {
sources += [
# Support for UI input events.
# Part of //base/test:test_config which is testingonly.
"//base/test/test_switches.cc",
"//base/test/test_switches.h",
"//base/test/test_timeouts.cc",
"//base/test/test_timeouts.h",
# Part of //ui/aura:test_support which is testingonly.
"//ui/aura/test/ui_controls_factory_aurawin.cc",
# Part of //ui/base:test_support which is testingonly.
"//ui/base/test/ui_controls_internal_win.cc",
"//ui/base/test/ui_controls_internal_win.h",
]
}
"libcef/browser/native/browser_platform_delegate_native_aura.cc",
"libcef/browser/native/browser_platform_delegate_native_aura.h",
"libcef/browser/views/view_util_aura.cc",
if (is_linux) {
sources += [
# Support for UI input events.
# Part of //ui/aura:test_support which is testingonly.
"//ui/aura/test/aura_test_utils.cc",
"//ui/aura/test/aura_test_utils.h",
# Part of //ui/events:test_support which is testingonly.
"//ui/events/test/x11_event_waiter.cc",
"//ui/events/test/x11_event_waiter.h",
# Part of //ui/ozone::ui_test_support which is testingonly.
"//ui/ozone/common/test/stub_ozone_ui_controls_test_helper.cc",
"//ui/ozone/common/test/stub_ozone_ui_controls_test_helper.h",
"//ui/ozone/public/ozone_ui_controls_test_helper.cc",
"//ui/ozone/public/ozone_ui_controls_test_helper.h",
"$root_gen_dir/ui/ozone/test_constructor_list.cc",
# Part of //ui/views:test_support which is testingonly.
"//ui/views/test/test_desktop_screen_ozone.cc",
"//ui/views/test/test_desktop_screen_ozone.h",
"//ui/views/test/ui_controls_factory_desktop_aura_ozone.cc",
"//ui/views/test/ui_controls_factory_desktop_aura_ozone.h",
"//ui/views/test/desktop_test_views_delegate_aura.cc",
"//ui/views/test/test_views_delegate_aura.cc",
# Support for UI input events.
# Part of //ui/base:test_support which is testingonly.
"//ui/base/test/ui_controls_aura.cc",
"//ui/aura/test/ui_controls_factory_aura.h",
]
deps += [
"//ui/ozone:generate_test_support_constructor_list",
"//ui/aura",
"//ui/wm",
"//ui/wm/public",
]
if (ozone_platform_x11) {
if (is_win) {
sources += [
# Support for UI input events.
# Part of //ui/base/x:test_support which is testingonly.
"//ui/base/x/test/x11_ui_controls_test_helper.cc",
"//ui/base/x/test/x11_ui_controls_test_helper.h",
# Part of //base/test:test_config which is testingonly.
"//base/test/test_switches.cc",
"//base/test/test_switches.h",
"//base/test/test_timeouts.cc",
"//base/test/test_timeouts.h",
# Part of //ui/aura:test_support which is testingonly.
"//ui/aura/test/x11_event_sender.h",
# Part of //ui/ozone/platform/x11:test_support which is testingonly.
"//ui/ozone/platform/x11/x11_ozone_ui_controls_test_helper.cc",
"//ui/ozone/platform/x11/x11_ozone_ui_controls_test_helper.h",
]
} else {
sources += [
# Support for UI input events.
"//ui/aura/test/ui_controls_factory_aurawin.cc",
# Part of //ui/base:test_support which is testingonly.
"//ui/aura/test/ui_controls_factory_ozone.cc",
# Part of //ui//events:test_support which is testingonly.
"//ui/events/test/events_test_utils.cc"
"//ui/base/test/ui_controls_internal_win.cc",
"//ui/base/test/ui_controls_internal_win.h",
]
}
if (is_linux) {
sources += [
# Support for UI input events.
# Part of //ui/aura:test_support which is testingonly.
"//ui/aura/test/aura_test_utils.cc",
"//ui/aura/test/aura_test_utils.h",
# Part of //ui/events:test_support which is testingonly.
"//ui/events/test/x11_event_waiter.cc",
"//ui/events/test/x11_event_waiter.h",
# Part of //ui/ozone::ui_test_support which is testingonly.
"//ui/ozone/common/test/stub_ozone_ui_controls_test_helper.cc",
"//ui/ozone/common/test/stub_ozone_ui_controls_test_helper.h",
"//ui/ozone/public/ozone_ui_controls_test_helper.cc",
"//ui/ozone/public/ozone_ui_controls_test_helper.h",
"$root_gen_dir/ui/ozone/test_constructor_list.cc",
# Part of //ui/views:test_support which is testingonly.
"//ui/views/test/test_desktop_screen_ozone.cc",
"//ui/views/test/test_desktop_screen_ozone.h",
"//ui/views/test/ui_controls_factory_desktop_aura_ozone.cc",
"//ui/views/test/ui_controls_factory_desktop_aura_ozone.h",
]
deps += [
"//ui/ozone:generate_test_support_constructor_list",
]
if (ozone_platform_x11) {
sources += [
# Support for UI input events.
# Part of //ui/base/x:test_support which is testingonly.
"//ui/base/x/test/x11_ui_controls_test_helper.cc",
"//ui/base/x/test/x11_ui_controls_test_helper.h",
# Part of //ui/aura:test_support which is testingonly.
"//ui/aura/test/x11_event_sender.h",
# Part of //ui/ozone/platform/x11:test_support which is testingonly.
"//ui/ozone/platform/x11/x11_ozone_ui_controls_test_helper.cc",
"//ui/ozone/platform/x11/x11_ozone_ui_controls_test_helper.h",
]
} else {
sources += [
# Support for UI input events.
# Part of //ui/base:test_support which is testingonly.
"//ui/aura/test/ui_controls_factory_ozone.cc",
# Part of //ui//events:test_support which is testingonly.
"//ui/events/test/events_test_utils.cc"
]
}
}
}
if (is_mac) {
sources += [
"libcef/browser/views/view_util_mac.mm",
# Part of //ui/views:test_support which is testingonly.
"//ui/views/test/desktop_test_views_delegate_mac.mm",
"//ui/views/test/test_views_delegate_mac.mm",
# Support for UI input events.
# Part of //ui/base:test_support which is testingonly.
"//ui/base/test/ui_controls_mac.mm",
# Part of //ui//events:test_support which is testingonly.
"//ui/events/test/cocoa_test_event_utils.mm",
]
}
} else {
sources += [
# Provides stub implementations for the views static methods.
"libcef_dll/views_stub.cc",
]
}
}
@@ -1366,7 +1382,7 @@ make_pack_header("resources") {
"$root_gen_dir/third_party/blink/public/resources/grit/blink_resources.h",
"$root_gen_dir/ui/resources/grit/ui_resources.h",
"$root_gen_dir/ui/resources/grit/webui_generated_resources.h",
"$root_gen_dir/ui/views/resources/grit/views_resources.h",
"$root_gen_dir/ui/resources/grit/webui_resources.h",
]
deps = [
@@ -1393,8 +1409,13 @@ make_pack_header("resources") {
"//third_party/blink/public:resources",
"//ui/resources:ui_resources_grd",
"//ui/resources:webui_generated_resources_grd",
"//ui/views/resources:resources_grd",
"//ui/resources:webui_resources_grd",
]
if (toolkit_views) {
inputs += [ "$root_gen_dir/ui/views/resources/grit/views_resources.h" ]
deps += [ "//ui/views/resources:resources_grd" ]
}
}
# Generate cef_pack_strings.h.
@@ -1544,6 +1565,8 @@ if (is_mac) {
# Add the SwiftShader .dylibs in the MODULE_DIR of the Framework app bundle.
bundle_data("cef_framework_swiftshader_binaries") {
sources = [
"$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib",
"$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib",
"$root_out_dir/vk_intermediates/libvk_swiftshader.dylib",
"$root_out_dir/vk_intermediates/vk_swiftshader_icd.json",
]
@@ -1551,6 +1574,7 @@ if (is_mac) {
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
public_deps = [
"//ui/gl:swiftshader_egl_library_copy",
"//ui/gl:swiftshader_vk_library_copy",
]
}

View File

@@ -7,6 +7,6 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{
'chromium_checkout': 'refs/tags/102.0.5005.115',
'depot_tools_checkout': '583ca66091'
'chromium_checkout': 'refs/tags/101.0.4951.67',
'depot_tools_checkout': '7f02c0d981'
}

View File

@@ -227,6 +227,7 @@ if(OS_LINUX)
snapshot_blob.bin
v8_context_snapshot.bin
vk_swiftshader_icd.json
swiftshader
)
# List of CEF resource files.
@@ -475,6 +476,7 @@ if(OS_WINDOWS)
vk_swiftshader.dll
vk_swiftshader_icd.json
vulkan-1.dll
swiftshader
)
if(NOT PROJECT_ARCH STREQUAL "arm64")

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=b1c1e44e6d3842064ef6e5b9823173f7ec1fcccc$
// $hash=b80e84c0039ab45d5c4562d64b67a84766c0dab3$
//
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
@@ -205,12 +205,15 @@ typedef struct _cef_run_file_dialog_callback_t {
cef_base_ref_counted_t base;
///
// Called asynchronously after the file dialog is dismissed. |file_paths| will
// be a single value or a list of values depending on the dialog mode. If the
// selection was cancelled |file_paths| will be NULL.
// Called asynchronously after the file dialog is dismissed.
// |selected_accept_filter| is the 0-based index of the value selected from
// the accept filters array passed to cef_browser_host_t::RunFileDialog.
// |file_paths| will be a single value or a list of values depending on the
// dialog mode. If the selection was cancelled |file_paths| will be NULL.
///
void(CEF_CALLBACK* on_file_dialog_dismissed)(
struct _cef_run_file_dialog_callback_t* self,
int selected_accept_filter,
cef_string_list_t file_paths);
} cef_run_file_dialog_callback_t;
@@ -388,10 +391,11 @@ typedef struct _cef_browser_host_t {
// selectable file types and may any combination of (a) valid lower-cased MIME
// types (e.g. "text/*" or "image/*"), (b) individual file extensions (e.g.
// ".txt" or ".png"), or (c) combined description and file extension delimited
// using "|" and ";" (e.g. "Image Types|.png;.gif;.jpg"). |callback| will be
// executed after the dialog is dismissed or immediately if another dialog is
// already pending. The dialog will be initiated asynchronously on the UI
// thread.
// using "|" and ";" (e.g. "Image Types|.png;.gif;.jpg").
// |selected_accept_filter| is the 0-based index of the filter that will be
// selected by default. |callback| will be executed after the dialog is
// dismissed or immediately if another dialog is already pending. The dialog
// will be initiated asynchronously on the UI thread.
///
void(CEF_CALLBACK* run_file_dialog)(
struct _cef_browser_host_t* self,
@@ -399,6 +403,7 @@ typedef struct _cef_browser_host_t {
const cef_string_t* title,
const cef_string_t* default_file_path,
cef_string_list_t accept_filters,
int selected_accept_filter,
struct _cef_run_file_dialog_callback_t* callback);
///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=dc579beb1f25f9bbdb72afb4b5b381e129f84e31$
// $hash=0f56154217707d141912dc8a298279df8df04311$
//
#ifndef CEF_INCLUDE_CAPI_CEF_DIALOG_HANDLER_CAPI_H_
@@ -57,11 +57,14 @@ typedef struct _cef_file_dialog_callback_t {
cef_base_ref_counted_t base;
///
// Continue the file selection. |file_paths| should be a single value or a
// list of values depending on the dialog mode. An NULL |file_paths| value is
// treated the same as calling cancel().
// Continue the file selection. |selected_accept_filter| should be the 0-based
// index of the value selected from the accept filters array passed to
// cef_dialog_handler_t::OnFileDialog. |file_paths| should be a single value
// or a list of values depending on the dialog mode. An NULL |file_paths|
// value is treated the same as calling cancel().
///
void(CEF_CALLBACK* cont)(struct _cef_file_dialog_callback_t* self,
int selected_accept_filter,
cef_string_list_t file_paths);
///
@@ -90,9 +93,10 @@ typedef struct _cef_dialog_handler_t {
// (a) valid lower-cased MIME types (e.g. "text/*" or "image/*"), (b)
// individual file extensions (e.g. ".txt" or ".png"), or (c) combined
// description and file extension delimited using "|" and ";" (e.g. "Image
// Types|.png;.gif;.jpg"). To display a custom dialog return true (1) and
// execute |callback| either inline or at a later time. To display the default
// dialog return false (0).
// Types|.png;.gif;.jpg"). |selected_accept_filter| is the 0-based index of
// the filter that should be selected by default. To display a custom dialog
// return true (1) and execute |callback| either inline or at a later time. To
// display the default dialog return false (0).
///
int(CEF_CALLBACK* on_file_dialog)(
struct _cef_dialog_handler_t* self,
@@ -101,6 +105,7 @@ typedef struct _cef_dialog_handler_t {
const cef_string_t* title,
const cef_string_t* default_file_path,
cef_string_list_t accept_filters,
int selected_accept_filter,
struct _cef_file_dialog_callback_t* callback);
} cef_dialog_handler_t;

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=7f88c6428929c0511ff90b6137efcc4cebcfeae4$
// $hash=cd5d7c4e83237ceb39c5639489ca6004d2d69f0c$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
@@ -73,14 +73,6 @@ typedef struct _cef_window_delegate_t {
void(CEF_CALLBACK* on_window_destroyed)(struct _cef_window_delegate_t* self,
struct _cef_window_t* window);
///
// Called when |window| is activated or deactivated.
///
void(CEF_CALLBACK* on_window_activation_changed)(
struct _cef_window_delegate_t* self,
struct _cef_window_t* window,
int active);
///
// Return the parent for |window| or NULL if the |window| does not have a
// parent. Windows with parents will not get a taskbar button. Set |is_menu|

View File

@@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "b6255e15aa977a7214cf28e4e1a2372b454838d4"
#define CEF_API_HASH_UNIVERSAL "34a42688778747c68f31e0194fea8323bc5388dc"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "b262c3a2cbd2632de1bfed887da8b8114c9ecbf5"
#define CEF_API_HASH_PLATFORM "c78306ad4768dc6c4ca1c376fa4c3799db8fd0eb"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "fd6d3d83442fe31ad26d5648755e0cf2e14a7fc7"
#define CEF_API_HASH_PLATFORM "c25d8bb5b7118a8f50c84e8a2746b2a14d7193ef"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "d686964de5e01eed900d78d5f8a7da9f8fc3a777"
#define CEF_API_HASH_PLATFORM "742fc8a47e757e34a87c7c814fc884591d5e9f98"
#endif
#ifdef __cplusplus

View File

@@ -206,11 +206,14 @@ class CefRunFileDialogCallback : public virtual CefBaseRefCounted {
public:
///
// Called asynchronously after the file dialog is dismissed.
// |selected_accept_filter| is the 0-based index of the value selected from
// the accept filters array passed to CefBrowserHost::RunFileDialog.
// |file_paths| will be a single value or a list of values depending on the
// dialog mode. If the selection was cancelled |file_paths| will be empty.
///
/*--cef(optional_param=file_paths)--*/
/*--cef(index_param=selected_accept_filter,optional_param=file_paths)--*/
virtual void OnFileDialogDismissed(
int selected_accept_filter,
const std::vector<CefString>& file_paths) = 0;
};
@@ -418,17 +421,19 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
// selectable file types and may any combination of (a) valid lower-cased MIME
// types (e.g. "text/*" or "image/*"), (b) individual file extensions (e.g.
// ".txt" or ".png"), or (c) combined description and file extension delimited
// using "|" and ";" (e.g. "Image Types|.png;.gif;.jpg"). |callback| will be
// executed after the dialog is dismissed or immediately if another dialog is
// already pending. The dialog will be initiated asynchronously on the UI
// thread.
// using "|" and ";" (e.g. "Image Types|.png;.gif;.jpg").
// |selected_accept_filter| is the 0-based index of the filter that will be
// selected by default. |callback| will be executed after the dialog is
// dismissed or immediately if another dialog is already pending. The dialog
// will be initiated asynchronously on the UI thread.
///
/*--cef(optional_param=title,optional_param=default_file_path,
optional_param=accept_filters)--*/
optional_param=accept_filters,index_param=selected_accept_filter)--*/
virtual void RunFileDialog(FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback) = 0;
///

View File

@@ -48,12 +48,16 @@
class CefFileDialogCallback : public virtual CefBaseRefCounted {
public:
///
// Continue the file selection. |file_paths| should be a single value or a
// Continue the file selection. |selected_accept_filter| should be the 0-based
// index of the value selected from the accept filters array passed to
// CefDialogHandler::OnFileDialog. |file_paths| should be a single value or a
// list of values depending on the dialog mode. An empty |file_paths| value is
// treated the same as calling Cancel().
///
/*--cef(capi_name=cont,optional_param=file_paths)--*/
virtual void Continue(const std::vector<CefString>& file_paths) = 0;
/*--cef(capi_name=cont,index_param=selected_accept_filter,
optional_param=file_paths)--*/
virtual void Continue(int selected_accept_filter,
const std::vector<CefString>& file_paths) = 0;
///
// Cancel the file selection.
@@ -81,17 +85,19 @@ class CefDialogHandler : public virtual CefBaseRefCounted {
// (a) valid lower-cased MIME types (e.g. "text/*" or "image/*"),
// (b) individual file extensions (e.g. ".txt" or ".png"), or (c) combined
// description and file extension delimited using "|" and ";" (e.g.
// "Image Types|.png;.gif;.jpg"). To display a custom dialog return true and
// execute |callback| either inline or at a later time. To display the default
// dialog return false.
// "Image Types|.png;.gif;.jpg"). |selected_accept_filter| is the 0-based
// index of the filter that should be selected by default. To display a custom
// dialog return true and execute |callback| either inline or at a later time.
// To display the default dialog return false.
///
/*--cef(optional_param=title,optional_param=default_file_path,
optional_param=accept_filters)--*/
optional_param=accept_filters,index_param=selected_accept_filter)--*/
virtual bool OnFileDialog(CefRefPtr<CefBrowser> browser,
FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefFileDialogCallback> callback) {
return false;
}

View File

@@ -99,9 +99,6 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {}
explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {}
CefWindowInfo& operator=(const CefWindowInfo&) = default;
CefWindowInfo& operator=(CefWindowInfo&&) = default;
///
// Create the browser as a child window.
///

View File

@@ -100,9 +100,6 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {}
explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {}
CefWindowInfo& operator=(const CefWindowInfo&) = default;
CefWindowInfo& operator=(CefWindowInfo&&) = default;
///
// Create the browser as a child view.
///

View File

@@ -2237,6 +2237,26 @@ typedef enum {
// already exists.
///
FILE_DIALOG_SAVE,
///
// General mask defining the bits used for the type values.
///
FILE_DIALOG_TYPE_MASK = 0xFF,
// Qualifiers.
// Any of the type values above can be augmented by one or more qualifiers.
// These qualifiers further define the dialog behavior.
///
// Prompt to overwrite if the user selects an existing file with the Save
// dialog.
///
FILE_DIALOG_OVERWRITEPROMPT_FLAG = 0x01000000,
///
// Do not display read-only files.
///
FILE_DIALOG_HIDEREADONLY_FLAG = 0x02000000,
} cef_file_dialog_mode_t;
///
@@ -3102,14 +3122,8 @@ typedef enum {
// pass-through mode).
CEF_CHANNEL_LAYOUT_BITSTREAM = 32,
// Front L, Front R, Front C, LFE, Side L, Side R,
// Front Height L, Front Height R, Rear Height L, Rear Height R
// Will be represented as six channels (5.1) due to eight channel limit
// kMaxConcurrentChannels
CEF_CHANNEL_LAYOUT_5_1_4_DOWNMIX = 33,
// Max value, must always equal the largest entry ever logged.
CEF_CHANNEL_LAYOUT_MAX = CEF_CHANNEL_LAYOUT_5_1_4_DOWNMIX
CEF_CHANNEL_LAYOUT_MAX = CEF_CHANNEL_LAYOUT_BITSTREAM
} cef_channel_layout_t;
///

View File

@@ -102,9 +102,6 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> {
explicit CefWindowInfo(const cef_window_info_t& r) : parent(r) {}
explicit CefWindowInfo(const CefWindowInfo& r) : parent(r) {}
CefWindowInfo& operator=(const CefWindowInfo&) = default;
CefWindowInfo& operator=(CefWindowInfo&&) = default;
///
// Create the browser as a child window.
///

View File

@@ -63,13 +63,6 @@ class CefWindowDelegate : public CefPanelDelegate {
/*--cef()--*/
virtual void OnWindowDestroyed(CefRefPtr<CefWindow> window) {}
///
// Called when |window| is activated or deactivated.
///
/*--cef()--*/
virtual void OnWindowActivationChanged(CefRefPtr<CefWindow> window,
bool active) {}
///
// Return the parent for |window| or NULL if the |window| does not have a
// parent. Windows with parents will not get a taskbar button. Set |is_menu|

View File

@@ -18,6 +18,7 @@
#include "libcef/browser/context.h"
#include "libcef/browser/devtools/devtools_manager.h"
#include "libcef/browser/media_capture_devices_dispatcher.h"
#include "libcef/browser/native/cursor_util.h"
#include "libcef/browser/osr/osr_util.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/thread_util.h"
@@ -32,9 +33,9 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "chrome/browser/file_select_helper.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/host_zoom_map.h"
@@ -46,11 +47,12 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_observer.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "net/base/net_errors.h"
#include "third_party/blink/public/mojom/widget/platform_widget.mojom-test-utils.h"
#include "ui/events/base_event_utils.h"
using content::KeyboardEventProcessingResult;
@@ -84,6 +86,48 @@ void ShowDevToolsWithHelper(ShowDevToolsHelper* helper) {
delete helper;
}
class CefWidgetHostInterceptor
: public blink::mojom::WidgetHostInterceptorForTesting,
public content::RenderWidgetHostObserver {
public:
CefWidgetHostInterceptor(AlloyBrowserHostImpl* browser,
content::RenderViewHost* render_view_host)
: browser_(browser),
render_widget_host_(
content::RenderWidgetHostImpl::From(render_view_host->GetWidget())),
impl_(render_widget_host_->widget_host_receiver_for_testing()
.SwapImplForTesting(this)) {
render_widget_host_->AddObserver(this);
}
CefWidgetHostInterceptor(const CefWidgetHostInterceptor&) = delete;
CefWidgetHostInterceptor& operator=(const CefWidgetHostInterceptor&) = delete;
blink::mojom::WidgetHost* GetForwardingInterface() override { return impl_; }
// WidgetHostInterceptorForTesting method:
void SetCursor(const ui::Cursor& cursor) override {
if (cursor_util::OnCursorChange(browser_, cursor)) {
// Don't change the cursor.
return;
}
GetForwardingInterface()->SetCursor(cursor);
}
// RenderWidgetHostObserver method:
void RenderWidgetHostDestroyed(
content::RenderWidgetHost* widget_host) override {
widget_host->RemoveObserver(this);
delete this;
}
private:
AlloyBrowserHostImpl* const browser_;
content::RenderWidgetHostImpl* const render_widget_host_;
blink::mojom::WidgetHost* const impl_;
};
static constexpr base::TimeDelta kRecentlyAudibleTimeout = base::Seconds(2);
} // namespace
@@ -199,15 +243,7 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::CreateInternal(
// Notify that the browser has been created. These must be delivered in the
// expected order.
if (opener && opener->platform_delegate_) {
// 1. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
// Do this first for consistency with the Chrome runtime.
opener->platform_delegate_->PopupBrowserCreated(browser.get(),
is_devtools_popup);
}
// 2. Notify the browser's LifeSpanHandler. This must always be the first
// 1. Notify the browser's LifeSpanHandler. This must always be the first
// notification for the browser. Block navigation to avoid issues with focus
// changes being sent to an unbound interface.
{
@@ -215,10 +251,17 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::CreateInternal(
browser->OnAfterCreated();
}
// 3. Notify the platform delegate. With Views this will result in a call to
// 2. Notify the platform delegate. With Views this will result in a call to
// CefBrowserViewDelegate::OnBrowserCreated().
browser->platform_delegate_->NotifyBrowserCreated();
if (opener && opener->platform_delegate_) {
// 3. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
opener->platform_delegate_->PopupBrowserCreated(browser.get(),
is_devtools_popup);
}
return browser;
}
@@ -312,6 +355,20 @@ bool AlloyBrowserHostImpl::TryCloseBrowser() {
return true;
}
void AlloyBrowserHostImpl::SetFocus(bool focus) {
// Always execute asynchronously to work around issue #3040.
CEF_POST_TASK(CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::SetFocusInternal,
this, focus));
}
void AlloyBrowserHostImpl::SetFocusInternal(bool focus) {
CEF_REQUIRE_UIT();
if (focus)
OnSetFocus(FOCUS_SOURCE_SYSTEM);
else if (platform_delegate_)
platform_delegate_->SetFocus(false);
}
CefWindowHandle AlloyBrowserHostImpl::GetWindowHandle() {
if (is_views_hosted_ && CEF_CURRENTLY_ON_UIT()) {
// Always return the most up-to-date window handle for a views-hosted
@@ -349,6 +406,27 @@ void AlloyBrowserHostImpl::SetZoomLevel(double zoomLevel) {
}
}
void AlloyBrowserHostImpl::RunFileDialog(
FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&AlloyBrowserHostImpl::RunFileDialog, this,
mode, title, default_file_path, accept_filters,
selected_accept_filter, callback));
return;
}
EnsureFileDialogManager();
file_dialog_manager_->RunFileDialog(mode, title, default_file_path,
accept_filters, selected_accept_filter,
callback);
}
void AlloyBrowserHostImpl::Print() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::Print, this));
@@ -586,6 +664,20 @@ void AlloyBrowserHostImpl::SendCaptureLostEvent() {
platform_delegate_->SendCaptureLostEvent();
}
void AlloyBrowserHostImpl::NotifyMoveOrResizeStarted() {
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&AlloyBrowserHostImpl::NotifyMoveOrResizeStarted, this));
return;
}
if (platform_delegate_)
platform_delegate_->NotifyMoveOrResizeStarted();
#endif
}
int AlloyBrowserHostImpl::GetWindowlessFrameRate() {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
@@ -646,6 +738,8 @@ void AlloyBrowserHostImpl::DestroyBrowser() {
OnBeforeClose();
// Destroy any platform constructs first.
if (file_dialog_manager_.get())
file_dialog_manager_->Destroy();
if (javascript_dialog_manager_.get())
javascript_dialog_manager_->Destroy();
if (menu_manager_.get())
@@ -728,6 +822,13 @@ void AlloyBrowserHostImpl::OnSetFocus(cef_focus_source_t source) {
platform_delegate_->SetFocus(true);
}
void AlloyBrowserHostImpl::RunFileChooser(
const CefFileDialogRunner::FileChooserParams& params,
CefFileDialogRunner::RunFileChooserCallback callback) {
EnsureFileDialogManager();
file_dialog_manager_->RunFileChooser(params, std::move(callback));
}
void AlloyBrowserHostImpl::EnterFullscreenModeForTab(
content::RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options) {
@@ -1249,9 +1350,8 @@ void AlloyBrowserHostImpl::RunFileChooser(
content::RenderFrameHost* render_frame_host,
scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) {
// This will eventually call into CefFileDialogManager.
FileSelectHelper::RunFileChooser(render_frame_host, std::move(listener),
params);
EnsureFileDialogManager();
file_dialog_manager_->RunFileChooser(listener, params);
}
bool AlloyBrowserHostImpl::HandleContextMenu(
@@ -1390,6 +1490,19 @@ bool AlloyBrowserHostImpl::IsPrerender2Supported(
// content::WebContentsObserver methods.
// -----------------------------------------------------------------------------
void AlloyBrowserHostImpl::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
if (render_frame_host->GetParent() == nullptr) {
auto render_view_host = render_frame_host->GetRenderViewHost();
new CefWidgetHostInterceptor(this, render_view_host);
platform_delegate_->RenderViewCreated(render_view_host);
}
}
void AlloyBrowserHostImpl::RenderViewReady() {
platform_delegate_->RenderViewReady();
}
void AlloyBrowserHostImpl::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (web_contents()) {
@@ -1547,3 +1660,11 @@ void AlloyBrowserHostImpl::UpdateDragCursor(
if (platform_delegate_)
platform_delegate_->UpdateDragCursor(operation);
}
void AlloyBrowserHostImpl::EnsureFileDialogManager() {
CEF_REQUIRE_UIT();
if (!file_dialog_manager_.get() && platform_delegate_) {
file_dialog_manager_.reset(new CefFileDialogManager(
this, platform_delegate_->CreateFileDialogRunner()));
}
}

View File

@@ -16,6 +16,7 @@
#include "include/cef_frame.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/file_dialog_manager.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/javascript_dialog_manager.h"
#include "libcef/browser/menu_manager.h"
@@ -78,10 +79,17 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// CefBrowserHost methods.
void CloseBrowser(bool force_close) override;
bool TryCloseBrowser() override;
void SetFocus(bool focus) override;
CefWindowHandle GetWindowHandle() override;
CefWindowHandle GetOpenerWindowHandle() override;
double GetZoomLevel() override;
void SetZoomLevel(double zoomLevel) override;
void RunFileDialog(FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback) override;
void Print() override;
void PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
@@ -105,6 +113,7 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
void SendExternalBeginFrame() override;
void SendTouchEvent(const CefTouchEvent& event) override;
void SendCaptureLostEvent() override;
void NotifyMoveOrResizeStarted() override;
int GetWindowlessFrameRate() override;
void SetWindowlessFrameRate(int frame_rate) override;
void ImeSetComposition(const CefString& text,
@@ -171,6 +180,12 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
void OnSetFocus(cef_focus_source_t source) override;
// Run the file chooser dialog specified by |params|. Only a single dialog may
// be pending at any given time. |callback| will be executed asynchronously
// after the dialog is dismissed or if another dialog is already pending.
void RunFileChooser(const CefFileDialogRunner::FileChooserParams& params,
CefFileDialogRunner::RunFileChooserCallback callback);
bool HandleContextMenu(content::WebContents* web_contents,
const content::ContextMenuParams& params);
@@ -278,6 +293,8 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// content::WebContentsObserver methods.
using content::WebContentsObserver::BeforeUnloadFired;
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
void RenderViewReady() override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void OnAudioStateChanged(bool audible) override;
@@ -316,9 +333,14 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// Give the platform delegate an opportunity to create the host window.
bool CreateHostWindow();
// Create the CefFileDialogManager if it doesn't already exist.
void EnsureFileDialogManager();
void StartAudioCapturer();
void OnRecentlyAudibleTimerFired();
void SetFocusInternal(bool focus);
CefWindowHandle opener_;
const bool is_windowless_;
CefWindowHandle host_window_handle_ = kNullWindowHandle;
@@ -333,6 +355,9 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// on the UI thread.
bool window_destroyed_ = false;
// Used for creating and managing file dialogs.
std::unique_ptr<CefFileDialogManager> file_dialog_manager_;
// Used for creating and managing JavaScript dialogs.
std::unique_ptr<CefJavaScriptDialogManager> javascript_dialog_manager_;

View File

@@ -13,7 +13,6 @@
#include "libcef/browser/context.h"
#include "libcef/browser/devtools/devtools_manager_delegate.h"
#include "libcef/browser/extensions/extension_system_factory.h"
#include "libcef/browser/file_dialog_runner.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
#include "libcef/browser/printing/constrained_window_views_client.h"
#include "libcef/browser/thread_util.h"
@@ -59,12 +58,14 @@
#endif
#endif // defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
#if BUILDFLAG(IS_MAC)
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_views_delegate.h"
#else
#include "ui/views/test/desktop_test_views_delegate.h"
#endif
#endif // defined(TOOLKIT_VIEWS)
#if defined(USE_AURA) && BUILDFLAG(IS_LINUX)
#include "ui/base/ime/init/input_method_initializer.h"
@@ -76,23 +77,11 @@
#if BUILDFLAG(IS_LINUX)
#include "base/path_service.h"
#include "chrome/browser/themes/theme_service_aura_linux.h"
#include "chrome/browser/ui/views/theme_profile_key.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/grit/chromium_strings.h"
#include "components/os_crypt/key_storage_config_linux.h"
#include "libcef/browser/printing/print_dialog_linux.h"
#include "ui/base/cursor/cursor_factory.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/linux/fake_input_method_context_factory.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/linux/linux_ui_delegate.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/views/linux_ui/linux_ui.h"
#if BUILDFLAG(USE_GTK)
#include "ui/gtk/gtk_ui_factory.h"
#endif
#endif // BUILDFLAG(IS_LINUX)
#if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM)
@@ -103,75 +92,6 @@
#include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
#endif
namespace {
#if BUILDFLAG(IS_LINUX)
std::unique_ptr<views::LinuxUI> BuildLinuxUI() {
// We can't use GtkUi in combination with multi-threaded-message-loop because
// Chromium's GTK implementation doesn't use GDK threads.
if (!!CefContext::Get()->settings().multi_threaded_message_loop)
return nullptr;
// If the ozone backend hasn't provided a LinuxUiDelegate, don't try to create
// a LinuxUi instance as this may result in a crash in toolkit initialization.
if (!ui::LinuxUiDelegate::GetInstance())
return nullptr;
// GtkUi is the only LinuxUI implementation for now.
#if BUILDFLAG(USE_GTK)
return BuildGtkUi();
#else
return nullptr;
#endif
}
// Based on chrome_browser_main_extra_parts_views_linux.cc
void ToolkitInitializedLinux() {
if (auto linux_ui = BuildLinuxUI()) {
linux_ui->SetUseSystemThemeCallback(
base::BindRepeating([](aura::Window* window) {
if (!window)
return true;
return ThemeServiceAuraLinux::ShouldUseSystemThemeForProfile(
GetThemeProfileForWindow(window));
}));
linux_ui->Initialize();
views::LinuxUI::SetInstance(std::move(linux_ui));
// Cursor theme changes are tracked by LinuxUI (via a CursorThemeManager
// implementation). Start observing them once it's initialized.
ui::CursorFactory::GetInstance()->ObserveThemeChanges();
} else {
// In case if GTK is not used, input method factory won't be set for X11 and
// Ozone/X11. Set a fake one instead to avoid crashing browser later.
DCHECK(!ui::LinuxInputMethodContextFactory::instance());
// Try to create input method through Ozone so that the backend has a chance
// to set factory by itself.
ui::OzonePlatform::GetInstance()->CreateInputMethod(
nullptr, gfx::kNullAcceleratedWidget);
}
// If factory is not set, set a fake instance.
if (!ui::LinuxInputMethodContextFactory::instance()) {
ui::LinuxInputMethodContextFactory::SetInstance(
new ui::FakeInputMethodContextFactory());
}
auto create_print_dialog_func =
printing::PrintingContextLinux::SetCreatePrintDialogFunction(
&CefPrintDialogLinux::CreatePrintDialog);
auto pdf_paper_size_func =
printing::PrintingContextLinux::SetPdfPaperSizeFunction(
&CefPrintDialogLinux::GetPdfPaperSize);
CefPrintDialogLinux::SetDefaultPrintingContextFuncs(create_print_dialog_func,
pdf_paper_size_func);
}
#endif // BUILDFLAG(IS_LINUX)
} // namespace
AlloyBrowserMainParts::AlloyBrowserMainParts(
content::MainFunctionParams parameters)
: BrowserMainParts(), parameters_(std::move(parameters)) {}
@@ -180,6 +100,16 @@ AlloyBrowserMainParts::~AlloyBrowserMainParts() {
constrained_window::SetConstrainedWindowViewsClient(nullptr);
}
int AlloyBrowserMainParts::PreEarlyInitialization() {
#if defined(USE_AURA) && BUILDFLAG(IS_LINUX)
// TODO(linux): Consider using a real input method or
// views::LinuxUI::SetInstance.
ui::InitializeInputMethodForTesting();
#endif
return content::RESULT_CODE_NORMAL_EXIT;
}
void AlloyBrowserMainParts::ToolkitInitialized() {
SetConstrainedWindowViewsClient(CreateCefConstrainedWindowViewsClient());
#if defined(USE_AURA)
@@ -188,16 +118,14 @@ void AlloyBrowserMainParts::ToolkitInitialized() {
wm_state_.reset(new wm::WMState);
#endif // defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
#if BUILDFLAG(IS_MAC)
views_delegate_ = std::make_unique<ChromeViewsDelegate>();
layout_provider_ = ChromeLayoutProvider::CreateLayoutProvider();
#else
views_delegate_ = std::make_unique<views::DesktopTestViewsDelegate>();
#endif
#if BUILDFLAG(IS_LINUX)
ToolkitInitializedLinux();
#endif
#endif // defined(TOOLKIT_VIEWS)
}
void AlloyBrowserMainParts::PreCreateMainMessageLoop() {
@@ -224,6 +152,11 @@ void AlloyBrowserMainParts::PreCreateMainMessageLoop() {
void AlloyBrowserMainParts::PostCreateMainMessageLoop() {
#if BUILDFLAG(IS_LINUX)
printing::PrintingContextLinux::SetCreatePrintDialogFunction(
&CefPrintDialogLinux::CreatePrintDialog);
printing::PrintingContextLinux::SetPdfPaperSizeFunction(
&CefPrintDialogLinux::GetPdfPaperSize);
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@@ -312,7 +245,6 @@ int AlloyBrowserMainParts::PreMainMessageLoopRun() {
PluginFinder::GetInstance()->Init();
scheme::RegisterWebUIControllerFactory();
file_dialog_runner::RegisterFactory();
#if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM) || \
BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
@@ -345,8 +277,10 @@ void AlloyBrowserMainParts::PostMainMessageLoopRun() {
}
void AlloyBrowserMainParts::PostDestroyThreads() {
#if defined(TOOLKIT_VIEWS)
views_delegate_.reset();
#if BUILDFLAG(IS_MAC)
layout_provider_.reset();
#endif
#endif // defined(TOOLKIT_VIEWS)
}

View File

@@ -24,12 +24,14 @@ class WMState;
}
#endif
#if defined(TOOLKIT_VIEWS)
namespace views {
class ViewsDelegate;
#if BUILDFLAG(IS_MAC)
class LayoutProvider;
#endif
} // namespace views
#endif // defined(TOOLKIT_VIEWS)
class CefDevToolsDelegate;
@@ -42,6 +44,7 @@ class AlloyBrowserMainParts : public content::BrowserMainParts {
~AlloyBrowserMainParts() override;
int PreEarlyInitialization() override;
void ToolkitInitialized() override;
void PreCreateMainMessageLoop() override;
void PostCreateMainMessageLoop() override;
@@ -89,10 +92,12 @@ class AlloyBrowserMainParts : public content::BrowserMainParts {
std::unique_ptr<wm::WMState> wm_state_;
#endif
#if defined(TOOLKIT_VIEWS)
std::unique_ptr<views::ViewsDelegate> views_delegate_;
#if BUILDFLAG(IS_MAC)
std::unique_ptr<views::LayoutProvider> layout_provider_;
#endif
#endif // defined(TOOLKIT_VIEWS)
};
#endif // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_BROWSER_MAIN_H_

View File

@@ -52,7 +52,6 @@
#include "base/stl_util.h"
#include "base/threading/thread_restrictions.h"
#include "cef/grit/cef_resources.h"
#include "chrome/browser/accessibility/live_caption_unavailability_notifier.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
@@ -69,7 +68,6 @@
#include "chrome/browser/profiles/renderer_updater_factory.h"
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
#include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -434,11 +432,6 @@ void BindPluginInfoHost(
std::move(receiver));
}
void BindMediaFoundationRendererNotifierHandler(
content::RenderFrameHost* frame_host,
mojo::PendingReceiver<media::mojom::MediaFoundationRendererNotifier>
receiver) {}
base::FilePath GetRootCachePath() {
// The CefContext::ValidateCachePath method enforces the requirement that all
// cache_path values be either equal to or a child of root_cache_path.
@@ -583,12 +576,6 @@ void AlloyContentBrowserClient::GetAdditionalViewSourceSchemes(
additional_schemes->push_back(extensions::kExtensionScheme);
}
std::unique_ptr<ui::SelectFilePolicy>
AlloyContentBrowserClient::CreateSelectFilePolicy(
content::WebContents* web_contents) {
return std::make_unique<ChromeSelectFilePolicy>(web_contents);
}
void AlloyContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
std::vector<std::string>* additional_allowed_schemes) {
ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
@@ -1405,9 +1392,6 @@ void AlloyContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host,
map);
map->Add<media::mojom::MediaFoundationRendererNotifier>(
base::BindRepeating(&BindMediaFoundationRendererNotifierHandler));
if (!extensions::ExtensionsEnabled())
return;

View File

@@ -58,8 +58,6 @@ class AlloyContentBrowserClient : public content::ContentBrowserClient {
std::vector<std::string>* additional_schemes) override;
void GetAdditionalViewSourceSchemes(
std::vector<std::string>* additional_schemes) override;
std::unique_ptr<ui::SelectFilePolicy> CreateSelectFilePolicy(
content::WebContents* web_contents) override;
void GetAdditionalAllowedSchemesForFileSystem(
std::vector<std::string>* additional_allowed_schemes) override;
bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin) override;

View File

@@ -0,0 +1,49 @@
// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#include "libcef/browser/alloy/alloy_dialog_util.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/file_dialog_runner.h"
#include "base/strings/utf_string_conversions.h"
namespace alloy {
void RunFileChooser(content::WebContents* web_contents,
const blink::mojom::FileChooserParams& params,
RunFileChooserCallback callback) {
CefRefPtr<AlloyBrowserHostImpl> browser = static_cast<AlloyBrowserHostImpl*>(
extensions::GetOwnerBrowserForHost(web_contents->GetRenderViewHost(),
nullptr)
.get());
if (!browser) {
LOG(ERROR) << "Failed to identify browser; canceling file dialog";
std::move(callback).Run(-1, {});
return;
}
CefFileDialogRunner::FileChooserParams cef_params;
cef_params.mode = params.mode;
cef_params.default_file_name = params.default_file_name;
cef_params.accept_types = params.accept_types;
browser->RunFileChooser(cef_params, std::move(callback));
}
// Based on net/base/filename_util_internal.cc FilePathToString16().
std::u16string FilePathTypeToString16(const base::FilePath::StringType& str) {
std::u16string result;
#if BUILDFLAG(IS_WIN)
result.assign(str.begin(), str.end());
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
if (!str.empty()) {
base::UTF8ToUTF16(str.c_str(), str.size(), &result);
}
#endif
return result;
}
} // namespace alloy

View File

@@ -0,0 +1,37 @@
// Copyright 2021 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_ALLOY_ALLOY_DIALOG_UTIL_H_
#define CEF_LIBCEF_BROWSER_ALLOY_ALLOY_DIALOG_UTIL_H_
#pragma once
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
namespace content {
class WebContents;
}
namespace alloy {
// The argument vector will be empty if the dialog was canceled.
using RunFileChooserCallback =
base::OnceCallback<void(int /*selected_accept_filter*/,
const std::vector<base::FilePath>& /*file_paths*/)>;
// Display the file chooser dialog. Execute |callback| on completion.
// Called from patched chrome/ files.
void RunFileChooser(content::WebContents* web_contents,
const blink::mojom::FileChooserParams& params,
RunFileChooserCallback callback);
std::u16string FilePathTypeToString16(const base::FilePath::StringType& str);
} // namespace alloy
#endif // CEF_LIBCEF_BROWSER_ALLOY_ALLOY_DIALOG_UTIL_H_

View File

@@ -25,6 +25,7 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "extensions/browser/process_manager.h"
#include "pdf/pdf_features.h"
#include "printing/mojom/print.mojom.h"
@@ -111,15 +112,10 @@ void CefBrowserPlatformDelegateAlloy::WebContentsCreated(
content::WebContents* web_contents,
bool owned) {
CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned);
find_in_page::FindTabHelper::CreateForWebContents(web_contents);
if (primary_) {
find_in_page::FindTabHelper::CreateForWebContents(web_contents);
if (owned) {
SetOwnedWebContents(web_contents);
}
} else {
DCHECK(!owned);
if (owned) {
SetOwnedWebContents(web_contents);
}
}
@@ -161,6 +157,14 @@ bool CefBrowserPlatformDelegateAlloy::
return true;
}
void CefBrowserPlatformDelegateAlloy::RenderViewCreated(
content::RenderViewHost* render_view_host) {
// Indicate that the view has an external parent (namely us). This changes the
// default view behavior in some cases (e.g. focus handling on Linux).
if (!IsViewsHosted() && render_view_host->GetWidget()->GetView())
render_view_host->GetWidget()->GetView()->SetHasExternalParent(true);
}
void CefBrowserPlatformDelegateAlloy::RenderViewReady() {
ConfigureAutoResize();
}

View File

@@ -35,6 +35,7 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate {
bool* was_blocked) override;
bool ShouldAllowRendererInitiatedCrossProcessNavigation(
bool is_main_frame_navigation) override;
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void RenderViewReady() override;
void BrowserCreated(CefBrowserHostBase* browser) override;
void CreateExtensionHost(const extensions::Extension* extension,

View File

@@ -129,12 +129,13 @@ base::Time ChromeProfileAlloy::GetStartTime() const {
}
base::FilePath ChromeProfileAlloy::last_selected_directory() {
return last_selected_directory_;
NOTREACHED();
return base::FilePath();
}
void ChromeProfileAlloy::set_last_selected_directory(
const base::FilePath& path) {
last_selected_directory_ = path;
NOTREACHED();
}
GURL ChromeProfileAlloy::GetHomePage() {

View File

@@ -8,7 +8,6 @@
#ifndef CEF_LIBCEF_BROWSER_ALLOY_CHROME_PROFILE_ALLOY_H_
#define CEF_LIBCEF_BROWSER_ALLOY_CHROME_PROFILE_ALLOY_H_
#include "base/files/file_path.h"
#include "chrome/browser/profiles/profile.h"
// This file provides a stub implementation of Chrome's Profile object for use
@@ -55,7 +54,6 @@ class ChromeProfileAlloy : public Profile {
private:
std::unique_ptr<variations::VariationsClient> variations_client_;
base::FilePath last_selected_directory_;
};
#endif // CEF_LIBCEF_BROWSER_ALLOY_CHROME_PROFILE_ALLOY_H_

View File

@@ -7,10 +7,8 @@
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/browser_util.h"
#include "libcef/browser/native/cursor_util.h"
#include "libcef/common/frame_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/focused_node_details.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -21,60 +19,12 @@
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_observer.h"
#include "content/public/browser/render_widget_host_view.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/mojom/widget/platform_widget.mojom-test-utils.h"
using content::KeyboardEventProcessingResult;
namespace {
class CefWidgetHostInterceptor
: public blink::mojom::WidgetHostInterceptorForTesting,
public content::RenderWidgetHostObserver {
public:
CefWidgetHostInterceptor(CefRefPtr<CefBrowser> browser,
content::RenderWidgetHost* render_widget_host)
: browser_(browser),
render_widget_host_(render_widget_host),
impl_(static_cast<content::RenderWidgetHostImpl*>(render_widget_host)
->widget_host_receiver_for_testing()
.SwapImplForTesting(this)) {
render_widget_host_->AddObserver(this);
}
CefWidgetHostInterceptor(const CefWidgetHostInterceptor&) = delete;
CefWidgetHostInterceptor& operator=(const CefWidgetHostInterceptor&) = delete;
blink::mojom::WidgetHost* GetForwardingInterface() override { return impl_; }
// WidgetHostInterceptorForTesting method:
void SetCursor(const ui::Cursor& cursor) override {
if (cursor_util::OnCursorChange(browser_, cursor)) {
// Don't change the cursor.
return;
}
GetForwardingInterface()->SetCursor(cursor);
}
// RenderWidgetHostObserver method:
void RenderWidgetHostDestroyed(
content::RenderWidgetHost* widget_host) override {
widget_host->RemoveObserver(this);
delete this;
}
private:
CefRefPtr<CefBrowser> const browser_;
content::RenderWidgetHost* const render_widget_host_;
blink::mojom::WidgetHost* const impl_;
};
} // namespace
CefBrowserContentsDelegate::CefBrowserContentsDelegate(
scoped_refptr<CefBrowserInfo> browser_info)
: browser_info_(browser_info) {
@@ -102,10 +52,6 @@ void CefBrowserContentsDelegate::ObserveWebContents(
// browser.
browser_info_->MaybeCreateFrame(new_contents->GetMainFrame(),
false /* is_guest_view */);
// Make sure RenderWidgetCreated is called at least one time. This Observer
// is registered too late to catch the initial creation.
RenderWidgetCreated(new_contents->GetRenderViewHost()->GetWidget());
} else {
registrar_.reset();
}
@@ -319,8 +265,6 @@ void CefBrowserContentsDelegate::RenderFrameCreated(
}
render_view_host->GetWidget()->GetView()->SetBackgroundColor(
base_background_color);
platform_delegate()->RenderViewCreated(render_view_host);
}
}
@@ -350,14 +294,7 @@ void CefBrowserContentsDelegate::RenderFrameDeleted(
}
}
void CefBrowserContentsDelegate::RenderWidgetCreated(
content::RenderWidgetHost* render_widget_host) {
new CefWidgetHostInterceptor(browser(), render_widget_host);
}
void CefBrowserContentsDelegate::RenderViewReady() {
platform_delegate()->RenderViewReady();
if (auto c = client()) {
if (auto handler = c->GetRequestHandler()) {
handler->OnRenderViewReady(browser());

View File

@@ -120,8 +120,6 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate,
content::RenderFrameHost::LifecycleState old_state,
content::RenderFrameHost::LifecycleState new_state) override;
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
void RenderWidgetCreated(
content::RenderWidgetHost* render_widget_host) override;
void RenderViewReady() override;
void PrimaryMainFrameRenderProcessGone(
base::TerminationStatus status) override;

View File

@@ -20,14 +20,11 @@
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "components/favicon/core/favicon_url.h"
#include "components/spellcheck/common/spellcheck_features.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/navigation_entry.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/shell_dialogs/select_file_policy.h"
#if BUILDFLAG(IS_MAC)
#include "components/spellcheck/browser/spellcheck_platform.h"
@@ -197,45 +194,6 @@ bool CefBrowserHostBase::HasView() {
return is_views_hosted_;
}
void CefBrowserHostBase::SetFocus(bool focus) {
// Always execute asynchronously to work around issue #3040.
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostBase::SetFocusInternal,
this, focus));
}
void CefBrowserHostBase::SetFocusInternal(bool focus) {
CEF_REQUIRE_UIT();
if (focus)
OnSetFocus(FOCUS_SOURCE_SYSTEM);
else if (platform_delegate_)
platform_delegate_->SetFocus(false);
}
void CefBrowserHostBase::RunFileDialog(
FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
CefRefPtr<CefRunFileDialogCallback> callback) {
DCHECK(callback);
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostBase::RunFileDialog,
this, mode, title, default_file_path,
accept_filters, callback));
return;
}
if (!callback || !EnsureFileDialogManager()) {
LOG(ERROR) << "File dialog canceled due to invalid state.";
if (callback)
callback->OnFileDialogDismissed({});
return;
}
file_dialog_manager_->RunFileDialog(mode, title, default_file_path,
accept_filters, callback);
}
void CefBrowserHostBase::StartDownload(const CefString& url) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
@@ -419,20 +377,6 @@ CefRefPtr<CefNavigationEntry> CefBrowserHostBase::GetVisibleNavigationEntry() {
return new CefNavigationEntryImpl(entry);
}
void CefBrowserHostBase::NotifyMoveOrResizeStarted() {
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefBrowserHostBase::NotifyMoveOrResizeStarted, this));
return;
}
if (platform_delegate_)
platform_delegate_->NotifyMoveOrResizeStarted();
#endif
}
void CefBrowserHostBase::ReplaceMisspelling(const CefString& word) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
@@ -833,45 +777,6 @@ void CefBrowserHostBase::ViewText(const std::string& text) {
platform_delegate_->ViewText(text);
}
void CefBrowserHostBase::RunFileChooserForBrowser(
const blink::mojom::FileChooserParams& params,
CefFileDialogManager::RunFileChooserCallback callback) {
if (!EnsureFileDialogManager()) {
LOG(ERROR) << "File dialog canceled due to invalid state.";
std::move(callback).Run({});
return;
}
file_dialog_manager_->RunFileChooser(params, std::move(callback));
}
void CefBrowserHostBase::RunSelectFile(
ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy,
ui::SelectFileDialog::Type type,
const std::u16string& title,
const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
const base::FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params) {
if (!EnsureFileDialogManager()) {
LOG(ERROR) << "File dialog canceled due to invalid state.";
listener->FileSelectionCanceled(params);
return;
}
file_dialog_manager_->RunSelectFile(listener, std::move(policy), type, title,
default_path, file_types, file_type_index,
default_extension, owning_window, params);
}
void CefBrowserHostBase::SelectFileListenerDestroyed(
ui::SelectFileDialog::Listener* listener) {
if (file_dialog_manager_) {
file_dialog_manager_->SelectFileListenerDestroyed(listener);
}
}
bool CefBrowserHostBase::MaybeAllowNavigation(
content::RenderFrameHost* opener,
bool is_guest_view,
@@ -900,13 +805,6 @@ void CefBrowserHostBase::OnBeforeClose() {
void CefBrowserHostBase::OnBrowserDestroyed() {
CEF_REQUIRE_UIT();
// Destroy any platform constructs.
if (file_dialog_manager_) {
file_dialog_manager_->Destroy();
file_dialog_manager_.reset();
}
for (auto& observer : observers_)
observer.OnBrowserDestroyed(this);
}
@@ -938,6 +836,7 @@ content::BrowserContext* CefBrowserHostBase::GetBrowserContext() const {
return nullptr;
}
#if defined(TOOLKIT_VIEWS)
views::Widget* CefBrowserHostBase::GetWindowWidget() const {
CEF_REQUIRE_UIT();
if (!platform_delegate_)
@@ -951,29 +850,7 @@ CefRefPtr<CefBrowserView> CefBrowserHostBase::GetBrowserView() const {
return platform_delegate_->GetBrowserView();
return nullptr;
}
gfx::NativeWindow CefBrowserHostBase::GetTopLevelNativeWindow() const {
CEF_REQUIRE_UIT();
// Windowless browsers always return nullptr from GetTopLevelNativeWindow().
if (!IsWindowless()) {
auto web_contents = GetWebContents();
if (web_contents) {
return web_contents->GetTopLevelNativeWindow();
}
}
return gfx::NativeWindow();
}
bool CefBrowserHostBase::IsFocused() const {
CEF_REQUIRE_UIT();
auto web_contents = GetWebContents();
if (web_contents) {
return static_cast<content::RenderFrameHostImpl*>(
web_contents->GetMainFrame())
->IsFocused();
}
return false;
}
#endif // defined(TOOLKIT_VIEWS)
bool CefBrowserHostBase::EnsureDevToolsManager() {
CEF_REQUIRE_UIT();
@@ -981,7 +858,7 @@ bool CefBrowserHostBase::EnsureDevToolsManager() {
return false;
if (!devtools_manager_) {
devtools_manager_ = std::make_unique<CefDevToolsManager>(this);
devtools_manager_.reset(new CefDevToolsManager(this));
}
return true;
}
@@ -1001,14 +878,3 @@ void CefBrowserHostBase::InitializeDevToolsRegistrationOnUIThread(
return;
devtools_manager_->InitializeRegistrationOnUIThread(registration);
}
bool CefBrowserHostBase::EnsureFileDialogManager() {
CEF_REQUIRE_UIT();
if (!contents_delegate_->web_contents())
return false;
if (!file_dialog_manager_) {
file_dialog_manager_ = std::make_unique<CefFileDialogManager>(this);
}
return true;
}

View File

@@ -13,7 +13,6 @@
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/devtools/devtools_manager.h"
#include "libcef/browser/file_dialog_manager.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/request_context_impl.h"
@@ -40,19 +39,17 @@ struct CefBrowserCreateParams {
settings = that.settings;
request_context = that.request_context;
extra_info = that.extra_info;
if (that.window_info)
MaybeSetWindowInfo(*that.window_info);
#if defined(TOOLKIT_VIEWS)
browser_view = that.browser_view;
#endif
return *this;
}
// Set |window_info| if appropriate (see below).
void MaybeSetWindowInfo(const CefWindowInfo& window_info);
// Platform-specific window creation info. Will be nullptr for Views-hosted
// browsers except when using the Chrome runtime with a native parent handle.
// Platform-specific window creation info. Will be nullptr when creating a
// views-hosted browser. Currently used with the alloy runtime only.
std::unique_ptr<CefWindowInfo> window_info;
#if defined(TOOLKIT_VIEWS)
// The BrowserView that will own a Views-hosted browser. Will be nullptr for
// popup browsers.
CefRefPtr<CefBrowserView> browser_view;
@@ -61,6 +58,7 @@ struct CefBrowserCreateParams {
// case the BrowserView for this browser will be created later (from
// PopupWebContentsCreated).
bool popup_with_views_hosted_opener = false;
#endif
// Client implementation. May be nullptr.
CefRefPtr<CefClient> client;
@@ -156,12 +154,6 @@ class CefBrowserHostBase : public CefBrowserHost,
CefRefPtr<CefClient> GetClient() override;
CefRefPtr<CefRequestContext> GetRequestContext() override;
bool HasView() override;
void SetFocus(bool focus) override;
void RunFileDialog(FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
CefRefPtr<CefRunFileDialogCallback> callback) override;
void StartDownload(const CefString& url) override;
void DownloadImage(const CefString& image_url,
bool is_favicon,
@@ -188,7 +180,6 @@ class CefBrowserHostBase : public CefBrowserHost,
void GetNavigationEntries(CefRefPtr<CefNavigationEntryVisitor> visitor,
bool current_only) override;
CefRefPtr<CefNavigationEntry> GetVisibleNavigationEntry() override;
void NotifyMoveOrResizeStarted() override;
// CefBrowser methods:
bool IsValid() override;
@@ -240,22 +231,6 @@ class CefBrowserHostBase : public CefBrowserHost,
virtual void OnSetFocus(cef_focus_source_t source) = 0;
void ViewText(const std::string& text);
// Calls CefFileDialogManager methods.
void RunFileChooserForBrowser(
const blink::mojom::FileChooserParams& params,
CefFileDialogManager::RunFileChooserCallback callback);
void RunSelectFile(ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy,
ui::SelectFileDialog::Type type,
const std::u16string& title,
const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
const base::FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params);
void SelectFileListenerDestroyed(ui::SelectFileDialog::Listener* listener);
// Called from CefBrowserInfoManager::MaybeAllowNavigation.
virtual bool MaybeAllowNavigation(content::RenderFrameHost* opener,
bool is_guest_view,
@@ -290,27 +265,15 @@ class CefBrowserHostBase : public CefBrowserHost,
return contents_delegate_.get();
}
#if defined(TOOLKIT_VIEWS)
// Returns the Widget owner for the browser window. Only used with windowed
// browsers.
// rendering.
views::Widget* GetWindowWidget() const;
// Returns the BrowserView associated with this browser. Only used with Views-
// based browsers.
CefRefPtr<CefBrowserView> GetBrowserView() const;
// Returns the top-level native window for this browser. With windowed
// browsers this will be an aura::Window* on Aura platforms (Windows/Linux)
// and an NSWindow wrapper object from native_widget_types.h on MacOS. With
// windowless browsers this method will always return an empty value.
gfx::NativeWindow GetTopLevelNativeWindow() const;
// Returns true if this browser is currently focused. A browser is considered
// focused when the top-level RenderFrameHost is in the parent chain of the
// currently focused RFH within the frame tree. In addition, its associated
// RenderWidgetHost must also be focused. With windowed browsers only one
// browser should be focused at a time. With windowless browsers this relies
// on the client to properly configure focus state.
bool IsFocused() const;
#endif
protected:
bool EnsureDevToolsManager();
@@ -320,11 +283,6 @@ class CefBrowserHostBase : public CefBrowserHost,
// Called from LoadMainFrameURL to perform the actual navigation.
virtual bool Navigate(const content::OpenURLParams& params);
void SetFocusInternal(bool focus);
// Create the CefFileDialogManager if it doesn't already exist.
bool EnsureFileDialogManager();
// Thread-safe members.
CefBrowserSettings settings_;
CefRefPtr<CefClient> client_;
@@ -340,9 +298,6 @@ class CefBrowserHostBase : public CefBrowserHost,
// Only accessed on the UI thread.
base::ObserverList<Observer> observers_;
// Used for creating and managing file dialogs.
std::unique_ptr<CefFileDialogManager> file_dialog_manager_;
// Volatile state accessed from multiple threads. All access must be protected
// by |state_lock_|.
base::Lock state_lock_;

View File

@@ -6,7 +6,6 @@
#include "include/cef_browser.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/chrome/chrome_browser_host_impl.h"
#include "libcef/browser/chrome/views/chrome_child_window.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/features/runtime.h"
@@ -139,7 +138,7 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
}
CefBrowserCreateParams create_params;
create_params.MaybeSetWindowInfo(windowInfo);
create_params.window_info.reset(new CefWindowInfo(windowInfo));
create_params.client = client;
create_params.url = url;
create_params.settings = settings;
@@ -149,22 +148,10 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
return CefBrowserHostBase::Create(create_params);
}
void CefBrowserCreateParams::MaybeSetWindowInfo(
const CefWindowInfo& new_window_info) {
if (!cef::IsChromeRuntimeEnabled() ||
chrome_child_window::HasParentHandle(new_window_info)) {
window_info = std::make_unique<CefWindowInfo>(new_window_info);
}
}
// static
CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::Create(
CefBrowserCreateParams& create_params) {
if (cef::IsChromeRuntimeEnabled()) {
if (auto browser =
chrome_child_window::MaybeCreateChildBrowser(create_params)) {
return browser.get();
}
auto browser = ChromeBrowserHostImpl::Create(create_params);
return browser.get();
}

View File

@@ -129,10 +129,10 @@ bool CefBrowserInfoManager::CanCreateWindow(
CefRefPtr<CefClient> client = browser->GetClient();
bool allow = true;
CefWindowInfo window_info;
std::unique_ptr<CefWindowInfo> window_info(new CefWindowInfo);
#if BUILDFLAG(IS_WIN)
window_info.SetAsPopup(nullptr, CefString());
window_info->SetAsPopup(nullptr, CefString());
#endif
auto pending_popup = std::make_unique<CefBrowserInfoManager::PendingPopup>();
@@ -157,20 +157,20 @@ bool CefBrowserInfoManager::CanCreateWindow(
#if (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC))
// Default to the size from the popup features.
if (cef_features.xSet)
window_info.bounds.x = cef_features.x;
window_info->bounds.x = cef_features.x;
if (cef_features.ySet)
window_info.bounds.y = cef_features.y;
window_info->bounds.y = cef_features.y;
if (cef_features.widthSet)
window_info.bounds.width = cef_features.width;
window_info->bounds.width = cef_features.width;
if (cef_features.heightSet)
window_info.bounds.height = cef_features.height;
window_info->bounds.height = cef_features.height;
#endif
allow = !handler->OnBeforePopup(
browser.get(), opener_frame, pending_popup->target_url.spec(),
pending_popup->target_frame_name,
static_cast<cef_window_open_disposition_t>(disposition), user_gesture,
cef_features, window_info, pending_popup->client,
cef_features, *window_info, pending_popup->client,
pending_popup->settings, pending_popup->extra_info,
no_javascript_access);
}
@@ -178,16 +178,12 @@ bool CefBrowserInfoManager::CanCreateWindow(
if (allow) {
CefBrowserCreateParams create_params;
create_params.MaybeSetWindowInfo(window_info);
// In most cases, Views-hosted browsers should create Views-hosted popups
// and native browsers should use default popup handling. The one exception
// is with the Chrome runtime where a Views-hosted browser may have an
// external parent. In that case we want to use default popup handling even
// though the parent is (technically) Views-hosted.
create_params.popup_with_views_hosted_opener =
browser->HasView() &&
!browser->platform_delegate()->HasExternalParent();
if (browser->HasView()) {
create_params.popup_with_views_hosted_opener = true;
} else {
create_params.window_info = std::move(window_info);
}
create_params.settings = pending_popup->settings;
create_params.client = pending_popup->client;

View File

@@ -7,9 +7,6 @@
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "base/logging.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() = default;
@@ -64,12 +61,7 @@ bool CefBrowserPlatformDelegate::
}
void CefBrowserPlatformDelegate::RenderViewCreated(
content::RenderViewHost* render_view_host) {
// Indicate that the view has an external parent (namely us). This setting is
// required for proper focus handling on Windows and Linux.
if (HasExternalParent() && render_view_host->GetWidget()->GetView())
render_view_host->GetWidget()->GetView()->SetHasExternalParent(true);
}
content::RenderViewHost* render_view_host) {}
void CefBrowserPlatformDelegate::RenderViewReady() {}
@@ -121,6 +113,7 @@ CefWindowHandle CefBrowserPlatformDelegate::GetHostWindowHandle() const {
return kNullWindowHandle;
}
#if defined(TOOLKIT_VIEWS)
views::Widget* CefBrowserPlatformDelegate::GetWindowWidget() const {
NOTREACHED();
return nullptr;
@@ -130,6 +123,7 @@ CefRefPtr<CefBrowserView> CefBrowserPlatformDelegate::GetBrowserView() const {
NOTREACHED();
return nullptr;
}
#endif // defined(TOOLKIT_VIEWS)
void CefBrowserPlatformDelegate::PopupWebContentsCreated(
const CefBrowserSettings& settings,
@@ -178,7 +172,9 @@ void CefBrowserPlatformDelegate::SendTouchEvent(const CefTouchEvent& event) {
NOTIMPLEMENTED();
}
void CefBrowserPlatformDelegate::SetFocus(bool setFocus) {}
void CefBrowserPlatformDelegate::SetFocus(bool setFocus) {
NOTIMPLEMENTED();
}
void CefBrowserPlatformDelegate::SendCaptureLostEvent() {
NOTIMPLEMENTED();
@@ -223,6 +219,12 @@ CefEventHandle CefBrowserPlatformDelegate::GetEventHandle(
return kNullEventHandle;
}
std::unique_ptr<CefFileDialogRunner>
CefBrowserPlatformDelegate::CreateFileDialogRunner() {
NOTIMPLEMENTED();
return nullptr;
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegate::CreateJavaScriptDialogRunner() {
NOTIMPLEMENTED();
@@ -242,12 +244,6 @@ bool CefBrowserPlatformDelegate::IsViewsHosted() const {
return false;
}
bool CefBrowserPlatformDelegate::HasExternalParent() const {
// In the majority of cases a Views-hosted browser will not have an external
// parent, and visa-versa.
return !IsViewsHosted();
}
void CefBrowserPlatformDelegate::WasHidden(bool hidden) {
NOTREACHED();
}

View File

@@ -57,12 +57,15 @@ class Size;
class Vector2d;
} // namespace gfx
#if defined(TOOLKIT_VIEWS)
namespace views {
class Widget;
}
#endif
struct CefBrowserCreateParams;
class CefBrowserHostBase;
class CefFileDialogRunner;
class CefJavaScriptDialogRunner;
class CefMenuRunner;
@@ -170,6 +173,7 @@ class CefBrowserPlatformDelegate {
// the client, which may be NULL. May be called on multiple threads.
virtual CefWindowHandle GetHostWindowHandle() const;
#if defined(TOOLKIT_VIEWS)
// Returns the Widget owner for the browser window. Only used with windowed
// rendering.
virtual views::Widget* GetWindowWidget() const;
@@ -177,6 +181,7 @@ class CefBrowserPlatformDelegate {
// Returns the BrowserView associated with this browser. Only used with views-
// based browsers.
virtual CefRefPtr<CefBrowserView> GetBrowserView() const;
#endif
// Called after the WebContents have been created for a new popup browser
// parented to this browser but before the AlloyBrowserHostImpl is created for
@@ -265,6 +270,9 @@ class CefBrowserPlatformDelegate {
virtual CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const;
// Create the platform-specific file dialog runner.
virtual std::unique_ptr<CefFileDialogRunner> CreateFileDialogRunner();
// Create the platform-specific JavaScript dialog runner.
virtual std::unique_ptr<CefJavaScriptDialogRunner>
CreateJavaScriptDialogRunner();
@@ -280,10 +288,6 @@ class CefBrowserPlatformDelegate {
// be called on multiple threads.
virtual bool IsViewsHosted() const;
// Returns true if this delegate implements a browser with external
// (client-provided) parent window. May be called on multiple threads.
virtual bool HasExternalParent() const;
// Notify the browser that it was hidden. Only used with windowless rendering.
virtual void WasHidden(bool hidden);

View File

@@ -13,11 +13,7 @@
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_child_window.h"
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
#include "libcef/browser/chrome/views/chrome_child_window.h"
#include "libcef/browser/extensions/browser_platform_delegate_background.h"
#include "libcef/browser/views/browser_platform_delegate_views.h"
#include "libcef/features/runtime_checks.h"
#if BUILDFLAG(IS_WIN)
@@ -33,6 +29,11 @@
#error A delegate implementation is not available for your platform.
#endif
#if defined(TOOLKIT_VIEWS)
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
#include "libcef/browser/views/browser_platform_delegate_views.h"
#endif
namespace {
std::unique_ptr<CefBrowserPlatformDelegateNative> CreateNativeDelegate(
@@ -79,40 +80,40 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
&create_params.settings, is_windowless ? STATE_ENABLED : STATE_DISABLED);
if (cef::IsChromeRuntimeEnabled()) {
CefWindowInfo window_info;
if (create_params.window_info) {
window_info = *create_params.window_info;
}
// CefWindowInfo is not used in this case.
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(window_info, background_color);
if (create_params.window_info) {
// CefWindowInfo should only be set if a parent handle was specified.
DCHECK(chrome_child_window::HasParentHandle(window_info));
return std::make_unique<CefBrowserPlatformDelegateChromeChildWindow>(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
} else if (create_params.browser_view ||
create_params.popup_with_views_hosted_opener) {
// CefWindowInfo is not used in this case.
CreateNativeDelegate(CefWindowInfo(), background_color);
#if defined(TOOLKIT_VIEWS)
if (create_params.browser_view ||
create_params.popup_with_views_hosted_opener) {
return std::make_unique<CefBrowserPlatformDelegateChromeViews>(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
}
#endif
return std::make_unique<CefBrowserPlatformDelegateChrome>(
std::move(native_delegate));
}
if (create_params.browser_view ||
create_params.popup_with_views_hosted_opener) {
// CefWindowInfo is not used in this case.
if (create_params.window_info) {
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(CefWindowInfo(), background_color);
return std::make_unique<CefBrowserPlatformDelegateViews>(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
CreateNativeDelegate(*create_params.window_info.get(),
background_color);
if (is_windowless) {
REQUIRE_ALLOY_RUNTIME();
const bool use_shared_texture =
create_params.window_info &&
create_params.window_info->shared_texture_enabled;
const bool use_external_begin_frame =
create_params.window_info &&
create_params.window_info->external_begin_frame_enabled;
return CreateOSRDelegate(std::move(native_delegate), use_shared_texture,
use_external_begin_frame);
}
return std::move(native_delegate);
} else if (create_params.extension_host_type ==
extensions::mojom::ViewType::kExtensionBackgroundPage) {
// Creating a background extension host without a window.
@@ -120,23 +121,17 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
CreateNativeDelegate(CefWindowInfo(), background_color);
return std::make_unique<CefBrowserPlatformDelegateBackground>(
std::move(native_delegate));
} else if (create_params.window_info) {
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(*create_params.window_info, background_color);
if (is_windowless) {
REQUIRE_ALLOY_RUNTIME();
const bool use_shared_texture =
create_params.window_info->shared_texture_enabled;
const bool use_external_begin_frame =
create_params.window_info->external_begin_frame_enabled;
return CreateOSRDelegate(std::move(native_delegate), use_shared_texture,
use_external_begin_frame);
}
return std::move(native_delegate);
}
#if defined(TOOLKIT_VIEWS)
else {
// CefWindowInfo is not used in this case.
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(CefWindowInfo(), background_color);
return std::make_unique<CefBrowserPlatformDelegateViews>(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
}
#endif // defined(TOOLKIT_VIEWS)
NOTREACHED();
return nullptr;

View File

@@ -4,8 +4,6 @@
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
#include "libcef/browser/views/view_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "ui/display/screen.h"
@@ -42,10 +40,6 @@ void CefBrowserPlatformDelegateChrome::BrowserDestroyed(
native_delegate_->BrowserDestroyed(browser);
}
CefWindowHandle CefBrowserPlatformDelegateChrome::GetHostWindowHandle() const {
return view_util::GetWindowHandle(GetNativeWindow());
}
SkColor CefBrowserPlatformDelegateChrome::GetBackgroundColor() const {
return native_delegate_->GetBackgroundColor();
}
@@ -79,9 +73,12 @@ gfx::Point CefBrowserPlatformDelegateChrome::GetScreenPoint(
const gfx::Point& view) const {
auto screen = display::Screen::GetScreen();
gfx::NativeWindow native_window =
chrome_browser_ ? chrome_browser_->window()->GetNativeWindow() : nullptr;
// Returns screen pixel coordinates.
auto screen_rect = screen->DIPToScreenRectInWindow(
GetNativeWindow(), gfx::Rect(view, gfx::Size(0, 0)));
native_window, gfx::Rect(view, gfx::Size(0, 0)));
return screen_rect.origin();
}
@@ -107,9 +104,3 @@ gfx::Point CefBrowserPlatformDelegateChrome::GetParentScreenPoint(
void CefBrowserPlatformDelegateChrome::set_chrome_browser(Browser* browser) {
chrome_browser_ = browser;
}
gfx::NativeWindow CefBrowserPlatformDelegateChrome::GetNativeWindow() const {
if (chrome_browser_ && chrome_browser_->window())
return chrome_browser_->window()->GetNativeWindow();
return gfx::NativeWindow();
}

View File

@@ -24,7 +24,6 @@ class CefBrowserPlatformDelegateChrome
void WebContentsDestroyed(content::WebContents* web_contents) override;
void BrowserCreated(CefBrowserHostBase* browser) override;
void BrowserDestroyed(CefBrowserHostBase* browser) override;
CefWindowHandle GetHostWindowHandle() const override;
SkColor GetBackgroundColor() const override;
void SendKeyEvent(const CefKeyEvent& event) override;
void SendMouseClickEvent(const CefMouseEvent& event,
@@ -46,13 +45,7 @@ class CefBrowserPlatformDelegateChrome
void set_chrome_browser(Browser* browser);
CefBrowserPlatformDelegateNative* native_delegate() const {
return native_delegate_.get();
}
protected:
gfx::NativeWindow GetNativeWindow() const;
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate_;
Browser* chrome_browser_ = nullptr;

View File

@@ -341,8 +341,9 @@ std::unique_ptr<BrowserDelegate> BrowserDelegate::Create(
create_params = params->create_params_;
// Clear these values so they're not persisted to additional Browsers.
params->create_params_.window_info.reset();
#if defined(TOOLKIT_VIEWS)
params->create_params_.browser_view = nullptr;
#endif
}
return std::make_unique<ChromeBrowserDelegate>(browser, create_params);

View File

@@ -22,8 +22,11 @@
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#if defined(TOOLKIT_VIEWS)
#include "libcef/browser/chrome/views/chrome_browser_frame.h"
#include "libcef/browser/chrome/views/chrome_browser_view.h"
#endif
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
@@ -108,7 +111,9 @@ void ChromeBrowserHostImpl::AddNewContents(
CefBrowserCreateParams params;
params.request_context = request_context();
#if defined(TOOLKIT_VIEWS)
params.browser_view = GetBrowserView();
#endif
// Create the new Browser representation.
auto browser = CreateBrowser(params);
@@ -138,9 +143,6 @@ void ChromeBrowserHostImpl::OnSetFocus(cef_focus_source_t source) {
if (contents_delegate_->OnSetFocus(source))
return;
if (platform_delegate_)
platform_delegate_->SetFocus(true);
if (browser_) {
const int tab_index = GetCurrentTabIndex();
if (tab_index != TabStripModel::kNoTab) {
@@ -161,14 +163,15 @@ bool ChromeBrowserHostImpl::TryCloseBrowser() {
return true;
}
CefWindowHandle ChromeBrowserHostImpl::GetWindowHandle() {
if (CEF_CURRENTLY_ON_UIT()) {
// Always return the most up-to-date window handle for a views-hosted
// browser since it may change if the view is re-parented.
if (platform_delegate_)
return platform_delegate_->GetHostWindowHandle();
void ChromeBrowserHostImpl::SetFocus(bool focus) {
if (focus) {
OnSetFocus(FOCUS_SOURCE_SYSTEM);
}
return host_window_handle_;
}
CefWindowHandle ChromeBrowserHostImpl::GetWindowHandle() {
NOTIMPLEMENTED();
return kNullWindowHandle;
}
CefWindowHandle ChromeBrowserHostImpl::GetOpenerWindowHandle() {
@@ -185,6 +188,17 @@ void ChromeBrowserHostImpl::SetZoomLevel(double zoomLevel) {
NOTIMPLEMENTED();
}
void ChromeBrowserHostImpl::RunFileDialog(
FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback) {
NOTIMPLEMENTED();
callback->OnFileDialogDismissed(0, {});
}
void ChromeBrowserHostImpl::Print() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&ChromeBrowserHostImpl::Print, this));
@@ -268,6 +282,10 @@ void ChromeBrowserHostImpl::SendCaptureLostEvent() {
NOTIMPLEMENTED();
}
void ChromeBrowserHostImpl::NotifyMoveOrResizeStarted() {
NOTIMPLEMENTED();
}
int ChromeBrowserHostImpl::GetWindowlessFrameRate() {
return 0;
}
@@ -418,6 +436,7 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
// Pass |params| to cef::BrowserDelegate::Create from the Browser constructor.
chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params);
#if defined(TOOLKIT_VIEWS)
// Configure Browser creation to use the existing Views-based
// Widget/BrowserFrame (ChromeBrowserFrame) and BrowserView/BrowserWindow
// (ChromeBrowserView). See views/chrome_browser_frame.h for related
@@ -440,6 +459,7 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
static_cast<ChromeBrowserFrame*>(chrome_browser_view->GetWidget());
chrome_browser_view->set_frame(chrome_widget);
}
#endif // defined(TOOLKIT_VIEWS)
// Create the Browser. This will indirectly create the ChomeBrowserDelegate.
// The same params will be used to create a new Browser if the tab is dragged
@@ -449,6 +469,7 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
bool show_browser = true;
#if defined(TOOLKIT_VIEWS)
if (chrome_browser_view) {
// Initialize the BrowserFrame and BrowserView and create the controls that
// require access to the Browser.
@@ -458,6 +479,7 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
// Don't show the browser by default.
show_browser = false;
}
#endif
if (show_browser) {
browser->window()->Show();
@@ -491,20 +513,7 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
// Notify that the browser has been created. These must be delivered in the
// expected order.
if (opener && opener->platform_delegate_) {
// 1. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
// We want to call this method first because the implementation will often
// create the Widget for the new popup browser. Without that Widget
// CefBrowserHost::GetWindowHandle() will return kNullWindowHandle in
// OnAfterCreated(), which breaks client expectations (e.g. clients expect
// everything about the browser to be valid at that time).
opener->platform_delegate_->PopupBrowserCreated(
this,
/*is_devtools_popup=*/false);
}
// 2. Notify the browser's LifeSpanHandler. This must always be the first
// 1. Notify the browser's LifeSpanHandler. This must always be the first
// notification for the browser.
{
// The WebContents won't be added to the Browser's TabStripModel until later
@@ -513,9 +522,17 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
OnAfterCreated();
}
// 3. Notify the platform delegate. With Views this will result in a call to
// 2. Notify the platform delegate. With Views this will result in a call to
// CefBrowserViewDelegate::OnBrowserCreated().
platform_delegate_->NotifyBrowserCreated();
if (opener && opener->platform_delegate_) {
// 3. Notify the opener browser's platform delegate. With Views this will
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
opener->platform_delegate_->PopupBrowserCreated(
this,
/*is_devtools_popup=*/false);
}
}
void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
@@ -523,17 +540,17 @@ void ChromeBrowserHostImpl::SetBrowser(Browser* browser) {
browser_ = browser;
static_cast<CefBrowserPlatformDelegateChrome*>(platform_delegate_.get())
->set_chrome_browser(browser);
if (browser_)
host_window_handle_ = platform_delegate_->GetHostWindowHandle();
}
void ChromeBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT();
#if defined(TOOLKIT_VIEWS)
if (browser_ && is_views_hosted_) {
auto chrome_browser_view =
static_cast<ChromeBrowserView*>(browser_->window());
chrome_browser_view->Destroyed();
}
#endif
platform_delegate_->CloseHostWindow();
}

View File

@@ -62,10 +62,17 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
// CefBrowserHost methods:
void CloseBrowser(bool force_close) override;
bool TryCloseBrowser() override;
void SetFocus(bool focus) override;
CefWindowHandle GetWindowHandle() override;
CefWindowHandle GetOpenerWindowHandle() override;
double GetZoomLevel() override;
void SetZoomLevel(double zoomLevel) override;
void RunFileDialog(FileDialogMode mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback) override;
void Print() override;
void PrintToPDF(const CefString& path,
const CefPdfPrintSettings& settings,
@@ -89,6 +96,7 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
void SendExternalBeginFrame() override;
void SendTouchEvent(const CefTouchEvent& event) override;
void SendCaptureLostEvent() override;
void NotifyMoveOrResizeStarted() override;
int GetWindowlessFrameRate() override;
void SetWindowlessFrameRate(int frame_rate) override;
void ImeSetComposition(const CefString& text,
@@ -159,7 +167,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
int GetCurrentTabIndex() const;
Browser* browser_ = nullptr;
CefWindowHandle host_window_handle_ = kNullWindowHandle;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_HOST_IMPL_H_

View File

@@ -6,7 +6,6 @@
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
#include "libcef/browser/context.h"
#include "libcef/browser/file_dialog_runner.h"
#include "libcef/browser/net/chrome_scheme_handler.h"
#include "base/task/post_task.h"
@@ -42,5 +41,4 @@ void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() {
scheme::RegisterWebUIControllerFactory();
context_menu::RegisterMenuCreatedCallback();
file_dialog_runner::RegisterFactory();
}

View File

@@ -1,29 +0,0 @@
// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_child_window.h"
#include "include/views/cef_browser_view.h"
#include "libcef/browser/chrome/views/chrome_child_window.h"
CefBrowserPlatformDelegateChromeChildWindow::
CefBrowserPlatformDelegateChromeChildWindow(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view)
: CefBrowserPlatformDelegateChromeViews(std::move(native_delegate),
browser_view) {}
void CefBrowserPlatformDelegateChromeChildWindow::CloseHostWindow() {
native_delegate_->CloseHostWindow();
}
void CefBrowserPlatformDelegateChromeChildWindow::SetFocus(bool focus) {
native_delegate_->SetFocus(focus);
}
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))
void CefBrowserPlatformDelegateChromeChildWindow::NotifyMoveOrResizeStarted() {
native_delegate_->NotifyMoveOrResizeStarted();
}
#endif

View File

@@ -1,29 +0,0 @@
// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_CHILD_WINDOW_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_CHILD_WINDOW_H_
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
// Implementation of Chrome-based browser functionality.
class CefBrowserPlatformDelegateChromeChildWindow
: public CefBrowserPlatformDelegateChromeViews {
public:
CefBrowserPlatformDelegateChromeChildWindow(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view);
// CefBrowserPlatformDelegate overrides.
void CloseHostWindow() override;
void SetFocus(bool focus) override;
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))
void NotifyMoveOrResizeStarted() override;
#endif
bool HasExternalParent() const override { return true; }
};
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_CHILD_WINDOW_H_

View File

@@ -95,11 +95,6 @@ void CefBrowserPlatformDelegateChromeViews::CloseHostWindow() {
widget->Close();
}
CefWindowHandle CefBrowserPlatformDelegateChromeViews::GetHostWindowHandle()
const {
return view_util::GetWindowHandle(GetWindowWidget());
}
views::Widget* CefBrowserPlatformDelegateChromeViews::GetWindowWidget() const {
if (browser_view_->root_view())
return browser_view_->root_view()->GetWidget();
@@ -117,11 +112,7 @@ void CefBrowserPlatformDelegateChromeViews::PopupWebContentsCreated(
content::WebContents* new_web_contents,
CefBrowserPlatformDelegate* new_platform_delegate,
bool is_devtools) {
// Default popup handling may not be Views-hosted.
if (!new_platform_delegate->IsViewsHosted()) {
return;
}
DCHECK(new_platform_delegate->IsViewsHosted());
auto* new_platform_delegate_impl =
static_cast<CefBrowserPlatformDelegateChromeViews*>(
new_platform_delegate);
@@ -143,11 +134,6 @@ void CefBrowserPlatformDelegateChromeViews::PopupWebContentsCreated(
void CefBrowserPlatformDelegateChromeViews::PopupBrowserCreated(
CefBrowserHostBase* new_browser,
bool is_devtools) {
// Default popup handling may not be Views-hosted.
if (!new_browser->HasView()) {
return;
}
CefRefPtr<CefBrowserView> new_browser_view =
CefBrowserView::GetForBrowser(new_browser);
DCHECK(new_browser_view);

View File

@@ -24,7 +24,6 @@ class CefBrowserPlatformDelegateChromeViews
void NotifyBrowserDestroyed() override;
void BrowserDestroyed(CefBrowserHostBase* browser) override;
void CloseHostWindow() override;
CefWindowHandle GetHostWindowHandle() const override;
views::Widget* GetWindowWidget() const override;
CefRefPtr<CefBrowserView> GetBrowserView() const override;
void PopupWebContentsCreated(
@@ -37,8 +36,6 @@ class CefBrowserPlatformDelegateChromeViews
bool is_devtools) override;
bool IsViewsHosted() const override;
CefRefPtr<CefBrowserViewImpl> browser_view() const { return browser_view_; }
private:
void SetBrowserView(CefRefPtr<CefBrowserViewImpl> browser_view);

View File

@@ -1,199 +0,0 @@
// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#include "libcef/browser/chrome/views/chrome_child_window.h"
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/browser/views/window_impl.h"
#if BUILDFLAG(IS_WIN)
#include "libcef/browser/native/browser_platform_delegate_native_win.h"
#include "ui/views/win/hwnd_util.h"
#endif
namespace {
class ChildWindowDelegate : public CefWindowDelegate {
public:
ChildWindowDelegate(const ChildWindowDelegate&) = delete;
ChildWindowDelegate& operator=(const ChildWindowDelegate&) = delete;
static void Create(CefRefPtr<CefBrowserView> browser_view,
const CefWindowInfo& window_info,
gfx::AcceleratedWidget parent_handle) {
DCHECK(parent_handle != gfx::kNullAcceleratedWidget);
// Create the Window. It will show itself after creation.
CefWindowImpl::Create(new ChildWindowDelegate(browser_view, window_info),
parent_handle);
}
void OnWindowCreated(CefRefPtr<CefWindow> window) override {
DCHECK(!window_);
window_ = window;
// Add the browser view. It will now have an associated Widget.
window_->AddChildView(browser_view_);
ShowWindow();
}
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
browser_view_ = nullptr;
window_ = nullptr;
}
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override {
CefRect initial_bounds(window_info_.bounds);
if (initial_bounds.IsEmpty())
return CefRect(0, 0, 800, 600);
return initial_bounds;
}
void ShowWindow() {
#if BUILDFLAG(IS_WIN)
auto widget = static_cast<CefWindowImpl*>(window_.get())->widget();
DCHECK(widget);
const HWND widget_hwnd = HWNDForWidget(widget);
DCHECK(widget_hwnd);
// The native delegate needs state to perform some actions.
auto browser =
static_cast<CefBrowserHostBase*>(browser_view_->GetBrowser().get());
auto platform_delegate = browser->platform_delegate();
DCHECK(platform_delegate->IsViewsHosted());
auto chrome_delegate =
static_cast<CefBrowserPlatformDelegateChromeViews*>(platform_delegate);
auto native_delegate = static_cast<CefBrowserPlatformDelegateNativeWin*>(
chrome_delegate->native_delegate());
native_delegate->set_widget(widget, widget_hwnd);
if (window_info_.ex_style & WS_EX_NOACTIVATE) {
const DWORD widget_ex_styles = GetWindowLongPtr(widget_hwnd, GWL_EXSTYLE);
// Add the WS_EX_NOACTIVATE style on the DesktopWindowTreeHostWin HWND
// so that HWNDMessageHandler::Show() called via Widget::Show() does not
// activate the window.
SetWindowLongPtr(widget_hwnd, GWL_EXSTYLE,
widget_ex_styles | WS_EX_NOACTIVATE);
window_->Show();
// Remove the WS_EX_NOACTIVATE style so that future mouse clicks inside
// the browser correctly activate and focus the window.
SetWindowLongPtr(widget_hwnd, GWL_EXSTYLE, widget_ex_styles);
return;
}
#endif // BUILDFLAG(IS_WIN)
window_->Show();
// Give keyboard focus to the browser view.
browser_view_->RequestFocus();
}
private:
ChildWindowDelegate(CefRefPtr<CefBrowserView> browser_view,
const CefWindowInfo& window_info)
: browser_view_(browser_view), window_info_(window_info) {}
CefRefPtr<CefBrowserView> browser_view_;
const CefWindowInfo window_info_;
CefRefPtr<CefWindow> window_;
IMPLEMENT_REFCOUNTING(ChildWindowDelegate);
};
class ChildBrowserViewDelegate : public CefBrowserViewDelegate {
public:
ChildBrowserViewDelegate() = default;
ChildBrowserViewDelegate(const ChildBrowserViewDelegate&) = delete;
ChildBrowserViewDelegate& operator=(const ChildBrowserViewDelegate&) = delete;
CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
CefRefPtr<CefBrowserView> browser_view,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
bool is_devtools) override {
return new ChildBrowserViewDelegate();
}
bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
CefRefPtr<CefBrowserView> popup_browser_view,
bool is_devtools) override {
DCHECK(!is_devtools);
auto new_browser = static_cast<CefBrowserHostBase*>(
popup_browser_view->GetBrowser().get());
auto new_platform_delegate = new_browser->platform_delegate();
DCHECK(new_platform_delegate->IsViewsHosted());
auto new_platform_delegate_impl =
static_cast<CefBrowserPlatformDelegateChromeViews*>(
new_platform_delegate);
const auto& window_info =
new_platform_delegate_impl->native_delegate()->window_info();
const auto parent_handle =
chrome_child_window::GetParentHandle(window_info);
if (parent_handle != gfx::kNullAcceleratedWidget) {
ChildWindowDelegate::Create(popup_browser_view, window_info,
parent_handle);
return true;
}
// Use the default implementation that creates a new Views-hosted top-level
// window.
return false;
}
private:
IMPLEMENT_REFCOUNTING(ChildBrowserViewDelegate);
};
} // namespace
namespace chrome_child_window {
bool HasParentHandle(const CefWindowInfo& window_info) {
return GetParentHandle(window_info) != gfx::kNullAcceleratedWidget;
}
gfx::AcceleratedWidget GetParentHandle(const CefWindowInfo& window_info) {
#if !BUILDFLAG(IS_MAC)
return window_info.parent_window;
#else
return gfx::kNullAcceleratedWidget;
#endif
}
CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
const CefBrowserCreateParams& create_params) {
// If the BrowserView already exists it means that we're dealing with a popup
// and we'll instead create the Window in OnPopupBrowserViewCreated.
if (create_params.browser_view)
return nullptr;
if (!create_params.window_info)
return nullptr;
const auto parent_handle = GetParentHandle(*create_params.window_info);
if (parent_handle == gfx::kNullAcceleratedWidget)
return nullptr;
// Create the BrowserView.
auto browser_view = CefBrowserViewImpl::Create(
*create_params.window_info, create_params.client, create_params.url,
create_params.settings, create_params.extra_info,
create_params.request_context, new ChildBrowserViewDelegate());
ChildWindowDelegate::Create(browser_view, *create_params.window_info,
parent_handle);
return static_cast<CefBrowserHostBase*>(browser_view->GetBrowser().get());
}
} // namespace chrome_child_window

View File

@@ -1,24 +0,0 @@
// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_CHILD_WINDOW_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_CHILD_WINDOW_H_
#pragma once
#include "libcef/browser/browser_host_base.h"
#include "ui/gfx/native_widget_types.h"
namespace chrome_child_window {
bool HasParentHandle(const CefWindowInfo& window_info);
gfx::AcceleratedWidget GetParentHandle(const CefWindowInfo& window_info);
// Called from CefBrowserHostBase::Create.
CefRefPtr<CefBrowserHostBase> MaybeCreateChildBrowser(
const CefBrowserCreateParams& create_params);
} // namespace chrome_child_window
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_CHILD_WINDOW_H_

View File

@@ -106,7 +106,7 @@ void CefDevToolsFileManager::Save(const std::string& url,
}
}
blink::mojom::FileChooserParams params;
CefFileDialogRunner::FileChooserParams params;
params.mode = blink::mojom::FileChooserParams::Mode::kSave;
if (!initial_path.empty()) {
params.default_file_name = initial_path;
@@ -115,7 +115,7 @@ void CefDevToolsFileManager::Save(const std::string& url,
}
}
browser_impl_->RunFileChooserForBrowser(
browser_impl_->RunFileChooser(
params,
base::BindOnce(&CefDevToolsFileManager::SaveAsDialogDismissed,
weak_factory_.GetWeakPtr(), url, content,
@@ -127,6 +127,7 @@ void CefDevToolsFileManager::SaveAsDialogDismissed(
const std::string& content,
SaveCallback saveCallback,
CancelCallback cancelCallback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
if (file_paths.size() == 1) {
SaveAsFileSelected(url, content, std::move(saveCallback), file_paths[0]);

View File

@@ -49,6 +49,7 @@ class CefDevToolsFileManager {
const std::string& content,
SaveCallback saveCallback,
CancelCallback cancelCallback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths);
void SaveAsFileSelected(const std::string& url,
const std::string& content,

View File

@@ -251,11 +251,8 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
}
CefBrowserCreateParams create_params;
if (inspected_browser->is_views_hosted()) {
create_params.popup_with_views_hosted_opener = true;
} else {
if (!inspected_browser->is_views_hosted())
create_params.window_info.reset(new CefWindowInfo(windowInfo));
}
create_params.client = client;
create_params.settings = new_settings;
create_params.devtools_opener = inspected_browser;
@@ -595,7 +592,7 @@ void CefDevToolsFrontend::CallClientFunction(
web_contents()->GetMainFrame()->AllowInjectingJavaScript();
base::Value::List arguments;
base::Value arguments(base::Value::Type::LIST);
if (!arg1.is_none()) {
arguments.Append(std::move(arg1));
if (!arg2.is_none()) {

View File

@@ -30,7 +30,7 @@ bool ParseEvent(const base::StringPiece& message,
const size_t method_start = sizeof(kMethodStart) - 1;
const size_t method_end = message.find(kMethodEnd, method_start);
if (method_end == base::StringPiece::npos)
if (method_end < 0U)
return false;
method = message.substr(method_start, method_end - method_start);
if (method.empty())
@@ -77,7 +77,7 @@ bool ParseResult(const base::StringPiece& message,
const size_t id_start = sizeof(kIdStart) - 1;
const size_t id_end = message.find(kIdEnd, id_start);
if (id_end == base::StringPiece::npos)
if (id_end < 0U)
return false;
const base::StringPiece& id_str = message.substr(id_start, id_end - id_start);
if (id_str.empty() || !base::StringToInt(id_str, &message_id))

View File

@@ -83,7 +83,7 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsEvent) {
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsEvent());
EXPECT_EQ("Test.myMethod", parser.method_);
EXPECT_STREQ("Test.myMethod", parser.method_.data());
EXPECT_TRUE(parser.params_.empty());
parser.Reset();
@@ -94,8 +94,8 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsEvent) {
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsEvent());
EXPECT_EQ("Test.myMethod2", parser.method_);
EXPECT_EQ("{}", parser.params_);
EXPECT_STREQ("Test.myMethod2", parser.method_.data());
EXPECT_STREQ("{}", parser.params_.data());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
@@ -105,8 +105,8 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsEvent) {
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsInitialized());
EXPECT_TRUE(parser.IsEvent());
EXPECT_EQ("Test.myMethod3", parser.method_);
EXPECT_EQ("{\"foo\":\"bar\"}", parser.params_);
EXPECT_STREQ("Test.myMethod3", parser.method_.data());
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.data());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsFailure_ResultMalformed) {
@@ -162,7 +162,7 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Result) {
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(1, parser.message_id_);
EXPECT_TRUE(parser.success_);
EXPECT_EQ("{}", parser.params_);
EXPECT_STREQ("{}", parser.params_.data());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
@@ -174,7 +174,7 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Result) {
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(2, parser.message_id_);
EXPECT_TRUE(parser.success_);
EXPECT_EQ("{\"foo\":\"bar\"}", parser.params_);
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.data());
}
TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Error) {
@@ -188,7 +188,7 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Error) {
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(1, parser.message_id_);
EXPECT_FALSE(parser.success_);
EXPECT_EQ("{}", parser.params_);
EXPECT_STREQ("{}", parser.params_.data());
parser.Reset();
EXPECT_FALSE(parser.IsInitialized());
@@ -200,21 +200,5 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Error) {
EXPECT_TRUE(parser.IsResult());
EXPECT_EQ(2, parser.message_id_);
EXPECT_FALSE(parser.success_);
EXPECT_EQ("{\"foo\":\"bar\"}", parser.params_);
}
TEST(DevToolsUtil, ProtocolParser_Can_Handle_MissingQuote) {
ProtocolParser parser;
const auto message = "{\"method\":\"Test.myMethod}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsFailure());
}
TEST(DevToolsUtil, ProtocolParser_Can_Handle_MissingComma) {
ProtocolParser parser;
const auto message = "{\"id\":1\"error\":{}}";
EXPECT_TRUE(parser.Initialize(message));
EXPECT_TRUE(parser.IsFailure());
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.data());
}

View File

@@ -136,7 +136,7 @@ class CefBeforeDownloadCallbackImpl : public CefBeforeDownloadCallback {
if (browser.get()) {
handled = true;
blink::mojom::FileChooserParams params;
CefFileDialogRunner::FileChooserParams params;
params.mode = blink::mojom::FileChooserParams::Mode::kSave;
if (!suggested_path.empty()) {
params.default_file_name = suggested_path;
@@ -146,7 +146,7 @@ class CefBeforeDownloadCallbackImpl : public CefBeforeDownloadCallback {
}
}
browser->RunFileChooserForBrowser(
browser->RunFileChooser(
params,
base::BindOnce(
&CefBeforeDownloadCallbackImpl::ChooseDownloadPathCallback,
@@ -166,6 +166,7 @@ class CefBeforeDownloadCallbackImpl : public CefBeforeDownloadCallback {
static void ChooseDownloadPathCallback(
content::DownloadTargetCallback callback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
DCHECK_LE(file_paths.size(), (size_t)1);

View File

@@ -4,14 +4,18 @@
#include "libcef/browser/extensions/api/file_system/cef_file_system_delegate.h"
#include "libcef/browser/alloy/alloy_dialog_util.h"
#include "apps/saved_files_service.h"
#include "base/callback.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "chrome/browser/extensions/api/file_system/file_entry_picker.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/web_contents.h"
#include "extensions/common/api/file_system.h"
#include "extensions/common/extension.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
using blink::mojom::FileChooserParams;
namespace extensions {
namespace cef {
@@ -42,17 +46,61 @@ bool CefFileSystemDelegate::ShowSelectFileDialog(
return false;
}
// The file picker will hold a reference to the ExtensionFunction
// instance, preventing its destruction (and subsequent sending of the
// function response) until the user has selected a file or cancelled the
// picker. At that point, the picker will delete itself, which will also free
// the function instance.
new FileEntryPicker(web_contents, default_path, *file_types, type,
std::move(files_selected_callback),
std::move(file_selection_canceled_callback));
absl::optional<FileChooserParams::Mode> mode;
switch (type) {
case ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER:
mode = FileChooserParams::Mode::kUploadFolder;
break;
case ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE:
mode = FileChooserParams::Mode::kSave;
break;
case ui::SelectFileDialog::Type::SELECT_OPEN_FILE:
mode = FileChooserParams::Mode::kOpen;
break;
case ui::SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE:
mode = FileChooserParams::Mode::kOpenMultiple;
break;
default:
NOTIMPLEMENTED();
return false;
}
FileChooserParams params;
params.mode = *mode;
params.default_file_name = default_path;
if (file_types) {
// A list of allowed extensions. For example, it might be
// { { "htm", "html" }, { "txt" } }
for (auto& vec : file_types->extensions) {
for (auto& ext : vec) {
params.accept_types.push_back(
alloy::FilePathTypeToString16(FILE_PATH_LITERAL(".") + ext));
}
}
}
alloy::RunFileChooser(
web_contents, params,
base::BindOnce(&CefFileSystemDelegate::FileDialogDismissed,
weak_ptr_factory_.GetWeakPtr(),
std::move(files_selected_callback),
std::move(file_selection_canceled_callback)));
return true;
}
void CefFileSystemDelegate::FileDialogDismissed(
FileSystemDelegate::FilesSelectedCallback files_selected_callback,
base::OnceClosure file_selection_canceled_callback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
if (!file_paths.empty()) {
std::move(files_selected_callback).Run(file_paths);
} else {
std::move(file_selection_canceled_callback).Run();
}
}
void CefFileSystemDelegate::ConfirmSensitiveDirectoryAccess(
bool has_write_permission,
const std::u16string& app_name,

View File

@@ -10,6 +10,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "extensions/browser/api/execute_code_function.h"
#include "extensions/browser/api/file_system/file_system_delegate.h"
#include "extensions/browser/extension_function.h"
@@ -50,6 +51,15 @@ class CefFileSystemDelegate : public FileSystemDelegate {
int GetDescriptionIdForAcceptType(const std::string& accept_type) override;
SavedFilesServiceInterface* GetSavedFilesService(
content::BrowserContext* browser_context) override;
private:
void FileDialogDismissed(
FileSystemDelegate::FilesSelectedCallback files_selected_callback,
base::OnceClosure file_selection_canceled_callback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths);
base::WeakPtrFactory<CefFileSystemDelegate> weak_ptr_factory_{this};
};
} // namespace cef

View File

@@ -102,6 +102,11 @@ CefEventHandle CefBrowserPlatformDelegateBackground::GetEventHandle(
return native_delegate_->GetEventHandle(event);
}
std::unique_ptr<CefFileDialogRunner>
CefBrowserPlatformDelegateBackground::CreateFileDialogRunner() {
return native_delegate_->CreateFileDialogRunner();
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateBackground::CreateJavaScriptDialogRunner() {
return native_delegate_->CreateJavaScriptDialogRunner();

View File

@@ -40,6 +40,7 @@ class CefBrowserPlatformDelegateBackground
const content::NativeWebKeyboardEvent& event) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
std::unique_ptr<CefFileDialogRunner> CreateFileDialogRunner() override;
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;

View File

@@ -27,8 +27,8 @@ CefComponentExtensionResourceManager::CefComponentExtensionResourceManager() {
pdf_extension_util::AddAdditionalData(/*enable_annotations=*/true, &dict);
ui::TemplateReplacements pdf_viewer_replacements;
ui::TemplateReplacementsFromDictionaryValue(dict.GetDict(),
&pdf_viewer_replacements);
ui::TemplateReplacementsFromDictionaryValue(
base::Value::AsDictionaryValue(dict), &pdf_viewer_replacements);
template_replacements_[extension_misc::kPdfExtensionId] =
std::move(pdf_viewer_replacements);
}

View File

@@ -381,7 +381,6 @@ base::DictionaryValue* CefExtensionFunctionDetails::OpenTab(
if (active_browser->is_views_hosted()) {
// The new browser will also be Views hosted.
create_params.popup_with_views_hosted_opener = true;
create_params.window_info.reset();
}

View File

@@ -90,7 +90,8 @@ class CefKioskDelegate : public extensions::KioskDelegate {
} // namespace
CefExtensionsBrowserClient::CefExtensionsBrowserClient()
: api_client_(new CefExtensionsAPIClient) {
: api_client_(new CefExtensionsAPIClient),
resource_manager_(new CefComponentExtensionResourceManager) {
AddAPIProvider(std::make_unique<CoreExtensionsBrowserAPIProvider>());
AddAPIProvider(std::make_unique<CefExtensionsBrowserAPIProvider>());
}
@@ -331,10 +332,6 @@ CefExtensionsBrowserClient::CreateRuntimeAPIDelegate(
const ComponentExtensionResourceManager*
CefExtensionsBrowserClient::GetComponentExtensionResourceManager() {
if (!resource_manager_) {
resource_manager_ =
std::make_unique<CefComponentExtensionResourceManager>();
}
return resource_manager_.get();
}

View File

@@ -8,22 +8,18 @@
#include <utility>
#include "include/cef_dialog_handler.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/context.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/thread_util.h"
#include "chrome/browser/file_select_helper.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/render_frame_host.h"
#include "ui/shell_dialogs/select_file_policy.h"
using blink::mojom::FileChooserParams;
#include "net/base/directory_lister.h"
namespace {
class CefFileDialogCallbackImpl : public CefFileDialogCallback {
public:
using CallbackType = CefFileDialogManager::RunFileChooserCallback;
using CallbackType = CefFileDialogRunner::RunFileChooserCallback;
explicit CefFileDialogCallbackImpl(CallbackType callback)
: callback_(std::move(callback)) {}
@@ -41,7 +37,8 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
}
}
void Continue(const std::vector<CefString>& file_paths) override {
void Continue(int selected_accept_filter,
const std::vector<CefString>& file_paths) override {
if (CEF_CURRENTLY_ON_UIT()) {
if (!callback_.is_null()) {
std::vector<base::FilePath> vec;
@@ -50,12 +47,12 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
for (; it != file_paths.end(); ++it)
vec.push_back(base::FilePath(*it));
}
std::move(callback_).Run(vec);
std::move(callback_).Run(selected_accept_filter, vec);
}
} else {
CEF_POST_TASK(CEF_UIT,
base::BindOnce(&CefFileDialogCallbackImpl::Continue, this,
file_paths));
selected_accept_filter, file_paths));
}
}
@@ -76,7 +73,7 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
static void CancelNow(CallbackType callback) {
CEF_REQUIRE_UIT();
std::vector<base::FilePath> file_paths;
std::move(callback).Run(file_paths);
std::move(callback).Run(0, file_paths);
}
CallbackType callback_;
@@ -85,210 +82,77 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
};
void RunFileDialogDismissed(CefRefPtr<CefRunFileDialogCallback> callback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
std::vector<CefString> paths;
if (file_paths.size() > 0) {
for (size_t i = 0; i < file_paths.size(); ++i)
paths.push_back(file_paths[i].value());
}
callback->OnFileDialogDismissed(paths);
callback->OnFileDialogDismissed(selected_accept_filter, paths);
}
// Based on net/base/filename_util_internal.cc FilePathToString16().
std::u16string FilePathTypeToString16(const base::FilePath::StringType& str) {
std::u16string result;
#if BUILDFLAG(IS_WIN)
result.assign(str.begin(), str.end());
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
if (!str.empty()) {
base::UTF8ToUTF16(str.c_str(), str.size(), &result);
}
#endif
return result;
}
FileChooserParams SelectFileToFileChooserParams(
ui::SelectFileDialog::Type type,
const std::u16string& title,
const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types) {
FileChooserParams params;
absl::optional<FileChooserParams::Mode> mode;
switch (type) {
case ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER:
mode = FileChooserParams::Mode::kUploadFolder;
break;
case ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE:
mode = FileChooserParams::Mode::kSave;
break;
case ui::SelectFileDialog::Type::SELECT_OPEN_FILE:
mode = FileChooserParams::Mode::kOpen;
break;
case ui::SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE:
mode = FileChooserParams::Mode::kOpenMultiple;
break;
default:
NOTIMPLEMENTED();
return params;
}
params.mode = *mode;
params.title = title;
params.default_file_name = default_path;
// Note that this translation will lose any mime-type based filters that
// may have existed in the original FileChooserParams::accept_types if this
// dialog was created via FileSelectHelper::RunFileChooser.
if (file_types) {
// A list of allowed extensions. For example, it might be
// { { "htm", "html" }, { "txt" } }
for (auto& vec : file_types->extensions) {
for (auto& ext : vec) {
params.accept_types.push_back(
FilePathTypeToString16(FILE_PATH_LITERAL(".") + ext));
}
}
}
return params;
}
class CefFileSelectListener : public content::FileSelectListener {
class UploadFolderHelper
: public net::DirectoryLister::DirectoryListerDelegate {
public:
using CallbackType = CefFileDialogManager::RunFileChooserCallback;
explicit CefFileSelectListener(CallbackType callback)
explicit UploadFolderHelper(
CefFileDialogRunner::RunFileChooserCallback callback)
: callback_(std::move(callback)) {}
private:
~CefFileSelectListener() override = default;
UploadFolderHelper(const UploadFolderHelper&) = delete;
UploadFolderHelper& operator=(const UploadFolderHelper&) = delete;
void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
const base::FilePath& base_dir,
FileChooserParams::Mode mode) override {
std::vector<base::FilePath> paths;
if (mode == FileChooserParams::Mode::kUploadFolder) {
if (!base_dir.empty()) {
paths.push_back(base_dir);
}
} else if (!files.empty()) {
for (auto& file : files) {
if (file->is_native_file()) {
paths.push_back(file->get_native_file()->file_path);
} else {
NOTIMPLEMENTED();
}
~UploadFolderHelper() override {
if (!callback_.is_null()) {
if (CEF_CURRENTLY_ON_UIT()) {
CancelNow(std::move(callback_));
} else {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&UploadFolderHelper::CancelNow,
std::move(callback_)));
}
}
std::move(callback_).Run(paths);
}
void FileSelectionCanceled() override { std::move(callback_).Run({}); }
void OnListFile(
const net::DirectoryLister::DirectoryListerData& data) override {
CEF_REQUIRE_UIT();
if (!data.info.IsDirectory())
select_files_.push_back(data.path);
}
CallbackType callback_;
void OnListDone(int error) override {
CEF_REQUIRE_UIT();
if (!callback_.is_null()) {
std::move(callback_).Run(0, select_files_);
}
}
private:
static void CancelNow(CefFileDialogRunner::RunFileChooserCallback callback) {
CEF_REQUIRE_UIT();
std::vector<base::FilePath> file_paths;
std::move(callback).Run(0, file_paths);
}
CefFileDialogRunner::RunFileChooserCallback callback_;
std::vector<base::FilePath> select_files_;
};
} // namespace
class CefSelectFileDialogListener : public ui::SelectFileDialog::Listener {
public:
CefSelectFileDialogListener(ui::SelectFileDialog::Listener* listener,
void* params,
base::OnceClosure callback)
: listener_(listener), params_(params), callback_(std::move(callback)) {}
CefFileDialogManager::CefFileDialogManager(
AlloyBrowserHostImpl* browser,
std::unique_ptr<CefFileDialogRunner> runner)
: browser_(browser),
runner_(std::move(runner)),
file_chooser_pending_(false),
weak_ptr_factory_(this) {}
CefSelectFileDialogListener(const CefSelectFileDialogListener&) = delete;
CefSelectFileDialogListener& operator=(const CefSelectFileDialogListener&) =
delete;
void Cancel(bool listener_destroyed) {
if (executing_) {
// We're likely still on the stack. Do nothing and wait for Destroy().
return;
}
if (listener_destroyed) {
// Don't execute the listener.
Destroy();
} else {
FileSelectionCanceled(params_);
}
}
ui::SelectFileDialog::Listener* listener() const { return listener_; }
private:
~CefSelectFileDialogListener() override = default;
void FileSelected(const base::FilePath& path,
int index,
void* params) override {
DCHECK_EQ(params, params_);
executing_ = true;
listener_->FileSelected(path, index, params);
Destroy();
}
void FileSelectedWithExtraInfo(const ui::SelectedFileInfo& file,
int index,
void* params) override {
DCHECK_EQ(params, params_);
executing_ = true;
listener_->FileSelectedWithExtraInfo(file, index, params);
Destroy();
}
void MultiFilesSelected(const std::vector<base::FilePath>& files,
void* params) override {
DCHECK_EQ(params, params_);
executing_ = true;
listener_->MultiFilesSelected(files, params);
Destroy();
}
void MultiFilesSelectedWithExtraInfo(
const std::vector<ui::SelectedFileInfo>& files,
void* params) override {
DCHECK_EQ(params, params_);
executing_ = true;
listener_->MultiFilesSelectedWithExtraInfo(files, params);
Destroy();
}
void FileSelectionCanceled(void* params) override {
DCHECK_EQ(params, params_);
executing_ = true;
listener_->FileSelectionCanceled(params);
Destroy();
}
void Destroy() {
std::move(callback_).Run();
delete this;
}
ui::SelectFileDialog::Listener* const listener_;
void* const params_;
base::OnceClosure callback_;
// Used to avoid re-entrancy from Cancel().
bool executing_ = false;
};
CefFileDialogManager::CefFileDialogManager(CefBrowserHostBase* browser)
: browser_(browser) {}
CefFileDialogManager::~CefFileDialogManager() = default;
CefFileDialogManager::~CefFileDialogManager() {}
void CefFileDialogManager::Destroy() {
if (dialog_listener_) {
// Cancel the listener and delete related objects.
SelectFileDoneByListenerCallback(/*listener_destroyed=*/false);
}
DCHECK(!dialog_);
DCHECK(!dialog_listener_);
DCHECK(active_listeners_.empty());
DCHECK(!file_chooser_pending_);
runner_.reset(nullptr);
}
void CefFileDialogManager::RunFileDialog(
@@ -296,13 +160,14 @@ void CefFileDialogManager::RunFileDialog(
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback) {
DCHECK(callback.get());
if (!callback.get())
return;
blink::mojom::FileChooserParams params;
switch (mode) {
CefFileDialogRunner::FileChooserParams params;
switch (mode & FILE_DIALOG_TYPE_MASK) {
case FILE_DIALOG_OPEN:
params.mode = blink::mojom::FileChooserParams::Mode::kOpen;
break;
@@ -317,6 +182,12 @@ void CefFileDialogManager::RunFileDialog(
break;
}
DCHECK_GE(selected_accept_filter, 0);
params.selected_accept_filter = selected_accept_filter;
params.overwriteprompt = !!(mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG);
params.hidereadonly = !!(mode & FILE_DIALOG_HIDEREADONLY_FLAG);
params.title = title;
if (!default_file_path.empty())
params.default_file_name = base::FilePath(default_file_path);
@@ -331,145 +202,55 @@ void CefFileDialogManager::RunFileDialog(
}
void CefFileDialogManager::RunFileChooser(
const blink::mojom::FileChooserParams& params,
RunFileChooserCallback callback) {
scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) {
CEF_REQUIRE_UIT();
// Execute the delegate with the most exact version of |params|. If not
// handled here there will be another call to the delegate from RunSelectFile.
// It might be better to execute the delegate only the single time here, but
// we don't currently have sufficient state in RunSelectFile to know that the
// delegate has already been executed.
callback = MaybeRunDelegate(params, std::move(callback));
if (callback.is_null()) {
// The delegate kept the callback.
return;
}
CefFileDialogRunner::FileChooserParams cef_params;
static_cast<blink::mojom::FileChooserParams&>(cef_params) = params;
FileChooserParams new_params = params;
// Make sure we get native files in CefFileSelectListener.
new_params.need_local_path = true;
// Requirements of FileSelectHelper.
if (params.mode != FileChooserParams::Mode::kSave) {
new_params.default_file_name = base::FilePath();
CefFileDialogRunner::RunFileChooserCallback callback;
if (params.mode == blink::mojom::FileChooserParams::Mode::kUploadFolder) {
callback = base::BindOnce(
&CefFileDialogManager::OnRunFileChooserUploadFolderDelegateCallback,
weak_ptr_factory_.GetWeakPtr(), params.mode, listener);
} else {
new_params.default_file_name = new_params.default_file_name.BaseName();
callback =
base::BindOnce(&CefFileDialogManager::OnRunFileChooserDelegateCallback,
weak_ptr_factory_.GetWeakPtr(), params.mode, listener);
}
// FileSelectHelper is usually only used for renderer-initiated dialogs via
// WebContentsDelegate::RunFileChooser. We choose to use it here instead of
// calling ui::SelectFileDialog::Create directly because it provides some nice
// functionality related to default dialog settings and filter list
// generation. We customize the behavior slightly for non-renderer-initiated
// dialogs by passing the |run_from_cef=true| flag. FileSelectHelper uses
// ui::SelectFileDialog::Create internally and that call will be intercepted
// by CefSelectFileDialogFactory, resulting in call to RunSelectFile below.
// See related comments on CefSelectFileDialogFactory.
FileSelectHelper::RunFileChooser(
browser_->GetWebContents()->GetMainFrame(),
base::MakeRefCounted<CefFileSelectListener>(std::move(callback)),
new_params, /*run_from_cef=*/true);
RunFileChooserInternal(cef_params, std::move(callback));
}
void CefFileDialogManager::RunSelectFile(
ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy,
ui::SelectFileDialog::Type type,
const std::u16string& title,
const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
const base::FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params) {
void CefFileDialogManager::RunFileChooser(
const CefFileDialogRunner::FileChooserParams& params,
CefFileDialogRunner::RunFileChooserCallback callback) {
CefFileDialogRunner::RunFileChooserCallback host_callback =
base::BindOnce(&CefFileDialogManager::OnRunFileChooserCallback,
weak_ptr_factory_.GetWeakPtr(), std::move(callback));
RunFileChooserInternal(params, std::move(host_callback));
}
void CefFileDialogManager::RunFileChooserInternal(
const CefFileDialogRunner::FileChooserParams& params,
CefFileDialogRunner::RunFileChooserCallback callback) {
CEF_REQUIRE_UIT();
active_listeners_.insert(listener);
// This will not be an exact representation of the original params.
auto chooser_params =
SelectFileToFileChooserParams(type, title, default_path, file_types);
auto callback =
base::BindOnce(&CefFileDialogManager::SelectFileDoneByDelegateCallback,
weak_ptr_factory_.GetWeakPtr(), base::Unretained(listener),
base::Unretained(params));
callback = MaybeRunDelegate(chooser_params, std::move(callback));
if (callback.is_null()) {
// The delegate kept the callback.
if (file_chooser_pending_) {
// Dismiss the new dialog immediately.
std::move(callback).Run(0, std::vector<base::FilePath>());
return;
}
if (dialog_) {
LOG(ERROR) << "Multiple simultaneous dialogs are not supported; "
"canceling the file dialog";
std::move(callback).Run({});
return;
}
file_chooser_pending_ = true;
#if BUILDFLAG(IS_LINUX)
// We can't use GtkUi in combination with multi-threaded-message-loop because
// Chromium's GTK implementation doesn't use GDK threads.
if (!!CefContext::Get()->settings().multi_threaded_message_loop) {
LOG(ERROR) << "Default dialog implementation is not available; "
"canceling the file dialog";
std::move(callback).Run({});
return;
}
#endif
bool handled = false;
// |callback| is no longer used at this point.
callback.Reset();
DCHECK(!dialog_listener_);
// This object will delete itself.
dialog_listener_ = new CefSelectFileDialogListener(
listener, params,
base::BindOnce(&CefFileDialogManager::SelectFileDoneByListenerCallback,
weak_ptr_factory_.GetWeakPtr(),
/*listener_destroyed=*/false));
// This call will not be intercepted by CefSelectFileDialogFactory due to the
// |run_from_cef=true| flag.
// See related comments on CefSelectFileDialogFactory.
dialog_ = ui::SelectFileDialog::Create(dialog_listener_, std::move(policy),
/*run_from_cef=*/true);
// With windowless rendering use the parent handle specified by the client.
if (browser_->IsWindowless()) {
DCHECK(!owning_window);
dialog_->set_owning_widget(browser_->GetWindowHandle());
}
dialog_->SelectFile(type, title, default_path, file_types, file_type_index,
default_extension, owning_window, params);
}
void CefFileDialogManager::SelectFileListenerDestroyed(
ui::SelectFileDialog::Listener* listener) {
CEF_REQUIRE_UIT();
DCHECK(listener);
// This notification will arrive from whomever owns |listener|, so we don't
// want to execute any |listener| methods after this point.
if (dialog_listener_ && listener == dialog_listener_->listener()) {
// Cancel the currently active dialog.
SelectFileDoneByListenerCallback(/*listener_destroyed=*/true);
} else {
// Any future SelectFileDoneByDelegateCallback call for |listener| becomes a
// no-op.
active_listeners_.erase(listener);
}
}
CefFileDialogManager::RunFileChooserCallback
CefFileDialogManager::MaybeRunDelegate(
const blink::mojom::FileChooserParams& params,
RunFileChooserCallback callback) {
if (auto client = browser_->client()) {
if (auto handler = browser_->client()->GetDialogHandler()) {
if (browser_->client().get()) {
CefRefPtr<CefDialogHandler> handler =
browser_->client()->GetDialogHandler();
if (handler.get()) {
int mode = FILE_DIALOG_OPEN;
switch (params.mode) {
case blink::mojom::FileChooserParams::Mode::kOpen:
@@ -489,6 +270,11 @@ CefFileDialogManager::MaybeRunDelegate(
break;
}
if (params.overwriteprompt)
mode |= FILE_DIALOG_OVERWRITEPROMPT_FLAG;
if (params.hidereadonly)
mode |= FILE_DIALOG_HIDEREADONLY_FLAG;
std::vector<std::u16string>::const_iterator it;
std::vector<CefString> accept_filters;
@@ -498,9 +284,10 @@ CefFileDialogManager::MaybeRunDelegate(
CefRefPtr<CefFileDialogCallbackImpl> callbackImpl(
new CefFileDialogCallbackImpl(std::move(callback)));
const bool handled = handler->OnFileDialog(
handled = handler->OnFileDialog(
browser_, static_cast<cef_file_dialog_mode_t>(mode), params.title,
params.default_file_name.value(), accept_filters, callbackImpl.get());
params.default_file_name.value(), accept_filters,
params.selected_accept_filter, callbackImpl.get());
if (!handled) {
// May return nullptr if the client has already executed the callback.
callback = callbackImpl->Disconnect();
@@ -508,57 +295,82 @@ CefFileDialogManager::MaybeRunDelegate(
}
}
return callback;
}
void CefFileDialogManager::SelectFileDoneByDelegateCallback(
ui::SelectFileDialog::Listener* listener,
void* params,
const std::vector<base::FilePath>& paths) {
CEF_REQUIRE_UIT();
// The listener may already be gone. This can occur if the client holds a
// RunFileChooserCallback past the call to SelectFileListenerDestroyed().
if (active_listeners_.find(listener) == active_listeners_.end())
return;
active_listeners_.erase(listener);
if (paths.empty()) {
listener->FileSelectionCanceled(params);
} else if (paths.size() == 1) {
listener->FileSelected(paths[0], /*index=*/0, params);
} else {
listener->MultiFilesSelected(paths, params);
if (!handled && !callback.is_null()) {
if (runner_.get()) {
runner_->Run(browser_, params, std::move(callback));
} else {
LOG(WARNING) << "No file dialog runner available for this platform";
std::move(callback).Run(0, std::vector<base::FilePath>());
}
}
// |listener| is likely deleted at this point.
}
void CefFileDialogManager::SelectFileDoneByListenerCallback(
bool listener_destroyed) {
void CefFileDialogManager::OnRunFileChooserCallback(
CefFileDialogRunner::RunFileChooserCallback callback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
CEF_REQUIRE_UIT();
// Avoid re-entrancy of this method. CefSelectFileDialogListener callbacks to
// the delegated listener may result in an immediate call to
// SelectFileListenerDestroyed() while |dialog_listener_| is still on the
// stack, followed by another execution from
// CefSelectFileDialogListener::Destroy(). Similarly, the below call to
// Cancel() may trigger another execution from
// CefSelectFileDialogListener::Destroy().
if (!dialog_listener_)
return;
Cleanup();
DCHECK(dialog_);
DCHECK(dialog_listener_);
active_listeners_.erase(dialog_listener_->listener());
// Clear |dialog_listener_| before calling Cancel() to avoid re-entrancy.
auto dialog_listener = dialog_listener_;
dialog_listener_ = nullptr;
dialog_listener->Cancel(listener_destroyed);
// There should be no further listener callbacks after this call.
dialog_->ListenerDestroyed();
dialog_ = nullptr;
// Execute the callback asynchronously.
CEF_POST_TASK(CEF_UIT, base::BindOnce(std::move(callback),
selected_accept_filter, file_paths));
}
void CefFileDialogManager::OnRunFileChooserUploadFolderDelegateCallback(
const blink::mojom::FileChooserParams::Mode mode,
scoped_refptr<content::FileSelectListener> listener,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
CEF_REQUIRE_UIT();
DCHECK_EQ(mode, blink::mojom::FileChooserParams::Mode::kUploadFolder);
if (file_paths.size() == 0) {
// Client canceled the file chooser.
OnRunFileChooserDelegateCallback(mode, listener, selected_accept_filter,
file_paths);
} else {
lister_.reset(new net::DirectoryLister(
file_paths[0], net::DirectoryLister::NO_SORT_RECURSIVE,
new UploadFolderHelper(base::BindOnce(
&CefFileDialogManager::OnRunFileChooserDelegateCallback,
weak_ptr_factory_.GetWeakPtr(), mode, listener))));
lister_->Start();
}
}
void CefFileDialogManager::OnRunFileChooserDelegateCallback(
blink::mojom::FileChooserParams::Mode mode,
scoped_refptr<content::FileSelectListener> listener,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths) {
CEF_REQUIRE_UIT();
base::FilePath base_dir;
std::vector<blink::mojom::FileChooserFileInfoPtr> selected_files;
if (!file_paths.empty()) {
if (mode == blink::mojom::FileChooserParams::Mode::kUploadFolder) {
base_dir = file_paths[0].DirName();
}
// Convert FilePath list to SelectedFileInfo list.
for (size_t i = 0; i < file_paths.size(); ++i) {
auto info = blink::mojom::FileChooserFileInfo::NewNativeFile(
blink::mojom::NativeFileInfo::New(file_paths[i], std::u16string()));
selected_files.push_back(std::move(info));
}
}
listener->FileSelected(std::move(selected_files), base_dir, mode);
Cleanup();
}
void CefFileDialogManager::Cleanup() {
if (lister_)
lister_.reset();
file_chooser_pending_ = false;
}

View File

@@ -7,25 +7,28 @@
#define CEF_LIBCEF_BROWSER_FILE_DIALOG_MANAGER_H_
#pragma once
#include <memory>
#include <set>
#include "include/cef_browser.h"
#include "libcef/browser/file_dialog_runner.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "ui/shell_dialogs/select_file_dialog.h"
#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
class FileSelectListener;
class WebContents;
} // namespace content
class CefBrowserHostBase;
class CefSelectFileDialogListener;
namespace net {
class DirectoryLister;
}
class AlloyBrowserHostImpl;
class CefFileDialogManager {
public:
explicit CefFileDialogManager(CefBrowserHostBase* browser);
// |runner| may be NULL if the platform doesn't implement dialogs.
CefFileDialogManager(AlloyBrowserHostImpl* browser,
std::unique_ptr<CefFileDialogRunner> runner);
CefFileDialogManager(const CefFileDialogManager&) = delete;
CefFileDialogManager& operator=(const CefFileDialogManager&) = delete;
@@ -35,65 +38,70 @@ class CefFileDialogManager {
// Delete the runner to free any platform constructs.
void Destroy();
// Run a file dialog with the specified parameters. See
// CefBrowserHost::RunFileDialog for usage documentation. This method should
// be called via CefBrowserHostBase::RunFileDialog.
// Called from AlloyBrowserHostImpl::RunFileChooser.
// See CefBrowserHost::RunFileDialog documentation.
void RunFileDialog(cef_file_dialog_mode_t mode,
const CefString& title,
const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
int selected_accept_filter,
CefRefPtr<CefRunFileDialogCallback> callback);
// The argument vector will be empty if the dialog was canceled.
using RunFileChooserCallback =
base::OnceCallback<void(const std::vector<base::FilePath>&)>;
// Called from AlloyBrowserHostImpl::RunFileChooser.
// See WebContentsDelegate::RunFileChooser documentation.
void RunFileChooser(scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params);
// Run the file dialog specified by |params|. |callback| will be executed
// synchronously or asynchronously after the dialog is dismissed. This method
// should be called via CefBrowserHostBase::RunFileChooser.
void RunFileChooser(const blink::mojom::FileChooserParams& params,
RunFileChooserCallback callback);
// Run a ui::SelectFileDialog with the specified parameters. See
// ui::SelectFileDialog for usage documentation. This method should be called
// via CefBrowserHostBase::RunSelectFile. It will be called for all file
// dialogs after interception via CefSelectFileDialog::SelectFileImpl.
void RunSelectFile(ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy,
ui::SelectFileDialog::Type type,
const std::u16string& title,
const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
const base::FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params);
// Must be called when the |listener| passed to RunSelectFile is destroyed.
void SelectFileListenerDestroyed(ui::SelectFileDialog::Listener* listener);
// Run the file chooser dialog specified by |params|. Only a single dialog may
// be pending at any given time. |callback| will be executed asynchronously
// after the dialog is dismissed or if another dialog is already pending.
void RunFileChooser(const CefFileDialogRunner::FileChooserParams& params,
CefFileDialogRunner::RunFileChooserCallback callback);
private:
[[nodiscard]] RunFileChooserCallback MaybeRunDelegate(
const blink::mojom::FileChooserParams& params,
RunFileChooserCallback callback);
void RunFileChooserInternal(
const CefFileDialogRunner::FileChooserParams& params,
CefFileDialogRunner::RunFileChooserCallback callback);
void SelectFileDoneByDelegateCallback(
ui::SelectFileDialog::Listener* listener,
void* params,
const std::vector<base::FilePath>& paths);
void SelectFileDoneByListenerCallback(bool listener_destroyed);
// Used with the RunFileChooser variant where the caller specifies a callback
// (no associated RenderFrameHost).
void OnRunFileChooserCallback(
CefFileDialogRunner::RunFileChooserCallback callback,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths);
// CefBrowserHostBase pointer is guaranteed to outlive this object.
CefBrowserHostBase* const browser_;
// Used with WebContentsDelegate::RunFileChooser when mode is
// blink::mojom::FileChooserParams::Mode::kUploadFolder.
void OnRunFileChooserUploadFolderDelegateCallback(
const blink::mojom::FileChooserParams::Mode mode,
scoped_refptr<content::FileSelectListener> listener,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths);
// Used when running a platform dialog via RunSelectFile.
scoped_refptr<ui::SelectFileDialog> dialog_;
CefSelectFileDialogListener* dialog_listener_ = nullptr;
// Used with WebContentsDelegate::RunFileChooser to notify the
// RenderFrameHost.
void OnRunFileChooserDelegateCallback(
blink::mojom::FileChooserParams::Mode mode,
scoped_refptr<content::FileSelectListener> listener,
int selected_accept_filter,
const std::vector<base::FilePath>& file_paths);
// List of all currently active listeners.
std::set<ui::SelectFileDialog::Listener*> active_listeners_;
// Clean up state associated with the last run.
void Cleanup();
base::WeakPtrFactory<CefFileDialogManager> weak_ptr_factory_{this};
// AlloyBrowserHostImpl pointer is guaranteed to outlive this object.
AlloyBrowserHostImpl* browser_;
std::unique_ptr<CefFileDialogRunner> runner_;
// True if a file chooser is currently pending.
bool file_chooser_pending_;
// Used for asynchronously listing directory contents.
std::unique_ptr<net::DirectoryLister> lister_;
// Must be the last member.
base::WeakPtrFactory<CefFileDialogManager> weak_ptr_factory_;
};
#endif // CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_MANAGER_H_

View File

@@ -1,189 +0,0 @@
// Copyright (c) 2022 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/file_dialog_runner.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info_manager.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "base/memory/singleton.h"
#include "chrome/browser/file_select_helper.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "ui/shell_dialogs/select_file_dialog_factory.h"
#include "ui/shell_dialogs/select_file_policy.h"
using blink::mojom::FileChooserParams;
namespace {
// Creation of a file dialog can be triggered via various code paths, but they
// all eventually result in a call to ui::SelectFileDialog::Create. We intercept
// that call with CefSelectFileDialogFactory and redirect it to
// CefFileDialogManager::RunSelectFile. After triggering the CefDialogHandler
// callbacks that method calls ui::SelectFileDialog::Create again with
// |run_from_cef=false| to trigger creation of the default platform dialog.
class CefSelectFileDialogFactory final : public ui::SelectFileDialogFactory {
public:
CefSelectFileDialogFactory(const CefSelectFileDialogFactory&) = delete;
CefSelectFileDialogFactory& operator=(const CefSelectFileDialogFactory&) =
delete;
static CefSelectFileDialogFactory* GetInstance() {
// Leaky because there is no useful cleanup to do.
return base::Singleton<
CefSelectFileDialogFactory,
base::LeakySingletonTraits<CefSelectFileDialogFactory>>::get();
}
ui::SelectFileDialog* Create(
ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy) override;
bool IsCefFactory() const override { return true; }
private:
friend struct base::DefaultSingletonTraits<CefSelectFileDialogFactory>;
CefSelectFileDialogFactory() { ui::SelectFileDialog::SetFactory(this); }
};
CefRefPtr<CefBrowserHostBase> GetBrowserForTopLevelNativeWindow(
gfx::NativeWindow owning_window) {
DCHECK(owning_window);
for (const auto& browser_info :
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
if (auto browser = browser_info->browser()) {
if (browser->GetTopLevelNativeWindow() == owning_window)
return browser;
}
}
return nullptr;
}
CefRefPtr<CefBrowserHostBase> GetLikelyFocusedBrowser() {
for (const auto& browser_info :
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
if (auto browser = browser_info->browser()) {
if (browser->IsFocused())
return browser;
}
}
return nullptr;
}
// Delegates the running of the dialog to CefFileDialogManager.
class CefSelectFileDialog final : public ui::SelectFileDialog {
public:
CefSelectFileDialog(ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy)
: ui::SelectFileDialog(listener, std::move(policy)) {
DCHECK(listener_);
}
CefSelectFileDialog(const CefSelectFileDialog&) = delete;
CefSelectFileDialog& operator=(const CefSelectFileDialog&) = delete;
void SelectFileImpl(Type type,
const std::u16string& title,
const base::FilePath& default_path,
const FileTypeInfo* file_types,
int file_type_index,
const base::FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params) override {
// Try to determine the associated browser (with decreasing levels of
// confidence).
// 1. Browser associated with the SelectFilePolicy. This is the most
// reliable mechanism if specified at the SelectFileDialog::Create call
// site.
if (select_file_policy_) {
auto chrome_policy =
static_cast<ChromeSelectFilePolicy*>(select_file_policy_.get());
auto web_contents = chrome_policy->source_contents();
if (web_contents) {
browser_ = extensions::GetOwnerBrowserForHost(
web_contents->GetRenderViewHost(), nullptr);
}
if (!browser_) {
LOG(WARNING) << "No browser associated with SelectFilePolicy";
}
}
// 2. Browser associated with the top-level native window (owning_window).
// This should be reliable with windowed browsers. However, |owning_window|
// will always be nullptr with windowless browsers.
if (!browser_ && owning_window) {
browser_ = GetBrowserForTopLevelNativeWindow(owning_window);
if (!browser_) {
LOG(WARNING) << "No browser associated with top-level native window";
}
}
// 3. Browser most likely to be focused. This may be somewhat iffy with
// windowless browsers as there is no guarantee that the client has only
// one browser focused at a time.
if (!browser_) {
browser_ = GetLikelyFocusedBrowser();
if (!browser_) {
LOG(WARNING) << "No likely focused browser";
}
}
if (!browser_) {
LOG(ERROR)
<< "Failed to identify associated browser; canceling the file dialog";
listener_->FileSelectionCanceled(params);
return;
}
owning_window_ = owning_window;
has_multiple_file_choices_ =
file_types ? file_types->extensions.size() > 1 : true;
browser_->RunSelectFile(listener_, std::move(select_file_policy_), type,
title, default_path, file_types, file_type_index,
default_extension, owning_window, params);
}
bool IsRunning(gfx::NativeWindow owning_window) const override {
return owning_window == owning_window_;
}
void ListenerDestroyed() override {
if (browser_)
browser_->SelectFileListenerDestroyed(listener_);
listener_ = nullptr;
}
bool HasMultipleFileTypeChoicesImpl() override {
return has_multiple_file_choices_;
}
private:
gfx::NativeWindow owning_window_ = nullptr;
bool has_multiple_file_choices_ = false;
CefRefPtr<CefBrowserHostBase> browser_;
};
ui::SelectFileDialog* CefSelectFileDialogFactory::Create(
ui::SelectFileDialog::Listener* listener,
std::unique_ptr<ui::SelectFilePolicy> policy) {
return new CefSelectFileDialog(listener, std::move(policy));
}
} // namespace
namespace file_dialog_runner {
void RegisterFactory() {
// Implicitly registers on creation.
CefSelectFileDialogFactory::GetInstance();
}
} // namespace file_dialog_runner

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2022 The Chromium Embedded Framework Authors.
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,11 +7,46 @@
#define CEF_LIBCEF_BROWSER_FILE_DIALOG_RUNNER_H_
#pragma once
namespace file_dialog_runner {
#include <vector>
// One-time registration on startup.
void RegisterFactory();
#include "base/callback.h"
#include "base/files/file_path.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
} // namespace file_dialog_runner
class AlloyBrowserHostImpl;
class CefFileDialogRunner {
public:
CefFileDialogRunner(const CefFileDialogRunner&) = delete;
CefFileDialogRunner& operator=(const CefFileDialogRunner&) = delete;
// Extend blink::mojom::FileChooserParams with some options unique to CEF.
struct FileChooserParams : public blink::mojom::FileChooserParams {
// 0-based index of the selected value in |accept_types|.
int selected_accept_filter = 0;
// True if the Save dialog should prompt before overwriting files.
bool overwriteprompt = true;
// True if read-only files should be hidden.
bool hidereadonly = true;
};
// The argument vector will be empty if the dialog was canceled.
using RunFileChooserCallback =
base::OnceCallback<void(int, const std::vector<base::FilePath>&)>;
// Display the file chooser dialog. Execute |callback| on completion.
virtual void Run(AlloyBrowserHostImpl* browser,
const FileChooserParams& params,
RunFileChooserCallback callback) = 0;
protected:
// Allow deletion via std::unique_ptr only.
friend std::default_delete<CefFileDialogRunner>;
CefFileDialogRunner() = default;
virtual ~CefFileDialogRunner() = default;
};
#endif // CEF_LIBCEF_BROWSER_FILE_DIALOG_RUNNER_H_

View File

@@ -414,10 +414,8 @@ void CefFrameHostImpl::ExecuteJavaScriptWithUserGestureForTests(
}
content::RenderFrameHost* rfh = GetRenderFrameHost();
if (rfh) {
rfh->ExecuteJavaScriptWithUserGestureForTests(javascript,
base::NullCallback());
}
if (rfh)
rfh->ExecuteJavaScriptWithUserGestureForTests(javascript);
}
content::RenderFrameHost* CefFrameHostImpl::GetRenderFrameHost() const {

View File

@@ -208,7 +208,7 @@ void CefMediaRouterManager::TerminateRoute(
GetMediaRouter()->TerminateRoute(route_id);
}
void CefMediaRouterManager::OnSinksUpdated(const MediaSinkVector& sinks) {
void CefMediaRouterManager::OnResultsUpdated(const MediaSinkVector& sinks) {
sinks_ = sinks;
NotifyCurrentSinks();
}

View File

@@ -25,7 +25,7 @@ class CefRouteMessageObserver;
// Manages CEF usage of MediaRouter. Owned by CefBrowserContext and only
// accessed on the UI thread.
class CefMediaRouterManager
: public media_router::MediaSinkWithCastModesObserver {
: public media_router::QueryResultManager::Observer {
public:
using MediaRouteVector = std::vector<media_router::MediaRoute>;
using MediaSinkVector = std::vector<media_router::MediaSinkWithCastModes>;
@@ -74,8 +74,8 @@ class CefMediaRouterManager
const std::string& message);
void TerminateRoute(const media_router::MediaRoute::Id& route_id);
// MediaSinkWithCastModesObserver methods.
void OnSinksUpdated(const MediaSinkVector& sinks) override;
// QueryResultManager::Observer methods.
void OnResultsUpdated(const MediaSinkVector& sinks) override;
private:
friend class CefMediaRoutesObserver;

View File

@@ -37,7 +37,7 @@ CefBrowserPlatformDelegateNativeLinux::CefBrowserPlatformDelegateNativeLinux(
void CefBrowserPlatformDelegateNativeLinux::BrowserDestroyed(
CefBrowserHostBase* browser) {
CefBrowserPlatformDelegateNativeAura::BrowserDestroyed(browser);
CefBrowserPlatformDelegateNative::BrowserDestroyed(browser);
if (host_window_created_) {
// Release the reference added in CreateHostWindow().
@@ -155,7 +155,7 @@ void CefBrowserPlatformDelegateNativeLinux::SetFocus(bool setFocus) {
void CefBrowserPlatformDelegateNativeLinux::NotifyMoveOrResizeStarted() {
// Call the parent method to dismiss any existing popups.
CefBrowserPlatformDelegateNativeAura::NotifyMoveOrResizeStarted();
CefBrowserPlatformDelegateNative::NotifyMoveOrResizeStarted();
if (!web_contents_)
return;

View File

@@ -40,6 +40,7 @@ class CefBrowserPlatformDelegateNativeMac
const content::NativeWebKeyboardEvent& event) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
std::unique_ptr<CefFileDialogRunner> CreateFileDialogRunner() override;
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;

View File

@@ -9,6 +9,7 @@
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/context.h"
#include "libcef/browser/native/file_dialog_runner_mac.h"
#include "libcef/browser/native/javascript_dialog_runner_mac.h"
#include "libcef/browser/native/menu_runner_mac.h"
#include "libcef/browser/thread_util.h"
@@ -165,22 +166,27 @@ bool CefBrowserPlatformDelegateNativeMac::CreateHostWindow() {
NSView* parentView =
CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(window_info_.parent_view);
const CGFloat x = static_cast<CGFloat>(window_info_.bounds.x);
const CGFloat y = static_cast<CGFloat>(window_info_.bounds.y);
const CGFloat width = static_cast<CGFloat>(window_info_.bounds.width);
const CGFloat height = static_cast<CGFloat>(window_info_.bounds.height);
NSRect content_rect = {{x, y}, {width, height}};
NSRect contentRect = {{static_cast<CGFloat>(window_info_.bounds.x),
static_cast<CGFloat>(window_info_.bounds.y)},
{static_cast<CGFloat>(window_info_.bounds.width),
static_cast<CGFloat>(window_info_.bounds.height)}};
if (parentView == nil) {
// Create a new window.
NSRect window_rect = {{x, y}, {width, height}};
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
NSRect window_rect = {
{static_cast<CGFloat>(window_info_.bounds.x),
screen_rect.size.height - static_cast<CGFloat>(window_info_.bounds.y)},
{static_cast<CGFloat>(window_info_.bounds.width),
static_cast<CGFloat>(window_info_.bounds.height)}};
if (window_rect.size.width == 0)
window_rect.size.width = 750;
if (window_rect.size.height == 0)
window_rect.size.height = 750;
content_rect = {{0, 0}, {window_rect.size.width, window_rect.size.height}};
contentRect.origin.x = 0;
contentRect.origin.y = 0;
contentRect.size.width = window_rect.size.width;
contentRect.size.height = window_rect.size.height;
newWnd = [[UnderlayOpenGLHostingWindow alloc]
initWithContentRect:window_rect
@@ -201,11 +207,6 @@ bool CefBrowserPlatformDelegateNativeMac::CreateHostWindow() {
// sub-views have layers. This is necessary to ensure correct layer
// ordering of all child views and their layers.
[parentView setWantsLayer:YES];
// Transform input Y coodinate into the MacOS coordinate.
NSRect primary_screen_rect = [[[NSScreen screens] firstObject] frame];
const CGFloat transformed_y = NSMaxY(primary_screen_rect) - y;
[newWnd setFrameTopLeftPoint:NSMakePoint(x, transformed_y)];
}
host_window_created_ = true;
@@ -215,7 +216,7 @@ bool CefBrowserPlatformDelegateNativeMac::CreateHostWindow() {
// Create the browser view.
CefBrowserHostView* browser_view =
[[CefBrowserHostView alloc] initWithFrame:content_rect];
[[CefBrowserHostView alloc] initWithFrame:contentRect];
browser_view.browser = browser_;
[parentView addSubview:browser_view];
[browser_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
@@ -362,6 +363,11 @@ CefEventHandle CefBrowserPlatformDelegateNativeMac::GetEventHandle(
return event.os_event;
}
std::unique_ptr<CefFileDialogRunner>
CefBrowserPlatformDelegateNativeMac::CreateFileDialogRunner() {
return base::WrapUnique(new CefFileDialogRunnerMac);
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateNativeMac::CreateJavaScriptDialogRunner() {
return base::WrapUnique(new CefJavaScriptDialogRunnerMac);

View File

@@ -10,6 +10,7 @@
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/context.h"
#include "libcef/browser/native/file_dialog_runner_win.h"
#include "libcef/browser/native/javascript_dialog_runner_win.h"
#include "libcef/browser/native/menu_runner_win.h"
#include "libcef/browser/native/window_delegate_view.h"
@@ -155,18 +156,9 @@ CefBrowserPlatformDelegateNativeWin::CefBrowserPlatformDelegateNativeWin(
SkColor background_color)
: CefBrowserPlatformDelegateNativeAura(window_info, background_color) {}
void CefBrowserPlatformDelegateNativeWin::set_widget(
views::Widget* widget,
CefWindowHandle widget_handle) {
DCHECK(!window_widget_);
window_widget_ = widget;
DCHECK(!window_info_.window);
window_info_.window = widget_handle;
}
void CefBrowserPlatformDelegateNativeWin::BrowserDestroyed(
CefBrowserHostBase* browser) {
CefBrowserPlatformDelegateNativeAura::BrowserDestroyed(browser);
CefBrowserPlatformDelegateNative::BrowserDestroyed(browser);
if (host_window_created_) {
// Release the reference added in CreateHostWindow().
@@ -177,11 +169,6 @@ void CefBrowserPlatformDelegateNativeWin::BrowserDestroyed(
bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() {
RegisterWindowClass();
if (window_info_.style == 0) {
// Client didn't intialize the CefWindowInfo. Provide reasonable defaults.
window_info_.SetAsPopup(nullptr, CefString());
}
has_frame_ = !(window_info_.style & WS_CHILD);
std::wstring windowName(CefString(&window_info_.window_name));
@@ -328,7 +315,7 @@ void CefBrowserPlatformDelegateNativeWin::SetFocus(bool setFocus) {
void CefBrowserPlatformDelegateNativeWin::NotifyMoveOrResizeStarted() {
// Call the parent method to dismiss any existing popups.
CefBrowserPlatformDelegateNativeAura::NotifyMoveOrResizeStarted();
CefBrowserPlatformDelegateNative::NotifyMoveOrResizeStarted();
if (!window_widget_)
return;
@@ -446,6 +433,11 @@ CefEventHandle CefBrowserPlatformDelegateNativeWin::GetEventHandle(
const_cast<CHROME_MSG*>(&event.os_event->native_event()));
}
std::unique_ptr<CefFileDialogRunner>
CefBrowserPlatformDelegateNativeWin::CreateFileDialogRunner() {
return base::WrapUnique(new CefFileDialogRunnerWin);
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateNativeWin::CreateJavaScriptDialogRunner() {
return base::WrapUnique(new CefJavaScriptDialogRunnerWin);

View File

@@ -16,9 +16,6 @@ class CefBrowserPlatformDelegateNativeWin
CefBrowserPlatformDelegateNativeWin(const CefWindowInfo& window_info,
SkColor background_color);
// Called from chrome_child_window.cc after |widget| is created.
void set_widget(views::Widget* widget, CefWindowHandle widget_handle);
// CefBrowserPlatformDelegate methods:
void BrowserDestroyed(CefBrowserHostBase* browser) override;
bool CreateHostWindow() override;
@@ -34,6 +31,7 @@ class CefBrowserPlatformDelegateNativeWin
const content::NativeWebKeyboardEvent& event) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
std::unique_ptr<CefFileDialogRunner> CreateFileDialogRunner() override;
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;

View File

@@ -7,68 +7,13 @@
#include "libcef/browser/browser_host_base.h"
#include "content/common/cursors/webcursor.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/base/cursor/cursor_factory.h"
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
#if defined(USE_AURA)
#include "ui/aura/cursor/cursor_loader.h"
#include "ui/display/display_util.h"
#endif
namespace cursor_util {
namespace {
#if defined(USE_AURA)
display::ScreenInfo GetScreenInfo(CefRefPtr<CefBrowser> browser) {
display::ScreenInfo screen_info;
bool screen_info_set = false;
if (auto web_contents =
static_cast<CefBrowserHostBase*>(browser.get())->GetWebContents()) {
if (auto view = web_contents->GetRenderWidgetHostView()) {
const auto screen_infos = view->GetScreenInfos();
if (!screen_infos.screen_infos.empty()) {
screen_info = screen_infos.current();
screen_info_set = true;
}
}
}
if (!screen_info_set) {
display::DisplayUtil::GetDefaultScreenInfo(&screen_info);
}
return screen_info;
}
display::Display::Rotation OrientationAngleToRotation(
uint16_t orientation_angle) {
// The Display rotation and the ScreenInfo orientation are not the same
// angle. The former is the physical display rotation while the later is the
// rotation required by the content to be shown properly on the screen, in
// other words, relative to the physical display.
if (orientation_angle == 0)
return display::Display::ROTATE_0;
if (orientation_angle == 90)
return display::Display::ROTATE_270;
if (orientation_angle == 180)
return display::Display::ROTATE_180;
if (orientation_angle == 270)
return display::Display::ROTATE_90;
NOTREACHED();
return display::Display::ROTATE_0;
}
#endif // defined(USE_AURA)
} // namespace
bool OnCursorChange(CefRefPtr<CefBrowser> browser,
const ui::Cursor& ui_cursor) {
auto client = browser->GetHost()->GetClient();
bool OnCursorChange(CefBrowserHostBase* browser, const ui::Cursor& ui_cursor) {
auto client = browser->GetClient();
if (!client)
return false;
auto handler = client->GetDisplayHandler();
@@ -90,32 +35,19 @@ bool OnCursorChange(CefRefPtr<CefBrowser> browser,
bool handled = false;
#if defined(USE_AURA)
aura::CursorLoader cursor_loader;
scoped_refptr<ui::PlatformCursor> platform_cursor;
CefCursorHandle native_cursor = kNullCursorHandle;
ui::Cursor loaded_cursor = ui_cursor;
CefCursorHandle platform_cursor;
scoped_refptr<ui::PlatformCursor> image_cursor;
if (ui_cursor.type() == ui::mojom::CursorType::kCustom) {
platform_cursor = ui::CursorFactory::GetInstance()->CreateImageCursor(
image_cursor = ui::CursorFactory::GetInstance()->CreateImageCursor(
ui::mojom::CursorType::kCustom, ui_cursor.custom_bitmap(),
ui_cursor.custom_hotspot());
platform_cursor = cursor_util::ToCursorHandle(image_cursor);
} else {
const auto& screen_info = GetScreenInfo(browser);
cursor_loader.SetDisplayData(
OrientationAngleToRotation(screen_info.orientation_angle),
screen_info.device_scale_factor);
// Attempts to load the cursor via the platform or from pak resources.
cursor_loader.SetPlatformCursor(&loaded_cursor);
platform_cursor = loaded_cursor.platform();
platform_cursor = cursor_util::GetPlatformCursor(ui_cursor.type());
}
if (platform_cursor) {
native_cursor = cursor_util::ToCursorHandle(platform_cursor);
}
handled = handler->OnCursorChange(browser, native_cursor, cursor_type,
handled = handler->OnCursorChange(browser, platform_cursor, cursor_type,
custom_cursor_info);
#elif BUILDFLAG(IS_MAC)
// |web_cursor| owns the resulting |native_cursor|.

View File

@@ -5,7 +5,7 @@
#ifndef CEF_LIBCEF_BROWSER_NATIVE_CURSOR_UTIL_H_
#define CEF_LIBCEF_BROWSER_NATIVE_CURSOR_UTIL_H_
#include "include/cef_browser.h"
#include "include/internal/cef_types.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
@@ -14,14 +14,17 @@
#include "ui/base/cursor/platform_cursor.h"
#endif
class CefBrowserHostBase;
namespace cursor_util {
#if defined(USE_AURA)
cef_cursor_handle_t GetPlatformCursor(ui::mojom::CursorType type);
cef_cursor_handle_t ToCursorHandle(scoped_refptr<ui::PlatformCursor> cursor);
#endif // defined(USE_AURA)
// Returns true if the client handled the cursor change.
bool OnCursorChange(CefRefPtr<CefBrowser> browser, const ui::Cursor& ui_cursor);
bool OnCursorChange(CefBrowserHostBase* browser, const ui::Cursor& ui_cursor);
} // namespace cursor_util

View File

@@ -4,6 +4,7 @@
#include "libcef/browser/native/cursor_util.h"
#include "ui/base/cursor/cursor_factory.h"
#include "ui/ozone/buildflags.h"
#if BUILDFLAG(OZONE_PLATFORM_X11)
@@ -14,6 +15,14 @@
namespace cursor_util {
cef_cursor_handle_t GetPlatformCursor(ui::mojom::CursorType type) {
auto cursor = ui::CursorFactory::GetInstance()->GetDefaultCursor(type);
if (cursor) {
return ToCursorHandle(cursor);
}
return 0;
}
cef_cursor_handle_t ToCursorHandle(scoped_refptr<ui::PlatformCursor> cursor) {
#if BUILDFLAG(OZONE_PLATFORM_X11)
// See https://crbug.com/1029142 for background.

View File

@@ -4,10 +4,159 @@
#include "libcef/browser/native/cursor_util.h"
#include <windows.h>
#include "libcef/common/app_manager.h"
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
#include "ui/base/win/win_cursor.h"
#include "ui/resources/grit/ui_unscaled_resources.h"
namespace cursor_util {
namespace {
// From content/common/cursors/webcursor_win.cc.
LPCWSTR ToCursorID(ui::mojom::CursorType type) {
switch (type) {
case ui::mojom::CursorType::kPointer:
return IDC_ARROW;
case ui::mojom::CursorType::kCross:
return IDC_CROSS;
case ui::mojom::CursorType::kHand:
return IDC_HAND;
case ui::mojom::CursorType::kIBeam:
return IDC_IBEAM;
case ui::mojom::CursorType::kWait:
return IDC_WAIT;
case ui::mojom::CursorType::kHelp:
return IDC_HELP;
case ui::mojom::CursorType::kEastResize:
return IDC_SIZEWE;
case ui::mojom::CursorType::kNorthResize:
return IDC_SIZENS;
case ui::mojom::CursorType::kNorthEastResize:
return IDC_SIZENESW;
case ui::mojom::CursorType::kNorthWestResize:
return IDC_SIZENWSE;
case ui::mojom::CursorType::kSouthResize:
return IDC_SIZENS;
case ui::mojom::CursorType::kSouthEastResize:
return IDC_SIZENWSE;
case ui::mojom::CursorType::kSouthWestResize:
return IDC_SIZENESW;
case ui::mojom::CursorType::kWestResize:
return IDC_SIZEWE;
case ui::mojom::CursorType::kNorthSouthNoResize:
case ui::mojom::CursorType::kNorthSouthResize:
return IDC_SIZENS;
case ui::mojom::CursorType::kEastWestNoResize:
case ui::mojom::CursorType::kEastWestResize:
return IDC_SIZEWE;
case ui::mojom::CursorType::kNorthEastSouthWestNoResize:
case ui::mojom::CursorType::kNorthEastSouthWestResize:
return IDC_SIZENESW;
case ui::mojom::CursorType::kNorthWestSouthEastNoResize:
case ui::mojom::CursorType::kNorthWestSouthEastResize:
return IDC_SIZENWSE;
case ui::mojom::CursorType::kColumnResize:
return MAKEINTRESOURCE(IDC_COLRESIZE);
case ui::mojom::CursorType::kRowResize:
return MAKEINTRESOURCE(IDC_ROWRESIZE);
case ui::mojom::CursorType::kMiddlePanning:
return MAKEINTRESOURCE(IDC_PAN_MIDDLE);
case ui::mojom::CursorType::kEastPanning:
return MAKEINTRESOURCE(IDC_PAN_EAST);
case ui::mojom::CursorType::kNorthPanning:
return MAKEINTRESOURCE(IDC_PAN_NORTH);
case ui::mojom::CursorType::kNorthEastPanning:
return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST);
case ui::mojom::CursorType::kNorthWestPanning:
return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST);
case ui::mojom::CursorType::kSouthPanning:
return MAKEINTRESOURCE(IDC_PAN_SOUTH);
case ui::mojom::CursorType::kSouthEastPanning:
return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST);
case ui::mojom::CursorType::kSouthWestPanning:
return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST);
case ui::mojom::CursorType::kWestPanning:
return MAKEINTRESOURCE(IDC_PAN_WEST);
case ui::mojom::CursorType::kMove:
return IDC_SIZEALL;
case ui::mojom::CursorType::kVerticalText:
return MAKEINTRESOURCE(IDC_VERTICALTEXT);
case ui::mojom::CursorType::kCell:
return MAKEINTRESOURCE(IDC_CELL);
case ui::mojom::CursorType::kAlias:
return MAKEINTRESOURCE(IDC_ALIAS);
case ui::mojom::CursorType::kProgress:
return IDC_APPSTARTING;
case ui::mojom::CursorType::kNoDrop:
return IDC_NO;
case ui::mojom::CursorType::kCopy:
return MAKEINTRESOURCE(IDC_COPYCUR);
case ui::mojom::CursorType::kNotAllowed:
return IDC_NO;
case ui::mojom::CursorType::kZoomIn:
return MAKEINTRESOURCE(IDC_ZOOMIN);
case ui::mojom::CursorType::kZoomOut:
return MAKEINTRESOURCE(IDC_ZOOMOUT);
case ui::mojom::CursorType::kGrab:
return MAKEINTRESOURCE(IDC_HAND_GRAB);
case ui::mojom::CursorType::kGrabbing:
return MAKEINTRESOURCE(IDC_HAND_GRABBING);
case ui::mojom::CursorType::kNull:
return IDC_NO;
case ui::mojom::CursorType::kMiddlePanningVertical:
return MAKEINTRESOURCE(IDC_PAN_MIDDLE_VERTICAL);
case ui::mojom::CursorType::kMiddlePanningHorizontal:
return MAKEINTRESOURCE(IDC_PAN_MIDDLE_HORIZONTAL);
// TODO(cef): Find better cursors for these things
case ui::mojom::CursorType::kDndNone:
return IDC_ARROW;
case ui::mojom::CursorType::kDndMove:
return IDC_ARROW;
case ui::mojom::CursorType::kDndCopy:
return IDC_ARROW;
case ui::mojom::CursorType::kDndLink:
return IDC_ARROW;
case ui::mojom::CursorType::kContextMenu:
case ui::mojom::CursorType::kCustom:
case ui::mojom::CursorType::kNone:
NOTIMPLEMENTED();
return IDC_ARROW;
}
NOTREACHED();
return NULL;
}
bool IsSystemCursorID(LPCWSTR cursor_id) {
// Check the range of values from WinUser.h.
return cursor_id >= IDC_ARROW && cursor_id <= IDC_HELP;
}
} // namespace
cef_cursor_handle_t GetPlatformCursor(ui::mojom::CursorType type) {
// Using a dark 1x1 bit bmp kNone cursor may still cause DWM to do composition
// work unnecessarily. Better to totally remove it from the screen.
// crbug.com/1069698
if (type == ui::mojom::CursorType::kNone) {
return nullptr;
}
HMODULE module_handle = NULL;
const wchar_t* cursor_id = ToCursorID(type);
if (!IsSystemCursorID(cursor_id)) {
module_handle =
::GetModuleHandle(CefAppManager::Get()->GetResourceDllName());
if (!module_handle)
module_handle = ::GetModuleHandle(NULL);
}
return LoadCursor(module_handle, cursor_id);
}
cef_cursor_handle_t ToCursorHandle(scoped_refptr<ui::PlatformCursor> cursor) {
return ui::WinCursor::FromPlatformCursor(cursor)->hcursor();
}

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_NATIVE_FILE_DIALOG_RUNNER_MAC_H_
#define CEF_LIBCEF_BROWSER_NATIVE_FILE_DIALOG_RUNNER_MAC_H_
#pragma once
#include "libcef/browser/file_dialog_runner.h"
#include "base/memory/weak_ptr.h"
@class NSView;
class CefFileDialogRunnerMac : public CefFileDialogRunner {
public:
CefFileDialogRunnerMac();
// CefFileDialogRunner methods:
void Run(AlloyBrowserHostImpl* browser,
const FileChooserParams& params,
RunFileChooserCallback callback) override;
private:
static void RunOpenFileDialog(
base::WeakPtr<CefFileDialogRunnerMac> weak_this,
const CefFileDialogRunner::FileChooserParams& params,
NSView* view,
int filter_index);
static void RunSaveFileDialog(
base::WeakPtr<CefFileDialogRunnerMac> weak_this,
const CefFileDialogRunner::FileChooserParams& params,
NSView* view,
int filter_index);
CefFileDialogRunner::RunFileChooserCallback callback_;
base::WeakPtrFactory<CefFileDialogRunnerMac> weak_ptr_factory_;
};
#endif // CEF_LIBCEF_BROWSER_NATIVE_FILE_DIALOG_RUNNER_MAC_H_

View File

@@ -0,0 +1,405 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/native/file_dialog_runner_mac.h"
#import <Cocoa/Cocoa.h>
#import <CoreServices/CoreServices.h>
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "base/mac/mac_util.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "cef/grit/cef_strings.h"
#include "chrome/grit/generated_resources.h"
#include "net/base/mime_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/strings/grit/ui_strings.h"
namespace {
std::u16string GetDescriptionFromMimeType(const std::string& mime_type) {
// Check for wild card mime types and return an appropriate description.
static const struct {
const char* mime_type;
int string_id;
} kWildCardMimeTypes[] = {
{"audio", IDS_AUDIO_FILES},
{"image", IDS_IMAGE_FILES},
{"text", IDS_TEXT_FILES},
{"video", IDS_VIDEO_FILES},
};
for (size_t i = 0; i < std::size(kWildCardMimeTypes); ++i) {
if (mime_type == std::string(kWildCardMimeTypes[i].mime_type) + "/*")
return l10n_util::GetStringUTF16(kWildCardMimeTypes[i].string_id);
}
return std::u16string();
}
void AddFilters(NSPopUpButton* button,
const std::vector<std::u16string>& accept_filters,
bool include_all_files,
std::vector<std::vector<std::u16string>>* all_extensions) {
for (size_t i = 0; i < accept_filters.size(); ++i) {
const std::u16string& filter = accept_filters[i];
if (filter.empty())
continue;
std::vector<std::u16string> extensions;
std::u16string description;
size_t sep_index = filter.find('|');
if (sep_index != std::string::npos) {
// Treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3".
description = filter.substr(0, sep_index);
const std::vector<std::u16string>& ext =
base::SplitString(filter.substr(sep_index + 1), u";",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
for (size_t x = 0; x < ext.size(); ++x) {
const std::u16string& file_ext = ext[x];
if (!file_ext.empty() && file_ext[0] == '.')
extensions.push_back(file_ext);
}
} else if (filter[0] == '.') {
// Treat as an extension beginning with the '.' character.
extensions.push_back(filter);
} else {
// Otherwise convert mime type to one or more extensions.
const std::string& ascii = base::UTF16ToASCII(filter);
std::vector<base::FilePath::StringType> ext;
net::GetExtensionsForMimeType(ascii, &ext);
if (!ext.empty()) {
for (size_t x = 0; x < ext.size(); ++x)
extensions.push_back(u"." + base::ASCIIToUTF16(ext[x]));
description = GetDescriptionFromMimeType(ascii);
}
}
if (extensions.empty())
continue;
// Don't display a crazy number of extensions since the NSPopUpButton width
// will keep growing.
const size_t kMaxExtensions = 10;
std::u16string ext_str;
for (size_t x = 0; x < std::min(kMaxExtensions, extensions.size()); ++x) {
const std::u16string& pattern = u"*" + extensions[x];
if (x != 0)
ext_str += u";";
ext_str += pattern;
}
if (extensions.size() > kMaxExtensions)
ext_str += u";...";
if (description.empty()) {
description = ext_str;
} else {
description += u" (" + ext_str + u")";
}
[button addItemWithTitle:base::SysUTF16ToNSString(description)];
all_extensions->push_back(extensions);
}
// Add the *.* filter, but only if we have added other filters (otherwise it
// is implied).
if (include_all_files && !all_extensions->empty()) {
[button addItemWithTitle:base::SysUTF8ToNSString("All Files (*)")];
all_extensions->push_back(std::vector<std::u16string>());
}
}
} // namespace
// Used to manage the file type filter in the NSSavePanel/NSOpenPanel.
@interface CefFilterDelegate : NSObject {
@private
NSSavePanel* panel_;
std::vector<std::vector<std::u16string>> extensions_;
int selected_index_;
}
- (id)initWithPanel:(NSSavePanel*)panel
andAcceptFilters:(const std::vector<std::u16string>&)accept_filters
andFilterIndex:(int)index;
- (void)setFilter:(int)index;
- (int)filter;
- (void)filterSelectionChanged:(id)sender;
- (void)setFileExtension;
@end
@implementation CefFilterDelegate
- (id)initWithPanel:(NSSavePanel*)panel
andAcceptFilters:(const std::vector<std::u16string>&)accept_filters
andFilterIndex:(int)index {
if (self = [super init]) {
DCHECK(panel);
panel_ = panel;
selected_index_ = 0;
NSPopUpButton* button = [[NSPopUpButton alloc] init];
AddFilters(button, accept_filters, true, &extensions_);
[button sizeToFit];
[button setTarget:self];
[button setAction:@selector(filterSelectionChanged:)];
if (index < static_cast<int>(extensions_.size())) {
[button selectItemAtIndex:index];
[self setFilter:index];
}
[panel_ setAccessoryView:button];
}
return self;
}
// Set the current filter index.
- (void)setFilter:(int)index {
DCHECK(index >= 0 && index < static_cast<int>(extensions_.size()));
selected_index_ = index;
// Set the selectable file types. For open panels this limits the files that
// can be selected. For save panels this applies a default file extenion when
// the dialog is dismissed if none is already provided.
NSMutableArray* acceptArray = nil;
if (!extensions_[index].empty()) {
acceptArray = [[NSMutableArray alloc] init];
for (size_t i = 0; i < extensions_[index].size(); ++i) {
[acceptArray
addObject:base::SysUTF16ToNSString(extensions_[index][i].substr(1))];
}
}
[panel_ setAllowedFileTypes:acceptArray];
if (![panel_ isKindOfClass:[NSOpenPanel class]]) {
// For save panels set the file extension.
[self setFileExtension];
}
}
// Returns the current filter index.
- (int)filter {
return selected_index_;
}
// Called when the selected filter is changed via the NSPopUpButton.
- (void)filterSelectionChanged:(id)sender {
NSPopUpButton* button = (NSPopUpButton*)sender;
[self setFilter:[button indexOfSelectedItem]];
}
// Set the extension on the currently selected file name.
- (void)setFileExtension {
const std::vector<std::u16string>& filter = extensions_[selected_index_];
if (filter.empty()) {
// All extensions are allowed so don't change anything.
return;
}
base::FilePath path(base::SysNSStringToUTF8([panel_ nameFieldStringValue]));
// If the file name currently includes an extension from |filter| then don't
// change anything.
std::u16string extension = base::UTF8ToUTF16(path.Extension());
if (!extension.empty()) {
for (size_t i = 0; i < filter.size(); ++i) {
if (filter[i] == extension)
return;
}
}
// Change the extension to the first value in |filter|.
path = path.ReplaceExtension(base::UTF16ToUTF8(filter[0]));
[panel_ setNameFieldStringValue:base::SysUTF8ToNSString(path.value())];
}
@end
CefFileDialogRunnerMac::CefFileDialogRunnerMac() : weak_ptr_factory_(this) {}
void CefFileDialogRunnerMac::Run(AlloyBrowserHostImpl* browser,
const FileChooserParams& params,
RunFileChooserCallback callback) {
callback_ = std::move(callback);
int filter_index = params.selected_accept_filter;
NSView* owner = CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(browser->GetWindowHandle());
auto weak_this = weak_ptr_factory_.GetWeakPtr();
if (params.mode == blink::mojom::FileChooserParams::Mode::kOpen ||
params.mode == blink::mojom::FileChooserParams::Mode::kOpenMultiple ||
params.mode == blink::mojom::FileChooserParams::Mode::kUploadFolder) {
RunOpenFileDialog(weak_this, params, owner, filter_index);
} else if (params.mode == blink::mojom::FileChooserParams::Mode::kSave) {
RunSaveFileDialog(weak_this, params, owner, filter_index);
} else {
NOTIMPLEMENTED();
}
}
// static
void CefFileDialogRunnerMac::RunOpenFileDialog(
base::WeakPtr<CefFileDialogRunnerMac> weak_this,
const CefFileDialogRunner::FileChooserParams& params,
NSView* view,
int filter_index) {
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
std::u16string title;
if (!params.title.empty()) {
title = params.title;
} else {
title = l10n_util::GetStringUTF16(
params.mode == blink::mojom::FileChooserParams::Mode::kOpen
? IDS_OPEN_FILE_DIALOG_TITLE
: (params.mode ==
blink::mojom::FileChooserParams::Mode::kOpenMultiple
? IDS_OPEN_FILES_DIALOG_TITLE
: IDS_SELECT_FOLDER_DIALOG_TITLE));
}
[openPanel setTitle:base::SysUTF16ToNSString(title)];
std::string filename, directory;
if (!params.default_file_name.empty()) {
if (params.mode == blink::mojom::FileChooserParams::Mode::kUploadFolder ||
params.default_file_name.EndsWithSeparator()) {
// The value is only a directory.
directory = params.default_file_name.value();
} else {
// The value is a file name and possibly a directory.
filename = params.default_file_name.BaseName().value();
directory = params.default_file_name.DirName().value();
}
}
if (!filename.empty()) {
[openPanel setNameFieldStringValue:base::SysUTF8ToNSString(filename)];
}
if (!directory.empty()) {
[openPanel setDirectoryURL:[NSURL fileURLWithPath:base::SysUTF8ToNSString(
directory)]];
}
CefFilterDelegate* filter_delegate = nil;
if (params.mode != blink::mojom::FileChooserParams::Mode::kUploadFolder &&
!params.accept_types.empty()) {
// Add the file filter control.
filter_delegate =
[[CefFilterDelegate alloc] initWithPanel:openPanel
andAcceptFilters:params.accept_types
andFilterIndex:filter_index];
}
// Further panel configuration.
[openPanel setAllowsOtherFileTypes:YES];
[openPanel setAllowsMultipleSelection:
(params.mode ==
blink::mojom::FileChooserParams::Mode::kOpenMultiple)];
[openPanel
setCanChooseFiles:(params.mode !=
blink::mojom::FileChooserParams::Mode::kUploadFolder)];
[openPanel
setCanChooseDirectories:(params.mode == blink::mojom::FileChooserParams::
Mode::kUploadFolder)];
[openPanel setShowsHiddenFiles:!params.hidereadonly];
// Show panel.
[openPanel
beginSheetModalForWindow:[view window]
completionHandler:^(NSInteger returnCode) {
int filter_index_to_use = (filter_delegate != nil)
? [filter_delegate filter]
: filter_index;
if (returnCode == NSFileHandlingPanelOKButton) {
std::vector<base::FilePath> files;
files.reserve(openPanel.URLs.count);
for (NSURL* url in openPanel.URLs) {
if (url.isFileURL)
files.push_back(base::FilePath(url.path.UTF8String));
}
std::move(weak_this->callback_)
.Run(filter_index_to_use, files);
} else {
std::move(weak_this->callback_)
.Run(filter_index_to_use, std::vector<base::FilePath>());
}
}];
}
// static
void CefFileDialogRunnerMac::RunSaveFileDialog(
base::WeakPtr<CefFileDialogRunnerMac> weak_this,
const CefFileDialogRunner::FileChooserParams& params,
NSView* view,
int filter_index) {
NSSavePanel* savePanel = [NSSavePanel savePanel];
std::u16string title;
if (!params.title.empty())
title = params.title;
else
title = l10n_util::GetStringUTF16(IDS_SAVE_AS_DIALOG_TITLE);
[savePanel setTitle:base::SysUTF16ToNSString(title)];
std::string filename, directory;
if (!params.default_file_name.empty()) {
if (params.default_file_name.EndsWithSeparator()) {
// The value is only a directory.
directory = params.default_file_name.value();
} else {
// The value is a file name and possibly a directory.
filename = params.default_file_name.BaseName().value();
directory = params.default_file_name.DirName().value();
}
}
if (!filename.empty()) {
[savePanel setNameFieldStringValue:base::SysUTF8ToNSString(filename)];
}
if (!directory.empty()) {
[savePanel setDirectoryURL:[NSURL fileURLWithPath:base::SysUTF8ToNSString(
directory)]];
}
CefFilterDelegate* filter_delegate = nil;
if (!params.accept_types.empty()) {
// Add the file filter control.
filter_delegate =
[[CefFilterDelegate alloc] initWithPanel:savePanel
andAcceptFilters:params.accept_types
andFilterIndex:filter_index];
}
[savePanel setAllowsOtherFileTypes:YES];
[savePanel setShowsHiddenFiles:!params.hidereadonly];
// Show panel.
[savePanel
beginSheetModalForWindow:view.window
completionHandler:^(NSInteger resultCode) {
int filter_index_to_use = (filter_delegate != nil)
? [filter_delegate filter]
: filter_index;
if (resultCode == NSFileHandlingPanelOKButton) {
NSURL* url = savePanel.URL;
const char* path = url.path.UTF8String;
std::vector<base::FilePath> files(1, base::FilePath(path));
std::move(weak_this->callback_)
.Run(filter_index_to_use, files);
} else {
std::move(weak_this->callback_)
.Run(filter_index_to_use, std::vector<base::FilePath>());
}
}];
}

View File

@@ -0,0 +1,560 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/native/file_dialog_runner_win.h"
#include <windows.h>
#include <commdlg.h>
#include <shlobj.h>
#include <wrl/client.h>
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "base/files/file_util.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "cef/grit/cef_strings.h"
#include "chrome/grit/generated_resources.h"
#include "net/base/mime_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/win/shell.h"
#include "ui/strings/grit/ui_strings.h"
namespace {
// From ui/base/dialogs/select_file_dialog_win.cc.
// Get the file type description from the registry. This will be "Text Document"
// for .txt files, "JPEG Image" for .jpg files, etc. If the registry doesn't
// have an entry for the file type, we return false, true if the description was
// found. 'file_ext' must be in form ".txt".
static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext,
std::wstring* reg_description) {
DCHECK(reg_description);
base::win::RegKey reg_ext(HKEY_CLASSES_ROOT, file_ext.c_str(), KEY_READ);
std::wstring reg_app;
if (reg_ext.ReadValue(NULL, &reg_app) == ERROR_SUCCESS && !reg_app.empty()) {
base::win::RegKey reg_link(HKEY_CLASSES_ROOT, reg_app.c_str(), KEY_READ);
if (reg_link.ReadValue(NULL, reg_description) == ERROR_SUCCESS)
return true;
}
return false;
}
// Set up a filter for a Save/Open dialog, which will consist of |file_ext| file
// extensions (internally separated by semicolons), |ext_desc| as the text
// descriptions of the |file_ext| types (optional), and (optionally) the default
// 'All Files' view. The purpose of the filter is to show only files of a
// particular type in a Windows Save/Open dialog box. The resulting filter is
// returned. The filters created here are:
// 1. only files that have 'file_ext' as their extension
// 2. all files (only added if 'include_all_files' is true)
// Example:
// file_ext: { "*.txt", "*.htm;*.html" }
// ext_desc: { "Text Document" }
// returned: "Text Document\0*.txt\0HTML Document\0*.htm;*.html\0"
// "All Files\0*.*\0\0" (in one big string)
// If a description is not provided for a file extension, it will be retrieved
// from the registry. If the file extension does not exist in the registry, it
// will be omitted from the filter, as it is likely a bogus extension.
std::wstring FormatFilterForExtensions(
const std::vector<std::wstring>& file_ext,
const std::vector<std::wstring>& ext_desc,
bool include_all_files) {
const std::wstring all_ext = L"*.*";
const std::wstring all_desc =
base::UTF16ToWide(l10n_util::GetStringUTF16(IDS_APP_SAVEAS_ALL_FILES)) +
L" (" + all_ext + L")";
DCHECK(file_ext.size() >= ext_desc.size());
if (file_ext.empty())
include_all_files = true;
std::wstring result;
// Create all supported .ext filter if more than one filter.
if (file_ext.size() > 1) {
std::set<base::WStringPiece> unique_exts;
for (const auto& exts : file_ext) {
for (const auto& ext : base::SplitStringPiece(
exts, L";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
unique_exts.insert(ext);
}
}
if (unique_exts.size() > 1) {
std::wstring ext;
auto it = unique_exts.cbegin();
ext = std::wstring(*it);
for (++it; it != unique_exts.cend(); ++it) {
ext += L";" + std::wstring(*it);
}
std::wstring desc =
base::UTF16ToWide(l10n_util::GetStringUTF16(IDS_CUSTOM_FILES)) +
L" (" + ext + L")";
result.append(desc.c_str(), desc.size() + 1); // Append NULL too.
result.append(ext.c_str(), ext.size() + 1);
}
}
for (size_t i = 0; i < file_ext.size(); ++i) {
std::wstring ext = file_ext[i];
std::wstring desc;
if (i < ext_desc.size())
desc = ext_desc[i];
if (ext.empty()) {
// Force something reasonable to appear in the dialog box if there is no
// extension provided.
include_all_files = true;
continue;
}
if (desc.empty()) {
DCHECK(ext.find(L'.') != std::wstring::npos);
std::wstring first_extension = ext.substr(ext.find(L'.'));
size_t first_separator_index = first_extension.find(L';');
if (first_separator_index != std::wstring::npos)
first_extension = first_extension.substr(0, first_separator_index);
// Find the extension name without the preceeding '.' character.
std::wstring ext_name = first_extension;
size_t ext_index = ext_name.find_first_not_of(L'.');
if (ext_index != std::wstring::npos)
ext_name = ext_name.substr(ext_index);
if (!GetRegistryDescriptionFromExtension(first_extension, &desc)) {
// The extension doesn't exist in the registry.
include_all_files = true;
}
}
if (!desc.empty())
desc += L" (" + ext + L")";
else
desc = ext;
result.append(desc.c_str(), desc.size() + 1); // Append NULL too.
result.append(ext.c_str(), ext.size() + 1);
}
if (include_all_files) {
result.append(all_desc.c_str(), all_desc.size() + 1);
result.append(all_ext.c_str(), all_ext.size() + 1);
}
result.append(1, '\0'); // Double NULL required.
return result;
}
std::wstring GetDescriptionFromMimeType(const std::string& mime_type) {
// Check for wild card mime types and return an appropriate description.
static const struct {
const char* mime_type;
int string_id;
} kWildCardMimeTypes[] = {
{"audio", IDS_AUDIO_FILES},
{"image", IDS_IMAGE_FILES},
{"text", IDS_TEXT_FILES},
{"video", IDS_VIDEO_FILES},
};
for (size_t i = 0; i < std::size(kWildCardMimeTypes); ++i) {
if (mime_type == std::string(kWildCardMimeTypes[i].mime_type) + "/*") {
return base::UTF16ToWide(
l10n_util::GetStringUTF16(kWildCardMimeTypes[i].string_id));
}
}
return std::wstring();
}
std::wstring GetFilterString(
const std::vector<std::u16string>& accept_filters) {
std::vector<std::wstring> extensions;
std::vector<std::wstring> descriptions;
for (size_t i = 0; i < accept_filters.size(); ++i) {
const std::wstring& filter = base::UTF16ToWide(accept_filters[i]);
if (filter.empty())
continue;
size_t sep_index = filter.find(L'|');
if (sep_index != std::wstring::npos) {
// Treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3".
const std::wstring& desc = filter.substr(0, sep_index);
const std::vector<std::u16string>& ext = base::SplitString(
base::WideToUTF16(filter.substr(sep_index + 1)), u";",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
std::wstring ext_str;
for (size_t x = 0; x < ext.size(); ++x) {
const std::wstring& file_ext = base::UTF16ToWide(ext[x]);
if (!file_ext.empty() && file_ext[0] == L'.') {
if (!ext_str.empty())
ext_str += L";";
ext_str += L"*" + file_ext;
}
}
if (!ext_str.empty()) {
extensions.push_back(ext_str);
descriptions.push_back(desc);
}
} else if (filter[0] == L'.') {
// Treat as an extension beginning with the '.' character.
extensions.push_back(L"*" + filter);
descriptions.push_back(std::wstring());
} else {
// Otherwise convert mime type to one or more extensions.
const std::string& ascii = base::WideToASCII(filter);
std::vector<base::FilePath::StringType> ext;
std::wstring ext_str;
net::GetExtensionsForMimeType(ascii, &ext);
if (!ext.empty()) {
for (size_t x = 0; x < ext.size(); ++x) {
if (x != 0)
ext_str += L";";
ext_str += L"*." + ext[x];
}
extensions.push_back(ext_str);
descriptions.push_back(GetDescriptionFromMimeType(ascii));
}
}
}
return FormatFilterForExtensions(extensions, descriptions, true);
}
// From chrome/browser/views/shell_dialogs_win.cc
bool RunOpenFileDialog(const CefFileDialogRunner::FileChooserParams& params,
HWND owner,
int* filter_index,
base::FilePath* path) {
OPENFILENAME ofn;
// We must do this otherwise the ofn's FlagsEx may be initialized to random
// junk in release builds which can cause the Places Bar not to show up!
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner;
wchar_t filename[MAX_PATH] = {0};
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
std::wstring directory;
if (!params.default_file_name.empty()) {
if (params.default_file_name.EndsWithSeparator()) {
// The value is only a directory.
directory = params.default_file_name.value();
} else {
// The value is a file name and possibly a directory.
base::wcslcpy(filename, params.default_file_name.value().c_str(),
std::size(filename));
directory = params.default_file_name.DirName().value();
}
}
if (!directory.empty())
ofn.lpstrInitialDir = directory.c_str();
std::wstring title;
if (!params.title.empty()) {
title = base::UTF16ToWide(params.title);
} else {
title = base::UTF16ToWide(
l10n_util::GetStringUTF16(IDS_OPEN_FILE_DIALOG_TITLE));
}
if (!title.empty())
ofn.lpstrTitle = title.c_str();
// We use OFN_NOCHANGEDIR so that the user can rename or delete the directory
// without having to close Chrome first.
ofn.Flags =
OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_ENABLESIZING;
if (params.hidereadonly)
ofn.Flags |= OFN_HIDEREADONLY;
const std::wstring& filter = GetFilterString(params.accept_types);
if (!filter.empty()) {
ofn.lpstrFilter = filter.c_str();
// Indices into |lpstrFilter| start at 1.
ofn.nFilterIndex = *filter_index + 1;
}
bool success = !!GetOpenFileName(&ofn);
if (success) {
*filter_index = ofn.nFilterIndex == 0 ? 0 : ofn.nFilterIndex - 1;
*path = base::FilePath(filename);
}
return success;
}
bool RunOpenMultiFileDialog(
const CefFileDialogRunner::FileChooserParams& params,
HWND owner,
int* filter_index,
std::vector<base::FilePath>* paths) {
OPENFILENAME ofn;
// We must do this otherwise the ofn's FlagsEx may be initialized to random
// junk in release builds which can cause the Places Bar not to show up!
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner;
std::unique_ptr<wchar_t[]> filename(new wchar_t[UNICODE_STRING_MAX_CHARS]);
filename[0] = 0;
ofn.lpstrFile = filename.get();
ofn.nMaxFile = UNICODE_STRING_MAX_CHARS;
std::wstring directory;
if (!params.default_file_name.empty()) {
if (params.default_file_name.EndsWithSeparator()) {
// The value is only a directory.
directory = params.default_file_name.value();
} else {
// The value is a file name and possibly a directory.
directory = params.default_file_name.DirName().value();
}
}
if (!directory.empty())
ofn.lpstrInitialDir = directory.c_str();
std::wstring title;
if (!params.title.empty()) {
title = base::UTF16ToWide(params.title);
} else {
title = base::UTF16ToWide(
l10n_util::GetStringUTF16(IDS_OPEN_FILES_DIALOG_TITLE));
}
if (!title.empty())
ofn.lpstrTitle = title.c_str();
// We use OFN_NOCHANGEDIR so that the user can rename or delete the directory
// without having to close Chrome first.
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER |
OFN_ALLOWMULTISELECT | OFN_ENABLESIZING;
if (params.hidereadonly)
ofn.Flags |= OFN_HIDEREADONLY;
const std::wstring& filter = GetFilterString(params.accept_types);
if (!filter.empty()) {
ofn.lpstrFilter = filter.c_str();
// Indices into |lpstrFilter| start at 1.
ofn.nFilterIndex = *filter_index + 1;
}
bool success = !!GetOpenFileName(&ofn);
if (success) {
std::vector<base::FilePath> files;
const wchar_t* selection = ofn.lpstrFile;
while (*selection) { // Empty string indicates end of list.
files.push_back(base::FilePath(selection));
// Skip over filename and null-terminator.
selection += files.back().value().length() + 1;
}
if (files.empty()) {
success = false;
} else if (files.size() == 1) {
// When there is one file, it contains the path and filename.
paths->swap(files);
} else {
// Otherwise, the first string is the path, and the remainder are
// filenames.
std::vector<base::FilePath>::iterator path = files.begin();
for (std::vector<base::FilePath>::iterator file = path + 1;
file != files.end(); ++file) {
paths->push_back(path->Append(*file));
}
}
}
if (success)
*filter_index = ofn.nFilterIndex == 0 ? 0 : ofn.nFilterIndex - 1;
return success;
}
// The callback function for when the select folder dialog is opened.
int CALLBACK BrowseCallbackProc(HWND window,
UINT message,
LPARAM parameter,
LPARAM data) {
if (message == BFFM_INITIALIZED) {
// WParam is TRUE since passing a path.
// data lParam member of the BROWSEINFO structure.
SendMessage(window, BFFM_SETSELECTION, TRUE, (LPARAM)data);
}
return 0;
}
bool RunOpenFolderDialog(const CefFileDialogRunner::FileChooserParams& params,
HWND owner,
base::FilePath* path) {
wchar_t dir_buffer[MAX_PATH + 1] = {0};
bool result = false;
BROWSEINFO browse_info = {0};
browse_info.hwndOwner = owner;
browse_info.pszDisplayName = dir_buffer;
browse_info.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
std::wstring title;
if (!params.title.empty()) {
title = base::UTF16ToWide(params.title);
} else {
title = base::UTF16ToWide(
l10n_util::GetStringUTF16(IDS_SELECT_FOLDER_DIALOG_TITLE));
}
if (!title.empty())
browse_info.lpszTitle = title.c_str();
const std::wstring& file_path = params.default_file_name.value();
if (!file_path.empty()) {
// Highlight the current value.
browse_info.lParam = (LPARAM)file_path.c_str();
browse_info.lpfn = &BrowseCallbackProc;
}
LPITEMIDLIST list = SHBrowseForFolder(&browse_info);
if (list) {
STRRET out_dir_buffer;
ZeroMemory(&out_dir_buffer, sizeof(out_dir_buffer));
out_dir_buffer.uType = STRRET_WSTR;
Microsoft::WRL::ComPtr<IShellFolder> shell_folder;
if (SHGetDesktopFolder(shell_folder.GetAddressOf()) == NOERROR) {
HRESULT hr = shell_folder->GetDisplayNameOf(list, SHGDN_FORPARSING,
&out_dir_buffer);
if (SUCCEEDED(hr) && out_dir_buffer.uType == STRRET_WSTR) {
*path = base::FilePath(out_dir_buffer.pOleStr);
CoTaskMemFree(out_dir_buffer.pOleStr);
result = true;
} else {
// Use old way if we don't get what we want.
wchar_t old_out_dir_buffer[MAX_PATH + 1];
if (SHGetPathFromIDList(list, old_out_dir_buffer)) {
*path = base::FilePath(old_out_dir_buffer);
result = true;
}
}
}
CoTaskMemFree(list);
}
return result;
}
bool RunSaveFileDialog(const CefFileDialogRunner::FileChooserParams& params,
HWND owner,
int* filter_index,
base::FilePath* path) {
OPENFILENAME ofn;
// We must do this otherwise the ofn's FlagsEx may be initialized to random
// junk in release builds which can cause the Places Bar not to show up!
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = owner;
wchar_t filename[MAX_PATH] = {0};
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
std::wstring directory;
if (!params.default_file_name.empty()) {
if (params.default_file_name.EndsWithSeparator()) {
// The value is only a directory.
directory = params.default_file_name.value();
} else {
// The value is a file name and possibly a directory.
base::wcslcpy(filename, params.default_file_name.value().c_str(),
std::size(filename));
directory = params.default_file_name.DirName().value();
}
}
if (!directory.empty())
ofn.lpstrInitialDir = directory.c_str();
std::wstring title;
if (!params.title.empty()) {
title = base::UTF16ToWide(params.title);
} else {
title =
base::UTF16ToWide(l10n_util::GetStringUTF16(IDS_SAVE_AS_DIALOG_TITLE));
}
if (!title.empty())
ofn.lpstrTitle = title.c_str();
// We use OFN_NOCHANGEDIR so that the user can rename or delete the directory
// without having to close Chrome first.
ofn.Flags =
OFN_EXPLORER | OFN_ENABLESIZING | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
if (params.hidereadonly)
ofn.Flags |= OFN_HIDEREADONLY;
if (params.overwriteprompt)
ofn.Flags |= OFN_OVERWRITEPROMPT;
const std::wstring& filter = GetFilterString(params.accept_types);
if (!filter.empty()) {
ofn.lpstrFilter = filter.c_str();
// Indices into |lpstrFilter| start at 1.
ofn.nFilterIndex = *filter_index + 1;
// If a filter is specified and the default file name is changed then append
// a file extension to the new name.
ofn.lpstrDefExt = L"";
}
bool success = !!GetSaveFileName(&ofn);
if (success) {
*filter_index = ofn.nFilterIndex == 0 ? 0 : ofn.nFilterIndex - 1;
*path = base::FilePath(filename);
}
return success;
}
} // namespace
CefFileDialogRunnerWin::CefFileDialogRunnerWin() {}
void CefFileDialogRunnerWin::Run(AlloyBrowserHostImpl* browser,
const FileChooserParams& params,
RunFileChooserCallback callback) {
int filter_index = params.selected_accept_filter;
std::vector<base::FilePath> files;
HWND owner = browser->GetWindowHandle();
if (params.mode == blink::mojom::FileChooserParams::Mode::kOpen) {
base::FilePath file;
if (RunOpenFileDialog(params, owner, &filter_index, &file))
files.push_back(file);
} else if (params.mode ==
blink::mojom::FileChooserParams::Mode::kOpenMultiple) {
RunOpenMultiFileDialog(params, owner, &filter_index, &files);
} else if (params.mode ==
blink::mojom::FileChooserParams::Mode::kUploadFolder) {
base::FilePath file;
if (RunOpenFolderDialog(params, owner, &file))
files.push_back(file);
} else if (params.mode == blink::mojom::FileChooserParams::Mode::kSave) {
base::FilePath file;
if (RunSaveFileDialog(params, owner, &filter_index, &file))
files.push_back(file);
} else {
NOTIMPLEMENTED();
}
std::move(callback).Run(filter_index, files);
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_NATIVE_FILE_DIALOG_RUNNER_WIN_H_
#define CEF_LIBCEF_BROWSER_NATIVE_FILE_DIALOG_RUNNER_WIN_H_
#pragma once
#include "libcef/browser/file_dialog_runner.h"
class CefFileDialogRunnerWin : public CefFileDialogRunner {
public:
CefFileDialogRunnerWin();
// CefFileDialogRunner methods:
void Run(AlloyBrowserHostImpl* browser,
const FileChooserParams& params,
RunFileChooserCallback callback) override;
};
#endif // CEF_LIBCEF_BROWSER_NATIVE_FILE_DIALOG_RUNNER_WIN_H_

View File

@@ -21,7 +21,6 @@
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/models/image_model.h"
#include "ui/base/models/menu_model.h"
#include "ui/base/themed_vector_icon.h"
#include "ui/color/color_provider_manager.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
@@ -32,6 +31,7 @@
#include "ui/gfx/text_utils.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/themed_vector_icon.h"
#include "ui/views/controls/menu/menu_config.h"
#include "ui/views/controls/menu/menu_insertion_delegate_win.h"

View File

@@ -17,6 +17,7 @@
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/x11_window_event_manager.h"
#include "ui/gfx/x/xproto_util.h"
#include "ui/ozone/platform/x11/x11_topmost_window_finder.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
namespace {
@@ -29,42 +30,6 @@ const char kWMDeleteWindow[] = "WM_DELETE_WINDOW";
const char kWMProtocols[] = "WM_PROTOCOLS";
const char kXdndProxy[] = "XdndProxy";
// Return true if |window| has any property with |property_name|.
// Deleted from ui/base/x/x11_util.h in https://crrev.com/62fc260067.
bool PropertyExists(x11::Window window, x11::Atom property) {
auto response = x11::Connection::Get()
->GetProperty(x11::GetPropertyRequest{
.window = window,
.property = property,
.long_length = 1,
})
.Sync();
return response && response->format;
}
// Returns true if |window| is visible.
// Deleted from ui/base/x/x11_util.h in https://crrev.com/62fc260067.
bool IsWindowVisible(x11::Window window) {
auto response = x11::Connection::Get()->GetWindowAttributes({window}).Sync();
if (!response || response->map_state != x11::MapState::Viewable)
return false;
// Minimized windows are not visible.
std::vector<x11::Atom> wm_states;
if (x11::GetArrayProperty(window, x11::GetAtom("_NET_WM_STATE"),
&wm_states)) {
x11::Atom hidden_atom = x11::GetAtom("_NET_WM_STATE_HIDDEN");
if (base::Contains(wm_states, hidden_atom))
return false;
}
// Do not check _NET_CURRENT_DESKTOP/_NET_WM_DESKTOP since some
// window managers (eg. i3) have per-monitor workspaces where more
// than one workspace can be visible at once, but only one will be
// "active".
return true;
}
x11::Window FindChild(x11::Window window) {
auto query_tree = x11::Connection::Get()->QueryTree({window}).Sync();
if (query_tree && query_tree->children.size() == 1U) {
@@ -83,7 +48,7 @@ x11::Window FindToplevelParent(x11::Window window) {
break;
top_level_window = window;
if (!PropertyExists(query_tree->parent, x11::GetAtom(kNetWMPid)) ||
if (!ui::PropertyExists(query_tree->parent, x11::GetAtom(kNetWMPid)) ||
query_tree->parent == query_tree->root) {
break;
}
@@ -262,7 +227,7 @@ void CefWindowX11::Focus() {
if (browser_.get()) {
auto child = FindChild(xwindow_);
if (child != x11::Window::None && IsWindowVisible(child)) {
if (child != x11::Window::None && ui::IsWindowVisible(child)) {
// Give focus to the child DesktopWindowTreeHostLinux.
focus_target = child;
}
@@ -369,6 +334,7 @@ bool CefWindowX11::TopLevelAlwaysOnTop() const {
void CefWindowX11::ProcessXEvent(const x11::Event& event) {
if (auto* configure = event.As<x11::ConfigureNotifyEvent>()) {
DCHECK_EQ(xwindow_, configure->event);
DCHECK_EQ(xwindow_, configure->window);
// It's possible that the X window may be resized by some other means
// than from within Aura (e.g. the X window manager can change the
// size). Make sure the root window size is maintained properly.

View File

@@ -31,7 +31,7 @@
#include "cef/grit/cef_resources.h"
#include "chrome/browser/browser_about_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chrome_untrusted_web_ui_configs.h"
#include "chrome/browser/ui/webui/chrome_untrusted_web_ui_controller_factory.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/browser/ui/webui/theme_source.h"
#include "chrome/common/url_constants.h"
@@ -41,7 +41,6 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/webui_config_map.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/common/user_agent.h"
@@ -579,13 +578,12 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
controller = content::ContentWebUIControllerFactory::GetInstance()
->CreateWebUIControllerForURL(web_ui, url);
if (controller)
if (controller.get())
return controller;
controller = content::WebUIConfigMap::GetInstance()
.controller_factory()
controller = ChromeUntrustedWebUIControllerFactory::GetInstance()
->CreateWebUIControllerForURL(web_ui, url);
if (controller)
if (controller.get())
return controller;
return ChromeWebUIControllerFactory::GetInstance()
@@ -608,9 +606,8 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
if (type != content::WebUI::kNoWebUI)
return type;
type = content::WebUIConfigMap::GetInstance()
.controller_factory()
->GetWebUIType(browser_context, url);
type = ChromeUntrustedWebUIControllerFactory::GetInstance()->GetWebUIType(
browser_context, url);
if (type != content::WebUI::kNoWebUI)
return type;
@@ -634,9 +631,8 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
if (content::ContentWebUIControllerFactory::GetInstance()->UseWebUIForURL(
browser_context, url) ||
content::WebUIConfigMap::GetInstance()
.controller_factory()
->UseWebUIForURL(browser_context, url) ||
ChromeUntrustedWebUIControllerFactory::GetInstance()->UseWebUIForURL(
browser_context, url) ||
ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
browser_context, url)) {
return true;
@@ -700,13 +696,9 @@ void RegisterWebUIControllerFactory() {
// Channel all WebUI handling through CefWebUIControllerFactory.
content::WebUIControllerFactory::UnregisterFactoryForTesting(
content::ContentWebUIControllerFactory::GetInstance());
content::WebUIControllerFactory::UnregisterFactoryForTesting(
content::WebUIConfigMap::GetInstance().controller_factory());
content::WebUIControllerFactory::RegisterFactory(
CefWebUIControllerFactory::GetInstance());
RegisterChromeUntrustedWebUIConfigs();
}
void BrowserURLHandlerCreated(content::BrowserURLHandler* handler) {

View File

@@ -315,7 +315,6 @@ class InterceptedRequest : public network::mojom::URLLoader,
bool input_stream_previously_failed_ = false;
bool request_was_redirected_ = false;
int redirect_limit_ = net::URLRequest::kMaxRedirects;
bool redirect_in_progress_ = false;
// To avoid sending multiple OnReceivedError callbacks.
bool sent_error_callback_ = false;
@@ -582,10 +581,7 @@ void InterceptedRequest::OnReceiveResponse(
void InterceptedRequest::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
network::mojom::URLResponseHeadPtr head) {
// Whether to notify the client. True by default so that we always notify for
// internal redirects that originate from the network process (for HSTS, etc).
// False while a redirect is in-progress to avoid duplicate notifications.
bool notify_client = !redirect_in_progress_;
bool needs_callback = false;
current_response_ = std::move(head);
current_body_.reset();
@@ -597,6 +593,8 @@ void InterceptedRequest::OnReceiveRedirect(
current_response_->headers = current_headers_;
current_headers_ = nullptr;
}
} else {
needs_callback = true;
}
if (--redirect_limit_ == 0) {
@@ -608,18 +606,18 @@ void InterceptedRequest::OnReceiveRedirect(
// When we redirect via ContinueToHandleOverrideHeaders the |redirect_info|
// value is sometimes nonsense (HTTP_OK). Also, we won't get another call to
// OnHeadersReceived for the new URL so we need to notify the client here.
// OnHeadersReceived for the new URL so we need to execute the callback here.
if (header_client_redirect_url_.is_valid() &&
redirect_info.status_code == net::HTTP_OK) {
DCHECK(current_request_uses_header_client_);
notify_client = true;
needs_callback = true;
new_redirect_info =
MakeRedirectResponseAndInfo(header_client_redirect_url_);
} else {
new_redirect_info = redirect_info;
}
if (notify_client) {
if (needs_callback) {
HandleResponseOrRedirectHeaders(
new_redirect_info,
base::BindOnce(&InterceptedRequest::ContinueToBeforeRedirect,
@@ -833,9 +831,6 @@ void InterceptedRequest::HandleResponseOrRedirectHeaders(
redirect_url_ = redirect_info.has_value() ? redirect_info->new_url : GURL();
original_url_ = request_.url;
if (!redirect_url_.is_empty())
redirect_in_progress_ = true;
// |current_response_| may be nullptr when called from OnHeadersReceived.
auto headers =
current_response_ ? current_response_->headers : current_headers_;
@@ -935,7 +930,6 @@ void InterceptedRequest::ContinueToBeforeRedirect(
}
request_was_redirected_ = true;
redirect_in_progress_ = false;
if (header_client_redirect_url_.is_valid())
header_client_redirect_url_ = GURL();

View File

@@ -1339,7 +1339,7 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
content::RenderFrameHost* frame = nullptr;
if (request.is_outermost_main_frame ||
if (request.is_main_frame ||
static_cast<blink::mojom::ResourceType>(request.resource_type) ==
blink::mojom::ResourceType::kMainFrame) {
frame = web_contents->GetMainFrame();

View File

@@ -194,6 +194,11 @@ CefEventHandle CefBrowserPlatformDelegateOsr::GetEventHandle(
return native_delegate_->GetEventHandle(event);
}
std::unique_ptr<CefFileDialogRunner>
CefBrowserPlatformDelegateOsr::CreateFileDialogRunner() {
return native_delegate_->CreateFileDialogRunner();
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateOsr::CreateJavaScriptDialogRunner() {
return native_delegate_->CreateJavaScriptDialogRunner();

View File

@@ -49,6 +49,7 @@ class CefBrowserPlatformDelegateOsr
const content::NativeWebKeyboardEvent& event) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
std::unique_ptr<CefFileDialogRunner> CreateFileDialogRunner() override;
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;

View File

@@ -30,33 +30,6 @@ using content::BrowserThread;
using printing::PageRanges;
using printing::PrintSettings;
namespace {
printing::PrintingContextLinux::CreatePrintDialogFunctionPtr
g_default_create_print_dialog_func = nullptr;
printing::PrintingContextLinux::PdfPaperSizeFunctionPtr
g_default_pdf_paper_size_func = nullptr;
CefRefPtr<CefBrowserHostBase> GetBrowserForContext(
printing::PrintingContextLinux* context) {
return extensions::GetOwnerBrowserForGlobalId(
frame_util::MakeGlobalId(context->render_process_id(),
context->render_frame_id()),
nullptr);
}
CefRefPtr<CefPrintHandler> GetPrintHandlerForBrowser(
CefRefPtr<CefBrowserHostBase> browser) {
if (browser) {
if (auto client = browser->GetClient()) {
return client->GetPrintHandler();
}
}
return nullptr;
}
} // namespace
class CefPrintDialogCallbackImpl : public CefPrintDialogCallback {
public:
explicit CefPrintDialogCallbackImpl(CefRefPtr<CefPrintDialogLinux> dialog)
@@ -131,30 +104,7 @@ class CefPrintJobCallbackImpl : public CefPrintJobCallback {
printing::PrintDialogGtkInterface* CefPrintDialogLinux::CreatePrintDialog(
PrintingContextLinux* context) {
CEF_REQUIRE_UIT();
printing::PrintDialogGtkInterface* interface = nullptr;
auto browser = GetBrowserForContext(context);
if (!browser) {
LOG(ERROR) << "No associated browser in CreatePrintDialog; using default "
"printing implementation.";
}
auto handler = GetPrintHandlerForBrowser(browser);
if (!handler) {
if (g_default_create_print_dialog_func) {
interface = g_default_create_print_dialog_func(context);
DCHECK(interface);
}
} else {
interface = new CefPrintDialogLinux(context, browser, handler);
}
if (!interface) {
LOG(ERROR) << "Null interface in CreatePrintDialog; printing will fail.";
}
return interface;
return new CefPrintDialogLinux(context);
}
// static
@@ -164,42 +114,27 @@ gfx::Size CefPrintDialogLinux::GetPdfPaperSize(
gfx::Size size;
auto browser = GetBrowserForContext(context);
if (!browser) {
LOG(ERROR) << "No associated browser in GetPdfPaperSize; using default "
"printing implementation.";
}
auto handler = GetPrintHandlerForBrowser(browser);
if (!handler) {
if (g_default_pdf_paper_size_func) {
size = g_default_pdf_paper_size_func(context);
DCHECK(!size.IsEmpty());
auto browser = extensions::GetOwnerBrowserForGlobalId(
frame_util::MakeGlobalId(context->render_process_id(),
context->render_frame_id()),
nullptr);
DCHECK(browser);
if (browser && browser->GetClient()) {
if (auto handler = browser->GetClient()->GetPrintHandler()) {
const printing::PrintSettings& settings = context->settings();
CefSize cef_size = handler->GetPdfPaperSize(
browser.get(), settings.device_units_per_inch());
size.SetSize(cef_size.width, cef_size.height);
}
} else {
const printing::PrintSettings& settings = context->settings();
CefSize cef_size = handler->GetPdfPaperSize(
browser.get(), settings.device_units_per_inch());
size.SetSize(cef_size.width, cef_size.height);
}
if (size.IsEmpty()) {
LOG(ERROR) << "Empty size value returned in GetPdfPaperSize; PDF printing "
"will fail.";
LOG(ERROR) << "Empty size value returned in GetPdfPaperSize; "
"PDF printing will fail.";
}
return size;
}
// static
void CefPrintDialogLinux::SetDefaultPrintingContextFuncs(
printing::PrintingContextLinux::CreatePrintDialogFunctionPtr
create_print_dialog_func,
printing::PrintingContextLinux::PdfPaperSizeFunctionPtr
pdf_paper_size_func) {
g_default_create_print_dialog_func = create_print_dialog_func;
g_default_pdf_paper_size_func = pdf_paper_size_func;
}
// static
void CefPrintDialogLinux::OnPrintStart(CefRefPtr<CefBrowserHostBase> browser) {
CEF_REQUIRE_UIT();
@@ -211,13 +146,14 @@ void CefPrintDialogLinux::OnPrintStart(CefRefPtr<CefBrowserHostBase> browser) {
}
}
CefPrintDialogLinux::CefPrintDialogLinux(PrintingContextLinux* context,
CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefPrintHandler> handler)
: context_(context), browser_(browser), handler_(handler) {
CefPrintDialogLinux::CefPrintDialogLinux(PrintingContextLinux* context)
: context_(context) {
DCHECK(context_);
browser_ = extensions::GetOwnerBrowserForGlobalId(
frame_util::MakeGlobalId(context_->render_process_id(),
context_->render_frame_id()),
nullptr);
DCHECK(browser_);
DCHECK(handler_);
}
CefPrintDialogLinux::~CefPrintDialogLinux() {
@@ -225,7 +161,7 @@ CefPrintDialogLinux::~CefPrintDialogLinux() {
// object because the PrintJobWorker which owns |context_| may already have
// been deleted.
CEF_REQUIRE_UIT();
handler_->OnPrintReset(browser_.get());
ReleaseHandler();
}
void CefPrintDialogLinux::UseDefaultSettings() {
@@ -243,6 +179,12 @@ void CefPrintDialogLinux::ShowDialog(
PrintingContextLinux::PrintSettingsCallback callback) {
CEF_REQUIRE_UIT();
SetHandler();
if (!handler_.get()) {
std::move(callback).Run(printing::mojom::ResultCode::kCanceled);
return;
}
callback_ = std::move(callback);
CefRefPtr<CefPrintDialogCallbackImpl> callback_impl(
@@ -298,11 +240,31 @@ void CefPrintDialogLinux::ReleaseDialog() {
Release();
}
void CefPrintDialogLinux::SetHandler() {
if (handler_.get())
return;
if (browser_ && browser_->GetClient()) {
handler_ = browser_->GetClient()->GetPrintHandler();
}
}
void CefPrintDialogLinux::ReleaseHandler() {
if (handler_.get()) {
handler_->OnPrintReset(browser_.get());
handler_ = nullptr;
}
}
bool CefPrintDialogLinux::UpdateSettings(
std::unique_ptr<PrintSettings> settings,
bool get_defaults) {
CEF_REQUIRE_UIT();
SetHandler();
if (!handler_.get())
return false;
CefRefPtr<CefPrintSettingsImpl> settings_impl(
new CefPrintSettingsImpl(std::move(settings), false));
handler_->OnPrintSettings(browser_.get(), settings_impl.get(), get_defaults);

View File

@@ -39,13 +39,6 @@ class CefPrintDialogLinux : public printing::PrintDialogGtkInterface,
// Returns the paper size in device units.
static gfx::Size GetPdfPaperSize(printing::PrintingContextLinux* context);
// Used for calling into the default GTK implementation.
static void SetDefaultPrintingContextFuncs(
printing::PrintingContextLinux::CreatePrintDialogFunctionPtr
create_print_dialog_func,
printing::PrintingContextLinux::PdfPaperSizeFunctionPtr
pdf_paper_size_func);
// Notify the client when printing has started.
static void OnPrintStart(CefRefPtr<CefBrowserHostBase> browser);
@@ -72,11 +65,12 @@ class CefPrintDialogLinux : public printing::PrintDialogGtkInterface,
friend class CefPrintDialogCallbackImpl;
friend class CefPrintJobCallbackImpl;
CefPrintDialogLinux(PrintingContextLinux* context,
CefRefPtr<CefBrowserHostBase> browser,
CefRefPtr<CefPrintHandler> handler);
explicit CefPrintDialogLinux(PrintingContextLinux* context);
~CefPrintDialogLinux() override;
void SetHandler();
void ReleaseHandler();
bool UpdateSettings(std::unique_ptr<printing::PrintSettings> settings,
bool get_defaults);
@@ -90,12 +84,12 @@ class CefPrintDialogLinux : public printing::PrintDialogGtkInterface,
// Handles print job response.
void OnJobCompleted();
CefRefPtr<CefPrintHandler> handler_;
// Printing dialog callback.
PrintingContextLinux::PrintSettingsCallback callback_;
PrintingContextLinux* context_;
CefRefPtr<CefBrowserHostBase> browser_;
CefRefPtr<CefPrintHandler> handler_;
base::FilePath path_to_pdf_;
};

View File

@@ -56,8 +56,8 @@ views::BoxLayout* CefBoxLayoutImpl::CreateLayout() {
views::BoxLayout* layout = new views::BoxLayout(
settings_.horizontal ? views::BoxLayout::Orientation::kHorizontal
: views::BoxLayout::Orientation::kVertical,
gfx::Insets::VH(settings_.inside_border_vertical_spacing,
settings_.inside_border_horizontal_spacing),
gfx::Insets(settings_.inside_border_vertical_spacing,
settings_.inside_border_horizontal_spacing),
settings_.between_child_spacing);
layout->set_main_axis_alignment(
static_cast<views::BoxLayout::MainAxisAlignment>(
@@ -65,7 +65,7 @@ views::BoxLayout* CefBoxLayoutImpl::CreateLayout() {
layout->set_cross_axis_alignment(
static_cast<views::BoxLayout::CrossAxisAlignment>(
settings_.cross_axis_alignment));
layout->set_inside_border_insets(gfx::Insets::TLBR(
layout->set_inside_border_insets(gfx::Insets(
settings_.inside_border_insets.top, settings_.inside_border_insets.left,
settings_.inside_border_insets.bottom,
settings_.inside_border_insets.right));

View File

@@ -257,6 +257,11 @@ CefEventHandle CefBrowserPlatformDelegateViews::GetEventHandle(
return native_delegate_->GetEventHandle(event);
}
std::unique_ptr<CefFileDialogRunner>
CefBrowserPlatformDelegateViews::CreateFileDialogRunner() {
return native_delegate_->CreateFileDialogRunner();
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateViews::CreateJavaScriptDialogRunner() {
return native_delegate_->CreateJavaScriptDialogRunner();

View File

@@ -60,6 +60,7 @@ class CefBrowserPlatformDelegateViews
const content::NativeWebKeyboardEvent& event) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
std::unique_ptr<CefFileDialogRunner> CreateFileDialogRunner() override;
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
override;
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;

View File

@@ -23,8 +23,8 @@ CefRefPtr<CefBrowserView> CefBrowserView::CreateBrowserView(
CefRefPtr<CefDictionaryValue> extra_info,
CefRefPtr<CefRequestContext> request_context,
CefRefPtr<CefBrowserViewDelegate> delegate) {
return CefBrowserViewImpl::Create(CefWindowInfo(), client, url, settings,
extra_info, request_context, delegate);
return CefBrowserViewImpl::Create(client, url, settings, extra_info,
request_context, delegate);
}
// static
@@ -41,7 +41,6 @@ CefRefPtr<CefBrowserView> CefBrowserView::GetForBrowser(
// static
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
const CefWindowInfo& window_info,
CefRefPtr<CefClient> client,
const CefString& url,
const CefBrowserSettings& settings,
@@ -63,8 +62,8 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
}
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
browser_view->SetPendingBrowserCreateParams(
window_info, client, url, settings, extra_info, request_context);
browser_view->SetPendingBrowserCreateParams(client, url, settings, extra_info,
request_context);
browser_view->Initialize();
browser_view->SetDefaults(settings);
return browser_view;
@@ -213,7 +212,6 @@ CefBrowserViewImpl::CefBrowserViewImpl(
: ParentClass(delegate), weak_ptr_factory_(this) {}
void CefBrowserViewImpl::SetPendingBrowserCreateParams(
const CefWindowInfo& window_info,
CefRefPtr<CefClient> client,
const CefString& url,
const CefBrowserSettings& settings,
@@ -221,7 +219,6 @@ void CefBrowserViewImpl::SetPendingBrowserCreateParams(
CefRefPtr<CefRequestContext> request_context) {
DCHECK(!pending_browser_create_params_);
pending_browser_create_params_.reset(new CefBrowserCreateParams());
pending_browser_create_params_->MaybeSetWindowInfo(window_info);
pending_browser_create_params_->client = client;
pending_browser_create_params_->url = url;
pending_browser_create_params_->settings = settings;
@@ -251,9 +248,6 @@ void CefBrowserViewImpl::InitializeRootView() {
}
views::WebView* CefBrowserViewImpl::web_view() const {
if (!root_view())
return nullptr;
if (cef::IsChromeRuntimeEnabled()) {
return static_cast<ChromeBrowserView*>(root_view())->contents_web_view();
}

View File

@@ -30,9 +30,7 @@ class CefBrowserViewImpl
CefBrowserViewImpl& operator=(const CefBrowserViewImpl&) = delete;
// Create a new CefBrowserView instance. |delegate| may be nullptr.
// |window_info| will only be used when creating a Chrome child window.
static CefRefPtr<CefBrowserViewImpl> Create(
const CefWindowInfo& window_info,
CefRefPtr<CefClient> client,
const CefString& url,
const CefBrowserSettings& settings,
@@ -86,7 +84,6 @@ class CefBrowserViewImpl
explicit CefBrowserViewImpl(CefRefPtr<CefBrowserViewDelegate> delegate);
void SetPendingBrowserCreateParams(
const CefWindowInfo& window_info,
CefRefPtr<CefClient> client,
const CefString& url,
const CefBrowserSettings& settings,

View File

@@ -576,8 +576,7 @@ CEF_VIEW_IMPL_T CefPoint CEF_VIEW_IMPL_D::GetPosition() {
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetInsets(const CefInsets& insets) {
CEF_REQUIRE_VALID_RETURN_VOID();
const gfx::Insets& gfx_insets =
gfx::Insets::TLBR(insets.top, insets.left, insets.bottom, insets.right);
gfx::Insets gfx_insets(insets.top, insets.left, insets.bottom, insets.right);
root_view()->SetBorder(
gfx_insets.IsEmpty() ? nullptr : views::CreateEmptyBorder(gfx_insets));
}

View File

@@ -9,7 +9,6 @@
#include "include/views/cef_view.h"
#include "include/views/cef_window.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/view.h"
namespace display {
@@ -124,9 +123,6 @@ gfx::NativeView GetNativeView(views::Widget* widget);
// Returns the platform window handle for |widget|. May return nullptr.
CefWindowHandle GetWindowHandle(views::Widget* widget);
// Returns the platform window handle for |window|. May return nullptr.
CefWindowHandle GetWindowHandle(gfx::NativeWindow window);
} // namespace view_util
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_UTIL_H_

View File

@@ -26,15 +26,9 @@ gfx::NativeView GetNativeView(views::Widget* widget) {
CefWindowHandle GetWindowHandle(views::Widget* widget) {
// Same implementation as views::HWNDForView() but cross-platform.
if (widget) {
return GetWindowHandle(widget->GetNativeWindow());
}
return kNullWindowHandle;
}
CefWindowHandle GetWindowHandle(gfx::NativeWindow window) {
// |window| is an aura::Window*.
if (window && window->GetRootWindow()) {
return window->GetHost()->GetAcceleratedWidget();
aura::Window* window = widget->GetNativeWindow();
if (window && window->GetRootWindow())
return window->GetHost()->GetAcceleratedWidget();
}
return kNullWindowHandle;
}

View File

@@ -4,8 +4,6 @@
#include "libcef/browser/views/view_util.h"
#import <Cocoa/Cocoa.h>
#include "include/internal/cef_types_mac.h"
#include "ui/views/widget/widget.h"
@@ -25,20 +23,10 @@ gfx::NativeView GetNativeView(views::Widget* widget) {
}
CefWindowHandle GetWindowHandle(views::Widget* widget) {
// |view| is a wrapper type from native_widget_types.h.
auto view = GetNativeView(widget);
if (view)
return CAST_NSVIEW_TO_CEF_WINDOW_HANDLE(view.GetNativeNSView());
return kNullWindowHandle;
}
CefWindowHandle GetWindowHandle(gfx::NativeWindow window) {
// |window| is a wrapper type from native_widget_types.h.
if (window) {
NSWindow* nswindow = window.GetNativeNSWindow();
return CAST_NSVIEW_TO_CEF_WINDOW_HANDLE([nswindow contentView]);
}
return kNullWindowHandle;
}
} // namespace view_util

View File

@@ -125,17 +125,16 @@ class CefUnhandledKeyEventHandler : public ui::EventHandler {
// static
CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindow(
CefRefPtr<CefWindowDelegate> delegate) {
return CefWindowImpl::Create(delegate, gfx::kNullAcceleratedWidget);
return CefWindowImpl::Create(delegate);
}
// static
CefRefPtr<CefWindowImpl> CefWindowImpl::Create(
CefRefPtr<CefWindowDelegate> delegate,
gfx::AcceleratedWidget parent_widget) {
CefRefPtr<CefWindowDelegate> delegate) {
CEF_REQUIRE_UIT_RETURN(nullptr);
CefRefPtr<CefWindowImpl> window = new CefWindowImpl(delegate);
window->Initialize();
window->CreateWidget(parent_widget);
window->CreateWidget();
if (delegate)
delegate->OnWindowCreated(window.get());
return window;
@@ -657,10 +656,10 @@ void CefWindowImpl::InitializeRootView() {
static_cast<CefWindowView*>(root_view())->Initialize();
}
void CefWindowImpl::CreateWidget(gfx::AcceleratedWidget parent_widget) {
void CefWindowImpl::CreateWidget() {
DCHECK(!widget_);
root_view()->CreateWidget(parent_widget);
root_view()->CreateWidget();
widget_ = root_view()->GetWidget();
DCHECK(widget_);

View File

@@ -33,10 +33,8 @@ class CefWindowImpl
CefWindowImpl(const CefWindowImpl&) = delete;
CefWindowImpl& operator=(const CefWindowImpl&) = delete;
// Create a new CefWindow instance. |delegate| may be nullptr. |parent_widget|
// will be used when creating a Chrome child window.
static CefRefPtr<CefWindowImpl> Create(CefRefPtr<CefWindowDelegate> delegate,
gfx::AcceleratedWidget parent_widget);
// Create a new CefWindow instance. |delegate| may be nullptr.
static CefRefPtr<CefWindowImpl> Create(CefRefPtr<CefWindowDelegate> delegate);
// CefWindow methods:
void Show() override;
@@ -143,7 +141,7 @@ class CefWindowImpl
void InitializeRootView() override;
// Initialize the Widget.
void CreateWidget(gfx::AcceleratedWidget parent_widget);
void CreateWidget();
views::Widget* widget_;

Some files were not shown because too many files have changed in this diff Show More