diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 20:34:00 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 20:34:00 +0000 |
commit | 186f13f42862926a39f452147004ef2861ba86e9 (patch) | |
tree | fa8729baf71e17a023e953b4fb27d0671d12bef2 /chrome/browser | |
parent | 06a277045d40f1cf1f6dbe86e6e1ed427bab4bdb (diff) | |
download | chromium_src-186f13f42862926a39f452147004ef2861ba86e9.zip chromium_src-186f13f42862926a39f452147004ef2861ba86e9.tar.gz chromium_src-186f13f42862926a39f452147004ef2861ba86e9.tar.bz2 |
Port more browser focus tests to linux.
Added a new test to make sure clicking sets focus, since I changed a lot of tests to programatically set focus instead of using clicking.
Also set the actual time on our synthetic key events. I'm still not sure this is necessary but would like to avoid subtle bugs.
Also get rid of the NineBox constructor that takes a theme provider and convert its callers to use cairo directly or the other NineBox constructor. This change was necessary because theme providers could go stale and then the NineBox would cause seg faults. Also, it was only being used for single images... and UniBox just sounds wrong.
Also fix extension shelf to paint its image with the correct x/y (noticeable only with certain themes). Remove the notification observer stuff from the extension shelf, as I don't think there is any action to be taken when the theme changes.
BUG=19076
BUG=19659
TEST=all the ported interactive ui tests (as well as all the already-working tests) pass.
TEST=(Linux) things still render correctly (frame image, drop shadows, find box, extension shelf)
Review URL: http://codereview.chromium.org/173030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23732 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/automation/ui_controls_linux.cc | 9 | ||||
-rw-r--r-- | chrome/browser/browser_focus_uitest.cc | 223 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 65 | ||||
-rw-r--r-- | chrome/browser/gtk/extension_shelf_gtk.cc | 40 | ||||
-rw-r--r-- | chrome/browser/gtk/extension_shelf_gtk.h | 18 | ||||
-rw-r--r-- | chrome/browser/gtk/find_bar_gtk.cc | 16 | ||||
-rw-r--r-- | chrome/browser/gtk/nine_box.cc | 38 | ||||
-rw-r--r-- | chrome/browser/gtk/nine_box.h | 26 | ||||
-rw-r--r-- | chrome/browser/gtk/tab_contents_container_gtk.cc | 17 | ||||
-rw-r--r-- | chrome/browser/gtk/tab_contents_container_gtk.h | 7 | ||||
-rw-r--r-- | chrome/browser/view_ids.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/tab_contents/native_tab_contents_container_win.cc | 2 |
12 files changed, 202 insertions, 260 deletions
diff --git a/chrome/browser/automation/ui_controls_linux.cc b/chrome/browser/automation/ui_controls_linux.cc index 53ba6fd..22902a6 100644 --- a/chrome/browser/automation/ui_controls_linux.cc +++ b/chrome/browser/automation/ui_controls_linux.cc @@ -40,7 +40,7 @@ class EventWaiter : public MessageLoopForUI::Observer { GdkEventType type_; }; -} +} // namespace namespace ui_controls { @@ -53,8 +53,11 @@ bool SendKeyPress(gfx::NativeWindow window, event->key.window = GTK_WIDGET(window)->window; g_object_ref(event->key.window); event->key.send_event = false; - // TODO(estade): Put the real time? - event->key.time = GDK_CURRENT_TIME; + + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + event->key.time = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + // TODO(estade): handle other state flags besides control, shift, alt? // For example caps lock. event->key.state = (control ? GDK_CONTROL_MASK : 0) | diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc index 4007ebd..ed3c6d1 100644 --- a/chrome/browser/browser_focus_uitest.cc +++ b/chrome/browser/browser_focus_uitest.cc @@ -11,6 +11,8 @@ #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/tab_contents/interstitial_page.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/view_ids.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/in_process_browser_test.h" @@ -56,8 +58,8 @@ class BrowserFocusTest : public InProcessBrowserTest { views::FocusManager* focus_manager = views::FocusManager::GetFocusManagerForNativeView(window); ASSERT_TRUE(focus_manager); - EXPECT_EQ(reinterpret_cast<views::View*>(browser_window)->GetViewByID(vid), - focus_manager->GetFocusedView()); + EXPECT_EQ(reinterpret_cast<BrowserView*>(browser_window)->GetViewByID(vid), + focus_manager->GetFocusedView()) << "For view id " << vid; #elif defined(OS_LINUX) GtkWidget* widget = ViewIDUtil::GetWidget(GTK_WIDGET(window), vid); ASSERT_TRUE(widget); @@ -67,6 +69,30 @@ class BrowserFocusTest : public InProcessBrowserTest { #endif } + static void HideNativeWindow(gfx::NativeWindow window) { +#if defined(OS_WIN) + // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of + // using Windows API. + ::ShowWindow(window, SW_HIDE); +#elif defined(OS_LINUX) + gtk_widget_hide(GTK_WIDGET(window)); +#else + NOTIMPLEMENTED(); +#endif + } + + static void ShowNativeWindow(gfx::NativeWindow window) { +#if defined(OS_WIN) + // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of + // using Windows API. + ::ShowWindow(window, SW_SHOW); +#elif defined(OS_LINUX) + gtk_widget_hide(GTK_WIDGET(window)); +#else + NOTIMPLEMENTED(); +#endif + } + private: #if defined(OS_LINUX) // Check if the focused widget for |root| is |target| or a child of |target|. @@ -147,7 +173,32 @@ class TestInterstitialPage : public InterstitialPage { } // namespace +// TODO(estade): port. #if defined(OS_WIN) +IN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) { + browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK, + true, -1, false, NULL); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); + + BrowserView* browser_view = static_cast<BrowserView*>(browser()->window()); + ui_controls::MoveMouseToCenterAndPress( + browser_view->GetTabContentsContainerView(), + ui_controls::LEFT, + ui_controls::DOWN | ui_controls::UP, + new MessageLoop::QuitTask()); + ui_test_utils::RunMessageLoop(); + CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); + + ui_controls::MoveMouseToCenterAndPress( + browser_view->GetLocationBarView(), + ui_controls::LEFT, + ui_controls::DOWN | ui_controls::UP, + new MessageLoop::QuitTask()); + ui_test_utils::RunMessageLoop(); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); +} +#endif + IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) { HTTPTestServer* server = StartHTTPServer(); @@ -155,40 +206,25 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) { GURL url = server->TestServerPageW(kSimplePage); ui_test_utils::NavigateToURL(browser(), url); - // The focus should be on the Tab contents. - HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd); - ASSERT_TRUE(browser_view); - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(hwnd); - ASSERT_TRUE(focus_manager); - - EXPECT_EQ(browser_view->GetTabContentsContainerView(), - focus_manager->GetFocusedView()); + gfx::NativeWindow window = browser()->window()->GetNativeHandle(); + // The focus should be on the Tab contents. + CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); // Now hide the window, show it again, the focus should not have changed. - // TODO(jcampan): retrieve the WidgetWin and show/hide on it instead of - // using Windows API. - ::ShowWindow(hwnd, SW_HIDE); - ::ShowWindow(hwnd, SW_SHOW); - EXPECT_EQ(browser_view->GetTabContentsContainerView(), - focus_manager->GetFocusedView()); - - // Click on the location bar. - LocationBarView* location_bar = browser_view->GetLocationBarView(); - ui_controls::MoveMouseToCenterAndPress(location_bar, - ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); - // Location bar should have focus. - EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); + HideNativeWindow(window); + ShowNativeWindow(window); + CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); + browser()->FocusLocationBar(); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Hide the window, show it again, the focus should not have changed. - ::ShowWindow(hwnd, SW_HIDE); - ::ShowWindow(hwnd, SW_SHOW); - EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); + HideNativeWindow(window); + ShowNativeWindow(window); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); + // The rest of this test does not make sense on Linux because the behavior + // of Activate() is not well defined and can vary by window manager. +#if defined(OS_WIN) // Open a new browser window. Browser* browser2 = Browser::Create(browser()->profile()); ASSERT_TRUE(browser2); @@ -209,17 +245,20 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BrowsersRememberFocus) { // Switch to the 1st browser window, focus should still be on the location // bar and the second browser should have nothing focused. browser()->window()->Activate(); - EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); EXPECT_EQ(NULL, focus_manager2->GetFocusedView()); // Switch back to the second browser, focus should still be on the page. browser2->window()->Activate(); - EXPECT_EQ(NULL, focus_manager->GetFocusedView()); + EXPECT_EQ(NULL, + views::FocusManager::GetFocusManagerForNativeView( + browser()->window()->GetNativeHandle())->GetFocusedView()); EXPECT_EQ(browser_view2->GetTabContentsContainerView(), focus_manager2->GetFocusedView()); // Close the 2nd browser to avoid a DCHECK(). browser_view2->Close(); +#endif } // Tabs remember focus. @@ -230,14 +269,6 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) { GURL url = server->TestServerPageW(kSimplePage); ui_test_utils::NavigateToURL(browser(), url); - HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd); - ASSERT_TRUE(browser_view); - - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(hwnd); - ASSERT_TRUE(focus_manager); - // Create several tabs. for (int i = 0; i < 4; ++i) { browser()->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, -1, @@ -257,19 +288,11 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) { browser()->SelectTabContentsAt(j, true); // Activate the location bar or the page. - views::View* view_to_focus; if (kFocusPage[i][j]) { - view_to_focus = browser_view->GetTabContentsContainerView(); + browser()->GetTabContentsAt(j)->view()->Focus(); } else { - view_to_focus = browser_view->GetLocationBarView(); + browser()->FocusLocationBar(); } - - ui_controls::MoveMouseToCenterAndPress(view_to_focus, - ui_controls::LEFT, - ui_controls::DOWN | - ui_controls::UP, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); } // Now come back to the tab and check the right view is focused. @@ -277,14 +300,9 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabsRememberFocus) { // Activate the tab. browser()->SelectTabContentsAt(j, true); - // Activate the location bar or the page. - views::View* view; - if (kFocusPage[i][j]) { - view = browser_view->GetTabContentsContainerView(); - } else { - view = browser_view->GetLocationBarView(); - } - EXPECT_EQ(view, focus_manager->GetFocusedView()); + ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW : + VIEW_ID_LOCATION_BAR; + CheckViewHasFocus(vid); } } } @@ -302,26 +320,40 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, BackgroundBrowserDontStealFocus) { ASSERT_TRUE(browser2); browser2->tabstrip_model()->delegate()->AddBlankTab(true); browser2->window()->Show(); + + Browser* focused_browser; + Browser* unfocused_browser; +#if defined(OS_LINUX) + // On Linux, calling Activate() is not guaranteed to move focus, so we have + // to figure out which browser does have focus. + if (browser2->window()->IsActive()) { + focused_browser = browser2; + unfocused_browser = browser(); + } else if (browser()->window()->IsActive()) { + focused_browser = browser(); + unfocused_browser = browser2; + } else { + ASSERT_TRUE(false); + } +#elif defined(OS_WIN) + focused_browser = browser(); + unfocused_browser = browser2; +#endif + GURL steal_focus_url = server->TestServerPageW(kStealFocusPage); - ui_test_utils::NavigateToURL(browser2, steal_focus_url); + ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url); // Activate the first browser. - browser()->window()->Activate(); + focused_browser->window()->Activate(); // Wait for the focus to be stolen by the other browser. - ::Sleep(2000); + PlatformThread::Sleep(2000); // Make sure the first browser is still active. - HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd); - ASSERT_TRUE(browser_view); - EXPECT_TRUE(browser_view->frame()->GetWindow()->IsActive()); + EXPECT_TRUE(focused_browser->window()->IsActive()); // Close the 2nd browser to avoid a DCHECK(). - HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle()); - BrowserView* browser_view2 = - BrowserView::GetBrowserViewForNativeWindow(hwnd2); - browser_view2->Close(); + browser2->window()->Close(); } // Page cannot steal focus when focus is on location bar. @@ -332,24 +364,13 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) { GURL url = server->TestServerPageW(kStealFocusPage); ui_test_utils::NavigateToURL(browser(), url); - HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd); - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(hwnd); - - // Click on the location bar. - LocationBarView* location_bar = browser_view->GetLocationBarView(); - ui_controls::MoveMouseToCenterAndPress(location_bar, - ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); + browser()->FocusLocationBar(); // Wait for the page to steal focus. - ::Sleep(2000); + PlatformThread::Sleep(2000); // Make sure the location bar is still focused. - EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); } // Focus traversal on a regular page. @@ -360,18 +381,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { GURL url = server->TestServerPageW(kTypicalPage); ui_test_utils::NavigateToURL(browser(), url); - HWND hwnd = reinterpret_cast<HWND>(browser()->window()->GetNativeHandle()); - BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(hwnd); - views::FocusManager* focus_manager = - views::FocusManager::GetFocusManagerForNativeView(hwnd); - - // Click on the location bar. - LocationBarView* location_bar = browser_view->GetLocationBarView(); - ui_controls::MoveMouseToCenterAndPress(location_bar, - ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP, - new MessageLoop::QuitTask()); - ui_test_utils::RunMessageLoop(); + browser()->FocusLocationBar(); const char* kExpElementIDs[] = { "", // Initially no element in the page should be focused @@ -380,10 +390,12 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { "gmapLink" }; + gfx::NativeWindow window = browser()->window()->GetNativeHandle(); + // Test forward focus traversal. for (int i = 0; i < 3; ++i) { // Location bar should be focused. - EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Now let's press tab to move the focus. for (int j = 0; j < 7; ++j) { @@ -396,14 +408,14 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { &actual)); ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); - ui_controls::SendKeyPressNotifyWhenDone(NULL, base::VKEY_TAB, false, + ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, false, false, new MessageLoop::QuitTask()); ui_test_utils::RunMessageLoop(); // Ideally, we wouldn't sleep here and instead would use the event // processed ack notification from the renderer. I am reluctant to create // a new notification/callback for that purpose just for this test. - ::Sleep(kActionDelayMs); + PlatformThread::Sleep(kActionDelayMs); } // At this point the renderer has sent us a message asking to advance the @@ -416,15 +428,15 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { // Now let's try reverse focus traversal. for (int i = 0; i < 3; ++i) { // Location bar should be focused. - EXPECT_EQ(location_bar, focus_manager->GetFocusedView()); + CheckViewHasFocus(VIEW_ID_LOCATION_BAR); // Now let's press shift-tab to move the focus in reverse. for (int j = 0; j < 7; ++j) { - ui_controls::SendKeyPressNotifyWhenDone(NULL, base::VKEY_TAB, false, + ui_controls::SendKeyPressNotifyWhenDone(window, base::VKEY_TAB, false, true, false, new MessageLoop::QuitTask()); ui_test_utils::RunMessageLoop(); - ::Sleep(kActionDelayMs); + PlatformThread::Sleep(kActionDelayMs); // Let's make sure the focus is on the expected element in the page. std::string actual; @@ -444,6 +456,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversal) { } } +#if defined(OS_WIN) // Focus traversal while an interstitial is showing. IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusTraversalOnInterstitial) { HTTPTestServer* server = StartHTTPServer(); @@ -667,10 +680,10 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) { // Makes sure the focus is in the right location when opening the different // types of tabs. // TODO(estade): undisable this. -IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabInitialFocus) { +IN_PROC_BROWSER_TEST_F(BrowserFocusTest, TabInitialFocus) { // Open the history tab, focus should be on the tab contents. browser()->ShowHistoryTab(); - CheckViewHasFocus(VIEW_ID_TAB_CONTAINER); + CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); // Open the new tab, focus should be on the location bar. browser()->NewTab(); @@ -678,7 +691,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabInitialFocus) { // Open the download tab, focus should be on the tab contents. browser()->ShowDownloadsTab(); - CheckViewHasFocus(VIEW_ID_TAB_CONTAINER); + CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); // Open about:blank, focus should be on the location bar. browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::LINK, diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index dc2e21d..d12875a 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -486,38 +486,29 @@ void BrowserWindowGtk::HandleAccelerator(guint keyval, gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget, GdkEventExpose* event, BrowserWindowGtk* window) { - static NineBox* default_background = NULL; - static NineBox* default_background_inactive = NULL; - static NineBox* default_background_otr = NULL; - static NineBox* default_background_otr_inactive = NULL; - ThemeProvider* theme_provider = window->browser()->profile()->GetThemeProvider(); - if (!default_background) { - default_background = new NineBox(theme_provider, - 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0); - default_background_inactive = new NineBox(theme_provider, - 0, IDR_THEME_FRAME_INACTIVE, 0, 0, 0, 0, 0, 0, 0); - default_background_otr = new NineBox(theme_provider, - 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0); - default_background_otr_inactive = new NineBox(theme_provider, - 0, IDR_THEME_FRAME_INCOGNITO_INACTIVE, 0, 0, 0, 0, 0, 0, 0); - } // Draw the default background. cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); - NineBox* image = NULL; + + int image_name; if (window->IsActive()) { - image = window->browser()->profile()->IsOffTheRecord() - ? default_background_otr : default_background; + image_name = window->browser()->profile()->IsOffTheRecord() ? + IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME; } else { - image = window->browser()->profile()->IsOffTheRecord() - ? default_background_otr_inactive : default_background_inactive; + image_name = window->browser()->profile()->IsOffTheRecord() ? + IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE; } - image->RenderTopCenterStrip(cr, 0, 0, widget->allocation.width); + GdkPixbuf* pixbuf = theme_provider->GetPixbufNamed(image_name); + gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); + cairo_rectangle(cr, event->area.x, event->area.y, + event->area.width, event->area.height); + cairo_fill(cr); if (theme_provider->HasCustomImage(IDR_THEME_FRAME_OVERLAY)) { GdkPixbuf* theme_overlay = theme_provider->GetPixbufNamed( @@ -533,16 +524,15 @@ gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget, if (window->use_custom_frame_.GetValue() && !window->IsMaximized()) { static NineBox custom_frame_border( - theme_provider, - IDR_WINDOW_TOP_LEFT_CORNER, - IDR_WINDOW_TOP_CENTER, - IDR_WINDOW_TOP_RIGHT_CORNER, - IDR_WINDOW_LEFT_SIDE, - NULL, - IDR_WINDOW_RIGHT_SIDE, - IDR_WINDOW_BOTTOM_LEFT_CORNER, - IDR_WINDOW_BOTTOM_CENTER, - IDR_WINDOW_BOTTOM_RIGHT_CORNER); + IDR_WINDOW_TOP_LEFT_CORNER, + IDR_WINDOW_TOP_CENTER, + IDR_WINDOW_TOP_RIGHT_CORNER, + IDR_WINDOW_LEFT_SIDE, + NULL, + IDR_WINDOW_RIGHT_SIDE, + IDR_WINDOW_BOTTOM_LEFT_CORNER, + IDR_WINDOW_BOTTOM_CENTER, + IDR_WINDOW_BOTTOM_RIGHT_CORNER); custom_frame_border.RenderToWidget(widget); } @@ -556,15 +546,20 @@ void BrowserWindowGtk::DrawContentShadow(cairo_t* cr, // Draw the shadow above the toolbar. Tabs on the tabstrip will draw over us. ThemeProvider* theme_provider = window->browser()->profile()->GetThemeProvider(); - static NineBox top_shadow(theme_provider, - 0, IDR_CONTENT_TOP_CENTER, 0, 0, 0, 0, 0, 0, 0); int left_x, top_y; gtk_widget_translate_coordinates(window->content_vbox_, GTK_WIDGET(window->window_), 0, 0, &left_x, &top_y); int width = window->content_vbox_->allocation.width; - top_shadow.RenderTopCenterStrip(cr, - left_x, top_y - kContentShadowThickness, width); + + GdkPixbuf* top_center = + theme_provider->GetPixbufNamed(IDR_CONTENT_TOP_CENTER); + gdk_cairo_set_source_pixbuf(cr, top_center, + left_x, top_y - kContentShadowThickness); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); + cairo_rectangle(cr, left_x, top_y - kContentShadowThickness, width, + gdk_pixbuf_get_height(top_center)); + cairo_fill(cr); // Only draw the rest of the shadow if the user has the custom frame enabled. if (!window->use_custom_frame_.GetValue()) diff --git a/chrome/browser/gtk/extension_shelf_gtk.cc b/chrome/browser/gtk/extension_shelf_gtk.cc index 768aee8..f574fe4 100644 --- a/chrome/browser/gtk/extension_shelf_gtk.cc +++ b/chrome/browser/gtk/extension_shelf_gtk.cc @@ -8,8 +8,8 @@ #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/nine_box.h" +#include "chrome/browser/gtk/tabs/tab_strip_gtk.h" #include "chrome/browser/profile.h" -#include "chrome/common/notification_service.h" #include "grit/app_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -65,9 +65,6 @@ ExtensionShelfGtk::ExtensionShelfGtk(Profile* profile, Browser* browser) theme_provider_(GtkThemeProvider::GetFrom(profile)), model_(browser->extension_shelf_model()) { Init(profile); - - registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources()); } ExtensionShelfGtk::~ExtensionShelfGtk() { @@ -161,25 +158,6 @@ void ExtensionShelfGtk::Init(Profile* profile) { model_->AddObserver(this); } -void ExtensionShelfGtk::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::BROWSER_THEME_CHANGED) { - // TODO(phajdan.jr): Handle theme changes. - } else { - NOTREACHED() << "unexpected notification"; - } -} - -void ExtensionShelfGtk::InitBackground() { - if (background_ninebox_.get()) - return; - - background_ninebox_.reset(new NineBox( - browser_->profile()->GetThemeProvider(), - 0, IDR_THEME_TOOLBAR, 0, 0, 0, 0, 0, 0, 0)); -} - void ExtensionShelfGtk::AdjustHeight() { if (model_->empty() || toolstrips_.empty()) { // It's possible that |model_| is not empty, but |toolstrips_| are empty @@ -213,10 +191,18 @@ gboolean ExtensionShelfGtk::OnHBoxExpose(GtkWidget* widget, cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); - bar->InitBackground(); - bar->background_ninebox_->RenderTopCenterStrip( - cr, event->area.x, event->area.y, - event->area.x + event->area.width); + gfx::Point tabstrip_origin = + static_cast<BrowserWindowGtk*>(bar->browser_->window())-> + tabstrip()->GetTabStripOriginForWidget(widget); + GdkPixbuf* background = bar->browser_->profile()->GetThemeProvider()-> + GetPixbufNamed(IDR_THEME_TOOLBAR); + gdk_cairo_set_source_pixbuf(cr, background, + tabstrip_origin.x(), tabstrip_origin.y()); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); + cairo_rectangle(cr, tabstrip_origin.x(), tabstrip_origin.y(), + event->area.x + event->area.width - tabstrip_origin.x(), + gdk_pixbuf_get_height(background)); + cairo_fill(cr); cairo_destroy(cr); return FALSE; // Propagate expose to children. diff --git a/chrome/browser/gtk/extension_shelf_gtk.h b/chrome/browser/gtk/extension_shelf_gtk.h index 81b055a89..5180000 100644 --- a/chrome/browser/gtk/extension_shelf_gtk.h +++ b/chrome/browser/gtk/extension_shelf_gtk.h @@ -11,8 +11,6 @@ #include "base/scoped_ptr.h" #include "chrome/browser/extensions/extension_shelf_model.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" class Browser; @@ -22,8 +20,7 @@ class NineBox; class Profile; struct GtkThemeProvider; -class ExtensionShelfGtk : public ExtensionShelfModelObserver, - public NotificationObserver { +class ExtensionShelfGtk : public ExtensionShelfModelObserver { public: ExtensionShelfGtk(Profile* profile, Browser* browser); virtual ~ExtensionShelfGtk(); @@ -53,14 +50,6 @@ class ExtensionShelfGtk : public ExtensionShelfModelObserver, // Create the contents of the extension shelf. void Init(Profile* profile); - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Loads the background image into memory, or does nothing if already loaded. - void InitBackground(); - // Determines what is our target height and sets it. void AdjustHeight(); @@ -83,11 +72,6 @@ class ExtensionShelfGtk : public ExtensionShelfModelObserver, GtkThemeProvider* theme_provider_; - // Paints the background for our bookmark bar. - scoped_ptr<NineBox> background_ninebox_; - - NotificationRegistrar registrar_; - // The model representing the toolstrips on the shelf. ExtensionShelfModel* model_; diff --git a/chrome/browser/gtk/find_bar_gtk.cc b/chrome/browser/gtk/find_bar_gtk.cc index 759a228..37e937f 100644 --- a/chrome/browser/gtk/find_bar_gtk.cc +++ b/chrome/browser/gtk/find_bar_gtk.cc @@ -151,10 +151,6 @@ FindBarGtk::FindBarGtk(Browser* browser) InitWidgets(); ViewIDUtil::SetID(text_entry_, VIEW_ID_FIND_IN_PAGE_TEXT_FIELD); - dialog_background_.reset(new NineBox(browser->profile()->GetThemeProvider(), - 0, IDR_THEME_TOOLBAR, 0, - 0, 0, 0, 0, 0, 0)); - // Insert the widget into the browser gtk hierarchy. window_->AddFindBar(this); @@ -669,9 +665,15 @@ gboolean FindBarGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, cairo_clip(cr); gfx::Point tabstrip_origin = bar->window_->tabstrip()->GetTabStripOriginForWidget(widget); - bar->dialog_background_->RenderTopCenterStrip( - cr, tabstrip_origin.x(), tabstrip_origin.y(), - e->area.x + e->area.width - tabstrip_origin.x()); + GdkPixbuf* background = bar->browser_->profile()->GetThemeProvider()-> + GetPixbufNamed(IDR_THEME_TOOLBAR); + gdk_cairo_set_source_pixbuf(cr, background, + tabstrip_origin.x(), tabstrip_origin.y()); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); + cairo_rectangle(cr, tabstrip_origin.x(), tabstrip_origin.y(), + e->area.x + e->area.width - tabstrip_origin.x(), + gdk_pixbuf_get_height(background)); + cairo_fill(cr); cairo_destroy(cr); // Draw the border. diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc index 26e79b1..6f6d77f 100644 --- a/chrome/browser/gtk/nine_box.cc +++ b/chrome/browser/gtk/nine_box.cc @@ -11,7 +11,6 @@ #include "base/gfx/gtk_util.h" #include "base/gfx/point.h" #include "base/logging.h" -#include "chrome/common/notification_service.h" namespace { @@ -46,29 +45,6 @@ NineBox::NineBox(int top_left, int top, int top_right, int left, int center, images_[8] = bottom_right ? rb.GetPixbufNamed(bottom_right) : NULL; } -NineBox::NineBox(ThemeProvider* theme_provider, - int top_left, int top, int top_right, int left, int center, - int right, int bottom_left, int bottom, int bottom_right) - : theme_provider_(theme_provider) { - image_ids_[0] = top_left; - image_ids_[1] = top; - image_ids_[2] = top_right; - image_ids_[3] = left; - image_ids_[4] = center; - image_ids_[5] = right; - image_ids_[6] = bottom_left; - image_ids_[7] = bottom; - image_ids_[8] = bottom_right; - - // Load images by pretending that we got a BROWSER_THEME_CHANGED - // notification. - Observe(NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources(), - NotificationService::NoDetails()); - registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources()); -} - NineBox::~NineBox() { } @@ -214,17 +190,3 @@ void NineBox::ContourWidget(GtkWidget* widget) const { g_object_unref(mask); } - -void NineBox::Observe(NotificationType type, const NotificationSource& source, - const NotificationDetails& details) { - if (NotificationType::BROWSER_THEME_CHANGED != type) { - NOTREACHED(); - return; - } - - // Reload images. - for (size_t i = 0; i < arraysize(image_ids_); ++i) { - images_[i] = image_ids_[i] ? - theme_provider_->GetPixbufNamed(image_ids_[i]) : NULL; - } -} diff --git a/chrome/browser/gtk/nine_box.h b/chrome/browser/gtk/nine_box.h index 4ceea54..a189797 100644 --- a/chrome/browser/gtk/nine_box.h +++ b/chrome/browser/gtk/nine_box.h @@ -7,12 +7,6 @@ #include <gtk/gtk.h> -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_type.h" - -class ThemeProvider; - // A NineBox manages a set of source images representing a 3x3 grid, where // non-corner images can be tiled to make a larger image. It's used to // use bitmaps for constructing image-based resizable widgets like buttons. @@ -24,18 +18,12 @@ class ThemeProvider; // // TODO(port): add support for caching server-side pixmaps of prerendered // nineboxes. -class NineBox : public NotificationObserver { +class NineBox { public: // Construct a NineBox with nine images. Images are specified using resource // ids that will be passed to the resource bundle. Use 0 for no image. NineBox(int top_left, int top, int top_right, int left, int center, int right, int bottom_left, int bottom, int bottom_right); - - // Same as above, but use themed images. - NineBox(ThemeProvider* theme_provider, - int top_left, int top, int top_right, int left, int center, int right, - int bottom_left, int bottom, int bottom_right); - ~NineBox(); // Render the NineBox to |dst|. @@ -56,20 +44,8 @@ class NineBox : public NotificationObserver { // needed). void ContourWidget(GtkWidget* widget) const; - // Provide NotificationObserver implementation. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); private: GdkPixbuf* images_[9]; - - // We need to remember the image ids that the user passes in and the theme - // provider so we can reload images if the user changes theme. - int image_ids_[9]; - ThemeProvider* theme_provider_; - - // Used to listen for theme change notifications. - NotificationRegistrar registrar_; }; #endif // CHROME_BROWSER_GTK_NINE_BOX_H_ diff --git a/chrome/browser/gtk/tab_contents_container_gtk.cc b/chrome/browser/gtk/tab_contents_container_gtk.cc index ebae3a6..41d0aae 100644 --- a/chrome/browser/gtk/tab_contents_container_gtk.cc +++ b/chrome/browser/gtk/tab_contents_container_gtk.cc @@ -8,7 +8,6 @@ #include "base/gfx/native_widget_types.h" #include "chrome/browser/gtk/gtk_floating_container.h" #include "chrome/browser/gtk/status_bubble_gtk.h" -#include "chrome/browser/gtk/view_id_util.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" #include "chrome/common/notification_service.h" @@ -70,7 +69,7 @@ void TabContentsContainerGtk::Init() { gtk_widget_show(fixed_); gtk_widget_show(floating_.get()); - ViewIDUtil::SetID(widget(), VIEW_ID_TAB_CONTAINER); + ViewIDUtil::SetDelegateForWidget(widget(), this); } void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) { @@ -159,6 +158,20 @@ void TabContentsContainerGtk::TabContentsDestroyed(TabContents* contents) { SetTabContents(NULL); } +// ----------------------------------------------------------------------------- +// ViewIDUtil::Delegate implementation + +GtkWidget* TabContentsContainerGtk::GetWidgetForViewID(ViewID view_id) { + if (view_id == VIEW_ID_TAB_CONTAINER || + view_id == VIEW_ID_TAB_CONTAINER_FOCUS_VIEW) { + return widget(); + } + + return NULL; +} + +// ----------------------------------------------------------------------------- + // static void TabContentsContainerGtk::OnFixedSizeAllocate( GtkWidget* fixed, diff --git a/chrome/browser/gtk/tab_contents_container_gtk.h b/chrome/browser/gtk/tab_contents_container_gtk.h index b76517d..8a7a8c7 100644 --- a/chrome/browser/gtk/tab_contents_container_gtk.h +++ b/chrome/browser/gtk/tab_contents_container_gtk.h @@ -8,6 +8,7 @@ #include <gtk/gtk.h> #include "base/basictypes.h" +#include "chrome/browser/gtk/view_id_util.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" @@ -17,7 +18,8 @@ class TabContents; typedef struct _GtkFloatingContainer GtkFloatingContainer; -class TabContentsContainerGtk : public NotificationObserver { +class TabContentsContainerGtk : public NotificationObserver, + public ViewIDUtil::Delegate { public: explicit TabContentsContainerGtk(StatusBubbleGtk* status_bubble); ~TabContentsContainerGtk(); @@ -38,6 +40,9 @@ class TabContentsContainerGtk : public NotificationObserver { GtkWidget* widget() { return floating_.get(); } + // ViewIDUtil::Delegate implementation --------------------------------------- + virtual GtkWidget* GetWidgetForViewID(ViewID id); + private: // Add or remove observers for events that we care about. void AddObservers(); diff --git a/chrome/browser/view_ids.h b/chrome/browser/view_ids.h index f46c559..92561de 100644 --- a/chrome/browser/view_ids.h +++ b/chrome/browser/view_ids.h @@ -49,6 +49,7 @@ enum ViewID { // Tab Container window. VIEW_ID_TAB_CONTAINER, + VIEW_ID_TAB_CONTAINER_FOCUS_VIEW, VIEW_ID_PREDEFINED_COUNT }; diff --git a/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc b/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc index dad95e4..83db8e0 100644 --- a/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc +++ b/chrome/browser/views/tab_contents/native_tab_contents_container_win.cc @@ -7,6 +7,7 @@ #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/tab_contents/interstitial_page.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/view_ids.h" #include "chrome/browser/views/tab_contents/tab_contents_container.h" #include "chrome/browser/views/tab_contents/tab_contents_view_win.h" @@ -18,6 +19,7 @@ NativeTabContentsContainerWin::NativeTabContentsContainerWin( TabContentsContainer* container) : container_(container) { + SetID(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); } NativeTabContentsContainerWin::~NativeTabContentsContainerWin() { |