diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1fba9498a34..032df7341aa 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -933,10 +933,9 @@ bool WebContents::OnMessageReceived(const IPC::Message& message, auto relay = NativeWindowRelay::FromWebContents(web_contents()); if (!relay) return false; - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host) - IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup) - IPC_END_MESSAGE_MAP() IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host) + IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_ShowPopup, + relay->window.get(), NativeWindow::ShowAutofillPopup) IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup, relay->window.get(), NativeWindow::HideAutofillPopup) IPC_MESSAGE_UNHANDLED(handled = false) @@ -945,16 +944,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message, return handled; } -void WebContents::ShowAutofillPopup( - content::RenderFrameHost* frame_host, - const gfx::RectF& bounds, - const std::vector& values, - const std::vector& labels) { - auto relay = NativeWindowRelay::FromWebContents(web_contents()); - if (relay) - relay->window->ShowAutofillPopup(frame_host, this, bounds, values, labels); -} - // There are three ways of destroying a webContents: // 1. call webContents.destroy(); // 2. garbage collection; @@ -1634,10 +1623,6 @@ bool WebContents::IsOffScreen() const { #endif } -bool WebContents::IsOffScreenOrEmbedderOffscreen() const { - return IsOffScreen() || (IsGuest() && embedder_ && embedder_->IsOffScreen()); -} - void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) { Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap)); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 337627c5751..d51265ed126 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -182,7 +182,6 @@ class WebContents : public mate::TrackableObject, // Methods for offscreen rendering bool IsOffScreen() const; - bool IsOffScreenOrEmbedderOffscreen() const; void OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap); void StartPainting(); void StopPainting(); @@ -358,12 +357,6 @@ class WebContents : public mate::TrackableObject, void DevToolsOpened() override; void DevToolsClosed() override; - void ShowAutofillPopup( - content::RenderFrameHost* frame_host, - const gfx::RectF& bounds, - const std::vector& values, - const std::vector& labels); - private: AtomBrowserContext* GetBrowserContext() const; diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index 6552a08df6c..5ed9ca8d981 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -92,6 +92,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated( // Show save dialog if save path was not set already on item file_dialog::DialogSettings settings; settings.parent_window = window; + settings.force_detached = window->IsOffScreenDummy(); settings.title = item->GetURL().spec(); settings.default_path = default_path; if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) { diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index a1fad7e8e85..df00e4c599a 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -242,7 +242,8 @@ void CommonWebContentsDelegate::RunFileChooser( content::RenderFrameHost* render_frame_host, const content::FileChooserParams& params) { if (!web_dialog_helper_) - web_dialog_helper_.reset(new WebDialogHelper(owner_window())); + web_dialog_helper_.reset(new WebDialogHelper(owner_window(), + owner_window()->IsOffScreenDummy())); web_dialog_helper_->RunFileChooser(render_frame_host, params); } @@ -250,7 +251,8 @@ void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest, int request_id, const base::FilePath& path) { if (!web_dialog_helper_) - web_dialog_helper_.reset(new WebDialogHelper(owner_window())); + web_dialog_helper_.reset(new WebDialogHelper(owner_window(), + owner_window()->IsOffScreenDummy())); web_dialog_helper_->EnumerateDirectory(guest, request_id, path); } @@ -298,6 +300,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile( } else { file_dialog::DialogSettings settings; settings.parent_window = owner_window(); + settings.force_detached = owner_window()->IsOffScreenDummy(); settings.title = url; settings.default_path = base::FilePath::FromUTF8Unsafe(url); if (!file_dialog::ShowSaveDialog(settings, &path)) { @@ -364,6 +367,7 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem( std::vector paths; file_dialog::DialogSettings settings; settings.parent_window = owner_window(); + settings.force_detached = owner_window()->IsOffScreenDummy(); settings.properties = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; if (!file_dialog::ShowOpenDialog(settings, &paths)) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index c65219c3c88..21d76e09eca 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -232,7 +232,6 @@ class NativeWindow : public base::SupportsUserData, const content::NativeWebKeyboardEvent& event) {} virtual void ShowAutofillPopup( content::RenderFrameHost* frame_host, - atom::api::WebContents* web_contents, const gfx::RectF& bounds, const std::vector& values, const std::vector& labels) {} diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 711f3b60459..db873893bf8 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -10,6 +10,7 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/native_browser_view_views.h" #include "atom/browser/ui/views/menu_bar.h" +#include "atom/browser/web_contents_preferences.h" #include "atom/browser/window_list.h" #include "atom/common/color_util.h" #include "atom/common/draggable_region.h" @@ -1357,13 +1358,19 @@ void NativeWindowViews::HandleKeyboardEvent( void NativeWindowViews::ShowAutofillPopup( content::RenderFrameHost* frame_host, - atom::api::WebContents* web_contents, const gfx::RectF& bounds, const std::vector& values, - const std::vector& labels) { + const std::vector& labels) { + WebContentsPreferences* web_preferences = + WebContentsPreferences::FromWebContents(web_contents()); + + bool isOffsceen = web_preferences->IsOffScreen(web_contents()); + bool isEmbedderOffscreen = web_preferences->IsGuest(web_contents()) && + web_preferences->IsOffScreen(web_preferences->Embedder(web_contents())); + autofill_popup_->CreateView( frame_host, - web_contents->IsOffScreenOrEmbedderOffscreen(), + isOffsceen || isEmbedderOffscreen, widget(), bounds); autofill_popup_->SetItems(values, labels); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 71a71275665..0f14f35c8f3 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -190,7 +190,6 @@ class NativeWindowViews : public NativeWindow, const content::NativeWebKeyboardEvent& event) override; void ShowAutofillPopup( content::RenderFrameHost* frame_host, - atom::api::WebContents* web_contents, const gfx::RectF& bounds, const std::vector& values, const std::vector& labels) override; diff --git a/atom/browser/osr/osr_output_device.cc b/atom/browser/osr/osr_output_device.cc index c35e364236f..1234a17b842 100644 --- a/atom/browser/osr/osr_output_device.cc +++ b/atom/browser/osr/osr_output_device.cc @@ -79,12 +79,12 @@ void OffScreenOutputDevice::EndPaint() { OnPaint(damage_rect_); } -void OffScreenOutputDevice::SetActive(bool active) { +void OffScreenOutputDevice::SetActive(bool active, bool paint) { if (active == active_) return; active_ = active; - if (active_) + if (active_ && paint) OnPaint(gfx::Rect(viewport_pixel_size_)); } diff --git a/atom/browser/osr/osr_output_device.h b/atom/browser/osr/osr_output_device.h index 5710bc41b83..a65865316fa 100644 --- a/atom/browser/osr/osr_output_device.h +++ b/atom/browser/osr/osr_output_device.h @@ -24,7 +24,7 @@ class OffScreenOutputDevice : public cc::SoftwareOutputDevice { SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override; void EndPaint() override; - void SetActive(bool active); + void SetActive(bool active, bool paint); void OnPaint(const gfx::Rect& damage_rect); private: diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index a53ef02b524..42d3b7792e3 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -549,7 +549,7 @@ void OffScreenRenderWidgetHostView::SubmitCompositorFrame( if (!frame.render_pass_list.empty()) { if (software_output_device_) { if (!begin_frame_timer_.get() || IsPopupWidget()) { - software_output_device_->SetActive(painting_); + software_output_device_->SetActive(painting_, false); } // The compositor will draw directly to the SoftwareOutputDevice which @@ -935,7 +935,7 @@ void OffScreenRenderWidgetHostView::SetNeedsBeginFrames( begin_frame_timer_->SetActive(needs_begin_frames); if (software_output_device_) { - software_output_device_->SetActive(needs_begin_frames && painting_); + software_output_device_->SetActive(needs_begin_frames && painting_, false); } } @@ -1151,7 +1151,7 @@ void OffScreenRenderWidgetHostView::SetPainting(bool painting) { painting_ = painting; if (software_output_device_) { - software_output_device_->SetActive(painting_); + software_output_device_->SetActive(painting_, true); } } diff --git a/atom/browser/ui/file_dialog.h b/atom/browser/ui/file_dialog.h index 79353d03a5d..80b96162bac 100644 --- a/atom/browser/ui/file_dialog.h +++ b/atom/browser/ui/file_dialog.h @@ -49,6 +49,7 @@ struct DialogSettings { Filters filters; int properties = 0; bool shows_tag_field = true; + bool force_detached = false; }; bool ShowOpenDialog(const DialogSettings& settings, diff --git a/atom/browser/ui/file_dialog_mac.mm b/atom/browser/ui/file_dialog_mac.mm index 59acc389e32..276f782ce0d 100644 --- a/atom/browser/ui/file_dialog_mac.mm +++ b/atom/browser/ui/file_dialog_mac.mm @@ -110,13 +110,13 @@ void SetupDialogForProperties(NSOpenPanel* dialog, int properties) { } // Run modal dialog with parent window and return user's choice. -int RunModalDialog(NSSavePanel* dialog, atom::NativeWindow* parent_window) { +int RunModalDialog(NSSavePanel* dialog, const DialogSettings& settings) { __block int chosen = NSFileHandlingPanelCancelButton; - if (!parent_window || !parent_window->GetNativeWindow() || - parent_window->IsOffScreenDummy()) { + if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || + settings.force_detached) { chosen = [dialog runModal]; } else { - NSWindow* window = parent_window->GetNativeWindow(); + NSWindow* window = settings.parent_window->GetNativeWindow(); [dialog beginSheetModalForWindow:window completionHandler:^(NSInteger c) { @@ -146,7 +146,7 @@ bool ShowOpenDialog(const DialogSettings& settings, SetupDialog(dialog, settings); SetupDialogForProperties(dialog, settings.properties); - int chosen = RunModalDialog(dialog, settings.parent_window); + int chosen = RunModalDialog(dialog, settings); if (chosen == NSFileHandlingPanelCancelButton) return false; @@ -166,7 +166,7 @@ void ShowOpenDialog(const DialogSettings& settings, __block OpenDialogCallback callback = c; if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || - settings.parent_window->IsOffScreenDummy()) { + settings.force_detached) { int chosen = [dialog runModal]; if (chosen == NSFileHandlingPanelCancelButton) { callback.Run(false, std::vector()); @@ -197,7 +197,7 @@ bool ShowSaveDialog(const DialogSettings& settings, SetupDialog(dialog, settings); - int chosen = RunModalDialog(dialog, settings.parent_window); + int chosen = RunModalDialog(dialog, settings); if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL]) return false; @@ -215,7 +215,7 @@ void ShowSaveDialog(const DialogSettings& settings, __block SaveDialogCallback callback = c; if (!settings.parent_window || !settings.parent_window->GetNativeWindow() || - settings.parent_window->IsOffScreenDummy()) { + settings.force_detached) { int chosen = [dialog runModal]; if (chosen == NSFileHandlingPanelCancelButton) { callback.Run(false, base::FilePath()); diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index cc621625818..2c9e1f51cea 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -239,6 +239,52 @@ bool WebContentsPreferences::IsPluginsEnabled( return IsPreferenceEnabled("plugins", web_contents); } +bool WebContentsPreferences::IsOffScreen( + content::WebContents* web_contents) { + return IsPreferenceEnabled("offscreen", web_contents); +} + +bool WebContentsPreferences::IsGuest( + content::WebContents* web_contents) { + WebContentsPreferences* self; + if (!web_contents) + return false; + + self = FromWebContents(web_contents); + if (!self) + return false; + + base::DictionaryValue& web_preferences = self->web_preferences_; + int guest_instance_id = 0; + return web_preferences.GetInteger( + options::kGuestInstanceID, &guest_instance_id); +} + +content::WebContents* WebContentsPreferences::Embedder( + content::WebContents* web_contents) { + WebContentsPreferences* self; + if (!web_contents) + return nullptr; + + self = FromWebContents(web_contents); + if (!self) + return nullptr; + + base::DictionaryValue& web_preferences = self->web_preferences_; + int g_instance_id = 0; + if (web_preferences.GetInteger(options::kGuestInstanceID, &g_instance_id)) { + auto manager = WebViewManager::GetWebViewManager(web_contents); + if (manager) { + auto embedder = manager->GetEmbedder(g_instance_id); + if (embedder) { + return embedder; + } + } + } + + return nullptr; +} + bool WebContentsPreferences::DisablePopups( content::WebContents* web_contents) { return IsPreferenceEnabled("disablePopups", web_contents); diff --git a/atom/browser/web_contents_preferences.h b/atom/browser/web_contents_preferences.h index 366aa1d9520..4fe34790c58 100644 --- a/atom/browser/web_contents_preferences.h +++ b/atom/browser/web_contents_preferences.h @@ -43,6 +43,9 @@ class WebContentsPreferences static bool UsesNativeWindowOpen(content::WebContents* web_contents); static bool DisablePopups(content::WebContents* web_contents); static bool IsPluginsEnabled(content::WebContents* web_contents); + static bool IsOffScreen(content::WebContents* web_contents); + static bool IsGuest(content::WebContents* web_contents); + static content::WebContents* Embedder(content::WebContents* web_contents); // Modify the WebPreferences according to |web_contents|'s preferences. static void OverrideWebkitPrefs( diff --git a/atom/browser/web_dialog_helper.cc b/atom/browser/web_dialog_helper.cc index 5107e3e3a07..a20d962c0a8 100644 --- a/atom/browser/web_dialog_helper.cc +++ b/atom/browser/web_dialog_helper.cc @@ -182,8 +182,9 @@ file_dialog::Filters GetFileTypesFromAcceptType( namespace atom { -WebDialogHelper::WebDialogHelper(NativeWindow* window) +WebDialogHelper::WebDialogHelper(NativeWindow* window, bool offscreen) : window_(window), + offscreen_(offscreen), weak_factory_(this) { } @@ -197,6 +198,7 @@ void WebDialogHelper::RunFileChooser( std::vector result; file_dialog::DialogSettings settings; + settings.force_detached = offscreen_; settings.filters = GetFileTypesFromAcceptType(params.accept_types); settings.parent_window = window_; settings.title = base::UTF16ToUTF8(params.title); diff --git a/atom/browser/web_dialog_helper.h b/atom/browser/web_dialog_helper.h index 67fe68031cd..8f4963fa0b0 100644 --- a/atom/browser/web_dialog_helper.h +++ b/atom/browser/web_dialog_helper.h @@ -23,7 +23,7 @@ class NativeWindow; class WebDialogHelper { public: - explicit WebDialogHelper(NativeWindow* window); + explicit WebDialogHelper(NativeWindow* window, bool offscreen); ~WebDialogHelper(); void RunFileChooser(content::RenderFrameHost* render_frame_host, @@ -34,6 +34,7 @@ class WebDialogHelper { private: NativeWindow* window_; + bool offscreen_; base::WeakPtrFactory weak_factory_;