diff options
author | wittman@chromium.org <wittman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-06 06:50:23 +0000 |
---|---|---|
committer | wittman@chromium.org <wittman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-06 06:50:23 +0000 |
commit | 51a2478710c9b2beda273832f2e4f4c825aa279a (patch) | |
tree | 77a926fd642222b69989250f7295d95d3cd42724 | |
parent | 8cea789efbec4198ab2315ee2f49927523832d2f (diff) | |
download | chromium_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
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); }; |