mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f249b2e034 | ||
|
1c5e658496 | ||
|
60bd108421 | ||
|
7bb810979a | ||
|
4209780760 | ||
|
f11ca748ed | ||
|
4981a5212d | ||
|
53d4ce97cc | ||
|
c41ac522c4 | ||
|
0aa55085cb | ||
|
7702d96b33 | ||
|
b62dd2b6ee | ||
|
916360e2e5 | ||
|
b318adddac | ||
|
c1b06ccee8 | ||
|
c04895b222 | ||
|
2ea7459a89 | ||
|
edef01f579 | ||
|
b1cd9d1598 | ||
|
d6b2b4b144 | ||
|
cbf66a8077 | ||
|
fc82de7aa7 | ||
|
111b6de46c | ||
|
512e588e40 | ||
|
4921dc2213 | ||
|
d8db6fa9da | ||
|
493232ce5a | ||
|
17cb26b8b9 | ||
|
a0a7a35fe2 | ||
|
75ca552a4e | ||
|
3000bc8748 | ||
|
5f4bccd672 | ||
|
0428438e72 | ||
|
21cf732e7f |
354
BUILD.gn
354
BUILD.gn
@@ -257,6 +257,9 @@ 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)
|
||||
@@ -411,8 +414,6 @@ 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",
|
||||
@@ -469,6 +470,22 @@ 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",
|
||||
@@ -531,9 +548,10 @@ 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",
|
||||
@@ -567,6 +585,8 @@ 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",
|
||||
@@ -657,6 +677,63 @@ 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",
|
||||
@@ -796,6 +873,14 @@ 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 += [
|
||||
@@ -912,6 +997,7 @@ static_library("libcef_static") {
|
||||
"//third_party/zlib:minizip",
|
||||
"//ui/base",
|
||||
"//ui/base/ime",
|
||||
"//ui/events",
|
||||
"//ui/events:events_base",
|
||||
"//ui/gfx",
|
||||
"//ui/gfx/geometry",
|
||||
@@ -919,6 +1005,9 @@ static_library("libcef_static") {
|
||||
"//ui/gfx/ipc/geometry",
|
||||
"//ui/gfx/ipc/skia",
|
||||
"//ui/gl",
|
||||
"//ui/strings",
|
||||
"//ui/views",
|
||||
"//ui/views/controls/webview",
|
||||
"//url",
|
||||
"//v8",
|
||||
]
|
||||
@@ -929,8 +1018,6 @@ 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",
|
||||
@@ -1002,20 +1089,29 @@ 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",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1027,204 +1123,92 @@ static_library("libcef_static") {
|
||||
deps += [ "//tools/v8_context_snapshot" ]
|
||||
}
|
||||
|
||||
if (toolkit_views) {
|
||||
if (use_aura) {
|
||||
sources += [
|
||||
"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",
|
||||
"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",
|
||||
|
||||
# Part of //ui/views:test_support which is testingonly.
|
||||
"//ui/views/test/desktop_test_views_delegate.h",
|
||||
"//ui/views/test/test_views_delegate.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.h",
|
||||
"//ui/base/test/ui_controls_aura.cc",
|
||||
"//ui/aura/test/ui_controls_factory_aura.h",
|
||||
]
|
||||
|
||||
deps += [
|
||||
"//ui/events",
|
||||
"//ui/strings",
|
||||
"//ui/views",
|
||||
"//ui/views/controls/webview",
|
||||
"//ui/aura",
|
||||
"//ui/wm",
|
||||
"//ui/wm/public",
|
||||
]
|
||||
|
||||
if (use_aura) {
|
||||
if (is_win) {
|
||||
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",
|
||||
|
||||
# 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",
|
||||
|
||||
# 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_aura.cc",
|
||||
"//ui/aura/test/ui_controls_factory_aura.h",
|
||||
"//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/aura",
|
||||
"//ui/wm",
|
||||
"//ui/wm/public",
|
||||
"//ui/ozone:generate_test_support_constructor_list",
|
||||
]
|
||||
|
||||
if (is_win) {
|
||||
if (ozone_platform_x11) {
|
||||
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/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/ui_controls_factory_aurawin.cc",
|
||||
"//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/base/test/ui_controls_internal_win.cc",
|
||||
"//ui/base/test/ui_controls_internal_win.h",
|
||||
"//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_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",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1382,7 +1366,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/resources/grit/webui_resources.h",
|
||||
"$root_gen_dir/ui/views/resources/grit/views_resources.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
@@ -1409,13 +1393,8 @@ make_pack_header("resources") {
|
||||
"//third_party/blink/public:resources",
|
||||
"//ui/resources:ui_resources_grd",
|
||||
"//ui/resources:webui_generated_resources_grd",
|
||||
"//ui/resources:webui_resources_grd",
|
||||
"//ui/views/resources: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.
|
||||
@@ -1565,8 +1544,6 @@ 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",
|
||||
]
|
||||
@@ -1574,7 +1551,6 @@ if (is_mac) {
|
||||
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
|
||||
]
|
||||
public_deps = [
|
||||
"//ui/gl:swiftshader_egl_library_copy",
|
||||
"//ui/gl:swiftshader_vk_library_copy",
|
||||
]
|
||||
}
|
||||
|
@@ -7,5 +7,6 @@
|
||||
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
|
||||
|
||||
{
|
||||
'chromium_checkout': 'refs/tags/101.0.4951.0'
|
||||
'chromium_checkout': 'refs/tags/102.0.5005.115',
|
||||
'depot_tools_checkout': '583ca66091'
|
||||
}
|
||||
|
@@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
python tools/gclient_hook.py
|
||||
python3 tools/gclient_hook.py
|
||||
|
@@ -227,7 +227,6 @@ if(OS_LINUX)
|
||||
snapshot_blob.bin
|
||||
v8_context_snapshot.bin
|
||||
vk_swiftshader_icd.json
|
||||
swiftshader
|
||||
)
|
||||
|
||||
# List of CEF resource files.
|
||||
@@ -476,7 +475,6 @@ if(OS_WINDOWS)
|
||||
vk_swiftshader.dll
|
||||
vk_swiftshader_icd.json
|
||||
vulkan-1.dll
|
||||
swiftshader
|
||||
)
|
||||
|
||||
if(NOT PROJECT_ARCH STREQUAL "arm64")
|
||||
|
@@ -1189,7 +1189,11 @@ struct AssertBindArgsValidity<std::index_sequence<Ns...>,
|
||||
TypeList<Args...>,
|
||||
TypeList<Unwrapped...>,
|
||||
TypeList<Params...>>
|
||||
: AssertConstructible<Ns, Args, std::decay_t<Args>, Unwrapped, Params>... {
|
||||
: AssertConstructible<static_cast<int>(Ns),
|
||||
Args,
|
||||
std::decay_t<Args>,
|
||||
Unwrapped,
|
||||
Params>... {
|
||||
static constexpr bool ok = true;
|
||||
};
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=b80e84c0039ab45d5c4562d64b67a84766c0dab3$
|
||||
// $hash=b1c1e44e6d3842064ef6e5b9823173f7ec1fcccc$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
||||
@@ -205,15 +205,12 @@ typedef struct _cef_run_file_dialog_callback_t {
|
||||
cef_base_ref_counted_t base;
|
||||
|
||||
///
|
||||
// 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.
|
||||
// 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.
|
||||
///
|
||||
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;
|
||||
|
||||
@@ -391,11 +388,10 @@ 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").
|
||||
// |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.
|
||||
// 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.
|
||||
///
|
||||
void(CEF_CALLBACK* run_file_dialog)(
|
||||
struct _cef_browser_host_t* self,
|
||||
@@ -403,7 +399,6 @@ 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);
|
||||
|
||||
///
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=0f56154217707d141912dc8a298279df8df04311$
|
||||
// $hash=dc579beb1f25f9bbdb72afb4b5b381e129f84e31$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_DIALOG_HANDLER_CAPI_H_
|
||||
@@ -57,14 +57,11 @@ typedef struct _cef_file_dialog_callback_t {
|
||||
cef_base_ref_counted_t base;
|
||||
|
||||
///
|
||||
// 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().
|
||||
// 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().
|
||||
///
|
||||
void(CEF_CALLBACK* cont)(struct _cef_file_dialog_callback_t* self,
|
||||
int selected_accept_filter,
|
||||
cef_string_list_t file_paths);
|
||||
|
||||
///
|
||||
@@ -93,10 +90,9 @@ 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"). |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).
|
||||
// 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).
|
||||
///
|
||||
int(CEF_CALLBACK* on_file_dialog)(
|
||||
struct _cef_dialog_handler_t* self,
|
||||
@@ -105,7 +101,6 @@ 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;
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=cd5d7c4e83237ceb39c5639489ca6004d2d69f0c$
|
||||
// $hash=7f88c6428929c0511ff90b6137efcc4cebcfeae4$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
|
||||
@@ -73,6 +73,14 @@ 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|
|
||||
|
@@ -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 "34a42688778747c68f31e0194fea8323bc5388dc"
|
||||
#define CEF_API_HASH_UNIVERSAL "b6255e15aa977a7214cf28e4e1a2372b454838d4"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "c78306ad4768dc6c4ca1c376fa4c3799db8fd0eb"
|
||||
#define CEF_API_HASH_PLATFORM "b262c3a2cbd2632de1bfed887da8b8114c9ecbf5"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "c25d8bb5b7118a8f50c84e8a2746b2a14d7193ef"
|
||||
#define CEF_API_HASH_PLATFORM "fd6d3d83442fe31ad26d5648755e0cf2e14a7fc7"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "742fc8a47e757e34a87c7c814fc884591d5e9f98"
|
||||
#define CEF_API_HASH_PLATFORM "d686964de5e01eed900d78d5f8a7da9f8fc3a777"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -206,14 +206,11 @@ 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(index_param=selected_accept_filter,optional_param=file_paths)--*/
|
||||
/*--cef(optional_param=file_paths)--*/
|
||||
virtual void OnFileDialogDismissed(
|
||||
int selected_accept_filter,
|
||||
const std::vector<CefString>& file_paths) = 0;
|
||||
};
|
||||
|
||||
@@ -421,19 +418,17 @@ 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").
|
||||
// |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.
|
||||
// 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.
|
||||
///
|
||||
/*--cef(optional_param=title,optional_param=default_file_path,
|
||||
optional_param=accept_filters,index_param=selected_accept_filter)--*/
|
||||
optional_param=accept_filters)--*/
|
||||
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;
|
||||
|
||||
///
|
||||
|
@@ -48,16 +48,12 @@
|
||||
class CefFileDialogCallback : public virtual CefBaseRefCounted {
|
||||
public:
|
||||
///
|
||||
// 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
|
||||
// Continue the file selection. |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,index_param=selected_accept_filter,
|
||||
optional_param=file_paths)--*/
|
||||
virtual void Continue(int selected_accept_filter,
|
||||
const std::vector<CefString>& file_paths) = 0;
|
||||
/*--cef(capi_name=cont,optional_param=file_paths)--*/
|
||||
virtual void Continue(const std::vector<CefString>& file_paths) = 0;
|
||||
|
||||
///
|
||||
// Cancel the file selection.
|
||||
@@ -85,19 +81,17 @@ 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"). |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.
|
||||
// "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.
|
||||
///
|
||||
/*--cef(optional_param=title,optional_param=default_file_path,
|
||||
optional_param=accept_filters,index_param=selected_accept_filter)--*/
|
||||
optional_param=accept_filters)--*/
|
||||
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;
|
||||
}
|
||||
|
@@ -99,6 +99,9 @@ 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.
|
||||
///
|
||||
|
@@ -100,6 +100,9 @@ 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.
|
||||
///
|
||||
|
@@ -584,10 +584,16 @@ class CefStringBase {
|
||||
return NULL;
|
||||
|
||||
userfree_struct_type str = traits::userfree_alloc();
|
||||
memcpy(str, string_, sizeof(struct_type));
|
||||
if (owner_) {
|
||||
// Transfer ownership of the data to |str|.
|
||||
memcpy(str, string_, sizeof(struct_type));
|
||||
// Free this class' structure but not the data.
|
||||
memset(string_, 0, sizeof(struct_type));
|
||||
} else {
|
||||
// Copy the data to |str|.
|
||||
traits::set(string_->str, string_->length, str, /*copy=*/true);
|
||||
}
|
||||
|
||||
// Free this class' structure but not the data.
|
||||
memset(string_, 0, sizeof(struct_type));
|
||||
ClearAndFree();
|
||||
|
||||
return str;
|
||||
|
@@ -2237,26 +2237,6 @@ 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;
|
||||
|
||||
///
|
||||
@@ -3122,8 +3102,14 @@ 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_BITSTREAM
|
||||
CEF_CHANNEL_LAYOUT_MAX = CEF_CHANNEL_LAYOUT_5_1_4_DOWNMIX
|
||||
} cef_channel_layout_t;
|
||||
|
||||
///
|
||||
|
@@ -102,6 +102,9 @@ 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.
|
||||
///
|
||||
|
@@ -63,6 +63,13 @@ 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|
|
||||
|
@@ -18,7 +18,6 @@
|
||||
#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"
|
||||
@@ -33,9 +32,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"
|
||||
@@ -47,12 +46,11 @@
|
||||
#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;
|
||||
@@ -86,48 +84,6 @@ 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
|
||||
@@ -243,7 +199,15 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::CreateInternal(
|
||||
// Notify that the browser has been created. These must be delivered in the
|
||||
// expected order.
|
||||
|
||||
// 1. Notify the browser's LifeSpanHandler. This must always be the first
|
||||
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
|
||||
// notification for the browser. Block navigation to avoid issues with focus
|
||||
// changes being sent to an unbound interface.
|
||||
{
|
||||
@@ -251,17 +215,10 @@ CefRefPtr<AlloyBrowserHostImpl> AlloyBrowserHostImpl::CreateInternal(
|
||||
browser->OnAfterCreated();
|
||||
}
|
||||
|
||||
// 2. Notify the platform delegate. With Views this will result in a call to
|
||||
// 3. 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;
|
||||
}
|
||||
|
||||
@@ -355,20 +312,6 @@ 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
|
||||
@@ -406,27 +349,6 @@ 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));
|
||||
@@ -664,20 +586,6 @@ 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()) {
|
||||
@@ -738,8 +646,6 @@ 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())
|
||||
@@ -822,13 +728,6 @@ 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) {
|
||||
@@ -1350,8 +1249,9 @@ void AlloyBrowserHostImpl::RunFileChooser(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
const blink::mojom::FileChooserParams& params) {
|
||||
EnsureFileDialogManager();
|
||||
file_dialog_manager_->RunFileChooser(listener, params);
|
||||
// This will eventually call into CefFileDialogManager.
|
||||
FileSelectHelper::RunFileChooser(render_frame_host, std::move(listener),
|
||||
params);
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::HandleContextMenu(
|
||||
@@ -1490,19 +1390,6 @@ 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()) {
|
||||
@@ -1660,11 +1547,3 @@ 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()));
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#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"
|
||||
@@ -79,17 +78,10 @@ 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,
|
||||
@@ -113,7 +105,6 @@ 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,
|
||||
@@ -180,12 +171,6 @@ 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);
|
||||
|
||||
@@ -293,8 +278,6 @@ 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;
|
||||
@@ -333,14 +316,9 @@ 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;
|
||||
@@ -355,9 +333,6 @@ 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_;
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#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"
|
||||
@@ -58,14 +59,12 @@
|
||||
#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"
|
||||
@@ -77,11 +76,23 @@
|
||||
|
||||
#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)
|
||||
@@ -92,6 +103,75 @@
|
||||
#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)) {}
|
||||
@@ -100,16 +180,6 @@ 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)
|
||||
@@ -118,14 +188,16 @@ 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
|
||||
#endif // defined(TOOLKIT_VIEWS)
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
ToolkitInitializedLinux();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AlloyBrowserMainParts::PreCreateMainMessageLoop() {
|
||||
@@ -152,11 +224,6 @@ 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();
|
||||
|
||||
@@ -245,6 +312,7 @@ int AlloyBrowserMainParts::PreMainMessageLoopRun() {
|
||||
PluginFinder::GetInstance()->Init();
|
||||
|
||||
scheme::RegisterWebUIControllerFactory();
|
||||
file_dialog_runner::RegisterFactory();
|
||||
|
||||
#if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM) || \
|
||||
BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
|
||||
@@ -277,10 +345,8 @@ 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)
|
||||
}
|
||||
|
@@ -24,14 +24,12 @@ 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;
|
||||
|
||||
@@ -44,7 +42,6 @@ class AlloyBrowserMainParts : public content::BrowserMainParts {
|
||||
|
||||
~AlloyBrowserMainParts() override;
|
||||
|
||||
int PreEarlyInitialization() override;
|
||||
void ToolkitInitialized() override;
|
||||
void PreCreateMainMessageLoop() override;
|
||||
void PostCreateMainMessageLoop() override;
|
||||
@@ -92,12 +89,10 @@ 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_
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#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"
|
||||
@@ -68,6 +69,7 @@
|
||||
#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"
|
||||
@@ -432,6 +434,11 @@ 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.
|
||||
@@ -576,6 +583,12 @@ 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(
|
||||
@@ -1392,6 +1405,9 @@ void AlloyContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(
|
||||
CefBrowserFrame::RegisterBrowserInterfaceBindersForFrame(render_frame_host,
|
||||
map);
|
||||
|
||||
map->Add<media::mojom::MediaFoundationRendererNotifier>(
|
||||
base::BindRepeating(&BindMediaFoundationRendererNotifierHandler));
|
||||
|
||||
if (!extensions::ExtensionsEnabled())
|
||||
return;
|
||||
|
||||
|
@@ -58,6 +58,8 @@ 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;
|
||||
|
@@ -1,49 +0,0 @@
|
||||
// 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
|
@@ -1,37 +0,0 @@
|
||||
// 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_
|
@@ -25,7 +25,6 @@
|
||||
#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"
|
||||
@@ -112,10 +111,15 @@ void CefBrowserPlatformDelegateAlloy::WebContentsCreated(
|
||||
content::WebContents* web_contents,
|
||||
bool owned) {
|
||||
CefBrowserPlatformDelegate::WebContentsCreated(web_contents, owned);
|
||||
find_in_page::FindTabHelper::CreateForWebContents(web_contents);
|
||||
|
||||
if (owned) {
|
||||
SetOwnedWebContents(web_contents);
|
||||
if (primary_) {
|
||||
find_in_page::FindTabHelper::CreateForWebContents(web_contents);
|
||||
|
||||
if (owned) {
|
||||
SetOwnedWebContents(web_contents);
|
||||
}
|
||||
} else {
|
||||
DCHECK(!owned);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,14 +161,6 @@ 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();
|
||||
}
|
||||
@@ -261,14 +257,11 @@ void CefBrowserPlatformDelegateAlloy::SendCaptureLostEvent() {
|
||||
|
||||
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))
|
||||
void CefBrowserPlatformDelegateAlloy::NotifyMoveOrResizeStarted() {
|
||||
if (!browser_)
|
||||
if (!web_contents_)
|
||||
return;
|
||||
|
||||
// Dismiss any existing popups.
|
||||
auto frame = browser_->GetMainFrame();
|
||||
if (frame && frame->IsValid()) {
|
||||
static_cast<CefFrameHostImpl*>(frame.get())->NotifyMoveOrResizeStarted();
|
||||
}
|
||||
web_contents_->ClearFocusedElement();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -35,7 +35,6 @@ 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,
|
||||
|
@@ -129,13 +129,12 @@ base::Time ChromeProfileAlloy::GetStartTime() const {
|
||||
}
|
||||
|
||||
base::FilePath ChromeProfileAlloy::last_selected_directory() {
|
||||
NOTREACHED();
|
||||
return base::FilePath();
|
||||
return last_selected_directory_;
|
||||
}
|
||||
|
||||
void ChromeProfileAlloy::set_last_selected_directory(
|
||||
const base::FilePath& path) {
|
||||
NOTREACHED();
|
||||
last_selected_directory_ = path;
|
||||
}
|
||||
|
||||
GURL ChromeProfileAlloy::GetHomePage() {
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#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
|
||||
@@ -54,6 +55,7 @@ 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_
|
||||
|
@@ -7,8 +7,10 @@
|
||||
#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"
|
||||
@@ -19,12 +21,60 @@
|
||||
#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) {
|
||||
@@ -52,6 +102,10 @@ 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();
|
||||
}
|
||||
@@ -265,6 +319,8 @@ void CefBrowserContentsDelegate::RenderFrameCreated(
|
||||
}
|
||||
render_view_host->GetWidget()->GetView()->SetBackgroundColor(
|
||||
base_background_color);
|
||||
|
||||
platform_delegate()->RenderViewCreated(render_view_host);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +350,14 @@ 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());
|
||||
@@ -421,6 +484,10 @@ void CefBrowserContentsDelegate::DidFinishNavigation(
|
||||
// history state).
|
||||
if (!navigation_handle->IsSameDocument()) {
|
||||
OnLoadStart(frame.get(), navigation_handle->GetPageTransition());
|
||||
if (navigation_handle->IsServedFromBackForwardCache()) {
|
||||
// We won't get an OnLoadEnd notification from anywhere else.
|
||||
OnLoadEnd(frame.get(), navigation_handle->GetURL(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_main_frame) {
|
||||
|
@@ -120,6 +120,8 @@ 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;
|
||||
|
@@ -20,11 +20,14 @@
|
||||
#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"
|
||||
@@ -194,6 +197,45 @@ 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(
|
||||
@@ -377,6 +419,20 @@ 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(
|
||||
@@ -777,6 +833,45 @@ 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,
|
||||
@@ -805,6 +900,13 @@ 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);
|
||||
}
|
||||
@@ -836,7 +938,6 @@ content::BrowserContext* CefBrowserHostBase::GetBrowserContext() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
views::Widget* CefBrowserHostBase::GetWindowWidget() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!platform_delegate_)
|
||||
@@ -850,7 +951,29 @@ CefRefPtr<CefBrowserView> CefBrowserHostBase::GetBrowserView() const {
|
||||
return platform_delegate_->GetBrowserView();
|
||||
return nullptr;
|
||||
}
|
||||
#endif // defined(TOOLKIT_VIEWS)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::EnsureDevToolsManager() {
|
||||
CEF_REQUIRE_UIT();
|
||||
@@ -858,7 +981,7 @@ bool CefBrowserHostBase::EnsureDevToolsManager() {
|
||||
return false;
|
||||
|
||||
if (!devtools_manager_) {
|
||||
devtools_manager_.reset(new CefDevToolsManager(this));
|
||||
devtools_manager_ = std::make_unique<CefDevToolsManager>(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -878,3 +1001,14 @@ 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;
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#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"
|
||||
|
||||
@@ -39,17 +40,19 @@ struct CefBrowserCreateParams {
|
||||
settings = that.settings;
|
||||
request_context = that.request_context;
|
||||
extra_info = that.extra_info;
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
if (that.window_info)
|
||||
MaybeSetWindowInfo(*that.window_info);
|
||||
browser_view = that.browser_view;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Platform-specific window creation info. Will be nullptr when creating a
|
||||
// views-hosted browser. Currently used with the alloy runtime only.
|
||||
// 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.
|
||||
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;
|
||||
@@ -58,7 +61,6 @@ 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;
|
||||
@@ -154,6 +156,12 @@ 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,
|
||||
@@ -180,6 +188,7 @@ 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;
|
||||
@@ -231,6 +240,22 @@ 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,
|
||||
@@ -265,15 +290,27 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
return contents_delegate_.get();
|
||||
}
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
// Returns the Widget owner for the browser window. Only used with windowed
|
||||
// rendering.
|
||||
// browsers.
|
||||
views::Widget* GetWindowWidget() const;
|
||||
|
||||
// Returns the BrowserView associated with this browser. Only used with Views-
|
||||
// based browsers.
|
||||
CefRefPtr<CefBrowserView> GetBrowserView() const;
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
|
||||
protected:
|
||||
bool EnsureDevToolsManager();
|
||||
@@ -283,6 +320,11 @@ 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_;
|
||||
@@ -298,6 +340,9 @@ 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_;
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#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"
|
||||
@@ -138,7 +139,7 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
||||
}
|
||||
|
||||
CefBrowserCreateParams create_params;
|
||||
create_params.window_info.reset(new CefWindowInfo(windowInfo));
|
||||
create_params.MaybeSetWindowInfo(windowInfo);
|
||||
create_params.client = client;
|
||||
create_params.url = url;
|
||||
create_params.settings = settings;
|
||||
@@ -148,10 +149,22 @@ 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();
|
||||
}
|
||||
|
@@ -168,13 +168,10 @@ void CefBrowserInfo::FrameHostStateChanged(
|
||||
content::RenderFrameHost::LifecycleState::kInBackForwardCache) &&
|
||||
new_state == content::RenderFrameHost::LifecycleState::kActive) {
|
||||
if (auto frame = GetFrameForHost(host)) {
|
||||
// Should only occur for the main frame.
|
||||
CHECK(frame->IsMain());
|
||||
|
||||
// Update the associated RFH, which may have changed.
|
||||
frame->MaybeReAttach(this, host);
|
||||
|
||||
{
|
||||
if (frame->IsMain()) {
|
||||
// Update the main frame object.
|
||||
NotificationStateLock lock_scope(this);
|
||||
SetMainFrame(browser_, frame);
|
||||
|
@@ -129,10 +129,10 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
bool allow = true;
|
||||
|
||||
std::unique_ptr<CefWindowInfo> window_info(new CefWindowInfo);
|
||||
CefWindowInfo window_info;
|
||||
|
||||
#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,12 +178,16 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
|
||||
if (allow) {
|
||||
CefBrowserCreateParams create_params;
|
||||
create_params.MaybeSetWindowInfo(window_info);
|
||||
|
||||
if (browser->HasView()) {
|
||||
create_params.popup_with_views_hosted_opener = true;
|
||||
} else {
|
||||
create_params.window_info = std::move(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();
|
||||
|
||||
create_params.settings = pending_popup->settings;
|
||||
create_params.client = pending_popup->client;
|
||||
|
@@ -7,6 +7,9 @@
|
||||
#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;
|
||||
|
||||
@@ -61,7 +64,12 @@ bool CefBrowserPlatformDelegate::
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) {}
|
||||
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);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::RenderViewReady() {}
|
||||
|
||||
@@ -113,7 +121,6 @@ CefWindowHandle CefBrowserPlatformDelegate::GetHostWindowHandle() const {
|
||||
return kNullWindowHandle;
|
||||
}
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
views::Widget* CefBrowserPlatformDelegate::GetWindowWidget() const {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
@@ -123,7 +130,6 @@ CefRefPtr<CefBrowserView> CefBrowserPlatformDelegate::GetBrowserView() const {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
#endif // defined(TOOLKIT_VIEWS)
|
||||
|
||||
void CefBrowserPlatformDelegate::PopupWebContentsCreated(
|
||||
const CefBrowserSettings& settings,
|
||||
@@ -172,9 +178,7 @@ void CefBrowserPlatformDelegate::SendTouchEvent(const CefTouchEvent& event) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::SetFocus(bool setFocus) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
void CefBrowserPlatformDelegate::SetFocus(bool setFocus) {}
|
||||
|
||||
void CefBrowserPlatformDelegate::SendCaptureLostEvent() {
|
||||
NOTIMPLEMENTED();
|
||||
@@ -219,12 +223,6 @@ CefEventHandle CefBrowserPlatformDelegate::GetEventHandle(
|
||||
return kNullEventHandle;
|
||||
}
|
||||
|
||||
std::unique_ptr<CefFileDialogRunner>
|
||||
CefBrowserPlatformDelegate::CreateFileDialogRunner() {
|
||||
NOTIMPLEMENTED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<CefJavaScriptDialogRunner>
|
||||
CefBrowserPlatformDelegate::CreateJavaScriptDialogRunner() {
|
||||
NOTIMPLEMENTED();
|
||||
@@ -244,6 +242,12 @@ 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();
|
||||
}
|
||||
|
@@ -57,15 +57,12 @@ 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;
|
||||
|
||||
@@ -173,7 +170,6 @@ 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;
|
||||
@@ -181,7 +177,6 @@ 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
|
||||
@@ -270,9 +265,6 @@ 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();
|
||||
@@ -288,6 +280,10 @@ 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);
|
||||
|
||||
|
@@ -13,7 +13,11 @@
|
||||
|
||||
#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)
|
||||
@@ -29,11 +33,6 @@
|
||||
#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(
|
||||
@@ -80,40 +79,40 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
|
||||
&create_params.settings, is_windowless ? STATE_ENABLED : STATE_DISABLED);
|
||||
|
||||
if (cef::IsChromeRuntimeEnabled()) {
|
||||
// CefWindowInfo is not used in this case.
|
||||
CefWindowInfo window_info;
|
||||
if (create_params.window_info) {
|
||||
window_info = *create_params.window_info;
|
||||
}
|
||||
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color);
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
if (create_params.browser_view ||
|
||||
create_params.popup_with_views_hosted_opener) {
|
||||
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.
|
||||
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.window_info) {
|
||||
if (create_params.browser_view ||
|
||||
create_params.popup_with_views_hosted_opener) {
|
||||
// CefWindowInfo is not used in this case.
|
||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
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);
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color);
|
||||
return std::make_unique<CefBrowserPlatformDelegateViews>(
|
||||
std::move(native_delegate),
|
||||
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
|
||||
} else if (create_params.extension_host_type ==
|
||||
extensions::mojom::ViewType::kExtensionBackgroundPage) {
|
||||
// Creating a background extension host without a window.
|
||||
@@ -121,17 +120,23 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
|
||||
CreateNativeDelegate(CefWindowInfo(), background_color);
|
||||
return std::make_unique<CefBrowserPlatformDelegateBackground>(
|
||||
std::move(native_delegate));
|
||||
}
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
else {
|
||||
// CefWindowInfo is not used in this case.
|
||||
} else 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, 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);
|
||||
}
|
||||
#endif // defined(TOOLKIT_VIEWS)
|
||||
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
|
@@ -4,6 +4,8 @@
|
||||
|
||||
#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"
|
||||
@@ -40,6 +42,10 @@ void CefBrowserPlatformDelegateChrome::BrowserDestroyed(
|
||||
native_delegate_->BrowserDestroyed(browser);
|
||||
}
|
||||
|
||||
CefWindowHandle CefBrowserPlatformDelegateChrome::GetHostWindowHandle() const {
|
||||
return view_util::GetWindowHandle(GetNativeWindow());
|
||||
}
|
||||
|
||||
SkColor CefBrowserPlatformDelegateChrome::GetBackgroundColor() const {
|
||||
return native_delegate_->GetBackgroundColor();
|
||||
}
|
||||
@@ -73,12 +79,9 @@ 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(
|
||||
native_window, gfx::Rect(view, gfx::Size(0, 0)));
|
||||
GetNativeWindow(), gfx::Rect(view, gfx::Size(0, 0)));
|
||||
return screen_rect.origin();
|
||||
}
|
||||
|
||||
@@ -104,3 +107,9 @@ 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();
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ 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,
|
||||
@@ -45,7 +46,13 @@ 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;
|
||||
|
@@ -341,9 +341,8 @@ std::unique_ptr<BrowserDelegate> BrowserDelegate::Create(
|
||||
create_params = params->create_params_;
|
||||
|
||||
// Clear these values so they're not persisted to additional Browsers.
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
params->create_params_.window_info.reset();
|
||||
params->create_params_.browser_view = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
return std::make_unique<ChromeBrowserDelegate>(browser, create_params);
|
||||
|
@@ -22,11 +22,8 @@
|
||||
#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(
|
||||
@@ -111,9 +108,7 @@ 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);
|
||||
@@ -143,6 +138,9 @@ 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) {
|
||||
@@ -163,15 +161,14 @@ bool ChromeBrowserHostImpl::TryCloseBrowser() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::SetFocus(bool focus) {
|
||||
if (focus) {
|
||||
OnSetFocus(FOCUS_SOURCE_SYSTEM);
|
||||
}
|
||||
}
|
||||
|
||||
CefWindowHandle ChromeBrowserHostImpl::GetWindowHandle() {
|
||||
NOTIMPLEMENTED();
|
||||
return kNullWindowHandle;
|
||||
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();
|
||||
}
|
||||
return host_window_handle_;
|
||||
}
|
||||
|
||||
CefWindowHandle ChromeBrowserHostImpl::GetOpenerWindowHandle() {
|
||||
@@ -188,17 +185,6 @@ 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));
|
||||
@@ -282,10 +268,6 @@ void ChromeBrowserHostImpl::SendCaptureLostEvent() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::NotifyMoveOrResizeStarted() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
int ChromeBrowserHostImpl::GetWindowlessFrameRate() {
|
||||
return 0;
|
||||
}
|
||||
@@ -436,7 +418,6 @@ 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
|
||||
@@ -459,7 +440,6 @@ 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
|
||||
@@ -469,7 +449,6 @@ 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.
|
||||
@@ -479,7 +458,6 @@ Browser* ChromeBrowserHostImpl::CreateBrowser(
|
||||
// Don't show the browser by default.
|
||||
show_browser = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (show_browser) {
|
||||
browser->window()->Show();
|
||||
@@ -513,7 +491,20 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
// Notify that the browser has been created. These must be delivered in the
|
||||
// expected order.
|
||||
|
||||
// 1. Notify the browser's LifeSpanHandler. This must always be the first
|
||||
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
|
||||
// notification for the browser.
|
||||
{
|
||||
// The WebContents won't be added to the Browser's TabStripModel until later
|
||||
@@ -522,17 +513,9 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
||||
OnAfterCreated();
|
||||
}
|
||||
|
||||
// 2. Notify the platform delegate. With Views this will result in a call to
|
||||
// 3. 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) {
|
||||
@@ -540,17 +523,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();
|
||||
}
|
||||
|
@@ -62,17 +62,10 @@ 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,
|
||||
@@ -96,7 +89,6 @@ 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,
|
||||
@@ -167,6 +159,7 @@ 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_
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#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"
|
||||
@@ -41,4 +42,5 @@ void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() {
|
||||
|
||||
scheme::RegisterWebUIControllerFactory();
|
||||
context_menu::RegisterMenuCreatedCallback();
|
||||
file_dialog_runner::RegisterFactory();
|
||||
}
|
||||
|
@@ -0,0 +1,29 @@
|
||||
// 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
|
@@ -0,0 +1,29 @@
|
||||
// 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_
|
@@ -95,6 +95,11 @@ 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();
|
||||
@@ -112,7 +117,11 @@ void CefBrowserPlatformDelegateChromeViews::PopupWebContentsCreated(
|
||||
content::WebContents* new_web_contents,
|
||||
CefBrowserPlatformDelegate* new_platform_delegate,
|
||||
bool is_devtools) {
|
||||
DCHECK(new_platform_delegate->IsViewsHosted());
|
||||
// Default popup handling may not be Views-hosted.
|
||||
if (!new_platform_delegate->IsViewsHosted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* new_platform_delegate_impl =
|
||||
static_cast<CefBrowserPlatformDelegateChromeViews*>(
|
||||
new_platform_delegate);
|
||||
@@ -134,6 +143,11 @@ 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);
|
||||
|
@@ -24,6 +24,7 @@ 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(
|
||||
@@ -36,6 +37,8 @@ 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);
|
||||
|
||||
|
199
libcef/browser/chrome/views/chrome_child_window.cc
Normal file
199
libcef/browser/chrome/views/chrome_child_window.cc
Normal file
@@ -0,0 +1,199 @@
|
||||
// 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
|
24
libcef/browser/chrome/views/chrome_child_window.h
Normal file
24
libcef/browser/chrome/views/chrome_child_window.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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_
|
@@ -106,7 +106,7 @@ void CefDevToolsFileManager::Save(const std::string& url,
|
||||
}
|
||||
}
|
||||
|
||||
CefFileDialogRunner::FileChooserParams params;
|
||||
blink::mojom::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_->RunFileChooser(
|
||||
browser_impl_->RunFileChooserForBrowser(
|
||||
params,
|
||||
base::BindOnce(&CefDevToolsFileManager::SaveAsDialogDismissed,
|
||||
weak_factory_.GetWeakPtr(), url, content,
|
||||
@@ -127,7 +127,6 @@ 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]);
|
||||
|
@@ -49,7 +49,6 @@ 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,
|
||||
|
@@ -251,8 +251,11 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
|
||||
}
|
||||
|
||||
CefBrowserCreateParams create_params;
|
||||
if (!inspected_browser->is_views_hosted())
|
||||
if (inspected_browser->is_views_hosted()) {
|
||||
create_params.popup_with_views_hosted_opener = true;
|
||||
} else {
|
||||
create_params.window_info.reset(new CefWindowInfo(windowInfo));
|
||||
}
|
||||
create_params.client = client;
|
||||
create_params.settings = new_settings;
|
||||
create_params.devtools_opener = inspected_browser;
|
||||
@@ -592,7 +595,7 @@ void CefDevToolsFrontend::CallClientFunction(
|
||||
|
||||
web_contents()->GetMainFrame()->AllowInjectingJavaScript();
|
||||
|
||||
base::Value arguments(base::Value::Type::LIST);
|
||||
base::Value::List arguments;
|
||||
if (!arg1.is_none()) {
|
||||
arguments.Append(std::move(arg1));
|
||||
if (!arg2.is_none()) {
|
||||
|
@@ -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 < 0U)
|
||||
if (method_end == base::StringPiece::npos)
|
||||
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 < 0U)
|
||||
if (id_end == base::StringPiece::npos)
|
||||
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))
|
||||
|
@@ -83,7 +83,7 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsEvent) {
|
||||
EXPECT_TRUE(parser.Initialize(message));
|
||||
EXPECT_TRUE(parser.IsInitialized());
|
||||
EXPECT_TRUE(parser.IsEvent());
|
||||
EXPECT_STREQ("Test.myMethod", parser.method_.data());
|
||||
EXPECT_EQ("Test.myMethod", parser.method_);
|
||||
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_STREQ("Test.myMethod2", parser.method_.data());
|
||||
EXPECT_STREQ("{}", parser.params_.data());
|
||||
EXPECT_EQ("Test.myMethod2", parser.method_);
|
||||
EXPECT_EQ("{}", parser.params_);
|
||||
|
||||
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_STREQ("Test.myMethod3", parser.method_.data());
|
||||
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.data());
|
||||
EXPECT_EQ("Test.myMethod3", parser.method_);
|
||||
EXPECT_EQ("{\"foo\":\"bar\"}", parser.params_);
|
||||
}
|
||||
|
||||
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_STREQ("{}", parser.params_.data());
|
||||
EXPECT_EQ("{}", parser.params_);
|
||||
|
||||
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_STREQ("{\"foo\":\"bar\"}", parser.params_.data());
|
||||
EXPECT_EQ("{\"foo\":\"bar\"}", parser.params_);
|
||||
}
|
||||
|
||||
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_STREQ("{}", parser.params_.data());
|
||||
EXPECT_EQ("{}", parser.params_);
|
||||
|
||||
parser.Reset();
|
||||
EXPECT_FALSE(parser.IsInitialized());
|
||||
@@ -200,5 +200,21 @@ TEST(DevToolsUtil, ProtocolParser_Initialize_IsResult_Error) {
|
||||
EXPECT_TRUE(parser.IsResult());
|
||||
EXPECT_EQ(2, parser.message_id_);
|
||||
EXPECT_FALSE(parser.success_);
|
||||
EXPECT_STREQ("{\"foo\":\"bar\"}", parser.params_.data());
|
||||
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());
|
||||
}
|
||||
|
@@ -136,7 +136,7 @@ class CefBeforeDownloadCallbackImpl : public CefBeforeDownloadCallback {
|
||||
if (browser.get()) {
|
||||
handled = true;
|
||||
|
||||
CefFileDialogRunner::FileChooserParams params;
|
||||
blink::mojom::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->RunFileChooser(
|
||||
browser->RunFileChooserForBrowser(
|
||||
params,
|
||||
base::BindOnce(
|
||||
&CefBeforeDownloadCallbackImpl::ChooseDownloadPathCallback,
|
||||
@@ -166,7 +166,6 @@ 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);
|
||||
|
||||
|
@@ -4,18 +4,14 @@
|
||||
|
||||
#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 {
|
||||
@@ -46,61 +42,17 @@ bool CefFileSystemDelegate::ShowSelectFileDialog(
|
||||
return false;
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
// 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));
|
||||
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,
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#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"
|
||||
@@ -51,15 +50,6 @@ 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
|
||||
|
@@ -102,11 +102,6 @@ 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();
|
||||
|
@@ -40,7 +40,6 @@ 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;
|
||||
|
@@ -27,8 +27,8 @@ CefComponentExtensionResourceManager::CefComponentExtensionResourceManager() {
|
||||
pdf_extension_util::AddAdditionalData(/*enable_annotations=*/true, &dict);
|
||||
|
||||
ui::TemplateReplacements pdf_viewer_replacements;
|
||||
ui::TemplateReplacementsFromDictionaryValue(
|
||||
base::Value::AsDictionaryValue(dict), &pdf_viewer_replacements);
|
||||
ui::TemplateReplacementsFromDictionaryValue(dict.GetDict(),
|
||||
&pdf_viewer_replacements);
|
||||
template_replacements_[extension_misc::kPdfExtensionId] =
|
||||
std::move(pdf_viewer_replacements);
|
||||
}
|
||||
|
@@ -381,6 +381,7 @@ 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();
|
||||
}
|
||||
|
||||
|
@@ -90,8 +90,7 @@ class CefKioskDelegate : public extensions::KioskDelegate {
|
||||
} // namespace
|
||||
|
||||
CefExtensionsBrowserClient::CefExtensionsBrowserClient()
|
||||
: api_client_(new CefExtensionsAPIClient),
|
||||
resource_manager_(new CefComponentExtensionResourceManager) {
|
||||
: api_client_(new CefExtensionsAPIClient) {
|
||||
AddAPIProvider(std::make_unique<CoreExtensionsBrowserAPIProvider>());
|
||||
AddAPIProvider(std::make_unique<CefExtensionsBrowserAPIProvider>());
|
||||
}
|
||||
@@ -332,6 +331,10 @@ CefExtensionsBrowserClient::CreateRuntimeAPIDelegate(
|
||||
|
||||
const ComponentExtensionResourceManager*
|
||||
CefExtensionsBrowserClient::GetComponentExtensionResourceManager() {
|
||||
if (!resource_manager_) {
|
||||
resource_manager_ =
|
||||
std::make_unique<CefComponentExtensionResourceManager>();
|
||||
}
|
||||
return resource_manager_.get();
|
||||
}
|
||||
|
||||
|
@@ -8,18 +8,22 @@
|
||||
#include <utility>
|
||||
|
||||
#include "include/cef_dialog_handler.h"
|
||||
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
|
||||
#include "libcef/browser/browser_host_base.h"
|
||||
#include "libcef/browser/context.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 "net/base/directory_lister.h"
|
||||
#include "ui/shell_dialogs/select_file_policy.h"
|
||||
|
||||
using blink::mojom::FileChooserParams;
|
||||
|
||||
namespace {
|
||||
|
||||
class CefFileDialogCallbackImpl : public CefFileDialogCallback {
|
||||
public:
|
||||
using CallbackType = CefFileDialogRunner::RunFileChooserCallback;
|
||||
using CallbackType = CefFileDialogManager::RunFileChooserCallback;
|
||||
|
||||
explicit CefFileDialogCallbackImpl(CallbackType callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
@@ -37,8 +41,7 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
|
||||
}
|
||||
}
|
||||
|
||||
void Continue(int selected_accept_filter,
|
||||
const std::vector<CefString>& file_paths) override {
|
||||
void Continue(const std::vector<CefString>& file_paths) override {
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
if (!callback_.is_null()) {
|
||||
std::vector<base::FilePath> vec;
|
||||
@@ -47,12 +50,12 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
|
||||
for (; it != file_paths.end(); ++it)
|
||||
vec.push_back(base::FilePath(*it));
|
||||
}
|
||||
std::move(callback_).Run(selected_accept_filter, vec);
|
||||
std::move(callback_).Run(vec);
|
||||
}
|
||||
} else {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&CefFileDialogCallbackImpl::Continue, this,
|
||||
selected_accept_filter, file_paths));
|
||||
file_paths));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +76,7 @@ class CefFileDialogCallbackImpl : public CefFileDialogCallback {
|
||||
static void CancelNow(CallbackType callback) {
|
||||
CEF_REQUIRE_UIT();
|
||||
std::vector<base::FilePath> file_paths;
|
||||
std::move(callback).Run(0, file_paths);
|
||||
std::move(callback).Run(file_paths);
|
||||
}
|
||||
|
||||
CallbackType callback_;
|
||||
@@ -82,77 +85,210 @@ 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(selected_accept_filter, paths);
|
||||
callback->OnFileDialogDismissed(paths);
|
||||
}
|
||||
|
||||
class UploadFolderHelper
|
||||
: public net::DirectoryLister::DirectoryListerDelegate {
|
||||
public:
|
||||
explicit UploadFolderHelper(
|
||||
CefFileDialogRunner::RunFileChooserCallback callback)
|
||||
: callback_(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;
|
||||
}
|
||||
|
||||
UploadFolderHelper(const UploadFolderHelper&) = delete;
|
||||
UploadFolderHelper& operator=(const UploadFolderHelper&) = delete;
|
||||
FileChooserParams SelectFileToFileChooserParams(
|
||||
ui::SelectFileDialog::Type type,
|
||||
const std::u16string& title,
|
||||
const base::FilePath& default_path,
|
||||
const ui::SelectFileDialog::FileTypeInfo* file_types) {
|
||||
FileChooserParams params;
|
||||
|
||||
~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_)));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnListFile(
|
||||
const net::DirectoryLister::DirectoryListerData& data) override {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!data.info.IsDirectory())
|
||||
select_files_.push_back(data.path);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
void OnListDone(int error) override {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!callback_.is_null()) {
|
||||
std::move(callback_).Run(0, select_files_);
|
||||
}
|
||||
}
|
||||
class CefFileSelectListener : public content::FileSelectListener {
|
||||
public:
|
||||
using CallbackType = CefFileDialogManager::RunFileChooserCallback;
|
||||
|
||||
explicit CefFileSelectListener(CallbackType callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
|
||||
private:
|
||||
static void CancelNow(CefFileDialogRunner::RunFileChooserCallback callback) {
|
||||
CEF_REQUIRE_UIT();
|
||||
std::vector<base::FilePath> file_paths;
|
||||
std::move(callback).Run(0, file_paths);
|
||||
~CefFileSelectListener() override = default;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::move(callback_).Run(paths);
|
||||
}
|
||||
|
||||
CefFileDialogRunner::RunFileChooserCallback callback_;
|
||||
std::vector<base::FilePath> select_files_;
|
||||
void FileSelectionCanceled() override { std::move(callback_).Run({}); }
|
||||
|
||||
CallbackType callback_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefFileDialogManager::CefFileDialogManager(
|
||||
AlloyBrowserHostImpl* browser,
|
||||
std::unique_ptr<CefFileDialogRunner> runner)
|
||||
: browser_(browser),
|
||||
runner_(std::move(runner)),
|
||||
file_chooser_pending_(false),
|
||||
weak_ptr_factory_(this) {}
|
||||
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() {}
|
||||
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;
|
||||
|
||||
void CefFileDialogManager::Destroy() {
|
||||
DCHECK(!file_chooser_pending_);
|
||||
runner_.reset(nullptr);
|
||||
if (dialog_listener_) {
|
||||
// Cancel the listener and delete related objects.
|
||||
SelectFileDoneByListenerCallback(/*listener_destroyed=*/false);
|
||||
}
|
||||
DCHECK(!dialog_);
|
||||
DCHECK(!dialog_listener_);
|
||||
DCHECK(active_listeners_.empty());
|
||||
}
|
||||
|
||||
void CefFileDialogManager::RunFileDialog(
|
||||
@@ -160,14 +296,13 @@ 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;
|
||||
|
||||
CefFileDialogRunner::FileChooserParams params;
|
||||
switch (mode & FILE_DIALOG_TYPE_MASK) {
|
||||
blink::mojom::FileChooserParams params;
|
||||
switch (mode) {
|
||||
case FILE_DIALOG_OPEN:
|
||||
params.mode = blink::mojom::FileChooserParams::Mode::kOpen;
|
||||
break;
|
||||
@@ -182,12 +317,6 @@ 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);
|
||||
@@ -202,55 +331,145 @@ void CefFileDialogManager::RunFileDialog(
|
||||
}
|
||||
|
||||
void CefFileDialogManager::RunFileChooser(
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
const blink::mojom::FileChooserParams& params) {
|
||||
const blink::mojom::FileChooserParams& params,
|
||||
RunFileChooserCallback callback) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
CefFileDialogRunner::FileChooserParams cef_params;
|
||||
static_cast<blink::mojom::FileChooserParams&>(cef_params) = params;
|
||||
|
||||
CefFileDialogRunner::RunFileChooserCallback callback;
|
||||
if (params.mode == blink::mojom::FileChooserParams::Mode::kUploadFolder) {
|
||||
callback = base::BindOnce(
|
||||
&CefFileDialogManager::OnRunFileChooserUploadFolderDelegateCallback,
|
||||
weak_ptr_factory_.GetWeakPtr(), params.mode, listener);
|
||||
} else {
|
||||
callback =
|
||||
base::BindOnce(&CefFileDialogManager::OnRunFileChooserDelegateCallback,
|
||||
weak_ptr_factory_.GetWeakPtr(), params.mode, listener);
|
||||
}
|
||||
|
||||
RunFileChooserInternal(cef_params, std::move(callback));
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (file_chooser_pending_) {
|
||||
// Dismiss the new dialog immediately.
|
||||
std::move(callback).Run(0, std::vector<base::FilePath>());
|
||||
// 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;
|
||||
}
|
||||
|
||||
file_chooser_pending_ = true;
|
||||
FileChooserParams new_params = params;
|
||||
|
||||
bool handled = false;
|
||||
// Make sure we get native files in CefFileSelectListener.
|
||||
new_params.need_local_path = true;
|
||||
|
||||
if (browser_->client().get()) {
|
||||
CefRefPtr<CefDialogHandler> handler =
|
||||
browser_->client()->GetDialogHandler();
|
||||
if (handler.get()) {
|
||||
// Requirements of FileSelectHelper.
|
||||
if (params.mode != FileChooserParams::Mode::kSave) {
|
||||
new_params.default_file_name = base::FilePath();
|
||||
} else {
|
||||
new_params.default_file_name = new_params.default_file_name.BaseName();
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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.
|
||||
return;
|
||||
}
|
||||
|
||||
if (dialog_) {
|
||||
LOG(ERROR) << "Multiple simultaneous dialogs are not supported; "
|
||||
"canceling the file dialog";
|
||||
std::move(callback).Run({});
|
||||
return;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
// |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()) {
|
||||
int mode = FILE_DIALOG_OPEN;
|
||||
switch (params.mode) {
|
||||
case blink::mojom::FileChooserParams::Mode::kOpen:
|
||||
@@ -270,11 +489,6 @@ void CefFileDialogManager::RunFileChooserInternal(
|
||||
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;
|
||||
@@ -284,10 +498,9 @@ void CefFileDialogManager::RunFileChooserInternal(
|
||||
|
||||
CefRefPtr<CefFileDialogCallbackImpl> callbackImpl(
|
||||
new CefFileDialogCallbackImpl(std::move(callback)));
|
||||
handled = handler->OnFileDialog(
|
||||
const bool handled = handler->OnFileDialog(
|
||||
browser_, static_cast<cef_file_dialog_mode_t>(mode), params.title,
|
||||
params.default_file_name.value(), accept_filters,
|
||||
params.selected_accept_filter, callbackImpl.get());
|
||||
params.default_file_name.value(), accept_filters, callbackImpl.get());
|
||||
if (!handled) {
|
||||
// May return nullptr if the client has already executed the callback.
|
||||
callback = callbackImpl->Disconnect();
|
||||
@@ -295,82 +508,57 @@ void CefFileDialogManager::RunFileChooserInternal(
|
||||
}
|
||||
}
|
||||
|
||||
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>());
|
||||
}
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
void CefFileDialogManager::OnRunFileChooserCallback(
|
||||
CefFileDialogRunner::RunFileChooserCallback callback,
|
||||
int selected_accept_filter,
|
||||
const std::vector<base::FilePath>& file_paths) {
|
||||
void CefFileDialogManager::SelectFileDoneByDelegateCallback(
|
||||
ui::SelectFileDialog::Listener* listener,
|
||||
void* params,
|
||||
const std::vector<base::FilePath>& paths) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
Cleanup();
|
||||
// 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;
|
||||
|
||||
// Execute the callback asynchronously.
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(std::move(callback),
|
||||
selected_accept_filter, file_paths));
|
||||
}
|
||||
active_listeners_.erase(listener);
|
||||
|
||||
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);
|
||||
if (paths.empty()) {
|
||||
listener->FileSelectionCanceled(params);
|
||||
} else if (paths.size() == 1) {
|
||||
listener->FileSelected(paths[0], /*index=*/0, params);
|
||||
} 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();
|
||||
listener->MultiFilesSelected(paths, params);
|
||||
}
|
||||
// |listener| is likely deleted at this point.
|
||||
}
|
||||
|
||||
void CefFileDialogManager::OnRunFileChooserDelegateCallback(
|
||||
blink::mojom::FileChooserParams::Mode mode,
|
||||
scoped_refptr<content::FileSelectListener> listener,
|
||||
int selected_accept_filter,
|
||||
const std::vector<base::FilePath>& file_paths) {
|
||||
void CefFileDialogManager::SelectFileDoneByListenerCallback(
|
||||
bool listener_destroyed) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
base::FilePath base_dir;
|
||||
std::vector<blink::mojom::FileChooserFileInfoPtr> selected_files;
|
||||
// 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;
|
||||
|
||||
if (!file_paths.empty()) {
|
||||
if (mode == blink::mojom::FileChooserParams::Mode::kUploadFolder) {
|
||||
base_dir = file_paths[0].DirName();
|
||||
}
|
||||
DCHECK(dialog_);
|
||||
DCHECK(dialog_listener_);
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
active_listeners_.erase(dialog_listener_->listener());
|
||||
|
||||
listener->FileSelected(std::move(selected_files), base_dir, mode);
|
||||
// Clear |dialog_listener_| before calling Cancel() to avoid re-entrancy.
|
||||
auto dialog_listener = dialog_listener_;
|
||||
dialog_listener_ = nullptr;
|
||||
dialog_listener->Cancel(listener_destroyed);
|
||||
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void CefFileDialogManager::Cleanup() {
|
||||
if (lister_)
|
||||
lister_.reset();
|
||||
|
||||
file_chooser_pending_ = false;
|
||||
// There should be no further listener callbacks after this call.
|
||||
dialog_->ListenerDestroyed();
|
||||
dialog_ = nullptr;
|
||||
}
|
||||
|
@@ -7,28 +7,25 @@
|
||||
#define CEF_LIBCEF_BROWSER_FILE_DIALOG_MANAGER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_browser.h"
|
||||
#include "libcef/browser/file_dialog_runner.h"
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "include/cef_browser.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"
|
||||
|
||||
namespace content {
|
||||
class FileSelectListener;
|
||||
class WebContents;
|
||||
} // namespace content
|
||||
|
||||
namespace net {
|
||||
class DirectoryLister;
|
||||
}
|
||||
|
||||
class AlloyBrowserHostImpl;
|
||||
class CefBrowserHostBase;
|
||||
class CefSelectFileDialogListener;
|
||||
|
||||
class CefFileDialogManager {
|
||||
public:
|
||||
// |runner| may be NULL if the platform doesn't implement dialogs.
|
||||
CefFileDialogManager(AlloyBrowserHostImpl* browser,
|
||||
std::unique_ptr<CefFileDialogRunner> runner);
|
||||
explicit CefFileDialogManager(CefBrowserHostBase* browser);
|
||||
|
||||
CefFileDialogManager(const CefFileDialogManager&) = delete;
|
||||
CefFileDialogManager& operator=(const CefFileDialogManager&) = delete;
|
||||
@@ -38,70 +35,65 @@ class CefFileDialogManager {
|
||||
// Delete the runner to free any platform constructs.
|
||||
void Destroy();
|
||||
|
||||
// Called from AlloyBrowserHostImpl::RunFileChooser.
|
||||
// See CefBrowserHost::RunFileDialog documentation.
|
||||
// Run a file dialog with the specified parameters. See
|
||||
// CefBrowserHost::RunFileDialog for usage documentation. This method should
|
||||
// be called via CefBrowserHostBase::RunFileDialog.
|
||||
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);
|
||||
|
||||
// Called from AlloyBrowserHostImpl::RunFileChooser.
|
||||
// See WebContentsDelegate::RunFileChooser documentation.
|
||||
void RunFileChooser(scoped_refptr<content::FileSelectListener> listener,
|
||||
const blink::mojom::FileChooserParams& params);
|
||||
// The argument vector will be empty if the dialog was canceled.
|
||||
using RunFileChooserCallback =
|
||||
base::OnceCallback<void(const std::vector<base::FilePath>&)>;
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
private:
|
||||
void RunFileChooserInternal(
|
||||
const CefFileDialogRunner::FileChooserParams& params,
|
||||
CefFileDialogRunner::RunFileChooserCallback callback);
|
||||
[[nodiscard]] RunFileChooserCallback MaybeRunDelegate(
|
||||
const blink::mojom::FileChooserParams& params,
|
||||
RunFileChooserCallback callback);
|
||||
|
||||
// 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);
|
||||
void SelectFileDoneByDelegateCallback(
|
||||
ui::SelectFileDialog::Listener* listener,
|
||||
void* params,
|
||||
const std::vector<base::FilePath>& paths);
|
||||
void SelectFileDoneByListenerCallback(bool listener_destroyed);
|
||||
|
||||
// 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);
|
||||
// CefBrowserHostBase pointer is guaranteed to outlive this object.
|
||||
CefBrowserHostBase* const browser_;
|
||||
|
||||
// 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);
|
||||
// Used when running a platform dialog via RunSelectFile.
|
||||
scoped_refptr<ui::SelectFileDialog> dialog_;
|
||||
CefSelectFileDialogListener* dialog_listener_ = nullptr;
|
||||
|
||||
// Clean up state associated with the last run.
|
||||
void Cleanup();
|
||||
// List of all currently active listeners.
|
||||
std::set<ui::SelectFileDialog::Listener*> active_listeners_;
|
||||
|
||||
// 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_;
|
||||
base::WeakPtrFactory<CefFileDialogManager> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_MANAGER_H_
|
||||
|
189
libcef/browser/file_dialog_runner.cc
Normal file
189
libcef/browser/file_dialog_runner.cc
Normal file
@@ -0,0 +1,189 @@
|
||||
// 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
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
|
||||
// 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.
|
||||
@@ -7,46 +7,11 @@
|
||||
#define CEF_LIBCEF_BROWSER_FILE_DIALOG_RUNNER_H_
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
namespace file_dialog_runner {
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
|
||||
// One-time registration on startup.
|
||||
void RegisterFactory();
|
||||
|
||||
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;
|
||||
};
|
||||
} // namespace file_dialog_runner
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_FILE_DIALOG_RUNNER_H_
|
||||
|
@@ -283,13 +283,6 @@ void CefFrameHostImpl::RefreshAttributes() {
|
||||
}
|
||||
}
|
||||
|
||||
void CefFrameHostImpl::NotifyMoveOrResizeStarted() {
|
||||
SendToRenderFrame(__FUNCTION__,
|
||||
base::BindOnce([](const RenderFrameType& render_frame) {
|
||||
render_frame->MoveOrResizeStarted();
|
||||
}));
|
||||
}
|
||||
|
||||
void CefFrameHostImpl::LoadRequest(cef::mojom::RequestParamsPtr params) {
|
||||
if (!url_util::FixupGURL(params->url))
|
||||
return;
|
||||
@@ -421,8 +414,10 @@ void CefFrameHostImpl::ExecuteJavaScriptWithUserGestureForTests(
|
||||
}
|
||||
|
||||
content::RenderFrameHost* rfh = GetRenderFrameHost();
|
||||
if (rfh)
|
||||
rfh->ExecuteJavaScriptWithUserGestureForTests(javascript);
|
||||
if (rfh) {
|
||||
rfh->ExecuteJavaScriptWithUserGestureForTests(javascript,
|
||||
base::NullCallback());
|
||||
}
|
||||
}
|
||||
|
||||
content::RenderFrameHost* CefFrameHostImpl::GetRenderFrameHost() const {
|
||||
|
@@ -82,10 +82,6 @@ class CefFrameHostImpl : public CefFrame, public cef::mojom::BrowserFrame {
|
||||
void SetFocused(bool focused);
|
||||
void RefreshAttributes();
|
||||
|
||||
// Notification that a move or resize of the renderer's containing window has
|
||||
// started. Used on Windows and Linux with the Alloy runtime.
|
||||
void NotifyMoveOrResizeStarted();
|
||||
|
||||
// Load the specified request.
|
||||
void LoadRequest(cef::mojom::RequestParamsPtr params);
|
||||
|
||||
|
@@ -208,7 +208,7 @@ void CefMediaRouterManager::TerminateRoute(
|
||||
GetMediaRouter()->TerminateRoute(route_id);
|
||||
}
|
||||
|
||||
void CefMediaRouterManager::OnResultsUpdated(const MediaSinkVector& sinks) {
|
||||
void CefMediaRouterManager::OnSinksUpdated(const MediaSinkVector& sinks) {
|
||||
sinks_ = sinks;
|
||||
NotifyCurrentSinks();
|
||||
}
|
||||
|
@@ -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::QueryResultManager::Observer {
|
||||
: public media_router::MediaSinkWithCastModesObserver {
|
||||
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);
|
||||
|
||||
// QueryResultManager::Observer methods.
|
||||
void OnResultsUpdated(const MediaSinkVector& sinks) override;
|
||||
// MediaSinkWithCastModesObserver methods.
|
||||
void OnSinksUpdated(const MediaSinkVector& sinks) override;
|
||||
|
||||
private:
|
||||
friend class CefMediaRoutesObserver;
|
||||
|
@@ -37,7 +37,7 @@ CefBrowserPlatformDelegateNativeLinux::CefBrowserPlatformDelegateNativeLinux(
|
||||
|
||||
void CefBrowserPlatformDelegateNativeLinux::BrowserDestroyed(
|
||||
CefBrowserHostBase* browser) {
|
||||
CefBrowserPlatformDelegateNative::BrowserDestroyed(browser);
|
||||
CefBrowserPlatformDelegateNativeAura::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.
|
||||
CefBrowserPlatformDelegateNative::NotifyMoveOrResizeStarted();
|
||||
CefBrowserPlatformDelegateNativeAura::NotifyMoveOrResizeStarted();
|
||||
|
||||
if (!web_contents_)
|
||||
return;
|
||||
|
@@ -40,7 +40,6 @@ 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;
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
#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"
|
||||
@@ -166,27 +165,22 @@ bool CefBrowserPlatformDelegateNativeMac::CreateHostWindow() {
|
||||
|
||||
NSView* parentView =
|
||||
CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(window_info_.parent_view);
|
||||
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)}};
|
||||
|
||||
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}};
|
||||
if (parentView == nil) {
|
||||
// Create a new window.
|
||||
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)}};
|
||||
NSRect window_rect = {{x, y}, {width, height}};
|
||||
if (window_rect.size.width == 0)
|
||||
window_rect.size.width = 750;
|
||||
if (window_rect.size.height == 0)
|
||||
window_rect.size.height = 750;
|
||||
|
||||
contentRect.origin.x = 0;
|
||||
contentRect.origin.y = 0;
|
||||
contentRect.size.width = window_rect.size.width;
|
||||
contentRect.size.height = window_rect.size.height;
|
||||
content_rect = {{0, 0}, {window_rect.size.width, window_rect.size.height}};
|
||||
|
||||
newWnd = [[UnderlayOpenGLHostingWindow alloc]
|
||||
initWithContentRect:window_rect
|
||||
@@ -207,6 +201,11 @@ 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;
|
||||
@@ -216,7 +215,7 @@ bool CefBrowserPlatformDelegateNativeMac::CreateHostWindow() {
|
||||
|
||||
// Create the browser view.
|
||||
CefBrowserHostView* browser_view =
|
||||
[[CefBrowserHostView alloc] initWithFrame:contentRect];
|
||||
[[CefBrowserHostView alloc] initWithFrame:content_rect];
|
||||
browser_view.browser = browser_;
|
||||
[parentView addSubview:browser_view];
|
||||
[browser_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||
@@ -363,11 +362,6 @@ 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);
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#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"
|
||||
@@ -156,9 +155,18 @@ 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) {
|
||||
CefBrowserPlatformDelegateNative::BrowserDestroyed(browser);
|
||||
CefBrowserPlatformDelegateNativeAura::BrowserDestroyed(browser);
|
||||
|
||||
if (host_window_created_) {
|
||||
// Release the reference added in CreateHostWindow().
|
||||
@@ -169,6 +177,11 @@ 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));
|
||||
@@ -315,7 +328,7 @@ void CefBrowserPlatformDelegateNativeWin::SetFocus(bool setFocus) {
|
||||
|
||||
void CefBrowserPlatformDelegateNativeWin::NotifyMoveOrResizeStarted() {
|
||||
// Call the parent method to dismiss any existing popups.
|
||||
CefBrowserPlatformDelegateNative::NotifyMoveOrResizeStarted();
|
||||
CefBrowserPlatformDelegateNativeAura::NotifyMoveOrResizeStarted();
|
||||
|
||||
if (!window_widget_)
|
||||
return;
|
||||
@@ -433,11 +446,6 @@ 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);
|
||||
|
@@ -16,6 +16,9 @@ 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;
|
||||
@@ -31,7 +34,6 @@ 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;
|
||||
|
@@ -7,13 +7,68 @@
|
||||
#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 {
|
||||
|
||||
bool OnCursorChange(CefBrowserHostBase* browser, const ui::Cursor& ui_cursor) {
|
||||
auto client = browser->GetClient();
|
||||
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();
|
||||
if (!client)
|
||||
return false;
|
||||
auto handler = client->GetDisplayHandler();
|
||||
@@ -35,19 +90,32 @@ bool OnCursorChange(CefBrowserHostBase* browser, const ui::Cursor& ui_cursor) {
|
||||
bool handled = false;
|
||||
|
||||
#if defined(USE_AURA)
|
||||
CefCursorHandle platform_cursor;
|
||||
scoped_refptr<ui::PlatformCursor> image_cursor;
|
||||
aura::CursorLoader cursor_loader;
|
||||
scoped_refptr<ui::PlatformCursor> platform_cursor;
|
||||
CefCursorHandle native_cursor = kNullCursorHandle;
|
||||
|
||||
ui::Cursor loaded_cursor = ui_cursor;
|
||||
|
||||
if (ui_cursor.type() == ui::mojom::CursorType::kCustom) {
|
||||
image_cursor = ui::CursorFactory::GetInstance()->CreateImageCursor(
|
||||
platform_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 {
|
||||
platform_cursor = cursor_util::GetPlatformCursor(ui_cursor.type());
|
||||
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();
|
||||
}
|
||||
|
||||
handled = handler->OnCursorChange(browser, platform_cursor, cursor_type,
|
||||
if (platform_cursor) {
|
||||
native_cursor = cursor_util::ToCursorHandle(platform_cursor);
|
||||
}
|
||||
|
||||
handled = handler->OnCursorChange(browser, native_cursor, cursor_type,
|
||||
custom_cursor_info);
|
||||
#elif BUILDFLAG(IS_MAC)
|
||||
// |web_cursor| owns the resulting |native_cursor|.
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#ifndef CEF_LIBCEF_BROWSER_NATIVE_CURSOR_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_NATIVE_CURSOR_UTIL_H_
|
||||
|
||||
#include "include/internal/cef_types.h"
|
||||
#include "include/cef_browser.h"
|
||||
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
|
||||
@@ -14,17 +14,14 @@
|
||||
#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(CefBrowserHostBase* browser, const ui::Cursor& ui_cursor);
|
||||
bool OnCursorChange(CefRefPtr<CefBrowser> browser, const ui::Cursor& ui_cursor);
|
||||
|
||||
} // namespace cursor_util
|
||||
|
||||
|
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "libcef/browser/native/cursor_util.h"
|
||||
|
||||
#include "ui/base/cursor/cursor_factory.h"
|
||||
#include "ui/ozone/buildflags.h"
|
||||
|
||||
#if BUILDFLAG(OZONE_PLATFORM_X11)
|
||||
@@ -15,14 +14,6 @@
|
||||
|
||||
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.
|
||||
|
@@ -4,158 +4,10 @@
|
||||
|
||||
#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) {
|
||||
return cursor_id >= IDC_ARROW; // See WinUser.h
|
||||
}
|
||||
|
||||
} // 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();
|
||||
}
|
||||
|
@@ -1,41 +0,0 @@
|
||||
// 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_
|
@@ -1,405 +0,0 @@
|
||||
// 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>());
|
||||
}
|
||||
}];
|
||||
}
|
@@ -1,560 +0,0 @@
|
||||
// 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, ®_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);
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
// 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_
|
@@ -21,6 +21,7 @@
|
||||
#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"
|
||||
@@ -31,7 +32,6 @@
|
||||
#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"
|
||||
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#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 {
|
||||
@@ -30,6 +29,42 @@ 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) {
|
||||
@@ -48,7 +83,7 @@ x11::Window FindToplevelParent(x11::Window window) {
|
||||
break;
|
||||
|
||||
top_level_window = window;
|
||||
if (!ui::PropertyExists(query_tree->parent, x11::GetAtom(kNetWMPid)) ||
|
||||
if (!PropertyExists(query_tree->parent, x11::GetAtom(kNetWMPid)) ||
|
||||
query_tree->parent == query_tree->root) {
|
||||
break;
|
||||
}
|
||||
@@ -227,7 +262,7 @@ void CefWindowX11::Focus() {
|
||||
|
||||
if (browser_.get()) {
|
||||
auto child = FindChild(xwindow_);
|
||||
if (child != x11::Window::None && ui::IsWindowVisible(child)) {
|
||||
if (child != x11::Window::None && IsWindowVisible(child)) {
|
||||
// Give focus to the child DesktopWindowTreeHostLinux.
|
||||
focus_target = child;
|
||||
}
|
||||
@@ -334,7 +369,6 @@ 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.
|
||||
|
@@ -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_controller_factory.h"
|
||||
#include "chrome/browser/ui/webui/chrome_untrusted_web_ui_configs.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,6 +41,7 @@
|
||||
#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"
|
||||
@@ -578,12 +579,13 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
|
||||
|
||||
controller = content::ContentWebUIControllerFactory::GetInstance()
|
||||
->CreateWebUIControllerForURL(web_ui, url);
|
||||
if (controller.get())
|
||||
if (controller)
|
||||
return controller;
|
||||
|
||||
controller = ChromeUntrustedWebUIControllerFactory::GetInstance()
|
||||
controller = content::WebUIConfigMap::GetInstance()
|
||||
.controller_factory()
|
||||
->CreateWebUIControllerForURL(web_ui, url);
|
||||
if (controller.get())
|
||||
if (controller)
|
||||
return controller;
|
||||
|
||||
return ChromeWebUIControllerFactory::GetInstance()
|
||||
@@ -606,8 +608,9 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
|
||||
if (type != content::WebUI::kNoWebUI)
|
||||
return type;
|
||||
|
||||
type = ChromeUntrustedWebUIControllerFactory::GetInstance()->GetWebUIType(
|
||||
browser_context, url);
|
||||
type = content::WebUIConfigMap::GetInstance()
|
||||
.controller_factory()
|
||||
->GetWebUIType(browser_context, url);
|
||||
if (type != content::WebUI::kNoWebUI)
|
||||
return type;
|
||||
|
||||
@@ -631,8 +634,9 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
|
||||
|
||||
if (content::ContentWebUIControllerFactory::GetInstance()->UseWebUIForURL(
|
||||
browser_context, url) ||
|
||||
ChromeUntrustedWebUIControllerFactory::GetInstance()->UseWebUIForURL(
|
||||
browser_context, url) ||
|
||||
content::WebUIConfigMap::GetInstance()
|
||||
.controller_factory()
|
||||
->UseWebUIForURL(browser_context, url) ||
|
||||
ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
|
||||
browser_context, url)) {
|
||||
return true;
|
||||
@@ -696,9 +700,13 @@ 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) {
|
||||
|
@@ -315,6 +315,7 @@ 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;
|
||||
@@ -581,7 +582,10 @@ void InterceptedRequest::OnReceiveResponse(
|
||||
void InterceptedRequest::OnReceiveRedirect(
|
||||
const net::RedirectInfo& redirect_info,
|
||||
network::mojom::URLResponseHeadPtr head) {
|
||||
bool needs_callback = false;
|
||||
// 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_;
|
||||
|
||||
current_response_ = std::move(head);
|
||||
current_body_.reset();
|
||||
@@ -593,8 +597,6 @@ void InterceptedRequest::OnReceiveRedirect(
|
||||
current_response_->headers = current_headers_;
|
||||
current_headers_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
needs_callback = true;
|
||||
}
|
||||
|
||||
if (--redirect_limit_ == 0) {
|
||||
@@ -606,18 +608,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 execute the callback here.
|
||||
// OnHeadersReceived for the new URL so we need to notify the client here.
|
||||
if (header_client_redirect_url_.is_valid() &&
|
||||
redirect_info.status_code == net::HTTP_OK) {
|
||||
DCHECK(current_request_uses_header_client_);
|
||||
needs_callback = true;
|
||||
notify_client = true;
|
||||
new_redirect_info =
|
||||
MakeRedirectResponseAndInfo(header_client_redirect_url_);
|
||||
} else {
|
||||
new_redirect_info = redirect_info;
|
||||
}
|
||||
|
||||
if (needs_callback) {
|
||||
if (notify_client) {
|
||||
HandleResponseOrRedirectHeaders(
|
||||
new_redirect_info,
|
||||
base::BindOnce(&InterceptedRequest::ContinueToBeforeRedirect,
|
||||
@@ -831,6 +833,9 @@ 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_;
|
||||
@@ -930,6 +935,7 @@ void InterceptedRequest::ContinueToBeforeRedirect(
|
||||
}
|
||||
|
||||
request_was_redirected_ = true;
|
||||
redirect_in_progress_ = false;
|
||||
|
||||
if (header_client_redirect_url_.is_valid())
|
||||
header_client_redirect_url_ = GURL();
|
||||
|
@@ -112,6 +112,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
CefRefPtr<CefResponseImpl> pending_response_;
|
||||
bool request_was_redirected_ = false;
|
||||
bool was_custom_handled_ = false;
|
||||
bool accept_language_added_ = false;
|
||||
CancelRequestCallback cancel_callback_;
|
||||
};
|
||||
|
||||
@@ -514,9 +515,12 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
}
|
||||
|
||||
// Add standard headers, if currently unspecified.
|
||||
request->headers.SetHeaderIfMissing(
|
||||
net::HttpRequestHeaders::kAcceptLanguage,
|
||||
init_state_->accept_language_);
|
||||
if (!request->headers.HasHeader(net::HttpRequestHeaders::kAcceptLanguage)) {
|
||||
request->headers.SetHeaderIfMissing(
|
||||
net::HttpRequestHeaders::kAcceptLanguage,
|
||||
init_state_->accept_language_);
|
||||
state->accept_language_added_ = true;
|
||||
}
|
||||
request->headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
|
||||
init_state_->user_agent_);
|
||||
|
||||
@@ -771,7 +775,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler {
|
||||
resource_response = CreateResourceResponse(request_id, resource_handler);
|
||||
DCHECK(resource_response);
|
||||
state->was_custom_handled_ = true;
|
||||
} else {
|
||||
} else if (state->accept_language_added_) {
|
||||
// The request will be handled by the NetworkService. Remove the
|
||||
// "Accept-Language" header here so that it can be re-added in
|
||||
// URLRequestHttpJob::AddExtraHeaders with correct ordering applied.
|
||||
@@ -1335,7 +1339,7 @@ std::unique_ptr<InterceptedRequestHandler> CreateInterceptedRequestHandler(
|
||||
|
||||
content::RenderFrameHost* frame = nullptr;
|
||||
|
||||
if (request.is_main_frame ||
|
||||
if (request.is_outermost_main_frame ||
|
||||
static_cast<blink::mojom::ResourceType>(request.resource_type) ==
|
||||
blink::mojom::ResourceType::kMainFrame) {
|
||||
frame = web_contents->GetMainFrame();
|
||||
|
@@ -194,11 +194,6 @@ 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();
|
||||
|
@@ -49,7 +49,6 @@ 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;
|
||||
|
@@ -30,6 +30,33 @@ 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)
|
||||
@@ -104,7 +131,30 @@ class CefPrintJobCallbackImpl : public CefPrintJobCallback {
|
||||
printing::PrintDialogGtkInterface* CefPrintDialogLinux::CreatePrintDialog(
|
||||
PrintingContextLinux* context) {
|
||||
CEF_REQUIRE_UIT();
|
||||
return new CefPrintDialogLinux(context);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -114,27 +164,42 @@ gfx::Size CefPrintDialogLinux::GetPdfPaperSize(
|
||||
|
||||
gfx::Size size;
|
||||
|
||||
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);
|
||||
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());
|
||||
}
|
||||
} 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();
|
||||
@@ -146,14 +211,13 @@ void CefPrintDialogLinux::OnPrintStart(CefRefPtr<CefBrowserHostBase> browser) {
|
||||
}
|
||||
}
|
||||
|
||||
CefPrintDialogLinux::CefPrintDialogLinux(PrintingContextLinux* context)
|
||||
: context_(context) {
|
||||
CefPrintDialogLinux::CefPrintDialogLinux(PrintingContextLinux* context,
|
||||
CefRefPtr<CefBrowserHostBase> browser,
|
||||
CefRefPtr<CefPrintHandler> handler)
|
||||
: context_(context), browser_(browser), handler_(handler) {
|
||||
DCHECK(context_);
|
||||
browser_ = extensions::GetOwnerBrowserForGlobalId(
|
||||
frame_util::MakeGlobalId(context_->render_process_id(),
|
||||
context_->render_frame_id()),
|
||||
nullptr);
|
||||
DCHECK(browser_);
|
||||
DCHECK(handler_);
|
||||
}
|
||||
|
||||
CefPrintDialogLinux::~CefPrintDialogLinux() {
|
||||
@@ -161,7 +225,7 @@ CefPrintDialogLinux::~CefPrintDialogLinux() {
|
||||
// object because the PrintJobWorker which owns |context_| may already have
|
||||
// been deleted.
|
||||
CEF_REQUIRE_UIT();
|
||||
ReleaseHandler();
|
||||
handler_->OnPrintReset(browser_.get());
|
||||
}
|
||||
|
||||
void CefPrintDialogLinux::UseDefaultSettings() {
|
||||
@@ -179,12 +243,6 @@ 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(
|
||||
@@ -240,31 +298,11 @@ 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);
|
||||
|
@@ -39,6 +39,13 @@ 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);
|
||||
|
||||
@@ -65,12 +72,11 @@ class CefPrintDialogLinux : public printing::PrintDialogGtkInterface,
|
||||
friend class CefPrintDialogCallbackImpl;
|
||||
friend class CefPrintJobCallbackImpl;
|
||||
|
||||
explicit CefPrintDialogLinux(PrintingContextLinux* context);
|
||||
CefPrintDialogLinux(PrintingContextLinux* context,
|
||||
CefRefPtr<CefBrowserHostBase> browser,
|
||||
CefRefPtr<CefPrintHandler> handler);
|
||||
~CefPrintDialogLinux() override;
|
||||
|
||||
void SetHandler();
|
||||
void ReleaseHandler();
|
||||
|
||||
bool UpdateSettings(std::unique_ptr<printing::PrintSettings> settings,
|
||||
bool get_defaults);
|
||||
|
||||
@@ -84,12 +90,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_;
|
||||
};
|
||||
|
@@ -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(settings_.inside_border_vertical_spacing,
|
||||
settings_.inside_border_horizontal_spacing),
|
||||
gfx::Insets::VH(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(
|
||||
layout->set_inside_border_insets(gfx::Insets::TLBR(
|
||||
settings_.inside_border_insets.top, settings_.inside_border_insets.left,
|
||||
settings_.inside_border_insets.bottom,
|
||||
settings_.inside_border_insets.right));
|
||||
|
@@ -257,11 +257,6 @@ 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();
|
||||
|
@@ -60,7 +60,6 @@ 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;
|
||||
|
@@ -23,8 +23,8 @@ CefRefPtr<CefBrowserView> CefBrowserView::CreateBrowserView(
|
||||
CefRefPtr<CefDictionaryValue> extra_info,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate) {
|
||||
return CefBrowserViewImpl::Create(client, url, settings, extra_info,
|
||||
request_context, delegate);
|
||||
return CefBrowserViewImpl::Create(CefWindowInfo(), client, url, settings,
|
||||
extra_info, request_context, delegate);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -41,6 +41,7 @@ CefRefPtr<CefBrowserView> CefBrowserView::GetForBrowser(
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
|
||||
const CefWindowInfo& window_info,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
@@ -62,8 +63,8 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
|
||||
browser_view->SetPendingBrowserCreateParams(client, url, settings, extra_info,
|
||||
request_context);
|
||||
browser_view->SetPendingBrowserCreateParams(
|
||||
window_info, client, url, settings, extra_info, request_context);
|
||||
browser_view->Initialize();
|
||||
browser_view->SetDefaults(settings);
|
||||
return browser_view;
|
||||
@@ -212,6 +213,7 @@ CefBrowserViewImpl::CefBrowserViewImpl(
|
||||
: ParentClass(delegate), weak_ptr_factory_(this) {}
|
||||
|
||||
void CefBrowserViewImpl::SetPendingBrowserCreateParams(
|
||||
const CefWindowInfo& window_info,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
@@ -219,6 +221,7 @@ 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;
|
||||
@@ -248,6 +251,9 @@ 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();
|
||||
}
|
||||
|
@@ -30,7 +30,9 @@ 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,
|
||||
@@ -84,6 +86,7 @@ class CefBrowserViewImpl
|
||||
explicit CefBrowserViewImpl(CefRefPtr<CefBrowserViewDelegate> delegate);
|
||||
|
||||
void SetPendingBrowserCreateParams(
|
||||
const CefWindowInfo& window_info,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
|
@@ -16,7 +16,13 @@
|
||||
// CefViewView template.
|
||||
class WebViewEx : public views::WebView {
|
||||
public:
|
||||
WebViewEx() : views::WebView(nullptr) {}
|
||||
WebViewEx() : views::WebView(nullptr) {
|
||||
// Mouse events on draggable regions will not be handled by the WebView.
|
||||
// Avoid the resulting DCHECK in NativeViewHost::OnMousePressed by
|
||||
// configuring the NativeViewHost not to process events via the view
|
||||
// hierarchy.
|
||||
holder()->SetCanProcessEventsWithinSubtree(false);
|
||||
}
|
||||
};
|
||||
|
||||
class CefBrowserViewView
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user