Merge pull request #10510 from brenca/osr-autofill-devtools-fix

OSR fixes - devtools, dialogs
This commit is contained in:
Cheng Zhao 2017-11-13 18:04:35 +09:00 committed by GitHub
commit 4d364fa27a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 170 additions and 69 deletions

View file

@ -909,6 +909,17 @@ void WebContents::DevToolsClosed() {
Emit("devtools-closed"); Emit("devtools-closed");
} }
void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
auto relay = NativeWindowRelay::FromWebContents(web_contents());
if (relay) {
relay->window->ShowAutofillPopup(
frame_host, web_contents(), bounds, values, labels);
}
}
bool WebContents::OnMessageReceived(const IPC::Message& message) { bool WebContents::OnMessageReceived(const IPC::Message& message) {
bool handled = true; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(WebContents, message) IPC_BEGIN_MESSAGE_MAP(WebContents, message)
@ -933,9 +944,10 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
auto relay = NativeWindowRelay::FromWebContents(web_contents()); auto relay = NativeWindowRelay::FromWebContents(web_contents());
if (!relay) if (!relay)
return false; 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_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_ShowPopup,
relay->window.get(), NativeWindow::ShowAutofillPopup)
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup, IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
relay->window.get(), NativeWindow::HideAutofillPopup) relay->window.get(), NativeWindow::HideAutofillPopup)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
@ -1623,10 +1635,6 @@ bool WebContents::IsOffScreen() const {
#endif #endif
} }
bool WebContents::IsOffScreenOrEmbedderOffscreen() const {
return IsOffScreen() || (embedder_ && embedder_->IsOffScreen());
}
void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) { void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) {
Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap)); Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap));
} }

View file

@ -182,7 +182,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Methods for offscreen rendering // Methods for offscreen rendering
bool IsOffScreen() const; bool IsOffScreen() const;
bool IsOffScreenOrEmbedderOffscreen() const;
void OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap); void OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap);
void StartPainting(); void StartPainting();
void StopPainting(); void StopPainting();
@ -358,6 +357,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DevToolsOpened() override; void DevToolsOpened() override;
void DevToolsClosed() override; void DevToolsClosed() override;
void ShowAutofillPopup(content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels);
private: private:
AtomBrowserContext* GetBrowserContext() const; AtomBrowserContext* GetBrowserContext() const;

View file

@ -144,6 +144,7 @@ void Window::Init(v8::Isolate* isolate,
options, options,
parent.IsEmpty() ? nullptr : parent->window_.get())); parent.IsEmpty() ? nullptr : parent->window_.get()));
web_contents->SetOwnerWindow(window_.get()); web_contents->SetOwnerWindow(window_.get());
window_->set_is_offscreen_dummy(api_web_contents_->IsOffScreen());
#if defined(TOOLKIT_VIEWS) #if defined(TOOLKIT_VIEWS)
// Sets the window icon. // Sets the window icon.

View file

@ -92,6 +92,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
// Show save dialog if save path was not set already on item // Show save dialog if save path was not set already on item
file_dialog::DialogSettings settings; file_dialog::DialogSettings settings;
settings.parent_window = window; settings.parent_window = window;
settings.force_detached = window->is_offscreen_dummy();
settings.title = item->GetURL().spec(); settings.title = item->GetURL().spec();
settings.default_path = default_path; settings.default_path = default_path;
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) { if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {

View file

@ -242,7 +242,8 @@ void CommonWebContentsDelegate::RunFileChooser(
content::RenderFrameHost* render_frame_host, content::RenderFrameHost* render_frame_host,
const content::FileChooserParams& params) { const content::FileChooserParams& params) {
if (!web_dialog_helper_) if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(owner_window())); web_dialog_helper_.reset(new WebDialogHelper(
owner_window(), owner_window()->is_offscreen_dummy()));
web_dialog_helper_->RunFileChooser(render_frame_host, params); web_dialog_helper_->RunFileChooser(render_frame_host, params);
} }
@ -250,7 +251,8 @@ void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
int request_id, int request_id,
const base::FilePath& path) { const base::FilePath& path) {
if (!web_dialog_helper_) if (!web_dialog_helper_)
web_dialog_helper_.reset(new WebDialogHelper(owner_window())); web_dialog_helper_.reset(new WebDialogHelper(
owner_window(), owner_window()->is_offscreen_dummy()));
web_dialog_helper_->EnumerateDirectory(guest, request_id, path); web_dialog_helper_->EnumerateDirectory(guest, request_id, path);
} }
@ -298,6 +300,7 @@ void CommonWebContentsDelegate::DevToolsSaveToFile(
} else { } else {
file_dialog::DialogSettings settings; file_dialog::DialogSettings settings;
settings.parent_window = owner_window(); settings.parent_window = owner_window();
settings.force_detached = owner_window()->is_offscreen_dummy();
settings.title = url; settings.title = url;
settings.default_path = base::FilePath::FromUTF8Unsafe(url); settings.default_path = base::FilePath::FromUTF8Unsafe(url);
if (!file_dialog::ShowSaveDialog(settings, &path)) { if (!file_dialog::ShowSaveDialog(settings, &path)) {
@ -364,6 +367,7 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem(
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
file_dialog::DialogSettings settings; file_dialog::DialogSettings settings;
settings.parent_window = owner_window(); settings.parent_window = owner_window();
settings.force_detached = owner_window()->is_offscreen_dummy();
settings.properties = file_dialog::FILE_DIALOG_OPEN_DIRECTORY; settings.properties = file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
if (!file_dialog::ShowOpenDialog(settings, &paths)) if (!file_dialog::ShowOpenDialog(settings, &paths))
return; return;

View file

@ -65,6 +65,7 @@ NativeWindow::NativeWindow(
aspect_ratio_(0.0), aspect_ratio_(0.0),
parent_(parent), parent_(parent),
is_modal_(false), is_modal_(false),
is_osr_dummy_(false),
inspectable_web_contents_(inspectable_web_contents), inspectable_web_contents_(inspectable_web_contents),
weak_factory_(this) { weak_factory_(this) {
options.Get(options::kFrame, &has_frame_); options.Get(options::kFrame, &has_frame_);

View file

@ -231,6 +231,7 @@ class NativeWindow : public base::SupportsUserData,
const content::NativeWebKeyboardEvent& event) {} const content::NativeWebKeyboardEvent& event) {}
virtual void ShowAutofillPopup( virtual void ShowAutofillPopup(
content::RenderFrameHost* frame_host, content::RenderFrameHost* frame_host,
content::WebContents* web_contents,
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {} const std::vector<base::string16>& labels) {}
@ -288,6 +289,9 @@ class NativeWindow : public base::SupportsUserData,
SkRegion* draggable_region() const { return draggable_region_.get(); } SkRegion* draggable_region() const { return draggable_region_.get(); }
bool enable_larger_than_screen() const { return enable_larger_than_screen_; } bool enable_larger_than_screen() const { return enable_larger_than_screen_; }
void set_is_offscreen_dummy(bool is_dummy) { is_osr_dummy_ = is_dummy; }
bool is_offscreen_dummy() const { return is_osr_dummy_; }
NativeWindow* parent() const { return parent_; } NativeWindow* parent() const { return parent_; }
bool is_modal() const { return is_modal_; } bool is_modal() const { return is_modal_; }
@ -366,6 +370,9 @@ class NativeWindow : public base::SupportsUserData,
// Is this a modal window. // Is this a modal window.
bool is_modal_; bool is_modal_;
// Is this a dummy window for an offscreen WebContents.
bool is_osr_dummy_;
// The page this window is viewing. // The page this window is viewing.
brightray::InspectableWebContents* inspectable_web_contents_; brightray::InspectableWebContents* inspectable_web_contents_;

View file

@ -10,6 +10,8 @@
#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/native_browser_view_views.h" #include "atom/browser/native_browser_view_views.h"
#include "atom/browser/ui/views/menu_bar.h" #include "atom/browser/ui/views/menu_bar.h"
#include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/color_util.h" #include "atom/common/color_util.h"
#include "atom/common/draggable_region.h" #include "atom/common/draggable_region.h"
@ -1357,17 +1359,37 @@ void NativeWindowViews::HandleKeyboardEvent(
void NativeWindowViews::ShowAutofillPopup( void NativeWindowViews::ShowAutofillPopup(
content::RenderFrameHost* frame_host, content::RenderFrameHost* frame_host,
content::WebContents* web_contents,
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) { const std::vector<base::string16>& labels) {
auto wc = atom::api::WebContents::FromWrappedClass( const auto* web_preferences =
v8::Isolate::GetCurrent(), web_contents()); WebContentsPreferences::FromWebContents(web_contents)->web_preferences();
bool is_offsceen = false;
web_preferences->GetBoolean("offscreen", &is_offsceen);
int guest_instance_id = 0;
web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id);
bool is_embedder_offscreen = false;
if (guest_instance_id) {
auto manager = WebViewManager::GetWebViewManager(web_contents);
if (manager) {
auto embedder = manager->GetEmbedder(guest_instance_id);
if (embedder) {
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
"offscreen", embedder);
}
}
}
autofill_popup_->CreateView( autofill_popup_->CreateView(
frame_host, frame_host,
wc->IsOffScreenOrEmbedderOffscreen(), is_offsceen || is_embedder_offscreen,
widget(), widget(),
bounds); bounds);
autofill_popup_->SetItems(values, labels); autofill_popup_->SetItems(values, labels);
autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight);
} }
void NativeWindowViews::HideAutofillPopup( void NativeWindowViews::HideAutofillPopup(
@ -1389,6 +1411,9 @@ void NativeWindowViews::Layout() {
gfx::Rect(0, menu_bar_bounds.height(), size.width(), gfx::Rect(0, menu_bar_bounds.height(), size.width(),
size.height() - menu_bar_bounds.height())); size.height() - menu_bar_bounds.height()));
} }
if (autofill_popup_.get())
autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight);
} }
gfx::Size NativeWindowViews::GetMinimumSize() const { gfx::Size NativeWindowViews::GetMinimumSize() const {

View file

@ -190,6 +190,7 @@ class NativeWindowViews : public NativeWindow,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;
void ShowAutofillPopup( void ShowAutofillPopup(
content::RenderFrameHost* frame_host, content::RenderFrameHost* frame_host,
content::WebContents* web_contents,
const gfx::RectF& bounds, const gfx::RectF& bounds,
const std::vector<base::string16>& values, const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) override; const std::vector<base::string16>& labels) override;

View file

@ -79,12 +79,12 @@ void OffScreenOutputDevice::EndPaint() {
OnPaint(damage_rect_); OnPaint(damage_rect_);
} }
void OffScreenOutputDevice::SetActive(bool active) { void OffScreenOutputDevice::SetActive(bool active, bool paint) {
if (active == active_) if (active == active_)
return; return;
active_ = active; active_ = active;
if (active_) if (active_ && paint)
OnPaint(gfx::Rect(viewport_pixel_size_)); OnPaint(gfx::Rect(viewport_pixel_size_));
} }

View file

@ -24,7 +24,7 @@ class OffScreenOutputDevice : public cc::SoftwareOutputDevice {
SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override; SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
void EndPaint() override; void EndPaint() override;
void SetActive(bool active); void SetActive(bool active, bool paint);
void OnPaint(const gfx::Rect& damage_rect); void OnPaint(const gfx::Rect& damage_rect);
private: private:

View file

@ -549,7 +549,7 @@ void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
if (!frame.render_pass_list.empty()) { if (!frame.render_pass_list.empty()) {
if (software_output_device_) { if (software_output_device_) {
if (!begin_frame_timer_.get() || IsPopupWidget()) { 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 // The compositor will draw directly to the SoftwareOutputDevice which
@ -935,7 +935,7 @@ void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
begin_frame_timer_->SetActive(needs_begin_frames); begin_frame_timer_->SetActive(needs_begin_frames);
if (software_output_device_) { 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; painting_ = painting;
if (software_output_device_) { if (software_output_device_) {
software_output_device_->SetActive(painting_); software_output_device_->SetActive(painting_, true);
} }
} }

View file

@ -155,7 +155,6 @@ void AutofillPopup::SetItems(const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) { const std::vector<base::string16>& labels) {
values_ = values; values_ = values;
labels_ = labels; labels_ = labels;
UpdatePopupBounds();
if (view_) { if (view_) {
view_->OnSuggestionsChanged(); view_->OnSuggestionsChanged();
} }
@ -166,21 +165,23 @@ void AutofillPopup::AcceptSuggestion(int index) {
frame_host_->GetRoutingID(), GetValueAt(index))); frame_host_->GetRoutingID(), GetValueAt(index)));
} }
void AutofillPopup::UpdatePopupBounds() { void AutofillPopup::UpdatePopupBounds(int height_compensation) {
int desired_width = GetDesiredPopupWidth(); int desired_width = GetDesiredPopupWidth();
int desired_height = GetDesiredPopupHeight(); int desired_height = GetDesiredPopupHeight();
bool is_rtl = false; bool is_rtl = false;
gfx::Point origin(element_bounds_.origin().x(),
element_bounds_.origin().y() - height_compensation);
gfx::Rect bounds(origin, element_bounds_.size());
gfx::Point top_left_corner_of_popup = gfx::Point top_left_corner_of_popup =
element_bounds_.origin() + origin + gfx::Vector2d(bounds.width() - desired_width, -desired_height);
gfx::Vector2d(element_bounds_.width() - desired_width, -desired_height);
// This is the bottom right point of the popup if the popup is below the // This is the bottom right point of the popup if the popup is below the
// element and grows to the right (since the is the lowest and furthest right // element and grows to the right (since the is the lowest and furthest right
// the popup could go). // the popup could go).
gfx::Point bottom_right_corner_of_popup = gfx::Point bottom_right_corner_of_popup =
element_bounds_.origin() + origin + gfx::Vector2d(desired_width, bounds.height() + desired_height);
gfx::Vector2d(desired_width, element_bounds_.height() + desired_height);
display::Display top_left_display = display::Display top_left_display =
GetDisplayNearestPoint(top_left_corner_of_popup, container_view_); GetDisplayNearestPoint(top_left_corner_of_popup, container_view_);
@ -189,14 +190,19 @@ void AutofillPopup::UpdatePopupBounds() {
std::pair<int, int> popup_x_and_width = std::pair<int, int> popup_x_and_width =
CalculatePopupXAndWidth(top_left_display, bottom_right_display, CalculatePopupXAndWidth(top_left_display, bottom_right_display,
desired_width, element_bounds_, is_rtl); desired_width, bounds, is_rtl);
std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight( std::pair<int, int> popup_y_and_height =
top_left_display, bottom_right_display, desired_height, element_bounds_); CalculatePopupYAndHeight(top_left_display, bottom_right_display,
desired_height, bounds);
popup_bounds_ = gfx::Rect(popup_x_and_width.first, popup_y_and_height.first, popup_bounds_ = gfx::Rect(
popup_x_and_width.first, popup_y_and_height.first,
popup_x_and_width.second, popup_y_and_height.second); popup_x_and_width.second, popup_y_and_height.second);
popup_bounds_in_view_ = gfx::Rect(popup_bounds_in_view_.origin(), popup_bounds_in_view_ = gfx::Rect(
popup_bounds_in_view_.origin(),
gfx::Size(popup_x_and_width.second, popup_y_and_height.second)); gfx::Size(popup_x_and_width.second, popup_y_and_height.second));
if (view_)
view_->DoUpdateBoundsAndRedrawPopup();
} }
int AutofillPopup::GetDesiredPopupHeight() { int AutofillPopup::GetDesiredPopupHeight() {

View file

@ -11,6 +11,7 @@
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "ui/gfx/font_list.h" #include "ui/gfx/font_list.h"
#include "ui/native_theme/native_theme.h" #include "ui/native_theme/native_theme.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace atom { namespace atom {
@ -28,13 +29,13 @@ class AutofillPopup {
void SetItems(const std::vector<base::string16>& values, void SetItems(const std::vector<base::string16>& values,
const std::vector<base::string16>& labels); const std::vector<base::string16>& labels);
void UpdatePopupBounds(int height_compensation);
private: private:
friend class AutofillPopupView; friend class AutofillPopupView;
void AcceptSuggestion(int index); void AcceptSuggestion(int index);
void UpdatePopupBounds();
int GetDesiredPopupHeight(); int GetDesiredPopupHeight();
int GetDesiredPopupWidth(); int GetDesiredPopupWidth();
gfx::Rect GetRowBounds(int i); gfx::Rect GetRowBounds(int i);

View file

@ -49,6 +49,7 @@ struct DialogSettings {
Filters filters; Filters filters;
int properties = 0; int properties = 0;
bool shows_tag_field = true; bool shows_tag_field = true;
bool force_detached = false;
}; };
bool ShowOpenDialog(const DialogSettings& settings, bool ShowOpenDialog(const DialogSettings& settings,

View file

@ -110,12 +110,13 @@ void SetupDialogForProperties(NSOpenPanel* dialog, int properties) {
} }
// Run modal dialog with parent window and return user's choice. // 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; __block int chosen = NSFileHandlingPanelCancelButton;
if (!parent_window || !parent_window->GetNativeWindow()) { if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.force_detached) {
chosen = [dialog runModal]; chosen = [dialog runModal];
} else { } else {
NSWindow* window = parent_window->GetNativeWindow(); NSWindow* window = settings.parent_window->GetNativeWindow();
[dialog beginSheetModalForWindow:window [dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger c) { completionHandler:^(NSInteger c) {
@ -145,7 +146,7 @@ bool ShowOpenDialog(const DialogSettings& settings,
SetupDialog(dialog, settings); SetupDialog(dialog, settings);
SetupDialogForProperties(dialog, settings.properties); SetupDialogForProperties(dialog, settings.properties);
int chosen = RunModalDialog(dialog, settings.parent_window); int chosen = RunModalDialog(dialog, settings);
if (chosen == NSFileHandlingPanelCancelButton) if (chosen == NSFileHandlingPanelCancelButton)
return false; return false;
@ -164,11 +165,9 @@ void ShowOpenDialog(const DialogSettings& settings,
// only store the pointer, by duplication we can force gcd to store a copy. // only store the pointer, by duplication we can force gcd to store a copy.
__block OpenDialogCallback callback = c; __block OpenDialogCallback callback = c;
NSWindow* window = settings.parent_window ? if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.parent_window->GetNativeWindow() : settings.force_detached) {
nullptr; int chosen = [dialog runModal];
[dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { if (chosen == NSFileHandlingPanelCancelButton) {
callback.Run(false, std::vector<base::FilePath>()); callback.Run(false, std::vector<base::FilePath>());
} else { } else {
@ -176,7 +175,19 @@ void ShowOpenDialog(const DialogSettings& settings,
ReadDialogPaths(dialog, &paths); ReadDialogPaths(dialog, &paths);
callback.Run(true, paths); callback.Run(true, paths);
} }
}]; } else {
NSWindow* window = settings.parent_window->GetNativeWindow();
[dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) {
callback.Run(false, std::vector<base::FilePath>());
} else {
std::vector<base::FilePath> paths;
ReadDialogPaths(dialog, &paths);
callback.Run(true, paths);
}
}];
}
} }
bool ShowSaveDialog(const DialogSettings& settings, bool ShowSaveDialog(const DialogSettings& settings,
@ -186,7 +197,7 @@ bool ShowSaveDialog(const DialogSettings& settings,
SetupDialog(dialog, settings); SetupDialog(dialog, settings);
int chosen = RunModalDialog(dialog, settings.parent_window); int chosen = RunModalDialog(dialog, settings);
if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL]) if (chosen == NSFileHandlingPanelCancelButton || ![[dialog URL] isFileURL])
return false; return false;
@ -203,18 +214,27 @@ void ShowSaveDialog(const DialogSettings& settings,
__block SaveDialogCallback callback = c; __block SaveDialogCallback callback = c;
NSWindow* window = settings.parent_window ? if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
settings.parent_window->GetNativeWindow() : settings.force_detached) {
nullptr; int chosen = [dialog runModal];
[dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) { if (chosen == NSFileHandlingPanelCancelButton) {
callback.Run(false, base::FilePath()); callback.Run(false, base::FilePath());
} else { } else {
std::string path = base::SysNSStringToUTF8([[dialog URL] path]); std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
callback.Run(true, base::FilePath(path)); callback.Run(true, base::FilePath(path));
} }
}]; } else {
NSWindow* window = settings.parent_window->GetNativeWindow();
[dialog beginSheetModalForWindow:window
completionHandler:^(NSInteger chosen) {
if (chosen == NSFileHandlingPanelCancelButton) {
callback.Run(false, base::FilePath());
} else {
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
callback.Run(true, base::FilePath(path));
}
}];
}
} }
} // namespace file_dialog } // namespace file_dialog

View file

@ -146,7 +146,8 @@ int ShowMessageBox(NativeWindow* parent_window,
// Use runModal for synchronous alert without parent, since we don't have a // Use runModal for synchronous alert without parent, since we don't have a
// window to wait for. // window to wait for.
if (!parent_window || !parent_window->GetNativeWindow()) if (!parent_window || !parent_window->GetNativeWindow() ||
parent_window->is_offscreen_dummy())
return [[alert autorelease] runModal]; return [[alert autorelease] runModal];
int ret_code = -1; int ret_code = -1;
@ -181,15 +182,24 @@ void ShowMessageBox(NativeWindow* parent_window,
NSAlert* alert = NSAlert* alert =
CreateNSAlert(parent_window, type, buttons, default_id, cancel_id, title, CreateNSAlert(parent_window, type, buttons, default_id, cancel_id, title,
message, detail, checkbox_label, checkbox_checked, icon); message, detail, checkbox_label, checkbox_checked, icon);
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
andAlert:alert
callEndModal:false];
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : nil; // Use runModal for synchronous alert without parent, since we don't have a
[alert beginSheetModalForWindow:window // window to wait for.
modalDelegate:delegate if (!parent_window || !parent_window->GetNativeWindow() ||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) parent_window->is_offscreen_dummy()) {
contextInfo:nil]; int ret = [[alert autorelease] runModal];
callback.Run(ret, false);
} else {
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
andAlert:alert
callEndModal:false];
NSWindow* window = parent_window ? parent_window->GetNativeWindow() : nil;
[alert beginSheetModalForWindow:window
modalDelegate:delegate
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
} }
void ShowErrorBox(const base::string16& title, const base::string16& content) { void ShowErrorBox(const base::string16& title, const base::string16& content) {

View file

@ -226,12 +226,13 @@ void AutofillPopupView::OnPaint(gfx::Canvas* canvas) {
SkBitmap bitmap; SkBitmap bitmap;
#if defined(ENABLE_OSR) #if defined(ENABLE_OSR)
std::unique_ptr<cc::SkiaPaintCanvas> paint_canvas;
if (view_proxy_.get()) { if (view_proxy_.get()) {
bitmap.allocN32Pixels(popup_->popup_bounds_in_view_.width(), bitmap.allocN32Pixels(popup_->popup_bounds_in_view_.width(),
popup_->popup_bounds_in_view_.height(), popup_->popup_bounds_in_view_.height(),
true); true);
cc::SkiaPaintCanvas paint_canvas(new SkCanvas(bitmap)); paint_canvas.reset(new cc::SkiaPaintCanvas(bitmap));
draw_canvas = new gfx::Canvas(&paint_canvas, 1.0); draw_canvas = new gfx::Canvas(paint_canvas.get(), 1.0);
} }
#endif #endif

View file

@ -182,8 +182,9 @@ file_dialog::Filters GetFileTypesFromAcceptType(
namespace atom { namespace atom {
WebDialogHelper::WebDialogHelper(NativeWindow* window) WebDialogHelper::WebDialogHelper(NativeWindow* window, bool offscreen)
: window_(window), : window_(window),
offscreen_(offscreen),
weak_factory_(this) { weak_factory_(this) {
} }
@ -197,6 +198,7 @@ void WebDialogHelper::RunFileChooser(
std::vector<content::FileChooserFileInfo> result; std::vector<content::FileChooserFileInfo> result;
file_dialog::DialogSettings settings; file_dialog::DialogSettings settings;
settings.force_detached = offscreen_;
settings.filters = GetFileTypesFromAcceptType(params.accept_types); settings.filters = GetFileTypesFromAcceptType(params.accept_types);
settings.parent_window = window_; settings.parent_window = window_;
settings.title = base::UTF16ToUTF8(params.title); settings.title = base::UTF16ToUTF8(params.title);

View file

@ -23,7 +23,7 @@ class NativeWindow;
class WebDialogHelper { class WebDialogHelper {
public: public:
explicit WebDialogHelper(NativeWindow* window); WebDialogHelper(NativeWindow* window, bool offscreen);
~WebDialogHelper(); ~WebDialogHelper();
void RunFileChooser(content::RenderFrameHost* render_frame_host, void RunFileChooser(content::RenderFrameHost* render_frame_host,
@ -34,6 +34,7 @@ class WebDialogHelper {
private: private:
NativeWindow* window_; NativeWindow* window_;
bool offscreen_;
base::WeakPtrFactory<WebDialogHelper> weak_factory_; base::WeakPtrFactory<WebDialogHelper> weak_factory_;

View file

@ -203,7 +203,7 @@ void AutofillAgent::ShowPopup(
void AutofillAgent::OnAcceptSuggestion(base::string16 suggestion) { void AutofillAgent::OnAcceptSuggestion(base::string16 suggestion) {
auto element = render_frame()->GetWebFrame()->GetDocument().FocusedElement(); auto element = render_frame()->GetWebFrame()->GetDocument().FocusedElement();
if (element.IsFormControlElement()) { if (element.IsFormControlElement()) {
ToWebInputElement(&element)->SetSuggestedValue( ToWebInputElement(&element)->SetAutofillValue(
blink::WebString::FromUTF16(suggestion)); blink::WebString::FromUTF16(suggestion));
} }
} }

View file

@ -94,7 +94,6 @@
if (visible) { if (visible) {
[devtools_window_ makeKeyAndOrderFront:nil]; [devtools_window_ makeKeyAndOrderFront:nil];
} else { } else {
[[self window] makeKeyAndOrderFront:nil];
[devtools_window_ setDelegate:nil]; [devtools_window_ setDelegate:nil];
[devtools_window_ close]; [devtools_window_ close];
devtools_window_.reset(); devtools_window_.reset();

View file

@ -443,11 +443,15 @@ ipcMain.on('ELECTRON_BROWSER_WINDOW_ALERT', function (event, message, title) {
if (message == null) message = '' if (message == null) message = ''
if (title == null) title = '' if (title == null) title = ''
event.returnValue = electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), { const dialogProperties = {
message: `${message}`, message: `${message}`,
title: `${title}`, title: `${title}`,
buttons: ['OK'] buttons: ['OK']
}) }
event.returnValue = event.sender.isOffscreen()
? electron.dialog.showMessageBox(dialogProperties)
: electron.dialog.showMessageBox(
event.sender.getOwnerBrowserWindow(), dialogProperties)
}) })
// Implements window.confirm(message, title) // Implements window.confirm(message, title)
@ -455,12 +459,16 @@ ipcMain.on('ELECTRON_BROWSER_WINDOW_CONFIRM', function (event, message, title) {
if (message == null) message = '' if (message == null) message = ''
if (title == null) title = '' if (title == null) title = ''
event.returnValue = !electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), { const dialogProperties = {
message: `${message}`, message: `${message}`,
title: `${title}`, title: `${title}`,
buttons: ['OK', 'Cancel'], buttons: ['OK', 'Cancel'],
cancelId: 1 cancelId: 1
}) }
event.returnValue = !(event.sender.isOffscreen()
? electron.dialog.showMessageBox(dialogProperties)
: electron.dialog.showMessageBox(
event.sender.getOwnerBrowserWindow(), dialogProperties))
}) })
// Implements window.close() // Implements window.close()