diff options
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.cc | 14 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 23 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 5 | ||||
-rw-r--r-- | chrome/browser/gtk/find_bar_gtk.cc | 99 | ||||
-rw-r--r-- | chrome/browser/gtk/find_bar_gtk.h | 36 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_floating_container.h | 2 |
6 files changed, 87 insertions, 92 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index d4949c7..c8ab529 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -293,15 +293,13 @@ void BookmarkBarGtk::Show(bool animate) { AnimationProgressed(slide_animation_.get()); } + // Hide out behind the findbar. This is rather fragile code, it could + // probably be improved. 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); - } + if (GTK_WIDGET_REALIZED(event_box_->parent)) + gdk_window_lower(event_box_->parent->window); + if (GTK_WIDGET_REALIZED(event_box_.get())) + gdk_window_lower(event_box_->window); } // Maybe show the instructions diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 443df13..63fe880 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -46,6 +46,7 @@ #include "chrome/browser/gtk/download_shelf_gtk.h" #include "chrome/browser/gtk/edit_search_engine_dialog.h" #include "chrome/browser/gtk/find_bar_gtk.h" +#include "chrome/browser/gtk/gtk_floating_container.h" #include "chrome/browser/gtk/go_button_gtk.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/import_dialog_gtk.h" @@ -1419,6 +1420,7 @@ void BrowserWindowGtk::OnStateChanged(GdkWindowState state, tabstrip_->Hide(); if (IsBookmarkBarSupported()) bookmark_bar_->EnterFullscreen(); + gtk_widget_hide(toolbar_border_); #if defined(OS_CHROMEOS) if (main_menu_button_) gtk_widget_hide(main_menu_button_->widget()); @@ -1430,6 +1432,9 @@ void BrowserWindowGtk::OnStateChanged(GdkWindowState state, } else { UpdateCustomFrame(); ShowSupportedWindowFeatures(); + + gtk_widget_show(toolbar_border_); + gdk_window_lower(toolbar_border_->window); } } @@ -1486,11 +1491,9 @@ bool BrowserWindowGtk::ShouldShowWindowIcon() const { } void BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) { - gtk_box_pack_start(GTK_BOX(render_area_vbox_), findbar->widget(), - FALSE, FALSE, 0); - gtk_box_reorder_child(GTK_BOX(render_area_vbox_), findbar->widget(), 0); - - gtk_widget_hide(toolbar_border_); + gtk_floating_container_add_floating( + GTK_FLOATING_CONTAINER(render_area_floating_container_), + findbar->widget()); } void BrowserWindowGtk::ResetCustomFrameCursor() { @@ -1700,6 +1703,9 @@ void BrowserWindowGtk::InitWidgets() { // |render_area_vbox_| is packed in |render_area_event_box_|. render_area_vbox_ = gtk_vbox_new(FALSE, 0); gtk_widget_set_name(render_area_vbox_, "chrome-render-area-vbox"); + render_area_floating_container_ = gtk_floating_container_new(); + gtk_container_add(GTK_CONTAINER(render_area_floating_container_), + render_area_vbox_); toolbar_border_ = gtk_event_box_new(); gtk_box_pack_start(GTK_BOX(render_area_vbox_), @@ -1732,14 +1738,15 @@ void BrowserWindowGtk::InitWidgets() { gtk_widget_set_size_request(devtools_container_->widget(), -1, kDefaultDevToolsHeight); } - gtk_widget_show_all(render_area_vbox_); + gtk_widget_show_all(render_area_floating_container_); gtk_widget_hide(devtools_container_->widget()); render_area_event_box_ = gtk_event_box_new(); // Set a white background so during startup the user sees white in the // content area before we get a TabContents in place. gtk_widget_modify_bg(render_area_event_box_, GTK_STATE_NORMAL, &gfx::kGdkWhite); - gtk_container_add(GTK_CONTAINER(render_area_event_box_), render_area_vbox_); + gtk_container_add(GTK_CONTAINER(render_area_event_box_), + render_area_floating_container_); gtk_widget_show(render_area_event_box_); gtk_box_pack_end(GTK_BOX(window_vbox_), render_area_event_box_, TRUE, TRUE, 0); @@ -2286,7 +2293,7 @@ void BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) { } 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. + // above the webpage (in terms of y). gtk_box_pack_end(GTK_BOX(render_area_vbox_), bookmark_bar_->widget(), FALSE, FALSE, 0); } diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 65c18b0..cb272ad 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -213,7 +213,10 @@ class BrowserWindowGtk : public BrowserWindow, GtkWidget* window_vbox_; // VBox that holds everything below the toolbar. GtkWidget* render_area_vbox_; - // EventBox that holds render_area_vbox_. + // Floating container that holds the render area. It is needed to position + // the findbar. + GtkWidget* render_area_floating_container_; + // EventBox that holds render_area_floating_container_. GtkWidget* render_area_event_box_; // Border between toolbar and render area. This is hidden when the find bar // is added because thereafter the findbar will draw the border for us. diff --git a/chrome/browser/gtk/find_bar_gtk.cc b/chrome/browser/gtk/find_bar_gtk.cc index 57102fa..9c02afb 100644 --- a/chrome/browser/gtk/find_bar_gtk.cc +++ b/chrome/browser/gtk/find_bar_gtk.cc @@ -15,6 +15,7 @@ #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/gtk/cairo_cached_surface.h" #include "chrome/browser/gtk/custom_button.h" +#include "chrome/browser/gtk/gtk_floating_container.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/nine_box.h" #include "chrome/browser/gtk/slide_animator_gtk.h" @@ -167,8 +168,7 @@ FindBarGtk::FindBarGtk(Browser* browser) container_width_(-1), container_height_(-1), match_label_failure_(false), - ignore_changed_signal_(false), - current_fixed_width_(-1) { + ignore_changed_signal_(false) { InitWidgets(); ViewIDUtil::SetID(text_entry_, VIEW_ID_FIND_IN_PAGE_TEXT_FIELD); @@ -190,14 +190,11 @@ FindBarGtk::FindBarGtk(Browser* browser) gtk_widget_add_events(text_entry_, GDK_BUTTON_PRESS_MASK); g_signal_connect(text_entry_, "button-press-event", G_CALLBACK(OnButtonPress), this); - g_signal_connect(widget(), "size-allocate", - G_CALLBACK(OnFixedSizeAllocate), this); g_signal_connect(container_, "expose-event", G_CALLBACK(OnExpose), this); } FindBarGtk::~FindBarGtk() { - fixed_.Destroy(); } void FindBarGtk::InitWidgets() { @@ -218,16 +215,6 @@ void FindBarGtk::InitWidgets() { SlideAnimatorGtk::DOWN, 0, false, false, NULL)); - // |fixed_| has to be at least one pixel tall. We color this pixel the same - // color as the border that separates the toolbar from the tab contents. - fixed_.Own(gtk_fixed_new()); - border_ = gtk_event_box_new(); - gtk_widget_set_size_request(border_, 1, 1); - - gtk_fixed_put(GTK_FIXED(widget()), border_, 0, 0); - gtk_fixed_put(GTK_FIXED(widget()), slide_widget(), 0, 0); - gtk_widget_set_size_request(widget(), -1, 0); - close_button_.reset(CustomDrawButton::CloseButton(theme_provider_)); gtk_util::CenterWidgetInHBox(hbox, close_button_->widget(), true, kCloseButtonPaddingLeft); @@ -303,18 +290,16 @@ void FindBarGtk::InitWidgets() { registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, NotificationService::AllSources()); + g_signal_connect(widget(), "parent-set", G_CALLBACK(OnParentSet), this); + // We take care to avoid showing the slide animator widget. gtk_widget_show_all(container_); gtk_widget_show(widget()); - gtk_widget_show(border_); -} - -GtkWidget* FindBarGtk::slide_widget() { - return slide_widget_->widget(); } void FindBarGtk::Show() { slide_widget_->Open(); + selection_rect = gfx::Rect(); Reposition(); if (container_->window) gdk_window_raise(container_->window); @@ -360,9 +345,10 @@ void FindBarGtk::SetFindText(const string16& find_text) { void FindBarGtk::UpdateUIForFindResult(const FindNotificationDetails& result, const string16& find_text) { if (!result.selection_rect().IsEmpty()) { + selection_rect = result.selection_rect(); int xposition = GetDialogPosition(result.selection_rect()).x(); - if (xposition != slide_widget()->allocation.x) - gtk_fixed_move(GTK_FIXED(widget()), slide_widget(), xposition, 0); + if (xposition != widget()->allocation.x) + Reposition(); } // Once we find a match we no longer want to keep track of what had @@ -417,9 +403,7 @@ gfx::Rect FindBarGtk::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { // At very low browser widths we can wind up with a negative |dialog_bounds| // width, so clamp it to 0. gfx::Rect dialog_bounds = gfx::Rect(ltr ? 0 : 15, 0, - std::max(0, widget()->allocation.width - - (ltr ? 15 : 0)), - 0); + std::max(0, widget()->parent->allocation.width - (ltr ? 15 : 0)), 0); GtkRequisition req; gtk_widget_size_request(container_, &req); @@ -435,12 +419,11 @@ gfx::Rect FindBarGtk::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { } void FindBarGtk::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) { - gtk_fixed_move(GTK_FIXED(widget()), slide_widget(), new_pos.x(), 0); slide_widget_->OpenWithoutAnimation(); } bool FindBarGtk::IsFindBarVisible() { - return GTK_WIDGET_VISIBLE(slide_widget()); + return GTK_WIDGET_VISIBLE(widget()); } void FindBarGtk::RestoreSavedFocus() { @@ -467,10 +450,6 @@ void FindBarGtk::Observe(NotificationType type, // Force reshapings of the find bar window. container_width_ = -1; container_height_ = -1; - current_fixed_width_ = -1; - - GdkColor color = theme_provider_->GetBorderColor(); - gtk_widget_modify_bg(border_, GTK_STATE_NORMAL, &color); if (theme_provider_->UseGtkTheme()) { gtk_widget_modify_base(text_entry_, GTK_STATE_NORMAL, NULL); @@ -585,12 +564,9 @@ void FindBarGtk::Reposition() { if (!IsFindBarVisible()) return; - int xposition = GetDialogPosition(gfx::Rect()).x(); - if (xposition == slide_widget()->allocation.x) { - return; - } else { - gtk_fixed_move(GTK_FIXED(widget()), slide_widget(), xposition, 0); - } + // This will trigger an allocate, which allows us to reposition. + if (widget()->parent) + gtk_widget_queue_resize(widget()->parent); } void FindBarGtk::StoreOutsideFocus() { @@ -636,6 +612,37 @@ bool FindBarGtk::MaybeForwardKeyEventToRenderer(GdkEventKey* event) { } // static +void FindBarGtk::OnParentSet(GtkWidget* widget, GtkObject* old_parent, + FindBarGtk* find_bar) { + if (!widget->parent) + return; + + g_signal_connect(widget->parent, "set-floating-position", + G_CALLBACK(OnSetFloatingPosition), find_bar); +} + +// static +void FindBarGtk::OnSetFloatingPosition( + GtkFloatingContainer* floating_container, + GtkAllocation* allocation, + FindBarGtk* find_bar) { + GtkWidget* findbar = find_bar->widget(); + + int xposition = find_bar->GetDialogPosition(find_bar->selection_rect).x(); + + GValue value = { 0, }; + g_value_init(&value, G_TYPE_INT); + g_value_set_int(&value, xposition); + gtk_container_child_set_property(GTK_CONTAINER(floating_container), + findbar, "x", &value); + + g_value_set_int(&value, 0); + gtk_container_child_set_property(GTK_CONTAINER(floating_container), + findbar, "y", &value); + g_value_unset(&value); +} + +// static gboolean FindBarGtk::OnChanged(GtkWindow* window, FindBarGtk* find_bar) { if (!find_bar->ignore_changed_signal_) find_bar->FindEntryTextInContents(true); @@ -699,28 +706,12 @@ gboolean FindBarGtk::OnContentEventBoxExpose(GtkWidget* widget, return FALSE; } -// static -void FindBarGtk::OnFixedSizeAllocate(GtkWidget* fixed, - GtkAllocation* allocation, - FindBarGtk* findbar) { - // Do nothing if our width hasn't changed. - if (findbar->current_fixed_width_ == allocation->width) - return; - findbar->current_fixed_width_ = allocation->width; - - // Set the background widget to the size of |fixed|. - gtk_widget_set_size_request(findbar->border_, - allocation->width, allocation->height); - - findbar->Reposition(); -} - // Used to handle custom painting of |container_|. gboolean FindBarGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, FindBarGtk* bar) { GtkRequisition req; gtk_widget_size_request(widget, &req); - gtk_widget_set_size_request(bar->slide_widget(), req.width, -1); + gtk_widget_set_size_request(bar->widget(), req.width, -1); if (bar->theme_provider_->UseGtkTheme()) { if (bar->container_width_ != widget->allocation.width || diff --git a/chrome/browser/gtk/find_bar_gtk.h b/chrome/browser/gtk/find_bar_gtk.h index c872060..137b2c3 100644 --- a/chrome/browser/gtk/find_bar_gtk.h +++ b/chrome/browser/gtk/find_bar_gtk.h @@ -11,6 +11,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/find_bar.h" #include "chrome/browser/gtk/focus_store_gtk.h" +#include "chrome/browser/gtk/slide_animator_gtk.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" @@ -24,6 +25,8 @@ class NineBox; class SlideAnimatorGtk; class TabContentsContainerGtk; +typedef struct _GtkFloatingContainer GtkFloatingContainer; + // Currently this class contains both a model and a view. We may want to // eventually pull out the model specific bits and share with Windows. class FindBarGtk : public FindBar, @@ -33,7 +36,7 @@ class FindBarGtk : public FindBar, explicit FindBarGtk(Browser* browser); virtual ~FindBarGtk(); - GtkWidget* widget() const { return fixed_.get(); } + GtkWidget* widget() const { return slide_widget_->widget(); } // Methods from FindBar. virtual FindBarController* GetFindBarController() const { @@ -81,19 +84,22 @@ class FindBarGtk : public FindBar, // See similar function in FindBarWin. bool MaybeForwardKeyEventToRenderer(GdkEventKey* event); - // Returns the child of |fixed_| that holds what the user perceives as the - // findbar. - GtkWidget* slide_widget(); - // Searches for another occurrence of the entry text, moving forward if // |forward_search| is true. void FindEntryTextInContents(bool forward_search); void UpdateMatchLabelAppearance(bool failure); - // Repositions the dialog without worrying about overlapping search results. + // Asynchronously repositions the dialog. void Reposition(); + static void OnParentSet(GtkWidget* widget, GtkObject* old_parent, + FindBarGtk* find_bar); + + static void OnSetFloatingPosition(GtkFloatingContainer* floating_container, + GtkAllocation* allocation, + FindBarGtk* find_bar); + // Callback when the entry text changes. static gboolean OnChanged(GtkWindow* window, FindBarGtk* find_bar); @@ -105,12 +111,6 @@ class FindBarGtk : public FindBar, // Callback for previous, next, and close button. static void OnClicked(GtkWidget* button, FindBarGtk* find_bar); - // Called when |fixed_| changes sizes. Used to position the dialog (the - // "dialog" is the widget hierarchy rooted at |slide_widget_|). - static void OnFixedSizeAllocate(GtkWidget* fixed, - GtkAllocation* allocation, - FindBarGtk* findbar); - // Handles shapping and drawing the find bar background. static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* event, FindBarGtk* bar); @@ -132,14 +132,6 @@ class FindBarGtk : public FindBar, // Provides colors and information about GTK. GtkThemeProvider* theme_provider_; - // GtkFixed containing the find bar widgets. - OwnedWidgetGtk fixed_; - - // An event box which shows the background for |fixed_|. We could just set - // |fixed_| to have its own GdkWindow and draw the background directly, but - // then |container_| would clip to the bounds of |fixed_|. - GtkWidget* border_; - // The widget that animates the slide-in and -out of the findbar. scoped_ptr<SlideAnimatorGtk> slide_widget_; @@ -194,6 +186,10 @@ class FindBarGtk : public FindBar, scoped_ptr<NineBox> dialog_background_; + // The selection rect we are currently showing. We cache it to avoid covering + // it up. + gfx::Rect selection_rect; + NotificationRegistrar registrar_; DISALLOW_COPY_AND_ASSIGN(FindBarGtk); diff --git a/chrome/browser/gtk/gtk_floating_container.h b/chrome/browser/gtk/gtk_floating_container.h index b2f4661..7cd6b0b 100644 --- a/chrome/browser/gtk/gtk_floating_container.h +++ b/chrome/browser/gtk/gtk_floating_container.h @@ -14,7 +14,7 @@ // that interface. The GtkBin portion contains normal content and is given the // same allocation that this container has. // -// In addition, any number of widgets can be through the +// In addition, any number of widgets can be added through the // gtk_floating_container_add_floating() method, which provides functionality // similar to a GtkFixed. Unlike a GtkFixed, coordinates are not set when you // gtk_fixed_put(). The location of the floating widgets is determined while |