From 9ba7db8815f3c19056f79fe48f69fa966ef2760a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 10 Feb 2014 20:07:38 +0800 Subject: [PATCH] win: Fix detecting attached modal dialog. --- browser/native_window.cc | 5 +++++ browser/native_window.h | 28 +++++++++++++++++++++++++++- browser/native_window_win.cc | 16 ---------------- browser/native_window_win.h | 1 - browser/ui/file_dialog_win.cc | 1 + browser/ui/message_box_win.cc | 5 ++++- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/browser/native_window.cc b/browser/native_window.cc index c81625c367d6..7c47c3122b18 100644 --- a/browser/native_window.cc +++ b/browser/native_window.cc @@ -49,6 +49,7 @@ NativeWindow::NativeWindow(content::WebContents* web_contents, has_frame_(true), is_closed_(false), node_integration_("all"), + has_dialog_attached_(false), weak_factory_(this), inspectable_web_contents_( brightray::InspectableWebContents::Create(web_contents)) { @@ -158,6 +159,10 @@ void NativeWindow::InitFromOptions(base::DictionaryValue* options) { Show(); } +bool NativeWindow::HasModalDialog() { + return has_dialog_attached_; +} + void NativeWindow::OpenDevTools() { inspectable_web_contents()->ShowDevTools(); } diff --git a/browser/native_window.h b/browser/native_window.h index ad6e8a152b76..0e802fd110d9 100644 --- a/browser/native_window.h +++ b/browser/native_window.h @@ -54,6 +54,25 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, typedef base::Callback& buffer)> CapturePageCallback; + class DialogScope { + public: + DialogScope(NativeWindow* window) + : window_(window) { + if (window_ != NULL) + window_->set_has_dialog_attached(true); + } + + ~DialogScope() { + if (window_ != NULL) + window_->set_has_dialog_attached(false); + } + + private: + NativeWindow* window_; + + DISALLOW_COPY_AND_ASSIGN(DialogScope); + }; + virtual ~NativeWindow(); // Create window with existing WebContents. @@ -100,7 +119,7 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, virtual void FlashFrame(bool flash) = 0; virtual void SetKiosk(bool kiosk) = 0; virtual bool IsKiosk() = 0; - virtual bool HasModalDialog() = 0; + virtual bool HasModalDialog(); virtual gfx::NativeWindow GetNativeWindow() = 0; virtual bool IsClosed() const { return is_closed_; } @@ -142,6 +161,10 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, bool has_frame() const { return has_frame_; } std::string node_integration() const { return node_integration_; } + void set_has_dialog_attached(bool has_dialog_attached) { + has_dialog_attached_ = has_dialog_attached; + } + protected: explicit NativeWindow(content::WebContents* web_contents, base::DictionaryValue* options); @@ -223,6 +246,9 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate, // The security token of iframe. std::string node_integration_; + // There is a dialog that has been attached to window. + bool has_dialog_attached_; + // Closure that would be called when window is unresponsive when closing, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresposive_closure_; diff --git a/browser/native_window_win.cc b/browser/native_window_win.cc index 2bbe78e90b38..fefe1b2b98a2 100644 --- a/browser/native_window_win.cc +++ b/browser/native_window_win.cc @@ -194,17 +194,6 @@ class NativeWindowFramelessView : public views::NonClientFrameView { DISALLOW_COPY_AND_ASSIGN(NativeWindowFramelessView); }; -bool WindowHasModalDialog(HWND parent, HWND except, HWND after = NULL) { - HWND hwnd = ::FindWindowEx(parent, after, NULL, NULL); - if (hwnd != except && - (::GetWindowLong(hwnd, GWL_STYLE) & (WS_VISIBLE | WS_POPUP))) - return true; - else if (hwnd == NULL) - return false; - else - return WindowHasModalDialog(parent, except, hwnd); -} - } // namespace NativeWindowWin::NativeWindowWin(content::WebContents* web_contents, @@ -370,11 +359,6 @@ bool NativeWindowWin::IsKiosk() { return IsFullscreen(); } -bool NativeWindowWin::HasModalDialog() { - return WindowHasModalDialog(GetNativeWindow(), - GetWebContents()->GetView()->GetNativeView()); -} - gfx::NativeWindow NativeWindowWin::GetNativeWindow() { return window_->GetNativeView(); } diff --git a/browser/native_window_win.h b/browser/native_window_win.h index d7f58f55e14b..738c98d68a40 100644 --- a/browser/native_window_win.h +++ b/browser/native_window_win.h @@ -65,7 +65,6 @@ class NativeWindowWin : public NativeWindow, virtual void FlashFrame(bool flash) OVERRIDE; virtual void SetKiosk(bool kiosk) OVERRIDE; virtual bool IsKiosk() OVERRIDE; - virtual bool HasModalDialog() OVERRIDE; virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; void OnMenuCommand(int position, HMENU menu); diff --git a/browser/ui/file_dialog_win.cc b/browser/ui/file_dialog_win.cc index 1f806dd5380f..b8b8233db9f4 100644 --- a/browser/ui/file_dialog_win.cc +++ b/browser/ui/file_dialog_win.cc @@ -163,6 +163,7 @@ class FileDialog { } bool Show(atom::NativeWindow* parent_window) { + atom::NativeWindow::DialogScope dialog_scope(parent_window); HWND window = parent_window ? parent_window->GetNativeWindow() : NULL; return dialog_->DoModal(window) == IDOK; } diff --git a/browser/ui/message_box_win.cc b/browser/ui/message_box_win.cc index d7714931174a..c7a61b8edbb7 100644 --- a/browser/ui/message_box_win.cc +++ b/browser/ui/message_box_win.cc @@ -76,6 +76,7 @@ class MessageDialog : public base::MessageLoop::Dispatcher, string16 title_; views::Widget* widget_; views::MessageBoxView* message_box_view_; + scoped_ptr dialog_scope_; std::vector buttons_; MessageBoxCallback callback_; @@ -96,7 +97,8 @@ MessageDialog::MessageDialog(NativeWindow* parent_window, result_(-1), title_(UTF8ToUTF16(title)), widget_(NULL), - message_box_view_(NULL) { + message_box_view_(NULL), + dialog_scope_(new NativeWindow::DialogScope(parent_window)) { DCHECK_GT(buttons.size(), 0u); set_owned_by_client(); @@ -174,6 +176,7 @@ string16 MessageDialog::GetWindowTitle() const { void MessageDialog::WindowClosing() { should_close_ = true; + dialog_scope_.reset(); if (delete_on_close_) { callback_.Run(GetResult());