summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 23:50:21 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 23:50:21 +0000
commit4bdb4865688a7626a2451e83d094130fc12cf7ed (patch)
tree3c74fad61f27ba27336cdff9419fe94925012f77 /chrome/browser/gtk
parent24313c1118b2ed8eb46181702558841eb9914f9e (diff)
downloadchromium_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.cc208
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.h28
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk_unittest.cc2
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc22
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h7
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc68
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h7
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc2
-rw-r--r--chrome/browser/gtk/rounded_window.cc14
-rw-r--r--chrome/browser/gtk/rounded_window.h7
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);