diff options
4 files changed, 190 insertions, 20 deletions
diff --git a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc index 4e25c14..d02ddbc 100644 --- a/chrome/browser/ui/views/location_bar/star_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/star_view_browsertest.cc @@ -4,10 +4,26 @@ #include "chrome/browser/ui/views/location_bar/star_view.h" +#include "base/command_line.h" +#include "base/prefs/pref_service.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar_view.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_utils.h" +#include "ui/base/ui_base_switches.h" + +#if defined(OS_WIN) && defined(USE_AURA) +#include "content/public/browser/web_contents_view.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#endif namespace { @@ -49,4 +65,98 @@ IN_PROC_BROWSER_TEST_F(StarViewTest, MAYBE_HideOnSecondClick) { EXPECT_FALSE(BookmarkBubbleView::IsShowing()); } +#if defined(OS_WIN) && defined(USE_AURA) + +class StarViewTestNoDWM : public InProcessBrowserTest { + public: + StarViewTestNoDWM() {} + + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + command_line->AppendSwitch(switches::kDisableDwmComposition); + } +}; + +BOOL CALLBACK EnumerateChildren(HWND hwnd, LPARAM l_param) { + HWND* child = reinterpret_cast<HWND*>(l_param); + *child = hwnd; + // The first child window is the plugin, then its children. So stop + // enumerating after the first callback. + return FALSE; +} + +// Ensure that UIs like the star window, user profiler picker, omnibox +// popup and bookmark editor are always over a windowed NPAPI plugin even if +// kDisableDwmComposition is used. +IN_PROC_BROWSER_TEST_F(StarViewTestNoDWM, WindowedNPAPIPluginHidden) { + browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize, + true); + LOG(ERROR) << "1"; + // First load the page and wait for the NPAPI plugin's window to display. + string16 expected_title(ASCIIToUTF16("ready")); + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + content::TitleWatcher title_watcher(tab, expected_title); + + GURL url = ui_test_utils::GetTestUrl( + base::FilePath().AppendASCII("printing"), + base::FilePath().AppendASCII("npapi_plugin.html")); + ui_test_utils::NavigateToURL(browser(), url); + LOG(ERROR) << "2"; + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); + LOG(ERROR) << "3"; + + // Now get the region of the plugin before the star view is shown. + HWND hwnd = + tab->GetView()->GetNativeView()->GetDispatcher()->GetAcceleratedWidget(); + HWND child = NULL; + EnumChildWindows(hwnd, EnumerateChildren,reinterpret_cast<LPARAM>(&child)); + LOG(ERROR) << "4"; + + RECT region_before, region_after; + int result = GetWindowRgnBox(child, ®ion_before); + ASSERT_EQ(result, SIMPLEREGION); + + // Now show the star view + BrowserView* browser_view = reinterpret_cast<BrowserView*>( + browser()->window()); + views::ImageView* star_view = + browser_view->GetToolbarView()->location_bar()->star_view(); + + scoped_refptr<content::MessageLoopRunner> runner = + new content::MessageLoopRunner; + LOG(ERROR) << "5"; + // Verify that clicking once shows the bookmark bubble. + ui_test_utils::MoveMouseToCenterAndPress( + star_view, + ui_controls::LEFT, + ui_controls::DOWN | ui_controls::UP, + runner->QuitClosure()); + LOG(ERROR) << "6"; + runner->Run(); + LOG(ERROR) << "7"; + + EXPECT_TRUE(BookmarkBubbleView::IsShowing()); + + result = GetWindowRgnBox(child, ®ion_after); + if (result == NULLREGION) { + // Depending on the browser window size, the plugin could be full covered. + return; + } + + if (result == COMPLEXREGION) { + // Complex region, by definition not equal to the initial region. + return; + } + + ASSERT_EQ(result, SIMPLEREGION); + bool rects_equal = + region_before.left == region_after.left && + region_before.top == region_after.top && + region_before.right == region_after.right && + region_before.bottom == region_after.bottom; + ASSERT_FALSE(rects_equal); +} + +#endif + } // namespace diff --git a/chrome/interactive_ui_tests.isolate b/chrome/interactive_ui_tests.isolate index ff3486a..ff3d1d4 100644 --- a/chrome/interactive_ui_tests.isolate +++ b/chrome/interactive_ui_tests.isolate @@ -83,6 +83,7 @@ ], 'isolate_dependency_untracked': [ '../third_party/python_26/', + '<(PRODUCT_DIR)/plugins/npapi_test_plugin.dll', ], }, }], diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index b08e23d..223348f 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -1254,6 +1254,8 @@ void RenderWidgetHostViewAura::DidReceiveFrameFromRenderer() { #if defined(OS_WIN) void RenderWidgetHostViewAura::UpdateConstrainedWindowRects( const std::vector<gfx::Rect>& rects) { + if (rects == constrained_rects_) + return; constrained_rects_ = rects; UpdateCutoutRects(); } diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index a6ad7f5..782d57e 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc @@ -655,6 +655,11 @@ class WebContentsViewAura::WindowObserver : view_(view), parent_(NULL) { view_->window_->AddObserver(this); + +#if defined(OS_WIN) + if (view_->window_->GetRootWindow()) + view_->window_->GetRootWindow()->AddObserver(this); +#endif } virtual ~WindowObserver() { @@ -670,6 +675,14 @@ class WebContentsViewAura::WindowObserver for (size_t i = 0; i < children.size(); ++i) children[i]->RemoveObserver(this); } + + aura::Window* root_window = view_->window_->GetRootWindow(); + if (root_window) { + root_window->RemoveObserver(this); + const aura::Window::Windows& root_children = root_window->children(); + for (size_t i = 0; i < root_children.size(); ++i) + root_children[i]->RemoveObserver(this); + } #endif } @@ -682,24 +695,38 @@ class WebContentsViewAura::WindowObserver // going to be deprecated in a year, this is ok for now. The test for this is // PrintPreviewTest.WindowedNPAPIPluginHidden. virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE { - if (new_window->parent() != parent_) + if (new_window == view_->window_) return; - new_window->AddObserver(this); - UpdateConstrainedWindows(NULL); + if (new_window == parent_) + return; // This happens if the parent moves to the root window. + + // Observe sibling windows of the WebContents, or children of the root + // window. + if (new_window->parent() == parent_ || + new_window->parent() == view_->window_->GetRootWindow()) { + new_window->AddObserver(this); + UpdateConstrainedWindows(NULL); + } } virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE { - if (window->parent() == parent_ && window != view_->window_) { - window->RemoveObserver(this); - UpdateConstrainedWindows(window); - } + if (window == view_->window_) + return; + + window->RemoveObserver(this); + UpdateConstrainedWindows(window); } virtual void OnWindowVisibilityChanged(aura::Window* window, bool visible) OVERRIDE { - if (window->parent() == parent_ && window != view_->window_) + if (window == view_->window_) + return; + + if (window->parent() == parent_ || + window->parent() == view_->window_->GetRootWindow()) { UpdateConstrainedWindows(NULL); + } } #endif @@ -721,16 +748,24 @@ class WebContentsViewAura::WindowObserver if (view) view->UpdateConstrainedWindowRects(std::vector<gfx::Rect>()); } + + // When we get parented to the root window, the code below will watch the + // parent, aka root window. Since we already watch the root window on + // Windows, unregister first so that the debug check doesn't fire. + if (parent && parent == window->GetRootWindow()) + parent->RemoveObserver(this); #endif parent_ = parent; if (parent) { parent->AddObserver(this); #if defined(OS_WIN) - const aura::Window::Windows& children = parent_->children(); - for (size_t i = 0; i < children.size(); ++i) { - if (children[i] != view_->window_) - children[i]->AddObserver(this); + if (parent != window->GetRootWindow()) { + const aura::Window::Windows& children = parent->children(); + for (size_t i = 0; i < children.size(); ++i) { + if (children[i] != view_->window_) + children[i]->AddObserver(this); + } } #endif } @@ -751,13 +786,21 @@ class WebContentsViewAura::WindowObserver } virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE { - if (window == view_->window_) + if (window == view_->window_) { window->GetDispatcher()->AddRootWindowObserver(this); +#if defined(OS_WIN) + window->GetRootWindow()->AddObserver(this); +#endif + } } virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE { - if (window == view_->window_) + if (window == view_->window_) { window->GetDispatcher()->RemoveRootWindowObserver(this); +#if defined(OS_WIN) + window->GetRootWindow()->RemoveObserver(this); +#endif + } } // Overridden RootWindowObserver: @@ -785,12 +828,26 @@ class WebContentsViewAura::WindowObserver return; std::vector<gfx::Rect> constrained_windows; - const aura::Window::Windows& children = parent_->children(); - for (size_t i = 0; i < children.size(); ++i) { - if (children[i] != view_->window_ && - children[i] != exclude && - children[i]->IsVisible()) { - constrained_windows.push_back(children[i]->GetBoundsInRootWindow()); + if (parent_) { + const aura::Window::Windows& children = parent_->children(); + for (size_t i = 0; i < children.size(); ++i) { + if (children[i] != view_->window_ && + children[i] != exclude && + children[i]->IsVisible()) { + constrained_windows.push_back(children[i]->GetBoundsInRootWindow()); + } + } + } + + aura::Window* root_window = view_->window_->GetRootWindow(); + const aura::Window::Windows& root_children = root_window->children(); + if (root_window) { + for (size_t i = 0; i < root_children.size(); ++i) { + if (root_children[i]->IsVisible() && + !root_children[i]->Contains(view_->window_.get())) { + constrained_windows.push_back( + root_children[i]->GetBoundsInRootWindow()); + } } } |