summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwittman@chromium.org <wittman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-06 06:50:23 +0000
committerwittman@chromium.org <wittman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-06 06:50:23 +0000
commit51a2478710c9b2beda273832f2e4f4c825aa279a (patch)
tree77a926fd642222b69989250f7295d95d3cd42724
parent8cea789efbec4198ab2315ee2f49927523832d2f (diff)
downloadchromium_src-51a2478710c9b2beda273832f2e4f4c825aa279a.zip
chromium_src-51a2478710c9b2beda273832f2e4f4c825aa279a.tar.gz
chromium_src-51a2478710c9b2beda273832f2e4f4c825aa279a.tar.bz2
Refactor modality-specific behavior from ConstrainedWindowViews to WebContentsModalDialogManager
This CL moves the Views web contents modal dialog code towards the interface described in the associated bug. Similar changes for Gtk and Cocoa will be made in follow-on CLs. To that end, this CL contains the following detailed changes: - Introduce NativeWebContentsModalDialogManager for providing platform-specific UI functionality within WebContentsModalDialogManager, and implement NativeWebContentsModalDialogManagerViews. - Under Views, move to a model where WebContentsModalDialogManager listens for closing events rather than requiring notifications from the widget. Continue using the existing model on Gtk and Cocoa, pending refactoring there. - Provide a mechanism for disabling mouse-driven dialog movement on Widget. - Remove NativeConstrainedWindowDelegate and subclasses as they're no longer necessary due to the above two items. - Update tests to account for closing notification to WebContentsModalDialogManager being done from the event loop, rather than synchronously. - Add temporary ConstrainedWindowViews factory function to minimize code churn at construction sites during this refactoring. The next planned steps in this work are: - Refactor ConstrainedWindow subclasses under Gtk and Cocoa to listen for closing events rather than requiring notifications from the widget. - Refactor uses of WebContentsModalDialog interface to use platform-specific equivalents in platform-specific code and, in platform-independent code, invoke functionality via some other mechanism: platform_utils, WebContentsModalDialogManager, ???. Remove WebContentsModalDialog interface. - Generalize WebContentsModalDialogManagerDelegate positioning interface and write WebContentsModalDialogManager::ShowDialog using the new interface. BUG=157161 Review URL: https://chromiumcodereview.appspot.com/12045037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180904 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/browser_command_controller_browsertest.cc2
-rw-r--r--chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm11
-rw-r--r--chrome/browser/ui/gtk/web_contents_modal_dialog_manager_gtk.cc11
-rw-r--r--chrome/browser/ui/native_web_contents_modal_dialog_manager.h29
-rw-r--r--chrome/browser/ui/views/autofill/autofill_dialog_views.cc2
-rw-r--r--chrome/browser/ui/views/collected_cookies_views.cc2
-rw-r--r--chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc2
-rw-r--r--chrome/browser/ui/views/constrained_window_views.cc81
-rw-r--r--chrome/browser/ui/views/constrained_window_views.h50
-rw-r--r--chrome/browser/ui/views/constrained_window_views_browsertest.cc8
-rw-r--r--chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc2
-rw-r--r--chrome/browser/ui/views/login_prompt_views.cc2
-rw-r--r--chrome/browser/ui/views/native_constrained_window_aura.cc48
-rw-r--r--chrome/browser/ui/views/native_constrained_window_win.cc60
-rw-r--r--chrome/browser/ui/views/ssl_client_certificate_selector.cc2
-rw-r--r--chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc2
-rw-r--r--chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc112
-rw-r--r--chrome/browser/ui/views/web_intent_picker_views.cc2
-rw-r--r--chrome/browser/ui/web_contents_modal_dialog_manager.cc7
-rw-r--r--chrome/browser/ui/web_contents_modal_dialog_manager.h12
-rw-r--r--chrome/browser/ui/web_contents_modal_dialog_manager_unittest.cc8
-rw-r--r--chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc1
-rw-r--r--chrome/chrome_browser_ui.gypi11
-rw-r--r--chrome/chrome_tests_unit.gypi1
-rw-r--r--ui/views/widget/widget.cc10
-rw-r--r--ui/views/widget/widget.h8
26 files changed, 259 insertions, 227 deletions
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc
index 930319b..1f71986 100644
--- a/chrome/browser/ui/browser_command_controller_browsertest.cc
+++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/test/test_utils.h"
typedef InProcessBrowserTest BrowserCommandControllerBrowserTest;
@@ -35,5 +36,6 @@ IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, DisableFind) {
// Closing the constrained window should reenable it.
delegate->Cancel();
+ content::RunAllPendingInMessageLoop();
EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
}
diff --git a/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm
new file mode 100644
index 0000000..fb82470
--- /dev/null
+++ b/chrome/browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm
@@ -0,0 +1,11 @@
+// Copyright (c) 2013 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 "chrome/browser/ui/web_contents_modal_dialog_manager.h"
+
+NativeWebContentsModalDialogManager*
+ WebContentsModalDialogManager::CreateNativeManager(
+ WebContentsModalDialogManager* manager) {
+ return NULL;
+}
diff --git a/chrome/browser/ui/gtk/web_contents_modal_dialog_manager_gtk.cc b/chrome/browser/ui/gtk/web_contents_modal_dialog_manager_gtk.cc
new file mode 100644
index 0000000..fb82470
--- /dev/null
+++ b/chrome/browser/ui/gtk/web_contents_modal_dialog_manager_gtk.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2013 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 "chrome/browser/ui/web_contents_modal_dialog_manager.h"
+
+NativeWebContentsModalDialogManager*
+ WebContentsModalDialogManager::CreateNativeManager(
+ WebContentsModalDialogManager* manager) {
+ return NULL;
+}
diff --git a/chrome/browser/ui/native_web_contents_modal_dialog_manager.h b/chrome/browser/ui/native_web_contents_modal_dialog_manager.h
new file mode 100644
index 0000000..7630b8c
--- /dev/null
+++ b/chrome/browser/ui/native_web_contents_modal_dialog_manager.h
@@ -0,0 +1,29 @@
+// 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 CHROME_BROWSER_UI_NATIVE_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_
+#define CHROME_BROWSER_UI_NATIVE_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_
+
+#include "ui/gfx/native_widget_types.h"
+
+// Provides an interface for platform-specific UI implementation for the web
+// contents modal dialog.
+class NativeWebContentsModalDialogManager {
+ public:
+ NativeWebContentsModalDialogManager() {}
+ virtual ~NativeWebContentsModalDialogManager() {}
+
+ // Starts management of the modal aspects of the dialog. This function should
+ // also register to be notified when the dialog is closing, so that it can
+ // notify the manager.
+ virtual void ManageDialog(gfx::NativeWindow window) = 0;
+
+ // Closes the web contents modal dialog.
+ virtual void CloseDialog(gfx::NativeWindow window) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NativeWebContentsModalDialogManager);
+};
+
+#endif // CHROME_BROWSER_UI_NATIVE_WEB_CONTENTS_MODAL_DIALOG_MANAGER_H_
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
index 5c5d64b..0dc677a 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
@@ -379,7 +379,7 @@ void AutofillDialogViews::Show() {
// Ownership of |contents_| is handed off by this call. The
// WebContentsModalDialog will take care of deleting itself after calling
// DeleteDelegate().
- window_ = new ConstrainedWindowViews(controller_->web_contents(), this);
+ window_ = ConstrainedWindowViews::Create(controller_->web_contents(), this);
focus_manager_ = window_->GetFocusManager();
focus_manager_->AddFocusChangeListener(this);
}
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index 38a0896..c945a62 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -198,7 +198,7 @@ CollectedCookiesViews::CollectedCookiesViews(content::WebContents* web_contents)
TabSpecificContentSettings::FromWebContents(web_contents);
registrar_.Add(this, chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN,
content::Source<TabSpecificContentSettings>(content_settings));
- window_ = new ConstrainedWindowViews(web_contents, this);
+ window_ = ConstrainedWindowViews::Create(web_contents, this);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
index 3489e2a..7bed073 100644
--- a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
+++ b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
@@ -190,7 +190,7 @@ ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
new ConstrainedWebDialogDelegateViewViews(
browser_context, delegate, tab_delegate);
WebContentsModalDialog* web_contents_modal_dialog =
- new ConstrainedWindowViews(web_contents, constrained_delegate);
+ ConstrainedWindowViews::Create(web_contents, constrained_delegate);
constrained_delegate->set_window(web_contents_modal_dialog);
return constrained_delegate;
}
diff --git a/chrome/browser/ui/views/constrained_window_views.cc b/chrome/browser/ui/views/constrained_window_views.cc
index e580e26..94fb8540 100644
--- a/chrome/browser/ui/views/constrained_window_views.cc
+++ b/chrome/browser/ui/views/constrained_window_views.cc
@@ -169,7 +169,8 @@ gfx::ImageSkia* VistaWindowResources::images_[];
class ConstrainedWindowFrameView : public views::NonClientFrameView,
public views::ButtonListener {
public:
- explicit ConstrainedWindowFrameView(ConstrainedWindowViews* container);
+ ConstrainedWindowFrameView(ConstrainedWindowViews* container,
+ bool browser_is_off_the_record);
virtual ~ConstrainedWindowFrameView();
void UpdateWindowTitle();
@@ -225,7 +226,7 @@ class ConstrainedWindowFrameView : public views::NonClientFrameView,
gfx::Rect CalculateClientAreaBounds(int width, int height) const;
SkColor GetTitleColor() const {
- return container_->owner()->GetBrowserContext()->IsOffTheRecord()
+ return browser_is_off_the_record_
#if defined(OS_WIN) && !defined(USE_AURA)
|| !ui::win::IsAeroGlassEnabled()
#endif
@@ -237,6 +238,8 @@ class ConstrainedWindowFrameView : public views::NonClientFrameView,
ConstrainedWindowViews* container_;
+ bool browser_is_off_the_record_;
+
scoped_ptr<views::WindowResources> resources_;
gfx::Rect title_bounds_;
@@ -286,9 +289,10 @@ const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
} // namespace
ConstrainedWindowFrameView::ConstrainedWindowFrameView(
- ConstrainedWindowViews* container)
+ ConstrainedWindowViews* container, bool browser_is_off_the_record)
: NonClientFrameView(),
container_(container),
+ browser_is_off_the_record_(browser_is_off_the_record),
close_button_(new views::ImageButton(this)),
frame_background_(new views::FrameBackground()) {
InitClass();
@@ -563,39 +567,22 @@ class ConstrainedWindowFrameViewAsh : public ash::CustomFrameViewAsh {
#endif // defined(USE_ASH)
ConstrainedWindowViews::ConstrainedWindowViews(
- content::WebContents* web_contents,
+ gfx::NativeView parent,
+ bool off_the_record,
views::WidgetDelegate* widget_delegate)
- : web_contents_(web_contents),
- ALLOW_THIS_IN_INITIALIZER_LIST(native_constrained_window_(
- NativeConstrainedWindow::CreateNativeConstrainedWindow(this))) {
+ : off_the_record_(off_the_record) {
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
params.delegate = widget_delegate;
- params.native_widget = native_constrained_window_->AsNativeWidget();
params.child = true;
- params.parent = web_contents_->GetNativeView();
+ params.parent = parent;
#if defined(USE_ASH)
// Ash window headers can be transparent.
params.transparent = true;
- views::corewm::SetChildWindowVisibilityChangesAnimated(params.parent);
- // No animations should get performed on the window since that will re-order
- // the window stack which will then cause many problems.
- if (params.parent && params.parent->parent()) {
- params.parent->parent()->SetProperty(aura::client::kAnimationsDisabledKey,
- true);
- }
#endif
- Init(params);
- WebContentsModalDialogManager* web_contents_modal_dialog_manager =
- WebContentsModalDialogManager::FromWebContents(web_contents_);
- web_contents_modal_dialog_manager->AddDialog(this);
-#if defined(USE_ASH)
- GetNativeWindow()->SetProperty(ash::kConstrainedWindowKey, true);
- views::corewm::SetModalParent(GetNativeWindow(),
- web_contents_->GetView()->GetNativeView());
-#endif
+ Init(params);
}
ConstrainedWindowViews::~ConstrainedWindowViews() {
@@ -607,15 +594,6 @@ void ConstrainedWindowViews::ShowWebContentsModalDialog() {
}
void ConstrainedWindowViews::CloseWebContentsModalDialog() {
-#if defined(USE_ASH)
- gfx::NativeView view = web_contents_->GetNativeView();
- // Allow the parent to animate again.
- if (view && view->parent())
- view->parent()->ClearProperty(aura::client::kAnimationsDisabledKey);
-#endif
- WebContentsModalDialogManager* web_contents_modal_dialog_manager =
- WebContentsModalDialogManager::FromWebContents(web_contents_);
- web_contents_modal_dialog_manager->WillClose(this);
Close();
}
@@ -636,6 +614,19 @@ gfx::NativeWindow ConstrainedWindowViews::GetNativeWindow() {
return Widget::GetNativeWindow();
}
+ConstrainedWindowViews* ConstrainedWindowViews::Create(
+ content::WebContents* web_contents,
+ views::WidgetDelegate* widget_delegate) {
+ WebContentsModalDialogManager* manager =
+ WebContentsModalDialogManager::FromWebContents(web_contents);
+ ConstrainedWindowViews* dialog = new ConstrainedWindowViews(
+ web_contents->GetNativeView(),
+ web_contents->GetBrowserContext()->IsOffTheRecord(),
+ widget_delegate);
+ manager->AddDialog(dialog);
+ return dialog;
+}
+
views::NonClientFrameView* ConstrainedWindowViews::CreateNonClientFrameView() {
if (views::DialogDelegate::UseNewStyle())
return views::DialogDelegate::CreateNewStyleFrameView(this);
@@ -644,25 +635,5 @@ views::NonClientFrameView* ConstrainedWindowViews::CreateNonClientFrameView() {
frame->Init(this);
return frame;
#endif
- return new ConstrainedWindowFrameView(this);
-}
-
-void ConstrainedWindowViews::OnNativeConstrainedWindowDestroyed() {
- WebContentsModalDialogManager* web_contents_modal_dialog_manager =
- WebContentsModalDialogManager::FromWebContents(web_contents_);
- web_contents_modal_dialog_manager->WillClose(this);
-}
-
-void ConstrainedWindowViews::OnNativeConstrainedWindowMouseActivate() {
- Activate();
-}
-
-views::internal::NativeWidgetDelegate*
- ConstrainedWindowViews::AsNativeWidgetDelegate() {
- return this;
-}
-
-int ConstrainedWindowViews::GetNonClientComponent(const gfx::Point& point) {
- // Prevent a constrained window to be moved by the user.
- return HTNOWHERE;
+ return new ConstrainedWindowFrameView(this, off_the_record_);
}
diff --git a/chrome/browser/ui/views/constrained_window_views.h b/chrome/browser/ui/views/constrained_window_views.h
index 3a5afdd..fef4ab3 100644
--- a/chrome/browser/ui/views/constrained_window_views.h
+++ b/chrome/browser/ui/views/constrained_window_views.h
@@ -23,31 +23,6 @@ class NonClientFrameView;
class WidgetDelegate;
}
-class NativeConstrainedWindowDelegate {
- public:
- virtual ~NativeConstrainedWindowDelegate() {}
-
- // Called after the NativeConstrainedWindow has been destroyed and is about to
- // be deleted.
- virtual void OnNativeConstrainedWindowDestroyed() = 0;
-
- // Called when the NativeConstrainedWindow is clicked on when inactive.
- virtual void OnNativeConstrainedWindowMouseActivate() = 0;
-
- virtual views::internal::NativeWidgetDelegate* AsNativeWidgetDelegate() = 0;
-};
-
-class NativeConstrainedWindow {
- public:
- virtual ~NativeConstrainedWindow() {}
-
- // Creates a platform-specific implementation of NativeConstrainedWindow.
- static NativeConstrainedWindow* CreateNativeConstrainedWindow(
- NativeConstrainedWindowDelegate* delegate);
-
- virtual views::NativeWidget* AsNativeWidget() = 0;
-};
-
///////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowViews
//
@@ -56,16 +31,13 @@ class NativeConstrainedWindow {
// itself and will be deleted soon after being closed.
//
class ConstrainedWindowViews : public views::Widget,
- public WebContentsModalDialog,
- public NativeConstrainedWindowDelegate {
+ public WebContentsModalDialog {
public:
- ConstrainedWindowViews(content::WebContents* web_contents,
+ ConstrainedWindowViews(gfx::NativeView parent,
+ bool off_the_record,
views::WidgetDelegate* widget_delegate);
virtual ~ConstrainedWindowViews();
- // Returns the WebContents that constrains this Constrained Window.
- content::WebContents* owner() const { return web_contents_; }
-
// Overridden from WebContentsModalDialog:
virtual void ShowWebContentsModalDialog() OVERRIDE;
virtual void CloseWebContentsModalDialog() OVERRIDE;
@@ -73,23 +45,15 @@ class ConstrainedWindowViews : public views::Widget,
virtual void PulseWebContentsModalDialog() OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
- // Default insets for the dialog:
- static gfx::Insets GetDefaultInsets();
+ // Factory function for the class (temporary).
+ static ConstrainedWindowViews* Create(content::WebContents* web_contents,
+ views::WidgetDelegate* widget_delegate);
private:
// Overridden from views::Widget:
virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
- // Overridden from NativeConstrainedWindowDelegate:
- virtual void OnNativeConstrainedWindowDestroyed() OVERRIDE;
- virtual void OnNativeConstrainedWindowMouseActivate() OVERRIDE;
- virtual views::internal::NativeWidgetDelegate*
- AsNativeWidgetDelegate() OVERRIDE;
- virtual int GetNonClientComponent(const gfx::Point& point) OVERRIDE;
-
- content::WebContents* web_contents_;
-
- NativeConstrainedWindow* native_constrained_window_;
+ bool off_the_record_;
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowViews);
};
diff --git a/chrome/browser/ui/views/constrained_window_views_browsertest.cc b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
index 8048dac..9defbae 100644
--- a/chrome/browser/ui/views/constrained_window_views_browsertest.cc
+++ b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
@@ -136,7 +136,7 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, FocusTest) {
// Create a constrained dialog. It will attach itself to web_contents.
scoped_ptr<TestConstrainedDialog> test_dialog1(new TestConstrainedDialog);
- ConstrainedWindowViews* window1 = new ConstrainedWindowViews(
+ ConstrainedWindowViews* window1 = ConstrainedWindowViews::Create(
web_contents, test_dialog1.get());
views::FocusManager* focus_manager = window1->GetFocusManager();
@@ -150,7 +150,7 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, FocusTest) {
// web_contents, but will remain hidden since the test_dialog1 is still
// showing.
scoped_ptr<TestConstrainedDialog> test_dialog2(new TestConstrainedDialog);
- ConstrainedWindowViews* window2 = new ConstrainedWindowViews(
+ ConstrainedWindowViews* window2 = ConstrainedWindowViews::Create(
web_contents, test_dialog2.get());
// Should be the same focus_manager.
ASSERT_EQ(focus_manager, window2->GetFocusManager());
@@ -211,7 +211,7 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, TabCloseTest) {
// Create a constrained dialog. It will attach itself to web_contents.
scoped_ptr<TestConstrainedDialog> test_dialog(new TestConstrainedDialog);
- new ConstrainedWindowViews(
+ ConstrainedWindowViews::Create(
web_contents, test_dialog.get());
bool closed =
@@ -232,7 +232,7 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, TabSwitchTest) {
// Create a constrained dialog. It will attach itself to web_contents.
scoped_ptr<TestConstrainedDialog> test_dialog(new TestConstrainedDialog);
- ConstrainedWindowViews* window = new ConstrainedWindowViews(
+ ConstrainedWindowViews* window = ConstrainedWindowViews::Create(
web_contents, test_dialog.get());
EXPECT_TRUE(window->IsVisible());
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
index b1abe91..d936a0b 100644
--- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
+++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -37,7 +37,7 @@ MediaGalleriesDialogViews::MediaGalleriesDialogViews(
// Ownership of |contents_| is handed off by this call. |window_| will take
// care of deleting itself after calling DeleteDelegate().
- window_ = new ConstrainedWindowViews(controller->web_contents(), this);
+ window_ = ConstrainedWindowViews::Create(controller->web_contents(), this);
}
MediaGalleriesDialogViews::~MediaGalleriesDialogViews() {}
diff --git a/chrome/browser/ui/views/login_prompt_views.cc b/chrome/browser/ui/views/login_prompt_views.cc
index 227b506..b1c32b7 100644
--- a/chrome/browser/ui/views/login_prompt_views.cc
+++ b/chrome/browser/ui/views/login_prompt_views.cc
@@ -135,7 +135,7 @@ class LoginHandlerViews : public LoginHandler,
// will occur via an InvokeLater on the UI thread, which is guaranteed
// to happen after this is called (since this was InvokeLater'd first).
WebContents* requesting_contents = GetWebContentsForLogin();
- SetDialog(new ConstrainedWindowViews(requesting_contents, this));
+ SetDialog(ConstrainedWindowViews::Create(requesting_contents, this));
NotifyAuthNeeded();
}
diff --git a/chrome/browser/ui/views/native_constrained_window_aura.cc b/chrome/browser/ui/views/native_constrained_window_aura.cc
deleted file mode 100644
index 77a6de5..0000000
--- a/chrome/browser/ui/views/native_constrained_window_aura.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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 "chrome/browser/ui/views/constrained_window_views.h"
-
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/window.h"
-#include "ui/views/widget/native_widget_aura.h"
-
-class NativeConstrainedWindowAura : public NativeConstrainedWindow,
- public views::NativeWidgetAura {
- public:
- explicit NativeConstrainedWindowAura(
- NativeConstrainedWindowDelegate* delegate)
- : views::NativeWidgetAura(delegate->AsNativeWidgetDelegate()),
- delegate_(delegate) {
- GetNativeWindow()->SetProperty(aura::client::kConstrainedWindowKey, true);
- }
-
- virtual ~NativeConstrainedWindowAura() {
- }
-
- private:
- // Overridden from NativeConstrainedWindow:
- virtual views::NativeWidget* AsNativeWidget() OVERRIDE {
- return this;
- }
-
- // Overridden from views::NativeWidgetAura:
- virtual void OnWindowDestroyed() OVERRIDE {
- delegate_->OnNativeConstrainedWindowDestroyed();
- views::NativeWidgetAura::OnWindowDestroyed();
- }
-
- NativeConstrainedWindowDelegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(NativeConstrainedWindowAura);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeConstrainedWindow, public:
-
-// static
-NativeConstrainedWindow* NativeConstrainedWindow::CreateNativeConstrainedWindow(
- NativeConstrainedWindowDelegate* delegate) {
- return new NativeConstrainedWindowAura(delegate);
-}
diff --git a/chrome/browser/ui/views/native_constrained_window_win.cc b/chrome/browser/ui/views/native_constrained_window_win.cc
deleted file mode 100644
index 931f971..0000000
--- a/chrome/browser/ui/views/native_constrained_window_win.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2011 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 "chrome/browser/ui/views/constrained_window_views.h"
-
-#include "ui/views/widget/native_widget_win.h"
-
-namespace {
-bool IsNonClientHitTestCode(UINT hittest) {
- return hittest != HTCLIENT && hittest != HTNOWHERE && hittest != HTCLOSE;
-}
-}
-
-class NativeConstrainedWindowWin : public NativeConstrainedWindow,
- public views::NativeWidgetWin {
- public:
- explicit NativeConstrainedWindowWin(NativeConstrainedWindowDelegate* delegate)
- : views::NativeWidgetWin(delegate->AsNativeWidgetDelegate()),
- delegate_(delegate) {
- }
-
- virtual ~NativeConstrainedWindowWin() {
- }
-
- private:
- // Overridden from NativeConstrainedWindow:
- virtual views::NativeWidget* AsNativeWidget() OVERRIDE {
- return this;
- }
-
- // Overridden from views::NativeWidgetWin:
- virtual void OnFinalMessage(HWND window) OVERRIDE {
- delegate_->OnNativeConstrainedWindowDestroyed();
- NativeWidgetWin::OnFinalMessage(window);
- }
- virtual bool PreHandleMSG(UINT message,
- WPARAM w_param,
- LPARAM l_param,
- LRESULT* result) OVERRIDE {
- if (message == WM_MOUSEACTIVATE &&
- IsNonClientHitTestCode(static_cast<UINT>(LOWORD(l_param)))) {
- delegate_->OnNativeConstrainedWindowMouseActivate();
- }
- return false;
- }
-
- NativeConstrainedWindowDelegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(NativeConstrainedWindowWin);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeConstrainedWindow, public:
-
-// static
-NativeConstrainedWindow* NativeConstrainedWindow::CreateNativeConstrainedWindow(
- NativeConstrainedWindowDelegate* delegate) {
- return new NativeConstrainedWindowWin(delegate);
-}
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
index 67e5235..a66b208 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
@@ -141,7 +141,7 @@ void SSLClientCertificateSelector::Init() {
StartObserving();
- window_ = new ConstrainedWindowViews(web_contents_, this);
+ window_ = ConstrainedWindowViews::Create(web_contents_, this);
// Select the first row automatically. This must be done after the dialog has
// been created.
diff --git a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
index cdf2dee..caae453 100644
--- a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
+++ b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
@@ -33,7 +33,7 @@ TabModalConfirmDialogViews::TabModalConfirmDialogViews(
: delegate_(delegate),
message_box_view_(new views::MessageBoxView(
views::MessageBoxView::InitParams(delegate->GetMessage()))) {
- delegate_->set_window(new ConstrainedWindowViews(web_contents, this));
+ delegate_->set_window(ConstrainedWindowViews::Create(web_contents, this));
}
TabModalConfirmDialogViews::~TabModalConfirmDialogViews() {
diff --git a/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
new file mode 100644
index 0000000..b5371b4
--- /dev/null
+++ b/chrome/browser/ui/views/web_contents_modal_dialog_manager_views.cc
@@ -0,0 +1,112 @@
+// 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 <set>
+
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/native_web_contents_modal_dialog_manager.h"
+#include "chrome/browser/ui/views/constrained_window_views.h"
+#include "chrome/browser/ui/web_contents_modal_dialog_manager.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_observer.h"
+
+#if defined(USE_AURA)
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/window.h"
+#include "ui/views/corewm/visibility_controller.h"
+#include "ui/views/corewm/window_animations.h"
+#include "ui/views/corewm/window_modality_controller.h"
+#endif
+
+#if defined(USE_ASH)
+#include "ash/ash_constants.h"
+#include "ash/shell.h"
+#include "ash/wm/custom_frame_view_ash.h"
+#endif
+
+namespace {
+
+class NativeWebContentsModalDialogManagerViews
+ : public NativeWebContentsModalDialogManager,
+ public views::WidgetObserver {
+ public:
+ NativeWebContentsModalDialogManagerViews(
+ WebContentsModalDialogManager* manager)
+ : manager_(manager) {
+ }
+
+ virtual ~NativeWebContentsModalDialogManagerViews() {
+ for (std::set<views::Widget*>::iterator it = observed_widgets_.begin();
+ it != observed_widgets_.end();
+ ++it) {
+ (*it)->RemoveObserver(this);
+ }
+ }
+
+ // NativeWebContentsModalDialogManager overrides
+ virtual void ManageDialog(gfx::NativeWindow window) OVERRIDE {
+ views::Widget* widget = GetWidget(window);
+ widget->AddObserver(this);
+ observed_widgets_.insert(widget);
+ widget->set_movement_disabled(true);
+
+#if defined(USE_AURA)
+ // TODO(wittman): remove once the new visual style is complete
+ widget->GetNativeWindow()->SetProperty(aura::client::kConstrainedWindowKey,
+ true);
+#endif
+
+#if defined(USE_ASH)
+ gfx::NativeView parent = platform_util::GetParent(widget->GetNativeView());
+ views::corewm::SetChildWindowVisibilityChangesAnimated(parent);
+ // No animations should get performed on the window since that will re-order
+ // the window stack which will then cause many problems.
+ if (parent && parent->parent()) {
+ parent->parent()->SetProperty(aura::client::kAnimationsDisabledKey, true);
+ }
+
+ // TODO(wittman): remove once the new visual style is complete
+ widget->GetNativeWindow()->SetProperty(ash::kConstrainedWindowKey, true);
+ views::corewm::SetModalParent(
+ widget->GetNativeWindow(),
+ platform_util::GetParent(widget->GetNativeView()));
+#endif
+ }
+
+ virtual void CloseDialog(gfx::NativeWindow window) OVERRIDE {
+ views::Widget* widget = GetWidget(window);
+#if defined(USE_ASH)
+ gfx::NativeView view = platform_util::GetParent(widget->GetNativeView());
+ // Allow the parent to animate again.
+ if (view && view->parent())
+ view->parent()->ClearProperty(aura::client::kAnimationsDisabledKey);
+#endif
+ widget->Close();
+ }
+
+ // views::WidgetObserver overrides
+ virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE {
+ manager_->WillClose(static_cast<ConstrainedWindowViews*>(widget));
+ observed_widgets_.erase(widget);
+ }
+
+ private:
+ static views::Widget* GetWidget(gfx::NativeWindow window) {
+ views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
+ DCHECK(widget);
+ return widget;
+ }
+
+ WebContentsModalDialogManager* manager_;
+ std::set<views::Widget*> observed_widgets_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeWebContentsModalDialogManagerViews);
+};
+
+} // namespace
+
+NativeWebContentsModalDialogManager* WebContentsModalDialogManager::
+CreateNativeManager(WebContentsModalDialogManager* manager) {
+ return new NativeWebContentsModalDialogManagerViews(manager);
+}
diff --git a/chrome/browser/ui/views/web_intent_picker_views.cc b/chrome/browser/ui/views/web_intent_picker_views.cc
index 3a8a99f..a23f0c8 100644
--- a/chrome/browser/ui/views/web_intent_picker_views.cc
+++ b/chrome/browser/ui/views/web_intent_picker_views.cc
@@ -1090,7 +1090,7 @@ WebIntentPickerViews::WebIntentPickerViews(WebContents* web_contents,
chrome_style::GetBackgroundColor()));
// Show the dialog.
- window_ = new ConstrainedWindowViews(web_contents, this);
+ window_ = ConstrainedWindowViews::Create(web_contents, this);
if (model_->IsInlineDisposition())
OnInlineDisposition(string16(), model_->inline_disposition_url());
else
diff --git a/chrome/browser/ui/web_contents_modal_dialog_manager.cc b/chrome/browser/ui/web_contents_modal_dialog_manager.cc
index 35ac064..819580e 100644
--- a/chrome/browser/ui/web_contents_modal_dialog_manager.cc
+++ b/chrome/browser/ui/web_contents_modal_dialog_manager.cc
@@ -25,6 +25,9 @@ void WebContentsModalDialogManager::AddDialog(
WebContentsModalDialog* dialog) {
child_dialogs_.push_back(dialog);
+ if (native_manager_)
+ native_manager_->ManageDialog(dialog->GetNativeWindow());
+
if (child_dialogs_.size() == 1) {
dialog->ShowWebContentsModalDialog();
BlockWebContentsInteraction(true);
@@ -78,7 +81,9 @@ void WebContentsModalDialogManager::FocusTopmostDialog() {
WebContentsModalDialogManager::WebContentsModalDialogManager(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
- delegate_(NULL) {
+ delegate_(NULL),
+ native_manager_(
+ ALLOW_THIS_IN_INITIALIZER_LIST(CreateNativeManager(this))) {
}
void WebContentsModalDialogManager::CloseAllDialogs() {
diff --git a/chrome/browser/ui/web_contents_modal_dialog_manager.h b/chrome/browser/ui/web_contents_modal_dialog_manager.h
index 3a392d4..9384095 100644
--- a/chrome/browser/ui/web_contents_modal_dialog_manager.h
+++ b/chrome/browser/ui/web_contents_modal_dialog_manager.h
@@ -7,8 +7,11 @@
#include <deque>
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/native_web_contents_modal_dialog_manager.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
+#include "ui/gfx/native_widget_types.h"
class WebContentsModalDialog;
class WebContentsModalDialogManagerDelegate;
@@ -23,6 +26,9 @@ class WebContentsModalDialogManager
WebContentsModalDialogManagerDelegate* delegate() const { return delegate_; }
void set_delegate(WebContentsModalDialogManagerDelegate* d) { delegate_ = d; }
+ static NativeWebContentsModalDialogManager* CreateNativeManager(
+ WebContentsModalDialogManager* manager);
+
// Adds the given dialog to the list of child dialogs. The dialog will notify
// via WillClose() when it is being destroyed.
void AddDialog(WebContentsModalDialog* dialog);
@@ -47,6 +53,9 @@ class WebContentsModalDialogManager
: manager_(manager) {}
void CloseAllDialogs() { manager_->CloseAllDialogs(); }
+ void ResetNativeManager(NativeWebContentsModalDialogManager* delegate) {
+ manager_->native_manager_.reset(delegate);
+ }
private:
WebContentsModalDialogManager* manager_;
@@ -86,6 +95,9 @@ class WebContentsModalDialogManager
// Delegate for notifying our owner about stuff. Not owned by us.
WebContentsModalDialogManagerDelegate* delegate_;
+ // Delegate for native UI-specific functions on the dialog.
+ scoped_ptr<NativeWebContentsModalDialogManager> native_manager_;
+
// All active dialogs.
WebContentsModalDialogList child_dialogs_;
diff --git a/chrome/browser/ui/web_contents_modal_dialog_manager_unittest.cc b/chrome/browser/ui/web_contents_modal_dialog_manager_unittest.cc
index 1532136..736ddfe 100644
--- a/chrome/browser/ui/web_contents_modal_dialog_manager_unittest.cc
+++ b/chrome/browser/ui/web_contents_modal_dialog_manager_unittest.cc
@@ -52,19 +52,21 @@ class WebContentsModalDialogCloseTest : public WebContentsModalDialog {
content::WebContents* web_contents_;
};
-TEST_F(WebContentsModalDialogManagerTest, ConstrainedWindows) {
+TEST_F(WebContentsModalDialogManagerTest, WebContentsModalDialogs) {
WebContentsModalDialogCloseTest window(web_contents());
window.close_count = 0;
WebContentsModalDialogManager* web_contents_modal_dialog_manager =
WebContentsModalDialogManager::FromWebContents(web_contents());
+ WebContentsModalDialogManager::TestApi test_api(
+ web_contents_modal_dialog_manager);
+
+ test_api.ResetNativeManager(NULL);
const int kWindowCount = 4;
for (int i = 0; i < kWindowCount; i++)
web_contents_modal_dialog_manager->AddDialog(&window);
EXPECT_EQ(window.close_count, 0);
- WebContentsModalDialogManager::TestApi test_api(
- web_contents_modal_dialog_manager);
test_api.CloseAllDialogs();
EXPECT_EQ(window.close_count, kWindowCount);
}
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
index 38e89df..d4504c0 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -270,6 +270,7 @@ TEST_F(PrintPreviewUIUnitTest, InitiatorTabGetsFocusOnPrintPreviewDialogClose) {
ASSERT_TRUE(preview_ui != NULL);
preview_ui->OnPrintPreviewDialogClosed();
+ message_loop()->RunUntilIdle();
EXPECT_EQ(2, browser()->tab_strip_model()->count());
EXPECT_FALSE(IsShowingWebContentsModalDialog(initiator_tab));
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 956575a..9539012 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -802,6 +802,7 @@
'browser/ui/cocoa/view_id_util.h',
'browser/ui/cocoa/view_id_util.mm',
'browser/ui/cocoa/view_resizer.h',
+ 'browser/ui/cocoa/web_contents_modal_dialog_manager_cocoa.mm',
'browser/ui/cocoa/web_dialog_window_controller.h',
'browser/ui/cocoa/web_dialog_window_controller.mm',
'browser/ui/cocoa/website_settings_bubble_controller.h',
@@ -1129,6 +1130,7 @@
'browser/ui/gtk/update_recommended_dialog.h',
'browser/ui/gtk/view_id_util.cc',
'browser/ui/gtk/view_id_util.h',
+ 'browser/ui/gtk/web_contents_modal_dialog_manager_gtk.cc',
'browser/ui/gtk/web_dialog_gtk.cc',
'browser/ui/gtk/web_dialog_gtk.h',
'browser/ui/gtk/web_intent_picker_gtk.cc',
@@ -1164,6 +1166,7 @@
'browser/ui/media_stream_infobar_delegate.cc',
'browser/ui/metro_pin_tab_helper_win.cc',
'browser/ui/metro_pin_tab_helper_win.h',
+ 'browser/ui/native_web_contents_modal_dialog_manager.h',
'browser/ui/network_profile_bubble.cc',
'browser/ui/network_profile_bubble.h',
'browser/ui/ntp_background_util.cc',
@@ -1660,8 +1663,6 @@
'browser/ui/views/message_center/web_notification_tray_win.cc',
'browser/ui/views/missing_system_file_dialog_win.cc',
'browser/ui/views/missing_system_file_dialog_win.h',
- 'browser/ui/views/native_constrained_window_aura.cc',
- 'browser/ui/views/native_constrained_window_win.cc',
'browser/ui/views/notifications/balloon_collection_views.cc',
'browser/ui/views/notifications/balloon_view_host.cc',
'browser/ui/views/notifications/balloon_view_host.h',
@@ -1778,6 +1779,7 @@
'browser/ui/views/user_data_dir_dialog_view.cc',
'browser/ui/views/user_data_dir_dialog_view.h',
'browser/ui/views/web_intent_picker_views.cc',
+ 'browser/ui/views/web_contents_modal_dialog_manager_views.cc',
'browser/ui/views/website_settings/permission_selector_view.cc',
'browser/ui/views/website_settings/permission_selector_view.h',
'browser/ui/views/website_settings/permission_selector_view_observer.h',
@@ -2401,7 +2403,6 @@
['exclude', '^browser/ui/views/frame/browser_frame_win.h'],
['exclude', '^browser/ui/views/frame/browser_non_client_frame_view_factory_win.cc'],
['exclude', '^browser/ui/views/importer/import_progress_dialog_view.cc'],
- ['exclude', '^browser/ui/views/native_constrained_window_win.cc'],
['exclude', '^browser/ui/views/omnibox/omnibox_view_win.cc'],
['exclude', '^browser/ui/views/omnibox/omnibox_view_win.h'],
['exclude', '^browser/ui/views/color_chooser_dialog.cc'],
@@ -2579,6 +2580,10 @@
'browser/ui/tab_contents/tab_contents_iterator.cc',
'browser/ui/uma_browsing_activity_observer.cc',
'browser/ui/uma_browsing_activity_observer.h',
+ 'browser/ui/web_contents_modal_dialog_manager_delegate.cc',
+ 'browser/ui/web_contents_modal_dialog_manager_delegate.h',
+ 'browser/ui/web_contents_modal_dialog_manager.cc',
+ 'browser/ui/web_contents_modal_dialog_manager.h',
'browser/ui/webui/bookmarks_ui.cc',
'browser/ui/webui/bookmarks_ui.h',
'browser/ui/webui/certificate_viewer_webui.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index ceeb083..a034575 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -2150,6 +2150,7 @@
'browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc',
'browser/ui/toolbar/toolbar_model_unittest.cc',
'browser/ui/toolbar/wrench_menu_model_unittest.cc',
+ 'browser/ui/web_contents_modal_dialog_manager_unittest.cc',
'browser/ui/webui/ntp/suggestions_combiner_unittest.cc',
'browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc',
'browser/ui/window_sizer/window_sizer_common_unittest.cc',
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 4a7bfcd..c1e5602 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -200,7 +200,8 @@ Widget::Widget()
is_mouse_button_pressed_(false),
is_touch_down_(false),
last_mouse_event_was_move_(false),
- root_layers_dirty_(false) {
+ root_layers_dirty_(false),
+ movement_disabled_(false) {
}
Widget::~Widget() {
@@ -1124,9 +1125,14 @@ void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) {
}
int Widget::GetNonClientComponent(const gfx::Point& point) {
- return non_client_view_ ?
+ int component = non_client_view_ ?
non_client_view_->NonClientHitTest(point) :
HTNOWHERE;
+
+ if (movement_disabled_ && (component == HTCAPTION || component == HTSYSMENU))
+ return HTNOWHERE;
+
+ return component;
}
void Widget::OnKeyEvent(ui::KeyEvent* event) {
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 22fda18..fee59fc 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -645,6 +645,10 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// with it. TYPE_CONTROL and TYPE_TOOLTIP is not considered top level.
bool is_top_level() const { return is_top_level_; }
+ // True when window movement via mouse interaction with the frame is disabled.
+ bool movement_disabled() const { return movement_disabled_; }
+ void set_movement_disabled(bool disabled) { movement_disabled_ = disabled; }
+
// Returns the work area bounds of the screen the Widget belongs to.
gfx::Rect GetWorkAreaBoundsInScreen() const;
@@ -836,6 +840,10 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Is |root_layers_| out of date?
bool root_layers_dirty_;
+ // True when window movement via mouse interaction with the frame should be
+ // disabled.
+ bool movement_disabled_;
+
DISALLOW_COPY_AND_ASSIGN(Widget);
};