diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-27 18:51:23 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-27 18:51:23 +0000 |
commit | 8391a30911633d75933729bc785a29384cc738ff (patch) | |
tree | 0dc312f57c6c8d90027fca95cb9949f371254ff7 | |
parent | 4c2da3a63c04cc52554b5057670a5ad7c7b8d800 (diff) | |
download | chromium_src-8391a30911633d75933729bc785a29384cc738ff.zip chromium_src-8391a30911633d75933729bc785a29384cc738ff.tar.gz chromium_src-8391a30911633d75933729bc785a29384cc738ff.tar.bz2 |
GTK: Draw floating bookmark bar correctly during resizes.
BUG=23907
TEST=Using ratchet + clank theme, go to NTP while bookmark bar is off so you see a floating bar. Maximize the window. It should look right.
Review URL: http://codereview.chromium.org/329022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30226 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.cc | 77 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.h | 26 |
2 files changed, 83 insertions, 20 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index dcfde4b..60a372a 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -128,7 +128,8 @@ BookmarkBarGtk::BookmarkBarGtk(BrowserWindowGtk* window, show_instructions_(true), menu_bar_helper_(this), floating_(false), - last_allocation_width_(-1) { + last_allocation_width_(-1), + event_box_paint_factory_(this) { #if defined(BROWSER_SYNC) if (profile->GetProfileSyncService()) { // Obtain a pointer to the profile sync service and add our instance as an @@ -227,7 +228,7 @@ void BookmarkBarGtk::Init(Profile* profile) { g_signal_connect(instructions_, "drag-data-received", G_CALLBACK(&OnDragReceived), this); - g_signal_connect(G_OBJECT(event_box_.get()), "expose-event", + g_signal_connect(event_box_.get(), "expose-event", G_CALLBACK(&OnEventBoxExpose), this); UpdateEventBoxPaintability(); @@ -615,8 +616,19 @@ void BookmarkBarGtk::UpdateFloatingState() { UpdateEventBoxPaintability(); // |window_| can be NULL during testing. - if (window_) + if (window_) { window_->BookmarkBarIsFloating(floating_); + // Listen for parent size allocations. + if (floating_ && widget()->parent) { + // Only connect once. + if (g_signal_handler_find(widget()->parent, G_SIGNAL_MATCH_FUNC, + 0, NULL, NULL, reinterpret_cast<gpointer>(OnParentSizeAllocate), + NULL) == 0) { + g_signal_connect(widget()->parent, "size-allocate", + G_CALLBACK(OnParentSizeAllocate), this); + } + } + } } void BookmarkBarGtk::UpdateEventBoxPaintability() { @@ -629,6 +641,34 @@ void BookmarkBarGtk::UpdateEventBoxPaintability() { theme_provider_->UseGtkTheme()); } +void BookmarkBarGtk::PaintEventBox() { + gfx::Size tab_contents_size; + if (GetTabContentsSize(&tab_contents_size) && + tab_contents_size != last_tab_contents_size_) { + last_tab_contents_size_ = tab_contents_size; + gtk_widget_queue_draw(event_box_.get()); + } +} + +bool BookmarkBarGtk::GetTabContentsSize(gfx::Size* size) { + Browser* browser = browser_; + if (!browser) { + NOTREACHED(); + return false; + } + TabContents* tab_contents = browser->GetSelectedTabContents(); + if (!tab_contents) { + NOTREACHED(); + return false; + } + if (!tab_contents->view()) { + NOTREACHED(); + return false; + } + *size = tab_contents->view()->GetContainerSize(); + return true; +} + bool BookmarkBarGtk::IsAlwaysShown() { return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); } @@ -1100,21 +1140,8 @@ gboolean BookmarkBarGtk::OnEventBoxExpose(GtkWidget* widget, cairo_destroy(cr); } else { gfx::Size tab_contents_size; - Browser* browser = bar->browser_; - if (!browser) { - NOTREACHED(); + if (!bar->GetTabContentsSize(&tab_contents_size)) return FALSE; - } - TabContents* tab_contents = browser->GetSelectedTabContents(); - if (!tab_contents) { - NOTREACHED(); - return FALSE; - } - if (!tab_contents->view()) { - NOTREACHED(); - return FALSE; - } - tab_contents_size = tab_contents->view()->GetContainerSize(); gfx::CanvasPaint canvas(event, true); NtpBackgroundUtil::PaintBackgroundDetachedMode(theme_provider, &canvas, gfx::Rect(widget->allocation), tab_contents_size.height()); @@ -1124,6 +1151,22 @@ gboolean BookmarkBarGtk::OnEventBoxExpose(GtkWidget* widget, } // static +void BookmarkBarGtk::OnParentSizeAllocate(GtkWidget* widget, + GtkAllocation* allocation, + BookmarkBarGtk* bar) { + // In floating mode, our layout depends on the size of the tab contents. + // We get the size-allocate signal before the tab contents does, hence we + // need to post a delayed task so we will paint correctly. Note that + // gtk_widget_queue_draw by itself does not work, despite that it claims to + // be asynchronous. + if (bar->floating_) { + MessageLoop::current()->PostTask(FROM_HERE, + bar->event_box_paint_factory_.NewRunnableMethod( + &BookmarkBarGtk::PaintEventBox)); + } +} + +// static gboolean BookmarkBarGtk::OnSeparatorExpose(GtkWidget* widget, GdkEventExpose* event, BookmarkBarGtk* bar) { diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h index bcd9d24..9745fd7 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.h +++ b/chrome/browser/gtk/bookmark_bar_gtk.h @@ -11,6 +11,7 @@ #include <vector> #include "app/slide_animation.h" +#include "base/gfx/size.h" #include "base/scoped_ptr.h" #include "chrome/browser/bookmarks/bookmark_model_observer.h" #include "chrome/browser/gtk/menu_bar_helper.h" @@ -150,6 +151,13 @@ class BookmarkBarGtk : public AnimationDelegate, // state. void UpdateEventBoxPaintability(); + // Queue a paint on the event box. + void PaintEventBox(); + + // Finds the size of the current tab contents. If the size cannot be found, + // DCHECKs and returns false. Otherwise, sets |size| to the correct value. + bool GetTabContentsSize(gfx::Size* size); + // Overridden from BookmarkModelObserver: // Invoked when the bookmark model has finished loading. Creates a button @@ -245,11 +253,16 @@ class BookmarkBarGtk : public AnimationDelegate, // GtkEventBox callbacks. static gboolean OnEventBoxExpose(GtkWidget* widget, GdkEventExpose* event, - BookmarkBarGtk* window); + BookmarkBarGtk* bar); // GtkVSeparator callbacks. static gboolean OnSeparatorExpose(GtkWidget* widget, GdkEventExpose* event, - BookmarkBarGtk* window); + BookmarkBarGtk* bar); + + // Callbacks on our parent widget. + static void OnParentSizeAllocate(GtkWidget* widget, + GtkAllocation* allocation, + BookmarkBarGtk* bar); #if defined(BROWSER_SYNC) // ProfileSyncServiceObserver method. @@ -320,7 +333,7 @@ class BookmarkBarGtk : public AnimationDelegate, // dragging. const BookmarkNode* dragged_node_; - // We create a GtkToolbarItem from |dragged_node_| for display. + // We create a GtkToolbarItem from |dragged_node_| ;or display. GtkToolItem* toolbar_drop_item_; // Theme provider for building buttons. @@ -351,6 +364,13 @@ class BookmarkBarGtk : public AnimationDelegate, int last_allocation_width_; NotificationRegistrar registrar_; + + // The size of the tab contents last time we forced a paint. We keep track + // of this so we don't force too many paints. + gfx::Size last_tab_contents_size_; + + // We post delayed paints using this factory. + ScopedRunnableMethodFactory<BookmarkBarGtk> event_box_paint_factory_; }; #endif // CHROME_BROWSER_GTK_BOOKMARK_BAR_GTK_H_ |