diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-01 23:50:21 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-01 23:50:21 +0000 |
commit | 4bdb4865688a7626a2451e83d094130fc12cf7ed (patch) | |
tree | 3c74fad61f27ba27336cdff9419fe94925012f77 /chrome/browser/gtk | |
parent | 24313c1118b2ed8eb46181702558841eb9914f9e (diff) | |
download | chromium_src-4bdb4865688a7626a2451e83d094130fc12cf7ed.zip chromium_src-4bdb4865688a7626a2451e83d094130fc12cf7ed.tar.gz chromium_src-4bdb4865688a7626a2451e83d094130fc12cf7ed.tar.bz2 |
GTK: Detach bookmark bar on NTP.
TODO=get alignment right for NTP background when alignment != top
TODO=fancy-pants animation (on windows this animation looks rather janky anyway so I'm not eager to work on this)
TODO=tweak in gtk mode (border color=?)
TEST=fiddle a lot, make sure there are no problems with find bar occlusion.
TEST=install a bunch of different themes; everything looks right (up to TODOs)
TEST=switch back and forth between gtk theme and chromium theme
TEST=popup windows still work
TEST=poked around in valgrind
TEST=poked around with fullscreen
BUG=18780
Review URL: http://codereview.chromium.org/243057
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27801 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.cc | 208 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.h | 28 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 22 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 68 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/download_shelf_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/rounded_window.cc | 14 | ||||
-rw-r--r-- | chrome/browser/gtk/rounded_window.h | 7 |
10 files changed, 294 insertions, 71 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index 89c78bf..ab74be7 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -25,6 +25,7 @@ #include "chrome/browser/gtk/custom_button.h" #include "chrome/browser/gtk/gtk_chrome_button.h" #include "chrome/browser/gtk/gtk_theme_provider.h" +#include "chrome/browser/gtk/rounded_window.h" #include "chrome/browser/gtk/tabstrip_origin_provider.h" #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" #include "chrome/browser/gtk/view_id_util.h" @@ -44,6 +45,17 @@ namespace { // The showing height of the bar. const int kBookmarkBarHeight = 29; +// Padding for when the bookmark bar is floating. +const int kTopBottomNTPPadding = 12; +const int kLeftRightNTPPadding = 8; + +// Padding around the bar's content area when the bookmark bar is floating. +const int kNTPPadding = 2; + +// The number of pixels of rounding on the corners of the bookmark bar content +// area when in floating mode. +const int kNTPRoundedness = 3; + // The height of the bar when it is "hidden". It is usually not completely // hidden because even when it is closed it forms the bottom few pixels of // the toolbar. @@ -93,11 +105,15 @@ void SetToolBarStyle() { } // namespace -BookmarkBarGtk::BookmarkBarGtk(Profile* profile, Browser* browser, +const int BookmarkBarGtk::kBookmarkBarNTPHeight = 57; + +BookmarkBarGtk::BookmarkBarGtk(BrowserWindowGtk* window, + Profile* profile, Browser* browser, TabstripOriginProvider* tabstrip_origin_provider) : profile_(NULL), page_navigator_(NULL), browser_(browser), + window_(window), tabstrip_origin_provider_(tabstrip_origin_provider), model_(NULL), instructions_(NULL), @@ -105,9 +121,13 @@ BookmarkBarGtk::BookmarkBarGtk(Profile* profile, Browser* browser, toolbar_drop_item_(NULL), theme_provider_(GtkThemeProvider::GetFrom(profile)), show_instructions_(true), - menu_bar_helper_(this) { + menu_bar_helper_(this), + floating_(false) { Init(profile); SetProfile(profile); + // Force an update by simulating being in the wrong state. + floating_ = !ShouldBeFloating(); + UpdateFloatingState(); registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, NotificationService::AllSources()); @@ -151,14 +171,22 @@ void BookmarkBarGtk::SetPageNavigator(PageNavigator* navigator) { void BookmarkBarGtk::Init(Profile* profile) { event_box_.Own(gtk_event_box_new()); - // Make the event box transparent so themes can use transparent backgrounds. - if (!theme_provider_->UseGtkTheme()) - gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), FALSE); g_signal_connect(event_box_.get(), "button-press-event", G_CALLBACK(&OnButtonPressed), this); + ntp_padding_box_ = gtk_alignment_new(0, 0, 1, 1); + gtk_container_add(GTK_CONTAINER(event_box_.get()), ntp_padding_box_); + + paint_box_ = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(ntp_padding_box_), paint_box_); + GdkColor paint_box_color = + theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR); + gtk_widget_modify_bg(paint_box_, GTK_STATE_NORMAL, &paint_box_color); + gtk_widget_add_events(paint_box_, GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK); + bookmark_hbox_ = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(event_box_.get()), bookmark_hbox_); + gtk_container_add(GTK_CONTAINER(paint_box_), bookmark_hbox_); instructions_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); gtk_alignment_set_padding(GTK_ALIGNMENT(instructions_), 0, 0, @@ -180,10 +208,9 @@ void BookmarkBarGtk::Init(Profile* profile) { g_signal_connect(instructions_, "drag-data-received", G_CALLBACK(&OnDragReceived), this); - // Only paint in chrome theme mode. - gtk_widget_set_app_paintable(widget(), !theme_provider_->UseGtkTheme()); - g_signal_connect(G_OBJECT(widget()), "expose-event", + g_signal_connect(G_OBJECT(event_box_.get()), "expose-event", G_CALLBACK(&OnEventBoxExpose), this); + UpdateEventBoxPaintability(); bookmark_toolbar_.Own(gtk_toolbar_new()); SetToolBarStyle(); @@ -236,6 +263,10 @@ void BookmarkBarGtk::Init(Profile* profile) { void BookmarkBarGtk::Show(bool animate) { gtk_widget_show_all(widget()); + bool old_floating = floating_; + UpdateFloatingState(); + // TODO(estade): animate the transition between floating and non. + animate = animate && (old_floating == floating_); if (animate) { slide_animation_->Show(); } else { @@ -243,6 +274,17 @@ void BookmarkBarGtk::Show(bool animate) { AnimationProgressed(slide_animation_.get()); } + if (floating_) { + // Hide out behind the findbar. + if (GTK_WIDGET_REALIZED(paint_box_)) { + // We toggle the above_child property so that the event window will + // get lowered after we lower the window of |paint_box_|. + gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box_.get()), TRUE); + gdk_window_lower(paint_box_->window); + gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box_.get()), FALSE); + } + } + // Maybe show the instructions if (show_instructions_) { gtk_widget_show(instructions_); @@ -252,6 +294,8 @@ void BookmarkBarGtk::Show(bool animate) { } void BookmarkBarGtk::Hide(bool animate) { + UpdateFloatingState(); + // After coming out of fullscreen, the browser window sets the bookmark bar // to the "hidden" state, which means we need to show our minimum height. gtk_widget_show(widget()); @@ -267,7 +311,9 @@ void BookmarkBarGtk::Hide(bool animate) { } void BookmarkBarGtk::EnterFullscreen() { - gtk_widget_hide(widget()); + UpdateFloatingState(); + if (!floating_) + gtk_widget_hide(widget()); } int BookmarkBarGtk::GetHeight() { @@ -494,6 +540,53 @@ int BookmarkBarGtk::GetFirstHiddenBookmark( return rv; } +bool BookmarkBarGtk::ShouldBeFloating() { + return (!IsAlwaysShown() || (window_ && window_->IsFullscreen())) && + browser_ && browser_->GetSelectedTabContents() && + browser_->GetSelectedTabContents()->IsBookmarkBarAlwaysVisible(); +} + +void BookmarkBarGtk::UpdateFloatingState() { + bool old_floating = floating_; + floating_ = ShouldBeFloating(); + if (floating_ == old_floating) + return; + + if (floating_) { + gtk_event_box_set_visible_window(GTK_EVENT_BOX(paint_box_), TRUE); + GdkColor stroke_color = theme_provider_->UseGtkTheme() ? + theme_provider_->GetBorderColor() : + theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_NTP_HEADER); + gtk_util::ActAsRoundedWindow(paint_box_, stroke_color, kNTPRoundedness, + gtk_util::ROUNDED_ALL, gtk_util::BORDER_ALL); + + gtk_alignment_set_padding(GTK_ALIGNMENT(ntp_padding_box_), + kTopBottomNTPPadding, kTopBottomNTPPadding, + kLeftRightNTPPadding, kLeftRightNTPPadding); + gtk_container_set_border_width(GTK_CONTAINER(bookmark_hbox_), kNTPPadding); + } else { + gtk_util::StopActingAsRoundedWindow(paint_box_); + gtk_event_box_set_visible_window(GTK_EVENT_BOX(paint_box_), FALSE); + gtk_alignment_set_padding(GTK_ALIGNMENT(ntp_padding_box_), 0, 0, 0, 0); + gtk_container_set_border_width(GTK_CONTAINER(bookmark_hbox_), 0); + } + + UpdateEventBoxPaintability(); + // |window_| can be NULL during testing. + if (window_) + window_->BookmarkBarIsFloating(floating_); +} + +void BookmarkBarGtk::UpdateEventBoxPaintability() { + gtk_widget_set_app_paintable(event_box_.get(), + !theme_provider_->UseGtkTheme() || floating_); + // When using the GTK+ theme, we need to have the event box be visible so + // buttons don't get a halo color from the background. When using Chromium + // themes, we want to let the background show through the toolbar. + gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), + theme_provider_->UseGtkTheme()); +} + bool BookmarkBarGtk::IsAlwaysShown() { return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); } @@ -501,9 +594,11 @@ bool BookmarkBarGtk::IsAlwaysShown() { void BookmarkBarGtk::AnimationProgressed(const Animation* animation) { DCHECK_EQ(animation, slide_animation_.get()); + int max_height = ShouldBeFloating() ? + kBookmarkBarNTPHeight : kBookmarkBarHeight; gint height = static_cast<gint>(animation->GetCurrentValue() * - (kBookmarkBarHeight - kBookmarkBarMinimumHeight)) + + (max_height - kBookmarkBarMinimumHeight)) + kBookmarkBarMinimumHeight; gtk_widget_set_size_request(event_box_.get(), -1, height); } @@ -529,14 +624,18 @@ void BookmarkBarGtk::Observe(NotificationType type, << "don't have a BookmarkModel. Taking no action."; } - // When using the GTK+ theme, let GTK optimize the background drawing. - gtk_widget_set_app_paintable(widget(), !theme_provider_->UseGtkTheme()); + UpdateEventBoxPaintability(); + + GdkColor paint_box_color = + theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_TOOLBAR); + gtk_widget_modify_bg(paint_box_, GTK_STATE_NORMAL, &paint_box_color); - // When using the GTK+ theme, we need to have the event box be visible so - // buttons don't get a halo color from the background. When using Chromium - // themes, we want to let the background show through the toolbar. - gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()), - theme_provider_->UseGtkTheme()); + if (floating_) { + GdkColor stroke_color = theme_provider_->UseGtkTheme() ? + theme_provider_->GetBorderColor() : + theme_provider_->GetGdkColor(BrowserThemeProvider::COLOR_NTP_HEADER); + gtk_util::SetRoundedWindowBorderColor(paint_box_, stroke_color); + } SetOverflowButtonAppearance(); } @@ -597,9 +696,6 @@ void BookmarkBarGtk::ConnectFolderButtonEvents(GtkWidget* widget) { g_signal_connect(widget, "drag-data-received", G_CALLBACK(&OnDragReceived), this); - // Connect to 'button-release-event' instead of 'clicked' because we need - // access to the modifier keys and we do different things on each - // button. g_signal_connect(G_OBJECT(widget), "button-press-event", G_CALLBACK(OnButtonPressed), this); g_signal_connect(G_OBJECT(widget), "clicked", @@ -914,30 +1010,66 @@ void BookmarkBarGtk::OnDragReceived(GtkWidget* widget, gboolean BookmarkBarGtk::OnEventBoxExpose(GtkWidget* widget, GdkEventExpose* event, BookmarkBarGtk* bar) { - // We don't need to render the toolbar image in GTK mode. - if (bar->theme_provider_->UseGtkTheme()) + GtkThemeProvider* theme_provider = bar->theme_provider_; + + // We don't need to render the toolbar image in GTK mode, except when + // detached. + if (theme_provider->UseGtkTheme() && !bar->floating_) return FALSE; - // Paint the background theme image. 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); - gfx::Point tabstrip_origin = - bar->tabstrip_origin_provider_->GetTabStripOriginForWidget(widget); - GtkThemeProvider* theme_provider = bar->theme_provider_; - CairoCachedSurface* background = theme_provider->GetSurfaceNamed( - IDR_THEME_TOOLBAR, widget); - background->SetSource(cr, tabstrip_origin.x(), tabstrip_origin.y()); - // We tile the toolbar background in both directions. - 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(), - event->area.y + event->area.height - tabstrip_origin.y()); - cairo_fill(cr); + if (!bar->floating_) { + // Paint the background theme image. + gfx::Point tabstrip_origin = + bar->tabstrip_origin_provider_->GetTabStripOriginForWidget(widget); + + CairoCachedSurface* background = theme_provider->GetSurfaceNamed( + IDR_THEME_TOOLBAR, widget); + background->SetSource(cr, tabstrip_origin.x(), tabstrip_origin.y()); + // We tile the toolbar background in both directions. + 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(), + event->area.y + event->area.height - tabstrip_origin.y()); + cairo_fill(cr); + } else { + // Paint the NTP background. First set the background color. + GdkColor bg_color = theme_provider->UseGtkTheme() ? gfx::kGdkWhite : + theme_provider->GetGdkColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND); + double bg_color_rgb[] = { + static_cast<double>(bg_color.red / 257) / 255.0, + static_cast<double>(bg_color.green / 257) / 255.0, + static_cast<double>(bg_color.blue / 257) / 255.0, }; + cairo_set_source_rgb(cr, bg_color_rgb[0], bg_color_rgb[1], bg_color_rgb[2]); + cairo_rectangle(cr, + event->area.x, + event->area.y, + event->area.width, + event->area.height); + cairo_fill(cr); + + // Now paint the image, if it exists. + // TODO(estade): handle different alignments. + if (theme_provider->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) { + CairoCachedSurface* background = theme_provider->GetSurfaceNamed( + IDR_THEME_NTP_BACKGROUND, widget); + background->SetSource(cr, widget->allocation.x, widget->allocation.y); + 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); + } + } + cairo_destroy(cr); return FALSE; // Propagate expose to children. diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h index 28e1d33..3ff93cb 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.h +++ b/chrome/browser/gtk/bookmark_bar_gtk.h @@ -38,7 +38,8 @@ class BookmarkBarGtk : public AnimationDelegate, FRIEND_TEST(BookmarkBarGtkUnittest, HidesHelpMessageWithBookmark); FRIEND_TEST(BookmarkBarGtkUnittest, BuildsButtons); public: - explicit BookmarkBarGtk(Profile* profile, Browser* browser, + explicit BookmarkBarGtk(BrowserWindowGtk* window, + Profile* profile, Browser* browser, TabstripOriginProvider* tabstrip_origin_provider); virtual ~BookmarkBarGtk(); @@ -96,6 +97,9 @@ class BookmarkBarGtk : public AnimationDelegate, virtual void PopupForButtonNextTo(GtkWidget* button, GtkMenuDirectionType dir); + // The NTP needs to have access to this. + static const int kBookmarkBarNTPHeight; + private: // Helper function which generates GtkToolItems for |bookmark_toolbar_|. void CreateAllBookmarkButtons(); @@ -129,6 +133,16 @@ class BookmarkBarGtk : public AnimationDelegate, int GetFirstHiddenBookmark(int extra_space, std::vector<GtkWidget*>* showing_folders); + // Returns true if the bookmark bar should be floating on the page (for + // NTP). + bool ShouldBeFloating(); + // Update the floating state (either enable or disable it, or do nothing). + void UpdateFloatingState(); + + // Turns on or off the app_paintable flag on |event_box_|, depending on our + // state. + void UpdateEventBoxPaintability(); + // Overridden from BookmarkModelObserver: // Invoked when the bookmark model has finished loading. Creates a button @@ -236,6 +250,7 @@ class BookmarkBarGtk : public AnimationDelegate, PageNavigator* page_navigator_; Browser* browser_; + BrowserWindowGtk* window_; // Provides us with the offset into the background theme image. TabstripOriginProvider* tabstrip_origin_provider_; @@ -248,6 +263,12 @@ class BookmarkBarGtk : public AnimationDelegate, // background color from the toplevel application window's GDK window. OwnedWidgetGtk event_box_; + // Used to float the bookmark bar when on the NTP. + GtkWidget* ntp_padding_box_; + + // Used to paint the background of the bookmark bar when in floating mode. + GtkWidget* paint_box_; + // Used to position all children. GtkWidget* bookmark_hbox_; @@ -289,6 +310,11 @@ class BookmarkBarGtk : public AnimationDelegate, scoped_ptr<SlideAnimation> slide_animation_; + // Whether we are currently configured as floating (detached from the + // toolbar). This reflects our actual state, and can be out of sync with + // what ShouldShowFloating() returns. + bool floating_; + NotificationRegistrar registrar_; }; diff --git a/chrome/browser/gtk/bookmark_bar_gtk_unittest.cc b/chrome/browser/gtk/bookmark_bar_gtk_unittest.cc index c878d51..87fb647 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk_unittest.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk_unittest.cc @@ -27,7 +27,7 @@ class BookmarkBarGtkUnittest : public ::testing::Test { browser_.reset(new Browser(Browser::TYPE_NORMAL, profile_.get())); origin_provider_.reset(new EmptyTabstripOriginProvider); - bookmark_bar_.reset(new BookmarkBarGtk(profile_.get(), browser_.get(), + bookmark_bar_.reset(new BookmarkBarGtk(NULL, profile_.get(), browser_.get(), origin_provider_.get())); } diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index ce1984e..b629b24 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -120,14 +120,12 @@ void BrowserToolbarGtk::Init(Profile* profile, gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_), FALSE); toolbar_ = gtk_hbox_new(FALSE, kToolbarWidgetSpacing); - GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), - ShouldOnlyShowLocation() ? 0 : kTopPadding, 0, - kLeftRightPadding, kLeftRightPadding); - g_signal_connect(alignment, "expose-event", + alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); + UpdateForBookmarkBarVisibility(false); + g_signal_connect(alignment_, "expose-event", G_CALLBACK(&OnAlignmentExpose), this); - gtk_container_add(GTK_CONTAINER(event_box_), alignment); - gtk_container_add(GTK_CONTAINER(alignment), toolbar_); + gtk_container_add(GTK_CONTAINER(event_box_), alignment_); + gtk_container_add(GTK_CONTAINER(alignment_), toolbar_); // Force the height of the toolbar so we get the right amount of padding // above and below the location bar. -1 for width means "let GTK do its // normal sizing". @@ -228,7 +226,7 @@ void BrowserToolbarGtk::Init(Profile* profile, if (ShouldOnlyShowLocation()) { gtk_widget_show(event_box_); - gtk_widget_show(alignment); + gtk_widget_show(alignment_); gtk_widget_show(toolbar_); gtk_widget_show_all(location_hbox); gtk_widget_hide(star_->widget()); @@ -271,6 +269,14 @@ LocationBar* BrowserToolbarGtk::GetLocationBar() const { return location_bar_.get(); } +void BrowserToolbarGtk::UpdateForBookmarkBarVisibility( + bool show_bottom_padding) { + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment_), + ShouldOnlyShowLocation() ? 0 : kTopPadding, + !show_bottom_padding || ShouldOnlyShowLocation() ? 0 : kTopPadding, + kLeftRightPadding, kLeftRightPadding); +} + // CommandUpdater::CommandObserver --------------------------------------------- void BrowserToolbarGtk::EnabledStateChangedForCommand(int id, bool enabled) { diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h index b2f0590..995c5d8 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -65,6 +65,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, GoButtonGtk* GetGoButton() { return go_.get(); } + // We have to show padding on the bottom of the toolbar when the bookmark + // is in floating mode. Otherwise the bookmark bar will paint it for us. + void UpdateForBookmarkBarVisibility(bool show_bottom_padding); + // Overridden from CommandUpdater::CommandObserver: virtual void EnabledStateChangedForCommand(int id, bool enabled); @@ -159,6 +163,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // Clearlooks). GtkWidget* event_box_; + // This widget handles padding around the outside of the toolbar. + GtkWidget* alignment_; + // Gtk widgets. The toolbar is an hbox with each of the other pieces of the // toolbar placed side by side. GtkWidget* toolbar_; diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index f6e85f1..1fff4f4 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -1255,9 +1255,7 @@ void BrowserWindowGtk::ActiveWindowChanged(GdkWindow* active_window) { void BrowserWindowGtk::MaybeShowBookmarkBar(TabContents* contents, bool animate) { - // Don't change the visibility state when the browser is full screen or if - // the bookmark bar isn't supported. - if (IsFullscreen() || !IsBookmarkBarSupported()) + if (!IsBookmarkBarSupported()) return; bool show_bar = false; @@ -1268,13 +1266,15 @@ void BrowserWindowGtk::MaybeShowBookmarkBar(TabContents* contents, show_bar = true; } - if (show_bar && !contents->IsBookmarkBarAlwaysVisible()) { + if (show_bar && contents && !contents->IsBookmarkBarAlwaysVisible()) { PrefService* prefs = contents->profile()->GetPrefs(); - show_bar = prefs->GetBoolean(prefs::kShowBookmarkBar); + show_bar = prefs->GetBoolean(prefs::kShowBookmarkBar) && !IsFullscreen(); } if (show_bar) { bookmark_bar_->Show(animate); + } else if (IsFullscreen()) { + bookmark_bar_->EnterFullscreen(); } else { bookmark_bar_->Hide(animate); } @@ -1474,6 +1474,14 @@ void BrowserWindowGtk::RegisterUserPrefs(PrefService* prefs) { prefs::kUseCustomChromeFrame, custom_frame_default); } +void BrowserWindowGtk::BookmarkBarIsFloating(bool is_floating) { + toolbar_->UpdateForBookmarkBarVisibility(is_floating); + + // This can be NULL during initialization of the bookmark bar. + if (bookmark_bar_.get()) + PlaceBookmarkBar(is_floating); +} + void BrowserWindowGtk::SetGeometryHints() { // Allow the user to resize us arbitrarily small. GdkGeometry geometry; @@ -1621,15 +1629,6 @@ void BrowserWindowGtk::InitWidgets() { G_CALLBACK(&OnCompactNavSpacerExpose), this); } #endif - - if (IsBookmarkBarSupported()) { - bookmark_bar_.reset(new BookmarkBarGtk(browser_->profile(), browser_.get(), - tabstrip_.get())); - gtk_box_pack_start(GTK_BOX(window_vbox_), bookmark_bar_->widget(), - FALSE, FALSE, 0); - gtk_widget_show(bookmark_bar_->widget()); - } - if (IsExtensionShelfSupported()) { extension_shelf_.reset(new ExtensionShelfGtk(browser()->profile(), browser_.get())); @@ -1659,8 +1658,7 @@ void BrowserWindowGtk::InitWidgets() { TRUE, TRUE); gtk_paned_pack2(GTK_PANED(contents_split_), devtools_container_->widget(), FALSE, TRUE); - gtk_box_pack_start(GTK_BOX(render_area_vbox_), contents_split_, TRUE, TRUE, - 0); + gtk_box_pack_end(GTK_BOX(render_area_vbox_), contents_split_, TRUE, TRUE, 0); // Restore split offset. int split_offset = g_browser_process->local_state()->GetInteger( prefs::kDevToolsSplitLocation); @@ -1672,6 +1670,20 @@ void BrowserWindowGtk::InitWidgets() { } gtk_widget_show_all(render_area_vbox_); gtk_widget_hide(devtools_container_->widget()); + render_area_event_box_ = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(render_area_event_box_), render_area_vbox_); + gtk_widget_show(render_area_event_box_); + gtk_box_pack_end(GTK_BOX(window_vbox_), render_area_event_box_, + TRUE, TRUE, 0); + + if (IsBookmarkBarSupported()) { + bookmark_bar_.reset(new BookmarkBarGtk(this, + browser_->profile(), + browser_.get(), + tabstrip_.get())); + PlaceBookmarkBar(false); + gtk_widget_show(bookmark_bar_->widget()); + } #if defined(OS_CHROMEOS) if (browser_->type() & Browser::TYPE_POPUP) { @@ -1689,10 +1701,6 @@ void BrowserWindowGtk::InitWidgets() { // proper control layout. UpdateCustomFrame(); - render_area_event_box_ = gtk_event_box_new(); - gtk_container_add(GTK_CONTAINER(render_area_event_box_), render_area_vbox_); - gtk_widget_show(render_area_event_box_); - gtk_container_add(GTK_CONTAINER(window_vbox_), render_area_event_box_); gtk_container_add(GTK_CONTAINER(window_), window_container_); gtk_widget_show(window_container_); browser_->tabstrip_model()->AddObserver(this); @@ -2183,6 +2191,26 @@ bool BrowserWindowGtk::UseCustomFrame() { (browser_->type() != Browser::TYPE_APP); } +void BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) { + GtkWidget* parent = gtk_widget_get_parent(bookmark_bar_->widget()); + if (parent) + gtk_container_remove(GTK_CONTAINER(parent), bookmark_bar_->widget()); + + if (!is_floating) { + // Place the bookmark bar at the end of |window_vbox_|; this happens after + // we have placed the extension shelf and render area at the end of + // |window_vbox_| so we will be above the render area. + gtk_box_pack_end(GTK_BOX(window_vbox_), bookmark_bar_->widget(), + FALSE, FALSE, 0); + } else { + // Place the bookmark bar at the end of the render area; this happens after + // the tab contents container has been placed there so we will be + // above the webpage. + gtk_box_pack_end(GTK_BOX(render_area_vbox_), bookmark_bar_->widget(), + FALSE, FALSE, 0); + } +} + // static bool BrowserWindowGtk::GetCustomFramePrefDefault() { int wm_window = 0; diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index e216266..d109821 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -199,6 +199,10 @@ class BrowserWindowGtk : public BrowserWindow, gfx::Rect bounds() const { return bounds_; } + // Make changes necessary when the floating state of the bookmark bar changes. + // This should only be called by the bookmark bar itself. + void BookmarkBarIsFloating(bool is_floating); + static void RegisterUserPrefs(PrefService* prefs); protected: @@ -323,6 +327,9 @@ class BrowserWindowGtk : public BrowserWindow, // Returns |true| if we should use the custom frame. bool UseCustomFrame(); + // Put the bookmark bar where it belongs. + void PlaceBookmarkBar(bool is_floating); + // Determine whether we use should default to native decorations or the custom // frame based on the currently-running window manager. static bool GetCustomFramePrefDefault(); diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index dba7532..5ced45d 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -127,6 +127,8 @@ DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent) // Stick ourselves at the bottom of the parent browser. gtk_box_pack_end(GTK_BOX(parent), slide_widget_->widget(), FALSE, FALSE, 0); + // Make sure we are at the very end. + gtk_box_reorder_child(GTK_BOX(parent), slide_widget_->widget(), 0); slide_widget_->Open(); } diff --git a/chrome/browser/gtk/rounded_window.cc b/chrome/browser/gtk/rounded_window.cc index a614634..79af804 100644 --- a/chrome/browser/gtk/rounded_window.cc +++ b/chrome/browser/gtk/rounded_window.cc @@ -158,7 +158,7 @@ gboolean OnRoundedWindowExpose(GtkWidget* widget, // If we want to have borders everywhere, we need to draw a polygon instead // of a set of lines. gdk_draw_polygon(drawable, gc, FALSE, &points[0], points.size()); - } else { + } else if (points.size() > 0) { gdk_draw_lines(drawable, gc, &points[0], points.size()); } @@ -181,7 +181,7 @@ void OnStyleSet(GtkWidget* widget, GtkStyle* previous_style) { } // namespace void ActAsRoundedWindow( - GtkWidget* widget, GdkColor color, int corner_size, + GtkWidget* widget, const GdkColor& color, int corner_size, int rounded_edges, int drawn_borders) { DCHECK(widget); gtk_widget_set_app_paintable(widget, TRUE); @@ -203,6 +203,16 @@ void ActAsRoundedWindow( data, FreeRoundedWindowData); } +void StopActingAsRoundedWindow(GtkWidget* widget) { + g_signal_handlers_disconnect_by_func(widget, + reinterpret_cast<gpointer>(OnRoundedWindowExpose), NULL); + g_signal_handlers_disconnect_by_func(widget, + reinterpret_cast<gpointer>(OnStyleSet), NULL); + + if (GTK_WIDGET_REALIZED(widget)) + gdk_window_shape_combine_mask(widget->window, NULL, 0, 0); +} + void SetRoundedWindowBorderColor(GtkWidget* widget, GdkColor color) { DCHECK(widget); RoundedWindowData* data = static_cast<RoundedWindowData*>( diff --git a/chrome/browser/gtk/rounded_window.h b/chrome/browser/gtk/rounded_window.h index d72991a..46287ff 100644 --- a/chrome/browser/gtk/rounded_window.h +++ b/chrome/browser/gtk/rounded_window.h @@ -11,6 +11,7 @@ namespace gtk_util { // Symbolic names for arguments to |rounded_edges| in ActAsRoundedWindow(). enum RoundedBorders { + ROUNDED_NONE = 0, ROUNDED_BOTTOM_LEFT = 1 << 0, ROUNDED_TOP_LEFT = 1 << 1, ROUNDED_TOP_RIGHT = 1 << 2, @@ -20,6 +21,7 @@ enum RoundedBorders { // Symbolic names for arguments to |drawn_borders| in ActAsRoundedWindow(). enum BorderEdge { + BORDER_NONE = 0, BORDER_LEFT = 1 << 0, BORDER_TOP = 1 << 1, BORDER_RIGHT = 1 << 2, @@ -34,9 +36,12 @@ enum BorderEdge { // control which corners are rounded. |drawn_borders| border control which // sides have a visible border drawn in |color|. void ActAsRoundedWindow( - GtkWidget* widget, GdkColor color, int corner_size, + GtkWidget* widget, const GdkColor& color, int corner_size, int rounded_edges, int drawn_borders); +// Undo most of the actions of ActAsRoundedWindow. +void StopActingAsRoundedWindow(GtkWidget* widget); + // Sets the color of the border on a widget that was returned from // ActAsRoundedWindow(). void SetRoundedWindowBorderColor(GtkWidget* widget, GdkColor color); |