diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-26 22:07:40 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-26 22:07:40 +0000 |
commit | 89efb52609f60683645bf4c15b93a0c336baa947 (patch) | |
tree | 30ca23a5d31780508e009070dd1697dd33b11412 | |
parent | 862a92ee0afc1be6470beed3e19465c24da223e2 (diff) | |
download | chromium_src-89efb52609f60683645bf4c15b93a0c336baa947.zip chromium_src-89efb52609f60683645bf4c15b93a0c336baa947.tar.gz chromium_src-89efb52609f60683645bf4c15b93a0c336baa947.tar.bz2 |
Fix a crash that happens when changing themes.
We were holding references to images that got deleted when themes
changed. These all happen to be in a NineBox, so have NineBox
reload images when the theme change notification is sent.
Also fix an expose bug that wasn't noticeable in the original
theme. We need to always place the image at 0, 0 for the
background and paint it all the way across the window (should
get clipped by cairo).
BUG=15366
Review URL: http://codereview.chromium.org/149102
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19426 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 5 | ||||
-rw-r--r-- | chrome/browser/gtk/nine_box.cc | 54 | ||||
-rw-r--r-- | chrome/browser/gtk/nine_box.h | 18 |
3 files changed, 55 insertions, 22 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 5d79502..1440791 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -418,7 +418,7 @@ gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget, cairo_clip(cr); NineBox* image = window->browser()->profile()->IsOffTheRecord() ? default_background_otr : default_background; - image->RenderTopCenterStrip(cr, event->area.x, 0, event->area.width); + image->RenderTopCenterStrip(cr, 0, 0, widget->allocation.width); cairo_destroy(cr); // TODO(tc): Draw the theme overlay. The windows code is below. @@ -703,7 +703,8 @@ void BrowserWindowGtk::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, } void BrowserWindowGtk::UserChangedTheme() { - NOTIMPLEMENTED(); + gdk_window_invalidate_rect(GTK_WIDGET(window_)->window, + >K_WIDGET(window_)->allocation, TRUE); } int BrowserWindowGtk::GetExtraRenderViewHeight() const { diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc index ba1b856..af2de61 100644 --- a/chrome/browser/gtk/nine_box.cc +++ b/chrome/browser/gtk/nine_box.cc @@ -6,9 +6,11 @@ #include "app/resource_bundle.h" #include "app/theme_provider.h" +#include "base/basictypes.h" #include "base/gfx/gtk_util.h" #include "base/gfx/point.h" #include "base/logging.h" +#include "chrome/common/notification_service.h" namespace { @@ -45,25 +47,25 @@ NineBox::NineBox(int top_left, int top, int top_right, int left, int center, 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) { - images_[0] = top_left ? - theme_provider->GetPixbufNamed(top_left) : NULL; - images_[1] = top ? - theme_provider->GetPixbufNamed(top) : NULL; - images_[2] = top_right ? - theme_provider->GetPixbufNamed(top_right) : NULL; - images_[3] = left ? - theme_provider->GetPixbufNamed(left) : NULL; - images_[4] = center ? - theme_provider->GetPixbufNamed(center) : NULL; - images_[5] = right ? - theme_provider->GetPixbufNamed(right) : NULL; - images_[6] = bottom_left ? - theme_provider->GetPixbufNamed(bottom_left) : NULL; - images_[7] = bottom ? - theme_provider->GetPixbufNamed(bottom) : NULL; - images_[8] = bottom_right ? - theme_provider->GetPixbufNamed(bottom_right) : NULL; + 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() { @@ -177,3 +179,17 @@ void NineBox::ContourWidget(GtkWidget* widget) const { g_object_unref(mask); cairo_destroy(cr); } + +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 dfdfafb..4ceea54 100644 --- a/chrome/browser/gtk/nine_box.h +++ b/chrome/browser/gtk/nine_box.h @@ -7,6 +7,10 @@ #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 @@ -20,7 +24,7 @@ class ThemeProvider; // // TODO(port): add support for caching server-side pixmaps of prerendered // nineboxes. -class NineBox { +class NineBox : public NotificationObserver { 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. @@ -52,8 +56,20 @@ class NineBox { // 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_ |